diff --git a/plugins/renamer/README.md b/plugins/renamer/README.md
deleted file mode 100644
index 053f7a8..0000000
--- a/plugins/renamer/README.md
+++ /dev/null
@@ -1,74 +0,0 @@
-
-# SQLITE Renamer for Stash (Task)
-Using metadata from your stash to rename your file.
-
-## Requirement
-- Stash
-- Python 3+ (Tested on Python v3.9.1 64bit, Win10)
-- Request Module (https://pypi.org/project/requests/)
-- Windows 10 ? (No idea if this work for all OS)
-
-## Installation
-
-- Download the whole folder 'renamer' (config.py, log.py, renamerTask.py/.yml)
-- Place it in your **plugins** folder (where the `config.yml` is)
-- Reload plugins (Settings > Plugins)
-- renamerTask should appear.
-
-### :exclamation: Make sure to configure the plugin by editing `config.py` before running it :exclamation:
-
-## Usage
-
-- You have tasks (Settings > Task):
- - **Dry-Run 🔍**: Don't edit any file, just show in log. It will create `renamer_scan.txt` that contains every edit.
- - **[DRYRUN] Check 10 scenes**: Check 10 scenes (by newest updated).
- - **[DRYRUN] Check all scenes**: Check all scenes.
- - **Process :pencil2:**: Edit your files, **don't touch Stash while doing this task**.
- - **Process scanned scene from Dry-Run task**: Read `renamer_scan.txt` instead of checking all scenes.
- - **Process 10 scenes**: Check 10 scenes (by newest updated).
- - **Process all scenes**: Check all scenes.
-
-## Configuration
-
-- Read/Edit `config.py`
- - I recommend setting the **log_file** as it can be useful to revert.
-- If you have the **renamerOnUpdate** plugin, you can copy the `config.py` from it.
-
-### Example
-
-> Note: The priority is Tag > Studio > Default
-
-The config will be:
-```py
-# Change filename for scenes from 'Vixen' or 'Slayed' studio.
-studio_templates = {
- "Slayed": "$date $performer - $title [$studio]",
- "Vixen": "$performer - $title [$studio]"
-}
-# Change filename if the tag 'rename_tag' is present.
-tag_templates = {
- "rename_tag": "$year $title - $studio $resolution $video_codec",
-}
-# Change filename no matter what
-use_default_template = True
-default_template = "$date $title"
-# Use space as a performer separator
-performer_splitchar = " "
-# If the scene has more than 3 performers, the $performer field will be ignored.
-performer_limit = 3
-```
-The scene was just scanned, everything is default (Title = Filename).
-
-Current filename: `Slayed.21.09.02.Ariana.Marie.Emily.Willis.And.Eliza.Ibarra.XXX.1080p.mp4`
-
-|Stash Field | Value | Filename | Trigger template |
-|--|:---:|--|--|
-| - | *Default* |`Slayed.21.09.02.Ariana.Marie.Emily.Willis.And.Eliza.Ibarra.XXX.1080p.mp4` | default_template
-| ~Title| **Driver**| `Driver.mp4` | default_template
-| +Date| **2021-09-02**| `2021-09-02 Driver.mp4` | default_template
-| +Performer | **Ariana Marie
Emily Willis
Eliza Ibarra**| `2021-09-02 Driver.mp4` | default_template
-| +Studio | **Vixen**| `Ariana Marie Emily Willis Eliza Ibarra - Driver [Vixen].mp4` | studio_templates [Vixen]
-| ~Studio | **Slayed**| `2021-09-02 Ariana Marie Emily Willis Eliza Ibarra - Driver [Slayed].mp4` | studio_templates [Slayed]
-| +Performer | **Elsa Jean**| `2021-09-02 Driver [Slayed].mp4` | studio_templates [Slayed]
**Reach performer_limit**.
-| +Tag | **rename_tag**| `2021 Driver - Slayed HD h264.mp4` | tag_templates [rename_tag]
-
diff --git a/plugins/renamer/config.py b/plugins/renamer/config.py
deleted file mode 100644
index b2421d7..0000000
--- a/plugins/renamer/config.py
+++ /dev/null
@@ -1,88 +0,0 @@
-###################################################################
-#
-# -----------------------------------------------------------------
-# Available: $date $year $performer $title $height $resolution $studio $parent_studio $studio_family $video_codec $audio_codec
-# -note:
-# $studio_family: If parent studio exist use it, else use the studio name.
-# $performer: If more than * performers, this field will be ignored. Limit to fix at Settings section below (default: 3)
-# $resolution: SD/HD/UHD/VERTICAL (for phone) | $height: 720p 1080p 4k 8k
-# -----------------------------------------------------------------
-# e.g.:
-# $title == Her Fantasy Ball
-# $date $title == 2016-12-29 Her Fantasy Ball
-# $year $title $height == 2016 Her Fantasy Ball 1080p
-# $date $performer - $title [$studio] == 2016-12-29 Eva Lovia - Her Fantasy Ball [Sneaky Sex]
-# $parent_studio $date $performer - $title == Reality Kings 2016-12-29 Eva Lovia - Her Fantasy Ball
-#
-####################################################################
-# TEMPLATE #
-
-# Priority : Tags > Studios > Default
-
-# templates to use for given tags
-# add or remove as needed
-tag_templates = {
- "!1. Western": "$date $performer - $title [$studio]",
- "!1. JAV": "$title",
- "!1. Anime": "$title $date [$studio]"
-}
-
-# adjust the below if you want to use studio names instead of tags for the renaming templates
-studio_templates = {
-
-}
-
-# change to True to use the default template if no specific tag/studio is found
-use_default_template = False
-# default template, adjust as needed
-default_template = "$date $title"
-
-######################################
-# Logging #
-
-# File to save what is renamed, can be useful if you need to revert changes.
-# Will look like: IDSCENE|OLD_PATH|NEW_PATH
-# Leave Blank ("") or use None if you don't want to use a log file, or a working path like: C:\Users\USERNAME\.stash\plugins\Hooks\rename_log.txt
-log_file = r""
-
-######################################
-# Settings #
-
-# Character to use as a performer separator.
-performer_splitchar = " "
-# Maximum number of performer names in the filename. If there are more than that in a scene the filename will not include any performer names!
-performer_limit = 3
-# ignore male performers.
-performer_ignore_male = False
-
-# If $performer is before $title, prevent having duplicate text.
-# e.g.:
-# Template used: $year $performer - $title
-# 2016 Dani Daniels - Dani Daniels in ***.mp4 --> 2016 Dani Daniels in ***.mp4
-prevent_title_performer = False
-
-# Only rename 'Organized' scenes.
-only_organized = False
-# Field to remove if the path is too long. First in list will be removed then second then ... if length is still too long.
-order_field = ["$video_codec", "$audio_codec", "$resolution", "$height", "$studio_family", "$studio", "$parent_studio","$performer"]
-# Alternate way to show diff. Not useful at all.
-alt_diff_display = False
-
-######################################
-# Module Related #
-
-# ! OPTIONAL module settings. Not needed for basic operation !
-
-# = psutil module (https://pypi.org/project/psutil/) =
-# Gets a list of all processes instead of stopping after the first one. Enabling it slows down the plugin
-process_getall = False
-# If the file is used by a process, the plugin will kill it. IT CAN MAKE STASH CRASH TOO.
-process_kill_attach = False
-# =========================
-
-# = Unidecode module (https://pypi.org/project/Unidecode/) =
-# Check site mentioned for more details.
-# TL;DR: Prevent having non common characters by replacing them.
-# Warning: If you have non-latin characters (Cyrillic, Kanji, Arabic, ...), the result will be extremely different.
-use_ascii = False
-# =========================
diff --git a/plugins/renamer/log.py b/plugins/renamer/log.py
deleted file mode 100644
index f381252..0000000
--- a/plugins/renamer/log.py
+++ /dev/null
@@ -1,52 +0,0 @@
-import sys
-
-
-# Log messages sent from a plugin instance are transmitted via stderr and are
-# encoded with a prefix consisting of special character SOH, then the log
-# level (one of t, d, i, w, e, or p - corresponding to trace, debug, info,
-# warning, error and progress levels respectively), then special character
-# STX.
-#
-# The LogTrace, LogDebug, LogInfo, LogWarning, and LogError methods, and their equivalent
-# formatted methods are intended for use by plugin instances to transmit log
-# messages. The LogProgress method is also intended for sending progress data.
-#
-
-def __prefix(level_char):
- start_level_char = b'\x01'
- end_level_char = b'\x02'
-
- ret = start_level_char + level_char + end_level_char
- return ret.decode()
-
-
-def __log(level_char, s):
- if level_char == "":
- return
-
- print(__prefix(level_char) + s + "\n", file=sys.stderr, flush=True)
-
-
-def LogTrace(s):
- __log(b't', s)
-
-
-def LogDebug(s):
- __log(b'd', s)
-
-
-def LogInfo(s):
- __log(b'i', s)
-
-
-def LogWarning(s):
- __log(b'w', s)
-
-
-def LogError(s):
- __log(b'e', s)
-
-
-def LogProgress(p):
- progress = min(max(0, p), 1)
- __log(b'p', str(progress))
diff --git a/plugins/renamer/renamerTask.py b/plugins/renamer/renamerTask.py
deleted file mode 100644
index b4fb40b..0000000
--- a/plugins/renamer/renamerTask.py
+++ /dev/null
@@ -1,647 +0,0 @@
-import difflib
-import json
-import os
-import re
-import sqlite3
-import subprocess
-import sys
-import time
-
-import requests
-
-try:
- import psutil # pip install psutil
- MODULE_PSUTIL = True
-except:
- MODULE_PSUTIL = False
-
-try:
- import unidecode # pip install Unidecode
- MODULE_UNIDECODE = True
-except:
- MODULE_UNIDECODE = False
-
-import config
-import log
-
-
-FRAGMENT = json.loads(sys.stdin.read())
-FRAGMENT_SERVER = FRAGMENT["server_connection"]
-PLUGIN_DIR = FRAGMENT_SERVER["PluginDir"]
-PLUGIN_ARGS = FRAGMENT['args'].get("mode")
-
-log.LogDebug("--Starting Plugin 'Renammer'--")
-
-#log.LogDebug("{}".format(FRAGMENT))
-
-def callGraphQL(query, variables=None, raise_exception=True):
- # Session cookie for authentication
- graphql_port = FRAGMENT_SERVER['Port']
- graphql_scheme = FRAGMENT_SERVER['Scheme']
- graphql_cookies = {
- 'session': FRAGMENT_SERVER.get('SessionCookie').get('Value')
- }
- graphql_headers = {
- "Accept-Encoding": "gzip, deflate, br",
- "Content-Type": "application/json",
- "Accept": "application/json",
- "Connection": "keep-alive",
- "DNT": "1"
- }
- graphql_domain = 'localhost'
- # Stash GraphQL endpoint
- graphql_url = graphql_scheme + "://" + graphql_domain + ":" + str(graphql_port) + "/graphql"
-
- json = {'query': query}
- if variables is not None:
- json['variables'] = variables
- try:
- response = requests.post(graphql_url, json=json,headers=graphql_headers, cookies=graphql_cookies, timeout=20)
- except Exception as e:
- exit_plugin(err="[FATAL] Exception with GraphQL request. {}".format(e))
- if response.status_code == 200:
- result = response.json()
- if result.get("error"):
- for error in result["error"]["errors"]:
- if raise_exception:
- raise Exception("GraphQL error: {}".format(error))
- else:
- log.LogError("GraphQL error: {}".format(error))
- return None
- if result.get("data"):
- return result.get("data")
- elif response.status_code == 401:
- exit_plugin(err="HTTP Error 401, Unauthorised.")
- else:
- raise ConnectionError("GraphQL query failed: {} - {}".format(response.status_code, response.content))
-
-
-def graphql_getScene(scene_id):
- query = """
- query FindScene($id: ID!, $checksum: String) {
- findScene(id: $id, checksum: $checksum) {
- ...SceneData
- }
- }
- fragment SceneData on Scene {
- id
- checksum
- oshash
- title
- details
- url
- date
- rating
- o_counter
- organized
- path
- phash
- interactive
- file {
- size
- duration
- video_codec
- audio_codec
- width
- height
- framerate
- bitrate
- }
- studio {
- ...SlimStudioData
- }
- movies {
- movie {
- ...MovieData
- }
- scene_index
- }
- tags {
- ...SlimTagData
- }
- performers {
- ...PerformerData
- }
- }
- fragment SlimStudioData on Studio {
- id
- name
- parent_studio {
- id
- name
- }
- details
- rating
- aliases
- }
- fragment MovieData on Movie {
- id
- checksum
- name
- aliases
- date
- rating
- director
- studio {
- ...SlimStudioData
- }
- synopsis
- url
- }
- fragment SlimTagData on Tag {
- id
- name
- aliases
- }
- fragment PerformerData on Performer {
- id
- checksum
- name
- url
- gender
- twitter
- instagram
- birthdate
- ethnicity
- country
- eye_color
- height
- measurements
- fake_tits
- career_length
- tattoos
- piercings
- aliases
- favorite
- tags {
- ...SlimTagData
- }
- rating
- details
- death_date
- hair_color
- weight
- }
- """
- variables = {
- "id": scene_id
- }
- result = callGraphQL(query, variables)
- return result.get('findScene')
-
-
-def graphql_getConfiguration():
- query = """
- query Configuration {
- configuration {
- general {
- databasePath
- }
- }
- }
- """
- result = callGraphQL(query)
- return result.get('configuration')
-
-
-def graphql_findScene(perPage,direc="DESC"):
- query = """
- query FindScenes($filter: FindFilterType) {
- findScenes(filter: $filter) {
- count
- scenes {
- ...SlimSceneData
- }
- }
- }
- fragment SlimSceneData on Scene {
- id
- checksum
- oshash
- title
- details
- url
- date
- rating
- o_counter
- organized
- path
- phash
- interactive
- scene_markers {
- id
- title
- seconds
- }
- galleries {
- id
- path
- title
- }
- studio {
- id
- name
- }
- movies {
- movie {
- id
- name
- }
- scene_index
- }
- tags {
- id
- name
- }
- performers {
- id
- name
- gender
- favorite
- }
- }
- """
- # ASC DESC
- variables = {'filter': {"direction": direc, "page": 1, "per_page": perPage, "sort": "updated_at"}}
- result = callGraphQL(query, variables)
- return result.get("findScenes")
-
-
-def makeFilename(scene_information, query):
- new_filename = str(query)
- for field in TEMPLATE_FIELD:
- field_name = field.replace("$","")
- if field in new_filename:
- if scene_information.get(field_name):
- if field == "$performer":
- if re.search(r"\$performer[-\s_]*\$title", new_filename) and scene_information.get('title') and PREVENT_TITLE_PERF:
- if re.search("^{}".format(scene_information["performer"]), scene_information["title"]):
- log.LogInfo("Ignoring the performer field because it's already in start of title")
- new_filename = re.sub('\$performer[-\s_]*', '', new_filename)
- continue
- new_filename = new_filename.replace(field, scene_information[field_name])
- else:
- new_filename = re.sub('\${}[-\s_]*'.format(field_name), '', new_filename)
-
- # remove []
- new_filename = re.sub('\[\W*]', '', new_filename)
- # Remove multiple space/_ in row
- new_filename = re.sub('[\s_]{2,}', ' ', new_filename)
- # Remove multiple - in row
- new_filename = re.sub('(?:[\s_]-){2,}', ' -', new_filename)
- # Remove space at start/end
- new_filename = new_filename.strip(" -")
- return new_filename
-
-
-def find_diff_text(a, b):
- addi = minus = stay = ""
- minus_ = addi_ = 0
- for _, s in enumerate(difflib.ndiff(a, b)):
- if s[0] == ' ':
- stay += s[-1]
- minus += "*"
- addi += "*"
- elif s[0] == '-':
- minus += s[-1]
- minus_ += 1
- elif s[0] == '+':
- addi += s[-1]
- addi_ += 1
- if minus_ > 20 or addi_ > 20:
- log.LogDebug("Diff Checker: +{}; -{};".format(addi_,minus_))
- log.LogDebug("OLD: {}".format(a))
- log.LogDebug("NEW: {}".format(b))
- else:
- log.LogDebug("Original: {}\n- Charac: {}\n+ Charac: {}\n Result: {}".format(a, minus, addi, b))
- return
-
-
-def has_handle(fpath,all_result=False):
- lst = []
- for proc in psutil.process_iter():
- try:
- for item in proc.open_files():
- if fpath == item.path:
- if all_result:
- lst.append(proc)
- else:
- return proc
- except Exception:
- pass
- return lst
-
-
-def exit_plugin(msg=None, err=None):
- if msg is None and err is None:
- msg = "plugin ended"
- output_json = {"output": msg, "error": err}
- print(json.dumps(output_json))
- sys.exit()
-
-
-def renamer(scene_id):
- filename_template = None
- STASH_SCENE = graphql_getScene(scene_id)
- # ================================================================ #
- # RENAMER #
- # Tags > Studios > Default
-
- # Default
- if config.use_default_template:
- filename_template = config.default_template
-
- # Change by Studio
- if STASH_SCENE.get("studio") and config.studio_templates:
- if config.studio_templates.get(STASH_SCENE["studio"]["name"]):
- filename_template = config.studio_templates[STASH_SCENE["studio"]["name"]]
- # by Parent
- if STASH_SCENE["studio"].get("parent_studio"):
- if config.studio_templates.get(STASH_SCENE["studio"]["name"]):
- filename_template = config.studio_templates[STASH_SCENE["studio"]["name"]]
-
- # Change by Tag
- if STASH_SCENE.get("tags") and config.tag_templates:
- for tag in STASH_SCENE["tags"]:
- if config.tag_templates.get(tag["name"]):
- filename_template = config.tag_templates[tag["name"]]
- break
-
- # END #
- ####################################################################
-
- if config.only_organized and not STASH_SCENE["organized"]:
- return("Scene ignored (not organized)")
-
- if not filename_template:
- return("No template for this scene.")
-
- #log.LogDebug("Using this template: {}".format(filename_template))
-
- current_path = STASH_SCENE["path"]
- # note: contain the dot (.mp4)
- file_extension = os.path.splitext(current_path)[1]
- # note: basename contains the extension
- current_filename = os.path.basename(current_path)
- current_directory = os.path.dirname(current_path)
-
- # Grabbing things from Stash
- scene_information = {}
-
- # Grab Title (without extension if present)
- if STASH_SCENE.get("title"):
- # Removing extension if present in title
- scene_information["title"] = re.sub("{}$".format(file_extension), "", STASH_SCENE["title"])
-
- # Grab Date
- scene_information["date"] = STASH_SCENE.get("date")
-
- # Grab Performer
- if STASH_SCENE.get("performers"):
- perf_list = ""
- perf_count = 0
-
- for perf in STASH_SCENE["performers"]:
- #log.LogDebug(performer)
- if PERFORMER_IGNORE_MALE and perf["gender"] == "MALE":
- continue
-
- if perf_count > PERFORMER_LIMIT:
- # We've already exceeded the limit. No need to keep checking
- break
-
- perf_list += perf["name"] + PERFORMER_SPLITCHAR
- perf_count += 1
-
- # Remove last character
- perf_list = perf_list[:-len(PERFORMER_SPLITCHAR)]
-
- if perf_count > PERFORMER_LIMIT:
- log.LogInfo("More than {} performer(s). Ignoring $performer".format(PERFORMER_LIMIT))
- perf_list = ""
-
- scene_information["performer"] = perf_list
-
- # Grab Studio name
- if STASH_SCENE.get("studio"):
- scene_information["studio"] = STASH_SCENE["studio"].get("name")
- scene_information["studio_family"] = scene_information["studio"]
- # Grab Parent name
- if STASH_SCENE["studio"].get("parent_studio"):
- scene_information["parent_studio"] = STASH_SCENE["studio"]["parent_studio"]["name"]
- scene_information["studio_family"] = scene_information["parent_studio"]
-
- # Grab Height (720p,1080p,4k...)
- scene_information["resolution"] = 'SD'
- scene_information["height"] = "{}p".format(STASH_SCENE["file"]["height"])
- if STASH_SCENE["file"]["height"] >= 720:
- scene_information["resolution"] = 'HD'
- if STASH_SCENE["file"]["height"] >= 2160:
- scene_information["height"] = '4k'
- scene_information["resolution"] = 'UHD'
- if STASH_SCENE["file"]["height"] >= 4320:
- scene_information["height"] = '8k'
- # For Phone ?
- if STASH_SCENE["file"]["height"] > STASH_SCENE["file"]["width"]:
- scene_information["resolution"] = 'VERTICAL'
-
- scene_information["video_codec"] = STASH_SCENE["file"]["video_codec"]
- scene_information["audio_codec"] = STASH_SCENE["file"]["audio_codec"]
-
- log.LogDebug("[{}] Scene information: {}".format(scene_id,scene_information))
-
- if scene_information.get("date"):
- scene_information["year"] = scene_information["date"][0:4]
-
-
- # Create the new filename
- new_filename = makeFilename(scene_information, filename_template) + file_extension
-
- # Remove illegal character for Windows ('#' and ',' is not illegal you can remove it)
- new_filename = re.sub('[\\/:"*?<>|#,]+', '', new_filename)
-
- # Trying to remove non standard character
- if MODULE_UNIDECODE and UNICODE_USE:
- new_filename = unidecode.unidecode(new_filename, errors='preserve')
- else:
- # Using typewriter for Apostrophe
- new_filename = re.sub("[’‘]+", "'", new_filename)
-
- # Replace the old filename by the new in the filepath
- new_path = current_path.rstrip(current_filename) + new_filename
-
- # Trying to prevent error with long path for Win10
- # https://docs.microsoft.com/en-us/windows/win32/fileio/maximum-file-path-limitation?tabs=cmd
- if len(new_path) > 240:
- log.LogWarning("The Path is too long ({})...".format(len(new_path)))
- for word in ORDER_SHORTFIELD:
- if word not in filename_template:
- continue
- filename_template = re.sub('\{}[-\s_]*'.format(word), '', filename_template).strip()
- log.LogDebug("Removing field: {}".format(word))
- new_filename = makeFilename(scene_information, filename_template) + file_extension
- new_path = current_path.rstrip(current_filename) + new_filename
- if len(new_path) < 240:
- log.LogInfo("Reduced filename to: {}".format(new_filename))
- break
- if len(new_path) > 240:
- return("Can't manage to reduce the path, operation aborted.")
-
- #log.LogDebug("Filename: {} -> {}".format(current_filename,new_filename))
- #log.LogDebug("Path: {} -> {}".format(current_path,new_path))
-
- if (new_path == current_path):
- return("Filename already correct. ({})".format(current_filename))
-
- if ALT_DIFF_DISPLAY:
- find_diff_text(current_filename,new_filename)
- else:
- log.LogDebug("[OLD] Filename: {}".format(current_filename))
- log.LogDebug("[NEW] Filename: {}".format(new_filename))
- if DRY_RUN:
- with open(FILE_DRYRUN_RESULT, 'a', encoding='utf-8') as f:
- f.write("{}|{}|{}\n".format(scene_id, current_filename, new_filename))
- return("[Dry-run] Writing in {}".format(FILE_DRYRUN_RESULT))
-
-
- # Connect to the DB
- try:
- sqliteConnection = sqlite3.connect(STASH_DATABASE)
- cursor = sqliteConnection.cursor()
- log.LogDebug("Python successfully connected to SQLite")
- except sqlite3.Error as error:
- return("FATAL SQLITE Error: {}".format(error))
-
- # Looking for duplicate filename
- folder_name = os.path.basename(os.path.dirname(new_path))
- cursor.execute("SELECT id FROM scenes WHERE path LIKE ? AND NOT id=?;", ["%" + folder_name + "_" + new_filename, scene_id])
- dupl_check = cursor.fetchall()
- if len(dupl_check) > 0:
- for dupl_row in dupl_check:
- log.LogError("Same path: [{}]".format(dupl_row[0]))
- return("Duplicate path detected, check log!")
-
- cursor.execute("SELECT id FROM scenes WHERE path LIKE ? AND NOT id=?;", ["%" + new_filename, scene_id])
- dupl_check = cursor.fetchall()
- if len(dupl_check) > 0:
- for dupl_row in dupl_check:
- log.LogInfo("Same filename: [{}]".format(dupl_row[0]))
-
- # OS Rename
- if (os.path.isfile(current_path) == True):
- try:
- os.rename(current_path, new_path)
- except PermissionError as err:
- if "[WinError 32]" in str(err) and MODULE_PSUTIL:
- log.LogWarning("A process use this file, trying to find it (Probably FFMPEG)")
- # Find what process access the file, it's ffmpeg for sure...
- process_use = has_handle(current_path, PROCESS_ALLRESULT)
- if process_use:
- # Terminate the process then try again to rename
- log.LogDebug("Process that use this file: {}".format(process_use))
- if PROCESS_KILL:
- p = psutil.Process(process_use.pid)
- p.terminate()
- p.wait(10)
- # If we don't manage to close it, this will create a error again.
- os.rename(current_path, new_path)
- else:
- return("A process prevent editing the file.")
- else:
- log.LogError(err)
- return ""
- if (os.path.isfile(new_path) == True):
- log.LogInfo("[OS] File Renamed!")
- if LOGFILE:
- with open(LOGFILE, 'a', encoding='utf-8') as f:
- f.write("{}|{}|{}\n".format(scene_id, current_path, new_path))
- else:
- # I don't think it's possible.
- return("[OS] File failed to rename ? {}".format(new_path))
- else:
- return("[OS] File don't exist in your Disk/Drive ({})".format(current_path))
-
- # Database rename
- cursor.execute("UPDATE scenes SET path=? WHERE id=?;", [new_path, scene_id])
- sqliteConnection.commit()
- # Close DB
- cursor.close()
- sqliteConnection.close()
- log.LogInfo("[SQLITE] Database updated and closed!")
- return ""
-
-
-# File that show what we will changed.
-FILE_DRYRUN_RESULT = os.path.join(PLUGIN_DIR, "renamer_scan.txt")
-
-STASH_CONFIG = graphql_getConfiguration()
-STASH_DATABASE = STASH_CONFIG["general"]["databasePath"]
-TEMPLATE_FIELD = "$date $year $performer $title $height $resolution $studio $parent_studio $studio_family $video_codec $audio_codec".split(" ")
-
-# READING CONFIG
-
-LOGFILE = config.log_file
-PERFORMER_SPLITCHAR = config.performer_splitchar
-PERFORMER_LIMIT = config.performer_limit
-PERFORMER_IGNORE_MALE = config.performer_ignore_male
-PREVENT_TITLE_PERF = config.prevent_title_performer
-
-PROCESS_KILL = config.process_kill_attach
-PROCESS_ALLRESULT = config.process_getall
-UNICODE_USE = config.use_ascii
-
-ORDER_SHORTFIELD = config.order_field
-ALT_DIFF_DISPLAY = config.alt_diff_display
-
-# Task
-scenes = None
-progress = 0
-start_time = time.time()
-
-if PLUGIN_ARGS in ["Process_test","Process_full","Process_dry"]:
- DRY_RUN = False
-else:
- log.LogDebug("Dry-Run enable")
- DRY_RUN = True
-
-if PLUGIN_ARGS in ["DRYRUN_test","Process_test"]:
- scenes = graphql_findScene(10, "DESC")
-if PLUGIN_ARGS in ["DRYRUN_full","Process_full"]:
- scenes = graphql_findScene(-1, "ASC")
-if PLUGIN_ARGS == "Process_dry":
- if os.path.exists(FILE_DRYRUN_RESULT):
- scenes = {"scenes":[]}
- with open(FILE_DRYRUN_RESULT, 'r', encoding='utf-8') as f:
- for line in f:
- scene_id_file = line.split("|")[0]
- scenes["scenes"].append({"id": scene_id_file})
- else:
- exit_plugin(err="Can't find the file from the dry-run ({}). Be sure to run a Dry-Run task before.".format(FILE_DRYRUN_RESULT))
-
-if not scenes:
- exit_plugin(err="no scene")
-
-log.LogDebug("Count scenes: {}".format(len(scenes["scenes"])))
-progress_step = 1 / len(scenes["scenes"])
-
-for scene in scenes["scenes"]:
- msg = renamer(scene["id"])
- if msg:
- log.LogDebug(msg)
- progress += progress_step
- log.LogProgress(progress)
-
-if PLUGIN_ARGS == "Process_dry":
- os.remove(FILE_DRYRUN_RESULT)
-
-if DRY_RUN:
- num_lines = 0
- if os.path.exists(FILE_DRYRUN_RESULT):
- num_lines = sum(1 for _ in open(FILE_DRYRUN_RESULT, encoding='utf-8'))
- if num_lines > 0:
- log.LogInfo("[DRY-RUN] There wil be {} file(s) changed. Check {} for more details".format(num_lines, FILE_DRYRUN_RESULT))
- else:
- log.LogInfo("[DRY-RUN] No change to do.")
-
-log.LogInfo("Took {} seconds".format(round(time.time() - start_time)))
-exit_plugin("Successful!")
diff --git a/plugins/renamer/renamerTask.yml b/plugins/renamer/renamerTask.yml
deleted file mode 100644
index d629c50..0000000
--- a/plugins/renamer/renamerTask.yml
+++ /dev/null
@@ -1,29 +0,0 @@
-name: renamerTask
-description: Rename filename based to a template.
-url: https://github.com/stashapp/CommunityScripts
-version: 1.1
-exec:
- - python
- - "{pluginDir}/renamerTask.py"
-interface: raw
-tasks:
- - name: '[DRYRUN] Check 10 scenes'
- description: Only check 10 scenes. Just show in log and create a file with the possible change.
- defaultArgs:
- mode: DRYRUN_test
- - name: '[DRYRUN] Check all scenes'
- description: Check all scenes. Just show in log and create a file with the possible change.
- defaultArgs:
- mode: DRYRUN_full
- - name: 'Process scanned scene from Dry-Run task'
- description: Edit scenes listed on the textfile from the Dry-Run task. ! Don't do anything in Stash in same time !
- defaultArgs:
- mode: Process_dry
- - name: 'Process 10 scenes'
- description: Edit the filename (if needed) for 10 scenes. ! Don't do anything in Stash in same time !
- defaultArgs:
- mode: Process_test
- - name: 'Process all scenes'
- description: Edit the filename (if needed) for all scenes. ! Don't do anything in Stash in same time !
- defaultArgs:
- mode: Process_full