forked from Github/Axter-Stash
1.1.6 beta
### 1.1.6 beta Note: This is a beta version, because not all of the javascript ajax functions have been tested yet. - Added the following to [**Advance Duplicate File Menu**] - Scene cover preview image option - Webp preview video option - Fix json string return for all calls made from javascript. - Added DupFileManagerPyVer field to json when called from javascript. - When deleting scene using Report, replaced completion prompt with scene background set to gray. - In Report, when rename occurs, the scene gets renamed inline, without having to reload report page. - Added GetRunPluginOperationJson to DupFileManager_report.js which allows result to safely be converted to json. If fails, it gracefully returns null.
This commit is contained in:
@@ -69,6 +69,14 @@ stash = StashPluginHelper(
|
||||
)
|
||||
stash.convertToAscii = True
|
||||
dry_run = stash.Setting("zzdryRun")
|
||||
DupFileManagerPyVer = "1.1"
|
||||
|
||||
taskName_deleteScene = "deleteScene"
|
||||
taskName_copyScene = "copyScene"
|
||||
taskName_moveScene = "moveScene"
|
||||
taskName_mergeScene = "mergeScene"
|
||||
taskName_addExcludeTag = "addExcludeTag"
|
||||
taskName_clearFlag = "clearFlag"
|
||||
|
||||
advanceMenuOptions = [ "applyCombo", "applyComboPinklist", "applyComboGraylist", "applyComboBlacklist", "pathToDelete", "pathToDeleteBlacklist", "sizeToDeleteLess", "sizeToDeleteGreater", "sizeToDeleteBlacklistLess", "sizeToDeleteBlacklistGreater", "durationToDeleteLess", "durationToDeleteGreater", "durationToDeleteBlacklistLess", "durationToDeleteBlacklistGreater",
|
||||
"commonResToDeleteLess", "commonResToDeleteEq", "commonResToDeleteGreater", "commonResToDeleteBlacklistLess", "commonResToDeleteBlacklistEq", "commonResToDeleteBlacklistGreater", "resolutionToDeleteLess", "resolutionToDeleteEq", "resolutionToDeleteGreater",
|
||||
@@ -78,8 +86,10 @@ advanceMenuOptions = [ "applyCombo", "applyComboPinklist", "applyComboGraylist"
|
||||
doJsonReturnModeTypes = ["tag_duplicates_task", "removeDupTag", "addExcludeTag", "removeExcludeTag", "mergeTags", "getLocalDupReportPath",
|
||||
"createDuplicateReportWithoutTagging", "deleteLocalDupReportHtmlFiles", "clear_duplicate_tags_task",
|
||||
"deleteAllDupFileManagerTags", "deleteBlackListTaggedDuplicatesTask", "deleteTaggedDuplicatesLwrResOrLwrDuration",
|
||||
"deleteBlackListTaggedDuplicatesLwrResOrLwrDuration", "create_duplicate_report_task", "copyScene"]
|
||||
"deleteBlackListTaggedDuplicatesLwrResOrLwrDuration", "create_duplicate_report_task", "copyScene", "renameFile", "deleteScene",
|
||||
"removeScene", "flagScene", "flagScene", "moveScene"]
|
||||
javascriptModeTypes = ["getReport", "getAdvanceMenu"]
|
||||
startsWithCommands = [taskName_deleteScene, taskName_copyScene, taskName_moveScene, taskName_mergeScene, taskName_addExcludeTag, taskName_clearFlag]
|
||||
javascriptModeTypes += advanceMenuOptions
|
||||
javascriptModeTypes += doJsonReturnModeTypes
|
||||
doJsonReturn = False
|
||||
@@ -89,6 +99,9 @@ def isReportOrAdvMenu():
|
||||
return True
|
||||
if stash.PLUGIN_TASK_NAME.endswith("Flag"):
|
||||
return True
|
||||
for startsWithCommand in startsWithCommands:
|
||||
if stash.PLUGIN_TASK_NAME.startswith(startsWithCommand):
|
||||
return True
|
||||
return False
|
||||
|
||||
if isReportOrAdvMenu():
|
||||
@@ -160,6 +173,8 @@ reportHeader = f"{DupFileManagerFolder}{os.sep}DupFileManager_rep
|
||||
|
||||
excludeFromReportIfSignificantTimeDiff = False
|
||||
htmlReportPaginate = stash.Setting('htmlReportPaginate')
|
||||
htmlIncludeCoverImage = stash.Setting('htmlIncludeCoverImage')
|
||||
htmlIncludeWebpPreview = stash.Setting('htmlIncludeWebpPreview')
|
||||
htmlIncludeImagePreview = stash.Setting('htmlIncludeImagePreview')
|
||||
htmlIncludeVideoPreview = stash.Setting('htmlIncludeVideoPreview')
|
||||
htmlHighlightTimeDiff = stash.Setting('htmlHighlightTimeDiff')
|
||||
@@ -220,6 +235,15 @@ if (stash.PLUGIN_TASK_NAME == "tag_duplicates_task" or stash.PLUGIN_TASK_NAME ==
|
||||
htmlIncludeVideoPreview = True
|
||||
else:
|
||||
htmlIncludeVideoPreview = False
|
||||
if len(targets) > 18:
|
||||
if targets[17] == "true":
|
||||
htmlIncludeWebpPreview = True
|
||||
else:
|
||||
htmlIncludeWebpPreview = False
|
||||
if targets[18] == "true":
|
||||
htmlIncludeCoverImage = True
|
||||
else:
|
||||
htmlIncludeCoverImage = False
|
||||
logTraceForAdvanceMenuOpt = True
|
||||
|
||||
if htmlIncludeImagePreview and (htmlImagePreviewSize == htmlImagePreviewPopupSize):
|
||||
@@ -242,7 +266,7 @@ if significantTimeDiff < .25:
|
||||
significantTimeDiff = float(0.25)
|
||||
|
||||
if logTraceForAdvanceMenuOpt:
|
||||
stash.Trace(f"PLUGIN_TASK_NAME={stash.PLUGIN_TASK_NAME}; matchDupDistance={matchDupDistance}; matchPhaseDistanceText={matchPhaseDistanceText}; matchPhaseDistance={matchPhaseDistance}; significantTimeDiff={significantTimeDiff}; htmlReportPaginate={htmlReportPaginate}; htmlIncludeImagePreview={htmlIncludeImagePreview}; htmlIncludeVideoPreview={htmlIncludeVideoPreview}; maxDupToProcess={maxDupToProcess}; htmlHighlightTimeDiff={htmlHighlightTimeDiff}; htmlImagePreviewSize={htmlImagePreviewSize}; htmlImagePreviewPopupSize={htmlImagePreviewPopupSize}; htmlImagePreviewPopupEnable={htmlImagePreviewPopupEnable}; htmlPreviewOrStream={htmlPreviewOrStream};")
|
||||
stash.Trace(f"PLUGIN_TASK_NAME={stash.PLUGIN_TASK_NAME}; matchDupDistance={matchDupDistance}; matchPhaseDistanceText={matchPhaseDistanceText}; matchPhaseDistance={matchPhaseDistance}; significantTimeDiff={significantTimeDiff}; htmlReportPaginate={htmlReportPaginate}; htmlIncludeCoverImage={htmlIncludeCoverImage}; htmlIncludeImagePreview={htmlIncludeImagePreview}; htmlIncludeVideoPreview={htmlIncludeVideoPreview}; maxDupToProcess={maxDupToProcess}; htmlHighlightTimeDiff={htmlHighlightTimeDiff}; htmlImagePreviewSize={htmlImagePreviewSize}; htmlImagePreviewPopupSize={htmlImagePreviewPopupSize}; htmlImagePreviewPopupEnable={htmlImagePreviewPopupEnable}; htmlPreviewOrStream={htmlPreviewOrStream};")
|
||||
|
||||
duplicateMarkForDeletion = stash.Setting('DupFileTag')
|
||||
if duplicateMarkForDeletion == "":
|
||||
@@ -576,7 +600,7 @@ def getPath(Scene, getParent = False):
|
||||
path = path.replace("'", "")
|
||||
path = path.replace("\\\\", "\\")
|
||||
if getParent:
|
||||
return pathlib.Path(path).resolve().parent
|
||||
return pathlib.Path(path).parent
|
||||
return path
|
||||
|
||||
htmlReportPrefix = None
|
||||
@@ -678,6 +702,26 @@ itemIndexSrchStr = "::itemIndex="
|
||||
ToDeleteSceneIDSrchStr = "<!-- ::DuplicateToDelete_SceneID="
|
||||
ToKeepSceneIDSrchStr = "::DuplicateToKeep_SceneID="
|
||||
|
||||
def writePreview(fileHtmlReport, scene):
|
||||
videoPreview = ""
|
||||
imagePreview = ""
|
||||
SceneCoverImg = ""
|
||||
webpPreview = ""
|
||||
if htmlIncludeVideoPreview:
|
||||
videoPreview = f"<td><video class=\"ID_{scene['id']}_preview\" {htmlReportVideoPreview} poster=\"{scene['paths']['screenshot']}\"><source src=\"{scene['paths'][htmlPreviewOrStream]}\" type=\"video/mp4\"></video></td>"
|
||||
if htmlIncludeWebpPreview:
|
||||
webpPreview = f"<td><img class=\"ID_{scene['id']}_preview\" {htmlReportVideoPreview} src=\"{scene['paths']['webp']}\" alt=\"\"></td>"
|
||||
if htmlIncludeCoverImage:
|
||||
SceneCoverImg = f"<td><img class=\"ID_{scene['id']}_preview\" width=\"{htmlImagePreviewSize}\" src=\"{scene['paths']['screenshot']}\" alt=\"\"></td>"
|
||||
if htmlIncludeImagePreview:
|
||||
spanPreviewImage = ""
|
||||
if htmlImagePreviewPopupEnable:
|
||||
spanPreviewImage = f"<span class=\"large\"><img class=\"ID_{scene['id']}_preview\" src=\"{scene['paths']['sprite']}\" class=\"large-image\" alt=\"\" width=\"{htmlImagePreviewPopupSize}\"></span>"
|
||||
imagePreview = f"<td><ul><li><img class=\"ID_{scene['id']}_preview\" src=\"{scene['paths']['sprite']}\" alt=\"\" width=\"{htmlImagePreviewSize}\">{spanPreviewImage}</li></ul></td>"
|
||||
if htmlIncludeVideoPreview or htmlIncludeCoverImage or htmlIncludeImagePreview or htmlIncludeWebpPreview:
|
||||
fileHtmlReport.write(f"{getSceneID(scene)}<table><tr>{videoPreview}{webpPreview}{imagePreview}{SceneCoverImg}</tr></table></td>")
|
||||
|
||||
|
||||
# //////////////////////////////////////////////////////////////////////////////
|
||||
# //////////////////////////////////////////////////////////////////////////////
|
||||
def writeRowToHtmlReport(fileHtmlReport, DupFile, DupFileToKeep, itemIndex, tagDuplicates = False, doTraceDetails = False):
|
||||
@@ -693,18 +737,9 @@ def writeRowToHtmlReport(fileHtmlReport, DupFile, DupFileToKeep, itemIndex, tagD
|
||||
dupFileExist = True if os.path.isfile(DupFile['files'][0]['path']) else False
|
||||
toKeepFileExist = True if os.path.isfile(DupFileToKeep['files'][0]['path']) else False
|
||||
fileHtmlReport.write(f"{htmlReportTableRow}")
|
||||
videoPreview = f"<video class=\"ID_{DupFile['id']}_preview\" {htmlReportVideoPreview} poster=\"{DupFile['paths']['screenshot']}\"><source src=\"{DupFile['paths'][htmlPreviewOrStream]}\" type=\"video/mp4\"></video>"
|
||||
if htmlIncludeImagePreview:
|
||||
spanPreviewImage = ""
|
||||
if htmlImagePreviewPopupEnable:
|
||||
spanPreviewImage = f"<span class=\"large\"><img class=\"ID_{DupFile['id']}_preview\" src=\"{DupFile['paths']['sprite']}\" class=\"large-image\" alt=\"\" width=\"{htmlImagePreviewPopupSize}\"></span>"
|
||||
imagePreview = f"<ul><li><img class=\"ID_{DupFile['id']}_preview\" src=\"{DupFile['paths']['sprite']}\" alt=\"\" width=\"{htmlImagePreviewSize}\">{spanPreviewImage}</li></ul>"
|
||||
if htmlIncludeVideoPreview:
|
||||
fileHtmlReport.write(f"{getSceneID(DupFile)}<table><tr><td>{videoPreview}</td><td>{imagePreview}</td></tr></table></td>")
|
||||
else:
|
||||
fileHtmlReport.write(f"{getSceneID(DupFile)}{imagePreview}</td>")
|
||||
elif htmlIncludeVideoPreview:
|
||||
fileHtmlReport.write(f"{getSceneID(DupFile)}{videoPreview}</td>")
|
||||
writePreview(fileHtmlReport, DupFile)
|
||||
|
||||
|
||||
fileHtmlReport.write(f"{getSceneID(DupFile)}<a href=\"{stash.STASH_URL}/scenes/{DupFile['id']}\" target=\"_blank\" rel=\"noopener noreferrer\" {fileNameClassID(DupFile)}>{getPath(DupFile)}</a>")
|
||||
fileHtmlReport.write(f"<p><table><tr class=\"scene-details\"><th>{getMarker(getRes(DupFile), getRes(DupFileToKeep))}Res</th><th>{getMarker(DupFile['files'][0]['duration'], DupFileToKeep['files'][0]['duration'], True)}Durration</th><th>BitRate</th><th>Codec</th><th>FrameRate</th><th>size</th><th>ID</th><th>index</th></tr>")
|
||||
fileHtmlReport.write(f"<tr class=\"scene-details\"><td {getColor(getRes(DupFile), getRes(DupFileToKeep), True)}>{DupFile['files'][0]['width']}x{DupFile['files'][0]['height']}</td><td {getColor(DupFile['files'][0]['duration'], DupFileToKeep['files'][0]['duration'], True, True, htmlHighlightTimeDiff)}>{DupFile['files'][0]['duration']}</td><td {getColor(DupFile['files'][0]['bit_rate'], DupFileToKeep['files'][0]['bit_rate'])}>{DupFile['files'][0]['bit_rate']}</td><td {getColor(DupFile['files'][0]['video_codec'], DupFileToKeep['files'][0]['video_codec'])}>{DupFile['files'][0]['video_codec']}</td><td {getColor(DupFile['files'][0]['frame_rate'], DupFileToKeep['files'][0]['frame_rate'])}>{DupFile['files'][0]['frame_rate']}</td><td {getColor(DupFile['files'][0]['size'], DupFileToKeep['files'][0]['size'])}>{DupFile['files'][0]['size']}</td><td>{DupFile['id']}</td><td>{itemIndex}</td></tr>")
|
||||
@@ -846,18 +881,8 @@ def writeRowToHtmlReport(fileHtmlReport, DupFile, DupFileToKeep, itemIndex, tagD
|
||||
fileHtmlReport.write("</p></td>")
|
||||
# ///////////////////////////////
|
||||
|
||||
videoPreview = f"<video class=\"ID_{DupFileToKeep['id']}_preview\" {htmlReportVideoPreview} poster=\"{DupFileToKeep['paths']['screenshot']}\"><source src=\"{DupFileToKeep['paths'][htmlPreviewOrStream]}\" type=\"video/mp4\"></video>"
|
||||
if htmlIncludeImagePreview:
|
||||
spanPreviewImage = ""
|
||||
if htmlImagePreviewPopupEnable:
|
||||
spanPreviewImage = f"<span class=\"large\"><img class=\"ID_{DupFileToKeep['id']}_preview\" src=\"{DupFileToKeep['paths']['sprite']}\" class=\"large-image\" alt=\"\" width=\"{htmlImagePreviewPopupSize}\"></span>"
|
||||
imagePreview = f"<ul><li><img class=\"ID_{DupFileToKeep['id']}_preview\" src=\"{DupFileToKeep['paths']['sprite']}\" alt=\"\" width=\"{htmlImagePreviewSize}\">{spanPreviewImage}</li></ul>"
|
||||
if htmlIncludeVideoPreview:
|
||||
fileHtmlReport.write(f"{getSceneID(DupFileToKeep)}<table><tr><td>{videoPreview}</td><td>{imagePreview}</td></tr></table></td>")
|
||||
else:
|
||||
fileHtmlReport.write(f"{getSceneID(DupFileToKeep)}{imagePreview}</td>")
|
||||
elif htmlIncludeVideoPreview:
|
||||
fileHtmlReport.write(f"{getSceneID(DupFileToKeep)}{videoPreview}</td>")
|
||||
writePreview(fileHtmlReport, DupFileToKeep)
|
||||
|
||||
fileHtmlReport.write(f"{getSceneID(DupFileToKeep)}<a href=\"{stash.STASH_URL}/scenes/{DupFileToKeep['id']}\" target=\"_blank\" rel=\"noopener noreferrer\" {fileNameClassID(DupFileToKeep)}>{getPath(DupFileToKeep)}</a>")
|
||||
fileHtmlReport.write(f"<p><table><tr class=\"scene-details\"><th>Res</th><th>Durration</th><th>BitRate</th><th>Codec</th><th>FrameRate</th><th>size</th><th>ID</th></tr>")
|
||||
fileHtmlReport.write(f"<tr class=\"scene-details\"><td>{DupFileToKeep['files'][0]['width']}x{DupFileToKeep['files'][0]['height']}</td><td>{DupFileToKeep['files'][0]['duration']}</td><td>{DupFileToKeep['files'][0]['bit_rate']}</td><td>{DupFileToKeep['files'][0]['video_codec']}</td><td>{DupFileToKeep['files'][0]['frame_rate']}</td><td>{DupFileToKeep['files'][0]['size']}</td><td>{DupFileToKeep['id']}</td></tr></table>")
|
||||
@@ -949,7 +974,7 @@ def writeRowToHtmlReport(fileHtmlReport, DupFile, DupFileToKeep, itemIndex, tagD
|
||||
fileHtmlReport.write(f"</tr>{ToDeleteSceneIDSrchStr}{DupFile['id']}{ToKeepSceneIDSrchStr}{DupFileToKeep['id']}{itemIndexSrchStr}{itemIndex}:: -->\n")
|
||||
|
||||
fragmentForSceneDetails = 'id tags {id name ignore_auto_tag} groups {group {name} } performers {name} galleries {id} files {path width height duration size video_codec bit_rate frame_rate} details '
|
||||
htmlFileData = " paths {screenshot sprite " + htmlPreviewOrStream + "} "
|
||||
htmlFileData = " paths {screenshot sprite webp " + htmlPreviewOrStream + "} "
|
||||
mergeFieldData = " code director title rating100 date studio {id name} urls "
|
||||
fragmentForSceneDetails += mergeFieldData + htmlFileData
|
||||
DuplicateCandidateForDeletionList = f"{htmlReportNameFolder}{os.sep}DuplicateCandidateForDeletionList.txt"
|
||||
@@ -1266,7 +1291,7 @@ def mangeDupFiles(merge=False, deleteDup=False, tagDuplicates=False, deleteBlack
|
||||
stash.optimise_database()
|
||||
if doGeneratePhash:
|
||||
stash.metadata_generate({"phashes": True})
|
||||
sys.stdout.write("Report complete")
|
||||
sys.stdout.write(f"{{'Report-Status' : 'Report complete', 'DupFileManagerPyVer': '{DupFileManagerPyVer}'}}")
|
||||
|
||||
def findCurrentTagId(tagNames):
|
||||
# tagNames = [i for n, i in enumerate(tagNames) if i not in tagNames[:n]]
|
||||
@@ -1681,7 +1706,7 @@ def removeDupTag():
|
||||
stash.Log(f"Processing scene ID# {scene}")
|
||||
stash.removeTag(scene, duplicateMarkForDeletion)
|
||||
stash.Log(f"Done removing tag from scene {scene}.")
|
||||
jsonReturn = "{'removeDupTag' : 'complete', 'id': '" + f"{scene}" + "'}"
|
||||
jsonReturn = f"{{'removeDupTag' : 'complete', 'id': '{scene}', 'DupFileManagerPyVer': '{DupFileManagerPyVer}'}}"
|
||||
stash.Log(f"Sending json value {jsonReturn}")
|
||||
sys.stdout.write(jsonReturn)
|
||||
|
||||
@@ -1693,7 +1718,7 @@ def addExcludeTag():
|
||||
stash.Log(f"Processing scene ID# {scene}")
|
||||
stash.addTag(scene, excludeDupFileDeleteTag)
|
||||
stash.Log(f"Done adding exclude tag to scene {scene}.")
|
||||
sys.stdout.write("{" + f"addExcludeTag : 'complete', id: '{scene}'" + "}")
|
||||
sys.stdout.write(f"{{'addExcludeTag' : 'complete', 'id': '{scene}', 'DupFileManagerPyVer': '{DupFileManagerPyVer}'}}")
|
||||
|
||||
def removeExcludeTag():
|
||||
if 'Target' not in stash.JSON_INPUT['args']:
|
||||
@@ -1703,7 +1728,7 @@ def removeExcludeTag():
|
||||
stash.Log(f"Processing scene ID# {scene}")
|
||||
stash.removeTag(scene, excludeDupFileDeleteTag)
|
||||
stash.Log(f"Done removing exclude tag from scene {scene}.")
|
||||
sys.stdout.write("{" + f"removeExcludeTag : 'complete', id: '{scene}'" + "}")
|
||||
sys.stdout.write(f"{{'removeExcludeTag' : 'complete', 'id': '{scene}', 'DupFileManagerPyVer': '{DupFileManagerPyVer}'}}")
|
||||
|
||||
def getParseData(getSceneDetails1=True, getSceneDetails2=True, checkIfNotSplitValue=False):
|
||||
if 'Target' not in stash.JSON_INPUT['args']:
|
||||
@@ -1754,7 +1779,7 @@ def mergeMetadataForAll(ReportName = htmlReportName):
|
||||
break
|
||||
mergeMetadataInThisFile(fileName)
|
||||
stash.Log(f"Done merging metadata for all scenes")
|
||||
sys.stdout.write("{mergeTags : 'complete'}")
|
||||
sys.stdout.write(f"{{'mergeTags' : 'complete', 'DupFileManagerPyVer': '{DupFileManagerPyVer}'}}")
|
||||
|
||||
# ToDo: Rename mergeTags to mergeMetadata
|
||||
def mergeTags(inputScene1=None):
|
||||
@@ -1764,7 +1789,7 @@ def mergeTags(inputScene1=None):
|
||||
if scene1 == "mergeMetadataForAll":
|
||||
mergeMetadataForAll()
|
||||
else:
|
||||
sys.stdout.write("{" + f"mergeTags : 'failed', id1: '{scene1}', id2: '{scene2}'" + "}")
|
||||
sys.stdout.write(f"{{'mergeTags' : 'failed', 'id1': '{scene1}', 'id2': '{scene2}', 'DupFileManagerPyVer': '{DupFileManagerPyVer}'}}")
|
||||
return
|
||||
else:
|
||||
scene1 = inputScene1
|
||||
@@ -1773,7 +1798,7 @@ def mergeTags(inputScene1=None):
|
||||
updateScenesInReports(scene2['id'])
|
||||
stash.Log(f"Done merging scenes for scene {scene1['id']} and scene {scene2['id']}")
|
||||
if inputScene1 == None:
|
||||
sys.stdout.write("{" + f"mergeTags : 'complete', id1: '{scene1['id']}', id2: '{scene2['id']}'" + "}")
|
||||
sys.stdout.write(f"{{'mergeTags' : 'complete', 'id1': '{scene1['id']}', 'id2': '{scene2['id']}', 'DupFileManagerPyVer': '{DupFileManagerPyVer}'}}")
|
||||
|
||||
def getLocalDupReportPath():
|
||||
htmlReportExist = "true" if os.path.isfile(htmlReportName) else "false"
|
||||
@@ -1785,7 +1810,7 @@ def getLocalDupReportPath():
|
||||
apikey_json = ", 'apiKey':''"
|
||||
if 'apiKey' in stash.STASH_CONFIGURATION:
|
||||
apikey_json = f", 'apiKey':'{stash.STASH_CONFIGURATION['apiKey']}'"
|
||||
jsonReturn = "{" + f"'LocalDupReportExist' : {htmlReportExist}, 'Path': '{localPath}', 'LocalDir': '{LocalDir}', 'ReportUrlDir': '{ReportUrlDir}', 'ReportUrl': '{ReportUrl}', 'AdvMenuUrl': '{AdvMenuUrl}', 'IS_DOCKER': '{stash.IS_DOCKER}', 'remoteReportDirURL': '{stash.Setting('remoteReportDirURL')}' {apikey_json}" + "}"
|
||||
jsonReturn = f"{{'LocalDupReportExist' : {htmlReportExist}, 'Path': '{localPath}', 'LocalDir': '{LocalDir}', 'ReportUrlDir': '{ReportUrlDir}', 'ReportUrl': '{ReportUrl}', 'AdvMenuUrl': '{AdvMenuUrl}', 'IS_DOCKER': '{stash.IS_DOCKER}', 'remoteReportDirURL': '{stash.Setting('remoteReportDirURL')}', 'DupFileManagerPyVer': '{DupFileManagerPyVer}' {apikey_json}}}"
|
||||
stash.Log(f"Sending json value {jsonReturn}")
|
||||
sys.stdout.write(jsonReturn)
|
||||
|
||||
@@ -1804,7 +1829,7 @@ def deleteLocalDupReportHtmlFiles(doJsonOutput = True):
|
||||
else:
|
||||
stash.Log(f"Report file does not exist: {htmlReportName}")
|
||||
if doJsonOutput:
|
||||
jsonReturn = "{'LocalDupReportExist' : " + f"{htmlReportExist}" + ", 'Path': '" + f"{htmlReportName}" + "', 'qty': '" + f"{x}" + "'}"
|
||||
jsonReturn = f"{{'LocalDupReportExist' : {htmlReportExist}, 'Path': '{htmlReportName}', 'qty': '{x}', 'DupFileManagerPyVer': '{DupFileManagerPyVer}'}}"
|
||||
stash.Log(f"Sending json value {jsonReturn}")
|
||||
sys.stdout.write(jsonReturn)
|
||||
|
||||
@@ -1836,7 +1861,7 @@ def removeAllDupTagsFromAllScenes(deleteTags=False):
|
||||
if removeTagFromAllScenes(tagToClear, deleteTags):
|
||||
validTags +=[tagToClear]
|
||||
if doJsonReturn:
|
||||
jsonReturn = "{'removeAllDupTagFromAllScenes' : " + f"{duplicateMarkForDeletion}" + ", 'OtherTags': '" + f"{validTags}" + "'}"
|
||||
jsonReturn = f"{{'removeAllDupTagFromAllScenes' : '{duplicateMarkForDeletion}', 'OtherTags': '{validTags}', 'DupFileManagerPyVer': '{DupFileManagerPyVer}'}}"
|
||||
stash.Log(f"Sending json value {jsonReturn}")
|
||||
sys.stdout.write(jsonReturn)
|
||||
else:
|
||||
@@ -2024,19 +2049,19 @@ def deleteScene(disableInReport=True, deleteFile=True, scene=None, writeToStdOut
|
||||
modifyPropertyToSceneClassToAllFiles(f"{scene}_preview", "{display:none;}")
|
||||
if writeToStdOut:
|
||||
stash.Log(f"{stash.PLUGIN_TASK_NAME} complete for scene {scene} with results = {result}")
|
||||
sys.stdout.write("{" + f"{stash.PLUGIN_TASK_NAME} : 'complete', id: '{scene}', result: '{result}'" + "}")
|
||||
sys.stdout.write(f"{{'{stash.PLUGIN_TASK_NAME}' : 'complete', 'id': '{scene}', 'result': '{result}', 'DupFileManagerPyVer': '{DupFileManagerPyVer}'}}")
|
||||
return result
|
||||
|
||||
def clearAllSceneFlags(flagColor=None):
|
||||
modifyPropertyToSceneClassToAllFiles(None, flagColor)
|
||||
stash.Log(f"{stash.PLUGIN_TASK_NAME} complete for all scenes")
|
||||
sys.stdout.write("{" + f"{stash.PLUGIN_TASK_NAME} : 'complete'" + "}")
|
||||
sys.stdout.write(f"{{'{stash.PLUGIN_TASK_NAME}' : 'complete', 'DupFileManagerPyVer': '{DupFileManagerPyVer}'}}")
|
||||
|
||||
def copyScene(moveScene=False, inputScene1=None):
|
||||
if inputScene1 == None:
|
||||
scene1, scene2 = getParseData()
|
||||
if scene1 == None or scene2 == None:
|
||||
sys.stdout.write("{" + f"{stash.PLUGIN_TASK_NAME} : 'failed', id1: '{scene1}', id2: '{scene2}'" + "}")
|
||||
sys.stdout.write(f"{{'{stash.PLUGIN_TASK_NAME}' : 'failed', 'id1': '{scene1}', 'id2': '{scene2}', 'DupFileManagerPyVer': '{DupFileManagerPyVer}'}}")
|
||||
return
|
||||
else:
|
||||
scene1 = inputScene1
|
||||
@@ -2061,16 +2086,16 @@ def copyScene(moveScene=False, inputScene1=None):
|
||||
updateScenesInReports(scene2['id'])
|
||||
stash.Log(f"{actionStr} complete for scene {scene1['id']} and {scene2['id']}")
|
||||
if inputScene1 == None:
|
||||
sys.stdout.write("{" + f"{stash.PLUGIN_TASK_NAME} : 'complete', id1: '{scene1['id']}', id2: '{scene2['id']}', result: '{result}'" + "}")
|
||||
sys.stdout.write(f"{{'{stash.PLUGIN_TASK_NAME}' : 'complete', 'id1': '{scene1['id']}', 'id2': '{scene2['id']}', 'result': '{result}', 'DupFileManagerPyVer': '{DupFileManagerPyVer}'}}")
|
||||
|
||||
def renameFile():
|
||||
scene, newName = getParseData(getSceneDetails2=False)
|
||||
if scene == None or newName == None:
|
||||
sys.stdout.write("{" + f"{stash.PLUGIN_TASK_NAME} : 'failed', scene: '{scene}', newName: '{newName}'" + "}")
|
||||
sys.stdout.write(f"{{'{stash.PLUGIN_TASK_NAME}' : 'failed', 'scene': '{scene}', 'newName': '{newName}', 'DupFileManagerPyVer': '{DupFileManagerPyVer}'}}")
|
||||
return
|
||||
newName = newName.strip("'")
|
||||
ext = pathlib.Path(scene['files'][0]['path']).suffix
|
||||
newNameFull = f"{pathlib.Path(scene['files'][0]['path']).resolve().parent}{os.sep}{newName}{ext}"
|
||||
newNameFull = f"{pathlib.Path(scene['files'][0]['path']).parent}{os.sep}{newName}{ext}"
|
||||
newNameFull = newNameFull.strip("'")
|
||||
newNameFull = newNameFull.replace("\\\\", "\\")
|
||||
oldNameFull = scene['files'][0]['path']
|
||||
@@ -2080,13 +2105,14 @@ def renameFile():
|
||||
result = os.rename(oldNameFull, newNameFull)
|
||||
stash.renameFileNameInDB(scene['files'][0]['id'], pathlib.Path(oldNameFull).stem, f"{newName}{ext}", UpdateUsingIdOnly = True)
|
||||
updateScenesInReports(scene['id'])
|
||||
stash.Log(f"{stash.PLUGIN_TASK_NAME} complete for scene {scene['id']} ;renamed to {newName}; result={result}")
|
||||
sys.stdout.write("{" + f"{stash.PLUGIN_TASK_NAME} : 'complete', scene: '{scene['id']}', newName: '{newName}', result: '{result}'" + "}")
|
||||
stash.Log(f"{stash.PLUGIN_TASK_NAME} complete for scene {scene['id']} ;renamed to {newNameFull}; result={result}")
|
||||
# newNameFull = newNameFull.replace("\\", "\\\\")
|
||||
sys.stdout.write(f"{{'{stash.PLUGIN_TASK_NAME}' : 'complete', 'scene': '{scene['id']}', 'newName': '{newNameFull}', 'result': '{result}', 'DupFileManagerPyVer': '{DupFileManagerPyVer}'}}")
|
||||
|
||||
def flagScene():
|
||||
scene, flagType = getParseData(False, False)
|
||||
if scene == None or flagType == None:
|
||||
sys.stdout.write("{" + f"{stash.PLUGIN_TASK_NAME} : 'failed', scene: '{scene}', flagType: '{flagType}'" + "}")
|
||||
sys.stdout.write(f"{{'{stash.PLUGIN_TASK_NAME}' : 'failed', 'scene': '{scene}', 'flagType': '{flagType}', 'DupFileManagerPyVer': '{DupFileManagerPyVer}'}}")
|
||||
return
|
||||
|
||||
if " highlight" in flagType:
|
||||
@@ -2112,9 +2138,9 @@ def flagScene():
|
||||
modifyPropertyToSceneClassToAllFiles(scene, "")
|
||||
else:
|
||||
stash.Log(f"Invalid flagType ({flagType})")
|
||||
sys.stdout.write("{" + f"{stash.PLUGIN_TASK_NAME} : 'failed', scene: '{scene}', flagType: '{flagType}'" + "}")
|
||||
sys.stdout.write(f"{{'{stash.PLUGIN_TASK_NAME}' : 'failed', 'scene': '{scene}', 'flagType': '{flagType}', 'DupFileManagerPyVer': '{DupFileManagerPyVer}'}}")
|
||||
return
|
||||
sys.stdout.write("{" + f"{stash.PLUGIN_TASK_NAME} : 'complete', scene: '{scene}', flagType: '{flagType}'" + "}")
|
||||
sys.stdout.write(f"{{'{stash.PLUGIN_TASK_NAME}' : 'complete', 'scene': '{scene}', 'flagType': '{flagType}', 'DupFileManagerPyVer': '{DupFileManagerPyVer}'}}")
|
||||
|
||||
def getReport():
|
||||
if 'Target' not in stash.JSON_INPUT['args']:
|
||||
@@ -2157,12 +2183,6 @@ def getAdvanceMenu():
|
||||
# Remove only graylist dup
|
||||
# Exclude graylist from delete
|
||||
# Include graylist in delete
|
||||
taskName_deleteScene = "deleteScene"
|
||||
taskName_copyScene = "copyScene"
|
||||
taskName_moveScene = "moveScene"
|
||||
taskName_mergeScene = "mergeScene"
|
||||
taskName_addExcludeTag = "addExcludeTag"
|
||||
taskName_clearFlag = "clearFlag"
|
||||
|
||||
try:
|
||||
if stash.PLUGIN_TASK_NAME == "tag_duplicates_task":
|
||||
@@ -2307,6 +2327,7 @@ except Exception as e:
|
||||
stash.convertToAscii = False
|
||||
stash.Error(f"Error: {e}\nTraceBack={tb}")
|
||||
if doJsonReturn:
|
||||
sys.stdout.write("{" + f"Exception : '{e}; See log file for TraceBack' " + "}")
|
||||
errStr = e.replace("'", "`")
|
||||
sys.stdout.write(f"{{'Exception' : '{errStr}; See log file for TraceBack', 'DupFileManagerPyVer': '{DupFileManagerPyVer}'}}")
|
||||
|
||||
stash.Log("\n*********************************\nEXITING ***********************\n*********************************")
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
name: DupFileManager
|
||||
description: Manages duplicate files.
|
||||
version: 1.1.5
|
||||
version: 1.1.6 beta
|
||||
url: https://github.com/David-Maisonave/Axter-Stash/tree/main/plugins/DupFileManager
|
||||
ui:
|
||||
# css:
|
||||
|
||||
@@ -10,6 +10,7 @@ console.log("Cookies = " + document.cookie);
|
||||
const StrRemoveToKeepConfirm = "RemoveToKeepConfirm=";
|
||||
const StrRemoveValidatePrompt = "RemoveValidatePrompt=";
|
||||
const StrDisableReloadPage = "DisableReloadPage=";
|
||||
var DupFileManagerPyVer = null;
|
||||
function SetPaginateButtonChange(){
|
||||
var chkBxRemoveValid = document.getElementById("RemoveValidatePrompt");
|
||||
var chkBxDisableDeleteConfirm = document.getElementById("RemoveToKeepConfirm");
|
||||
@@ -18,9 +19,9 @@ function SetPaginateButtonChange(){
|
||||
RemoveValidatePromptValue = StrRemoveValidatePrompt + "false";
|
||||
DisableReloadPageValue = StrDisableReloadPage + "false";
|
||||
if (chkBxRemoveValid.checked)
|
||||
RemoveToKeepConfirmValue = StrRemoveToKeepConfirm + "true";
|
||||
if (chkBxDisableDeleteConfirm.checked)
|
||||
RemoveValidatePromptValue = StrRemoveValidatePrompt + "true";
|
||||
if (chkBxDisableDeleteConfirm.checked)
|
||||
RemoveToKeepConfirmValue = StrRemoveToKeepConfirm + "true";
|
||||
if (chkBxDisableReloadPage != null && chkBxDisableReloadPage.checked)
|
||||
DisableReloadPageValue = StrDisableReloadPage + "true";
|
||||
document.cookie = RemoveToKeepConfirmValue + "&" + RemoveValidatePromptValue + "&" + DisableReloadPageValue + "; SameSite=None; Secure";
|
||||
@@ -32,6 +33,17 @@ function trim(str, ch) {
|
||||
while(end > start && str[end - 1] === ch) --end;
|
||||
return (start > 0 || end < str.length) ? str.substring(start, end) : str;
|
||||
}
|
||||
function GetRunPluginOperationJson(result){
|
||||
try{
|
||||
jsonResults = JSON.parse(result);
|
||||
const jsonSubResults = JSON.parse(jsonResults.data.runPluginOperation.replaceAll("'", "\"").replaceAll("\\", "\\\\"));
|
||||
DupFileManagerPyVer = jsonSubResults.DupFileManagerPyVer
|
||||
return jsonSubResults;
|
||||
}catch(error){
|
||||
console.error(error);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
function RunPluginOperation(Mode, ActionID, button, asyncAjax){ // Mode=Value and ActionID=id
|
||||
if (Mode == null || Mode === ""){
|
||||
console.log("Error: Mode is empty or null; ActionID = " + ActionID);
|
||||
@@ -49,16 +61,26 @@ function RunPluginOperation(Mode, ActionID, button, asyncAjax){ // Mode=Value an
|
||||
query: `mutation RunPluginOperation($plugin_id:ID!,$args:Map!){runPluginOperation(plugin_id:$plugin_id,args:$args)}`,
|
||||
variables: {"plugin_id": "DupFileManager", "args": { "Target" : ActionID, "mode":Mode}},
|
||||
}), success: function(result){
|
||||
console.log(result);
|
||||
console.log("For ActionID '" + ActionID + "' result=" + result);
|
||||
const jsonSubResults = GetRunPluginOperationJson(result);
|
||||
if (asyncAjax){
|
||||
$('html').removeClass('wait');
|
||||
$("body").css("cursor", "default");
|
||||
}
|
||||
if (Mode.startsWith("copyScene") || Mode.startsWith("renameFile") || Mode === "clearAllSceneFlags" || Mode.startsWith("clearFlag") || Mode.startsWith("mergeScene") || Mode.startsWith("mergeTags") || (Mode !== "deleteScene" && Mode.startsWith("deleteScene"))){
|
||||
if (Mode === "deleteScene" || Mode === "removeScene"){
|
||||
console.log("Delete complete. Setting background color for .ID_" + ActionID);
|
||||
$('.ID_' + ActionID).css('background-color','gray');
|
||||
}
|
||||
else if (Mode === "renameFile" && jsonSubResults != null){
|
||||
const FnId = ".FN_ID_" + jsonSubResults.scene;
|
||||
console.log("Changing existing file name ID (" + FnId + ") '" + $(FnId).text() + "' to '" + jsonSubResults.newName + "'");
|
||||
$(FnId).text(jsonSubResults.newName);
|
||||
}else if (Mode.startsWith("copyScene") || Mode.startsWith("renameFile") || Mode === "clearAllSceneFlags" || Mode.startsWith("clearFlag") || Mode.startsWith("mergeScene") || Mode.startsWith("mergeTags") || (Mode !== "deleteScene" && Mode.startsWith("deleteScene"))){
|
||||
const chkBxDisableReloadPage = document.getElementById("DisableReloadPage");
|
||||
if (chkBxDisableReloadPage == null || !chkBxDisableReloadPage.checked)
|
||||
window.location.reload();
|
||||
} else if (!chkBxRemoveValid.checked && Mode !== "flagScene") alert("Action " + Mode + " for scene(s) ID# " + ActionID + " complete.\\n\\nResults=" + result);
|
||||
} else if (!chkBxRemoveValid.checked && Mode !== "flagScene")
|
||||
alert("Action " + Mode + " for scene(s) ID# " + ActionID + " complete.\\n\\nResults=" + result);
|
||||
}, error: function(XMLHttpRequest, textStatus, errorThrown) {
|
||||
console.log("Ajax failed with Status: " + textStatus + "; Error: " + errorThrown);
|
||||
if (asyncAjax){
|
||||
@@ -218,7 +240,7 @@ $(document).ready(function(){
|
||||
if (!chkBxDisableDeleteConfirm.checked && !confirm(question))
|
||||
return;
|
||||
if (Mode === "deleteScene" || Mode === "removeScene"){
|
||||
$('.ID_' + ActionID).css('background-color','gray');
|
||||
// $('.ID_' + ActionID).css('background-color','gray');
|
||||
$('.ID_' + ActionID).css('pointer-events','none');
|
||||
}
|
||||
}
|
||||
|
||||
@@ -7,6 +7,10 @@
|
||||
report_config = {
|
||||
# Paginate HTML report. Maximum number of results to display on one page, before adding (paginating) an additional page.
|
||||
"htmlReportPaginate" : 100,
|
||||
# If enabled, report displays the scene cover as a preview image
|
||||
"htmlIncludeCoverImage" : False,
|
||||
# If enabled, report displays Webp as a preview image
|
||||
"htmlIncludeWebpPreview" : False,
|
||||
# If enabled, report displays an image preview similar to sceneDuplicateChecker
|
||||
"htmlIncludeImagePreview" : False,
|
||||
"htmlImagePreviewSize" : 140,
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
# DupFileManager: Ver 1.1.5 (By David Maisonave)
|
||||
# DupFileManager: Ver 1.1.6 beta (By David Maisonave)
|
||||
|
||||
DupFileManager is a [Stash](https://github.com/stashapp/stash) plugin which manages duplicate files in the Stash system.
|
||||
It has both **task** and **tools-UI** components.
|
||||
@@ -135,7 +135,6 @@ Users can setup a private or alternate remote site by changing variables **remot
|
||||
- Scheduled Changes
|
||||
- Remove [Max Dup Process] from the Stash->Plugins GUI. This option already exist in advance menu. Planned for 1.2.0 Version.
|
||||
- Add chat icon to report which on hover, displays a popup window showing scene details content. Planned for 1.2.0 Version.
|
||||
- Add image icon to report; on hover show scene cover image. Planned for 1.2.0 Version.
|
||||
- Add studio icon to report; on hover show studio name. Planned for 1.2.0 Version.
|
||||
- Add option on report to view rating and change it. Use an icon with a number on it to show rating. Planned for 1.2.0 Version.
|
||||
- On report make flag toggle logic. In other words, when flag button is selected, and scene is already that color, remove the colored flag. Planned for 1.2.0 Version.
|
||||
|
||||
@@ -69,7 +69,7 @@ function RunPluginDupFileManager(Mode, Param = 0, Async = false, TagOnlyScenes =
|
||||
}
|
||||
console.log("Ajax success with result = " + result);
|
||||
if (Mode === "tag_duplicates_task" || Mode === "create_duplicate_report_task"){
|
||||
if (result.indexOf("\"Report complete\"") == -1)
|
||||
if (result.indexOf("Report complete") == -1)
|
||||
alert("Stash RunPluginOperation returned unexpected results.\nNot sure if report completed successfully.\n\nResults = " + result);
|
||||
else{
|
||||
var Notice = "";
|
||||
@@ -128,7 +128,7 @@ function GetStashTabUrl(Tab){
|
||||
function GetReportCreateOptions(Value){
|
||||
if (Value === "-1")
|
||||
return "";
|
||||
const param = Value + ":" + $("#significantTimeDiff").val() + ":" + $("#IncludePreviewImage").prop('checked') + ":" + $("#scenesPerPage").val() + ":" + $("#ImagePreviewSize").val() + ":" + $("#ImagePreviewPopupSize").val() + ":" + $("#TimeDiffHighlight").val() + ":" + $("#maxDupToProcess").val() + ":" + $("#streamOverPreview").prop('checked') + ":" + $("#SupperHighlight").val() + ":" + $("#DetailDiffTextColor").val() + ":" + $("#LowerHighlight").val() + ":" + $("#ReportBackgroundColor").val() + ":" + $("#ReportTextColor").val() + ":" + $("#VideoPreviewWidth").val() + ":" + $("#VideoPreviewHeight").val() + ":" + $("#IncludePreviewVideo").prop('checked');
|
||||
const param = Value + ":" + $("#significantTimeDiff").val() + ":" + $("#IncludePreviewImage").prop('checked') + ":" + $("#scenesPerPage").val() + ":" + $("#ImagePreviewSize").val() + ":" + $("#ImagePreviewPopupSize").val() + ":" + $("#TimeDiffHighlight").val() + ":" + $("#maxDupToProcess").val() + ":" + $("#streamOverPreview").prop('checked') + ":" + $("#SupperHighlight").val() + ":" + $("#DetailDiffTextColor").val() + ":" + $("#LowerHighlight").val() + ":" + $("#ReportBackgroundColor").val() + ":" + $("#ReportTextColor").val() + ":" + $("#VideoPreviewWidth").val() + ":" + $("#VideoPreviewHeight").val() + ":" + $("#IncludePreviewVideo").prop('checked') + ":" + $("#IncludeWebpPreviewImage").prop('checked') + ":" + $("#IncludeSceneCoverPreviewImage").prop('checked');
|
||||
console.log("param = " + param);
|
||||
return param;
|
||||
}
|
||||
@@ -294,19 +294,24 @@ $(document).ready(function(){
|
||||
$("#ImagePreviewPopupSize").prop('disabled', false);
|
||||
}
|
||||
else{
|
||||
$("#ImagePreviewSize").prop('disabled', true);
|
||||
if ($("#IncludeSceneCoverPreviewImage").prop('checked'))
|
||||
$("#ImagePreviewSize").prop('disabled', false);
|
||||
else
|
||||
$("#ImagePreviewSize").prop('disabled', true);
|
||||
$("#ImagePreviewPopupSize").prop('disabled', true);
|
||||
}
|
||||
if ($("#IncludePreviewVideo").prop('checked')){
|
||||
$("#streamOverPreview").prop('disabled', false);
|
||||
if ($("#IncludePreviewVideo").prop('checked') || $("#IncludeWebpPreviewImage").prop('checked')){
|
||||
$("#VideoPreviewWidth").prop('disabled', false);
|
||||
$("#VideoPreviewHeight").prop('disabled', false);
|
||||
}
|
||||
else{
|
||||
$("#streamOverPreview").prop('disabled', true);
|
||||
$("#VideoPreviewWidth").prop('disabled', true);
|
||||
$("#VideoPreviewHeight").prop('disabled', true);
|
||||
}
|
||||
if ($("#IncludePreviewVideo").prop('checked'))
|
||||
$("#streamOverPreview").prop('disabled', false);
|
||||
else
|
||||
$("#streamOverPreview").prop('disabled', true);
|
||||
$("button").click(function(){
|
||||
ProcessClick(this);
|
||||
});
|
||||
@@ -324,10 +329,19 @@ $(document).ready(function(){
|
||||
$("#ImagePreviewPopupSize").prop('disabled', false);
|
||||
}
|
||||
else{
|
||||
$("#ImagePreviewSize").prop('disabled', true);
|
||||
if ($("#IncludeSceneCoverPreviewImage").prop('checked'))
|
||||
$("#ImagePreviewSize").prop('disabled', false);
|
||||
else
|
||||
$("#ImagePreviewSize").prop('disabled', true);
|
||||
$("#ImagePreviewPopupSize").prop('disabled', true);
|
||||
}
|
||||
});
|
||||
$("#IncludeSceneCoverPreviewImage").change(function() {
|
||||
if(this.checked || $("#IncludePreviewImage").prop('checked'))
|
||||
$("#ImagePreviewSize").prop('disabled', false);
|
||||
else
|
||||
$("#ImagePreviewSize").prop('disabled', true);
|
||||
});
|
||||
$("#IncludePreviewVideo").change(function() {
|
||||
if(this.checked){
|
||||
$("#streamOverPreview").prop('disabled', false);
|
||||
@@ -336,6 +350,22 @@ $(document).ready(function(){
|
||||
}
|
||||
else{
|
||||
$("#streamOverPreview").prop('disabled', true);
|
||||
if ($("#IncludeWebpPreviewImage").prop('checked')){
|
||||
$("#VideoPreviewWidth").prop('disabled', false);
|
||||
$("#VideoPreviewHeight").prop('disabled', false);
|
||||
}
|
||||
else {
|
||||
$("#VideoPreviewWidth").prop('disabled', true);
|
||||
$("#VideoPreviewHeight").prop('disabled', true);
|
||||
}
|
||||
}
|
||||
});
|
||||
$("#IncludeWebpPreviewImage").change(function() {
|
||||
if(this.checked || $("#IncludePreviewVideo").prop('checked')){
|
||||
$("#VideoPreviewWidth").prop('disabled', false);
|
||||
$("#VideoPreviewHeight").prop('disabled', false);
|
||||
}
|
||||
else{
|
||||
$("#VideoPreviewWidth").prop('disabled', true);
|
||||
$("#VideoPreviewHeight").prop('disabled', true);
|
||||
}
|
||||
@@ -2023,13 +2053,14 @@ function DeleteDupInPath(){
|
||||
</tr>
|
||||
<tr>
|
||||
<td>
|
||||
<div class="easyui-tooltip" title="Create report with preview image."><label for="IncludePreviewImage">Include Preview Image:</label><input type="checkbox" id="IncludePreviewImage" name="IncludePreviewImage" value="true"></div>
|
||||
<div class="easyui-tooltip" title="Create report with a collage preview image."><label for="IncludePreviewImage">Collage preview image:</label><input type="checkbox" id="IncludePreviewImage" name="IncludePreviewImage" value="true"></div>
|
||||
<div class="easyui-tooltip" title="Create report with scene cover preview image. Requires DupFileManger version 1.1.6 or higher."><label for="IncludeSceneCoverPreviewImage">Scene cover preview image:</label><input type="checkbox" id="IncludeSceneCoverPreviewImage" name="IncludeSceneCoverPreviewImage" value="true"></div>
|
||||
</td>
|
||||
<td>
|
||||
<div class="easyui-tooltip" title="This value is the size of preview image. Default value is 140."><label for="ImagePreviewSize">Preview Image Size:</label><input type="number" min="50" max="600" step="10" id="ImagePreviewSize" name="ImagePreviewSize" value="140"></div>
|
||||
<div class="easyui-tooltip" title="This value is the width size of the preview image. Default value is 160."><label for="ImagePreviewSize">Preview image width:</label><input type="number" min="50" max="600" step="10" id="ImagePreviewSize" name="ImagePreviewSize" value="160"></div>
|
||||
</td>
|
||||
<td>
|
||||
<div class="easyui-tooltip" title="This value is the size of the popup window when mouse hovers over the image. Default value is 600."><label for="ImagePreviewPopupSize">Image Popup Size:</label><input type="number" min="200" max="3000" step="100" id="ImagePreviewPopupSize" name="ImagePreviewPopupSize" value="600"></div>
|
||||
<div class="easyui-tooltip" title="This value is the size of the collage popup window when mouse hovers over the image. Default value is 600."><label for="ImagePreviewPopupSize">Collage Image Popup Size:</label><input type="number" min="200" max="3000" step="100" id="ImagePreviewPopupSize" name="ImagePreviewPopupSize" value="600"></div>
|
||||
</td>
|
||||
</tr>
|
||||
<tr><td colspan="3">
|
||||
@@ -2061,7 +2092,8 @@ function DeleteDupInPath(){
|
||||
</tr>
|
||||
<tr>
|
||||
<td rowspan="2">
|
||||
<div class="easyui-tooltip" title="Create report with preview video."><label for="IncludePreviewVideo">Include Preview Video:</label><input type="checkbox" id="IncludePreviewVideo" name="IncludePreviewVideo" value="true" checked></div>
|
||||
<div class="easyui-tooltip" title="Create report with preview video."><label for="IncludePreviewVideo">Preview video:</label><input type="checkbox" id="IncludePreviewVideo" name="IncludePreviewVideo" value="true" checked></div>
|
||||
<div class="easyui-tooltip" title="Create report with Webp preview video. Requires DupFileManger version 1.1.6 or higher."><label for="IncludeWebpPreviewImage">Webp preview video:</label><input type="checkbox" id="IncludeWebpPreviewImage" name="IncludeWebpPreviewImage" value="true"></div>
|
||||
</td>
|
||||
<td colspan="2">
|
||||
<div class="easyui-tooltip" title="Create report with full video available in the preview section instead of a partial video. This option works in Chrome, but does not work so well in firefox."><label for="streamOverPreview">For preview, display full stream video instead of partial preview video:</label><input type="checkbox" id="streamOverPreview" name="streamOverPreview" value="true"></div>
|
||||
@@ -2204,4 +2236,3 @@ function DeleteDupInPath(){
|
||||
<div id="div1"></div>
|
||||
</body></html>
|
||||
|
||||
|
||||
|
||||
@@ -108,5 +108,15 @@
|
||||
### 1.1.5
|
||||
- After deleting scene from report, disable preview for the deleted scene on the report.
|
||||
- Add option to report to avoid reloading page after updating report.
|
||||
### 1.1.6 beta
|
||||
Note: This is a beta version, because not all of the javascript ajax functions have been tested yet.
|
||||
- Added the following to [**Advance Duplicate File Menu**]
|
||||
- Scene cover preview image option
|
||||
- Webp preview video option
|
||||
- Fix json string return for all calls made from javascript.
|
||||
- Added DupFileManagerPyVer field to json when called from javascript.
|
||||
- When deleting scene using Report, replaced completion prompt with scene background set to gray.
|
||||
- In Report, when rename occurs, the scene gets renamed inline, without having to reload report page.
|
||||
- Added GetRunPluginOperationJson to DupFileManager_report.js which allows result to safely be converted to json. If fails, it gracefully returns null.
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user