diff --git a/CHANGES.md b/CHANGES.md
index a94b40b2..e2c9af86 100644
--- a/CHANGES.md
+++ b/CHANGES.md
@@ -16,6 +16,7 @@
* Change remove redundant py2 import futures
* Change add jobs to centralise scheduler activities
* Change refactor scene_exceptions
+* Add to config/media-process/File Handling, "Rename TBA" and "Rename any"
* Add config to change media process log message if there is no media to process
* Change view-show text "invalid timeformat" to "time unknown"
diff --git a/gui/slick/interfaces/default/config_postProcessing.tmpl b/gui/slick/interfaces/default/config_postProcessing.tmpl
index a3a4a191..fd207464 100644
--- a/gui/slick/interfaces/default/config_postProcessing.tmpl
+++ b/gui/slick/interfaces/default/config_postProcessing.tmpl
@@ -242,10 +242,30 @@
+
+
+
+
+
+
+
+
diff --git a/sickgear/__init__.py b/sickgear/__init__.py
index 74bf37aa..a5800cb7 100644
--- a/sickgear/__init__.py
+++ b/sickgear/__init__.py
@@ -719,9 +719,9 @@ def init_stage_1(console_logging):
global TV_DOWNLOAD_DIR, PROCESS_METHOD, PROCESS_AUTOMATICALLY, MEDIAPROCESS_INTERVAL, \
POSTPONE_IF_SYNC_FILES, PROCESS_POSITIVE_LOG, EXTRA_SCRIPTS, SG_EXTRA_SCRIPTS, \
DEFAULT_MEDIAPROCESS_INTERVAL, MIN_MEDIAPROCESS_INTERVAL, \
- UNPACK, SKIP_REMOVED_FILES, MOVE_ASSOCIATED_FILES, NFO_RENAME, RENAME_EPISODES, RENAME_TBA_EPISODES, \
- RENAME_NAME_CHANGED_EPISODES, AIRDATE_EPISODES, \
- USE_FAILED_DOWNLOADS, DELETE_FAILED
+ UNPACK, SKIP_REMOVED_FILES, MOVE_ASSOCIATED_FILES, NFO_RENAME, \
+ RENAME_EPISODES, RENAME_TBA_EPISODES, RENAME_NAME_CHANGED_EPISODES, \
+ AIRDATE_EPISODES, USE_FAILED_DOWNLOADS, DELETE_FAILED
# Media Process/Episode Naming
global NAMING_PATTERN, NAMING_MULTI_EP, NAMING_STRIP_YEAR, NAMING_CUSTOM_ABD, NAMING_ABD_PATTERN, \
NAMING_CUSTOM_SPORTS, NAMING_SPORTS_PATTERN, \
diff --git a/sickgear/notifiers/__init__.py b/sickgear/notifiers/__init__.py
index b35ae421..0882a00c 100644
--- a/sickgear/notifiers/__init__.py
+++ b/sickgear/notifiers/__init__.py
@@ -132,7 +132,7 @@ def notify_git_update(new_version=''):
n.notify_git_update(new_version)
-def notify_update_library(ep_obj, flush_q=False):
+def notify_update_library(ep_obj, flush_q=False, include_online=True):
if not flush_q or sickgear.QUEUE_UPDATE_LIBRARY:
@@ -160,7 +160,8 @@ def notify_update_library(ep_obj, flush_q=False):
elif not flush_q:
- n.update_library(show_obj=ep_obj.show_obj, show_name=ep_obj.show_obj.name, ep_obj=ep_obj)
+ n.update_library(show_obj=ep_obj.show_obj, show_name=ep_obj.show_obj.name, ep_obj=ep_obj,
+ include_online=include_online)
if flush_q:
sickgear.QUEUE_UPDATE_LIBRARY = []
diff --git a/sickgear/notifiers/generic.py b/sickgear/notifiers/generic.py
index a9f14ff8..d546b87c 100644
--- a/sickgear/notifiers/generic.py
+++ b/sickgear/notifiers/generic.py
@@ -91,9 +91,13 @@ class BaseNotifier(object):
def notify_git_update(self, *args, **kwargs):
pass
- def update_library(self, **kwargs):
+ def update_library(self, include_online=True, **kwargs):
"""
note: nmj_notifier fires its library update when the notify_download is issued (inside notifiers)
+
+ :param include_online: Set False if to exclude derived notifiers from library updates.
+ For example, Trakt doesn't need to be updated when renaming the episode name part of a filename,
+ therefore, this is set False for that specific notification use case update.
"""
pass
diff --git a/sickgear/notifiers/trakt.py b/sickgear/notifiers/trakt.py
index cb24c4ff..9bdd024f 100644
--- a/sickgear/notifiers/trakt.py
+++ b/sickgear/notifiers/trakt.py
@@ -41,9 +41,10 @@ class TraktNotifier(BaseNotifier):
return True
return False
- def update_library(self, ep_obj=None, **kwargs):
+ def update_library(self, ep_obj=None, include_online=True, **kwargs):
- self._update_collection(ep_obj)
+ if include_online:
+ self._update_collection(ep_obj)
def _update_collection(self, ep_obj):
"""
diff --git a/sickgear/tv.py b/sickgear/tv.py
index 8c2e08f0..ec4ecd49 100644
--- a/sickgear/tv.py
+++ b/sickgear/tv.py
@@ -78,9 +78,9 @@ if coreid_warnings:
tz_p = du_parser()
invalid_date_limit = datetime.date(1900, 1, 1)
-tba_ep_name = re.compile(r'^(episode \d+|tba)$', flags=re.I)
-tba_ep_filename = re.compile(r'\b(episode \d+|tba)\b', flags=re.I)
-ep_name_regex = re.compile(r'%E[._]?N', flags=re.I)
+tba_tvinfo_name = re.compile(r'^(episode \d+|tba)$', flags=re.I)
+tba_file_name = re.compile(r'\b(episode.\d+|tba)\b', flags=re.I)
+pattern_ep_name = re.compile(r'%E[._]?N', flags=re.I)
# status codes for switching tv show source
TVSWITCH_DUPLICATE_SHOW = 0
@@ -4470,20 +4470,20 @@ class TVEpisode(TVEpisodeBase):
if sickgear.RENAME_EPISODES and self.with_ep_name():
ep_filename = os.path.basename(self._location or '')
- ep_basename, ep_ext = os.path.splitext(ep_filename)
+ ep_basename, _ = os.path.splitext(ep_filename)
ep_name_changed = (bool(self._location) and old_name != self._name) or \
(sickgear.RENAME_NAME_CHANGED_EPISODES and bool(ep_basename)
and ep_basename != os.path.basename(self.proper_path()))
- ep_name_tba_changed = (ep_name_changed and bool(tba_ep_name.search(old_name))) or \
- (not bool(tba_ep_name.search(self._name or ''))
- and bool(tba_ep_filename.search(ep_filename or '')))
+ ep_name_tba_changed = (ep_name_changed and bool(tba_tvinfo_name.search(old_name))) or \
+ (not bool(tba_tvinfo_name.search(self._name or ''))
+ and bool(tba_file_name.search(ep_filename or '')))
if ((ep_name_tba_changed and sickgear.RENAME_TBA_EPISODES)
or (ep_name_changed and sickgear.RENAME_NAME_CHANGED_EPISODES)):
- if (re_res := self.rename()):
- notifiers.notify_update_library(self)
+ # noinspection PySimplifyBooleanCheck
+ if re_res := self.rename():
+ notifiers.notify_update_library(self, include_online=False)
elif False == re_res:
- # rename failed
- logger.debug('Failed to change changed episode name based filename')
+ logger.debug('Failed to rename files to TV info episode name')
# shouldn't get here probably
else:
@@ -5144,17 +5144,8 @@ class TVEpisode(TVEpisodeBase):
"""
Just the folder name of the episode
"""
-
if None is pattern:
- # we only use ABD if it's enabled, this is an ABD show, AND this is not a multi-ep
- if self._show_obj.air_by_date and sickgear.NAMING_CUSTOM_ABD and not self.related_ep_obj:
- pattern = sickgear.NAMING_ABD_PATTERN
- elif self._show_obj.sports and sickgear.NAMING_CUSTOM_SPORTS and not self.related_ep_obj:
- pattern = sickgear.NAMING_SPORTS_PATTERN
- elif self._show_obj.anime and sickgear.NAMING_CUSTOM_ANIME:
- pattern = sickgear.NAMING_ANIME_PATTERN
- else:
- pattern = sickgear.NAMING_PATTERN
+ pattern = self.naming_pattern()
# split off the dirs only, if they exist
name_groups = re.split(r'[\\/]', pattern)
@@ -5164,41 +5155,37 @@ class TVEpisode(TVEpisodeBase):
return ''
return self._format_pattern(os.sep.join(name_groups[:-1]), multi)
- def with_ep_name(self):
- """
- returns if the episode naming contain the episode name
- """
- # type: (...) -> bool
- if self._show_obj.air_by_date and sickgear.NAMING_CUSTOM_ABD and not self.related_ep_obj:
- return bool(ep_name_regex.search(sickgear.NAMING_ABD_PATTERN))
- elif self._show_obj.sports and sickgear.NAMING_CUSTOM_SPORTS and not self.related_ep_obj:
- return bool(ep_name_regex.search(sickgear.NAMING_SPORTS_PATTERN))
- elif self._show_obj.anime and sickgear.NAMING_CUSTOM_ANIME:
- return bool(ep_name_regex.search(sickgear.NAMING_ANIME_PATTERN))
- else:
- return bool(ep_name_regex.search(sickgear.NAMING_PATTERN))
-
def formatted_filename(self, pattern=None, multi=None, anime_type=None):
"""
Just the filename of the episode, formatted based on the naming settings
"""
-
- if None is pattern:
- # we only use ABD if it's enabled, this is an ABD show, AND this is not a multi-ep
- if self._show_obj.air_by_date and sickgear.NAMING_CUSTOM_ABD and not self.related_ep_obj:
- pattern = sickgear.NAMING_ABD_PATTERN
- elif self._show_obj.sports and sickgear.NAMING_CUSTOM_SPORTS and not self.related_ep_obj:
- pattern = sickgear.NAMING_SPORTS_PATTERN
- elif self._show_obj.anime and sickgear.NAMING_CUSTOM_ANIME:
- pattern = sickgear.NAMING_ANIME_PATTERN
- else:
- pattern = sickgear.NAMING_PATTERN
-
# split off the dirs only, if they exist
- name_groups = re.split(r'[\\/]', pattern)
+ name_groups = re.split(r'[\\/]', pattern or self.naming_pattern())
return self._format_pattern(name_groups[-1], multi, anime_type)
+ def with_ep_name(self):
+ # type: (...) -> bool
+ """
+ returns if the episode naming contain the episode name
+ """
+ return bool(pattern_ep_name.search(self.naming_pattern()))
+
+ def naming_pattern(self):
+ # type: (...) -> AnyStr
+ """
+ return a naming pattern for this show
+ """
+ # we only use ABD if it's enabled, this is an ABD show, AND this is not a multi-ep
+ if self._show_obj.air_by_date and sickgear.NAMING_CUSTOM_ABD and not self.related_ep_obj:
+ return sickgear.NAMING_ABD_PATTERN
+ if self._show_obj.sports and sickgear.NAMING_CUSTOM_SPORTS and not self.related_ep_obj:
+ return sickgear.NAMING_SPORTS_PATTERN
+ if self._show_obj.anime and sickgear.NAMING_CUSTOM_ANIME:
+ return sickgear.NAMING_ANIME_PATTERN
+
+ return sickgear.NAMING_PATTERN
+
def rename(self):
# type: (...) -> Optional[bool]
"""
diff --git a/sickgear/webserve.py b/sickgear/webserve.py
index c75944f1..05a1b17c 100644
--- a/sickgear/webserve.py
+++ b/sickgear/webserve.py
@@ -8498,20 +8498,20 @@ class ConfigMediaProcess(Config):
t.submenu = self.config_menu('Processing')
return t.respond()
- def save_post_processing(self, tv_download_dir=None, process_automatically=None, mediaprocess_interval=None,
- unpack=None, keep_processed_dir=None, process_method=None,
- extra_scripts='', sg_extra_scripts='',
- rename_episodes=None, airdate_episodes=None,
- move_associated_files=None, postpone_if_sync_files=None, process_positive_log=None,
- naming_custom_abd=None, naming_custom_sports=None, naming_custom_anime=None,
- naming_strip_year=None, use_failed_downloads=None, delete_failed=None,
- skip_removed_files=None, nfo_rename=None,
- xbmc_data=None, xbmc_12plus_data=None, mediabrowser_data=None, sony_ps3_data=None,
- wdtv_data=None, tivo_data=None, mede8er_data=None, kodi_data=None,
- naming_pattern=None, naming_multi_ep=None,
- naming_anime=None, naming_anime_pattern=None, naming_anime_multi_ep=None,
- naming_abd_pattern=None, naming_sports_pattern=None,
- **kwargs): # kwargs picks up deprecated vars sent from legacy UIs
+ def save_post_processing(
+ self, tv_download_dir=None, process_method=None, process_automatically=None, mediaprocess_interval=None,
+ postpone_if_sync_files=None, process_positive_log=None, extra_scripts='', sg_extra_scripts='',
+ unpack=None, skip_removed_files=None, move_associated_files=None, nfo_rename=None,
+ rename_episodes=None, rename_tba_episodes=None, rename_name_changed_episodes=None,
+ airdate_episodes=None, use_failed_downloads=None, delete_failed=None,
+ naming_pattern=None, naming_multi_ep=None, naming_strip_year=None,
+ naming_custom_abd=None, naming_abd_pattern=None,
+ naming_custom_sports=None, naming_sports_pattern=None,
+ naming_custom_anime=None, naming_anime_pattern=None,naming_anime_multi_ep=None, naming_anime=None,
+ kodi_data=None, mede8er_data=None, xbmc_data=None, mediabrowser_data=None,
+ sony_ps3_data=None, tivo_data=None, wdtv_data=None, xbmc_12plus_data=None,
+ keep_processed_dir=None,
+ **kwargs): # kwargs picks up deprecated vars sent from legacy UIs
results = []
@@ -8536,6 +8536,8 @@ class ConfigMediaProcess(Config):
sickgear.EXTRA_SCRIPTS = [x.strip() for x in extra_scripts.split('|') if x.strip()]
sickgear.SG_EXTRA_SCRIPTS = [x.strip() for x in sg_extra_scripts.split('|') if x.strip()]
sickgear.RENAME_EPISODES = config.checkbox_to_value(rename_episodes)
+ sickgear.RENAME_TBA_EPISODES = config.checkbox_to_value(rename_tba_episodes)
+ sickgear.RENAME_NAME_CHANGED_EPISODES = config.checkbox_to_value(rename_name_changed_episodes)
sickgear.AIRDATE_EPISODES = config.checkbox_to_value(airdate_episodes)
sickgear.MOVE_ASSOCIATED_FILES = config.checkbox_to_value(move_associated_files)
sickgear.POSTPONE_IF_SYNC_FILES = config.checkbox_to_value(postpone_if_sync_files)