renamerOnUpdate

renamerOnUpdate

Using metadata from your Stash to rename/move your file.

Requirement

Installation (manually)

  • Download the whole folder ‘renamerOnUpdate
    • renamerOnUpdate_config.py
    • log.py
    • renamerOnUpdate.py
    • renamerOnUpdate.yml
  • Place it in your plugins folder (where the config.yml is)
  • Reload plugins (Settings > Plugins > Reload)
  • renamerOnUpdate appears

:exclamation: Make sure to copy renamerOnUpdate_config.py to config.py
and configure the plugin before running it :exclamation:

Installation (via manager)

  • Go to Settings > Plugins
  • Find Available Plugins and expand the package called Community (stable).
  • Select renamerOnUpdate and click Install

:exclamation: Make sure to copy renamerOnUpdate_config.py to config.py
and configure the plugin before running it :exclamation:

Usage

  • Everytime you update a scene, it will check/rename your file. An update can be:

    • Saving in Scene Edit.
    • Clicking the Organized button.
    • Running a scan that updates the path.
  • By pressing the button in the Task menu.

    • It will go through each of your scenes.
    • :warning: It’s recommended to understand correctly how this plugin works,
      and use DryRun first.

Configuration

  • Read/Edit config.py

    • Change template filename/path
    • Add log_file path
  • There are multiple buttons in Task menu:

    • Enable: (default) Enable the trigger update
    • Disable: Disable the trigger update
    • Dry-run: A switch to enable/disable dry-run mode
  • Dry-run mode:

    • It prevents editing the file, only shows in your log.
    • This mode can write into a file (dryrun_renamerOnUpdate.txt), the change that the plugin will do.
      • You need to set a path for log_file in renamerOnUpdate_config.py
      • The format will be: scene_id|current path|new path. (e.g. 100|C:\Temp\foo.mp4|C:\Temp\bar.mp4)
      • This file will be overwritten everytime the plugin is triggered.

Custom configuration file

Due to the nature of how plugin updates work, your renamerOnUpdate_config.py
file will get replaced with the fresh copy resetting it to default values.
To work around that you can create a custom config file and use it instead.

  • Create a copy of renamerOnUpdate_config.py
  • Rename your copy to config.py
  • Use the config.py(it will default to renamerOnUpdate_config.py if not found)

[!note]
Since config.py file is not tracked it won’t get updated with new configuration options, so you will need to update it manually.

renamerOnUpdate_config.py explained

Template

To modify your path/filename, you can use variables.
These are elements that will change based on your metadata.

  • Variables are represented with a word preceded with a $ symbol. (E.g. $date)
  • If the metadata exists, this term will be replaced by it:
    • Scene date = 2006-01-02, $date = 2006-01-02
  • You can find the list of available variables in renamerOnUpdate_config.py

In the example below, we will use:

Filename

Change your filename (C:\Temp\QmlnQnVja0J1bm55.mp4)


Priority : Tags > Studios > Default

Filename - Based on a Tag

tag_templates  = {
 "rename_tag": "$year $title - $studio $resolution $video_codec",
 "rename_tag2": "$title"
}
tag new path
rename_tag C:\Temp\2008 Big Buck Bunny - Blender Institute 1080p H264.mp4
rename_tag2 C:\Temp\Big Buck Bunny.mp4

Filename - Based on a Studio

studio_templates  = {
 "Blender Institute": "$date - $title [$studio]",
 "Pixar": "$title [$studio]"
}
studio new path
Blender Institute C:\Temp\2008-05-20 - Big Buck Bunny [Blender Institute].mp4
Pixar C:\Temp\Big Buck Bunny [Pixar].mp4

Filename - Change filename no matter what

use_default_template  =  True
default_template  =  "$date $title"

The file became: C:\Temp\2008-05-20 - Big Buck Bunny.mp4

Path

Change your path (C:\Temp\QmlnQnVja0J1bm55.mp4)

Path - Based on a Tag

p_tag_templates  = {
 "rename_tag": r"D:\Video\\",
 "rename_tag2": r"E:\Video\$year"
}
tag new path
rename_tag D:\Video\QmlnQnVja0J1bm55.mp4
rename_tag2 E:\Video\2008\QmlnQnVja0J1bm55.mp4

Path - Based on a Studio

p_studio_templates  = {
 "Blender Institute": r"D:\Video\Blender\\",
 "Pixar": r"E:\Video\$studio\\"
}
studio new path
Blender Institute D:\Video\Blender\QmlnQnVja0J1bm55.mp4
Pixar E:\Video\Pixar\QmlnQnVja0J1bm55.mp4

Path - Based on a Path

p_path_templates = {
 r"C:\Temp": r"D:\Video\\",
 r"C:\Video": r"E:\Video\Win\\"
}
file path new path
C:\Temp D:\Video\QmlnQnVja0J1bm55.mp4
C:\Video E:\Video\Win\QmlnQnVja0J1bm55.mp4

Path - Change path no matter what

p_use_default_template  =  True
p_default_template  =  r"D:\Video\\"

The file is moved to: D:\Video\QmlnQnVja0J1bm55.mp4

Path - Special Variables

$studio_hierarchy - Create the entire hierarchy of studio
as folder (E.g. ../MindGeek/Brazzers/Hot And Mean/video.mp4). Use your parent studio.

^* - The current directory of the file.
Explanation:

  • If: p_default_template = r"^*\$performer"
  • It creates a folder with a performer name
    in the current directory where the file is.
  • C:\Temp\video.mp4 so ^*=C:\Temp\, result: C:\Temp\Jane Doe\video.mp4
  • If you don’t use prevent_consecutive option,
    the plugin will create a new folder everytime (C:\Temp\Jane Doe\Jane Doe\...\video.mp4).

Advanced

Groups

You can group elements in the template with {},
it’s used when you want to remove a character if a variable is null.

Example:

With date in Stash:

  • [$studio] $date - $title[Blender] 2008-05-20 - Big Buck Bunny

Without date in Stash:

  • [$studio] $date - $title[Blender] - Big Buck Bunny

If you want to use the - only when you have the date,
you can group the - with $date
Without date in Stash:

  • [$studio] {$date -} $title[Blender] Big Buck Bunny
3 Likes
1 Like

I would like to see some sample configurations if someone wouldn’t mind sharing theirs. Here’s mine:

tag_templates = {
    "Hentai": "$date $title"
}
studio_templates = {}
use_default_template = True
default_template = "$date [{$parent_studio, }$studio]{ $performer}{ - $movie_title $movie_scene}{ - $title}{ ($duration $resolution $height $video_codec)}{ ($tags)}"
p_tag_templates = {
    "Webcam": "/public/nsfw/performers/$performer/webcam",
    "JAV": "/public/nsfw/categories/jav/$studio_hierarchy",
    "Movie": "/public/nsfw/studios/$studio_hierarchy",
    "PMV": "/public/nsfw/categories/pmv",
    "HMV": "/public/nsfw/categories/hmv",
    "Hentai": "/public/nsfw/categories/hentai/$studio_hierarchy",
    "Animated": "/public/nsfw/categories/animated",
}
p_studio_templates = {
}
p_path_templates = {}
p_use_default_template = True
p_default_template = r"/public/nsfw/studios/$studio_hierarchy"
p_non_organized = r""
p_tag_option = {}
log_file = r"/home/user/.stash/plugins/community/renamerOnUpdate/rename_log.txt"
associated_extension = ["srt", "vtt", "funscript"]
filename_as_title = False
filename_splitchar = " "
field_whitespaceSeperator = ""
field_replacer = {}
replace_words = {}
date_format = r"%Y-%m-%d"
duration_format = r"%H;%M;%S"
lowercase_Filename = False
titlecase_Filename = False
removecharac_Filename = "#"
performer_splitchar = ", "
performer_limit = 3
performer_limit_keep = True
performer_sort = "name"
performer_ignoreGender = []
duplicate_suffix = ["", "_1", "_2", "_3", "_4", "_5", "_6", "_7", "_8", "_9", "_10"]
prevent_title_performer = False
prevent_consecutive = True
remove_emptyfolder = True
path_one_performer = True
path_noperformer_folder = False
path_keep_alrperf = True
prepositions_list = ["The", "A", "An"]
prepositions_removal = False
squeeze_studio_names = False
rating_format = "{}"
tags_splitchar = ", "
tags_whitelist = [
    "Low Quality", "Trailer"
]
tags_blacklist = [
]
only_organized = True
ignore_path_length = False
order_field = [
    "$video_codec",
    "$audio_codec",
    "$resolution",
    "tags",
    "rating",
    "$height",
    "$title",
    "$studio_family",
    "$studio",
    "$parent_studio",
    "$performer",
]
alt_diff_display = False
batch_number_scene = -1
enable_hook = True
dry_run = False
dry_run_append = True
process_getall = False
process_kill_attach = False
use_ascii = False

First off, thanks for developing and maintaining this plugin—it really helps streamline media organization for many of us!

The main issue I keep running into with this plugin is that sometimes files get renamed incorrectly because Stash misidentifies some scenes, especially with shorter clips. After this happens, I’m stuck: if I manually fix the filename, it just gets auto-renamed again the next time the scene updates. So basically, the only workaround I’ve found is to copy those affected files elsewhere to keep track of them, which isn’t ideal.

Does anyone have any better ideas or solutions for this?
Maybe some way to mark scenes as “locked” so the renamer skips them, or exclude by some criteria? Or any suggestions for alternative methods to avoid this renaming loop with misidentified files?

Would love to hear how others handle this, or if there are any tips from the developer for dealing with this edge case!

Thanks in advance!

You can setup tag to automatically move it to new directory https://discourse.stashapp.cc/t/renameronupdate/1754#p-3298-path-based-on-a-tag-15.

When I set a tag to a scene, the scene file gets duplicated… Any fix to this issue?

What has changed in this version over the original?

The recent develop builds of Stash, and the upcoming stable release introduces,

Partial dates (year only or month/year) are now supported for all date fields. (#6359)

This breaks renamerOnUpdate’s date format handling when it expects to receive dates in the YYYY-MM-DD format but may receive them in YYYY or YYYY-MM format instead.

ERRO[2025-12-16 22:00:01] [Plugin / renamerOnUpdate] main function error: time data ‘2017’ does not match format ‘%Y-%m-%d’
ERRO[2025-12-16 22:00:01] [Plugin / renamerOnUpdate] Traceback (most recent call last):
ERRO[2025-12-16 22:00:01] [Plugin / renamerOnUpdate]   File “/home/voorhees/.stash/plugins/community/renamerOnUpdate/renamerOnUpdate.py”, line 1594, in 
ERRO[2025-12-16 22:00:01] [Plugin / renamerOnUpdate]     renamer(FRAGMENT_SCENE_ID)
ERRO[2025-12-16 22:00:01] [Plugin / renamerOnUpdate]   File “/home/voorhees/.stash/plugins/community/renamerOnUpdate/renamerOnUpdate.py”, line 1295, in renamer
ERRO[2025-12-16 22:00:01] [Plugin / renamerOnUpdate]     scene_information = extract_info(stash_scene, template)
ERRO[2025-12-16 22:00:01] [Plugin / renamerOnUpdate]                         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
ERRO[2025-12-16 22:00:01] [Plugin / renamerOnUpdate]   File “/home/voorhees/.stash/plugins/community/renamerOnUpdate/renamerOnUpdate.py”, line 537, in extract_info
ERRO[2025-12-16 22:00:01] [Plugin / renamerOnUpdate]     date_scene = datetime.strptime(scene_information[“date”], r"%Y-%m-%d")
ERRO[2025-12-16 22:00:01] [Plugin / renamerOnUpdate]                  ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
ERRO[2025-12-16 22:00:01] [Plugin / renamerOnUpdate]   File “/usr/lib/python3.12/_strptime.py”, line 554, in _strptime_datetime
ERRO[2025-12-16 22:00:01] [Plugin / renamerOnUpdate]     tt, fraction, gmtoff_fraction = _strptime(data_string, format)
ERRO[2025-12-16 22:00:01] [Plugin / renamerOnUpdate]                                     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
ERRO[2025-12-16 22:00:01] [Plugin / renamerOnUpdate]   File “/usr/lib/python3.12/_strptime.py”, line 333, in _strptime
ERRO[2025-12-16 22:00:01] [Plugin / renamerOnUpdate]     raise ValueError(“time data %r does not match format %r” %
ERRO[2025-12-16 22:00:01] [Plugin / renamerOnUpdate] ValueError: time data ‘2017’ does not match format ‘%Y-%m-%d’

Can you make an option to only run for scenes that have a StashID?
Such as:
require_stashid = True # Only process scenes with StashIDs