mirror of
https://github.com/Tautulli/Tautulli.git
synced 2025-07-16 02:02:58 -07:00
Trigger on_watched based on credits markers
This commit is contained in:
parent
b1dd28e39b
commit
b2b12044e3
2 changed files with 101 additions and 31 deletions
|
@ -110,11 +110,13 @@ class ActivityHandler(object):
|
|||
self.set_session_state()
|
||||
self.get_db_session()
|
||||
|
||||
def set_session_state(self):
|
||||
self.ap.set_session_state(session_key=self.session_key,
|
||||
state=self.state,
|
||||
view_offset=self.view_offset,
|
||||
stopped=helpers.timestamp())
|
||||
def set_session_state(self, view_offset=None):
|
||||
self.ap.set_session_state(
|
||||
session_key=self.session_key,
|
||||
state=self.state,
|
||||
view_offset=view_offset or self.view_offset,
|
||||
stopped=helpers.timestamp()
|
||||
)
|
||||
|
||||
def put_notification(self, notify_action, **kwargs):
|
||||
notification = {'stream_data': self.db_session.copy(), 'notify_action': notify_action}
|
||||
|
@ -246,26 +248,34 @@ class ActivityHandler(object):
|
|||
self.put_notification('on_change')
|
||||
|
||||
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):
|
||||
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):
|
||||
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))
|
||||
|
||||
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(
|
||||
session=self.db_session, notify_action='on_watched', notified=False)
|
||||
|
||||
|
@ -368,38 +378,58 @@ class ActivityHandler(object):
|
|||
|
||||
if self.db_session['marker'] != marker_idx:
|
||||
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']:
|
||||
# Schedule a callback for the exact offset of the marker
|
||||
schedule_callback(
|
||||
'session_key-{}-marker-{}'.format(self.session_key, marker_idx),
|
||||
func=callback_func,
|
||||
func=self._marker_callback,
|
||||
args=[marker],
|
||||
milliseconds=marker['start_time_offset'] - self.view_offset
|
||||
)
|
||||
else:
|
||||
callback_func(marker)
|
||||
self._marker_callback(marker)
|
||||
|
||||
break
|
||||
|
||||
if not marker_flag:
|
||||
self.ap.set_marker(session_key=self.session_key, marker_idx=0)
|
||||
|
||||
def check_watched(self):
|
||||
# Monitor if the stream has reached the watch percentage for notifications
|
||||
if not self.db_session['watched'] and self.timeline['state'] != 'buffering':
|
||||
progress_percent = helpers.get_percent(self.timeline['viewOffset'], self.db_session['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
|
||||
}
|
||||
def _marker_callback(self, marker):
|
||||
if self.get_live_session():
|
||||
# Reset ActivityProcessor object for new database thread
|
||||
self.ap = activity_processor.ActivityProcessor()
|
||||
|
||||
if progress_percent >= watched_percent.get(self.db_session['media_type'], 101):
|
||||
self.ap.set_watched(session_key=self.session_key)
|
||||
self.on_watched()
|
||||
if marker['type'] == 'intro':
|
||||
self.on_intro(marker)
|
||||
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):
|
||||
|
|
|
@ -1733,3 +1733,43 @@ def short_season(title):
|
|||
if title.startswith('Season ') and title[7:].isdigit():
|
||||
return 'S%s' % title[7:]
|
||||
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
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue