Added galleries option

This commit is contained in:
David Maisonave
2024-07-23 17:30:15 -04:00
parent 66cb879288
commit 117aab0ef2
4 changed files with 84 additions and 57 deletions

View File

@@ -25,7 +25,7 @@ FORMAT = "[%(asctime)s - LN:%(lineno)s] %(message)s"
logging.basicConfig(filename=log_file_path, level=logging.INFO, format=FORMAT) logging.basicConfig(filename=log_file_path, level=logging.INFO, format=FORMAT)
logger = logging.getLogger('renamefile') logger = logging.getLogger('renamefile')
DEFAULT_ENDPOINT = "http://localhost:9999/graphql" # Default GraphQL endpoint DEFAULT_ENDPOINT = "http://localhost:9999/graphql" # Default GraphQL endpoint
DEFAULT_FIELD_KEY_LIST = "title, performers, tags" # Default Field Key List with the desired order DEFAULT_FIELD_KEY_LIST = "title,performers,studio,tags" # Default Field Key List with the desired order
DEFAULT_SEPERATOR = "-" DEFAULT_SEPERATOR = "-"
PLUGIN_ARGS = False PLUGIN_ARGS = False
@@ -39,19 +39,19 @@ FRAGMENT_SERVER = json_input["server_connection"]
stash = StashInterface(FRAGMENT_SERVER) stash = StashInterface(FRAGMENT_SERVER)
pluginConfiguration = stash.get_configuration()["plugins"] pluginConfiguration = stash.get_configuration()["plugins"]
settings = { settings = {
"dryRun": False,
"fileRenameViaMove": False,
"performerAppend": False, "performerAppend": False,
"performerIncludeInFileName": False, "studioAppend": False,
"tagAppend": False, "tagAppend": False,
"tagIncludeInFileName": False, "z_keyFIeldsIncludeInFileName": False,
"zFieldKeyList": DEFAULT_FIELD_KEY_LIST, "zafileRenameViaMove": False,
"zfieldKeyList": DEFAULT_FIELD_KEY_LIST,
"zgraphqlEndpoint": DEFAULT_ENDPOINT, "zgraphqlEndpoint": DEFAULT_ENDPOINT,
"zmaximumTagKeys": 12, "zmaximumTagKeys": 12,
"zpathToExclude": "", "zpathToExclude": "",
"zseparators": DEFAULT_SEPERATOR, "zseparators": DEFAULT_SEPERATOR,
"ztagWhitelist": "", "ztagWhitelist": "",
"zzdebugTracing": False, "zzdebugTracing": False,
"zzdryRun": False,
} }
if "renamefile" in pluginConfiguration: if "renamefile" in pluginConfiguration:
settings.update(pluginConfiguration["renamefile"]) settings.update(pluginConfiguration["renamefile"])
@@ -59,7 +59,7 @@ if "renamefile" in pluginConfiguration:
debugTracing = settings["zzdebugTracing"] debugTracing = settings["zzdebugTracing"]
# Extract dry_run setting from settings # Extract dry_run setting from settings
dry_run = settings["dryRun"] dry_run = settings["zzdryRun"]
dry_run_prefix = '' dry_run_prefix = ''
try: try:
PLUGIN_ARGS = json_input['args']["mode"] PLUGIN_ARGS = json_input['args']["mode"]
@@ -88,9 +88,9 @@ if not endpoint or endpoint == "":
endpoint = DEFAULT_ENDPOINT endpoint = DEFAULT_ENDPOINT
# Extract rename_files and move_files settings from renamefile_settings.py # Extract rename_files and move_files settings from renamefile_settings.py
rename_files = config["rename_files"] rename_files = config["rename_files"]
move_files = settings["fileRenameViaMove"] move_files = settings["zafileRenameViaMove"]
if debugTracing: logger.info("Debug Tracing................") if debugTracing: logger.info("Debug Tracing................")
fieldKeyList = settings["zFieldKeyList"] # Default Field Key List with the desired order fieldKeyList = settings["zfieldKeyList"] # Default Field Key List with the desired order
if not fieldKeyList or fieldKeyList == "": if not fieldKeyList or fieldKeyList == "":
fieldKeyList = DEFAULT_FIELD_KEY_LIST fieldKeyList = DEFAULT_FIELD_KEY_LIST
fieldKeyList = fieldKeyList.replace(" ", "") fieldKeyList = fieldKeyList.replace(" ", "")
@@ -148,8 +148,7 @@ def form_filename(original_file_stem, scene_details, wrapper_styles):
tag_keys_added = 0 tag_keys_added = 0
default_title = '' default_title = ''
if_notitle_use_org_filename = config["if_notitle_use_org_filename"] if_notitle_use_org_filename = config["if_notitle_use_org_filename"]
include_tag_if_in_name = settings["tagIncludeInFileName"] include_keyField_if_in_name = settings["z_keyFIeldsIncludeInFileName"]
include_performer_if_in_name = settings["performerIncludeInFileName"]
if if_notitle_use_org_filename: if if_notitle_use_org_filename:
default_title = original_file_stem default_title = original_file_stem
# ................... # ...................
@@ -187,12 +186,20 @@ def form_filename(original_file_stem, scene_details, wrapper_styles):
for key in fieldKeyList: for key in fieldKeyList:
if key == 'studio': if key == 'studio':
studio_name = scene_details.get('studio', {}).get('name', '') if settings["studioAppend"]:
if studio_name: if debugTracing: logger.info("Debug Tracing................")
if wrapper_styles.get('studio'): studio_name = scene_details.get('studio', {})
filename_parts.append(f"{wrapper_styles['studio'][0]}{studio_name}{wrapper_styles['studio'][1]}") if debugTracing: logger.info(f"Debug Tracing (studio_name={studio_name})................")
else: if studio_name:
filename_parts.append(studio_name) studio_name = scene_details.get('studio', {}).get('name', '')
if debugTracing: logger.info(f"Debug Tracing (studio_name={studio_name})................")
if studio_name:
if debugTracing: logger.info("Debug Tracing................")
if include_keyField_if_in_name or studio_name.lower() not in title.lower():
if wrapper_styles.get('studio'):
filename_parts.append(f"{wrapper_styles['studio'][0]}{studio_name}{wrapper_styles['studio'][1]}")
else:
filename_parts.append(studio_name)
elif key == 'title': elif key == 'title':
if title: # This value has already been fetch in start of function because it needs to be defined before tags and performers if title: # This value has already been fetch in start of function because it needs to be defined before tags and performers
if wrapper_styles.get('title'): if wrapper_styles.get('title'):
@@ -203,8 +210,8 @@ def form_filename(original_file_stem, scene_details, wrapper_styles):
if settings["performerAppend"]: if settings["performerAppend"]:
performers = '-'.join([performer.get('name', '') for performer in scene_details.get('performers', [])]) performers = '-'.join([performer.get('name', '') for performer in scene_details.get('performers', [])])
if performers: if performers:
if debugTracing: logger.info(f"Debug Tracing (include_performer_if_in_name={include_performer_if_in_name})................") if debugTracing: logger.info(f"Debug Tracing (include_keyField_if_in_name={include_keyField_if_in_name})................")
if include_performer_if_in_name or performers.lower() not in title.lower(): if include_keyField_if_in_name or performers.lower() not in title.lower():
if debugTracing: logger.info(f"Debug Tracing (performers={performers})................") if debugTracing: logger.info(f"Debug Tracing (performers={performers})................")
if wrapper_styles.get('performers'): if wrapper_styles.get('performers'):
filename_parts.append(f"{wrapper_styles['performers'][0]}{performers}{wrapper_styles['performers'][1]}") filename_parts.append(f"{wrapper_styles['performers'][0]}{performers}{wrapper_styles['performers'][1]}")
@@ -212,7 +219,9 @@ def form_filename(original_file_stem, scene_details, wrapper_styles):
filename_parts.append(performers) filename_parts.append(performers)
elif key == 'date': elif key == 'date':
scene_date = scene_details.get('date', '') scene_date = scene_details.get('date', '')
if debugTracing: logger.info("Debug Tracing................")
if scene_date: if scene_date:
if debugTracing: logger.info("Debug Tracing................")
if wrapper_styles.get('date'): if wrapper_styles.get('date'):
filename_parts.append(f"{wrapper_styles['date'][0]}{scene_date}{wrapper_styles['date'][1]}") filename_parts.append(f"{wrapper_styles['date'][0]}{scene_date}{wrapper_styles['date'][1]}")
else: else:
@@ -233,23 +242,40 @@ def form_filename(original_file_stem, scene_details, wrapper_styles):
else: else:
filename_parts.append(video_codec) filename_parts.append(video_codec)
elif key == 'frame_rate': elif key == 'frame_rate':
frame_rate = str(scene_details.get('files', [{}])[0].get('frame_rate', '')) + ' FPS' # Convert to string and append ' FPS' frame_rate = str(scene_details.get('files', [{}])[0].get('frame_rate', '')) + 'FPS' # Convert to string and append ' FPS'
if frame_rate: if frame_rate:
if wrapper_styles.get('frame_rate'): if wrapper_styles.get('frame_rate'):
filename_parts.append(f"{wrapper_styles['frame_rate'][0]}{frame_rate}{wrapper_styles['frame_rate'][1]}") filename_parts.append(f"{wrapper_styles['frame_rate'][0]}{frame_rate}{wrapper_styles['frame_rate'][1]}")
else: else:
filename_parts.append(frame_rate) filename_parts.append(frame_rate)
elif key == 'galleries':
galleries = [gallery.get('title', '') for gallery in scene_details.get('galleries', [])]
if debugTracing: logger.info("Debug Tracing................")
for gallery_name in galleries:
if debugTracing: logger.info(f"Debug Tracing (include_keyField_if_in_name={include_keyField_if_in_name}) (gallery_name={gallery_name})................")
if include_keyField_if_in_name or gallery_name.lower() not in title.lower():
if wrapper_styles.get('galleries'):
filename_parts.append(f"{wrapper_styles['galleries'][0]}{gallery_name}{wrapper_styles['galleries'][1]}")
if debugTracing: logger.info("Debug Tracing................")
else:
filename_parts.append(gallery_name)
if debugTracing: logger.info("Debug Tracing................")
if debugTracing: logger.info(f"Debug Tracing (gallery_name={gallery_name})................")
if debugTracing: logger.info("Debug Tracing................")
elif key == 'tags': elif key == 'tags':
if settings["tagAppend"]: if settings["tagAppend"]:
tags = [tag.get('name', '') for tag in scene_details.get('tags', [])] tags = [tag.get('name', '') for tag in scene_details.get('tags', [])]
if debugTracing: logger.info("Debug Tracing................") if debugTracing: logger.info("Debug Tracing................")
for tag_name in tags: for tag_name in tags:
if debugTracing: logger.info(f"Debug Tracing (include_tag_if_in_name={include_tag_if_in_name})................") if debugTracing: logger.info(f"Debug Tracing (include_keyField_if_in_name={include_keyField_if_in_name}) (tag_name={tag_name})................")
if include_tag_if_in_name or tag_name.lower() not in title.lower(): if include_keyField_if_in_name or tag_name.lower() not in title.lower():
add_tag(tag_name) add_tag(tag_name)
if debugTracing: logger.info(f"Debug Tracing (tag_name={tag_name})................") if debugTracing: logger.info(f"Debug Tracing (tag_name={tag_name})................")
if debugTracing: logger.info("Debug Tracing................")
if debugTracing: logger.info("Debug Tracing................")
new_filename = separator.join(filename_parts).replace(double_separator, separator) new_filename = separator.join(filename_parts).replace(double_separator, separator)
if debugTracing: logger.info(f"Debug Tracing (new_filename={new_filename})................")
# Check if the scene's path matches any of the excluded paths # Check if the scene's path matches any of the excluded paths
if exclude_paths and should_exclude_path(scene_details): if exclude_paths and should_exclude_path(scene_details):
@@ -271,6 +297,9 @@ def find_scene_by_id(scene_id):
video_codec video_codec
frame_rate frame_rate
} }
galleries {
title
}
studio { studio {
name name
} }

View File

@@ -1,42 +1,33 @@
name: RenameFile name: RenameFile
description: "Renames video (scene) file names when the user edits the [Title] field located in the scene [Edit] tab. description: Renames video (scene) file names when the user edits the [Title] field located in the scene [Edit] tab.
The file is renamed to the [Title] field value after user clicks save button. version: 0.3.0
Optionally, tags and performers can be appended to the file name when rename occurs.
Additional options available in file renamefile_settings.py.
Note: On Windows OS, the file can not be renamed while it's playing. Refresh the URL to allow file release and rename."
version: 0.2.6
url: https://github.com/David-Maisonave/Axter-Stash/tree/main/plugins/RenameFile url: https://github.com/David-Maisonave/Axter-Stash/tree/main/plugins/RenameFile
ui:
settings: settings:
dryRun:
displayName: Dry Run
description: Enable to run script in [Dry Run] mode. In dry run mode, files are NOT renamed, and only logging is performed. Use the logging to determine if rename will occur as expected. This should always be enabled on the first run after renamefile_settings.py has been modified.
type: BOOLEAN
fileRenameViaMove:
displayName: Rename Using Move
description: Enable to have file moved when renaming file.
type: BOOLEAN
performerAppend: performerAppend:
displayName: Append Performers displayName: Append Performers
description: Enable to append performers name to file name when renaming a file. Requires performers to be included in [Key Fields] list, which by default it is included. description: Enable to append performers name to file name when renaming a file. Requires performers to be included in [Key Fields] list, which by default it is included.
type: BOOLEAN type: BOOLEAN
performerIncludeInFileName: studioAppend:
displayName: Include Existing Performers displayName: Append Studio
description: Enable to append performer even if performers name already exists in the original file name. description: Enable to append studio name to file name when renaming a file. Requires studio to be included in [Key Fields] list, which by default it is included.
type: BOOLEAN type: BOOLEAN
tagAppend: tagAppend:
displayName: Append Tags displayName: Append Tags
description: Enable to append tag names to file name when renaming a file. Requires tags to be included in [Key Fields] list, which by default it is included. description: Enable to append tag names to file name when renaming a file. Requires tags to be included in [Key Fields] list, which by default it is included.
type: BOOLEAN type: BOOLEAN
tagIncludeInFileName: z_keyFIeldsIncludeInFileName: # Prefixing z_ to variable names so that the GUI will place these fields after above fields (alphabatically listed)
displayName: Include Existing Tags displayName: Include Existing Key Field
description: Enable to append tag name even if tag already exists in original file name. description: Enable to append performer, tags, studios, & galleries even if name already exists in the original file name.
type: BOOLEAN type: BOOLEAN
zFieldKeyList: zafileRenameViaMove:
displayName: Rename Using Move
description: Enable to have file moved when renaming file.
type: BOOLEAN
zfieldKeyList:
displayName: Key Fields displayName: Key Fields
description: "(Default=title,performers,tags) Define key fields to use to format the file name. This is a comma seperated list, and the list should be in the desired format order. For example, if the user wants the performers name before the title, set the performers name first. Example:\"performers,title,tags\". This is an example of user adding height:\"title,performers,tags,height\" Here's an example using all of the supported fields: \"title,performers,tags,studio,date,height,video_codec,frame_rate\"." description: '(Default=title,performers,studio,tags) Define key fields to use to format the file name. This is a comma seperated list, and the list should be in the desired format order. For example, if the user wants the performers name before the title, set the performers name first. Example:"performers,title,tags". This is an example of user adding height:"title,performers,tags,height" Here''s an example using all of the supported fields: "title,performers,tags,studio,galleries,date,height,video_codec,frame_rate".'
type: STRING type: STRING
zgraphqlEndpoint: # Prefixing z_ to variable names so that the GUI will place these fields after above fields (alphabatically listed) zgraphqlEndpoint:
displayName: GraphQL Endpoint displayName: GraphQL Endpoint
description: (Default=http://localhost:9999/graphql). Update with your endpoint, or leave blank to use default. description: (Default=http://localhost:9999/graphql). Update with your endpoint, or leave blank to use default.
type: STRING type: STRING
@@ -46,20 +37,24 @@ settings:
type: NUMBER type: NUMBER
zpathToExclude: zpathToExclude:
displayName: Exclude Path displayName: Exclude Path
description: "Add path(s) to exclude from RenameFile. Example Usage: r\"/path/to/exclude1\" When entering multiple paths, use space. Example: r\"/path_1_to/exclude\" r\"/someOtherPath2Exclude\" r\"/yetAnotherPath\"" description: 'Add path(s) to exclude from RenameFile. Example Usage: r"/path/to/exclude1" When entering multiple paths, use space. Example: r"/path_1_to/exclude" r"/someOtherPath2Exclude" r"/yetAnotherPath"'
type: STRING type: STRING
zseparators: zseparators:
displayName: Separator displayName: Separator
description: "(Default=-) Define the separator to use between different parts of the filename. Example Usage: \",\"" description: '(Default=-) Define the separator to use between different parts of the filename. Example Usage: ","'
type: STRING type: STRING
ztagWhitelist: ztagWhitelist:
displayName: Tag Whitelist displayName: Tag Whitelist
description: "Define a whitelist of allowed tags or EMPTY to allow all tags. Example Usage: \"tag1\", \"tag2\", \"tag3\"" description: 'Define a whitelist of allowed tags or EMPTY to allow all tags. Example Usage: "tag1", "tag2", "tag3"'
type: STRING type: STRING
zzdebugTracing: zzdebugTracing:
displayName: Debug Tracing displayName: Debug Tracing
description: (Default=false) [***For Advanced Users***] Enable debug tracing. When enabled, additional tracing logging is added to Stash\plugins\RenameFile\renamefile.log description: (Default=false) [***For Advanced Users***] Enable debug tracing. When enabled, additional tracing logging is added to Stash\plugins\RenameFile\renamefile.log
type: BOOLEAN type: BOOLEAN
zzdryRun:
displayName: Dry Run
description: Enable to run script in [Dry Run] mode. In dry run mode, files are NOT renamed, and only logging is performed. Use the logging to determine if rename will occur as expected. This should always be enabled on the first run after renamefile_settings.py has been modified.
type: BOOLEAN
exec: exec:
- python - python
- "{pluginDir}/renamefile.py" - "{pluginDir}/renamefile.py"

View File

@@ -10,14 +10,15 @@ config = {
# Define wrapper styles for different parts of the filename. # Define wrapper styles for different parts of the filename.
# Use '[]' for square brackets, '{}' for curly brackets, '()' for parentheses, or an empty string for None. # Use '[]' for square brackets, '{}' for curly brackets, '()' for parentheses, or an empty string for None.
"wrapper_styles": { "wrapper_styles": {
"studio": '[]', # Modify these values to change how each part of the filename is wrapped. "studio": '{}', # Modify these values to change how each part of the filename is wrapped.
"title": '', # Use '[]' for square brackets, '{}' for curly brackets, '()' for parentheses, or an empty string for None. "title": '', # Use '[]' for square brackets, '{}' for curly brackets, '()' for parentheses, or an empty string for None.
"performers": '()', # Modify these values to change how each part of the filename is wrapped. "performers": '()',
"date": '[]', # Use '[]' for square brackets, '{}' for curly brackets, '()' for parentheses, or an empty string for None. "galleries": '()',
"height": '()', # Modify these values to change how each part of the filename is wrapped. "date": '()',
"video_codec": '[]', # Use '[]' for square brackets, '{}' for curly brackets, '()' for parentheses, or an empty string for None. "height": '',
"frame_rate": '[]', # Modify these values to change how each part of the filename is wrapped. "video_codec": '',
"tag": '[]' # Modify these values to change how each tag part of the filename is wrapped. "frame_rate": '',
"tag": '[]'
}, },
# Define whether files should be renamed when moved # Define whether files should be renamed when moved
"rename_files": True, "rename_files": True,

View File

@@ -1 +1,3 @@
stashapp-tools stashapp-tools
pyYAML
requests