mirror of
https://github.com/Tautulli/Tautulli.git
synced 2025-07-11 07:46:07 -07:00
New pause, resume and buffer notification options.
Reworked notification config in settings menu.
This commit is contained in:
parent
b7baf1a05d
commit
a96482ee3c
9 changed files with 532 additions and 131 deletions
|
@ -348,7 +348,8 @@ def dbcheck():
|
|||
'bitrate INTEGER, video_resolution TEXT, video_framerate TEXT, aspect_ratio TEXT, '
|
||||
'audio_channels INTEGER, transcode_protocol TEXT, transcode_container TEXT, '
|
||||
'transcode_video_codec TEXT, transcode_audio_codec TEXT, transcode_audio_channels INTEGER,'
|
||||
'transcode_width INTEGER, transcode_height INTEGER)'
|
||||
'transcode_width INTEGER, transcode_height INTEGER, buffer_count INTEGER DEFAULT 0, '
|
||||
'buffer_last_triggered INTEGER)'
|
||||
)
|
||||
|
||||
# session_history table :: This is a history table which logs essential stream details
|
||||
|
@ -529,7 +530,8 @@ def dbcheck():
|
|||
c_db.execute(
|
||||
'CREATE TABLE IF NOT EXISTS notify_log (id INTEGER PRIMARY KEY AUTOINCREMENT, '
|
||||
'session_key INTEGER, rating_key INTEGER, user_id INTEGER, user TEXT, '
|
||||
'agent_id INTEGER, agent_name TEXT, on_play INTEGER, on_stop INTEGER, on_watched INTEGER)'
|
||||
'agent_id INTEGER, agent_name TEXT, on_play INTEGER, on_stop INTEGER, on_watched INTEGER, '
|
||||
'on_pause INTEGER, on_resume INTEGER, on_buffer INTEGER)'
|
||||
)
|
||||
|
||||
# Upgrade sessions table from earlier versions
|
||||
|
@ -550,6 +552,33 @@ def dbcheck():
|
|||
'ALTER TABLE users ADD COLUMN keep_history INTEGER DEFAULT 1'
|
||||
)
|
||||
|
||||
# Upgrade sessions table from earlier versions
|
||||
try:
|
||||
c_db.execute('SELECT on_pause from notify_log')
|
||||
except sqlite3.OperationalError:
|
||||
logger.debug(u"Altering database. Updating database table sessions.")
|
||||
c_db.execute(
|
||||
'ALTER TABLE notify_log ADD COLUMN on_pause INTEGER'
|
||||
)
|
||||
c_db.execute(
|
||||
'ALTER TABLE notify_log ADD COLUMN on_resume INTEGER'
|
||||
)
|
||||
c_db.execute(
|
||||
'ALTER TABLE notify_log ADD COLUMN on_buffer INTEGER'
|
||||
)
|
||||
|
||||
# Upgrade sessions table from earlier versions
|
||||
try:
|
||||
c_db.execute('SELECT buffer_count from sessions')
|
||||
except sqlite3.OperationalError:
|
||||
logger.debug(u"Altering database. Updating database table sessions.")
|
||||
c_db.execute(
|
||||
'ALTER TABLE sessions ADD COLUMN buffer_count INTEGER DEFAULT 0'
|
||||
)
|
||||
c_db.execute(
|
||||
'ALTER TABLE sessions ADD COLUMN buffer_last_triggered INTEGER'
|
||||
)
|
||||
|
||||
conn_db.commit()
|
||||
c_db.close()
|
||||
|
||||
|
|
|
@ -39,7 +39,12 @@ _CONFIG_DEFINITIONS = {
|
|||
'BOXCAR_TOKEN': (str, 'Boxcar', ''),
|
||||
'BOXCAR_ON_PLAY': (int, 'Boxcar', 0),
|
||||
'BOXCAR_ON_STOP': (int, 'Boxcar', 0),
|
||||
'BOXCAR_ON_PAUSE': (int, 'Boxcar', 0),
|
||||
'BOXCAR_ON_RESUME': (int, 'Boxcar', 0),
|
||||
'BOXCAR_ON_BUFFER': (int, 'Boxcar', 0),
|
||||
'BOXCAR_ON_WATCHED': (int, 'Boxcar', 0),
|
||||
'BUFFER_THRESHOLD': (int, 'Monitoring', 3),
|
||||
'BUFFER_WAIT': (int, 'Monitoring', 900),
|
||||
'CACHE_DIR': (str, 'General', ''),
|
||||
'CACHE_SIZEMB': (int, 'Advanced', 32),
|
||||
'CHECK_GITHUB': (int, 'General', 1),
|
||||
|
@ -58,6 +63,9 @@ _CONFIG_DEFINITIONS = {
|
|||
'EMAIL_TLS': (int, 'Email', 0),
|
||||
'EMAIL_ON_PLAY': (int, 'Email', 0),
|
||||
'EMAIL_ON_STOP': (int, 'Email', 0),
|
||||
'EMAIL_ON_PAUSE': (int, 'Email', 0),
|
||||
'EMAIL_ON_RESUME': (int, 'Email', 0),
|
||||
'EMAIL_ON_BUFFER': (int, 'Email', 0),
|
||||
'EMAIL_ON_WATCHED': (int, 'Email', 0),
|
||||
'ENABLE_HTTPS': (int, 'General', 0),
|
||||
'FIRST_RUN_COMPLETE': (int, 'General', 0),
|
||||
|
@ -70,6 +78,9 @@ _CONFIG_DEFINITIONS = {
|
|||
'GROWL_PASSWORD': (str, 'Growl', ''),
|
||||
'GROWL_ON_PLAY': (int, 'Growl', 0),
|
||||
'GROWL_ON_STOP': (int, 'Growl', 0),
|
||||
'GROWL_ON_PAUSE': (int, 'Growl', 0),
|
||||
'GROWL_ON_RESUME': (int, 'Growl', 0),
|
||||
'GROWL_ON_BUFFER': (int, 'Growl', 0),
|
||||
'GROWL_ON_WATCHED': (int, 'Growl', 0),
|
||||
'HOME_STATS_LENGTH': (int, 'General', 30),
|
||||
'HTTPS_CERT': (str, 'General', ''),
|
||||
|
@ -101,18 +112,30 @@ _CONFIG_DEFINITIONS = {
|
|||
'NMA_PRIORITY': (int, 'NMA', 0),
|
||||
'NMA_ON_PLAY': (int, 'NMA', 0),
|
||||
'NMA_ON_STOP': (int, 'NMA', 0),
|
||||
'NMA_ON_PAUSE': (int, 'NMA', 0),
|
||||
'NMA_ON_RESUME': (int, 'NMA', 0),
|
||||
'NMA_ON_BUFFER': (int, 'NMA', 0),
|
||||
'NMA_ON_WATCHED': (int, 'NMA', 0),
|
||||
'NOTIFY_WATCHED_PERCENT': (int, 'Monitoring', 85),
|
||||
'NOTIFY_ON_START_SUBJECT_TEXT': (str, 'Monitoring', 'PlexPy ({server_name})'),
|
||||
'NOTIFY_ON_START_BODY_TEXT': (str, 'Monitoring', '{user} ({player}) started playing {title}.'),
|
||||
'NOTIFY_ON_STOP_SUBJECT_TEXT': (str, 'Monitoring', 'PlexPy ({server_name})'),
|
||||
'NOTIFY_ON_STOP_BODY_TEXT': (str, 'Monitoring', '{user} ({player}) has stopped {title}.'),
|
||||
'NOTIFY_ON_PAUSE_SUBJECT_TEXT': (str, 'Monitoring', 'PlexPy ({server_name})'),
|
||||
'NOTIFY_ON_PAUSE_BODY_TEXT': (str, 'Monitoring', '{user} ({player}) has paused {title}.'),
|
||||
'NOTIFY_ON_RESUME_SUBJECT_TEXT': (str, 'Monitoring', 'PlexPy ({server_name})'),
|
||||
'NOTIFY_ON_RESUME_BODY_TEXT': (str, 'Monitoring', '{user} ({player}) has resumed {title}.'),
|
||||
'NOTIFY_ON_BUFFER_SUBJECT_TEXT': (str, 'Monitoring', 'PlexPy ({server_name})'),
|
||||
'NOTIFY_ON_BUFFER_BODY_TEXT': (str, 'Monitoring', '{user} ({player}) is buffering {title}.'),
|
||||
'NOTIFY_ON_WATCHED_SUBJECT_TEXT': (str, 'Monitoring', 'PlexPy ({server_name})'),
|
||||
'NOTIFY_ON_WATCHED_BODY_TEXT': (str, 'Monitoring', '{user} ({player}) has watched {title}.'),
|
||||
'OSX_NOTIFY_APP': (str, 'OSX_Notify', '/Applications/PlexPy'),
|
||||
'OSX_NOTIFY_ENABLED': (int, 'OSX_Notify', 0),
|
||||
'OSX_NOTIFY_ON_PLAY': (int, 'OSX_Notify', 0),
|
||||
'OSX_NOTIFY_ON_STOP': (int, 'OSX_Notify', 0),
|
||||
'OSX_NOTIFY_ON_PAUSE': (int, 'OSX_Notify', 0),
|
||||
'OSX_NOTIFY_ON_RESUME': (int, 'OSX_Notify', 0),
|
||||
'OSX_NOTIFY_ON_BUFFER': (int, 'OSX_Notify', 0),
|
||||
'OSX_NOTIFY_ON_WATCHED': (int, 'OSX_Notify', 0),
|
||||
'PLEX_CLIENT_HOST': (str, 'Plex', ''),
|
||||
'PLEX_ENABLED': (int, 'Plex', 0),
|
||||
|
@ -120,17 +143,26 @@ _CONFIG_DEFINITIONS = {
|
|||
'PLEX_USERNAME': (str, 'Plex', ''),
|
||||
'PLEX_ON_PLAY': (int, 'Plex', 0),
|
||||
'PLEX_ON_STOP': (int, 'Plex', 0),
|
||||
'PLEX_ON_PAUSE': (int, 'Plex', 0),
|
||||
'PLEX_ON_RESUME': (int, 'Plex', 0),
|
||||
'PLEX_ON_BUFFER': (int, 'Plex', 0),
|
||||
'PLEX_ON_WATCHED': (int, 'Plex', 0),
|
||||
'PROWL_ENABLED': (int, 'Prowl', 0),
|
||||
'PROWL_KEYS': (str, 'Prowl', ''),
|
||||
'PROWL_PRIORITY': (int, 'Prowl', 0),
|
||||
'PROWL_ON_PLAY': (int, 'Prowl', 0),
|
||||
'PROWL_ON_STOP': (int, 'Prowl', 0),
|
||||
'PROWL_ON_PAUSE': (int, 'Prowl', 0),
|
||||
'PROWL_ON_RESUME': (int, 'Prowl', 0),
|
||||
'PROWL_ON_BUFFER': (int, 'Prowl', 0),
|
||||
'PROWL_ON_WATCHED': (int, 'Prowl', 0),
|
||||
'PUSHALOT_APIKEY': (str, 'Pushalot', ''),
|
||||
'PUSHALOT_ENABLED': (int, 'Pushalot', 0),
|
||||
'PUSHALOT_ON_PLAY': (int, 'Pushalot', 0),
|
||||
'PUSHALOT_ON_STOP': (int, 'Pushalot', 0),
|
||||
'PUSHALOT_ON_PAUSE': (int, 'Pushalot', 0),
|
||||
'PUSHALOT_ON_RESUME': (int, 'Pushalot', 0),
|
||||
'PUSHALOT_ON_BUFFER': (int, 'Pushalot', 0),
|
||||
'PUSHALOT_ON_WATCHED': (int, 'Pushalot', 0),
|
||||
'PUSHBULLET_APIKEY': (str, 'PushBullet', ''),
|
||||
'PUSHBULLET_DEVICEID': (str, 'PushBullet', ''),
|
||||
|
@ -138,6 +170,9 @@ _CONFIG_DEFINITIONS = {
|
|||
'PUSHBULLET_ENABLED': (int, 'PushBullet', 0),
|
||||
'PUSHBULLET_ON_PLAY': (int, 'PushBullet', 0),
|
||||
'PUSHBULLET_ON_STOP': (int, 'PushBullet', 0),
|
||||
'PUSHBULLET_ON_PAUSE': (int, 'PushBullet', 0),
|
||||
'PUSHBULLET_ON_RESUME': (int, 'PushBullet', 0),
|
||||
'PUSHBULLET_ON_BUFFER': (int, 'PushBullet', 0),
|
||||
'PUSHBULLET_ON_WATCHED': (int, 'PushBullet', 0),
|
||||
'PUSHOVER_APITOKEN': (str, 'Pushover', ''),
|
||||
'PUSHOVER_ENABLED': (int, 'Pushover', 0),
|
||||
|
@ -145,6 +180,9 @@ _CONFIG_DEFINITIONS = {
|
|||
'PUSHOVER_PRIORITY': (int, 'Pushover', 0),
|
||||
'PUSHOVER_ON_PLAY': (int, 'Pushover', 0),
|
||||
'PUSHOVER_ON_STOP': (int, 'Pushover', 0),
|
||||
'PUSHOVER_ON_PAUSE': (int, 'Pushover', 0),
|
||||
'PUSHOVER_ON_RESUME': (int, 'Pushover', 0),
|
||||
'PUSHOVER_ON_BUFFER': (int, 'Pushover', 0),
|
||||
'PUSHOVER_ON_WATCHED': (int, 'Pushover', 0),
|
||||
'REFRESH_USERS_INTERVAL': (int, 'Monitoring', 12),
|
||||
'REFRESH_USERS_ON_STARTUP': (int, 'Monitoring', 1),
|
||||
|
@ -165,6 +203,9 @@ _CONFIG_DEFINITIONS = {
|
|||
'XBMC_USERNAME': (str, 'XBMC', ''),
|
||||
'XBMC_ON_PLAY': (int, 'XBMC', 0),
|
||||
'XBMC_ON_STOP': (int, 'XBMC', 0),
|
||||
'XBMC_ON_PAUSE': (int, 'XBMC', 0),
|
||||
'XBMC_ON_RESUME': (int, 'XBMC', 0),
|
||||
'XBMC_ON_BUFFER': (int, 'XBMC', 0),
|
||||
'XBMC_ON_WATCHED': (int, 'XBMC', 0)
|
||||
}
|
||||
# pylint:disable=R0902
|
||||
|
|
|
@ -59,6 +59,11 @@ def check_active_sessions():
|
|||
# Push it on it's own thread so we don't hold up our db actions
|
||||
threading.Thread(target=notification_handler.notify,
|
||||
kwargs=dict(stream_data=stream, notify_action='pause')).start()
|
||||
if session['state'] == 'playing' and stream['state'] == 'paused':
|
||||
# Push any notifications -
|
||||
# Push it on it's own thread so we don't hold up our db actions
|
||||
threading.Thread(target=notification_handler.notify,
|
||||
kwargs=dict(stream_data=stream, notify_action='resume')).start()
|
||||
if stream['state'] == 'paused':
|
||||
# The stream is still paused so we need to increment the paused_counter
|
||||
# Using the set config parameter as the interval, probably not the most accurate but
|
||||
|
@ -67,6 +72,47 @@ def check_active_sessions():
|
|||
monitor_db.action('UPDATE sessions SET paused_counter = ? '
|
||||
'WHERE session_key = ? AND rating_key = ?',
|
||||
[paused_counter, stream['session_key'], stream['rating_key']])
|
||||
if session['state'] == 'buffering':
|
||||
# The stream is buffering so we need to increment the buffer_count
|
||||
# We're going just increment on every monitor ping,
|
||||
# would be difficult to keep track otherwise
|
||||
monitor_db.action('UPDATE sessions SET buffer_count = buffer_count + 1 '
|
||||
'WHERE session_key = ? AND rating_key = ?',
|
||||
[stream['session_key'], stream['rating_key']])
|
||||
|
||||
# Check the current buffer count and last buffer to determine if we should notify
|
||||
buffer_values = monitor_db.select('SELECT buffer_count, buffer_last_triggered '
|
||||
'FROM sessions '
|
||||
'WHERE session_key = ? AND rating_key = ?',
|
||||
[stream['session_key'], stream['rating_key']])
|
||||
|
||||
if buffer_values[0]['buffer_count'] >= plexpy.CONFIG.BUFFER_THRESHOLD:
|
||||
# Push any notifications -
|
||||
# Push it on it's own thread so we don't hold up our db actions
|
||||
# Our first buffer notification
|
||||
if buffer_values[0]['buffer_count'] == plexpy.CONFIG.BUFFER_THRESHOLD:
|
||||
logger.info(u"PlexPy Monitor :: User '%s' has triggered a buffer warning."
|
||||
% stream['user'])
|
||||
# Set the buffer trigger time
|
||||
monitor_db.action('UPDATE sessions '
|
||||
'SET buffer_last_triggered = strftime("%s","now") '
|
||||
'WHERE session_key = ? AND rating_key = ?',
|
||||
[stream['session_key'], stream['rating_key']])
|
||||
|
||||
threading.Thread(target=notification_handler.notify,
|
||||
kwargs=dict(stream_data=stream, notify_action='buffer')).start()
|
||||
else:
|
||||
# Subsequent buffer notifications after wait time
|
||||
if int(time.time()) > buffer_values[0]['buffer_last_triggered'] + \
|
||||
plexpy.CONFIG.BUFFER_WAIT:
|
||||
logger.info(u"PlexPy Monitor :: User '%s' has triggered multiple buffer warnings."
|
||||
% stream['user'])
|
||||
threading.Thread(target=notification_handler.notify,
|
||||
kwargs=dict(stream_data=stream, notify_action='buffer')).start()
|
||||
|
||||
logger.debug(u"PlexPy Monitor :: Stream buffering. Count is now %s. Last triggered %s."
|
||||
% (buffer_values[0][0], buffer_values[0][1]))
|
||||
|
||||
# Check if the user has reached the offset in the media we defined as the "watched" percent
|
||||
# Don't trigger if state is buffer as some clients push the progress to the end when
|
||||
# buffering on start.
|
||||
|
|
|
@ -52,6 +52,33 @@ def notify(stream_data=None, notify_action=None):
|
|||
|
||||
set_notify_state(session=stream_data, state='stop', agent_info=agent)
|
||||
|
||||
elif agent['on_pause'] and notify_action == 'pause':
|
||||
# Build and send notification
|
||||
notify_strings = build_notify_text(session=stream_data, state=notify_action)
|
||||
notifiers.send_notification(config_id=agent['id'],
|
||||
subject=notify_strings[0],
|
||||
body=notify_strings[1])
|
||||
|
||||
set_notify_state(session=stream_data, state='pause', agent_info=agent)
|
||||
|
||||
elif agent['on_resume'] and notify_action == 'resume':
|
||||
# Build and send notification
|
||||
notify_strings = build_notify_text(session=stream_data, state=notify_action)
|
||||
notifiers.send_notification(config_id=agent['id'],
|
||||
subject=notify_strings[0],
|
||||
body=notify_strings[1])
|
||||
|
||||
set_notify_state(session=stream_data, state='resume', agent_info=agent)
|
||||
|
||||
elif agent['on_buffer'] and notify_action == 'buffer':
|
||||
# Build and send notification
|
||||
notify_strings = build_notify_text(session=stream_data, state=notify_action)
|
||||
notifiers.send_notification(config_id=agent['id'],
|
||||
subject=notify_strings[0],
|
||||
body=notify_strings[1])
|
||||
|
||||
set_notify_state(session=stream_data, state='buffer', agent_info=agent)
|
||||
|
||||
elif agent['on_watched'] and notify_action == 'watched':
|
||||
# Get the current states for notifications from our db
|
||||
notify_states = get_notify_state(session=stream_data)
|
||||
|
@ -100,6 +127,33 @@ def notify(stream_data=None, notify_action=None):
|
|||
# Set the notification state in the db
|
||||
set_notify_state(session=stream_data, state='stop', agent_info=agent)
|
||||
|
||||
elif agent['on_pause'] and notify_action == 'pause':
|
||||
# Build and send notification
|
||||
notify_strings = build_notify_text(session=stream_data, state=notify_action)
|
||||
notifiers.send_notification(config_id=agent['id'],
|
||||
subject=notify_strings[0],
|
||||
body=notify_strings[1])
|
||||
# Set the notification state in the db
|
||||
set_notify_state(session=stream_data, state='pause', agent_info=agent)
|
||||
|
||||
elif agent['on_resume'] and notify_action == 'resume':
|
||||
# Build and send notification
|
||||
notify_strings = build_notify_text(session=stream_data, state=notify_action)
|
||||
notifiers.send_notification(config_id=agent['id'],
|
||||
subject=notify_strings[0],
|
||||
body=notify_strings[1])
|
||||
# Set the notification state in the db
|
||||
set_notify_state(session=stream_data, state='resume', agent_info=agent)
|
||||
|
||||
elif agent['on_buffer'] and notify_action == 'buffer':
|
||||
# Build and send notification
|
||||
notify_strings = build_notify_text(session=stream_data, state=notify_action)
|
||||
notifiers.send_notification(config_id=agent['id'],
|
||||
subject=notify_strings[0],
|
||||
body=notify_strings[1])
|
||||
# Set the notification state in the db
|
||||
set_notify_state(session=stream_data, state='buffer', agent_info=agent)
|
||||
|
||||
elif stream_data['media_type'] == 'clip':
|
||||
pass
|
||||
else:
|
||||
|
@ -110,7 +164,7 @@ def notify(stream_data=None, notify_action=None):
|
|||
|
||||
def get_notify_state(session):
|
||||
monitor_db = database.MonitorDatabase()
|
||||
result = monitor_db.select('SELECT on_play, on_stop, on_watched, agent_id '
|
||||
result = monitor_db.select('SELECT on_play, on_stop, on_pause, on_resume, on_buffer, on_watched, agent_id '
|
||||
'FROM notify_log '
|
||||
'WHERE session_key = ? '
|
||||
'AND rating_key = ? '
|
||||
|
@ -121,8 +175,11 @@ def get_notify_state(session):
|
|||
for item in result:
|
||||
notify_state = {'on_play': item[0],
|
||||
'on_stop': item[1],
|
||||
'on_watched': item[2],
|
||||
'agent_id': item[3]}
|
||||
'on_pause': item[2],
|
||||
'on_resume': item[3],
|
||||
'on_buffer': item[4],
|
||||
'on_watched': item[5],
|
||||
'agent_id': item[6]}
|
||||
notify_states.append(notify_state)
|
||||
|
||||
return notify_states
|
||||
|
@ -136,6 +193,12 @@ def set_notify_state(session, state, agent_info):
|
|||
values = {'on_play': int(time.time())}
|
||||
elif state == 'stop':
|
||||
values = {'on_stop': int(time.time())}
|
||||
elif state == 'pause':
|
||||
values = {'on_pause': int(time.time())}
|
||||
elif state == 'resume':
|
||||
values = {'on_resume': int(time.time())}
|
||||
elif state == 'buffer':
|
||||
values = {'on_buffer': int(time.time())}
|
||||
elif state == 'watched':
|
||||
values = {'on_watched': int(time.time())}
|
||||
else:
|
||||
|
@ -173,34 +236,28 @@ def build_notify_text(session, state):
|
|||
if session['media_type'] == 'episode':
|
||||
# Regex pattern to remove the text in the tags we don't want
|
||||
pattern = re.compile('<movie>[^>]+.</movie>|<music>[^>]+.</music>', re.IGNORECASE)
|
||||
|
||||
# Remove the unwanted tags and strip any unmatch tags too.
|
||||
on_start_subject = strip_tag(re.sub(pattern, '', plexpy.CONFIG.NOTIFY_ON_START_SUBJECT_TEXT))
|
||||
on_start_body = strip_tag(re.sub(pattern, '', plexpy.CONFIG.NOTIFY_ON_START_BODY_TEXT))
|
||||
on_stop_subject = strip_tag(re.sub(pattern, '', plexpy.CONFIG.NOTIFY_ON_STOP_SUBJECT_TEXT))
|
||||
on_stop_body = strip_tag(re.sub(pattern, '', plexpy.CONFIG.NOTIFY_ON_STOP_BODY_TEXT))
|
||||
on_watched_subject = strip_tag(re.sub(pattern, '', plexpy.CONFIG.NOTIFY_ON_WATCHED_SUBJECT_TEXT))
|
||||
on_watched_body = strip_tag(re.sub(pattern, '', plexpy.CONFIG.NOTIFY_ON_WATCHED_BODY_TEXT))
|
||||
elif session['media_type'] == 'movie':
|
||||
# Regex pattern to remove the text in the tags we don't want
|
||||
pattern = re.compile('<tv>[^>]+.</tv>|<music>[^>]+.</music>', re.IGNORECASE)
|
||||
|
||||
# Remove the unwanted tags and strip any unmatch tags too.
|
||||
on_start_subject = strip_tag(re.sub(pattern, '', plexpy.CONFIG.NOTIFY_ON_START_SUBJECT_TEXT))
|
||||
on_start_body = strip_tag(re.sub(pattern, '', plexpy.CONFIG.NOTIFY_ON_START_BODY_TEXT))
|
||||
on_stop_subject = strip_tag(re.sub(pattern, '', plexpy.CONFIG.NOTIFY_ON_STOP_SUBJECT_TEXT))
|
||||
on_stop_body = strip_tag(re.sub(pattern, '', plexpy.CONFIG.NOTIFY_ON_STOP_BODY_TEXT))
|
||||
on_watched_subject = strip_tag(re.sub(pattern, '', plexpy.CONFIG.NOTIFY_ON_WATCHED_SUBJECT_TEXT))
|
||||
on_watched_body = strip_tag(re.sub(pattern, '', plexpy.CONFIG.NOTIFY_ON_WATCHED_BODY_TEXT))
|
||||
elif session['media_type'] == 'track':
|
||||
# Regex pattern to remove the text in the tags we don't want
|
||||
pattern = re.compile('<tv>[^>]+.</tv>|<movie>[^>]+.</movie>', re.IGNORECASE)
|
||||
else:
|
||||
pattern = None
|
||||
|
||||
if session['media_type'] == 'episode' or session['media_type'] == 'movie' or session['media_type'] == 'track' \
|
||||
and pattern:
|
||||
# Remove the unwanted tags and strip any unmatch tags too.
|
||||
on_start_subject = strip_tag(re.sub(pattern, '', plexpy.CONFIG.NOTIFY_ON_START_SUBJECT_TEXT))
|
||||
on_start_body = strip_tag(re.sub(pattern, '', plexpy.CONFIG.NOTIFY_ON_START_BODY_TEXT))
|
||||
on_stop_subject = strip_tag(re.sub(pattern, '', plexpy.CONFIG.NOTIFY_ON_STOP_SUBJECT_TEXT))
|
||||
on_stop_body = strip_tag(re.sub(pattern, '', plexpy.CONFIG.NOTIFY_ON_STOP_BODY_TEXT))
|
||||
on_pause_subject = strip_tag(re.sub(pattern, '', plexpy.CONFIG.NOTIFY_ON_PAUSE_SUBJECT_TEXT))
|
||||
on_pause_body = strip_tag(re.sub(pattern, '', plexpy.CONFIG.NOTIFY_ON_PAUSE_BODY_TEXT))
|
||||
on_resume_subject = strip_tag(re.sub(pattern, '', plexpy.CONFIG.NOTIFY_ON_RESUME_SUBJECT_TEXT))
|
||||
on_resume_body = strip_tag(re.sub(pattern, '', plexpy.CONFIG.NOTIFY_ON_RESUME_BODY_TEXT))
|
||||
on_buffer_subject = strip_tag(re.sub(pattern, '', plexpy.CONFIG.NOTIFY_ON_BUFFER_SUBJECT_TEXT))
|
||||
on_buffer_body = strip_tag(re.sub(pattern, '', plexpy.CONFIG.NOTIFY_ON_BUFFER_BODY_TEXT))
|
||||
on_watched_subject = strip_tag(re.sub(pattern, '', plexpy.CONFIG.NOTIFY_ON_WATCHED_SUBJECT_TEXT))
|
||||
on_watched_body = strip_tag(re.sub(pattern, '', plexpy.CONFIG.NOTIFY_ON_WATCHED_BODY_TEXT))
|
||||
else:
|
||||
|
@ -208,6 +265,12 @@ def build_notify_text(session, state):
|
|||
on_start_body = plexpy.CONFIG.NOTIFY_ON_START_BODY_TEXT
|
||||
on_stop_subject = plexpy.CONFIG.NOTIFY_ON_STOP_SUBJECT_TEXT
|
||||
on_stop_body = plexpy.CONFIG.NOTIFY_ON_STOP_BODY_TEXT
|
||||
on_pause_subject = plexpy.CONFIG.NOTIFY_ON_PAUSE_SUBJECT_TEXT
|
||||
on_pause_body = plexpy.CONFIG.NOTIFY_ON_PAUSE_BODY_TEXT
|
||||
on_resume_subject = plexpy.CONFIG.NOTIFY_ON_RESUME_SUBJECT_TEXT
|
||||
on_resume_body = plexpy.CONFIG.NOTIFY_ON_RESUME_BODY_TEXT
|
||||
on_buffer_subject = plexpy.CONFIG.NOTIFY_ON_BUFFER_SUBJECT_TEXT
|
||||
on_buffer_body = plexpy.CONFIG.NOTIFY_ON_BUFFER_BODY_TEXT
|
||||
on_watched_subject = plexpy.CONFIG.NOTIFY_ON_WATCHED_SUBJECT_TEXT
|
||||
on_watched_body = plexpy.CONFIG.NOTIFY_ON_WATCHED_BODY_TEXT
|
||||
|
||||
|
@ -310,6 +373,78 @@ def build_notify_text(session, state):
|
|||
except:
|
||||
logger.error(u"PlexPy Notifier :: Unable to parse custom notification body. Using fallback.")
|
||||
|
||||
return [subject_text, body_text]
|
||||
else:
|
||||
return [subject_text, body_text]
|
||||
elif state == 'pause':
|
||||
# Default body text
|
||||
body_text = '%s (%s) has paused %s' % (session['friendly_name'],
|
||||
session['player'],
|
||||
full_title)
|
||||
|
||||
if on_pause_subject and on_pause_body:
|
||||
try:
|
||||
subject_text = on_pause_subject.format(**available_params)
|
||||
except LookupError, e:
|
||||
logger.error(u"PlexPy Notifier :: Unable to parse field %s in notification subject. Using fallback." % e)
|
||||
except:
|
||||
logger.error(u"PlexPy Notifier :: Unable to parse custom notification subject. Using fallback.")
|
||||
|
||||
try:
|
||||
body_text = on_pause_body.format(**available_params)
|
||||
except LookupError, e:
|
||||
logger.error(u"PlexPy Notifier :: Unable to parse field %s in notification body. Using fallback." % e)
|
||||
except:
|
||||
logger.error(u"PlexPy Notifier :: Unable to parse custom notification body. Using fallback.")
|
||||
|
||||
return [subject_text, body_text]
|
||||
else:
|
||||
return [subject_text, body_text]
|
||||
elif state == 'resume':
|
||||
# Default body text
|
||||
body_text = '%s (%s) has resumed %s' % (session['friendly_name'],
|
||||
session['player'],
|
||||
full_title)
|
||||
|
||||
if on_resume_subject and on_resume_body:
|
||||
try:
|
||||
subject_text = on_resume_subject.format(**available_params)
|
||||
except LookupError, e:
|
||||
logger.error(u"PlexPy Notifier :: Unable to parse field %s in notification subject. Using fallback." % e)
|
||||
except:
|
||||
logger.error(u"PlexPy Notifier :: Unable to parse custom notification subject. Using fallback.")
|
||||
|
||||
try:
|
||||
body_text = on_resume_body.format(**available_params)
|
||||
except LookupError, e:
|
||||
logger.error(u"PlexPy Notifier :: Unable to parse field %s in notification body. Using fallback." % e)
|
||||
except:
|
||||
logger.error(u"PlexPy Notifier :: Unable to parse custom notification body. Using fallback.")
|
||||
|
||||
return [subject_text, body_text]
|
||||
else:
|
||||
return [subject_text, body_text]
|
||||
elif state == 'buffer':
|
||||
# Default body text
|
||||
body_text = '%s (%s) is buffering %s' % (session['friendly_name'],
|
||||
session['player'],
|
||||
full_title)
|
||||
|
||||
if on_buffer_subject and on_buffer_body:
|
||||
try:
|
||||
subject_text = on_buffer_subject.format(**available_params)
|
||||
except LookupError, e:
|
||||
logger.error(u"PlexPy Notifier :: Unable to parse field %s in notification subject. Using fallback." % e)
|
||||
except:
|
||||
logger.error(u"PlexPy Notifier :: Unable to parse custom notification subject. Using fallback.")
|
||||
|
||||
try:
|
||||
body_text = on_buffer_body.format(**available_params)
|
||||
except LookupError, e:
|
||||
logger.error(u"PlexPy Notifier :: Unable to parse field %s in notification body. Using fallback." % e)
|
||||
except:
|
||||
logger.error(u"PlexPy Notifier :: Unable to parse custom notification body. Using fallback.")
|
||||
|
||||
return [subject_text, body_text]
|
||||
else:
|
||||
return [subject_text, body_text]
|
||||
|
|
|
@ -59,6 +59,9 @@ def available_notification_agents():
|
|||
'state': checked(plexpy.CONFIG.GROWL_ENABLED),
|
||||
'on_play': plexpy.CONFIG.GROWL_ON_PLAY,
|
||||
'on_stop': plexpy.CONFIG.GROWL_ON_STOP,
|
||||
'on_pause': plexpy.CONFIG.GROWL_ON_PAUSE,
|
||||
'on_resume': plexpy.CONFIG.GROWL_ON_RESUME,
|
||||
'on_buffer': plexpy.CONFIG.GROWL_ON_BUFFER,
|
||||
'on_watched': plexpy.CONFIG.GROWL_ON_WATCHED
|
||||
},
|
||||
{'name': 'Prowl',
|
||||
|
@ -68,6 +71,9 @@ def available_notification_agents():
|
|||
'state': checked(plexpy.CONFIG.PROWL_ENABLED),
|
||||
'on_play': plexpy.CONFIG.PROWL_ON_PLAY,
|
||||
'on_stop': plexpy.CONFIG.PROWL_ON_STOP,
|
||||
'on_pause': plexpy.CONFIG.PROWL_ON_PAUSE,
|
||||
'on_resume': plexpy.CONFIG.PROWL_ON_RESUME,
|
||||
'on_buffer': plexpy.CONFIG.PROWL_ON_BUFFER,
|
||||
'on_watched': plexpy.CONFIG.PROWL_ON_WATCHED
|
||||
},
|
||||
{'name': 'XBMC',
|
||||
|
@ -77,6 +83,9 @@ def available_notification_agents():
|
|||
'state': checked(plexpy.CONFIG.XBMC_ENABLED),
|
||||
'on_play': plexpy.CONFIG.XBMC_ON_PLAY,
|
||||
'on_stop': plexpy.CONFIG.XBMC_ON_STOP,
|
||||
'on_pause': plexpy.CONFIG.XBMC_ON_PAUSE,
|
||||
'on_resume': plexpy.CONFIG.XBMC_ON_RESUME,
|
||||
'on_buffer': plexpy.CONFIG.XBMC_ON_BUFFER,
|
||||
'on_watched': plexpy.CONFIG.XBMC_ON_WATCHED
|
||||
},
|
||||
{'name': 'Plex',
|
||||
|
@ -86,6 +95,9 @@ def available_notification_agents():
|
|||
'state': checked(plexpy.CONFIG.PLEX_ENABLED),
|
||||
'on_play': plexpy.CONFIG.PLEX_ON_PLAY,
|
||||
'on_stop': plexpy.CONFIG.PLEX_ON_STOP,
|
||||
'on_pause': plexpy.CONFIG.PLEX_ON_PAUSE,
|
||||
'on_resume': plexpy.CONFIG.PLEX_ON_RESUME,
|
||||
'on_buffer': plexpy.CONFIG.PLEX_ON_BUFFER,
|
||||
'on_watched': plexpy.CONFIG.PLEX_ON_WATCHED
|
||||
},
|
||||
{'name': 'NotifyMyAndroid',
|
||||
|
@ -95,6 +107,9 @@ def available_notification_agents():
|
|||
'state': checked(plexpy.CONFIG.NMA_ENABLED),
|
||||
'on_play': plexpy.CONFIG.NMA_ON_PLAY,
|
||||
'on_stop': plexpy.CONFIG.NMA_ON_STOP,
|
||||
'on_pause': plexpy.CONFIG.NMA_ON_PAUSE,
|
||||
'on_resume': plexpy.CONFIG.NMA_ON_RESUME,
|
||||
'on_buffer': plexpy.CONFIG.NMA_ON_BUFFER,
|
||||
'on_watched': plexpy.CONFIG.NMA_ON_WATCHED
|
||||
},
|
||||
{'name': 'Pushalot',
|
||||
|
@ -104,6 +119,9 @@ def available_notification_agents():
|
|||
'state': checked(plexpy.CONFIG.PUSHALOT_ENABLED),
|
||||
'on_play': plexpy.CONFIG.PUSHALOT_ON_PLAY,
|
||||
'on_stop': plexpy.CONFIG.PUSHALOT_ON_STOP,
|
||||
'on_pause': plexpy.CONFIG.PUSHALOT_ON_PAUSE,
|
||||
'on_resume': plexpy.CONFIG.PUSHALOT_ON_RESUME,
|
||||
'on_buffer': plexpy.CONFIG.PUSHALOT_ON_BUFFER,
|
||||
'on_watched': plexpy.CONFIG.PUSHALOT_ON_WATCHED
|
||||
},
|
||||
{'name': 'Pushbullet',
|
||||
|
@ -113,6 +131,9 @@ def available_notification_agents():
|
|||
'state': checked(plexpy.CONFIG.PUSHBULLET_ENABLED),
|
||||
'on_play': plexpy.CONFIG.PUSHBULLET_ON_PLAY,
|
||||
'on_stop': plexpy.CONFIG.PUSHBULLET_ON_STOP,
|
||||
'on_pause': plexpy.CONFIG.PUSHBULLET_ON_PAUSE,
|
||||
'on_resume': plexpy.CONFIG.PUSHBULLET_ON_RESUME,
|
||||
'on_buffer': plexpy.CONFIG.PUSHBULLET_ON_BUFFER,
|
||||
'on_watched': plexpy.CONFIG.PUSHBULLET_ON_WATCHED
|
||||
},
|
||||
{'name': 'Pushover',
|
||||
|
@ -122,6 +143,9 @@ def available_notification_agents():
|
|||
'state': checked(plexpy.CONFIG.PUSHOVER_ENABLED),
|
||||
'on_play': plexpy.CONFIG.PUSHOVER_ON_PLAY,
|
||||
'on_stop': plexpy.CONFIG.PUSHOVER_ON_STOP,
|
||||
'on_pause': plexpy.CONFIG.PUSHOVER_ON_PAUSE,
|
||||
'on_resume': plexpy.CONFIG.PUSHOVER_ON_RESUME,
|
||||
'on_buffer': plexpy.CONFIG.PUSHOVER_ON_BUFFER,
|
||||
'on_watched': plexpy.CONFIG.PUSHOVER_ON_WATCHED
|
||||
},
|
||||
{'name': 'Boxcar2',
|
||||
|
@ -131,6 +155,9 @@ def available_notification_agents():
|
|||
'state': checked(plexpy.CONFIG.BOXCAR_ENABLED),
|
||||
'on_play': plexpy.CONFIG.BOXCAR_ON_PLAY,
|
||||
'on_stop': plexpy.CONFIG.BOXCAR_ON_STOP,
|
||||
'on_pause': plexpy.CONFIG.BOXCAR_ON_PAUSE,
|
||||
'on_resume': plexpy.CONFIG.BOXCAR_ON_RESUME,
|
||||
'on_buffer': plexpy.CONFIG.BOXCAR_ON_BUFFER,
|
||||
'on_watched': plexpy.CONFIG.BOXCAR_ON_WATCHED
|
||||
},
|
||||
{'name': 'E-mail',
|
||||
|
@ -140,6 +167,9 @@ def available_notification_agents():
|
|||
'state': checked(plexpy.CONFIG.EMAIL_ENABLED),
|
||||
'on_play': plexpy.CONFIG.EMAIL_ON_PLAY,
|
||||
'on_stop': plexpy.CONFIG.EMAIL_ON_STOP,
|
||||
'on_pause': plexpy.CONFIG.EMAIL_ON_PAUSE,
|
||||
'on_resume': plexpy.CONFIG.EMAIL_ON_RESUME,
|
||||
'on_buffer': plexpy.CONFIG.EMAIL_ON_BUFFER,
|
||||
'on_watched': plexpy.CONFIG.EMAIL_ON_WATCHED
|
||||
}
|
||||
]
|
||||
|
@ -154,6 +184,9 @@ def available_notification_agents():
|
|||
'state': checked(plexpy.CONFIG.OSX_NOTIFY_ENABLED),
|
||||
'on_play': plexpy.CONFIG.OSX_NOTIFY_ON_PLAY,
|
||||
'on_stop': plexpy.CONFIG.OSX_NOTIFY_ON_STOP,
|
||||
'on_pause': plexpy.CONFIG.OSX_NOTIFY_ON_PAUSE,
|
||||
'on_resume': plexpy.CONFIG.OSX_NOTIFY_ON_RESUME,
|
||||
'on_buffer': plexpy.CONFIG.OSX_NOTIFY_ON_BUFFER,
|
||||
'on_watched': plexpy.CONFIG.OSX_NOTIFY_ON_WATCHED
|
||||
})
|
||||
|
||||
|
|
|
@ -436,9 +436,17 @@ class WebInterface(object):
|
|||
"notify_on_start_body_text": plexpy.CONFIG.NOTIFY_ON_START_BODY_TEXT,
|
||||
"notify_on_stop_subject_text": plexpy.CONFIG.NOTIFY_ON_STOP_SUBJECT_TEXT,
|
||||
"notify_on_stop_body_text": plexpy.CONFIG.NOTIFY_ON_STOP_BODY_TEXT,
|
||||
"notify_on_pause_subject_text": plexpy.CONFIG.NOTIFY_ON_PAUSE_SUBJECT_TEXT,
|
||||
"notify_on_pause_body_text": plexpy.CONFIG.NOTIFY_ON_PAUSE_BODY_TEXT,
|
||||
"notify_on_resume_subject_text": plexpy.CONFIG.NOTIFY_ON_RESUME_SUBJECT_TEXT,
|
||||
"notify_on_resume_body_text": plexpy.CONFIG.NOTIFY_ON_RESUME_BODY_TEXT,
|
||||
"notify_on_buffer_subject_text": plexpy.CONFIG.NOTIFY_ON_BUFFER_SUBJECT_TEXT,
|
||||
"notify_on_buffer_body_text": plexpy.CONFIG.NOTIFY_ON_BUFFER_BODY_TEXT,
|
||||
"notify_on_watched_subject_text": plexpy.CONFIG.NOTIFY_ON_WATCHED_SUBJECT_TEXT,
|
||||
"notify_on_watched_body_text": plexpy.CONFIG.NOTIFY_ON_WATCHED_BODY_TEXT,
|
||||
"home_stats_length": plexpy.CONFIG.HOME_STATS_LENGTH
|
||||
"home_stats_length": plexpy.CONFIG.HOME_STATS_LENGTH,
|
||||
"buffer_threshold": plexpy.CONFIG.BUFFER_THRESHOLD,
|
||||
"buffer_wait": plexpy.CONFIG.BUFFER_WAIT
|
||||
}
|
||||
|
||||
return serve_template(templatename="settings.html", title="Settings", config=config)
|
||||
|
@ -1226,3 +1234,19 @@ class WebInterface(object):
|
|||
|
||||
return serve_template(templatename="notification_config.html", title="Notification Configuration",
|
||||
data=config, checkboxes=checkboxes)
|
||||
|
||||
@cherrypy.expose
|
||||
def get_notification_agent_triggers(self, config_id, **kwargs):
|
||||
if config_id.isdigit():
|
||||
agents = notifiers.available_notification_agents()
|
||||
for agent in agents:
|
||||
if int(config_id) == agent['id']:
|
||||
this_agent = agent
|
||||
break
|
||||
else:
|
||||
this_agent = None
|
||||
else:
|
||||
return None
|
||||
|
||||
return serve_template(templatename="notification_triggers_modal.html", title="Notification Triggers",
|
||||
data=this_agent)
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue