forked from Github/Axter-Stash
Added task option Delete Tagged Duplicates
This commit is contained in:
@@ -16,8 +16,9 @@ from DupFileManager_config import config # Import config from DupFileManager_con
|
|||||||
parser = argparse.ArgumentParser()
|
parser = argparse.ArgumentParser()
|
||||||
parser.add_argument('--url', '-u', dest='stash_url', type=str, help='Add Stash URL')
|
parser.add_argument('--url', '-u', dest='stash_url', type=str, help='Add Stash URL')
|
||||||
parser.add_argument('--trace', '-t', dest='trace', action='store_true', help='Enables debug trace mode.')
|
parser.add_argument('--trace', '-t', dest='trace', action='store_true', help='Enables debug trace mode.')
|
||||||
parser.add_argument('--remove_dup', '-r', dest='remove', action='store_true', help='Remove (delete) duplicate files.')
|
|
||||||
parser.add_argument('--add_dup_tag', '-a', dest='dup_tag', action='store_true', help='Set a tag to duplicate files.')
|
parser.add_argument('--add_dup_tag', '-a', dest='dup_tag', action='store_true', help='Set a tag to duplicate files.')
|
||||||
|
parser.add_argument('--del_tag_dup', '-d', dest='del_tag', action='store_true', help='Only delete scenes having DuplicateMarkForDeletion tag.')
|
||||||
|
parser.add_argument('--remove_dup', '-r', dest='remove', action='store_true', help='Remove (delete) duplicate files.')
|
||||||
parse_args = parser.parse_args()
|
parse_args = parser.parse_args()
|
||||||
|
|
||||||
settings = {
|
settings = {
|
||||||
@@ -39,7 +40,7 @@ stash = StashPluginHelper(
|
|||||||
debugTracing=parse_args.trace,
|
debugTracing=parse_args.trace,
|
||||||
settings=settings,
|
settings=settings,
|
||||||
config=config,
|
config=config,
|
||||||
maxbytes=50*1024*1024,
|
maxbytes=10*1024*1024,
|
||||||
)
|
)
|
||||||
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})************************************************")
|
||||||
@@ -182,7 +183,6 @@ def createTagId(tagName, tagName_descp, deleteIfExist = False):
|
|||||||
return tagId['id']
|
return tagId['id']
|
||||||
|
|
||||||
def setTagId(tagId, tagName, sceneDetails, DupFileToKeep):
|
def setTagId(tagId, tagName, sceneDetails, DupFileToKeep):
|
||||||
stash.Trace()
|
|
||||||
details = ""
|
details = ""
|
||||||
ORG_DATA_DICT = {'id' : sceneDetails['id']}
|
ORG_DATA_DICT = {'id' : sceneDetails['id']}
|
||||||
dataDict = ORG_DATA_DICT.copy()
|
dataDict = ORG_DATA_DICT.copy()
|
||||||
@@ -380,6 +380,44 @@ def mangeDupFiles(merge=False, deleteDup=False, tagDuplicates=False):
|
|||||||
stash.metadata_clean_generated()
|
stash.metadata_clean_generated()
|
||||||
stash.optimise_database()
|
stash.optimise_database()
|
||||||
|
|
||||||
|
def deleteTagggedDuplicates():
|
||||||
|
tagId = stash.find_tags(q=duplicateMarkForDeletion)
|
||||||
|
if len(tagId) > 0 and 'id' in tagId[0]:
|
||||||
|
tagId = tagId[0]['id']
|
||||||
|
else:
|
||||||
|
stash.Warn(f"Could not find tag ID for tag '{duplicateMarkForDeletion}'.")
|
||||||
|
return
|
||||||
|
QtyDup = 0
|
||||||
|
QtyDeleted = 0
|
||||||
|
QtyFailedQuery = 0
|
||||||
|
stash.Trace("#########################################################################")
|
||||||
|
sceneIDs = stash.find_scenes(f={"tags": {"value":tagId, "modifier":"INCLUDES"}}, fragment='id')
|
||||||
|
stash.Trace(f"Found the following scenes with tag ({duplicateMarkForDeletion}): sceneIDs = {sceneIDs}")
|
||||||
|
for sceneID in sceneIDs:
|
||||||
|
# stash.Trace(f"Getting scene data for scene ID {sceneID['id']}.")
|
||||||
|
QtyDup += 1
|
||||||
|
scene = stash.find_scene(sceneID['id'])
|
||||||
|
if scene == None or len(scene) == 0:
|
||||||
|
stash.Warn(f"Could not get scene data for scene ID {sceneID['id']}.")
|
||||||
|
QtyFailedQuery += 1
|
||||||
|
continue
|
||||||
|
# stash.Log(f"scene={scene}")
|
||||||
|
DupFileName = scene['files'][0]['path']
|
||||||
|
DupFileNameOnly = pathlib.Path(DupFileName).stem
|
||||||
|
stash.Warn(f"Deleting duplicate '{DupFileName}'", toAscii=True, printTo=LOG_STASH_N_PLUGIN)
|
||||||
|
if alternateTrashCanPath != "":
|
||||||
|
destPath = f"{alternateTrashCanPath }{os.sep}{DupFileNameOnly}"
|
||||||
|
if os.path.isfile(destPath):
|
||||||
|
destPath = f"{alternateTrashCanPath }{os.sep}_{time.time()}_{DupFileNameOnly}"
|
||||||
|
shutil.move(DupFileName, destPath)
|
||||||
|
elif moveToTrashCan:
|
||||||
|
sendToTrash(DupFileName)
|
||||||
|
result = stash.destroy_scene(scene['id'], delete_file=True)
|
||||||
|
stash.Trace(f"destroy_scene result={result} for file {DupFileName}", toAscii=True)
|
||||||
|
QtyDeleted += 1
|
||||||
|
stash.Log(f"QtyDup={QtyDup}, QtyDeleted={QtyDeleted}, QtyFailedQuery={QtyFailedQuery}", printTo=LOG_STASH_N_PLUGIN)
|
||||||
|
return
|
||||||
|
|
||||||
def testSetDupTagOnScene(sceneId):
|
def testSetDupTagOnScene(sceneId):
|
||||||
scene = stash.find_scene(sceneId)
|
scene = stash.find_scene(sceneId)
|
||||||
stash.Log(f"scene={scene}")
|
stash.Log(f"scene={scene}")
|
||||||
@@ -393,16 +431,21 @@ def testSetDupTagOnScene(sceneId):
|
|||||||
if stash.PLUGIN_TASK_NAME == "tag_duplicates_task":
|
if stash.PLUGIN_TASK_NAME == "tag_duplicates_task":
|
||||||
mangeDupFiles(tagDuplicates=True, merge=mergeDupFilename)
|
mangeDupFiles(tagDuplicates=True, merge=mergeDupFilename)
|
||||||
stash.Trace(f"{stash.PLUGIN_TASK_NAME} EXIT")
|
stash.Trace(f"{stash.PLUGIN_TASK_NAME} EXIT")
|
||||||
elif stash.PLUGIN_TASK_NAME == "delete_duplicates":
|
elif stash.PLUGIN_TASK_NAME == "delete_tagged_duplicates_task":
|
||||||
|
deleteTagggedDuplicates()
|
||||||
|
stash.Trace(f"{stash.PLUGIN_TASK_NAME} EXIT")
|
||||||
|
elif stash.PLUGIN_TASK_NAME == "delete_duplicates_task":
|
||||||
mangeDupFiles(deleteDup=True, merge=mergeDupFilename)
|
mangeDupFiles(deleteDup=True, merge=mergeDupFilename)
|
||||||
stash.Trace(f"{stash.PLUGIN_TASK_NAME} EXIT")
|
stash.Trace(f"{stash.PLUGIN_TASK_NAME} EXIT")
|
||||||
elif parse_args.dup_tag:
|
elif parse_args.dup_tag:
|
||||||
mangeDupFiles(tagDuplicates=True, merge=mergeDupFilename)
|
mangeDupFiles(tagDuplicates=True, merge=mergeDupFilename)
|
||||||
stash.Trace(f"Tag duplicate EXIT")
|
stash.Trace(f"Tag duplicate EXIT")
|
||||||
|
elif parse_args.del_tag:
|
||||||
|
deleteTagggedDuplicates()
|
||||||
|
stash.Trace(f"Delete Tagged duplicates EXIT")
|
||||||
elif parse_args.remove:
|
elif parse_args.remove:
|
||||||
mangeDupFiles(deleteDup=True, merge=mergeDupFilename)
|
mangeDupFiles(deleteDup=True, merge=mergeDupFilename)
|
||||||
stash.Trace(f"Delete duplicate EXIT")
|
stash.Trace(f"Delete duplicate 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})")
|
||||||
|
|
||||||
|
|||||||
@@ -57,10 +57,14 @@ exec:
|
|||||||
interface: raw
|
interface: raw
|
||||||
tasks:
|
tasks:
|
||||||
- name: Tag Duplicates
|
- name: Tag Duplicates
|
||||||
description: Set tag DuplicateMarkForDeletion to the duplicates with lower resolution, duration, file name length, and/or black list path.
|
description: Set tag DuplicateMarkForDeletion to the duplicates with lower resolution, duration, file name length, or black list path.
|
||||||
defaultArgs:
|
defaultArgs:
|
||||||
mode: tag_duplicates_task
|
mode: tag_duplicates_task
|
||||||
- name: Delete Duplicates
|
- name: Delete Tagged Duplicates
|
||||||
description: Deletes duplicate files
|
description: Only delete scenes having DuplicateMarkForDeletion tag.
|
||||||
defaultArgs:
|
defaultArgs:
|
||||||
mode: delete_duplicates
|
mode: delete_tagged_duplicates_task
|
||||||
|
- name: Delete Duplicates
|
||||||
|
description: Delete duplicate scenes. Performs deletion without first tagging.
|
||||||
|
defaultArgs:
|
||||||
|
mode: delete_duplicates_task
|
||||||
|
|||||||
@@ -212,23 +212,23 @@ class StashScheduler: # Stash Scheduler
|
|||||||
|
|
||||||
result = None
|
result = None
|
||||||
if task['task'] == "Clean":
|
if task['task'] == "Clean":
|
||||||
result = stash.metadata_clean(paths=targetPaths, dry_run=stash.DRY_RUN)
|
result = self.jobIdOutput(stash.metadata_clean(paths=targetPaths, dry_run=stash.DRY_RUN))
|
||||||
elif task['task'] == "Clean Generated Files":
|
elif task['task'] == "Clean Generated Files":
|
||||||
result = stash.metadata_clean_generated()
|
result = self.jobIdOutput(stash.metadata_clean_generated()))
|
||||||
elif task['task'] == "Generate":
|
elif task['task'] == "Generate":
|
||||||
result = stash.metadata_generate()
|
result = self.jobIdOutput(stash.metadata_generate())
|
||||||
elif task['task'] == "Backup":
|
elif task['task'] == "Backup":
|
||||||
result = self.runBackupTask(task)
|
result = self.jobIdOutput(self.runBackupTask(task))
|
||||||
elif task['task'] == "Scan":
|
elif task['task'] == "Scan":
|
||||||
result = stash.metadata_scan(paths=targetPaths)
|
result = self.jobIdOutput(stash.metadata_scan(paths=targetPaths))
|
||||||
elif task['task'] == "Auto Tag":
|
elif task['task'] == "Auto Tag":
|
||||||
result = stash.metadata_autotag(paths=targetPaths)
|
result = self.jobIdOutput(stash.metadata_autotag(paths=targetPaths))
|
||||||
elif task['task'] == "Optimise Database":
|
elif task['task'] == "Optimise Database":
|
||||||
result = stash.optimise_database()
|
result = self.jobIdOutput(stash.optimise_database())
|
||||||
elif task['task'] == "RenameGeneratedFiles":
|
elif task['task'] == "RenameGeneratedFiles":
|
||||||
result = stash.rename_generated_files()
|
result = self.jobIdOutput(stash.rename_generated_files())
|
||||||
elif task['task'] == "GQL":
|
elif task['task'] == "GQL":
|
||||||
result = stash.call_GQL(task['input'])
|
result = self.jobIdOutput(stash.call_GQL(task['input']))
|
||||||
elif task['task'] == "Log":
|
elif task['task'] == "Log":
|
||||||
Msg = "Scheduled Logging (INFO)."
|
Msg = "Scheduled Logging (INFO)."
|
||||||
if 'msg' in task and task['msg'] != "":
|
if 'msg' in task and task['msg'] != "":
|
||||||
@@ -256,11 +256,23 @@ class StashScheduler: # Stash Scheduler
|
|||||||
elif task['task'] == "execute":
|
elif task['task'] == "execute":
|
||||||
result = self.runExecuteProcessTask(task)
|
result = self.runExecuteProcessTask(task)
|
||||||
else:
|
else:
|
||||||
result = self.runPluginTask(task)
|
result = self.jobIdOutput(self.runPluginTask(task))
|
||||||
|
|
||||||
if result:
|
if result:
|
||||||
stash.Trace(f"Task '{task['task']}' result={result}")
|
stash.Trace(f"Task '{task['task']}' result={result}")
|
||||||
|
|
||||||
|
def jobIdOutput(self, result):
|
||||||
|
if result == None or result == "":
|
||||||
|
return result
|
||||||
|
jobId = None
|
||||||
|
if type(result) is int:
|
||||||
|
jobId = result
|
||||||
|
elif str(result).isnumeric():
|
||||||
|
jobId = int(result)
|
||||||
|
else:
|
||||||
|
return result
|
||||||
|
return f"Task started with Job-ID#({jobId})"
|
||||||
|
|
||||||
def runExecuteProcessTask(self, task):
|
def runExecuteProcessTask(self, task):
|
||||||
if 'command' in task and task['command'] != "":
|
if 'command' in task and task['command'] != "":
|
||||||
cmd = task['command'].replace("<plugin_path>", f"{pathlib.Path(__file__).resolve().parent}{os.sep}")
|
cmd = task['command'].replace("<plugin_path>", f"{pathlib.Path(__file__).resolve().parent}{os.sep}")
|
||||||
@@ -289,7 +301,6 @@ class StashScheduler: # Stash Scheduler
|
|||||||
return None
|
return None
|
||||||
|
|
||||||
def runPluginTask(self, task):
|
def runPluginTask(self, task):
|
||||||
# ToDo: Add code to check if plugin is installed.
|
|
||||||
try:
|
try:
|
||||||
if 'pluginId' in task and task['pluginId'] != "":
|
if 'pluginId' in task and task['pluginId'] != "":
|
||||||
invalidDir = False
|
invalidDir = False
|
||||||
|
|||||||
Reference in New Issue
Block a user