mirror of
https://github.com/Tautulli/Tautulli.git
synced 2025-08-20 13:23:24 -07:00
Merge pull request #1321 from samwiseg00/add/notify_state_change
Add the ability to notify on transcode decision state change
This commit is contained in:
commit
6bb6e27378
3 changed files with 59 additions and 8 deletions
|
@ -662,17 +662,17 @@ def dbcheck():
|
||||||
'CREATE TABLE IF NOT EXISTS notifiers (id INTEGER PRIMARY KEY AUTOINCREMENT, '
|
'CREATE TABLE IF NOT EXISTS notifiers (id INTEGER PRIMARY KEY AUTOINCREMENT, '
|
||||||
'agent_id INTEGER, agent_name TEXT, agent_label TEXT, friendly_name TEXT, notifier_config TEXT, '
|
'agent_id INTEGER, agent_name TEXT, agent_label TEXT, friendly_name TEXT, notifier_config TEXT, '
|
||||||
'on_play INTEGER DEFAULT 0, on_stop INTEGER DEFAULT 0, on_pause INTEGER DEFAULT 0, '
|
'on_play INTEGER DEFAULT 0, on_stop INTEGER DEFAULT 0, on_pause INTEGER DEFAULT 0, '
|
||||||
'on_resume INTEGER DEFAULT 0, on_buffer INTEGER DEFAULT 0, on_watched INTEGER DEFAULT 0, '
|
'on_resume INTEGER DEFAULT 0, on_change INTEGER DEFAULT 0, on_buffer INTEGER DEFAULT 0, on_watched INTEGER DEFAULT 0, '
|
||||||
'on_created INTEGER DEFAULT 0, on_extdown INTEGER DEFAULT 0, on_intdown INTEGER DEFAULT 0, '
|
'on_created INTEGER DEFAULT 0, on_extdown INTEGER DEFAULT 0, on_intdown INTEGER DEFAULT 0, '
|
||||||
'on_extup INTEGER DEFAULT 0, on_intup INTEGER DEFAULT 0, on_pmsupdate INTEGER DEFAULT 0, '
|
'on_extup INTEGER DEFAULT 0, on_intup INTEGER DEFAULT 0, on_pmsupdate INTEGER DEFAULT 0, '
|
||||||
'on_concurrent INTEGER DEFAULT 0, on_newdevice INTEGER DEFAULT 0, on_plexpyupdate INTEGER DEFAULT 0, '
|
'on_concurrent INTEGER DEFAULT 0, on_newdevice INTEGER DEFAULT 0, on_plexpyupdate INTEGER DEFAULT 0, '
|
||||||
'on_play_subject TEXT, on_stop_subject TEXT, on_pause_subject TEXT, '
|
'on_play_subject TEXT, on_stop_subject TEXT, on_pause_subject TEXT, '
|
||||||
'on_resume_subject TEXT, on_buffer_subject TEXT, on_watched_subject TEXT, '
|
'on_resume_subject TEXT, on_change_subject TEXT, on_buffer_subject TEXT, on_watched_subject TEXT, '
|
||||||
'on_created_subject TEXT, on_extdown_subject TEXT, on_intdown_subject TEXT, '
|
'on_created_subject TEXT, on_extdown_subject TEXT, on_intdown_subject TEXT, '
|
||||||
'on_extup_subject TEXT, on_intup_subject TEXT, on_pmsupdate_subject TEXT, '
|
'on_extup_subject TEXT, on_intup_subject TEXT, on_pmsupdate_subject TEXT, '
|
||||||
'on_concurrent_subject TEXT, on_newdevice_subject TEXT, on_plexpyupdate_subject TEXT, '
|
'on_concurrent_subject TEXT, on_newdevice_subject TEXT, on_plexpyupdate_subject TEXT, '
|
||||||
'on_play_body TEXT, on_stop_body TEXT, on_pause_body TEXT, '
|
'on_play_body TEXT, on_stop_body TEXT, on_pause_body TEXT, '
|
||||||
'on_resume_body TEXT, on_buffer_body TEXT, on_watched_body TEXT, '
|
'on_resume_body TEXT, on_change_body TEXT, on_buffer_body TEXT, on_watched_body TEXT, '
|
||||||
'on_created_body TEXT, on_extdown_body TEXT, on_intdown_body TEXT, '
|
'on_created_body TEXT, on_extdown_body TEXT, on_intdown_body TEXT, '
|
||||||
'on_extup_body TEXT, on_intup_body TEXT, on_pmsupdate_body TEXT, '
|
'on_extup_body TEXT, on_intup_body TEXT, on_pmsupdate_body TEXT, '
|
||||||
'on_concurrent_body TEXT, on_newdevice_body TEXT, on_plexpyupdate_body TEXT, '
|
'on_concurrent_body TEXT, on_newdevice_body TEXT, on_plexpyupdate_body TEXT, '
|
||||||
|
@ -1733,6 +1733,21 @@ def dbcheck():
|
||||||
'ALTER TABLE notifiers ADD COLUMN custom_conditions_logic TEXT'
|
'ALTER TABLE notifiers ADD COLUMN custom_conditions_logic TEXT'
|
||||||
)
|
)
|
||||||
|
|
||||||
|
# Upgrade notifiers table from earlier versions
|
||||||
|
try:
|
||||||
|
c_db.execute('SELECT on_change FROM notifiers')
|
||||||
|
except sqlite3.OperationalError:
|
||||||
|
logger.debug(u"Altering database. Updating database table notifiers.")
|
||||||
|
c_db.execute(
|
||||||
|
'ALTER TABLE notifiers ADD COLUMN on_change INTEGER DEFAULT 0'
|
||||||
|
)
|
||||||
|
c_db.execute(
|
||||||
|
'ALTER TABLE notifiers ADD COLUMN on_change_subject TEXT'
|
||||||
|
)
|
||||||
|
c_db.execute(
|
||||||
|
'ALTER TABLE notifiers ADD COLUMN on_change_body TEXT'
|
||||||
|
)
|
||||||
|
|
||||||
# Upgrade tvmaze_lookup table from earlier versions
|
# Upgrade tvmaze_lookup table from earlier versions
|
||||||
try:
|
try:
|
||||||
c_db.execute('SELECT rating_key FROM tvmaze_lookup')
|
c_db.execute('SELECT rating_key FROM tvmaze_lookup')
|
||||||
|
|
|
@ -184,6 +184,19 @@ class ActivityHandler(object):
|
||||||
|
|
||||||
plexpy.NOTIFY_QUEUE.put({'stream_data': db_session.copy(), 'notify_action': 'on_resume'})
|
plexpy.NOTIFY_QUEUE.put({'stream_data': db_session.copy(), 'notify_action': 'on_resume'})
|
||||||
|
|
||||||
|
def on_change(self):
|
||||||
|
if self.is_valid_session():
|
||||||
|
logger.debug(u"Tautulli ActivityHandler :: Session %s has changed transcode decision." % str(self.get_session_key()))
|
||||||
|
|
||||||
|
# Update the session state and viewOffset
|
||||||
|
self.update_db_session()
|
||||||
|
|
||||||
|
# Retrieve the session data from our temp table
|
||||||
|
ap = activity_processor.ActivityProcessor()
|
||||||
|
db_session = ap.get_session_by_key(session_key=self.get_session_key())
|
||||||
|
|
||||||
|
plexpy.NOTIFY_QUEUE.put({'stream_data': db_session.copy(), 'notify_action': 'on_change'})
|
||||||
|
|
||||||
def on_buffer(self):
|
def on_buffer(self):
|
||||||
if self.is_valid_session():
|
if self.is_valid_session():
|
||||||
logger.debug(u"Tautulli ActivityHandler :: Session %s is buffering." % self.get_session_key())
|
logger.debug(u"Tautulli ActivityHandler :: Session %s is buffering." % self.get_session_key())
|
||||||
|
@ -228,6 +241,7 @@ class ActivityHandler(object):
|
||||||
this_state = self.timeline['state']
|
this_state = self.timeline['state']
|
||||||
this_rating_key = str(self.timeline['ratingKey'])
|
this_rating_key = str(self.timeline['ratingKey'])
|
||||||
this_key = self.timeline['key']
|
this_key = self.timeline['key']
|
||||||
|
this_transcode_key = self.timeline.get('transcodeSession', '')
|
||||||
|
|
||||||
# Get the live tv session uuid
|
# Get the live tv session uuid
|
||||||
this_live_uuid = this_key.split('/')[-1] if this_key.startswith('/livetv/sessions') else None
|
this_live_uuid = this_key.split('/')[-1] if this_key.startswith('/livetv/sessions') else None
|
||||||
|
@ -241,13 +255,14 @@ class ActivityHandler(object):
|
||||||
last_state = db_session['state']
|
last_state = db_session['state']
|
||||||
last_rating_key = str(db_session['rating_key'])
|
last_rating_key = str(db_session['rating_key'])
|
||||||
last_live_uuid = db_session['live_uuid']
|
last_live_uuid = db_session['live_uuid']
|
||||||
|
last_transcode_key = db_session['transcode_key'].split('/')[-1]
|
||||||
|
|
||||||
# Make sure the same item is being played
|
# Make sure the same item is being played
|
||||||
if this_rating_key == last_rating_key or this_live_uuid == last_live_uuid:
|
if this_rating_key == last_rating_key or this_live_uuid == last_live_uuid:
|
||||||
# Update the session state and viewOffset
|
# Update the session state and viewOffset
|
||||||
if this_state == 'playing':
|
if this_state == 'playing':
|
||||||
# Update the session in our temp session table
|
# Update the session in our temp session table
|
||||||
# if the last set temporary stopped time exceeds 15 seconds
|
# if the last set temporary stopped time exceeds 60 seconds
|
||||||
if int(time.time()) - db_session['stopped'] > 60:
|
if int(time.time()) - db_session['stopped'] > 60:
|
||||||
self.update_db_session()
|
self.update_db_session()
|
||||||
|
|
||||||
|
@ -267,6 +282,9 @@ class ActivityHandler(object):
|
||||||
# Update the session last_paused timestamp
|
# Update the session last_paused timestamp
|
||||||
self.on_pause(still_paused=True)
|
self.on_pause(still_paused=True)
|
||||||
|
|
||||||
|
if this_transcode_key != last_transcode_key and this_state != 'buffering':
|
||||||
|
self.on_change()
|
||||||
|
|
||||||
# If a client doesn't register stop events (I'm looking at you PHT!) check if the ratingKey has changed
|
# If a client doesn't register stop events (I'm looking at you PHT!) check if the ratingKey has changed
|
||||||
else:
|
else:
|
||||||
# Manually stop and start
|
# Manually stop and start
|
||||||
|
|
|
@ -244,6 +244,14 @@ def available_notification_actions():
|
||||||
'icon': 'fa-play',
|
'icon': 'fa-play',
|
||||||
'media_types': ('movie', 'episode', 'track')
|
'media_types': ('movie', 'episode', 'track')
|
||||||
},
|
},
|
||||||
|
{'label': 'Transcode Decision Change',
|
||||||
|
'name': 'on_change',
|
||||||
|
'description': 'Trigger a notification when a stream changes transcode decision.',
|
||||||
|
'subject': 'Tautulli ({server_name})',
|
||||||
|
'body': '{user} ({player}) has changed transcode decision for {title}.',
|
||||||
|
'icon': 'fa-exchange-alt',
|
||||||
|
'media_types': ('movie', 'episode', 'track')
|
||||||
|
},
|
||||||
{'label': 'Watched',
|
{'label': 'Watched',
|
||||||
'name': 'on_watched',
|
'name': 'on_watched',
|
||||||
'description': 'Trigger a notification when a video stream reaches the specified watch percentage.',
|
'description': 'Trigger a notification when a video stream reaches the specified watch percentage.',
|
||||||
|
@ -403,7 +411,9 @@ def get_notify_agents():
|
||||||
return tuple(a['name'] for a in sorted(available_notification_agents(), key=lambda k: k['label']))
|
return tuple(a['name'] for a in sorted(available_notification_agents(), key=lambda k: k['label']))
|
||||||
|
|
||||||
|
|
||||||
def get_notify_actions():
|
def get_notify_actions(return_dict=False):
|
||||||
|
if return_dict:
|
||||||
|
return {a.pop('name'): a for a in available_notification_actions()}
|
||||||
return tuple(a['name'] for a in available_notification_actions())
|
return tuple(a['name'] for a in available_notification_actions())
|
||||||
|
|
||||||
|
|
||||||
|
@ -467,15 +477,23 @@ def get_notifier_config(notifier_id=None):
|
||||||
logger.error(u"Tautulli Notifiers :: Failed to get notifier config options: %s." % e)
|
logger.error(u"Tautulli Notifiers :: Failed to get notifier config options: %s." % e)
|
||||||
return
|
return
|
||||||
|
|
||||||
notify_actions = get_notify_actions()
|
notify_actions = get_notify_actions(return_dict=True)
|
||||||
|
|
||||||
notifier_actions = {}
|
notifier_actions = {}
|
||||||
notifier_text = {}
|
notifier_text = {}
|
||||||
for k in result.keys():
|
for k in result.keys():
|
||||||
if k in notify_actions:
|
if k in notify_actions:
|
||||||
|
subject = result.pop(k + '_subject')
|
||||||
|
body = result.pop(k + '_body')
|
||||||
|
|
||||||
|
if subject is None:
|
||||||
|
subject = "" if result['agent_name'] in ('scripts', 'webhook') else notify_actions[k]['subject']
|
||||||
|
if body is None:
|
||||||
|
body = "" if result['agent_name'] in ('scripts', 'webhook') else notify_actions[k]['body']
|
||||||
|
|
||||||
notifier_actions[k] = helpers.cast_to_int(result.pop(k))
|
notifier_actions[k] = helpers.cast_to_int(result.pop(k))
|
||||||
notifier_text[k] = {'subject': result.pop(k + '_subject'),
|
notifier_text[k] = {'subject': subject,
|
||||||
'body': result.pop(k + '_body')}
|
'body': body}
|
||||||
|
|
||||||
try:
|
try:
|
||||||
result['custom_conditions'] = json.loads(result['custom_conditions'])
|
result['custom_conditions'] = json.loads(result['custom_conditions'])
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue