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:
JonnyWong16 2018-10-05 21:07:08 -07:00 committed by GitHub
commit 6bb6e27378
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
3 changed files with 59 additions and 8 deletions

View file

@ -662,17 +662,17 @@ def dbcheck():
'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, '
'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_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_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_extup_subject TEXT, on_intup_subject TEXT, on_pmsupdate_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_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_extup_body TEXT, on_intup_body TEXT, on_pmsupdate_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'
)
# 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
try:
c_db.execute('SELECT rating_key FROM tvmaze_lookup')

View file

@ -184,6 +184,19 @@ class ActivityHandler(object):
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):
if self.is_valid_session():
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_rating_key = str(self.timeline['ratingKey'])
this_key = self.timeline['key']
this_transcode_key = self.timeline.get('transcodeSession', '')
# Get the live tv session uuid
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_rating_key = str(db_session['rating_key'])
last_live_uuid = db_session['live_uuid']
last_transcode_key = db_session['transcode_key'].split('/')[-1]
# Make sure the same item is being played
if this_rating_key == last_rating_key or this_live_uuid == last_live_uuid:
# Update the session state and viewOffset
if this_state == 'playing':
# 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:
self.update_db_session()
@ -267,6 +282,9 @@ class ActivityHandler(object):
# Update the session last_paused timestamp
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
else:
# Manually stop and start

View file

@ -244,6 +244,14 @@ def available_notification_actions():
'icon': 'fa-play',
'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',
'name': 'on_watched',
'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']))
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())
@ -467,15 +477,23 @@ def get_notifier_config(notifier_id=None):
logger.error(u"Tautulli Notifiers :: Failed to get notifier config options: %s." % e)
return
notify_actions = get_notify_actions()
notify_actions = get_notify_actions(return_dict=True)
notifier_actions = {}
notifier_text = {}
for k in result.keys():
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_text[k] = {'subject': result.pop(k + '_subject'),
'body': result.pop(k + '_body')}
notifier_text[k] = {'subject': subject,
'body': body}
try:
result['custom_conditions'] = json.loads(result['custom_conditions'])