diff --git a/data/interfaces/default/settings.html b/data/interfaces/default/settings.html
index d96df248..0626b92f 100644
--- a/data/interfaces/default/settings.html
+++ b/data/interfaces/default/settings.html
@@ -984,11 +984,20 @@
+
+
+ Group Notifications into TV Show or Artist
+
+
+ Enable to only send one TV show or artist notification when multiple seasons or albums are added. Movies, single episodes, and single tracks are unaffected.
+ Note: A season range can be shown (e.g. 1-3), but all other season/episode/album/track metadata will be unavailable.
diff --git a/plexpy/activity_handler.py b/plexpy/activity_handler.py
index 4830f8dd..128ceacb 100644
--- a/plexpy/activity_handler.py
+++ b/plexpy/activity_handler.py
@@ -303,71 +303,52 @@ class TimelineHandler(object):
metadata = self.get_metadata()
if metadata:
grandparent_rating_key = int(metadata['grandparent_rating_key'])
+ parent_rating_key = int(metadata['parent_rating_key'])
+
+ grandparent_set = RECENTLY_ADDED_QUEUE.get(grandparent_rating_key, set())
+ grandparent_set.add(parent_rating_key)
+ RECENTLY_ADDED_QUEUE[grandparent_rating_key] = grandparent_set
+
+ parent_set = RECENTLY_ADDED_QUEUE.get(parent_rating_key, set())
+ parent_set.add(rating_key)
+ RECENTLY_ADDED_QUEUE[parent_rating_key] = parent_set
logger.debug(u"PlexPy TimelineHandler :: Library item %s (grandparent %s) added to recently added queue."
% (str(rating_key), str(grandparent_rating_key)))
- RECENTLY_ADDED_QUEUE[grandparent_rating_key] = RECENTLY_ADDED_QUEUE.get(grandparent_rating_key, []) + [(media_type, rating_key)]
elif media_type in ('season', 'album'):
metadata = self.get_metadata()
if metadata:
parent_rating_key = int(metadata['parent_rating_key'])
+ parent_set = RECENTLY_ADDED_QUEUE.get(parent_rating_key, set())
+ parent_set.add(rating_key)
+ RECENTLY_ADDED_QUEUE[parent_rating_key] = parent_set
+
logger.debug(u"PlexPy TimelineHandler :: Library item %s (parent %s) added to recently added queue."
% (str(rating_key), str(parent_rating_key)))
- RECENTLY_ADDED_QUEUE[parent_rating_key] = RECENTLY_ADDED_QUEUE.get(parent_rating_key, []) + [(media_type, rating_key)]
else:
+ queue_set = RECENTLY_ADDED_QUEUE.get(rating_key, set())
+ RECENTLY_ADDED_QUEUE[rating_key] = queue_set
+
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_type == 'processed' and media_type and section_id > 0 and metadata_state is None and rating_key in RECENTLY_ADDED_QUEUE:
+ if state_type == 'processed' and media_type in ('movie', 'show', 'artist') and section_id > 0 and metadata_state is None:
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, **kwargs):
- for key in keys: self.on_created(key, **kwargs)
+ child_keys = RECENTLY_ADDED_QUEUE.pop(rating_key, [])
- if plexpy.CONFIG.NOTIFY_GROUP_RECENTLY_ADDED:
- media_type_dict = {}
- for type, key in child_keys:
- media_type_dict[type] = media_type_dict.get(type, []) + [key]
-
- if len(media_type_dict.get('episode', [])) > 1:
- if len(media_type_dict.get('season', [])) > 1:
- 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['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:
- 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['track'])
- else:
- notify_keys(media_type_dict.get('track', []))
-
- notify_keys(media_type_dict.get('movie', []))
+ if plexpy.CONFIG.NOTIFY_GROUP_RECENTLY_ADDED_GRANDPARENT and len(child_keys) > 1:
+ self.on_created(rating_key, child_keys=child_keys)
else:
- notify_keys([key for type, key in child_keys if type in ('movie', 'episode', 'track')])
\ No newline at end of file
+ for child_key in child_keys:
+ grandchild_keys = RECENTLY_ADDED_QUEUE.pop(child_key, [])
+
+ if plexpy.CONFIG.NOTIFY_GROUP_RECENTLY_ADDED_PARENT and len(grandchild_keys) > 1:
+ self.on_created(child_key, child_keys=grandchild_keys)
+
+ else:
+ for grandchild_key in grandchild_keys:
+ self.on_created(grandchild_key)
diff --git a/plexpy/config.py b/plexpy/config.py
index 8d267e47..51e1bd1e 100644
--- a/plexpy/config.py
+++ b/plexpy/config.py
@@ -314,7 +314,9 @@ _CONFIG_DEFINITIONS = {
'NMA_ON_NEWDEVICE': (int, 'NMA', 0),
'NOTIFICATION_THREADS': (int, 'Advanced', 2),
'NOTIFY_CONSECUTIVE': (int, 'Monitoring', 1),
- 'NOTIFY_GROUP_RECENTLY_ADDED': (int, 'Monitoring', 1),
+ 'NOTIFY_GROUP_RECENTLY_ADDED_GRANDPARENT': (int, 'Monitoring', 0),
+ 'NOTIFY_GROUP_RECENTLY_ADDED_PARENT': (int, 'Monitoring', 1),
+ 'NOTIFY_GROUP_RECENTLY_ADDED': (int, 'Monitoring', 0),
'NOTIFY_UPLOAD_POSTERS': (int, 'Monitoring', 0),
'NOTIFY_RECENTLY_ADDED': (int, 'Monitoring', 0),
'NOTIFY_RECENTLY_ADDED_GRANDPARENT': (int, 'Monitoring', 0),
@@ -842,6 +844,8 @@ class Config(object):
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.NOTIFY_GROUP_RECENTLY_ADDED_PARENT = self.NOTIFY_GROUP_RECENTLY_ADDED
+
self.MONITORING_USE_WEBSOCKET = 1
self.HTTP_PROXY = 1
diff --git a/plexpy/notification_handler.py b/plexpy/notification_handler.py
index 687dd92a..3921f6ac 100644
--- a/plexpy/notification_handler.py
+++ b/plexpy/notification_handler.py
@@ -257,13 +257,13 @@ def build_media_notify_params(notify_action=None, session=None, timeline=None, *
server_uptime = 'N/A'
# Get metadata for the item
+ pms_connect = pmsconnect.PmsConnect()
if session:
rating_key = session['rating_key']
+ metadata = pms_connect.get_metadata_details(rating_key=rating_key, get_media_info=True)
elif timeline:
rating_key = timeline['rating_key']
-
- pms_connect = pmsconnect.PmsConnect()
- metadata = pms_connect.get_metadata_details(rating_key=rating_key, get_media_info=True)
+ metadata = timeline
if not metadata:
logger.error(u"PlexPy NotificationHandler :: Unable to retrieve metadata for rating_key %s" % str(rating_key))
@@ -353,65 +353,46 @@ def build_media_notify_params(notify_action=None, session=None, timeline=None, *
else:
full_title = 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 plexpy.CONFIG.NOTIFY_GROUP_RECENTLY_ADDED_GRANDPARENT and metadata['media_type'] in ('show', 'artist'):
+ show_name = metadata['title']
+ episode_name = ''
+ artist_name = metadata['title']
+ album_name = ''
+ track_name = ''
- if notify_action == 'on_created' and plexpy.CONFIG.NOTIFY_GROUP_RECENTLY_ADDED and metadata['media_type'] != 'movie':
- if metadata['media_type'] in ('episode', '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)
+ num, num00 = format_group_index([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
- elif metadata['media_type'] in ('season', '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)
+ episode_num, episode_num00 = '', ''
+ track_num, track_num00 = '', ''
- num, num00 = format_group_index([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 plexpy.CONFIG.NOTIFY_GROUP_RECENTLY_ADDED_PARENT and metadata['media_type'] in ('season', '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)
- elif metadata['media_type'] in ('show', 'artist'):
- show_name = metadata['title']
- episode_name = ''
- artist_name = metadata['title']
- album_name = ''
- track_name = ''
+ num, num00 = format_group_index([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
- num, num00 = format_group_index([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_index([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
+ else:
+ 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)
available_params = {# Global paramaters
'plexpy_version': common.VERSION_NUMBER,
@@ -669,20 +650,23 @@ def strip_tag(data, agent_id=None):
def format_group_index(group_keys):
+ group_keys = sorted(group_keys)
+
num = []
num00 = []
for k, g in groupby(enumerate(group_keys), lambda (i, x): i-x):
group = map(itemgetter(1), g)
+ g_min, g_max = min(group), max(group)
- 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)))
+ if g_min == g_max:
+ num.append('{0:01d}'.format(g_min))
+ num00.append('{0:02d}'.format(g_min))
else:
- num.append(str(group[0]).zfill(1))
- num00.append(str(group[0]).zfill(2))
+ num.append('{0:01d}-{1:01d}'.format(g_min, g_max))
+ num00.append('{0:02d}-{1:02d}'.format(g_min, g_max))
- return ','.join(sorted(num)) or '0', ','.join(sorted(num00)) or '00'
+ return ','.join(num) or '0', ','.join(num00) or '00'
def get_poster_info(metadata):
diff --git a/plexpy/webserve.py b/plexpy/webserve.py
index 5fb74e73..540f36a5 100644
--- a/plexpy/webserve.py
+++ b/plexpy/webserve.py
@@ -2569,7 +2569,8 @@ 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_group_recently_added": checked(plexpy.CONFIG.NOTIFY_GROUP_RECENTLY_ADDED),
+ "notify_group_recently_added_grandparent": checked(plexpy.CONFIG.NOTIFY_GROUP_RECENTLY_ADDED_GRANDPARENT),
+ "notify_group_recently_added_parent": checked(plexpy.CONFIG.NOTIFY_GROUP_RECENTLY_ADDED_PARENT),
"notify_concurrent_by_ip": checked(plexpy.CONFIG.NOTIFY_CONCURRENT_BY_IP),
"notify_concurrent_threshold": plexpy.CONFIG.NOTIFY_CONCURRENT_THRESHOLD,
"notify_watched_percent": plexpy.CONFIG.NOTIFY_WATCHED_PERCENT,
@@ -2607,7 +2608,8 @@ class WebInterface(object):
"movie_notify_enable", "tv_notify_enable", "music_notify_enable",
"refresh_libraries_on_startup", "refresh_users_on_startup",
"movie_logging_enable", "tv_logging_enable", "music_logging_enable",
- "notify_consecutive", "notify_upload_posters", "notify_recently_added", "notify_group_recently_added",
+ "notify_consecutive", "notify_upload_posters", "notify_recently_added",
+ "notify_group_recently_added_grandparent", "notify_group_recently_added_parent",
"monitor_pms_updates", "monitor_remote_access", "get_file_sizes", "log_blacklist", "http_hash_password",
"allow_guest_access", "cache_images", "http_basic_auth", "notify_concurrent_by_ip",
"history_table_activity", "plexpy_auto_update"