diff --git a/data/interfaces/default/history_table_modal.html b/data/interfaces/default/history_table_modal.html index 152589eb..58345fcf 100644 --- a/data/interfaces/default/history_table_modal.html +++ b/data/interfaces/default/history_table_modal.html @@ -38,6 +38,7 @@ type: "post", data: function ( d ) { return { 'json_data': JSON.stringify( d ), + 'grouping': false, 'start_date': '${data}' }; } diff --git a/data/interfaces/default/settings.html b/data/interfaces/default/settings.html index 000084b0..3adc935e 100644 --- a/data/interfaces/default/settings.html +++ b/data/interfaces/default/settings.html @@ -496,6 +496,12 @@ available_notification_agents = notifiers.available_notification_agents()

Set the progress percentage of when a watched notification should be triggered. Minimum 50, Maximum 95.

+
+ +

Disable to prevent consecutive notifications (i.e. both watched & stopped notifications).

+

Custom Notification Messages

diff --git a/plexpy/activity_handler.py b/plexpy/activity_handler.py index 675eb891..681705b8 100644 --- a/plexpy/activity_handler.py +++ b/plexpy/activity_handler.py @@ -1,4 +1,4 @@ -# This file is part of PlexPy. +# This file is part of PlexPy. # # PlexPy is free software: you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by @@ -16,7 +16,7 @@ import time import plexpy -from plexpy import logger, pmsconnect, activity_processor, threading, notification_handler +from plexpy import logger, pmsconnect, activity_processor, threading, notification_handler, helpers class ActivityHandler(object): @@ -83,8 +83,10 @@ class ActivityHandler(object): db_session = ap.get_session_by_key(session_key=self.get_session_key()) # Fire off notifications - threading.Thread(target=notification_handler.notify, - kwargs=dict(stream_data=db_session, notify_action='stop')).start() + progress_percent = helpers.get_percent(self.timeline['viewOffset'], db_session['duration']) + if plexpy.CONFIG.NOTIFY_CONSECUTIVE or progress_percent < plexpy.CONFIG.NOTIFY_WATCHED_PERCENT: + threading.Thread(target=notification_handler.notify, + kwargs=dict(stream_data=db_session, notify_action='stop')).start() # Write it to the history table monitor_proc = activity_processor.ActivityProcessor() @@ -110,8 +112,10 @@ class ActivityHandler(object): db_session = ap.get_session_by_key(session_key=self.get_session_key()) # Fire off notifications - threading.Thread(target=notification_handler.notify, - kwargs=dict(stream_data=db_session, notify_action='pause')).start() + progress_percent = helpers.get_percent(self.timeline['viewOffset'], db_session['duration']) + if plexpy.CONFIG.NOTIFY_CONSECUTIVE or progress_percent < 99: + threading.Thread(target=notification_handler.notify, + kwargs=dict(stream_data=db_session, notify_action='pause')).start() def on_resume(self): if self.is_valid_session(): @@ -130,8 +134,10 @@ class ActivityHandler(object): db_session = ap.get_session_by_key(session_key=self.get_session_key()) # Fire off notifications - threading.Thread(target=notification_handler.notify, - kwargs=dict(stream_data=db_session, notify_action='resume')).start() + progress_percent = helpers.get_percent(self.timeline['viewOffset'], db_session['duration']) + if plexpy.CONFIG.NOTIFY_CONSECUTIVE or progress_percent < 99: + threading.Thread(target=notification_handler.notify, + kwargs=dict(stream_data=db_session, notify_action='resume')).start() def on_buffer(self): if self.is_valid_session(): @@ -165,8 +171,6 @@ class ActivityHandler(object): # This function receives events from our websocket connection def process(self): if self.is_valid_session(): - from plexpy import helpers - ap = activity_processor.ActivityProcessor() db_session = ap.get_session_by_key(session_key=self.get_session_key()) diff --git a/plexpy/activity_pinger.py b/plexpy/activity_pinger.py index 1b99cf05..5955abe1 100644 --- a/plexpy/activity_pinger.py +++ b/plexpy/activity_pinger.py @@ -1,4 +1,4 @@ -# This file is part of PlexPy. +# This file is part of PlexPy. # # PlexPy is free software: you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by @@ -48,6 +48,12 @@ def check_active_sessions(ws_request=False): for stream in db_streams: if any(d['session_key'] == str(stream['session_key']) and d['rating_key'] == str(stream['rating_key']) for d in media_container): + + if stream['view_offset'] and stream['duration']: + progress_percent = helpers.get_percent(stream['view_offset'], stream['duration']) + else: + progress_percent = None + # The user's session is still active for session in media_container: if session['session_key'] == str(stream['session_key']) and \ @@ -55,13 +61,15 @@ def check_active_sessions(ws_request=False): # The user is still playing the same media item # Here we can check the play states if session['state'] != stream['state']: - if session['state'] == 'paused': + if session['state'] == 'paused' \ + and (plexpy.CONFIG.NOTIFY_CONSECUTIVE or progress_percent < 99): # 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='pause')).start() - if session['state'] == 'playing' and stream['state'] == 'paused': + if session['state'] == 'playing' and stream['state'] == 'paused' \ + and (plexpy.CONFIG.NOTIFY_CONSECUTIVE or progress_percent < 99): # 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, @@ -126,13 +134,11 @@ def check_active_sessions(ws_request=False): # 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. - if session['view_offset'] and session['duration'] and session['state'] != 'buffering': - if helpers.get_percent(session['view_offset'], - session['duration']) > plexpy.CONFIG.NOTIFY_WATCHED_PERCENT: - # 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='watched')).start() + if progress_percent >= plexpy.CONFIG.NOTIFY_WATCHED_PERCENT and session['state'] != 'buffering': + # 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='watched')).start() else: # The user has stopped playing a stream @@ -141,18 +147,21 @@ def check_active_sessions(ws_request=False): monitor_db.action('DELETE FROM sessions WHERE session_key = ? AND rating_key = ?', [stream['session_key'], stream['rating_key']]) - # Check if the user has reached the offset in the media we defined as the "watched" percent if stream['view_offset'] and stream['duration']: - if helpers.get_percent(stream['view_offset'], - stream['duration']) > plexpy.CONFIG.NOTIFY_WATCHED_PERCENT: - # 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='watched')).start() + progress_percent = helpers.get_percent(stream['view_offset'], stream['duration']) + else: + progress_percent = None - # 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='stop')).start() + # Check if the user has reached the offset in the media we defined as the "watched" percent + if plexpy.CONFIG.NOTIFY_CONSECUTIVE or progress_percent >= plexpy.CONFIG.NOTIFY_WATCHED_PERCENT: + # 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='watched')).start() + if plexpy.CONFIG.NOTIFY_CONSECUTIVE or progress_percent < plexpy.CONFIG.NOTIFY_WATCHED_PERCENT: + # 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='stop')).start() # Write the item history on playback stop monitor_process.write_session_history(session=stream) diff --git a/plexpy/config.py b/plexpy/config.py index c5e1c8a2..6810a693 100644 --- a/plexpy/config.py +++ b/plexpy/config.py @@ -122,6 +122,7 @@ _CONFIG_DEFINITIONS = { 'NMA_ON_RESUME': (int, 'NMA', 0), 'NMA_ON_BUFFER': (int, 'NMA', 0), 'NMA_ON_WATCHED': (int, 'NMA', 0), + 'NOTIFY_CONSECUTIVE': (int, 'Monitoring', 1), '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}.'), diff --git a/plexpy/webserve.py b/plexpy/webserve.py index 46bb3dc2..3129e493 100644 --- a/plexpy/webserve.py +++ b/plexpy/webserve.py @@ -439,6 +439,7 @@ class WebInterface(object): "music_logging_enable": checked(plexpy.CONFIG.MUSIC_LOGGING_ENABLE), "logging_ignore_interval": plexpy.CONFIG.LOGGING_IGNORE_INTERVAL, "pms_is_remote": checked(plexpy.CONFIG.PMS_IS_REMOTE), + "notify_consecutive": checked(plexpy.CONFIG.NOTIFY_CONSECUTIVE), "notify_watched_percent": plexpy.CONFIG.NOTIFY_WATCHED_PERCENT, "notify_on_start_subject_text": plexpy.CONFIG.NOTIFY_ON_START_SUBJECT_TEXT, "notify_on_start_body_text": plexpy.CONFIG.NOTIFY_ON_START_BODY_TEXT, @@ -476,7 +477,7 @@ class WebInterface(object): "tv_notify_on_stop", "movie_notify_on_stop", "music_notify_on_stop", "tv_notify_on_pause", "movie_notify_on_pause", "music_notify_on_pause", "refresh_users_on_startup", "ip_logging_enable", "video_logging_enable", "music_logging_enable", "pms_is_remote", "home_stats_type", - "group_history_tables" + "group_history_tables", "notify_consecutive" ] for checked_config in checked_configs: if checked_config not in kwargs: