diff --git a/data/interfaces/default/css/plexpy.css b/data/interfaces/default/css/plexpy.css index d9a67b65..98edd295 100644 --- a/data/interfaces/default/css/plexpy.css +++ b/data/interfaces/default/css/plexpy.css @@ -2671,6 +2671,12 @@ a .home-platforms-list-cover-face:hover border-radius: 8px; background-clip: padding-box; } +pre::-webkit-scrollbar-track { + background-color: rgba(255,255,255,.2); +} +pre::-webkit-scrollbar-thumb { + background-color: rgba(0,0,0,.15); +} @media only screen and (min-device-width: 300px) diff --git a/data/interfaces/default/settings.html b/data/interfaces/default/settings.html index 6a61c9e5..beb463e6 100644 --- a/data/interfaces/default/settings.html +++ b/data/interfaces/default/settings.html @@ -951,15 +951,10 @@

- Enable to only get one TV Show or Artist notification for a batch of recently added Episodes or Tracks. Movies are unaffected.
- % if config['notify_recently_added_grandparent'] == 'Checked': - Note: No Season/Episode or Album/Track metadata will be available. - % else: - Note: No Season/Episode or Album/Track metadata will be available. - % endif + Enable to only get one TV Show/Season or Artist/Album notification for a batch of recently added Episodes or Tracks. Movies are unaffected.

@@ -1588,27 +1583,27 @@ {season_num} - The season number for the episode. + The season number. (e.g. 1, or 1-3) {season_num00} - The two digit season number. + The two digit season number. (e.g. 01, or 01-03) {episode_num} - The episode number for the episode. + The episode number. (e.g. 6, or 6-10) {episode_num00} - The two digit episode number. + The two digit episode number. (e.g. 06, or 06-10) {track_num} - The track number for the track. + The track number. (e.g. 4, or 4-10) {track_num00} - The two digit track number. + The two digit track number. (e.g. 04, or 04-10) {year} @@ -1815,23 +1810,25 @@

All text inside <movie></movie> tags will only be sent when the media item is a movie.

Example:

-
{user} has started playing {title} <movie>({year})</movie>
+
{title} <movie>({year})</movie> was recently added to Plex
-

TV Tag

+

Show / Season / Episode Tags

-

All text inside <tv></tv> tags will only be sent when the media item is an episode.

+

All text inside <show></show>/<season></season>/<episode></episode> + tags will only be sent when the media item is an show/season/episode.

Example:

-
{user} has started playing {title} <tv>(S{season_num}E{episode_num})</tv>
+
<show>{show_name}</show><seasom>{show_name} - Season {season_num}</season><episode>{show_name} - S{season_num}E{episode_num} - {episode_name}</episode> was recently added to Plex.
-

Music Tag

+

Artist / Album / Track Tag

-

All text inside <music></music> tags will only be sent when the media item is a track.

+

All text inside <artist></artist>/<album></album>/<track></track> + tags will only be sent when the media item is a track.

Example:

-
{user} has started playing {title} <music>(Track {track_num})</music>
+
<artist>{artist_name}</artist><album>{artist_name} - {album_name}</album><track>{artist_name} - {album_name} - {track_name}</track> was recently added to Plex.
diff --git a/plexpy/activity_handler.py b/plexpy/activity_handler.py index cc57aea8..3a062a87 100644 --- a/plexpy/activity_handler.py +++ b/plexpy/activity_handler.py @@ -258,7 +258,7 @@ class TimelineHandler(object): return None - def on_created(self, rating_key): + def on_created(self, rating_key, **kwargs): if self.is_item(): logger.debug(u"PlexPy TimelineHandler :: Library item %s added to Plex." % str(rating_key)) pms_connect = pmsconnect.PmsConnect() @@ -266,7 +266,9 @@ class TimelineHandler(object): if metadata_list: metadata = metadata_list['metadata'] - plexpy.NOTIFY_QUEUE.put({'timeline_data': metadata, 'notify_action': 'on_created'}) + data = {'timeline_data': metadata, 'notify_action': 'on_created'} + data.update(kwargs) + plexpy.NOTIFY_QUEUE.put(data) else: logger.error(u"PlexPy TimelineHandler :: Unable to retrieve metadata for rating_key %s" \ % str(rating_key)) @@ -317,12 +319,12 @@ class TimelineHandler(object): logger.debug(u"PlexPy TimelineHandler :: Library item %s added to recently added queue." % str(rating_key)) RECENTLY_ADDED_QUEUE[rating_key] = RECENTLY_ADDED_QUEUE.get(rating_key, []) + [(media_type, rating_key)] - if state == 5 and media_type and section_id > 0 and rating_key in RECENTLY_ADDED_QUEUE.keys(): + if state == 5 and media_type and section_id > 0 and rating_key in RECENTLY_ADDED_QUEUE: logger.debug(u"PlexPy TimelineHandler :: Library item %s done processing metadata." % str(rating_key)) child_keys = RECENTLY_ADDED_QUEUE.pop(rating_key) - def notify_keys(keys): - for key in keys: self.on_created(key) + def notify_keys(keys, **kwargs): + for key in keys: self.on_created(key, **kwargs) if plexpy.CONFIG.NOTIFY_GROUP_RECENTLY_ADDED: media_type_dict = {} @@ -331,21 +333,39 @@ class TimelineHandler(object): if len(media_type_dict.get('episode', [])) > 1: if len(media_type_dict.get('season', [])) > 1: - notify_keys(media_type_dict.get('show', [])) + if media_type_dict.get('show', []): + notify_keys(media_type_dict['show'], + child_keys=media_type_dict.get('season', []), + grandchild_keys=media_type_dict.get('episode', [])) + else: + notify_keys(media_type_dict['season'], + child_keys=media_type_dict.get('episode', [])) + elif media_type_dict.get('season', []): + notify_keys(media_type_dict['season'], + child_keys=media_type_dict.get('episode', [])) else: - notify_keys(media_type_dict.get('season', media_type_dict.get('episode', []))) + notify_keys(media_type_dict['episode']) else: notify_keys(media_type_dict.get('episode', [])) if len(media_type_dict.get('track', [])) > 1: if len(media_type_dict.get('album', [])) > 1: - notify_keys(media_type_dict.get('artist', [])) + if media_type_dict.get('artist', []): + notify_keys(media_type_dict['artist'], + child_keys=media_type_dict.get('album', []), + grandchild_keys=media_type_dict.get('track', [])) + else: + notify_keys(media_type_dict['album'], + child_keys=media_type_dict.get('track', [])) + elif media_type_dict.get('album', []): + notify_keys(media_type_dict['album'], + child_keys=media_type_dict.get('track', [])) else: - notify_keys(media_type_dict.get('album', media_type_dict.get('track', []))) + notify_keys(media_type_dict['track']) else: notify_keys(media_type_dict.get('track', [])) notify_keys(media_type_dict.get('movie', [])) else: - notify_keys(child_keys) \ No newline at end of file + notify_keys([key for type, key in child_keys if type in ('movie', 'episode', 'track')]) \ No newline at end of file diff --git a/plexpy/activity_pinger.py b/plexpy/activity_pinger.py index e62edadb..64e2f373 100644 --- a/plexpy/activity_pinger.py +++ b/plexpy/activity_pinger.py @@ -258,7 +258,7 @@ def check_recently_added(): if metadata: - if not plexpy.CONFIG.NOTIFY_RECENTLY_ADDED_GRANDPARENT: + if not plexpy.CONFIG.NOTIFY_GROUP_RECENTLY_ADDED: for item in metadata: library_details = library_data.get_details(section_id=item['section_id']) diff --git a/plexpy/config.py b/plexpy/config.py index c1fe3470..e198f171 100644 --- a/plexpy/config.py +++ b/plexpy/config.py @@ -776,19 +776,22 @@ class Config(object): self.CONFIG_VERSION = '2' if self.CONFIG_VERSION == '2': - self.NOTIFY_ON_START_SUBJECT_TEXT = self.NOTIFY_ON_START_SUBJECT_TEXT.replace('{progress}','{progress_duration}') - self.NOTIFY_ON_START_BODY_TEXT = self.NOTIFY_ON_START_BODY_TEXT.replace('{progress}','{progress_duration}') - self.NOTIFY_ON_STOP_SUBJECT_TEXT = self.NOTIFY_ON_STOP_SUBJECT_TEXT.replace('{progress}','{progress_duration}') - self.NOTIFY_ON_STOP_BODY_TEXT = self.NOTIFY_ON_STOP_BODY_TEXT.replace('{progress}','{progress_duration}') - self.NOTIFY_ON_PAUSE_SUBJECT_TEXT = self.NOTIFY_ON_PAUSE_SUBJECT_TEXT.replace('{progress}','{progress_duration}') - self.NOTIFY_ON_PAUSE_BODY_TEXT = self.NOTIFY_ON_PAUSE_BODY_TEXT.replace('{progress}','{progress_duration}') - self.NOTIFY_ON_RESUME_SUBJECT_TEXT = self.NOTIFY_ON_RESUME_SUBJECT_TEXT.replace('{progress}','{progress_duration}') - self.NOTIFY_ON_RESUME_BODY_TEXT = self.NOTIFY_ON_RESUME_BODY_TEXT.replace('{progress}','{progress_duration}') - self.NOTIFY_ON_BUFFER_SUBJECT_TEXT = self.NOTIFY_ON_BUFFER_SUBJECT_TEXT.replace('{progress}','{progress_duration}') - self.NOTIFY_ON_BUFFER_BODY_TEXT = self.NOTIFY_ON_BUFFER_BODY_TEXT.replace('{progress}','{progress_duration}') - self.NOTIFY_ON_WATCHED_SUBJECT_TEXT = self.NOTIFY_ON_WATCHED_SUBJECT_TEXT.replace('{progress}','{progress_duration}') - self.NOTIFY_ON_WATCHED_BODY_TEXT = self.NOTIFY_ON_WATCHED_BODY_TEXT.replace('{progress}','{progress_duration}') - self.NOTIFY_SCRIPTS_ARGS_TEXT = self.NOTIFY_SCRIPTS_ARGS_TEXT.replace('{progress}','{progress_duration}') + def rep(s): + return s.replace('{progress}','{progress_duration}') + + self.NOTIFY_ON_START_SUBJECT_TEXT = rep(self.NOTIFY_ON_START_SUBJECT_TEXT) + self.NOTIFY_ON_START_BODY_TEXT = rep(self.NOTIFY_ON_START_BODY_TEXT) + self.NOTIFY_ON_STOP_SUBJECT_TEXT = rep(self.NOTIFY_ON_STOP_SUBJECT_TEXT) + self.NOTIFY_ON_STOP_BODY_TEXT = rep(self.NOTIFY_ON_STOP_BODY_TEXT) + self.NOTIFY_ON_PAUSE_SUBJECT_TEXT = rep(self.NOTIFY_ON_PAUSE_SUBJECT_TEXT) + self.NOTIFY_ON_PAUSE_BODY_TEXT = rep(self.NOTIFY_ON_PAUSE_BODY_TEXT) + self.NOTIFY_ON_RESUME_SUBJECT_TEXT = rep(self.NOTIFY_ON_RESUME_SUBJECT_TEXT) + self.NOTIFY_ON_RESUME_BODY_TEXT = rep(self.NOTIFY_ON_RESUME_BODY_TEXT) + self.NOTIFY_ON_BUFFER_SUBJECT_TEXT = rep(self.NOTIFY_ON_BUFFER_SUBJECT_TEXT) + self.NOTIFY_ON_BUFFER_BODY_TEXT = rep(self.NOTIFY_ON_BUFFER_BODY_TEXT) + self.NOTIFY_ON_WATCHED_SUBJECT_TEXT = rep(self.NOTIFY_ON_WATCHED_SUBJECT_TEXT) + self.NOTIFY_ON_WATCHED_BODY_TEXT = rep(self.NOTIFY_ON_WATCHED_BODY_TEXT) + self.NOTIFY_SCRIPTS_ARGS_TEXT = rep(self.NOTIFY_SCRIPTS_ARGS_TEXT) self.CONFIG_VERSION = '3' if self.CONFIG_VERSION == '3': @@ -814,3 +817,22 @@ class Config(object): if self.GIT_USER.lower() == 'drzoidberg33': self.GIT_USER = 'JonnyWong16' self.CONFIG_VERSION = '7' + + if self.CONFIG_VERSION == '7': + def rep(s): + return s.replace('','').replace('','').replace('','').replace('','') + + self.NOTIFY_ON_START_SUBJECT_TEXT = rep(self.NOTIFY_ON_START_SUBJECT_TEXT) + self.NOTIFY_ON_START_BODY_TEXT = rep(self.NOTIFY_ON_START_BODY_TEXT) + self.NOTIFY_ON_STOP_SUBJECT_TEXT = rep(self.NOTIFY_ON_STOP_SUBJECT_TEXT) + self.NOTIFY_ON_STOP_BODY_TEXT = rep(self.NOTIFY_ON_STOP_BODY_TEXT) + self.NOTIFY_ON_PAUSE_SUBJECT_TEXT = rep(self.NOTIFY_ON_PAUSE_SUBJECT_TEXT) + self.NOTIFY_ON_PAUSE_BODY_TEXT = rep(self.NOTIFY_ON_PAUSE_BODY_TEXT) + self.NOTIFY_ON_RESUME_SUBJECT_TEXT = rep(self.NOTIFY_ON_RESUME_SUBJECT_TEXT) + self.NOTIFY_ON_RESUME_BODY_TEXT = rep(self.NOTIFY_ON_RESUME_BODY_TEXT) + self.NOTIFY_ON_BUFFER_SUBJECT_TEXT = rep(self.NOTIFY_ON_BUFFER_SUBJECT_TEXT) + self.NOTIFY_ON_BUFFER_BODY_TEXT = rep(self.NOTIFY_ON_BUFFER_BODY_TEXT) + self.NOTIFY_ON_WATCHED_SUBJECT_TEXT = rep(self.NOTIFY_ON_WATCHED_SUBJECT_TEXT) + self.NOTIFY_ON_WATCHED_BODY_TEXT = rep(self.NOTIFY_ON_WATCHED_BODY_TEXT) + self.NOTIFY_SCRIPTS_ARGS_TEXT = rep(self.NOTIFY_SCRIPTS_ARGS_TEXT) + self.CONFIG_VERSION = '8' \ No newline at end of file diff --git a/plexpy/notification_handler.py b/plexpy/notification_handler.py index 143ba615..33af4d6f 100644 --- a/plexpy/notification_handler.py +++ b/plexpy/notification_handler.py @@ -16,6 +16,8 @@ import arrow import bleach +from itertools import groupby +from operator import itemgetter import os import re import threading @@ -53,7 +55,7 @@ def start_threads(num_threads=1): thread.start() -def add_notifier_each(notify_action=None, stream_data=None, timeline_data=None): +def add_notifier_each(notify_action=None, stream_data=None, timeline_data=None, **kwargs): if not notify_action: logger.debug(u"PlexPy NotificationHandler :: Notify called but no action received.") return @@ -69,10 +71,12 @@ def add_notifier_each(notify_action=None, stream_data=None, timeline_data=None): stream_data=stream_data, timeline_data=timeline_data) if conditions: - plexpy.NOTIFY_QUEUE.put({'notifier_id': notifier['id'], - 'notify_action': notify_action, - 'stream_data': stream_data, - 'timeline_data': timeline_data}) + data = {'notifier_id': notifier['id'], + 'notify_action': notify_action, + 'stream_data': stream_data, + 'timeline_data': timeline_data} + data.update(kwargs) + plexpy.NOTIFY_QUEUE.put(data) def notify_conditions(notifier=None, notify_action=None, stream_data=None, timeline_data=None): if stream_data: @@ -131,7 +135,7 @@ def notify_conditions(notifier=None, notify_action=None, stream_data=None, timel return False -def notify(notifier_id=None, notify_action=None, stream_data=None, timeline_data=None): +def notify(notifier_id=None, notify_action=None, stream_data=None, timeline_data=None, **kwargs): notifier_config = notifiers.get_notifier_config(notifier_id=notifier_id) if not notifier_config: @@ -141,7 +145,8 @@ def notify(notifier_id=None, notify_action=None, stream_data=None, timeline_data # Build the notification parameters parameters, metadata = build_media_notify_params(notify_action=notify_action, session=stream_data, - timeline=timeline_data) + timeline=timeline_data, + **kwargs) else: # Build the notification parameters parameters, metadata = build_server_notify_params(notify_action=notify_action) @@ -225,7 +230,7 @@ def set_notify_state(notify_action, notifier, subject, body, session=None, metad logger.error(u"PlexPy NotificationHandler :: Unable to set notify state.") -def build_media_notify_params(notify_action=None, session=None, timeline=None): +def build_media_notify_params(notify_action=None, session=None, timeline=None, **kwargs): # Get time formats date_format = plexpy.CONFIG.DATE_FORMAT.replace('Do','') time_format = plexpy.CONFIG.TIME_FORMAT.replace('Do','') @@ -254,21 +259,32 @@ def build_media_notify_params(notify_action=None, session=None, timeline=None): pms_connect = pmsconnect.PmsConnect() metadata_list = pms_connect.get_metadata_details(rating_key=rating_key) - current_activity = pms_connect.get_current_activity() - sessions = current_activity.get('sessions', []) - stream_count = current_activity.get('stream_count', '') - user_stream_count = sum(1 for d in sessions if d['user_id'] == session['user_id']) if session else '' - if metadata_list: metadata = metadata_list['metadata'] else: logger.error(u"PlexPy NotificationHandler :: Unable to retrieve metadata for rating_key %s" % str(rating_key)) return None, None + child_metadata = grandchild_metadata = [] + if 'child_keys' in kwargs: + for key in kwargs['child_keys']: + child_metadata.append(pms_connect.get_metadata_details(rating_key=key)['metadata']) + if 'grandchild_keys' in kwargs: + for key in kwargs['grandchild_keys']: + grandchild_metadata.append(pms_connect.get_metadata_details(rating_key=key)['metadata']) + + current_activity = pms_connect.get_current_activity() + sessions = current_activity.get('sessions', []) + stream_count = current_activity.get('stream_count', '') + user_stream_count = sum(1 for d in sessions if d['user_id'] == session['user_id']) if session else '' + # Create a title if metadata['media_type'] == 'episode' or metadata['media_type'] == 'track': full_title = '%s - %s' % (metadata['grandparent_title'], metadata['title']) + elif metadata['media_type'] == 'season' or metadata['media_type'] == 'album': + full_title = '%s - %s' % (metadata['parent_title'], + metadata['title']) else: full_title = metadata['title'] @@ -375,19 +391,65 @@ def build_media_notify_params(notify_action=None, session=None, timeline=None): metadata['poster_url'] = poster_url - # Fix metadata params for notify recently added grandparent - if notify_action == 'created' and plexpy.CONFIG.NOTIFY_RECENTLY_ADDED_GRANDPARENT: - show_name = metadata['title'] - episode_name = '' - artist_name = metadata['title'] - album_name = '' - track_name = '' - else: - show_name = metadata['grandparent_title'] - episode_name = metadata['title'] - artist_name = metadata['grandparent_title'] - album_name = metadata['parent_title'] - track_name = metadata['title'] + # Fix metadata params for grouped recently added + show_name = metadata['grandparent_title'] + episode_name = metadata['title'] + artist_name = metadata['grandparent_title'] + album_name = metadata['parent_title'] + track_name = metadata['title'] + season_num = metadata['parent_media_index'].zfill(1) + season_num00 = metadata['parent_media_index'].zfill(2) + episode_num = metadata['media_index'].zfill(1) + episode_num00 = metadata['media_index'].zfill(2) + track_num = metadata['media_index'].zfill(1) + track_num00 = metadata['media_index'].zfill(2) + + if notify_action == 'on_created' and plexpy.CONFIG.NOTIFY_GROUP_RECENTLY_ADDED and metadata['media_type'] != 'movie': + if metadata['media_type'] == 'episode' or metadata['media_type'] == 'track': + show_name = metadata['grandparent_title'] + episode_name = metadata['title'] + artist_name = metadata['grandparent_title'] + album_name = metadata['parent_title'] + track_name = metadata['title'] + season_num = metadata['parent_media_index'].zfill(1) + season_num00 = metadata['parent_media_index'].zfill(2) + episode_num = metadata['media_index'].zfill(1) + episode_num00 = metadata['media_index'].zfill(2) + track_num = metadata['media_index'].zfill(1) + track_num00 = metadata['media_index'].zfill(2) + + elif metadata['media_type'] == 'season' or metadata['media_type'] == 'album': + show_name = metadata['parent_title'] + episode_name = '' + artist_name = metadata['parent_title'] + album_name = metadata['title'] + track_name = '' + season_num = metadata['media_index'].zfill(1) + season_num00 = metadata['media_index'].zfill(2) + + num, num00 = format_group_keys([helpers.cast_to_int(d['media_index']) + for d in child_metadata if d['parent_rating_key'] == rating_key]) + episode_num, episode_num00 = num, num00 + track_num, track_num00 = num, num00 + + elif metadata['media_type'] == 'show' or metadata['media_type'] == 'artist': + show_name = metadata['title'] + episode_name = '' + artist_name = metadata['title'] + album_name = '' + track_name = '' + + num, num00 = format_group_keys([helpers.cast_to_int(d['media_index']) + for d in child_metadata if d['parent_rating_key'] == rating_key]) + season_num, season_num00 = num, num00 + + num, num00 = format_group_keys([helpers.cast_to_int(d['media_index']) + for d in grandchild_metadata if d['grandparent_rating_key'] == rating_key]) + episode_num, episode_num00 = num, num00 + track_num, track_num00 = num, num00 + + else: + pass available_params = {# Global paramaters 'server_name': server_name, @@ -443,12 +505,12 @@ def build_media_notify_params(notify_action=None, session=None, timeline=None): 'artist_name': artist_name, 'album_name': album_name, 'track_name': track_name, - 'season_num': metadata['parent_media_index'].zfill(1), - 'season_num00': metadata['parent_media_index'].zfill(2), - 'episode_num': metadata['media_index'].zfill(1), - 'episode_num00': metadata['media_index'].zfill(2), - 'track_num': metadata['media_index'].zfill(1), - 'track_num00': metadata['media_index'].zfill(2), + 'season_num': season_num, + 'season_num00': season_num00, + 'episode_num': episode_num, + 'episode_num00': episode_num00, + 'track_num': track_num, + 'track_num00': track_num00, 'year': metadata['year'], 'release_date': arrow.get(metadata['originally_available_at']).format(date_format) if metadata['originally_available_at'] else '', @@ -537,16 +599,27 @@ def build_server_notify_params(notify_action=None): def build_notify_text(subject='', body='', notify_action=None, parameters=None, agent_id=None): + media_type = parameters.get('media_type') + + all_tags = r'.*?|' \ + '.*?|.*?|.*?|' \ + '.*?|.*?|.*?' + # Check for exclusion tags - if parameters.get('media_type') == 'movie': - # Regex pattern to remove the text in the tags we don't want - pattern = re.compile(r'||.*?|.*?', re.IGNORECASE | re.DOTALL) - elif parameters.get('media_type') == 'show' or parameters.get('media_type') == 'episode': - # Regex pattern to remove the text in the tags we don't want - pattern = re.compile(r'.*?|||.*?', re.IGNORECASE | re.DOTALL) - elif parameters.get('media_type') == 'artist' or parameters.get('media_type') == 'track': - # Regex pattern to remove the text in the tags we don't want - pattern = re.compile(r'.*?|.*?||', re.IGNORECASE | re.DOTALL) + if media_type == 'movie': + pattern = re.compile(all_tags.replace('.*?', '|'), re.IGNORECASE | re.DOTALL) + elif media_type == 'show': + pattern = re.compile(all_tags.replace('.*?', '|'), re.IGNORECASE | re.DOTALL) + elif media_type == 'season': + pattern = re.compile(all_tags.replace('.*?', '|'), re.IGNORECASE | re.DOTALL) + elif media_type == 'episode': + pattern = re.compile(all_tags.replace('.*?', '|'), re.IGNORECASE | re.DOTALL) + elif media_type == 'artist': + pattern = re.compile(all_tags.replace('.*?', '|'), re.IGNORECASE | re.DOTALL) + elif media_type == 'album': + pattern = re.compile(all_tags.replace('.*?', '|'), re.IGNORECASE | re.DOTALL) + elif media_type == 'track': + pattern = re.compile(all_tags.replace('.*?', '|'), re.IGNORECASE | re.DOTALL) else: pattern = None @@ -611,3 +684,19 @@ def strip_tag(data, agent_id=None): else: whitelist = {} return bleach.clean(data, tags=whitelist.keys(), attributes=whitelist, strip=True) + +def format_group_keys(group_keys): + num = [] + num00 = [] + + for k, g in groupby(enumerate(group_keys), lambda (i, x): i-x): + group = map(itemgetter(1), g) + + if len(group) > 1: + num.append('{0}-{1}'.format(str(min(group)).zfill(1), str(max(group)).zfill(1))) + num00.append('{0}-{1}'.format(str(min(group)).zfill(2), str(max(group)).zfill(2))) + else: + num.append(str(group[0]).zfill(1)) + num00.append(str(group[0]).zfill(2)) + + return ','.join(sorted(num)) or '0', ','.join(sorted(num00)) or '00' diff --git a/plexpy/webserve.py b/plexpy/webserve.py index 3093b102..3bfb9100 100644 --- a/plexpy/webserve.py +++ b/plexpy/webserve.py @@ -2573,7 +2573,7 @@ class WebInterface(object): "notify_consecutive": checked(plexpy.CONFIG.NOTIFY_CONSECUTIVE), "notify_upload_posters": checked(plexpy.CONFIG.NOTIFY_UPLOAD_POSTERS), "notify_recently_added": checked(plexpy.CONFIG.NOTIFY_RECENTLY_ADDED), - "notify_recently_added_grandparent": checked(plexpy.CONFIG.NOTIFY_RECENTLY_ADDED_GRANDPARENT), + "notify_group_recently_added": checked(plexpy.CONFIG.NOTIFY_GROUP_RECENTLY_ADDED), "notify_recently_added_delay": plexpy.CONFIG.NOTIFY_RECENTLY_ADDED_DELAY, "notify_concurrent_by_ip": checked(plexpy.CONFIG.NOTIFY_CONCURRENT_BY_IP), "notify_concurrent_threshold": plexpy.CONFIG.NOTIFY_CONCURRENT_THRESHOLD, @@ -2637,7 +2637,7 @@ class WebInterface(object): "movie_notify_enable", "tv_notify_enable", "music_notify_enable", "monitoring_use_websocket", "refresh_libraries_on_startup", "refresh_users_on_startup", "ip_logging_enable", "movie_logging_enable", "tv_logging_enable", "music_logging_enable", - "notify_consecutive", "notify_upload_posters", "notify_recently_added", "notify_recently_added_grandparent", + "notify_consecutive", "notify_upload_posters", "notify_recently_added", "notify_group_recently_added", "monitor_pms_updates", "monitor_remote_access", "get_file_sizes", "log_blacklist", "http_hash_password", "allow_guest_access", "cache_images", "http_proxy", "http_basic_auth", "notify_concurrent_by_ip", "history_table_activity"