forked from Github/Axter-Stash
Added advance menu option
This commit is contained in:
@@ -33,4 +33,35 @@
|
|||||||
margin: 1em;
|
margin: 1em;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Dashed border */
|
||||||
|
hr.dashed {
|
||||||
|
border-top: 3px dashed #bbb;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Dotted border */
|
||||||
|
hr.dotted {
|
||||||
|
border-top: 3px dotted #bbb;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Solid border */
|
||||||
|
hr.solid {
|
||||||
|
border-top: 3px solid #bbb;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Rounded border */
|
||||||
|
hr.rounded {
|
||||||
|
border-top: 8px solid #bbb;
|
||||||
|
border-radius: 5px;
|
||||||
|
}
|
||||||
|
|
||||||
|
h3.under_construction {
|
||||||
|
color:red;
|
||||||
|
background-color:yellow;
|
||||||
|
}
|
||||||
|
|
||||||
|
h3.submenu {
|
||||||
|
color:Tomato;
|
||||||
|
background-color:rgba(100, 100, 100);
|
||||||
|
}
|
||||||
|
|
||||||
/*# sourceMappingURL=DupFileManager.css.map */
|
/*# sourceMappingURL=DupFileManager.css.map */
|
||||||
|
|||||||
File diff suppressed because one or more lines are too long
@@ -21,20 +21,33 @@ parser.add_argument('--remove_dup', '-r', dest='remove', action='store_true', he
|
|||||||
parse_args = parser.parse_args()
|
parse_args = parser.parse_args()
|
||||||
|
|
||||||
settings = {
|
settings = {
|
||||||
|
"matchDupDistance": 0,
|
||||||
"mergeDupFilename": False,
|
"mergeDupFilename": False,
|
||||||
"whitelistDelDupInSameFolder": False,
|
"whitelistDelDupInSameFolder": False,
|
||||||
|
"zvWhitelist": "",
|
||||||
|
"zwGraylist": "",
|
||||||
|
"zxBlacklist": "",
|
||||||
|
"zyMaxDupToProcess": 0,
|
||||||
|
"zySwapHighRes": False,
|
||||||
|
"zySwapLongLength": False,
|
||||||
|
"zySwapBetterBitRate": False,
|
||||||
|
"zySwapCodec": False,
|
||||||
|
"zySwapBetterFrameRate": False,
|
||||||
|
"zzDebug": False,
|
||||||
|
"zzTracing": False,
|
||||||
|
|
||||||
|
"zzObsoleteSettingsCheckVer2": False, # This is a hidden variable that is NOT displayed in the UI
|
||||||
|
|
||||||
|
# Obsolete setting names
|
||||||
|
"zWhitelist": "",
|
||||||
|
"zxGraylist": "",
|
||||||
|
"zyBlacklist": "",
|
||||||
|
"zyMatchDupDistance": 0,
|
||||||
"zSwapHighRes": False,
|
"zSwapHighRes": False,
|
||||||
"zSwapLongLength": False,
|
"zSwapLongLength": False,
|
||||||
"zSwapBetterBitRate": False,
|
"zSwapBetterBitRate": False,
|
||||||
"zSwapCodec": False,
|
"zSwapCodec": False,
|
||||||
"zSwapBetterFrameRate": False,
|
"zSwapBetterFrameRate": False,
|
||||||
"zWhitelist": "",
|
|
||||||
"zxGraylist": "",
|
|
||||||
"zyBlacklist": "",
|
|
||||||
"zyMatchDupDistance": 0,
|
|
||||||
"zyMaxDupToProcess": 0,
|
|
||||||
"zzDebug": False,
|
|
||||||
"zzTracing": False,
|
|
||||||
}
|
}
|
||||||
stash = StashPluginHelper(
|
stash = StashPluginHelper(
|
||||||
stash_url=parse_args.stash_url,
|
stash_url=parse_args.stash_url,
|
||||||
@@ -46,23 +59,53 @@ stash = StashPluginHelper(
|
|||||||
DebugFieldName="zzDebug",
|
DebugFieldName="zzDebug",
|
||||||
)
|
)
|
||||||
stash.convertToAscii = True
|
stash.convertToAscii = True
|
||||||
doJsonReturnModeTypes = ["tag_duplicates_task", "removeDupTag", "addExcludeTag", "removeExcludeTag", "mergeTags", "getLocalDupReportPath", "createDuplicateReportWithoutTagging", "deleteLocalDupReportHtmlFiles"]
|
|
||||||
|
advanceMenuOptions = [ "pathToDelete", "pathToDeleteBlacklist", "sizeToDeleteLess", "sizeToDeleteGreater", "sizeToDeleteBlacklistLess", "sizeToDeleteBlacklistGreater", "durationToDeleteLess", "durationToDeleteGreater", "durationToDeleteBlacklistLess", "durationToDeleteBlacklistGreater",
|
||||||
|
"commonResToDeleteLess", "commonResToDeleteEq", "commonResToDeleteGreater", "commonResToDeleteBlacklistLess", "commonResToDeleteBlacklistEq", "commonResToDeleteBlacklistGreater", "resolutionToDeleteLess", "resolutionToDeleteEq", "resolutionToDeleteGreater",
|
||||||
|
"resolutionToDeleteBlacklistLess", "resolutionToDeleteBlacklistEq", "resolutionToDeleteBlacklistGreater", "ratingToDeleteLess", "ratingToDeleteEq", "ratingToDeleteGreater", "ratingToDeleteBlacklistLess", "ratingToDeleteBlacklistEq", "ratingToDeleteBlacklistGreater",
|
||||||
|
"tagToDelete", "tagToDeleteBlacklist", "titleToDelete", "titleToDeleteBlacklist", "pathStrToDelete", "pathStrToDeleteBlacklist"]
|
||||||
|
|
||||||
|
doJsonReturnModeTypes = ["tag_duplicates_task", "removeDupTag", "addExcludeTag", "removeExcludeTag", "mergeTags", "getLocalDupReportPath",
|
||||||
|
"createDuplicateReportWithoutTagging", "deleteLocalDupReportHtmlFiles", "clear_duplicate_tags_task",
|
||||||
|
"deleteAllDupFileManagerTags", "deleteBlackListTaggedDuplicatesTask", "deleteTaggedDuplicatesLwrResOrLwrDuration",
|
||||||
|
"deleteBlackListTaggedDuplicatesLwrResOrLwrDuration"]
|
||||||
|
doJsonReturnModeTypes += [advanceMenuOptions]
|
||||||
doJsonReturn = False
|
doJsonReturn = False
|
||||||
if stash.PLUGIN_TASK_NAME in doJsonReturnModeTypes:
|
if len(sys.argv) < 2 and stash.PLUGIN_TASK_NAME in doJsonReturnModeTypes:
|
||||||
doJsonReturn = True
|
doJsonReturn = True
|
||||||
stash.log_to_norm = stash.LogTo.FILE
|
stash.log_to_norm = stash.LogTo.FILE
|
||||||
|
elif stash.PLUGIN_TASK_NAME == "doEarlyExit":
|
||||||
|
time.sleep(3)
|
||||||
|
stash.Log("Doing early exit because of task name")
|
||||||
|
time.sleep(3)
|
||||||
|
exit(0)
|
||||||
|
|
||||||
stash.Log("******************* Starting *******************")
|
stash.Log("******************* Starting *******************")
|
||||||
if len(sys.argv) > 1:
|
if len(sys.argv) > 1:
|
||||||
stash.Log(f"argv = {sys.argv}")
|
stash.Log(f"argv = {sys.argv}")
|
||||||
else:
|
else:
|
||||||
stash.Trace(f"No command line arguments. JSON_INPUT['args'] = {stash.JSON_INPUT['args']}; PLUGIN_TASK_NAME = {stash.PLUGIN_TASK_NAME}")
|
stash.Debug(f"No command line arguments. JSON_INPUT['args'] = {stash.JSON_INPUT['args']}; PLUGIN_TASK_NAME = {stash.PLUGIN_TASK_NAME}; argv = {sys.argv}")
|
||||||
stash.status(logLevel=logging.DEBUG)
|
stash.status(logLevel=logging.DEBUG)
|
||||||
|
|
||||||
|
|
||||||
# stash.Trace(f"\nStarting (__file__={__file__}) (stash.CALLED_AS_STASH_PLUGIN={stash.CALLED_AS_STASH_PLUGIN}) (stash.DEBUG_TRACING={stash.DEBUG_TRACING}) (stash.PLUGIN_TASK_NAME={stash.PLUGIN_TASK_NAME})************************************************")
|
# stash.Trace(f"\nStarting (__file__={__file__}) (stash.CALLED_AS_STASH_PLUGIN={stash.CALLED_AS_STASH_PLUGIN}) (stash.DEBUG_TRACING={stash.DEBUG_TRACING}) (stash.PLUGIN_TASK_NAME={stash.PLUGIN_TASK_NAME})************************************************")
|
||||||
# stash.encodeToUtf8 = True
|
# stash.encodeToUtf8 = True
|
||||||
|
|
||||||
|
# ToDo: Remove below commented out lines of code
|
||||||
|
# Test code that should be deleted after testing is complete
|
||||||
|
# stash.configure_plugin(stash.PLUGIN_ID, {"zSwapHighRes" : True})
|
||||||
|
# stash.configure_plugin(stash.PLUGIN_ID, {"zSwapLongLength" : True})
|
||||||
|
# stash.configure_plugin(stash.PLUGIN_ID, {"zSwapBetterFrameRate" : True})
|
||||||
|
# stash.configure_plugin(stash.PLUGIN_ID, {"zzObsoleteSettingsCheckVer2" : False})
|
||||||
|
# stash.configure_plugin(stash.PLUGIN_ID, {"zSwapBetterBitRate" : True})
|
||||||
|
# stash.configure_plugin(stash.PLUGIN_ID, {"zSwapCodec" : True})
|
||||||
|
# stash.configure_plugin(stash.PLUGIN_ID, {"zyMatchDupDistance" : 1})
|
||||||
|
# stash.configure_plugin(stash.PLUGIN_ID, {"zySwapCodec" : True})
|
||||||
|
# stash.configure_plugin(stash.PLUGIN_ID, {"zxGraylist" : "B:\\_\\"})
|
||||||
|
# exit(0)
|
||||||
|
|
||||||
|
obsoleteSettingsToConvert = {"zWhitelist" : "zvWhitelist", "zxGraylist" : "zwGraylist", "zyBlacklist" : "zxBlacklist", "zyMatchDupDistance" : "matchDupDistance", "zSwapHighRes" : "zySwapHighRes", "zSwapLongLength" : "zySwapLongLength", "zSwapBetterBitRate" : "zySwapBetterBitRate", "zSwapCodec" : "zySwapCodec", "zSwapBetterFrameRate" : "zySwapBetterFrameRate"}
|
||||||
|
stash.replaceObsoleteSettings(obsoleteSettingsToConvert, "zzObsoleteSettingsCheckVer2")
|
||||||
|
|
||||||
|
|
||||||
LOG_STASH_N_PLUGIN = stash.LogTo.STASH if stash.CALLED_AS_STASH_PLUGIN else stash.LogTo.CONSOLE + stash.LogTo.FILE
|
LOG_STASH_N_PLUGIN = stash.LogTo.STASH if stash.CALLED_AS_STASH_PLUGIN else stash.LogTo.CONSOLE + stash.LogTo.FILE
|
||||||
listSeparator = stash.Setting('listSeparator', ',', notEmpty=True)
|
listSeparator = stash.Setting('listSeparator', ',', notEmpty=True)
|
||||||
@@ -79,11 +122,11 @@ significantTimeDiff = stash.Setting('significantTimeDiff')
|
|||||||
toRecycleBeforeSwap = stash.Setting('toRecycleBeforeSwap')
|
toRecycleBeforeSwap = stash.Setting('toRecycleBeforeSwap')
|
||||||
cleanAfterDel = stash.Setting('cleanAfterDel')
|
cleanAfterDel = stash.Setting('cleanAfterDel')
|
||||||
|
|
||||||
swapHighRes = stash.Setting('zSwapHighRes')
|
swapHighRes = stash.Setting('zySwapHighRes')
|
||||||
swapLongLength = stash.Setting('zSwapLongLength')
|
swapLongLength = stash.Setting('zySwapLongLength')
|
||||||
swapBetterBitRate = stash.Setting('zSwapBetterBitRate')
|
swapBetterBitRate = stash.Setting('zySwapBetterBitRate')
|
||||||
swapCodec = stash.Setting('zSwapCodec')
|
swapCodec = stash.Setting('zySwapCodec')
|
||||||
swapBetterFrameRate = stash.Setting('zSwapBetterFrameRate')
|
swapBetterFrameRate = stash.Setting('zySwapBetterFrameRate')
|
||||||
favorLongerFileName = stash.Setting('favorLongerFileName')
|
favorLongerFileName = stash.Setting('favorLongerFileName')
|
||||||
favorLargerFileSize = stash.Setting('favorLargerFileSize')
|
favorLargerFileSize = stash.Setting('favorLargerFileSize')
|
||||||
favorBitRateChange = stash.Setting('favorBitRateChange')
|
favorBitRateChange = stash.Setting('favorBitRateChange')
|
||||||
@@ -106,7 +149,7 @@ tagLongDurationLowRes = stash.Setting('tagLongDurationLowRes')
|
|||||||
bitRateIsImporantComp = stash.Setting('bitRateIsImporantComp')
|
bitRateIsImporantComp = stash.Setting('bitRateIsImporantComp')
|
||||||
codecIsImporantComp = stash.Setting('codecIsImporantComp')
|
codecIsImporantComp = stash.Setting('codecIsImporantComp')
|
||||||
|
|
||||||
matchDupDistance = int(stash.Setting('zyMatchDupDistance'))
|
matchDupDistance = int(stash.Setting('matchDupDistance'))
|
||||||
matchPhaseDistance = PhashDistance.EXACT
|
matchPhaseDistance = PhashDistance.EXACT
|
||||||
matchPhaseDistanceText = "Exact Match"
|
matchPhaseDistanceText = "Exact Match"
|
||||||
if matchDupDistance == 1:
|
if matchDupDistance == 1:
|
||||||
@@ -130,7 +173,7 @@ duplicateMarkForDeletion = stash.Setting('DupFileTag')
|
|||||||
if duplicateMarkForDeletion == "":
|
if duplicateMarkForDeletion == "":
|
||||||
duplicateMarkForDeletion = 'DuplicateMarkForDeletion'
|
duplicateMarkForDeletion = 'DuplicateMarkForDeletion'
|
||||||
|
|
||||||
base1_duplicateWhitelistTag = duplicateMarkForDeletion
|
base1_duplicateMarkForDeletion = duplicateMarkForDeletion
|
||||||
|
|
||||||
duplicateWhitelistTag = stash.Setting('DupWhiteListTag')
|
duplicateWhitelistTag = stash.Setting('DupWhiteListTag')
|
||||||
if duplicateWhitelistTag == "":
|
if duplicateWhitelistTag == "":
|
||||||
@@ -160,7 +203,7 @@ if stash.Setting('underscoreDupFileTag') and not duplicateMarkForDeletion.starts
|
|||||||
else:
|
else:
|
||||||
stash.Trace(f"duplicateMarkForDeletion = {duplicateMarkForDeletion}")
|
stash.Trace(f"duplicateMarkForDeletion = {duplicateMarkForDeletion}")
|
||||||
|
|
||||||
base2_duplicateWhitelistTag = duplicateMarkForDeletion
|
base2_duplicateMarkForDeletion = duplicateMarkForDeletion
|
||||||
|
|
||||||
if stash.Setting('appendMatchDupDistance'):
|
if stash.Setting('appendMatchDupDistance'):
|
||||||
duplicateMarkForDeletion += f"_{matchDupDistance}"
|
duplicateMarkForDeletion += f"_{matchDupDistance}"
|
||||||
@@ -168,15 +211,15 @@ if stash.Setting('appendMatchDupDistance'):
|
|||||||
|
|
||||||
stash.initMergeMetadata(excludeMergeTags)
|
stash.initMergeMetadata(excludeMergeTags)
|
||||||
|
|
||||||
graylist = stash.Setting('zxGraylist').split(listSeparator)
|
graylist = stash.Setting('zwGraylist').split(listSeparator)
|
||||||
graylist = [item.lower() for item in graylist]
|
graylist = [item.lower() for item in graylist]
|
||||||
if graylist == [""] : graylist = []
|
if graylist == [""] : graylist = []
|
||||||
stash.Trace(f"graylist = {graylist}")
|
stash.Trace(f"graylist = {graylist}")
|
||||||
whitelist = stash.Setting('zWhitelist').split(listSeparator)
|
whitelist = stash.Setting('zvWhitelist').split(listSeparator)
|
||||||
whitelist = [item.lower() for item in whitelist]
|
whitelist = [item.lower() for item in whitelist]
|
||||||
if whitelist == [""] : whitelist = []
|
if whitelist == [""] : whitelist = []
|
||||||
stash.Trace(f"whitelist = {whitelist}")
|
stash.Trace(f"whitelist = {whitelist}")
|
||||||
blacklist = stash.Setting('zyBlacklist').split(listSeparator)
|
blacklist = stash.Setting('zxBlacklist').split(listSeparator)
|
||||||
blacklist = [item.lower() for item in blacklist]
|
blacklist = [item.lower() for item in blacklist]
|
||||||
if blacklist == [""] : blacklist = []
|
if blacklist == [""] : blacklist = []
|
||||||
stash.Trace(f"blacklist = {blacklist}")
|
stash.Trace(f"blacklist = {blacklist}")
|
||||||
@@ -457,9 +500,12 @@ def getPath(Scene, getParent = False):
|
|||||||
return pathlib.Path(path).resolve().parent
|
return pathlib.Path(path).resolve().parent
|
||||||
return path
|
return path
|
||||||
|
|
||||||
def getHtmlReportTableRow(qtyResults):
|
def getHtmlReportTableRow(qtyResults, tagDuplicates):
|
||||||
htmlReportPrefix = stash.Setting('htmlReportPrefix')
|
htmlReportPrefix = stash.Setting('htmlReportPrefix')
|
||||||
|
htmlReportPrefix = htmlReportPrefix.replace('http://127.0.0.1:9999/graphql', stash.url)
|
||||||
htmlReportPrefix = htmlReportPrefix.replace('http://localhost:9999/graphql', stash.url)
|
htmlReportPrefix = htmlReportPrefix.replace('http://localhost:9999/graphql', stash.url)
|
||||||
|
if tagDuplicates == False:
|
||||||
|
htmlReportPrefix = htmlReportPrefix.replace('name="AdvanceMenu"', "hidden")
|
||||||
htmlReportPrefix = htmlReportPrefix.replace('(QtyPlaceHolder)', f'{qtyResults}')
|
htmlReportPrefix = htmlReportPrefix.replace('(QtyPlaceHolder)', f'{qtyResults}')
|
||||||
htmlReportPrefix = htmlReportPrefix.replace('(MatchTypePlaceHolder)', f'(Match Type = {matchPhaseDistanceText})')
|
htmlReportPrefix = htmlReportPrefix.replace('(MatchTypePlaceHolder)', f'(Match Type = {matchPhaseDistanceText})')
|
||||||
htmlReportPrefix = htmlReportPrefix.replace('(DateCreatedPlaceHolder)', datetime.now().strftime("%d-%b-%Y, %H:%M:%S"))
|
htmlReportPrefix = htmlReportPrefix.replace('(DateCreatedPlaceHolder)', datetime.now().strftime("%d-%b-%Y, %H:%M:%S"))
|
||||||
@@ -490,7 +536,7 @@ def logReason(DupFileToKeep, Scene, reason):
|
|||||||
|
|
||||||
htmlReportName = f"{stash.PLUGINS_PATH}{os.sep}{stash.Setting('htmlReportName')}"
|
htmlReportName = f"{stash.PLUGINS_PATH}{os.sep}{stash.Setting('htmlReportName')}"
|
||||||
|
|
||||||
def mangeDupFiles(merge=False, deleteDup=False, tagDuplicates=False):
|
def mangeDupFiles(merge=False, deleteDup=False, tagDuplicates=False, deleteBlacklistOnly=False, deleteLowerResAndDuration=False):
|
||||||
global reasonDict
|
global reasonDict
|
||||||
duplicateMarkForDeletion_descp = 'Tag added to duplicate scenes so-as to tag them for deletion.'
|
duplicateMarkForDeletion_descp = 'Tag added to duplicate scenes so-as to tag them for deletion.'
|
||||||
stash.Trace(f"duplicateMarkForDeletion = {duplicateMarkForDeletion}")
|
stash.Trace(f"duplicateMarkForDeletion = {duplicateMarkForDeletion}")
|
||||||
@@ -536,8 +582,9 @@ def mangeDupFiles(merge=False, deleteDup=False, tagDuplicates=False):
|
|||||||
stash.Log(f"Found {qtyResults} duplicate sets...")
|
stash.Log(f"Found {qtyResults} duplicate sets...")
|
||||||
fileHtmlReport = None
|
fileHtmlReport = None
|
||||||
if createHtmlReport:
|
if createHtmlReport:
|
||||||
|
deleteLocalDupReportHtmlFiles(False)
|
||||||
fileHtmlReport = open(htmlReportName, "w")
|
fileHtmlReport = open(htmlReportName, "w")
|
||||||
fileHtmlReport.write(f"{getHtmlReportTableRow(qtyResults)}\n")
|
fileHtmlReport.write(f"{getHtmlReportTableRow(qtyResults, tagDuplicates)}\n")
|
||||||
fileHtmlReport.write(f"{stash.Setting('htmlReportTable')}\n")
|
fileHtmlReport.write(f"{stash.Setting('htmlReportTable')}\n")
|
||||||
htmlReportTableHeader = stash.Setting('htmlReportTableHeader')
|
htmlReportTableHeader = stash.Setting('htmlReportTableHeader')
|
||||||
fileHtmlReport.write(f"{htmlReportTableRow}{htmlReportTableHeader}Scene</th>{htmlReportTableHeader}Duplicate to Delete</th>{htmlReportTableHeader}Scene-ToKeep</th>{htmlReportTableHeader}Duplicate to Keep</th></tr>\n")
|
fileHtmlReport.write(f"{htmlReportTableRow}{htmlReportTableHeader}Scene</th>{htmlReportTableHeader}Duplicate to Delete</th>{htmlReportTableHeader}Scene-ToKeep</th>{htmlReportTableHeader}Duplicate to Keep</th></tr>\n")
|
||||||
@@ -656,8 +703,10 @@ def mangeDupFiles(merge=False, deleteDup=False, tagDuplicates=False):
|
|||||||
else:
|
else:
|
||||||
# ToDo: Add merge logic here
|
# ToDo: Add merge logic here
|
||||||
if deleteDup:
|
if deleteDup:
|
||||||
QtyDeleted += 1
|
|
||||||
DupFileName = DupFile['files'][0]['path']
|
DupFileName = DupFile['files'][0]['path']
|
||||||
|
if not deleteBlacklistOnly or stash.startsWithInList(blacklist, DupFile['files'][0]['path']):
|
||||||
|
if not deleteLowerResAndDuration or (isBetterVideo(DupFile, DupFileToKeep) and not significantMoreTimeCompareToBetterVideo(DupFileToKeep, DupFile)) or (significantMoreTimeCompareToBetterVideo(DupFile, DupFileToKeep) and not isBetterVideo(DupFileToKeep, DupFile)):
|
||||||
|
QtyDeleted += 1
|
||||||
DupFileNameOnly = pathlib.Path(DupFileName).stem
|
DupFileNameOnly = pathlib.Path(DupFileName).stem
|
||||||
stash.Warn(f"Deleting duplicate '{DupFileName}';QtyDup={QtyDup};Set={QtyDupSet} of {qtyResults};QtyDeleted={QtyDeleted}", toAscii=True, printTo=LOG_STASH_N_PLUGIN)
|
stash.Warn(f"Deleting duplicate '{DupFileName}';QtyDup={QtyDup};Set={QtyDupSet} of {qtyResults};QtyDeleted={QtyDeleted}", toAscii=True, printTo=LOG_STASH_N_PLUGIN)
|
||||||
if alternateTrashCanPath != "":
|
if alternateTrashCanPath != "":
|
||||||
@@ -755,7 +804,7 @@ def mangeDupFiles(merge=False, deleteDup=False, tagDuplicates=False):
|
|||||||
fileHtmlReport.close()
|
fileHtmlReport.close()
|
||||||
PaginateId+=1
|
PaginateId+=1
|
||||||
fileHtmlReport = open(nextHtmReport, "w")
|
fileHtmlReport = open(nextHtmReport, "w")
|
||||||
fileHtmlReport.write(f"{getHtmlReportTableRow(qtyResults)}\n")
|
fileHtmlReport.write(f"{getHtmlReportTableRow(qtyResults, tagDuplicates)}\n")
|
||||||
if PaginateId > 1:
|
if PaginateId > 1:
|
||||||
prevHtmReport = htmlReportNameHomePage.replace(".html", f"_{PaginateId-1}.html")
|
prevHtmReport = htmlReportNameHomePage.replace(".html", f"_{PaginateId-1}.html")
|
||||||
else:
|
else:
|
||||||
@@ -781,7 +830,7 @@ def mangeDupFiles(merge=False, deleteDup=False, tagDuplicates=False):
|
|||||||
didAddTag = 1 if didAddTag else 0
|
didAddTag = 1 if didAddTag else 0
|
||||||
stash.Log(f"Tagging duplicate {DupFile['files'][0]['path']} for deletion;AddTag={didAddTag};Qty={QtyDup};Set={QtyDupSet} of {qtyResults};NewlyTag={QtyNewlyTag};isTag={QtyTagForDel}", toAscii=True, printTo=LOG_STASH_N_PLUGIN)
|
stash.Log(f"Tagging duplicate {DupFile['files'][0]['path']} for deletion;AddTag={didAddTag};Qty={QtyDup};Set={QtyDupSet} of {qtyResults};NewlyTag={QtyNewlyTag};isTag={QtyTagForDel}", toAscii=True, printTo=LOG_STASH_N_PLUGIN)
|
||||||
stash.Trace(SepLine)
|
stash.Trace(SepLine)
|
||||||
if maxDupToProcess > 0 and QtyDup > maxDupToProcess:
|
if maxDupToProcess > 0 and ((QtyTagForDel > maxDupToProcess) or (QtyTagForDel == 0 and QtyDup > maxDupToProcess)):
|
||||||
break
|
break
|
||||||
|
|
||||||
if fileHtmlReport != None:
|
if fileHtmlReport != None:
|
||||||
@@ -818,14 +867,9 @@ def mangeDupFiles(merge=False, deleteDup=False, tagDuplicates=False):
|
|||||||
# Delete all DupFileManager created tags
|
# Delete all DupFileManager created tags
|
||||||
fileHtmlReport.write(f"{stash.Setting('htmlReportPostfix')}")
|
fileHtmlReport.write(f"{stash.Setting('htmlReportPostfix')}")
|
||||||
fileHtmlReport.close()
|
fileHtmlReport.close()
|
||||||
# ToDo: Add a better working method to open HTML page htmlReportName
|
|
||||||
stash.Log(f"Opening web page {htmlReportName}")
|
|
||||||
import webbrowser
|
|
||||||
webbrowser.open(htmlReportName, new=2, autoraise=True)
|
|
||||||
os.system(f"start file://{htmlReportName}")
|
|
||||||
stash.Log(f"************************************************************", printTo = stash.LogTo.STASH)
|
stash.Log(f"************************************************************", printTo = stash.LogTo.STASH)
|
||||||
stash.Log(f"************************************************************", printTo = stash.LogTo.STASH)
|
stash.Log(f"************************************************************", printTo = stash.LogTo.STASH)
|
||||||
stash.Log(f"View Stash duplicate report using the following link: file://{htmlReportName}", printTo = stash.LogTo.STASH)
|
stash.Log(f"View Stash duplicate report using Stash->Settings->Tools->[Duplicate File Report]", printTo = stash.LogTo.STASH)
|
||||||
stash.Log(f"************************************************************", printTo = stash.LogTo.STASH)
|
stash.Log(f"************************************************************", printTo = stash.LogTo.STASH)
|
||||||
stash.Log(f"************************************************************", printTo = stash.LogTo.STASH)
|
stash.Log(f"************************************************************", printTo = stash.LogTo.STASH)
|
||||||
|
|
||||||
@@ -843,16 +887,57 @@ def mangeDupFiles(merge=False, deleteDup=False, tagDuplicates=False):
|
|||||||
sys.stdout.write("Report complete")
|
sys.stdout.write("Report complete")
|
||||||
|
|
||||||
def findCurrentTagId(tagNames):
|
def findCurrentTagId(tagNames):
|
||||||
tagNames = [i for n, i in enumerate(tagNames) if i not in tagNames[:n]]
|
# tagNames = [i for n, i in enumerate(tagNames) if i not in tagNames[:n]]
|
||||||
for tagName in tagNames:
|
for tagName in tagNames:
|
||||||
tagId = stash.find_tags(q=tagName)
|
tagId = stash.find_tags(q=tagName)
|
||||||
if len(tagId) > 0 and 'id' in tagId[0]:
|
if len(tagId) > 0 and 'id' in tagId[0]:
|
||||||
stash.Debug("Using tag name {tagName} with Tag ID {tagId[0]['id']}")
|
stash.Debug(f"Using tag name {tagName} with Tag ID {tagId[0]['id']}")
|
||||||
return tagId[0]['id']
|
return tagId[0]['id']
|
||||||
return "-1"
|
return "-1"
|
||||||
|
|
||||||
def manageTagggedDuplicates(deleteScenes=False, clearTag=False, setGrayListTag=False):
|
def getAdvanceMenuOptionSelected():
|
||||||
tagId = findCurrentTagId([duplicateMarkForDeletion, base1_duplicateWhitelistTag, base2_duplicateWhitelistTag, 'DuplicateMarkForDeletion', '_DuplicateMarkForDeletion'])
|
isBlackList = False
|
||||||
|
pathToDelete = ""
|
||||||
|
sizeToDelete = -1
|
||||||
|
durationToDelete = -1
|
||||||
|
resolutionToDelete = -1
|
||||||
|
ratingToDelete = -1
|
||||||
|
tagToDelete = ""
|
||||||
|
titleToDelete = ""
|
||||||
|
pathStrToDelete = ""
|
||||||
|
compareToLess = False
|
||||||
|
compareToGreater = False
|
||||||
|
if 'Target' in stash.JSON_INPUT['args']:
|
||||||
|
if "Blacklist" in stash.PLUGIN_TASK_NAME:
|
||||||
|
isBlackList = True
|
||||||
|
if "Less" in stash.PLUGIN_TASK_NAME:
|
||||||
|
compareToLess = True
|
||||||
|
if "Greater" in stash.PLUGIN_TASK_NAME:
|
||||||
|
compareToGreater = True
|
||||||
|
|
||||||
|
if "pathToDelete" in stash.PLUGIN_TASK_NAME:
|
||||||
|
pathToDelete = stash.JSON_INPUT['args']['Target'].lower()
|
||||||
|
elif "sizeToDelete" in stash.PLUGIN_TASK_NAME:
|
||||||
|
sizeToDelete = int(stash.JSON_INPUT['args']['Target'])
|
||||||
|
elif "durationToDelete" in stash.PLUGIN_TASK_NAME:
|
||||||
|
durationToDelete = int(stash.JSON_INPUT['args']['Target'])
|
||||||
|
elif "commonResToDelete" in stash.PLUGIN_TASK_NAME:
|
||||||
|
resolutionToDelete = int(stash.JSON_INPUT['args']['Target'])
|
||||||
|
elif "resolutionToDelete" in stash.PLUGIN_TASK_NAME:
|
||||||
|
resolutionToDelete = int(stash.JSON_INPUT['args']['Target'])
|
||||||
|
elif "ratingToDelete" in stash.PLUGIN_TASK_NAME:
|
||||||
|
ratingToDelete = int(stash.JSON_INPUT['args']['Target']) * 20
|
||||||
|
elif "tagToDelete" in stash.PLUGIN_TASK_NAME:
|
||||||
|
tagToDelete = stash.JSON_INPUT['args']['Target'].lower()
|
||||||
|
elif "titleToDelete" in stash.PLUGIN_TASK_NAME:
|
||||||
|
titleToDelete = stash.JSON_INPUT['args']['Target'].lower()
|
||||||
|
elif "pathStrToDelete" in stash.PLUGIN_TASK_NAME:
|
||||||
|
pathStrToDelete = stash.JSON_INPUT['args']['Target'].lower()
|
||||||
|
return isBlackList, pathToDelete, sizeToDelete, durationToDelete, resolutionToDelete, ratingToDelete, tagToDelete, titleToDelete, pathStrToDelete, compareToLess, compareToGreater
|
||||||
|
|
||||||
|
def manageTagggedDuplicates(deleteScenes=False, clearTag=False, setGrayListTag=False, tagId=-1, advanceMenuOptionSelected=False):
|
||||||
|
if tagId == -1:
|
||||||
|
tagId = findCurrentTagId([duplicateMarkForDeletion, base1_duplicateMarkForDeletion, base2_duplicateMarkForDeletion, 'DuplicateMarkForDeletion', '_DuplicateMarkForDeletion'])
|
||||||
if int(tagId) < 0:
|
if int(tagId) < 0:
|
||||||
stash.Warn(f"Could not find tag ID for tag '{duplicateMarkForDeletion}'.")
|
stash.Warn(f"Could not find tag ID for tag '{duplicateMarkForDeletion}'.")
|
||||||
return
|
return
|
||||||
@@ -861,6 +946,20 @@ def manageTagggedDuplicates(deleteScenes=False, clearTag=False, setGrayListTag=F
|
|||||||
if clearAllDupfileManagerTags:
|
if clearAllDupfileManagerTags:
|
||||||
excludedTags = [duplicateMarkForDeletion, duplicateWhitelistTag, excludeDupFileDeleteTag, graylistMarkForDeletion, longerDurationLowerResolution]
|
excludedTags = [duplicateMarkForDeletion, duplicateWhitelistTag, excludeDupFileDeleteTag, graylistMarkForDeletion, longerDurationLowerResolution]
|
||||||
|
|
||||||
|
isBlackList = False
|
||||||
|
pathToDelete = ""
|
||||||
|
sizeToDelete = -1
|
||||||
|
durationToDelete = -1
|
||||||
|
resolutionToDelete = -1
|
||||||
|
ratingToDelete = -1
|
||||||
|
tagToDelete = ""
|
||||||
|
titleToDelete = ""
|
||||||
|
pathStrToDelete = ""
|
||||||
|
compareToLess = False
|
||||||
|
compareToGreater = False
|
||||||
|
if advanceMenuOptionSelected:
|
||||||
|
isBlackList, pathToDelete, sizeToDelete, durationToDelete, resolutionToDelete, ratingToDelete, tagToDelete, titleToDelete, pathStrToDelete, compareToLess, compareToGreater = getAdvanceMenuOptionSelected()
|
||||||
|
|
||||||
QtyDup = 0
|
QtyDup = 0
|
||||||
QtyDeleted = 0
|
QtyDeleted = 0
|
||||||
QtyClearedTags = 0
|
QtyClearedTags = 0
|
||||||
@@ -868,7 +967,7 @@ def manageTagggedDuplicates(deleteScenes=False, clearTag=False, setGrayListTag=F
|
|||||||
QtyFailedQuery = 0
|
QtyFailedQuery = 0
|
||||||
stash.Debug("#########################################################################")
|
stash.Debug("#########################################################################")
|
||||||
stash.startSpinningProcessBar()
|
stash.startSpinningProcessBar()
|
||||||
scenes = stash.find_scenes(f={"tags": {"value":tagId, "modifier":"INCLUDES"}}, fragment='id tags {id name} files {path width height duration size video_codec bit_rate frame_rate} details')
|
scenes = stash.find_scenes(f={"tags": {"value":tagId, "modifier":"INCLUDES"}}, fragment='id tags {id name} files {path width height duration size video_codec bit_rate frame_rate} details title rating100')
|
||||||
stash.stopSpinningProcessBar()
|
stash.stopSpinningProcessBar()
|
||||||
qtyResults = len(scenes)
|
qtyResults = len(scenes)
|
||||||
stash.Log(f"Found {qtyResults} scenes with tag ({duplicateMarkForDeletion})")
|
stash.Log(f"Found {qtyResults} scenes with tag ({duplicateMarkForDeletion})")
|
||||||
@@ -915,6 +1014,80 @@ def manageTagggedDuplicates(deleteScenes=False, clearTag=False, setGrayListTag=F
|
|||||||
elif deleteScenes:
|
elif deleteScenes:
|
||||||
DupFileName = scene['files'][0]['path']
|
DupFileName = scene['files'][0]['path']
|
||||||
DupFileNameOnly = pathlib.Path(DupFileName).stem
|
DupFileNameOnly = pathlib.Path(DupFileName).stem
|
||||||
|
if advanceMenuOptionSelected:
|
||||||
|
if isBlackList:
|
||||||
|
if not stash.startsWithInList(blacklist, scene['files'][0]['path']):
|
||||||
|
continue
|
||||||
|
|
||||||
|
if pathToDelete != "":
|
||||||
|
if not DupFileName.lower().startswith(pathToDelete):
|
||||||
|
stash.Debug(f"Skipping file {DupFileName} because it does not start with {pathToDelete}.")
|
||||||
|
continue
|
||||||
|
elif pathStrToDelete != "":
|
||||||
|
if not pathStrToDelete in DupFileName.lower():
|
||||||
|
stash.Debug(f"Skipping file {DupFileName} because it does not contain value {pathStrToDelete}.")
|
||||||
|
continue
|
||||||
|
elif sizeToDelete != -1:
|
||||||
|
compareTo = int(scene['files'][0]['size'])
|
||||||
|
if compareToLess:
|
||||||
|
if not (compareTo < sizeToDelete):
|
||||||
|
continue
|
||||||
|
elif compareToGreater:
|
||||||
|
if not (compareTo > sizeToDelete):
|
||||||
|
continue
|
||||||
|
else:
|
||||||
|
if not compareTo == sizeToDelete:
|
||||||
|
continue
|
||||||
|
elif durationToDelete != -1:
|
||||||
|
compareTo = int(scene['files'][0]['duration'])
|
||||||
|
if compareToLess:
|
||||||
|
if not (compareTo < durationToDelete):
|
||||||
|
continue
|
||||||
|
elif compareToGreater:
|
||||||
|
if not (compareTo > durationToDelete):
|
||||||
|
continue
|
||||||
|
else:
|
||||||
|
if not compareTo == durationToDelete:
|
||||||
|
continue
|
||||||
|
elif resolutionToDelete != -1:
|
||||||
|
compareTo = int(scene['files'][0]['width']) * int(scene['files'][0]['height'])
|
||||||
|
if compareToLess:
|
||||||
|
if not (compareTo < resolutionToDelete):
|
||||||
|
continue
|
||||||
|
elif compareToGreater:
|
||||||
|
if not (compareTo > resolutionToDelete):
|
||||||
|
continue
|
||||||
|
else:
|
||||||
|
if not compareTo == resolutionToDelete:
|
||||||
|
continue
|
||||||
|
elif ratingToDelete != -1:
|
||||||
|
if scene['rating100'] == "None":
|
||||||
|
compareTo = 0
|
||||||
|
else:
|
||||||
|
compareTo = int(scene['rating100'])
|
||||||
|
if compareToLess:
|
||||||
|
if not (compareTo < resolutionToDelete):
|
||||||
|
continue
|
||||||
|
elif compareToGreater:
|
||||||
|
if not (compareTo > resolutionToDelete):
|
||||||
|
continue
|
||||||
|
else:
|
||||||
|
if not compareTo == resolutionToDelete:
|
||||||
|
continue
|
||||||
|
elif titleToDelete != "":
|
||||||
|
if not titleToDelete in scene['title'].lower():
|
||||||
|
stash.Debug(f"Skipping file {DupFileName} because it does not contain value {titleToDelete} in title ({scene['title']}).")
|
||||||
|
continue
|
||||||
|
elif tagToDelete != "":
|
||||||
|
doProcessThis = False
|
||||||
|
for tag in scene['tags']:
|
||||||
|
if tag['name'].lower() == tagToDelete:
|
||||||
|
doProcessThis = True
|
||||||
|
break
|
||||||
|
if doProcessThis == False:
|
||||||
|
continue
|
||||||
|
else:
|
||||||
|
continue
|
||||||
stash.Warn(f"Deleting duplicate '{DupFileName}'", toAscii=True, printTo=LOG_STASH_N_PLUGIN)
|
stash.Warn(f"Deleting duplicate '{DupFileName}'", toAscii=True, printTo=LOG_STASH_N_PLUGIN)
|
||||||
if alternateTrashCanPath != "":
|
if alternateTrashCanPath != "":
|
||||||
destPath = f"{alternateTrashCanPath }{os.sep}{DupFileNameOnly}"
|
destPath = f"{alternateTrashCanPath }{os.sep}{DupFileNameOnly}"
|
||||||
@@ -932,14 +1105,13 @@ def manageTagggedDuplicates(deleteScenes=False, clearTag=False, setGrayListTag=F
|
|||||||
stash.Debug("#####################################################")
|
stash.Debug("#####################################################")
|
||||||
stash.Log(f"QtyDup={QtyDup}, QtyClearedTags={QtyClearedTags}, QtySetGraylistTag={QtySetGraylistTag}, QtyDeleted={QtyDeleted}, QtyFailedQuery={QtyFailedQuery}", printTo=LOG_STASH_N_PLUGIN)
|
stash.Log(f"QtyDup={QtyDup}, QtyClearedTags={QtyClearedTags}, QtySetGraylistTag={QtySetGraylistTag}, QtyDeleted={QtyDeleted}, QtyFailedQuery={QtyFailedQuery}", printTo=LOG_STASH_N_PLUGIN)
|
||||||
killScanningJobs()
|
killScanningJobs()
|
||||||
if deleteScenes:
|
if deleteScenes and not advanceMenuOptionSelected:
|
||||||
if cleanAfterDel:
|
if cleanAfterDel:
|
||||||
stash.Log("Adding clean jobs to the Task Queue", printTo=LOG_STASH_N_PLUGIN)
|
stash.Log("Adding clean jobs to the Task Queue", printTo=LOG_STASH_N_PLUGIN)
|
||||||
stash.metadata_clean()
|
stash.metadata_clean()
|
||||||
stash.metadata_clean_generated()
|
stash.metadata_clean_generated()
|
||||||
stash.optimise_database()
|
stash.optimise_database()
|
||||||
if doNotGeneratePhash:
|
|
||||||
stash.metadata_generate({"phashes": True})
|
|
||||||
|
|
||||||
def removeDupTag():
|
def removeDupTag():
|
||||||
if 'Target' not in stash.JSON_INPUT['args']:
|
if 'Target' not in stash.JSON_INPUT['args']:
|
||||||
@@ -989,28 +1161,6 @@ def mergeTags():
|
|||||||
stash.Log(f"Done merging scenes for scene {scenes[0]} and scene {scenes[1]}")
|
stash.Log(f"Done merging scenes for scene {scenes[0]} and scene {scenes[1]}")
|
||||||
sys.stdout.write("{" + f"mergeTags : 'complete', id1: '{scene1}', id2: '{scene2}'" + "}")
|
sys.stdout.write("{" + f"mergeTags : 'complete', id1: '{scene1}', id2: '{scene2}'" + "}")
|
||||||
|
|
||||||
def openWebpage():
|
|
||||||
htmlReportName = f"{stash.PLUGINS_PATH}{os.sep}{stash.Setting('htmlReportName')}"
|
|
||||||
stash.Log(f"Opening web page {htmlReportName}")
|
|
||||||
# chromePath = r"C:\Program Files (x86)\Google\Chrome\Application\chrome.exe"
|
|
||||||
chromePath = r"C:\PROGRA~2\Google\Chrome\Application\chrome.exe"
|
|
||||||
firefox = r"C:\PROGRA~1\MOZILL~1\firefox.exe"
|
|
||||||
browserPath = chromePath
|
|
||||||
if os.path.isfile(browserPath):
|
|
||||||
stash.Log(f"Opening web page {htmlReportName} with user {os.getlogin()} using {browserPath}")
|
|
||||||
# pw_record = pwd.getpwnam(os.getlogin())
|
|
||||||
# uid = pw_record.pw_uid
|
|
||||||
# gid = pw_record.pw_gid
|
|
||||||
# os.setgid(gid)
|
|
||||||
# os.setuid(uid)
|
|
||||||
# stash.Log(f"Using uid={uid} and gid={gid}")
|
|
||||||
# stash.executeProcess(f"\"{browserPath}\" -incognito --new-window \"file://{htmlReportName}\"", ExecDetach=True)
|
|
||||||
os.system(f"{browserPath} -incognito --new-window \"file://{htmlReportName}\"")
|
|
||||||
# else:
|
|
||||||
import webbrowser
|
|
||||||
webbrowser.open(htmlReportName, new=2, autoraise=True)
|
|
||||||
os.system(f"start file:///{htmlReportName}")
|
|
||||||
|
|
||||||
def getLocalDupReportPath():
|
def getLocalDupReportPath():
|
||||||
htmlReportExist = "true" if os.path.isfile(htmlReportName) else "false"
|
htmlReportExist = "true" if os.path.isfile(htmlReportName) else "false"
|
||||||
# htmlReportExist = "false"
|
# htmlReportExist = "false"
|
||||||
@@ -1019,7 +1169,7 @@ def getLocalDupReportPath():
|
|||||||
stash.Log(f"Sending json value {jsonReturn}")
|
stash.Log(f"Sending json value {jsonReturn}")
|
||||||
sys.stdout.write(jsonReturn)
|
sys.stdout.write(jsonReturn)
|
||||||
|
|
||||||
def deleteLocalDupReportHtmlFiles():
|
def deleteLocalDupReportHtmlFiles(doJsonOutput = True):
|
||||||
htmlReportExist = "true" if os.path.isfile(htmlReportName) else "false"
|
htmlReportExist = "true" if os.path.isfile(htmlReportName) else "false"
|
||||||
if os.path.isfile(htmlReportName):
|
if os.path.isfile(htmlReportName):
|
||||||
stash.Log(f"Deleting file {htmlReportName}")
|
stash.Log(f"Deleting file {htmlReportName}")
|
||||||
@@ -1033,10 +1183,42 @@ def deleteLocalDupReportHtmlFiles():
|
|||||||
os.remove(fileName)
|
os.remove(fileName)
|
||||||
else:
|
else:
|
||||||
stash.Log(f"Report file does not exist: {htmlReportName}")
|
stash.Log(f"Report file does not exist: {htmlReportName}")
|
||||||
|
if doJsonOutput:
|
||||||
jsonReturn = "{'LocalDupReportExist' : " + f"{htmlReportExist}" + ", 'Path': '" + f"{htmlReportName}" + "', 'qty': '" + f"{x}" + "'}"
|
jsonReturn = "{'LocalDupReportExist' : " + f"{htmlReportExist}" + ", 'Path': '" + f"{htmlReportName}" + "', 'qty': '" + f"{x}" + "'}"
|
||||||
stash.Log(f"Sending json value {jsonReturn}")
|
stash.Log(f"Sending json value {jsonReturn}")
|
||||||
sys.stdout.write(jsonReturn)
|
sys.stdout.write(jsonReturn)
|
||||||
|
|
||||||
|
def removeTagFromAllScenes(tagName, deleteTags):
|
||||||
|
tagId = stash.find_tags(q=tagName)
|
||||||
|
if len(tagId) > 0 and 'id' in tagId[0]:
|
||||||
|
if deleteTags:
|
||||||
|
stash.Debug(f"Deleting tag name {tagName} with Tag ID {tagId[0]['id']} from stash.")
|
||||||
|
stash.destroy_tag(int(tagId[0]['id']))
|
||||||
|
else:
|
||||||
|
stash.Debug(f"Removing tag name {tagName} with Tag ID {tagId[0]['id']} from all scenes.")
|
||||||
|
manageTagggedDuplicates(clearTag=True, tagId=int(tagId[0]['id']))
|
||||||
|
return True
|
||||||
|
return False
|
||||||
|
|
||||||
|
def removeAllDupTagsFromAllScenes(deleteTags=False):
|
||||||
|
tagsToClear = [duplicateMarkForDeletion, base1_duplicateMarkForDeletion, base2_duplicateMarkForDeletion, graylistMarkForDeletion, longerDurationLowerResolution, duplicateWhitelistTag]
|
||||||
|
for x in range(0, 3):
|
||||||
|
tagsToClear += [base1_duplicateMarkForDeletion + f"_{x}"]
|
||||||
|
for x in range(0, 3):
|
||||||
|
tagsToClear += [base2_duplicateMarkForDeletion + f"_{x}"]
|
||||||
|
tagsToClear = list(set(tagsToClear)) # Remove duplicates
|
||||||
|
validTags = []
|
||||||
|
for tagToClear in tagsToClear:
|
||||||
|
if removeTagFromAllScenes(tagToClear, deleteTags):
|
||||||
|
validTags +=[tagToClear]
|
||||||
|
if doJsonReturn:
|
||||||
|
jsonReturn = "{'removeAllDupTagFromAllScenes' : " + f"{duplicateMarkForDeletion}" + ", 'OtherTags': '" + f"{validTags}" + "'}"
|
||||||
|
stash.Log(f"Sending json value {jsonReturn}")
|
||||||
|
sys.stdout.write(jsonReturn)
|
||||||
|
else:
|
||||||
|
stash.Log(f"Clear tags {tagsToClear}")
|
||||||
|
|
||||||
|
|
||||||
# ToDo: Add additional menu items option only for bottom of report:
|
# ToDo: Add additional menu items option only for bottom of report:
|
||||||
# Remove from stash all files no longer part of stash library
|
# Remove from stash all files no longer part of stash library
|
||||||
# Remove from stash all files in the Exclusion list (Not supporting regexps)
|
# Remove from stash all files in the Exclusion list (Not supporting regexps)
|
||||||
@@ -1052,7 +1234,7 @@ try:
|
|||||||
mangeDupFiles(deleteDup=True, merge=mergeDupFilename)
|
mangeDupFiles(deleteDup=True, merge=mergeDupFilename)
|
||||||
stash.Debug(f"{stash.PLUGIN_TASK_NAME} EXIT")
|
stash.Debug(f"{stash.PLUGIN_TASK_NAME} EXIT")
|
||||||
elif stash.PLUGIN_TASK_NAME == "clear_duplicate_tags_task":
|
elif stash.PLUGIN_TASK_NAME == "clear_duplicate_tags_task":
|
||||||
manageTagggedDuplicates(clearTag=True)
|
removeAllDupTagsFromAllScenes()
|
||||||
stash.Debug(f"{stash.PLUGIN_TASK_NAME} EXIT")
|
stash.Debug(f"{stash.PLUGIN_TASK_NAME} EXIT")
|
||||||
elif stash.PLUGIN_TASK_NAME == "graylist_tag_task":
|
elif stash.PLUGIN_TASK_NAME == "graylist_tag_task":
|
||||||
manageTagggedDuplicates(setGrayListTag=True)
|
manageTagggedDuplicates(setGrayListTag=True)
|
||||||
@@ -1081,6 +1263,18 @@ try:
|
|||||||
elif stash.PLUGIN_TASK_NAME == "createDuplicateReportWithoutTagging":
|
elif stash.PLUGIN_TASK_NAME == "createDuplicateReportWithoutTagging":
|
||||||
mangeDupFiles(tagDuplicates=False, merge=mergeDupFilename)
|
mangeDupFiles(tagDuplicates=False, merge=mergeDupFilename)
|
||||||
stash.Debug(f"{stash.PLUGIN_TASK_NAME} EXIT")
|
stash.Debug(f"{stash.PLUGIN_TASK_NAME} EXIT")
|
||||||
|
elif stash.PLUGIN_TASK_NAME == "deleteAllDupFileManagerTags":
|
||||||
|
removeAllDupTagsFromAllScenes(deleteTags=True)
|
||||||
|
stash.Debug(f"{stash.PLUGIN_TASK_NAME} EXIT")
|
||||||
|
elif stash.PLUGIN_TASK_NAME == "deleteBlackListTaggedDuplicatesTask":
|
||||||
|
mangeDupFiles(deleteDup=True, merge=mergeDupFilename, deleteBlacklistOnly=True)
|
||||||
|
stash.Debug(f"{stash.PLUGIN_TASK_NAME} EXIT")
|
||||||
|
elif stash.PLUGIN_TASK_NAME == "deleteTaggedDuplicatesLwrResOrLwrDuration":
|
||||||
|
mangeDupFiles(deleteDup=True, merge=mergeDupFilename, deleteLowerResAndDuration=True)
|
||||||
|
stash.Debug(f"{stash.PLUGIN_TASK_NAME} EXIT")
|
||||||
|
elif stash.PLUGIN_TASK_NAME == "deleteBlackListTaggedDuplicatesLwrResOrLwrDuration":
|
||||||
|
mangeDupFiles(deleteDup=True, merge=mergeDupFilename, deleteBlacklistOnly=True, deleteLowerResAndDuration=True)
|
||||||
|
stash.Debug(f"{stash.PLUGIN_TASK_NAME} EXIT")
|
||||||
elif parse_args.dup_tag:
|
elif parse_args.dup_tag:
|
||||||
stash.PLUGIN_TASK_NAME = "dup_tag"
|
stash.PLUGIN_TASK_NAME = "dup_tag"
|
||||||
mangeDupFiles(tagDuplicates=True, merge=mergeDupFilename)
|
mangeDupFiles(tagDuplicates=True, merge=mergeDupFilename)
|
||||||
@@ -1091,12 +1285,15 @@ try:
|
|||||||
stash.Debug(f"Delete Tagged duplicates EXIT")
|
stash.Debug(f"Delete Tagged duplicates EXIT")
|
||||||
elif parse_args.clear_tag:
|
elif parse_args.clear_tag:
|
||||||
stash.PLUGIN_TASK_NAME = "clear_tag"
|
stash.PLUGIN_TASK_NAME = "clear_tag"
|
||||||
manageTagggedDuplicates(clearTag=True)
|
removeAllDupTagsFromAllScenes()
|
||||||
stash.Debug(f"Clear duplicate tags EXIT")
|
stash.Debug(f"Clear duplicate tags EXIT")
|
||||||
elif parse_args.remove:
|
elif parse_args.remove:
|
||||||
stash.PLUGIN_TASK_NAME = "remove"
|
stash.PLUGIN_TASK_NAME = "remove"
|
||||||
mangeDupFiles(deleteDup=True, merge=mergeDupFilename)
|
mangeDupFiles(deleteDup=True, merge=mergeDupFilename)
|
||||||
stash.Debug(f"Delete duplicate EXIT")
|
stash.Debug(f"Delete duplicate EXIT")
|
||||||
|
elif len(sys.argv) < 2 and stash.PLUGIN_TASK_NAME in advanceMenuOptions:
|
||||||
|
manageTagggedDuplicates(deleteScenes=True, advanceMenuOptionSelected=True)
|
||||||
|
stash.Debug(f"{stash.PLUGIN_TASK_NAME} EXIT")
|
||||||
else:
|
else:
|
||||||
stash.Log(f"Nothing to do!!! (PLUGIN_ARGS_MODE={stash.PLUGIN_TASK_NAME})")
|
stash.Log(f"Nothing to do!!! (PLUGIN_ARGS_MODE={stash.PLUGIN_TASK_NAME})")
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
|
|||||||
@@ -10,6 +10,10 @@ ui:
|
|||||||
- DupFileManager.css.map
|
- DupFileManager.css.map
|
||||||
- DupFileManager.js.map
|
- DupFileManager.js.map
|
||||||
settings:
|
settings:
|
||||||
|
matchDupDistance:
|
||||||
|
displayName: Match Duplicate Distance
|
||||||
|
description: (Default=0) Where 0 = Exact Match, 1 = High Match, 2 = Medium Match, and 3 = Low Match.
|
||||||
|
type: NUMBER
|
||||||
mergeDupFilename:
|
mergeDupFilename:
|
||||||
displayName: Merge Duplicate Tags
|
displayName: Merge Duplicate Tags
|
||||||
description: Before deletion, merge metadata from duplicate. E.g. Tag names, performers, studios, title, galleries, rating, details, etc...
|
description: Before deletion, merge metadata from duplicate. E.g. Tag names, performers, studios, title, galleries, rating, details, etc...
|
||||||
@@ -18,46 +22,42 @@ settings:
|
|||||||
displayName: Whitelist Delete In Same Folder
|
displayName: Whitelist Delete In Same Folder
|
||||||
description: Allow whitelist deletion of duplicates within the same whitelist folder.
|
description: Allow whitelist deletion of duplicates within the same whitelist folder.
|
||||||
type: BOOLEAN
|
type: BOOLEAN
|
||||||
zSwapBetterBitRate:
|
zvWhitelist:
|
||||||
displayName: Swap Better Bit Rate
|
|
||||||
description: Swap better bit rate for duplicate files. Use with DupFileManager_config.py file option favorHighBitRate
|
|
||||||
type: BOOLEAN
|
|
||||||
zSwapBetterFrameRate:
|
|
||||||
displayName: Swap Better Frame Rate
|
|
||||||
description: Swap better frame rate for duplicates. Use with DupFileManager_config.py file option favorHigherFrameRate
|
|
||||||
type: BOOLEAN
|
|
||||||
zSwapCodec:
|
|
||||||
displayName: Swap Better Codec
|
|
||||||
description: If enabled, swap better codec duplicate files to preferred path.
|
|
||||||
type: BOOLEAN
|
|
||||||
zSwapHighRes:
|
|
||||||
displayName: Swap Higher Resolution
|
|
||||||
description: If enabled, swap higher resolution duplicate files to preferred path.
|
|
||||||
type: BOOLEAN
|
|
||||||
zSwapLongLength:
|
|
||||||
displayName: Swap Longer Duration
|
|
||||||
description: If enabled, swap longer duration media files to preferred path. Longer is determine by significantLongerTime field.
|
|
||||||
type: BOOLEAN
|
|
||||||
zWhitelist:
|
|
||||||
displayName: White List
|
displayName: White List
|
||||||
description: A comma seperated list of paths NOT to be deleted. E.g. C:\Favorite\,E:\MustKeep\
|
description: A comma seperated list of paths NOT to be deleted. E.g. C:\Favorite\,E:\MustKeep\
|
||||||
type: STRING
|
type: STRING
|
||||||
zxGraylist:
|
zwGraylist:
|
||||||
displayName: Gray List
|
displayName: Gray List
|
||||||
description: Preferential paths to determine which duplicate should be kept. E.g. C:\2nd_Fav,C:\3rd_Fav,C:\4th_Fav,H:\ShouldKeep
|
description: Preferential paths to determine which duplicate should be kept. E.g. C:\2nd_Fav,C:\3rd_Fav,C:\4th_Fav,H:\ShouldKeep
|
||||||
type: STRING
|
type: STRING
|
||||||
zyBlacklist:
|
zxBlacklist:
|
||||||
displayName: Black List
|
displayName: Black List
|
||||||
description: Least preferential paths; Determine primary deletion candidates. E.g. C:\Downloads,C:\DelMe-3rd,C:\DelMe-2nd,C:\DeleteMeFirst
|
description: Least preferential paths; Determine primary deletion candidates. E.g. C:\Downloads,C:\DelMe-3rd,C:\DelMe-2nd,C:\DeleteMeFirst
|
||||||
type: STRING
|
type: STRING
|
||||||
zyMatchDupDistance:
|
|
||||||
displayName: Match Duplicate Distance
|
|
||||||
description: (Default=0) Where 0 = Exact Match, 1 = High Match, 2 = Medium Match, and 3 = Low Match.
|
|
||||||
type: NUMBER
|
|
||||||
zyMaxDupToProcess:
|
zyMaxDupToProcess:
|
||||||
displayName: Max Dup Process
|
displayName: Max Dup Process
|
||||||
description: (Default=0) Maximum number of duplicates to process. If 0, infinity.
|
description: (Default=0) Maximum number of duplicates to process. If 0, infinity.
|
||||||
type: NUMBER
|
type: NUMBER
|
||||||
|
zySwapBetterBitRate:
|
||||||
|
displayName: Swap Better Bit Rate
|
||||||
|
description: Swap better bit rate for duplicate files. Use with DupFileManager_config.py file option favorHighBitRate
|
||||||
|
type: BOOLEAN
|
||||||
|
zySwapBetterFrameRate:
|
||||||
|
displayName: Swap Better Frame Rate
|
||||||
|
description: Swap better frame rate for duplicates. Use with DupFileManager_config.py file option favorHigherFrameRate
|
||||||
|
type: BOOLEAN
|
||||||
|
zySwapCodec:
|
||||||
|
displayName: Swap Better Codec
|
||||||
|
description: If enabled, swap better codec duplicate files to preferred path.
|
||||||
|
type: BOOLEAN
|
||||||
|
zySwapHighRes:
|
||||||
|
displayName: Swap Higher Resolution
|
||||||
|
description: If enabled, swap higher resolution duplicate files to preferred path.
|
||||||
|
type: BOOLEAN
|
||||||
|
zySwapLongLength:
|
||||||
|
displayName: Swap Longer Duration
|
||||||
|
description: If enabled, swap longer duration media files to preferred path. Longer is determine by significantLongerTime field.
|
||||||
|
type: BOOLEAN
|
||||||
zzDebug:
|
zzDebug:
|
||||||
displayName: Debug
|
displayName: Debug
|
||||||
description: Enable debug so-as to add additional debug logging in Stash\plugins\DupFileManager\DupFileManager.log
|
description: Enable debug so-as to add additional debug logging in Stash\plugins\DupFileManager\DupFileManager.log
|
||||||
@@ -87,11 +87,3 @@ tasks:
|
|||||||
description: Delete duplicate scenes. Performs deletion without first tagging.
|
description: Delete duplicate scenes. Performs deletion without first tagging.
|
||||||
defaultArgs:
|
defaultArgs:
|
||||||
mode: delete_duplicates_task
|
mode: delete_duplicates_task
|
||||||
- name: Generate PHASH Matching
|
|
||||||
description: Generate PHASH file matching. Used for file comparisons.
|
|
||||||
defaultArgs:
|
|
||||||
mode: generate_phash_task
|
|
||||||
- name: Tag Graylist
|
|
||||||
description: Set tag _GraylistMarkForDeletion to scenes having DuplicateMarkForDeletion tag and that are in the Graylist.
|
|
||||||
defaultArgs:
|
|
||||||
mode: graylist_tag_task
|
|
||||||
|
|||||||
@@ -119,7 +119,7 @@ table, th, td {border:1px solid black;}
|
|||||||
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.7.1/jquery.min.js"></script>
|
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.7.1/jquery.min.js"></script>
|
||||||
<script>
|
<script>
|
||||||
function RunPluginDupFileManager(Mode, ActionID, chkBxRemoveValid, button) {
|
function RunPluginDupFileManager(Mode, ActionID, chkBxRemoveValid, button) {
|
||||||
$.ajax({method: "POST", url: "http://127.0.0.1:9999/graphql", contentType: "application/json", dataType: "text",
|
$.ajax({method: "POST", url: "http://localhost:9999/graphql", contentType: "application/json", dataType: "text",
|
||||||
data: JSON.stringify({
|
data: JSON.stringify({
|
||||||
query: `mutation RunPluginOperation($plugin_id:ID!,$args:Map!){runPluginOperation(plugin_id:$plugin_id,args:$args)}`,
|
query: `mutation RunPluginOperation($plugin_id:ID!,$args:Map!){runPluginOperation(plugin_id:$plugin_id,args:$args)}`,
|
||||||
variables: {"plugin_id": "DupFileManager", "args": { "Target" : ActionID, "mode":Mode}},
|
variables: {"plugin_id": "DupFileManager", "args": { "Target" : ActionID, "mode":Mode}},
|
||||||
@@ -139,7 +139,7 @@ $(document).ready(function(){
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
const SceneId = this.id;
|
const SceneId = this.id;
|
||||||
$.ajax({method: "POST", url: "http://127.0.0.1:9999/graphql", contentType: "application/json",
|
$.ajax({method: "POST", url: "http://localhost:9999/graphql", contentType: "application/json",
|
||||||
data: JSON.stringify({
|
data: JSON.stringify({
|
||||||
query: `mutation SceneDestroy($input:SceneDestroyInput!) {sceneDestroy(input: $input)}`,
|
query: `mutation SceneDestroy($input:SceneDestroyInput!) {sceneDestroy(input: $input)}`,
|
||||||
variables: {"input":{"delete_file":true,"id":SceneId}},
|
variables: {"input":{"delete_file":true,"id":SceneId}},
|
||||||
@@ -149,6 +149,12 @@ $(document).ready(function(){
|
|||||||
}});
|
}});
|
||||||
this.style.visibility = 'hidden';
|
this.style.visibility = 'hidden';
|
||||||
}
|
}
|
||||||
|
else if (this.id === "AdvanceMenu")
|
||||||
|
{
|
||||||
|
var newUrl = window.location.href;
|
||||||
|
newUrl = newUrl.replace(/DuplicateTagScenes[_0-9]*.html/g, "DupFileManager/advance_options.html?GQL=http://localhost:9999/graphql");
|
||||||
|
window.open(newUrl, "_blank");
|
||||||
|
}
|
||||||
else
|
else
|
||||||
RunPluginDupFileManager(this.value, this.id, chkBxRemoveValid, this)
|
RunPluginDupFileManager(this.value, this.id, chkBxRemoveValid, this)
|
||||||
});
|
});
|
||||||
@@ -166,6 +172,7 @@ $(document).ready(function(){
|
|||||||
<td><table><tr>
|
<td><table><tr>
|
||||||
<td><input type="checkbox" id="RemoveValidatePrompt" name="RemoveValidatePrompt"><label for="RemoveValidatePrompt" title="Disable Validate Prompts (Popups)">Disable Task Prompt</label><br></td>
|
<td><input type="checkbox" id="RemoveValidatePrompt" name="RemoveValidatePrompt"><label for="RemoveValidatePrompt" title="Disable Validate Prompts (Popups)">Disable Task Prompt</label><br></td>
|
||||||
<td><input type="checkbox" id="RemoveToKeepConfirm" name="RemoveToKeepConfirm"><label for="RemoveToKeepConfirm" title="Disable confirmation prompts for delete scenes">Disable Delete Confirmation</label><br></td>
|
<td><input type="checkbox" id="RemoveToKeepConfirm" name="RemoveToKeepConfirm"><label for="RemoveToKeepConfirm" title="Disable confirmation prompts for delete scenes">Disable Delete Confirmation</label><br></td>
|
||||||
|
<td><button id="AdvanceMenu" title="View advance menu for tagged duplicates." name="AdvanceMenu">Advance Tag Menu</button></td>
|
||||||
</tr></table></td>
|
</tr></table></td>
|
||||||
</tr></table></center>
|
</tr></table></center>
|
||||||
<h2>Stash Duplicate Scenes Report (MatchTypePlaceHolder)</h2>\n""",
|
<h2>Stash Duplicate Scenes Report (MatchTypePlaceHolder)</h2>\n""",
|
||||||
|
|||||||
@@ -421,6 +421,48 @@ class StashPluginHelper(StashInterface):
|
|||||||
self.Log(f"StashPluginHelper Status: (CALLED_AS_STASH_PLUGIN={self.CALLED_AS_STASH_PLUGIN}), (RUNNING_IN_COMMAND_LINE_MODE={self.RUNNING_IN_COMMAND_LINE_MODE}), (DEBUG_TRACING={self.DEBUG_TRACING}), (DRY_RUN={self.DRY_RUN}), (PLUGIN_ID={self.PLUGIN_ID}), (PLUGIN_TASK_NAME={self.PLUGIN_TASK_NAME}), (STASH_URL={self.STASH_URL}), (MAIN_SCRIPT_NAME={self.MAIN_SCRIPT_NAME})",
|
self.Log(f"StashPluginHelper Status: (CALLED_AS_STASH_PLUGIN={self.CALLED_AS_STASH_PLUGIN}), (RUNNING_IN_COMMAND_LINE_MODE={self.RUNNING_IN_COMMAND_LINE_MODE}), (DEBUG_TRACING={self.DEBUG_TRACING}), (DRY_RUN={self.DRY_RUN}), (PLUGIN_ID={self.PLUGIN_ID}), (PLUGIN_TASK_NAME={self.PLUGIN_TASK_NAME}), (STASH_URL={self.STASH_URL}), (MAIN_SCRIPT_NAME={self.MAIN_SCRIPT_NAME})",
|
||||||
printTo, logLevel, lineNo)
|
printTo, logLevel, lineNo)
|
||||||
|
|
||||||
|
# Replaces obsolete UI settings variable with new name. Only use this with strings and numbers.
|
||||||
|
# Example usage:
|
||||||
|
# obsoleteSettingsToConvert = {"OldVariableName" : "NewVariableName", "AnotherOldVarName" : "NewName2"}
|
||||||
|
# stash.replaceObsoleteSettings(obsoleteSettingsToConvert, "ObsoleteSettingsCheckVer2")
|
||||||
|
def replaceObsoleteSettings(self, settingSet:dict, SettingToCheckFirst="", init_defaults=False):
|
||||||
|
if SettingToCheckFirst == "" or self.Setting(SettingToCheckFirst) == False:
|
||||||
|
for key in settingSet:
|
||||||
|
obsoleteVar = self.Setting(key)
|
||||||
|
if isinstance(obsoleteVar, bool):
|
||||||
|
if obsoleteVar:
|
||||||
|
if self.Setting(settingSet[key]) == False:
|
||||||
|
self.Log(f"Detected obsolete (bool) settings ({key}). Moving obsolete settings to new setting name {settingSet[key]}.")
|
||||||
|
results = self.configure_plugin(self.PLUGIN_ID, {settingSet[key]:self.Setting(key), key : False}, init_defaults)
|
||||||
|
self.Debug(f"configure_plugin = {results}")
|
||||||
|
else:
|
||||||
|
self.Log(f"Detected obsolete (bool) settings ({key}), and deleting it's content because new setting name ({settingSet[key]}) is already populated.")
|
||||||
|
results = self.configure_plugin(self.PLUGIN_ID, {key : False}, init_defaults)
|
||||||
|
self.Debug(f"configure_plugin = {results}")
|
||||||
|
elif isinstance(obsoleteVar, int): # Both int and bool type returns true here
|
||||||
|
if obsoleteVar > 0:
|
||||||
|
if self.Setting(settingSet[key]) > 0:
|
||||||
|
self.Log(f"Detected obsolete (int) settings ({key}), and deleting it's content because new setting name ({settingSet[key]}) is already populated.")
|
||||||
|
results = self.configure_plugin(self.PLUGIN_ID, {key : 0}, init_defaults)
|
||||||
|
self.Debug(f"configure_plugin = {results}")
|
||||||
|
else:
|
||||||
|
self.Log(f"Detected obsolete (int) settings ({key}). Moving obsolete settings to new setting name {settingSet[key]}.")
|
||||||
|
results = self.configure_plugin(self.PLUGIN_ID, {settingSet[key]:self.Setting(key), key : 0}, init_defaults)
|
||||||
|
self.Debug(f"configure_plugin = {results}")
|
||||||
|
elif obsoleteVar != "":
|
||||||
|
if self.Setting(settingSet[key]) == "":
|
||||||
|
self.Log(f"Detected obsolete (str) settings ({key}). Moving obsolete settings to new setting name {settingSet[key]}.")
|
||||||
|
results = self.configure_plugin(self.PLUGIN_ID, {settingSet[key]:self.Setting(key), key : ""}, init_defaults)
|
||||||
|
self.Debug(f"configure_plugin = {results}")
|
||||||
|
else:
|
||||||
|
self.Log(f"Detected obsolete (str) settings ({key}), and deleting it's content because new setting name ({settingSet[key]}) is already populated.")
|
||||||
|
results = self.configure_plugin(self.PLUGIN_ID, {key : ""}, init_defaults)
|
||||||
|
self.Debug(f"configure_plugin = {results}")
|
||||||
|
if SettingToCheckFirst != "":
|
||||||
|
results = self.configure_plugin(self.PLUGIN_ID, {SettingToCheckFirst : True}, init_defaults)
|
||||||
|
self.Debug(f"configure_plugin = {results}")
|
||||||
|
|
||||||
|
|
||||||
def executeProcess(self, args, ExecDetach=False):
|
def executeProcess(self, args, ExecDetach=False):
|
||||||
pid = None
|
pid = None
|
||||||
self.Trace(f"self.IS_WINDOWS={self.IS_WINDOWS} args={args}")
|
self.Trace(f"self.IS_WINDOWS={self.IS_WINDOWS} args={args}")
|
||||||
|
|||||||
1667
plugins/DupFileManager/advance_options.html
Normal file
1667
plugins/DupFileManager/advance_options.html
Normal file
File diff suppressed because it is too large
Load Diff
@@ -421,6 +421,48 @@ class StashPluginHelper(StashInterface):
|
|||||||
self.Log(f"StashPluginHelper Status: (CALLED_AS_STASH_PLUGIN={self.CALLED_AS_STASH_PLUGIN}), (RUNNING_IN_COMMAND_LINE_MODE={self.RUNNING_IN_COMMAND_LINE_MODE}), (DEBUG_TRACING={self.DEBUG_TRACING}), (DRY_RUN={self.DRY_RUN}), (PLUGIN_ID={self.PLUGIN_ID}), (PLUGIN_TASK_NAME={self.PLUGIN_TASK_NAME}), (STASH_URL={self.STASH_URL}), (MAIN_SCRIPT_NAME={self.MAIN_SCRIPT_NAME})",
|
self.Log(f"StashPluginHelper Status: (CALLED_AS_STASH_PLUGIN={self.CALLED_AS_STASH_PLUGIN}), (RUNNING_IN_COMMAND_LINE_MODE={self.RUNNING_IN_COMMAND_LINE_MODE}), (DEBUG_TRACING={self.DEBUG_TRACING}), (DRY_RUN={self.DRY_RUN}), (PLUGIN_ID={self.PLUGIN_ID}), (PLUGIN_TASK_NAME={self.PLUGIN_TASK_NAME}), (STASH_URL={self.STASH_URL}), (MAIN_SCRIPT_NAME={self.MAIN_SCRIPT_NAME})",
|
||||||
printTo, logLevel, lineNo)
|
printTo, logLevel, lineNo)
|
||||||
|
|
||||||
|
# Replaces obsolete UI settings variable with new name. Only use this with strings and numbers.
|
||||||
|
# Example usage:
|
||||||
|
# obsoleteSettingsToConvert = {"OldVariableName" : "NewVariableName", "AnotherOldVarName" : "NewName2"}
|
||||||
|
# stash.replaceObsoleteSettings(obsoleteSettingsToConvert, "ObsoleteSettingsCheckVer2")
|
||||||
|
def replaceObsoleteSettings(self, settingSet:dict, SettingToCheckFirst="", init_defaults=False):
|
||||||
|
if SettingToCheckFirst == "" or self.Setting(SettingToCheckFirst) == False:
|
||||||
|
for key in settingSet:
|
||||||
|
obsoleteVar = self.Setting(key)
|
||||||
|
if isinstance(obsoleteVar, bool):
|
||||||
|
if obsoleteVar:
|
||||||
|
if self.Setting(settingSet[key]) == False:
|
||||||
|
self.Log(f"Detected obsolete (bool) settings ({key}). Moving obsolete settings to new setting name {settingSet[key]}.")
|
||||||
|
results = self.configure_plugin(self.PLUGIN_ID, {settingSet[key]:self.Setting(key), key : False}, init_defaults)
|
||||||
|
self.Debug(f"configure_plugin = {results}")
|
||||||
|
else:
|
||||||
|
self.Log(f"Detected obsolete (bool) settings ({key}), and deleting it's content because new setting name ({settingSet[key]}) is already populated.")
|
||||||
|
results = self.configure_plugin(self.PLUGIN_ID, {key : False}, init_defaults)
|
||||||
|
self.Debug(f"configure_plugin = {results}")
|
||||||
|
elif isinstance(obsoleteVar, int): # Both int and bool type returns true here
|
||||||
|
if obsoleteVar > 0:
|
||||||
|
if self.Setting(settingSet[key]) > 0:
|
||||||
|
self.Log(f"Detected obsolete (int) settings ({key}), and deleting it's content because new setting name ({settingSet[key]}) is already populated.")
|
||||||
|
results = self.configure_plugin(self.PLUGIN_ID, {key : 0}, init_defaults)
|
||||||
|
self.Debug(f"configure_plugin = {results}")
|
||||||
|
else:
|
||||||
|
self.Log(f"Detected obsolete (int) settings ({key}). Moving obsolete settings to new setting name {settingSet[key]}.")
|
||||||
|
results = self.configure_plugin(self.PLUGIN_ID, {settingSet[key]:self.Setting(key), key : 0}, init_defaults)
|
||||||
|
self.Debug(f"configure_plugin = {results}")
|
||||||
|
elif obsoleteVar != "":
|
||||||
|
if self.Setting(settingSet[key]) == "":
|
||||||
|
self.Log(f"Detected obsolete (str) settings ({key}). Moving obsolete settings to new setting name {settingSet[key]}.")
|
||||||
|
results = self.configure_plugin(self.PLUGIN_ID, {settingSet[key]:self.Setting(key), key : ""}, init_defaults)
|
||||||
|
self.Debug(f"configure_plugin = {results}")
|
||||||
|
else:
|
||||||
|
self.Log(f"Detected obsolete (str) settings ({key}), and deleting it's content because new setting name ({settingSet[key]}) is already populated.")
|
||||||
|
results = self.configure_plugin(self.PLUGIN_ID, {key : ""}, init_defaults)
|
||||||
|
self.Debug(f"configure_plugin = {results}")
|
||||||
|
if SettingToCheckFirst != "":
|
||||||
|
results = self.configure_plugin(self.PLUGIN_ID, {SettingToCheckFirst : True}, init_defaults)
|
||||||
|
self.Debug(f"configure_plugin = {results}")
|
||||||
|
|
||||||
|
|
||||||
def executeProcess(self, args, ExecDetach=False):
|
def executeProcess(self, args, ExecDetach=False):
|
||||||
pid = None
|
pid = None
|
||||||
self.Trace(f"self.IS_WINDOWS={self.IS_WINDOWS} args={args}")
|
self.Trace(f"self.IS_WINDOWS={self.IS_WINDOWS} args={args}")
|
||||||
|
|||||||
@@ -421,6 +421,48 @@ class StashPluginHelper(StashInterface):
|
|||||||
self.Log(f"StashPluginHelper Status: (CALLED_AS_STASH_PLUGIN={self.CALLED_AS_STASH_PLUGIN}), (RUNNING_IN_COMMAND_LINE_MODE={self.RUNNING_IN_COMMAND_LINE_MODE}), (DEBUG_TRACING={self.DEBUG_TRACING}), (DRY_RUN={self.DRY_RUN}), (PLUGIN_ID={self.PLUGIN_ID}), (PLUGIN_TASK_NAME={self.PLUGIN_TASK_NAME}), (STASH_URL={self.STASH_URL}), (MAIN_SCRIPT_NAME={self.MAIN_SCRIPT_NAME})",
|
self.Log(f"StashPluginHelper Status: (CALLED_AS_STASH_PLUGIN={self.CALLED_AS_STASH_PLUGIN}), (RUNNING_IN_COMMAND_LINE_MODE={self.RUNNING_IN_COMMAND_LINE_MODE}), (DEBUG_TRACING={self.DEBUG_TRACING}), (DRY_RUN={self.DRY_RUN}), (PLUGIN_ID={self.PLUGIN_ID}), (PLUGIN_TASK_NAME={self.PLUGIN_TASK_NAME}), (STASH_URL={self.STASH_URL}), (MAIN_SCRIPT_NAME={self.MAIN_SCRIPT_NAME})",
|
||||||
printTo, logLevel, lineNo)
|
printTo, logLevel, lineNo)
|
||||||
|
|
||||||
|
# Replaces obsolete UI settings variable with new name. Only use this with strings and numbers.
|
||||||
|
# Example usage:
|
||||||
|
# obsoleteSettingsToConvert = {"OldVariableName" : "NewVariableName", "AnotherOldVarName" : "NewName2"}
|
||||||
|
# stash.replaceObsoleteSettings(obsoleteSettingsToConvert, "ObsoleteSettingsCheckVer2")
|
||||||
|
def replaceObsoleteSettings(self, settingSet:dict, SettingToCheckFirst="", init_defaults=False):
|
||||||
|
if SettingToCheckFirst == "" or self.Setting(SettingToCheckFirst) == False:
|
||||||
|
for key in settingSet:
|
||||||
|
obsoleteVar = self.Setting(key)
|
||||||
|
if isinstance(obsoleteVar, bool):
|
||||||
|
if obsoleteVar:
|
||||||
|
if self.Setting(settingSet[key]) == False:
|
||||||
|
self.Log(f"Detected obsolete (bool) settings ({key}). Moving obsolete settings to new setting name {settingSet[key]}.")
|
||||||
|
results = self.configure_plugin(self.PLUGIN_ID, {settingSet[key]:self.Setting(key), key : False}, init_defaults)
|
||||||
|
self.Debug(f"configure_plugin = {results}")
|
||||||
|
else:
|
||||||
|
self.Log(f"Detected obsolete (bool) settings ({key}), and deleting it's content because new setting name ({settingSet[key]}) is already populated.")
|
||||||
|
results = self.configure_plugin(self.PLUGIN_ID, {key : False}, init_defaults)
|
||||||
|
self.Debug(f"configure_plugin = {results}")
|
||||||
|
elif isinstance(obsoleteVar, int): # Both int and bool type returns true here
|
||||||
|
if obsoleteVar > 0:
|
||||||
|
if self.Setting(settingSet[key]) > 0:
|
||||||
|
self.Log(f"Detected obsolete (int) settings ({key}), and deleting it's content because new setting name ({settingSet[key]}) is already populated.")
|
||||||
|
results = self.configure_plugin(self.PLUGIN_ID, {key : 0}, init_defaults)
|
||||||
|
self.Debug(f"configure_plugin = {results}")
|
||||||
|
else:
|
||||||
|
self.Log(f"Detected obsolete (int) settings ({key}). Moving obsolete settings to new setting name {settingSet[key]}.")
|
||||||
|
results = self.configure_plugin(self.PLUGIN_ID, {settingSet[key]:self.Setting(key), key : 0}, init_defaults)
|
||||||
|
self.Debug(f"configure_plugin = {results}")
|
||||||
|
elif obsoleteVar != "":
|
||||||
|
if self.Setting(settingSet[key]) == "":
|
||||||
|
self.Log(f"Detected obsolete (str) settings ({key}). Moving obsolete settings to new setting name {settingSet[key]}.")
|
||||||
|
results = self.configure_plugin(self.PLUGIN_ID, {settingSet[key]:self.Setting(key), key : ""}, init_defaults)
|
||||||
|
self.Debug(f"configure_plugin = {results}")
|
||||||
|
else:
|
||||||
|
self.Log(f"Detected obsolete (str) settings ({key}), and deleting it's content because new setting name ({settingSet[key]}) is already populated.")
|
||||||
|
results = self.configure_plugin(self.PLUGIN_ID, {key : ""}, init_defaults)
|
||||||
|
self.Debug(f"configure_plugin = {results}")
|
||||||
|
if SettingToCheckFirst != "":
|
||||||
|
results = self.configure_plugin(self.PLUGIN_ID, {SettingToCheckFirst : True}, init_defaults)
|
||||||
|
self.Debug(f"configure_plugin = {results}")
|
||||||
|
|
||||||
|
|
||||||
def executeProcess(self, args, ExecDetach=False):
|
def executeProcess(self, args, ExecDetach=False):
|
||||||
pid = None
|
pid = None
|
||||||
self.Trace(f"self.IS_WINDOWS={self.IS_WINDOWS} args={args}")
|
self.Trace(f"self.IS_WINDOWS={self.IS_WINDOWS} args={args}")
|
||||||
|
|||||||
Reference in New Issue
Block a user