mirror of
https://github.com/Tautulli/Tautulli.git
synced 2025-07-08 06:00:51 -07:00
Option to group recently added by parent or grandparent
This commit is contained in:
parent
a13f84fbf6
commit
5aaa014207
5 changed files with 97 additions and 117 deletions
|
@ -984,11 +984,20 @@
|
||||||
|
|
||||||
<div class="checkbox">
|
<div class="checkbox">
|
||||||
<label>
|
<label>
|
||||||
<input type="checkbox" name="notify_group_recently_added" id="notify_group_recently_added" value="1" ${config['notify_group_recently_added']}> Group notifications for recently added TV Shows or Music
|
<input type="checkbox" name="notify_group_recently_added_parent" id="notify_group_recently_added_parent" value="1" ${config['notify_group_recently_added_parent']}> Group Notifications into Season or Album
|
||||||
</label>
|
</label>
|
||||||
<p class="help-block">
|
<p class="help-block">
|
||||||
Enable to only send one TV Show/Season or Artist/Album notification for a batch of recently added media. Movies are unaffected.<br />
|
Enable to only send one season or album notification when multiple episodes or tracks are added. Movies, single episodes, and single tracks are unaffected.<br />
|
||||||
Note: When grouped, numeric ranges will be shown (e.g. S01E01-03), but specific episode/track metadata will be unavailable.
|
Note: An episode/track range can be shown (e.g. 01-12), but all other episode/track metadata will be unavailable.
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
<div class="checkbox">
|
||||||
|
<label>
|
||||||
|
<input type="checkbox" name="notify_group_recently_added_grandparent" id="notify_group_recently_added_grandparent" value="1" ${config['notify_group_recently_added_grandparent']}> Group Notifications into TV Show or Artist
|
||||||
|
</label>
|
||||||
|
<p class="help-block">
|
||||||
|
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.<br />
|
||||||
|
Note: A season range can be shown (e.g. 1-3), but all other season/episode/album/track metadata will be unavailable.
|
||||||
</p>
|
</p>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|
|
@ -303,71 +303,52 @@ class TimelineHandler(object):
|
||||||
metadata = self.get_metadata()
|
metadata = self.get_metadata()
|
||||||
if metadata:
|
if metadata:
|
||||||
grandparent_rating_key = int(metadata['grandparent_rating_key'])
|
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."
|
logger.debug(u"PlexPy TimelineHandler :: Library item %s (grandparent %s) added to recently added queue."
|
||||||
% (str(rating_key), str(grandparent_rating_key)))
|
% (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'):
|
elif media_type in ('season', 'album'):
|
||||||
metadata = self.get_metadata()
|
metadata = self.get_metadata()
|
||||||
if metadata:
|
if metadata:
|
||||||
parent_rating_key = int(metadata['parent_rating_key'])
|
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."
|
logger.debug(u"PlexPy TimelineHandler :: Library item %s (parent %s) added to recently added queue."
|
||||||
% (str(rating_key), str(parent_rating_key)))
|
% (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:
|
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))
|
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))
|
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):
|
child_keys = RECENTLY_ADDED_QUEUE.pop(rating_key, [])
|
||||||
for key in keys: self.on_created(key, **kwargs)
|
|
||||||
|
|
||||||
if plexpy.CONFIG.NOTIFY_GROUP_RECENTLY_ADDED:
|
if plexpy.CONFIG.NOTIFY_GROUP_RECENTLY_ADDED_GRANDPARENT and len(child_keys) > 1:
|
||||||
media_type_dict = {}
|
self.on_created(rating_key, child_keys=child_keys)
|
||||||
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', []))
|
|
||||||
|
|
||||||
else:
|
else:
|
||||||
notify_keys([key for type, key in child_keys if type in ('movie', 'episode', 'track')])
|
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)
|
||||||
|
|
|
@ -314,7 +314,9 @@ _CONFIG_DEFINITIONS = {
|
||||||
'NMA_ON_NEWDEVICE': (int, 'NMA', 0),
|
'NMA_ON_NEWDEVICE': (int, 'NMA', 0),
|
||||||
'NOTIFICATION_THREADS': (int, 'Advanced', 2),
|
'NOTIFICATION_THREADS': (int, 'Advanced', 2),
|
||||||
'NOTIFY_CONSECUTIVE': (int, 'Monitoring', 1),
|
'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_UPLOAD_POSTERS': (int, 'Monitoring', 0),
|
||||||
'NOTIFY_RECENTLY_ADDED': (int, 'Monitoring', 0),
|
'NOTIFY_RECENTLY_ADDED': (int, 'Monitoring', 0),
|
||||||
'NOTIFY_RECENTLY_ADDED_GRANDPARENT': (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_ON_WATCHED_BODY_TEXT = rep(self.NOTIFY_ON_WATCHED_BODY_TEXT)
|
||||||
self.NOTIFY_SCRIPTS_ARGS_TEXT = rep(self.NOTIFY_SCRIPTS_ARGS_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.MONITORING_USE_WEBSOCKET = 1
|
||||||
self.HTTP_PROXY = 1
|
self.HTTP_PROXY = 1
|
||||||
|
|
||||||
|
|
|
@ -257,13 +257,13 @@ def build_media_notify_params(notify_action=None, session=None, timeline=None, *
|
||||||
server_uptime = 'N/A'
|
server_uptime = 'N/A'
|
||||||
|
|
||||||
# Get metadata for the item
|
# Get metadata for the item
|
||||||
|
pms_connect = pmsconnect.PmsConnect()
|
||||||
if session:
|
if session:
|
||||||
rating_key = session['rating_key']
|
rating_key = session['rating_key']
|
||||||
|
metadata = pms_connect.get_metadata_details(rating_key=rating_key, get_media_info=True)
|
||||||
elif timeline:
|
elif timeline:
|
||||||
rating_key = timeline['rating_key']
|
rating_key = timeline['rating_key']
|
||||||
|
metadata = timeline
|
||||||
pms_connect = pmsconnect.PmsConnect()
|
|
||||||
metadata = pms_connect.get_metadata_details(rating_key=rating_key, get_media_info=True)
|
|
||||||
|
|
||||||
if not metadata:
|
if not metadata:
|
||||||
logger.error(u"PlexPy NotificationHandler :: Unable to retrieve metadata for rating_key %s" % str(rating_key))
|
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:
|
else:
|
||||||
full_title = metadata['title']
|
full_title = metadata['title']
|
||||||
|
|
||||||
# Fix metadata params for grouped recently added
|
if plexpy.CONFIG.NOTIFY_GROUP_RECENTLY_ADDED_GRANDPARENT and metadata['media_type'] in ('show', 'artist'):
|
||||||
show_name = metadata['grandparent_title']
|
show_name = metadata['title']
|
||||||
episode_name = metadata['title']
|
episode_name = ''
|
||||||
artist_name = metadata['grandparent_title']
|
artist_name = metadata['title']
|
||||||
album_name = metadata['parent_title']
|
album_name = ''
|
||||||
track_name = metadata['title']
|
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)
|
|
||||||
|
|
||||||
if notify_action == 'on_created' and plexpy.CONFIG.NOTIFY_GROUP_RECENTLY_ADDED and metadata['media_type'] != 'movie':
|
num, num00 = format_group_index([helpers.cast_to_int(d['media_index'])
|
||||||
if metadata['media_type'] in ('episode', 'track'):
|
for d in child_metadata if d['parent_rating_key'] == rating_key])
|
||||||
show_name = metadata['grandparent_title']
|
season_num, season_num00 = num, num00
|
||||||
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'] in ('season', 'album'):
|
episode_num, episode_num00 = '', ''
|
||||||
show_name = metadata['parent_title']
|
track_num, track_num00 = '', ''
|
||||||
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_index([helpers.cast_to_int(d['media_index'])
|
elif plexpy.CONFIG.NOTIFY_GROUP_RECENTLY_ADDED_PARENT and metadata['media_type'] in ('season', 'album'):
|
||||||
for d in child_metadata if d['parent_rating_key'] == rating_key])
|
show_name = metadata['parent_title']
|
||||||
episode_num, episode_num00 = num, num00
|
episode_name = ''
|
||||||
track_num, track_num00 = num, num00
|
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'):
|
num, num00 = format_group_index([helpers.cast_to_int(d['media_index'])
|
||||||
show_name = metadata['title']
|
for d in child_metadata if d['parent_rating_key'] == rating_key])
|
||||||
episode_name = ''
|
episode_num, episode_num00 = num, num00
|
||||||
artist_name = metadata['title']
|
track_num, track_num00 = num, num00
|
||||||
album_name = ''
|
|
||||||
track_name = ''
|
|
||||||
|
|
||||||
num, num00 = format_group_index([helpers.cast_to_int(d['media_index'])
|
else:
|
||||||
for d in child_metadata if d['parent_rating_key'] == rating_key])
|
show_name = metadata['grandparent_title']
|
||||||
season_num, season_num00 = num, num00
|
episode_name = metadata['title']
|
||||||
|
artist_name = metadata['grandparent_title']
|
||||||
num, num00 = format_group_index([helpers.cast_to_int(d['media_index'])
|
album_name = metadata['parent_title']
|
||||||
for d in grandchild_metadata if d['grandparent_rating_key'] == rating_key])
|
track_name = metadata['title']
|
||||||
episode_num, episode_num00 = num, num00
|
season_num = metadata['parent_media_index'].zfill(1)
|
||||||
track_num, track_num00 = num, num00
|
season_num00 = metadata['parent_media_index'].zfill(2)
|
||||||
|
episode_num = metadata['media_index'].zfill(1)
|
||||||
else:
|
episode_num00 = metadata['media_index'].zfill(2)
|
||||||
pass
|
track_num = metadata['media_index'].zfill(1)
|
||||||
|
track_num00 = metadata['media_index'].zfill(2)
|
||||||
|
|
||||||
available_params = {# Global paramaters
|
available_params = {# Global paramaters
|
||||||
'plexpy_version': common.VERSION_NUMBER,
|
'plexpy_version': common.VERSION_NUMBER,
|
||||||
|
@ -669,20 +650,23 @@ def strip_tag(data, agent_id=None):
|
||||||
|
|
||||||
|
|
||||||
def format_group_index(group_keys):
|
def format_group_index(group_keys):
|
||||||
|
group_keys = sorted(group_keys)
|
||||||
|
|
||||||
num = []
|
num = []
|
||||||
num00 = []
|
num00 = []
|
||||||
|
|
||||||
for k, g in groupby(enumerate(group_keys), lambda (i, x): i-x):
|
for k, g in groupby(enumerate(group_keys), lambda (i, x): i-x):
|
||||||
group = map(itemgetter(1), g)
|
group = map(itemgetter(1), g)
|
||||||
|
g_min, g_max = min(group), max(group)
|
||||||
|
|
||||||
if len(group) > 1:
|
if g_min == g_max:
|
||||||
num.append('{0}-{1}'.format(str(min(group)).zfill(1), str(max(group)).zfill(1)))
|
num.append('{0:01d}'.format(g_min))
|
||||||
num00.append('{0}-{1}'.format(str(min(group)).zfill(2), str(max(group)).zfill(2)))
|
num00.append('{0:02d}'.format(g_min))
|
||||||
else:
|
else:
|
||||||
num.append(str(group[0]).zfill(1))
|
num.append('{0:01d}-{1:01d}'.format(g_min, g_max))
|
||||||
num00.append(str(group[0]).zfill(2))
|
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):
|
def get_poster_info(metadata):
|
||||||
|
|
|
@ -2569,7 +2569,8 @@ class WebInterface(object):
|
||||||
"notify_consecutive": checked(plexpy.CONFIG.NOTIFY_CONSECUTIVE),
|
"notify_consecutive": checked(plexpy.CONFIG.NOTIFY_CONSECUTIVE),
|
||||||
"notify_upload_posters": checked(plexpy.CONFIG.NOTIFY_UPLOAD_POSTERS),
|
"notify_upload_posters": checked(plexpy.CONFIG.NOTIFY_UPLOAD_POSTERS),
|
||||||
"notify_recently_added": checked(plexpy.CONFIG.NOTIFY_RECENTLY_ADDED),
|
"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_by_ip": checked(plexpy.CONFIG.NOTIFY_CONCURRENT_BY_IP),
|
||||||
"notify_concurrent_threshold": plexpy.CONFIG.NOTIFY_CONCURRENT_THRESHOLD,
|
"notify_concurrent_threshold": plexpy.CONFIG.NOTIFY_CONCURRENT_THRESHOLD,
|
||||||
"notify_watched_percent": plexpy.CONFIG.NOTIFY_WATCHED_PERCENT,
|
"notify_watched_percent": plexpy.CONFIG.NOTIFY_WATCHED_PERCENT,
|
||||||
|
@ -2607,7 +2608,8 @@ class WebInterface(object):
|
||||||
"movie_notify_enable", "tv_notify_enable", "music_notify_enable",
|
"movie_notify_enable", "tv_notify_enable", "music_notify_enable",
|
||||||
"refresh_libraries_on_startup", "refresh_users_on_startup",
|
"refresh_libraries_on_startup", "refresh_users_on_startup",
|
||||||
"movie_logging_enable", "tv_logging_enable", "music_logging_enable",
|
"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",
|
"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",
|
"allow_guest_access", "cache_images", "http_basic_auth", "notify_concurrent_by_ip",
|
||||||
"history_table_activity", "plexpy_auto_update"
|
"history_table_activity", "plexpy_auto_update"
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue