Trigger on_watched based on credits markers

This commit is contained in:
JonnyWong16 2023-02-20 17:14:35 -08:00
parent b1dd28e39b
commit b2b12044e3
No known key found for this signature in database
GPG key ID: B1F1F9807184697A
2 changed files with 101 additions and 31 deletions

View file

@ -110,11 +110,13 @@ class ActivityHandler(object):
self.set_session_state() self.set_session_state()
self.get_db_session() self.get_db_session()
def set_session_state(self): def set_session_state(self, view_offset=None):
self.ap.set_session_state(session_key=self.session_key, self.ap.set_session_state(
state=self.state, session_key=self.session_key,
view_offset=self.view_offset, state=self.state,
stopped=helpers.timestamp()) view_offset=view_offset or self.view_offset,
stopped=helpers.timestamp()
)
def put_notification(self, notify_action, **kwargs): def put_notification(self, notify_action, **kwargs):
notification = {'stream_data': self.db_session.copy(), 'notify_action': notify_action} notification = {'stream_data': self.db_session.copy(), 'notify_action': notify_action}
@ -246,26 +248,34 @@ class ActivityHandler(object):
self.put_notification('on_change') self.put_notification('on_change')
def on_intro(self, marker): def on_intro(self, marker):
if self.get_live_session(): logger.debug("Tautulli ActivityHandler :: Session %s reached intro marker." % str(self.session_key))
logger.debug("Tautulli ActivityHandler :: Session %s reached intro marker." % str(self.session_key))
self.put_notification('on_intro', marker=marker) self.set_session_state(view_offset=marker['start_time_offset'])
self.put_notification('on_intro', marker=marker)
def on_commercial(self, marker): def on_commercial(self, marker):
if self.get_live_session(): logger.debug("Tautulli ActivityHandler :: Session %s reached commercial marker." % str(self.session_key))
logger.debug("Tautulli ActivityHandler :: Session %s reached commercial marker." % str(self.session_key))
self.put_notification('on_commercial', marker=marker) self.set_session_state(view_offset=marker['start_time_offset'])
self.put_notification('on_commercial', marker=marker)
def on_credits(self, marker): def on_credits(self, marker):
if self.get_live_session(): logger.debug("Tautulli ActivityHandler :: Session %s reached credits marker." % str(self.session_key))
logger.debug("Tautulli ActivityHandler :: Session %s reached credits marker." % str(self.session_key))
self.put_notification('on_credits', marker=marker) self.set_session_state(view_offset=marker['start_time_offset'])
def on_watched(self): self.put_notification('on_credits', marker=marker)
def on_watched(self, marker=None):
logger.debug("Tautulli ActivityHandler :: Session %s watched." % str(self.session_key)) logger.debug("Tautulli ActivityHandler :: Session %s watched." % str(self.session_key))
if marker:
self.set_session_state(view_offset=marker['start_time_offset'])
else:
self.update_db_session()
watched_notifiers = notification_handler.get_notify_state_enabled( watched_notifiers = notification_handler.get_notify_state_enabled(
session=self.db_session, notify_action='on_watched', notified=False) session=self.db_session, notify_action='on_watched', notified=False)
@ -368,38 +378,58 @@ class ActivityHandler(object):
if self.db_session['marker'] != marker_idx: if self.db_session['marker'] != marker_idx:
self.ap.set_marker(session_key=self.session_key, marker_idx=marker_idx, marker_type=marker['type']) self.ap.set_marker(session_key=self.session_key, marker_idx=marker_idx, marker_type=marker['type'])
callback_func = getattr(self, 'on_{}'.format(marker['type']))
if self.view_offset < marker['start_time_offset']: if self.view_offset < marker['start_time_offset']:
# Schedule a callback for the exact offset of the marker # Schedule a callback for the exact offset of the marker
schedule_callback( schedule_callback(
'session_key-{}-marker-{}'.format(self.session_key, marker_idx), 'session_key-{}-marker-{}'.format(self.session_key, marker_idx),
func=callback_func, func=self._marker_callback,
args=[marker], args=[marker],
milliseconds=marker['start_time_offset'] - self.view_offset milliseconds=marker['start_time_offset'] - self.view_offset
) )
else: else:
callback_func(marker) self._marker_callback(marker)
break break
if not marker_flag: if not marker_flag:
self.ap.set_marker(session_key=self.session_key, marker_idx=0) self.ap.set_marker(session_key=self.session_key, marker_idx=0)
def check_watched(self): def _marker_callback(self, marker):
# Monitor if the stream has reached the watch percentage for notifications if self.get_live_session():
if not self.db_session['watched'] and self.timeline['state'] != 'buffering': # Reset ActivityProcessor object for new database thread
progress_percent = helpers.get_percent(self.timeline['viewOffset'], self.db_session['duration']) self.ap = activity_processor.ActivityProcessor()
watched_percent = {
'movie': plexpy.CONFIG.MOVIE_WATCHED_PERCENT,
'episode': plexpy.CONFIG.TV_WATCHED_PERCENT,
'track': plexpy.CONFIG.MUSIC_WATCHED_PERCENT,
'clip': plexpy.CONFIG.TV_WATCHED_PERCENT
}
if progress_percent >= watched_percent.get(self.db_session['media_type'], 101): if marker['type'] == 'intro':
self.ap.set_watched(session_key=self.session_key) self.on_intro(marker)
self.on_watched() elif marker['type'] == 'commercial':
self.on_commercial(marker)
elif marker['type'] == 'credits':
self.on_credits(marker)
if not self.db_session['watched']:
if marker['final'] and plexpy.CONFIG.WATCHED_MARKER == 1:
self._marker_watched(marker)
elif marker['first'] and (plexpy.CONFIG.WATCHED_MARKER in (2, 3)):
self._marker_watched(marker)
def _marker_watched(self, marker):
if not self.db_session['watched']:
self._watched_callback(marker)
def check_watched(self):
if plexpy.CONFIG.WATCHED_MARKER == 1 or plexpy.CONFIG.WATCHED_MARKER == 2:
return
# Monitor if the stream has reached the watch percentage for notifications
if not self.db_session['watched'] and self.state != 'buffering' and helpers.check_watched(
self.db_session['media_type'], self.view_offset, self.db_session['duration']
):
self._watched_callback()
def _watched_callback(self, marker=None):
self.ap.set_watched(session_key=self.session_key)
self.on_watched(marker)
class TimelineHandler(object): class TimelineHandler(object):

View file

@ -1733,3 +1733,43 @@ def short_season(title):
if title.startswith('Season ') and title[7:].isdigit(): if title.startswith('Season ') and title[7:].isdigit():
return 'S%s' % title[7:] return 'S%s' % title[7:]
return title return title
def get_first_final_marker(markers):
first = None
final = None
for marker in markers:
if marker['first']:
first = marker
if marker['final']:
final = marker
return first, final
def check_watched(media_type, view_offset, duration, marker_credits_first=None, marker_credits_final=None):
if isinstance(marker_credits_first, dict):
marker_credits_first = marker_credits_first['start_time_offset']
if isinstance(marker_credits_final, dict):
marker_credits_final = marker_credits_final['start_time_offset']
view_offset = cast_to_int(view_offset)
duration = cast_to_int(duration)
watched_percent = {
'movie': plexpy.CONFIG.MOVIE_WATCHED_PERCENT,
'episode': plexpy.CONFIG.TV_WATCHED_PERCENT,
'track': plexpy.CONFIG.MUSIC_WATCHED_PERCENT,
'clip': plexpy.CONFIG.TV_WATCHED_PERCENT
}
threshold = watched_percent.get(media_type, 0) / 100 * duration
if not threshold:
return False
if plexpy.CONFIG.WATCHED_MARKER == 1 and marker_credits_final:
return view_offset >= marker_credits_final
elif plexpy.CONFIG.WATCHED_MARKER == 2 and marker_credits_first:
return view_offset >= marker_credits_first
elif plexpy.CONFIG.WATCHED_MARKER == 3 and marker_credits_first:
return view_offset >= min(threshold, marker_credits_first)
else:
return view_offset >= threshold