mirror of
https://github.com/Tautulli/Tautulli.git
synced 2025-07-08 06:00:51 -07:00
Add grouped notification params
This commit is contained in:
parent
d97cacff14
commit
e1bd5ed49e
7 changed files with 221 additions and 87 deletions
|
@ -2671,6 +2671,12 @@ a .home-platforms-list-cover-face:hover
|
||||||
border-radius: 8px;
|
border-radius: 8px;
|
||||||
background-clip: padding-box;
|
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
|
@media only screen
|
||||||
and (min-device-width: 300px)
|
and (min-device-width: 300px)
|
||||||
|
|
|
@ -951,15 +951,10 @@
|
||||||
|
|
||||||
<div class="checkbox">
|
<div class="checkbox">
|
||||||
<label>
|
<label>
|
||||||
<input type="checkbox" name="notify_recently_added_grandparent" id="notify_recently_added_grandparent" value="1" ${config['notify_recently_added_grandparent']}> Group notifications for recently added TV Shows or Music
|
<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
|
||||||
</label>
|
</label>
|
||||||
<p class="help-block">
|
<p class="help-block">
|
||||||
Enable to only get one TV Show or Artist notification for a batch of recently added Episodes or Tracks. Movies are unaffected.<br />
|
Enable to only get one TV Show/Season or Artist/Album notification for a batch of recently added Episodes or Tracks. Movies are unaffected.<br />
|
||||||
% if config['notify_recently_added_grandparent'] == 'Checked':
|
|
||||||
<span id="notify_recently_added_grandparent_note" style="color: #eb8600;">Note: No Season/Episode or Album/Track metadata will be available.</span>
|
|
||||||
% else:
|
|
||||||
<span id="notify_recently_added_grandparent_note">Note: No Season/Episode or Album/Track metadata will be available.</span>
|
|
||||||
% endif
|
|
||||||
</p>
|
</p>
|
||||||
</div>
|
</div>
|
||||||
<div class="form-group">
|
<div class="form-group">
|
||||||
|
@ -1588,27 +1583,27 @@
|
||||||
</tr>
|
</tr>
|
||||||
<tr>
|
<tr>
|
||||||
<td><strong>{season_num}</strong></td>
|
<td><strong>{season_num}</strong></td>
|
||||||
<td>The season number for the episode.</td>
|
<td>The season number. <span class="small-muted">(e.g. 1, or 1-3)</span></td>
|
||||||
</tr>
|
</tr>
|
||||||
<tr>
|
<tr>
|
||||||
<td><strong>{season_num00}</strong></td>
|
<td><strong>{season_num00}</strong></td>
|
||||||
<td>The two digit season number.</td>
|
<td>The two digit season number. <span class="small-muted">(e.g. 01, or 01-03)</span></td>
|
||||||
</tr>
|
</tr>
|
||||||
<tr>
|
<tr>
|
||||||
<td><strong>{episode_num}</strong></td>
|
<td><strong>{episode_num}</strong></td>
|
||||||
<td>The episode number for the episode.</td>
|
<td>The episode number. <span class="small-muted">(e.g. 6, or 6-10)</span></td>
|
||||||
</tr>
|
</tr>
|
||||||
<tr>
|
<tr>
|
||||||
<td><strong>{episode_num00}</strong></td>
|
<td><strong>{episode_num00}</strong></td>
|
||||||
<td>The two digit episode number.</td>
|
<td>The two digit episode number. <span class="small-muted">(e.g. 06, or 06-10)</span></td>
|
||||||
</tr>
|
</tr>
|
||||||
<tr>
|
<tr>
|
||||||
<td><strong>{track_num}</strong></td>
|
<td><strong>{track_num}</strong></td>
|
||||||
<td>The track number for the track.</td>
|
<td>The track number. <span class="small-muted">(e.g. 4, or 4-10)</span></td>
|
||||||
</tr>
|
</tr>
|
||||||
<tr>
|
<tr>
|
||||||
<td><strong>{track_num00}</strong></td>
|
<td><strong>{track_num00}</strong></td>
|
||||||
<td>The two digit track number.</td>
|
<td>The two digit track number. <span class="small-muted">(e.g. 04, or 04-10)</span></td>
|
||||||
</tr>
|
</tr>
|
||||||
<tr>
|
<tr>
|
||||||
<td><strong>{year}</strong></td>
|
<td><strong>{year}</strong></td>
|
||||||
|
@ -1815,23 +1810,25 @@
|
||||||
<div style="padding-bottom: 10px;">
|
<div style="padding-bottom: 10px;">
|
||||||
<p class="help-block">All text inside <span class="inline-pre"><movie></movie></span> tags will only be sent when the media item is a movie.</p>
|
<p class="help-block">All text inside <span class="inline-pre"><movie></movie></span> tags will only be sent when the media item is a movie.</p>
|
||||||
<p><strong style="color: #fff;">Example:</strong></p>
|
<p><strong style="color: #fff;">Example:</strong></p>
|
||||||
<pre>{user} has started playing {title} <movie>({year})</movie></pre>
|
<pre>{title} <movie>({year})</movie> was recently added to Plex</pre>
|
||||||
</div>
|
</div>
|
||||||
<div>
|
<div>
|
||||||
<h4>TV Tag</h4>
|
<h4>Show / Season / Episode Tags</h4>
|
||||||
</div>
|
</div>
|
||||||
<div style="padding-bottom: 10px;">
|
<div style="padding-bottom: 10px;">
|
||||||
<p class="help-block">All text inside <span class="inline-pre"><tv></tv></span> tags will only be sent when the media item is an episode.</p>
|
<p class="help-block">All text inside <span class="inline-pre"><show></show></span>/<span class="inline-pre"><season></season></span>/<span class="inline-pre"><episode></episode></span>
|
||||||
|
tags will only be sent when the media item is an show/season/episode.</p>
|
||||||
<p><strong style="color: #fff;">Example:</strong></p>
|
<p><strong style="color: #fff;">Example:</strong></p>
|
||||||
<pre>{user} has started playing {title} <tv>(S{season_num}E{episode_num})</tv></pre>
|
<pre><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.</pre>
|
||||||
</div>
|
</div>
|
||||||
<div>
|
<div>
|
||||||
<h4>Music Tag</h4>
|
<h4>Artist / Album / Track Tag</h4>
|
||||||
</div>
|
</div>
|
||||||
<div>
|
<div>
|
||||||
<p class="help-block">All text inside <span class="inline-pre"><music></music></span> tags will only be sent when the media item is a track.</p>
|
<p class="help-block">All text inside <span class="inline-pre"><artist></artist></span>/<span class="inline-pre"><album></album></span>/<span class="inline-pre"><track></track></span>
|
||||||
|
tags will only be sent when the media item is a track.</p>
|
||||||
<p><strong style="color: #fff;">Example:</strong></p>
|
<p><strong style="color: #fff;">Example:</strong></p>
|
||||||
<pre>{user} has started playing {title} <music>(Track {track_num})</music></pre>
|
<pre><artist>{artist_name}</artist><album>{artist_name} - {album_name}</album><track>{artist_name} - {album_name} - {track_name}</track> was recently added to Plex.</pre>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
@ -258,7 +258,7 @@ class TimelineHandler(object):
|
||||||
|
|
||||||
return None
|
return None
|
||||||
|
|
||||||
def on_created(self, rating_key):
|
def on_created(self, rating_key, **kwargs):
|
||||||
if self.is_item():
|
if self.is_item():
|
||||||
logger.debug(u"PlexPy TimelineHandler :: Library item %s added to Plex." % str(rating_key))
|
logger.debug(u"PlexPy TimelineHandler :: Library item %s added to Plex." % str(rating_key))
|
||||||
pms_connect = pmsconnect.PmsConnect()
|
pms_connect = pmsconnect.PmsConnect()
|
||||||
|
@ -266,7 +266,9 @@ class TimelineHandler(object):
|
||||||
|
|
||||||
if metadata_list:
|
if metadata_list:
|
||||||
metadata = metadata_list['metadata']
|
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:
|
else:
|
||||||
logger.error(u"PlexPy TimelineHandler :: Unable to retrieve metadata for rating_key %s" \
|
logger.error(u"PlexPy TimelineHandler :: Unable to retrieve metadata for rating_key %s" \
|
||||||
% str(rating_key))
|
% 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))
|
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)]
|
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))
|
logger.debug(u"PlexPy TimelineHandler :: Library item %s done processing metadata." % str(rating_key))
|
||||||
child_keys = RECENTLY_ADDED_QUEUE.pop(rating_key)
|
child_keys = RECENTLY_ADDED_QUEUE.pop(rating_key)
|
||||||
|
|
||||||
def notify_keys(keys):
|
def notify_keys(keys, **kwargs):
|
||||||
for key in keys: self.on_created(key)
|
for key in keys: self.on_created(key, **kwargs)
|
||||||
|
|
||||||
if plexpy.CONFIG.NOTIFY_GROUP_RECENTLY_ADDED:
|
if plexpy.CONFIG.NOTIFY_GROUP_RECENTLY_ADDED:
|
||||||
media_type_dict = {}
|
media_type_dict = {}
|
||||||
|
@ -331,21 +333,39 @@ class TimelineHandler(object):
|
||||||
|
|
||||||
if len(media_type_dict.get('episode', [])) > 1:
|
if len(media_type_dict.get('episode', [])) > 1:
|
||||||
if len(media_type_dict.get('season', [])) > 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:
|
else:
|
||||||
notify_keys(media_type_dict.get('season', media_type_dict.get('episode', [])))
|
notify_keys(media_type_dict['episode'])
|
||||||
else:
|
else:
|
||||||
notify_keys(media_type_dict.get('episode', []))
|
notify_keys(media_type_dict.get('episode', []))
|
||||||
|
|
||||||
if len(media_type_dict.get('track', [])) > 1:
|
if len(media_type_dict.get('track', [])) > 1:
|
||||||
if len(media_type_dict.get('album', [])) > 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:
|
else:
|
||||||
notify_keys(media_type_dict.get('album', media_type_dict.get('track', [])))
|
notify_keys(media_type_dict['track'])
|
||||||
else:
|
else:
|
||||||
notify_keys(media_type_dict.get('track', []))
|
notify_keys(media_type_dict.get('track', []))
|
||||||
|
|
||||||
notify_keys(media_type_dict.get('movie', []))
|
notify_keys(media_type_dict.get('movie', []))
|
||||||
|
|
||||||
else:
|
else:
|
||||||
notify_keys(child_keys)
|
notify_keys([key for type, key in child_keys if type in ('movie', 'episode', 'track')])
|
|
@ -258,7 +258,7 @@ def check_recently_added():
|
||||||
|
|
||||||
if metadata:
|
if metadata:
|
||||||
|
|
||||||
if not plexpy.CONFIG.NOTIFY_RECENTLY_ADDED_GRANDPARENT:
|
if not plexpy.CONFIG.NOTIFY_GROUP_RECENTLY_ADDED:
|
||||||
for item in metadata:
|
for item in metadata:
|
||||||
|
|
||||||
library_details = library_data.get_details(section_id=item['section_id'])
|
library_details = library_data.get_details(section_id=item['section_id'])
|
||||||
|
|
|
@ -776,19 +776,22 @@ class Config(object):
|
||||||
self.CONFIG_VERSION = '2'
|
self.CONFIG_VERSION = '2'
|
||||||
|
|
||||||
if 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}')
|
def rep(s):
|
||||||
self.NOTIFY_ON_START_BODY_TEXT = self.NOTIFY_ON_START_BODY_TEXT.replace('{progress}','{progress_duration}')
|
return s.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_START_SUBJECT_TEXT = rep(self.NOTIFY_ON_START_SUBJECT_TEXT)
|
||||||
self.NOTIFY_ON_PAUSE_SUBJECT_TEXT = self.NOTIFY_ON_PAUSE_SUBJECT_TEXT.replace('{progress}','{progress_duration}')
|
self.NOTIFY_ON_START_BODY_TEXT = rep(self.NOTIFY_ON_START_BODY_TEXT)
|
||||||
self.NOTIFY_ON_PAUSE_BODY_TEXT = self.NOTIFY_ON_PAUSE_BODY_TEXT.replace('{progress}','{progress_duration}')
|
self.NOTIFY_ON_STOP_SUBJECT_TEXT = rep(self.NOTIFY_ON_STOP_SUBJECT_TEXT)
|
||||||
self.NOTIFY_ON_RESUME_SUBJECT_TEXT = self.NOTIFY_ON_RESUME_SUBJECT_TEXT.replace('{progress}','{progress_duration}')
|
self.NOTIFY_ON_STOP_BODY_TEXT = rep(self.NOTIFY_ON_STOP_BODY_TEXT)
|
||||||
self.NOTIFY_ON_RESUME_BODY_TEXT = self.NOTIFY_ON_RESUME_BODY_TEXT.replace('{progress}','{progress_duration}')
|
self.NOTIFY_ON_PAUSE_SUBJECT_TEXT = rep(self.NOTIFY_ON_PAUSE_SUBJECT_TEXT)
|
||||||
self.NOTIFY_ON_BUFFER_SUBJECT_TEXT = self.NOTIFY_ON_BUFFER_SUBJECT_TEXT.replace('{progress}','{progress_duration}')
|
self.NOTIFY_ON_PAUSE_BODY_TEXT = rep(self.NOTIFY_ON_PAUSE_BODY_TEXT)
|
||||||
self.NOTIFY_ON_BUFFER_BODY_TEXT = self.NOTIFY_ON_BUFFER_BODY_TEXT.replace('{progress}','{progress_duration}')
|
self.NOTIFY_ON_RESUME_SUBJECT_TEXT = rep(self.NOTIFY_ON_RESUME_SUBJECT_TEXT)
|
||||||
self.NOTIFY_ON_WATCHED_SUBJECT_TEXT = self.NOTIFY_ON_WATCHED_SUBJECT_TEXT.replace('{progress}','{progress_duration}')
|
self.NOTIFY_ON_RESUME_BODY_TEXT = rep(self.NOTIFY_ON_RESUME_BODY_TEXT)
|
||||||
self.NOTIFY_ON_WATCHED_BODY_TEXT = self.NOTIFY_ON_WATCHED_BODY_TEXT.replace('{progress}','{progress_duration}')
|
self.NOTIFY_ON_BUFFER_SUBJECT_TEXT = rep(self.NOTIFY_ON_BUFFER_SUBJECT_TEXT)
|
||||||
self.NOTIFY_SCRIPTS_ARGS_TEXT = self.NOTIFY_SCRIPTS_ARGS_TEXT.replace('{progress}','{progress_duration}')
|
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'
|
self.CONFIG_VERSION = '3'
|
||||||
|
|
||||||
if self.CONFIG_VERSION == '3':
|
if self.CONFIG_VERSION == '3':
|
||||||
|
@ -814,3 +817,22 @@ class Config(object):
|
||||||
if self.GIT_USER.lower() == 'drzoidberg33':
|
if self.GIT_USER.lower() == 'drzoidberg33':
|
||||||
self.GIT_USER = 'JonnyWong16'
|
self.GIT_USER = 'JonnyWong16'
|
||||||
self.CONFIG_VERSION = '7'
|
self.CONFIG_VERSION = '7'
|
||||||
|
|
||||||
|
if self.CONFIG_VERSION == '7':
|
||||||
|
def rep(s):
|
||||||
|
return s.replace('<tv>','<episode>').replace('</tv>','</episode>').replace('<music>','<track>').replace('</music>','</track>')
|
||||||
|
|
||||||
|
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'
|
|
@ -16,6 +16,8 @@
|
||||||
|
|
||||||
import arrow
|
import arrow
|
||||||
import bleach
|
import bleach
|
||||||
|
from itertools import groupby
|
||||||
|
from operator import itemgetter
|
||||||
import os
|
import os
|
||||||
import re
|
import re
|
||||||
import threading
|
import threading
|
||||||
|
@ -53,7 +55,7 @@ def start_threads(num_threads=1):
|
||||||
thread.start()
|
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:
|
if not notify_action:
|
||||||
logger.debug(u"PlexPy NotificationHandler :: Notify called but no action received.")
|
logger.debug(u"PlexPy NotificationHandler :: Notify called but no action received.")
|
||||||
return
|
return
|
||||||
|
@ -69,10 +71,12 @@ def add_notifier_each(notify_action=None, stream_data=None, timeline_data=None):
|
||||||
stream_data=stream_data,
|
stream_data=stream_data,
|
||||||
timeline_data=timeline_data)
|
timeline_data=timeline_data)
|
||||||
if conditions:
|
if conditions:
|
||||||
plexpy.NOTIFY_QUEUE.put({'notifier_id': notifier['id'],
|
data = {'notifier_id': notifier['id'],
|
||||||
'notify_action': notify_action,
|
'notify_action': notify_action,
|
||||||
'stream_data': stream_data,
|
'stream_data': stream_data,
|
||||||
'timeline_data': timeline_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):
|
def notify_conditions(notifier=None, notify_action=None, stream_data=None, timeline_data=None):
|
||||||
if stream_data:
|
if stream_data:
|
||||||
|
@ -131,7 +135,7 @@ def notify_conditions(notifier=None, notify_action=None, stream_data=None, timel
|
||||||
return False
|
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)
|
notifier_config = notifiers.get_notifier_config(notifier_id=notifier_id)
|
||||||
|
|
||||||
if not notifier_config:
|
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
|
# Build the notification parameters
|
||||||
parameters, metadata = build_media_notify_params(notify_action=notify_action,
|
parameters, metadata = build_media_notify_params(notify_action=notify_action,
|
||||||
session=stream_data,
|
session=stream_data,
|
||||||
timeline=timeline_data)
|
timeline=timeline_data,
|
||||||
|
**kwargs)
|
||||||
else:
|
else:
|
||||||
# Build the notification parameters
|
# Build the notification parameters
|
||||||
parameters, metadata = build_server_notify_params(notify_action=notify_action)
|
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.")
|
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
|
# Get time formats
|
||||||
date_format = plexpy.CONFIG.DATE_FORMAT.replace('Do','')
|
date_format = plexpy.CONFIG.DATE_FORMAT.replace('Do','')
|
||||||
time_format = plexpy.CONFIG.TIME_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()
|
pms_connect = pmsconnect.PmsConnect()
|
||||||
metadata_list = pms_connect.get_metadata_details(rating_key=rating_key)
|
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:
|
if metadata_list:
|
||||||
metadata = metadata_list['metadata']
|
metadata = metadata_list['metadata']
|
||||||
else:
|
else:
|
||||||
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))
|
||||||
return None, None
|
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
|
# Create a title
|
||||||
if metadata['media_type'] == 'episode' or metadata['media_type'] == 'track':
|
if metadata['media_type'] == 'episode' or metadata['media_type'] == 'track':
|
||||||
full_title = '%s - %s' % (metadata['grandparent_title'],
|
full_title = '%s - %s' % (metadata['grandparent_title'],
|
||||||
metadata['title'])
|
metadata['title'])
|
||||||
|
elif metadata['media_type'] == 'season' or metadata['media_type'] == 'album':
|
||||||
|
full_title = '%s - %s' % (metadata['parent_title'],
|
||||||
|
metadata['title'])
|
||||||
else:
|
else:
|
||||||
full_title = metadata['title']
|
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
|
metadata['poster_url'] = poster_url
|
||||||
|
|
||||||
# Fix metadata params for notify recently added grandparent
|
# Fix metadata params for grouped recently added
|
||||||
if notify_action == 'created' and plexpy.CONFIG.NOTIFY_RECENTLY_ADDED_GRANDPARENT:
|
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)
|
||||||
else:
|
season_num00 = metadata['parent_media_index'].zfill(2)
|
||||||
show_name = metadata['grandparent_title']
|
episode_num = metadata['media_index'].zfill(1)
|
||||||
episode_name = metadata['title']
|
episode_num00 = metadata['media_index'].zfill(2)
|
||||||
artist_name = metadata['grandparent_title']
|
track_num = metadata['media_index'].zfill(1)
|
||||||
album_name = metadata['parent_title']
|
track_num00 = metadata['media_index'].zfill(2)
|
||||||
track_name = metadata['title']
|
|
||||||
|
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
|
available_params = {# Global paramaters
|
||||||
'server_name': server_name,
|
'server_name': server_name,
|
||||||
|
@ -443,12 +505,12 @@ def build_media_notify_params(notify_action=None, session=None, timeline=None):
|
||||||
'artist_name': artist_name,
|
'artist_name': artist_name,
|
||||||
'album_name': album_name,
|
'album_name': album_name,
|
||||||
'track_name': track_name,
|
'track_name': track_name,
|
||||||
'season_num': metadata['parent_media_index'].zfill(1),
|
'season_num': season_num,
|
||||||
'season_num00': metadata['parent_media_index'].zfill(2),
|
'season_num00': season_num00,
|
||||||
'episode_num': metadata['media_index'].zfill(1),
|
'episode_num': episode_num,
|
||||||
'episode_num00': metadata['media_index'].zfill(2),
|
'episode_num00': episode_num00,
|
||||||
'track_num': metadata['media_index'].zfill(1),
|
'track_num': track_num,
|
||||||
'track_num00': metadata['media_index'].zfill(2),
|
'track_num00': track_num00,
|
||||||
'year': metadata['year'],
|
'year': metadata['year'],
|
||||||
'release_date': arrow.get(metadata['originally_available_at']).format(date_format)
|
'release_date': arrow.get(metadata['originally_available_at']).format(date_format)
|
||||||
if metadata['originally_available_at'] else '',
|
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):
|
def build_notify_text(subject='', body='', notify_action=None, parameters=None, agent_id=None):
|
||||||
|
media_type = parameters.get('media_type')
|
||||||
|
|
||||||
|
all_tags = r'<movie>.*?</movie>|' \
|
||||||
|
'<show>.*?</show>|<season>.*?</season>|<episode>.*?</episode>|' \
|
||||||
|
'<artist>.*?</artist>|<album>.*?</album>|<track>.*?</track>'
|
||||||
|
|
||||||
# Check for exclusion tags
|
# Check for exclusion tags
|
||||||
if parameters.get('media_type') == 'movie':
|
if media_type == 'movie':
|
||||||
# Regex pattern to remove the text in the tags we don't want
|
pattern = re.compile(all_tags.replace('<movie>.*?</movie>', '<movie>|</movie>'), re.IGNORECASE | re.DOTALL)
|
||||||
pattern = re.compile(r'<movie>|</movie>|<tv>.*?</tv>|<music>.*?</music>', re.IGNORECASE | re.DOTALL)
|
elif media_type == 'show':
|
||||||
elif parameters.get('media_type') == 'show' or parameters.get('media_type') == 'episode':
|
pattern = re.compile(all_tags.replace('<show>.*?</show>', '<show>|</show>'), re.IGNORECASE | re.DOTALL)
|
||||||
# Regex pattern to remove the text in the tags we don't want
|
elif media_type == 'season':
|
||||||
pattern = re.compile(r'<movie>.*?</movie>|<tv>|</tv>|<music>.*?</music>', re.IGNORECASE | re.DOTALL)
|
pattern = re.compile(all_tags.replace('<season>.*?</season>', '<season>|</season>'), re.IGNORECASE | re.DOTALL)
|
||||||
elif parameters.get('media_type') == 'artist' or parameters.get('media_type') == 'track':
|
elif media_type == 'episode':
|
||||||
# Regex pattern to remove the text in the tags we don't want
|
pattern = re.compile(all_tags.replace('<episode>.*?</episode>', '<episode>|</episode>'), re.IGNORECASE | re.DOTALL)
|
||||||
pattern = re.compile(r'<movie>.*?</movie>|<tv>.*?</tv>|<music>|</music>', re.IGNORECASE | re.DOTALL)
|
elif media_type == 'artist':
|
||||||
|
pattern = re.compile(all_tags.replace('<artist>.*?</artist>', '<artist>|</artist>'), re.IGNORECASE | re.DOTALL)
|
||||||
|
elif media_type == 'album':
|
||||||
|
pattern = re.compile(all_tags.replace('<album>.*?</album>', '<album>|</album>'), re.IGNORECASE | re.DOTALL)
|
||||||
|
elif media_type == 'track':
|
||||||
|
pattern = re.compile(all_tags.replace('<track>.*?</track>', '<track>|</track>'), re.IGNORECASE | re.DOTALL)
|
||||||
else:
|
else:
|
||||||
pattern = None
|
pattern = None
|
||||||
|
|
||||||
|
@ -611,3 +684,19 @@ def strip_tag(data, agent_id=None):
|
||||||
else:
|
else:
|
||||||
whitelist = {}
|
whitelist = {}
|
||||||
return bleach.clean(data, tags=whitelist.keys(), attributes=whitelist, strip=True)
|
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'
|
||||||
|
|
|
@ -2573,7 +2573,7 @@ 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_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_recently_added_delay": plexpy.CONFIG.NOTIFY_RECENTLY_ADDED_DELAY,
|
||||||
"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,
|
||||||
|
@ -2637,7 +2637,7 @@ class WebInterface(object):
|
||||||
"movie_notify_enable", "tv_notify_enable", "music_notify_enable", "monitoring_use_websocket",
|
"movie_notify_enable", "tv_notify_enable", "music_notify_enable", "monitoring_use_websocket",
|
||||||
"refresh_libraries_on_startup", "refresh_users_on_startup",
|
"refresh_libraries_on_startup", "refresh_users_on_startup",
|
||||||
"ip_logging_enable", "movie_logging_enable", "tv_logging_enable", "music_logging_enable",
|
"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",
|
"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",
|
"allow_guest_access", "cache_images", "http_proxy", "http_basic_auth", "notify_concurrent_by_ip",
|
||||||
"history_table_activity"
|
"history_table_activity"
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue