From bec3e339508536fad4fea14aa089662d31effaa6 Mon Sep 17 00:00:00 2001 From: David Maisonave <47364845+David-Maisonave@users.noreply.github.com> Date: Tue, 20 Aug 2024 23:07:02 -0400 Subject: [PATCH] misc --- plugins/DupFileManager/DupFileManager.py | 23 +++++++++++--- .../DupFileManager/DupFileManager_config.py | 31 ------------------- .../DupFileManager_config_dev.py | 30 ++++++++++++++++++ plugins/DupFileManager/README.md | 1 + plugins/DupFileManager/requirements.txt | 3 +- plugins/RenameFile/README.md | 2 +- plugins/RenameFile/renamefile.py | 4 +-- plugins/RenameFile/renamefile.yml | 8 ++--- 8 files changed, 58 insertions(+), 44 deletions(-) create mode 100644 plugins/DupFileManager/DupFileManager_config_dev.py diff --git a/plugins/DupFileManager/DupFileManager.py b/plugins/DupFileManager/DupFileManager.py index b4d815a..3da4abb 100644 --- a/plugins/DupFileManager/DupFileManager.py +++ b/plugins/DupFileManager/DupFileManager.py @@ -43,6 +43,9 @@ stash.Trace(f"(stashPaths={stash.STASH_PATHS})") listSeparator = stash.pluginConfig['listSeparator'] if stash.pluginConfig['listSeparator'] != "" else ',' addPrimaryDupPathToDetails = stash.pluginConfig['addPrimaryDupPathToDetails'] +mergeDupFilename = stash.pluginSettings['mergeDupFilename'] +moveToTrashCan = stash.pluginSettings['moveToTrashCan'] +alternateTrashCanPath = stash.pluginConfig['dup_path'] def realpath(path): """ @@ -136,7 +139,7 @@ def setTagId(tagId, tagName, sceneDetails, PrimeDuplicateScene = ""): elif sceneDetails['details'] == "": PrimeDuplicateScene = f"Primary Duplicate = {PrimeDuplicateScene}" else: - PrimeDuplicateScene = f"Primary Duplicate = {PrimeDuplicateScene}; {sceneDetails['details']}" + PrimeDuplicateScene = f"Primary Duplicate = {PrimeDuplicateScene};\n{sceneDetails['details']}" for tag in sceneDetails['tags']: if tag['name'] == tagName: if PrimeDuplicateScene != "" and addPrimaryDupPathToDetails: @@ -193,10 +196,11 @@ def mangeDupFiles(merge=False, deleteDup=False, tagDuplicates=False): QtyAlmostDup = 0 QtyTagForDel = 0 QtySkipForDel = 0 + stash.Log("#########################################################################") + stash.Log("#########################################################################") stash.Log("Waiting for find_duplicate_scenes_diff to return results...") DupFileSets = stash.find_duplicate_scenes_diff(duration_diff=duration_diff) stash.Log("#########################################################################") - stash.Log("#########################################################################") for DupFileSet in DupFileSets: stash.Trace(f"DupFileSet={DupFileSet}") QtyDupSet+=1 @@ -207,7 +211,8 @@ def mangeDupFiles(merge=False, deleteDup=False, tagDuplicates=False): for DupFile in DupFileSet: QtyDup+=1 Scene = stash.find_scene(DupFile['id']) - stash.Trace(f"Scene = {Scene.encode('ascii','ignore')}") + sceneData = f"Scene = {Scene}" + stash.Trace(sceneData.encode('ascii','ignore')) DupFileDetailList = DupFileDetailList + [Scene] if DupFileToKeep != "": if DupFileToKeep['files'][0]['duration'] == Scene['files'][0]['duration']: @@ -243,9 +248,17 @@ def mangeDupFiles(merge=False, deleteDup=False, tagDuplicates=False): QtySkipForDel+=1 else: if deleteDup: - stash.Log(f"Deleting duplicate '{DupFile['files'][0]['path'].encode('ascii','ignore')}'") - # ToDo: Add logic to check if moving file to deletion folder, or doing full delete. + DupFileName = DupFile['files'][0]['path'] + DupFileNameOnly = pathlib.Path(DupFileName).stem + stash.Log(f"Deleting duplicate '{DupFileName.encode('ascii','ignore')}'") # ToDo: Add logic to check if tag merging is needed before performing deletion. + if alternateTrashCanPath != "": + shutil.move(DupFileName, f"{alternateTrashCanPath }{os.sep}{DupFileNameOnly}") + elif moveToTrashCan: + from send2trash import send2trash # Requirement: pip install Send2Trash + send2trash(DupFileName) + else: + os.remove(DupFileName) elif tagDuplicates: if QtyTagForDel == 0: stash.Log(f"Tagging duplicate {DupFile['files'][0]['path'].encode('ascii','ignore')} for deletion with tag {duplicateMarkForDeletion}.") diff --git a/plugins/DupFileManager/DupFileManager_config.py b/plugins/DupFileManager/DupFileManager_config.py index 1dfa780..29250f2 100644 --- a/plugins/DupFileManager/DupFileManager_config.py +++ b/plugins/DupFileManager/DupFileManager_config.py @@ -6,37 +6,6 @@ config = { "listSeparator" : ",", # If enabled, adds the primary duplicate path to the scene detail. "addPrimaryDupPathToDetails" : True, - - # If enabled, ignore reparsepoints. For Windows NT drives only. - "ignoreReparsepoints" : True, - # If enabled, ignore symbolic links. - "ignoreSymbolicLinks" : True, - - - # If enabled, swap higher resolution duplicate files to preferred path. - "swapHighRes" : True, - # If enabled, swap longer length media files to preferred path. Longer will be determine by significantLongerTime value. - "swapLongLength" : True, - # If enabled, swap longer file name to preferred path. - "swapLongFileName" : False, - - # If enabled, when finding exact duplicate files, keep file with the shorter name. The default is to keep file name with the longer name. - "keepShorterFileName" : False, - # If enabled, when finding duplicate files, keep media with the shorter time length. The default is to keep media with longer time length. - "keepShorterLength" : False, - # If enabled, when finding duplicate files, keep media with the lower resolution. The default is to keep media with higher resolution. - "keepLowerResolution" : False, - # If enabled, keep duplicate media with high resolution over media with significant longer time. - "keepHighResOverLen" : False, # Requires keepBothHighResAndLongerLen = False - # The threshold as to what percentage is consider a significant longer time. Default is 15% longer. - "significantLongerTime" : 15, # 15% longer time - # If enabled, keep both duplicate files if the LOWER resolution file is significantly longer. - "keepBothHighResAndLongerLen" : True, - - # Define ignore list to avoid specific directories. No action is taken on any file in the ignore list. - "ignore_paths": [], #Example: "ignore_paths": ['C:\\SomeMediaPath\\subpath', "E:\\YetAnotherPath\\subpath', "E:\\YetAnotherPath\\secondSubPath'] - # Keep empty to check all paths, or populate it with the only paths to check for duplicates - "onlyCheck_paths": [], #Example: "onlyCheck_paths": ['C:\\SomeMediaPath\\subpath', "E:\\YetAnotherPath\\subpath', "E:\\YetAnotherPath\\secondSubPath'] # Alternative path to move duplicate files. Path needs to be in the same drive as the duplicate file. "dup_path": "", #Example: "C:\\TempDeleteFolder" diff --git a/plugins/DupFileManager/DupFileManager_config_dev.py b/plugins/DupFileManager/DupFileManager_config_dev.py new file mode 100644 index 0000000..a88844b --- /dev/null +++ b/plugins/DupFileManager/DupFileManager_config_dev.py @@ -0,0 +1,30 @@ +# Below fields are in the development stage, and should not be used. +config_dev = { + # If enabled, ignore reparsepoints. For Windows NT drives only. + "ignoreReparsepoints" : True, + # If enabled, ignore symbolic links. + "ignoreSymbolicLinks" : True, + + # If enabled, swap higher resolution duplicate files to preferred path. + "swapHighRes" : True, + # If enabled, swap longer length media files to preferred path. Longer will be determine by significantLongerTime value. + "swapLongLength" : True, + # If enabled, swap longer file name to preferred path. + "swapLongFileName" : False, + + # If enabled, when finding exact duplicate files, keep file with the shorter name. The default is to keep file name with the longer name. + "keepShorterFileName" : False, + # If enabled, when finding duplicate files, keep media with the shorter time length. The default is to keep media with longer time length. + "keepShorterLength" : False, + # If enabled, when finding duplicate files, keep media with the lower resolution. The default is to keep media with higher resolution. + "keepLowerResolution" : False, + # If enabled, keep duplicate media with high resolution over media with significant longer time. + "keepHighResOverLen" : False, # Requires keepBothHighResAndLongerLen = False + # The threshold as to what percentage is consider a significant longer time. Default is 15% longer. + "significantLongerTime" : 15, # 15% longer time + # If enabled, keep both duplicate files if the LOWER resolution file is significantly longer. + "keepBothHighResAndLongerLen" : True, + + # Keep empty to check all paths, or populate it with the only paths to check for duplicates + "onlyCheck_paths": [], #Example: "onlyCheck_paths": ['C:\\SomeMediaPath\\subpath', "E:\\YetAnotherPath\\subpath', "E:\\YetAnotherPath\\secondSubPath'] +} diff --git a/plugins/DupFileManager/README.md b/plugins/DupFileManager/README.md index 3161444..2c3a2ff 100644 --- a/plugins/DupFileManager/README.md +++ b/plugins/DupFileManager/README.md @@ -26,6 +26,7 @@ This Plugin is under construction!!! `pip install stashapp-tools` `pip install --upgrade stashapp-tools` `pip install pyYAML` +`pip install Send2Trash` ### Installation - Follow **Requirements** instructions. diff --git a/plugins/DupFileManager/requirements.txt b/plugins/DupFileManager/requirements.txt index 19a1174..d503550 100644 --- a/plugins/DupFileManager/requirements.txt +++ b/plugins/DupFileManager/requirements.txt @@ -1,3 +1,4 @@ stashapp-tools >= 0.2.50 pyYAML -watchdog \ No newline at end of file +watchdog +Send2Trash \ No newline at end of file diff --git a/plugins/RenameFile/README.md b/plugins/RenameFile/README.md index 8850198..39e2f8a 100644 --- a/plugins/RenameFile/README.md +++ b/plugins/RenameFile/README.md @@ -1,4 +1,4 @@ -# RenameFile: Ver 0.4.3 (By David Maisonave) +# RenameFile: Ver 0.4.4 (By David Maisonave) RenameFile is a [Stash](https://github.com/stashapp/stash) plugin which performs the following tasks. - **Rename Scene File Name** (On-The-Fly) - **Append tag names** to file name diff --git a/plugins/RenameFile/renamefile.py b/plugins/RenameFile/renamefile.py index 00e112a..a8ab1fd 100644 --- a/plugins/RenameFile/renamefile.py +++ b/plugins/RenameFile/renamefile.py @@ -66,7 +66,7 @@ settings = { "studioAppend": False, "tagAppend": False, "z_keyFIeldsIncludeInFileName": False, - "zafileRenameViaMove": False, + "zafileRenameViaRaname": False, "zfieldKeyList": DEFAULT_FIELD_KEY_LIST, "zmaximumTagKeys": 12, "zseparators": DEFAULT_SEPERATOR, @@ -133,7 +133,7 @@ endpoint = f"{json_input['server_connection']['Scheme']}://{endpointHost}:{json_ if debugTracing: logger.info(f"Debug Tracing (endpoint={endpoint})................") # Extract rename_files and move_files settings from renamefile_settings.py rename_files = config["rename_files"] -move_files = settings["zafileRenameViaMove"] +move_files = False if settings["zafileRenameViaRaname"] else True if debugTracing: logger.info("Debug Tracing................") fieldKeyList = settings["zfieldKeyList"] # Default Field Key List with the desired order if not fieldKeyList or fieldKeyList == "": diff --git a/plugins/RenameFile/renamefile.yml b/plugins/RenameFile/renamefile.yml index 75f16c4..af9ee0a 100644 --- a/plugins/RenameFile/renamefile.yml +++ b/plugins/RenameFile/renamefile.yml @@ -1,6 +1,6 @@ name: RenameFile description: Renames video (scene) file names when the user edits the [Title] field located in the scene [Edit] tab. -version: 0.4.3 +version: 0.4.4 url: https://github.com/David-Maisonave/Axter-Stash/tree/main/plugins/RenameFile settings: performerAppend: @@ -19,9 +19,9 @@ settings: displayName: Include Existing Key Field description: Enable to append performer, tags, studios, & galleries even if name already exists in the original file name. type: BOOLEAN - zafileRenameViaMove: - displayName: Rename Using Move - description: Enable to have file moved when renaming file. + zafileRenameViaRaname: + displayName: Rename Instead of Move + description: Enable to rename file instead of Move file. (Not recommended for Windows OS) type: BOOLEAN zfieldKeyList: displayName: Key Fields