mirror of
https://github.com/Tautulli/Tautulli.git
synced 2025-07-08 06:00:51 -07:00
Reimplement recently added delay to group items
This commit is contained in:
parent
7e7609743a
commit
f42f1182f2
4 changed files with 101 additions and 87 deletions
|
@ -836,7 +836,17 @@
|
||||||
Note: A season range can be shown (e.g. 1-3), but all other season/episode/album/track metadata will be unavailable.
|
Note: A season range can be shown (e.g. 1-3), but all other season/episode/album/track metadata will be unavailable.
|
||||||
</p>
|
</p>
|
||||||
</div>
|
</div>
|
||||||
<div class="checkbox">
|
<div class="form-group">
|
||||||
|
<label for="notify_recently_added_delay">Notification Delay</label>
|
||||||
|
<div class="row">
|
||||||
|
<div class="col-md-2">
|
||||||
|
<input type="text" class="form-control" data-parsley-type="integer" id="notify_recently_added_delay" name="notify_recently_added_delay" value="${config['notify_recently_added_delay']}" size="5" data-parsley-min="60" data-parsley-trigger="change" data-parsley-errors-container="#notify_recently_added_delay_error" required>
|
||||||
|
</div>
|
||||||
|
<div id="notify_recently_added_delay_error" class="alert alert-danger settings-alert" role="alert"></div>
|
||||||
|
</div>
|
||||||
|
<p class="help-block">Set the delay (in seconds) to wait for consecutive recently added items to group together and to allow metadata to be processed before sending the notification. Minimum 60 seconds.</p>
|
||||||
|
</div>
|
||||||
|
<!--<div class="checkbox">
|
||||||
<label>
|
<label>
|
||||||
<input type="checkbox" name="notify_recently_added_upgrade" id="notify_recently_added_upgrade" value="1" ${config['notify_recently_added_upgrade']}> Send a Notification for New Versions <span style="color: #eb8600; padding-left: 10px;">[Not working]</span>
|
<input type="checkbox" name="notify_recently_added_upgrade" id="notify_recently_added_upgrade" value="1" ${config['notify_recently_added_upgrade']}> Send a Notification for New Versions <span style="color: #eb8600; padding-left: 10px;">[Not working]</span>
|
||||||
</label>
|
</label>
|
||||||
|
@ -844,7 +854,7 @@
|
||||||
Enable to send another recently added notification when adding a new version of existing media.<br />
|
Enable to send another recently added notification when adding a new version of existing media.<br />
|
||||||
Note: If multiple versions are available, PlexPy will assume the higher quality one is newer.
|
Note: If multiple versions are available, PlexPy will assume the higher quality one is newer.
|
||||||
</p>
|
</p>
|
||||||
</div>
|
</div>-->
|
||||||
|
|
||||||
<p><input type="button" class="btn btn-bright save-button" value="Save" data-success="Changes saved successfully"></p>
|
<p><input type="button" class="btn btn-bright save-button" value="Save" data-success="Changes saved successfully"></p>
|
||||||
|
|
||||||
|
|
|
@ -213,7 +213,8 @@ class ActivityHandler(object):
|
||||||
# If we already have this session in the temp table, check for state changes
|
# If we already have this session in the temp table, check for state changes
|
||||||
if db_session:
|
if db_session:
|
||||||
# Re-schedule the callback to reset the 5 minutes timer
|
# Re-schedule the callback to reset the 5 minutes timer
|
||||||
schedule_callback(self.get_session_key(), args=[self.get_session_key()], minutes=5)
|
schedule_callback('session_key-{}'.format(self.get_session_key()),
|
||||||
|
function=force_stop_stream, args=[self.get_session_key()], minutes=5)
|
||||||
|
|
||||||
last_state = db_session['state']
|
last_state = db_session['state']
|
||||||
last_key = str(db_session['rating_key'])
|
last_key = str(db_session['rating_key'])
|
||||||
|
@ -236,7 +237,7 @@ class ActivityHandler(object):
|
||||||
self.on_stop()
|
self.on_stop()
|
||||||
|
|
||||||
# Remove the callback if the stream is stopped
|
# Remove the callback if the stream is stopped
|
||||||
schedule_callback(self.get_session_key(), remove_job=True)
|
schedule_callback('session_key-{}'.format(self.get_session_key()), remove_job=True)
|
||||||
|
|
||||||
elif this_state == 'buffering':
|
elif this_state == 'buffering':
|
||||||
self.on_buffer()
|
self.on_buffer()
|
||||||
|
@ -264,7 +265,8 @@ class ActivityHandler(object):
|
||||||
self.on_start()
|
self.on_start()
|
||||||
|
|
||||||
# Schedule a callback to force stop a stale stream 5 minutes later
|
# Schedule a callback to force stop a stale stream 5 minutes later
|
||||||
schedule_callback(self.get_session_key(), args=[self.get_session_key()], minutes=5)
|
schedule_callback('session_key-{}'.format(self.get_session_key()),
|
||||||
|
function=force_stop_stream, args=[self.get_session_key()], minutes=5)
|
||||||
|
|
||||||
|
|
||||||
class TimelineHandler(object):
|
class TimelineHandler(object):
|
||||||
|
@ -293,39 +295,6 @@ class TimelineHandler(object):
|
||||||
|
|
||||||
return None
|
return None
|
||||||
|
|
||||||
def on_created(self, rating_key, **kwargs):
|
|
||||||
if self.is_item():
|
|
||||||
logger.debug(u"PlexPy TimelineHandler :: Library item %s added to Plex." % str(rating_key))
|
|
||||||
pms_connect = pmsconnect.PmsConnect()
|
|
||||||
metadata = pms_connect.get_metadata_details(rating_key)
|
|
||||||
|
|
||||||
if metadata:
|
|
||||||
notify = True
|
|
||||||
|
|
||||||
data_factory = datafactory.DataFactory()
|
|
||||||
if 'child_keys' not in kwargs:
|
|
||||||
if data_factory.get_recently_added_item(rating_key):
|
|
||||||
logger.debug(u"PlexPy TimelineHandler :: Library item %s added already. Not notifying again." % str(rating_key))
|
|
||||||
notify = False
|
|
||||||
|
|
||||||
if notify:
|
|
||||||
data = {'timeline_data': metadata, 'notify_action': 'on_created'}
|
|
||||||
data.update(kwargs)
|
|
||||||
plexpy.NOTIFY_QUEUE.put(data)
|
|
||||||
|
|
||||||
all_keys = [rating_key]
|
|
||||||
if 'child_keys' in kwargs:
|
|
||||||
all_keys.extend(kwargs['child_keys'])
|
|
||||||
|
|
||||||
for key in all_keys:
|
|
||||||
data_factory.set_recently_added_item(key)
|
|
||||||
|
|
||||||
logger.debug(u"Added %s items to the recently_added database table." % str(len(all_keys)))
|
|
||||||
|
|
||||||
else:
|
|
||||||
logger.error(u"PlexPy TimelineHandler :: Unable to retrieve metadata for rating_key %s" \
|
|
||||||
% str(rating_key))
|
|
||||||
|
|
||||||
# This function receives events from our websocket connection
|
# This function receives events from our websocket connection
|
||||||
def process(self):
|
def process(self):
|
||||||
if self.is_item():
|
if self.is_item():
|
||||||
|
@ -374,6 +343,10 @@ class TimelineHandler(object):
|
||||||
logger.debug(u"PlexPy TimelineHandler :: Library item '%s' (%s, grandparent %s) added to recently added queue."
|
logger.debug(u"PlexPy TimelineHandler :: Library item '%s' (%s, grandparent %s) added to recently added queue."
|
||||||
% (title, str(rating_key), str(grandparent_rating_key)))
|
% (title, str(rating_key), str(grandparent_rating_key)))
|
||||||
|
|
||||||
|
# Schedule a callback to clear the recently added queue
|
||||||
|
schedule_callback('rating_key-{}'.format(grandparent_rating_key), function=clear_recently_added_queue,
|
||||||
|
args=[grandparent_rating_key], seconds=plexpy.CONFIG.NOTIFY_RECENTLY_ADDED_DELAY)
|
||||||
|
|
||||||
elif media_type in ('season', 'album'):
|
elif media_type in ('season', 'album'):
|
||||||
metadata = self.get_metadata()
|
metadata = self.get_metadata()
|
||||||
if metadata:
|
if metadata:
|
||||||
|
@ -386,6 +359,10 @@ class TimelineHandler(object):
|
||||||
logger.debug(u"PlexPy TimelineHandler :: Library item '%s' (%s , parent %s) added to recently added queue."
|
logger.debug(u"PlexPy TimelineHandler :: Library item '%s' (%s , parent %s) added to recently added queue."
|
||||||
% (title, str(rating_key), str(parent_rating_key)))
|
% (title, str(rating_key), str(parent_rating_key)))
|
||||||
|
|
||||||
|
# Schedule a callback to clear the recently added queue
|
||||||
|
schedule_callback('rating_key-{}'.format(parent_rating_key), function=clear_recently_added_queue,
|
||||||
|
args=[parent_rating_key], seconds=plexpy.CONFIG.NOTIFY_RECENTLY_ADDED_DELAY)
|
||||||
|
|
||||||
else:
|
else:
|
||||||
queue_set = RECENTLY_ADDED_QUEUE.get(rating_key, set())
|
queue_set = RECENTLY_ADDED_QUEUE.get(rating_key, set())
|
||||||
RECENTLY_ADDED_QUEUE[rating_key] = queue_set
|
RECENTLY_ADDED_QUEUE[rating_key] = queue_set
|
||||||
|
@ -393,6 +370,10 @@ class TimelineHandler(object):
|
||||||
logger.debug(u"PlexPy TimelineHandler :: Library item '%s' (%s) added to recently added queue."
|
logger.debug(u"PlexPy TimelineHandler :: Library item '%s' (%s) added to recently added queue."
|
||||||
% (title, str(rating_key)))
|
% (title, str(rating_key)))
|
||||||
|
|
||||||
|
# Schedule a callback to clear the recently added queue
|
||||||
|
schedule_callback('rating_key-{}'.format(rating_key), function=clear_recently_added_queue,
|
||||||
|
args=[rating_key], seconds=plexpy.CONFIG.NOTIFY_RECENTLY_ADDED_DELAY)
|
||||||
|
|
||||||
# A movie, show, or artist is done processing
|
# A movie, show, or artist is done processing
|
||||||
elif media_type in ('movie', 'show', 'artist') and section_id > 0 and \
|
elif media_type in ('movie', 'show', 'artist') and section_id > 0 and \
|
||||||
state_type == 5 and metadata_state is None and queue_size is None and \
|
state_type == 5 and metadata_state is None and queue_size is None and \
|
||||||
|
@ -401,47 +382,6 @@ class TimelineHandler(object):
|
||||||
logger.debug(u"PlexPy TimelineHandler :: Library item '%s' (%s) done processing metadata."
|
logger.debug(u"PlexPy TimelineHandler :: Library item '%s' (%s) done processing metadata."
|
||||||
% (title, str(rating_key)))
|
% (title, str(rating_key)))
|
||||||
|
|
||||||
child_keys = RECENTLY_ADDED_QUEUE[rating_key]
|
|
||||||
|
|
||||||
if plexpy.CONFIG.NOTIFY_GROUP_RECENTLY_ADDED_GRANDPARENT and len(child_keys) > 1:
|
|
||||||
self.on_created(rating_key, child_keys=child_keys)
|
|
||||||
|
|
||||||
elif child_keys:
|
|
||||||
for child_key in child_keys:
|
|
||||||
grandchild_keys = RECENTLY_ADDED_QUEUE.get(child_key, [])
|
|
||||||
|
|
||||||
if plexpy.CONFIG.NOTIFY_GROUP_RECENTLY_ADDED_PARENT and len(grandchild_keys) > 1:
|
|
||||||
self.on_created(child_key, child_keys=grandchild_keys)
|
|
||||||
|
|
||||||
elif grandchild_keys:
|
|
||||||
for grandchild_key in grandchild_keys:
|
|
||||||
self.on_created(grandchild_key)
|
|
||||||
|
|
||||||
else:
|
|
||||||
self.on_created(child_key)
|
|
||||||
|
|
||||||
else:
|
|
||||||
self.on_created(rating_key)
|
|
||||||
|
|
||||||
# Remove all keys
|
|
||||||
del_keys(rating_key)
|
|
||||||
|
|
||||||
|
|
||||||
# An episode or track is done processing (upgrade only)
|
|
||||||
#elif plexpy.CONFIG.NOTIFY_RECENTLY_ADDED_UPGRADE and \
|
|
||||||
# media_type in ('episode', 'track') and section_id > 0 and \
|
|
||||||
# state_type == 5 and metadata_state is None and queue_size is None and \
|
|
||||||
# rating_key in RECENTLY_ADDED_QUEUE:
|
|
||||||
|
|
||||||
# logger.debug(u"PlexPy TimelineHandler :: Library item '%s' (%s) done processing metadata (upgrade)."
|
|
||||||
# % (title, str(rating_key)))
|
|
||||||
|
|
||||||
# grandparent_rating_key = RECENTLY_ADDED_QUEUE[rating_key]
|
|
||||||
# self.on_created(rating_key)
|
|
||||||
|
|
||||||
# # Remove all keys
|
|
||||||
# del_keys(grandparent_rating_key)
|
|
||||||
|
|
||||||
# An item was deleted, make sure it is removed from the queue
|
# An item was deleted, make sure it is removed from the queue
|
||||||
elif state_type == 9 and metadata_state == 'deleted':
|
elif state_type == 9 and metadata_state == 'deleted':
|
||||||
if rating_key in RECENTLY_ADDED_QUEUE and not RECENTLY_ADDED_QUEUE[rating_key]:
|
if rating_key in RECENTLY_ADDED_QUEUE and not RECENTLY_ADDED_QUEUE[rating_key]:
|
||||||
|
@ -449,6 +389,9 @@ class TimelineHandler(object):
|
||||||
% str(rating_key))
|
% str(rating_key))
|
||||||
del_keys(rating_key)
|
del_keys(rating_key)
|
||||||
|
|
||||||
|
# Remove the callback if the item is removed
|
||||||
|
schedule_callback('rating_key-{}'.format(rating_key), remove_job=True)
|
||||||
|
|
||||||
|
|
||||||
def del_keys(key):
|
def del_keys(key):
|
||||||
if isinstance(key, set):
|
if isinstance(key, set):
|
||||||
|
@ -458,17 +401,17 @@ def del_keys(key):
|
||||||
del_keys(RECENTLY_ADDED_QUEUE.pop(key))
|
del_keys(RECENTLY_ADDED_QUEUE.pop(key))
|
||||||
|
|
||||||
|
|
||||||
def schedule_callback(id, remove_job=False, args=None, **kwargs):
|
def schedule_callback(id, function=None, remove_job=False, args=None, **kwargs):
|
||||||
if ACTIVITY_SCHED.get_job(str(id)):
|
if ACTIVITY_SCHED.get_job(id):
|
||||||
if remove_job:
|
if remove_job:
|
||||||
ACTIVITY_SCHED.remove_job(str(id))
|
ACTIVITY_SCHED.remove_job(id)
|
||||||
else:
|
else:
|
||||||
ACTIVITY_SCHED.reschedule_job(
|
ACTIVITY_SCHED.reschedule_job(
|
||||||
str(id), args=args, trigger=DateTrigger(
|
id, args=args, trigger=DateTrigger(
|
||||||
run_date=datetime.datetime.now() + datetime.timedelta(**kwargs)))
|
run_date=datetime.datetime.now() + datetime.timedelta(**kwargs)))
|
||||||
elif not remove_job:
|
elif not remove_job:
|
||||||
ACTIVITY_SCHED.add_job(
|
ACTIVITY_SCHED.add_job(
|
||||||
force_stop_stream, args=args, id=str(id), trigger=DateTrigger(
|
function, args=args, id=id, trigger=DateTrigger(
|
||||||
run_date=datetime.datetime.now() + datetime.timedelta(**kwargs)))
|
run_date=datetime.datetime.now() + datetime.timedelta(**kwargs)))
|
||||||
|
|
||||||
|
|
||||||
|
@ -494,7 +437,8 @@ def force_stop_stream(session_key):
|
||||||
ap.increment_write_attempts(session_key=session_key)
|
ap.increment_write_attempts(session_key=session_key)
|
||||||
|
|
||||||
# Reschedule for 30 seconds later
|
# Reschedule for 30 seconds later
|
||||||
schedule_callback(session_key, args=[session_key], seconds=30)
|
schedule_callback('session_key={}'.format(session_key), function=force_stop_stream,
|
||||||
|
args=[session_key], seconds=30)
|
||||||
|
|
||||||
else:
|
else:
|
||||||
logger.warn(u"PlexPy Monitor :: Failed to write stream with sessionKey %s ratingKey %s to the database. " \
|
logger.warn(u"PlexPy Monitor :: Failed to write stream with sessionKey %s ratingKey %s to the database. " \
|
||||||
|
@ -502,4 +446,63 @@ def force_stop_stream(session_key):
|
||||||
% (sessions['session_key'], sessions['rating_key'], str(sessions['write_attempts'])))
|
% (sessions['session_key'], sessions['rating_key'], str(sessions['write_attempts'])))
|
||||||
logger.info(u"PlexPy Monitor :: Removing stale stream with sessionKey %s ratingKey %s from session queue"
|
logger.info(u"PlexPy Monitor :: Removing stale stream with sessionKey %s ratingKey %s from session queue"
|
||||||
% (sessions['session_key'], sessions['rating_key']))
|
% (sessions['session_key'], sessions['rating_key']))
|
||||||
ap.delete_session(session_key=session_key)
|
ap.delete_session(session_key=session_key)
|
||||||
|
|
||||||
|
|
||||||
|
def clear_recently_added_queue(rating_key):
|
||||||
|
child_keys = RECENTLY_ADDED_QUEUE[rating_key]
|
||||||
|
|
||||||
|
if plexpy.CONFIG.NOTIFY_GROUP_RECENTLY_ADDED_GRANDPARENT and len(child_keys) > 1:
|
||||||
|
on_created(rating_key, child_keys=child_keys)
|
||||||
|
|
||||||
|
elif child_keys:
|
||||||
|
for child_key in child_keys:
|
||||||
|
grandchild_keys = RECENTLY_ADDED_QUEUE.get(child_key, [])
|
||||||
|
|
||||||
|
if plexpy.CONFIG.NOTIFY_GROUP_RECENTLY_ADDED_PARENT and len(grandchild_keys) > 1:
|
||||||
|
on_created(child_key, child_keys=grandchild_keys)
|
||||||
|
|
||||||
|
elif grandchild_keys:
|
||||||
|
for grandchild_key in grandchild_keys:
|
||||||
|
on_created(grandchild_key)
|
||||||
|
|
||||||
|
else:
|
||||||
|
on_created(child_key)
|
||||||
|
|
||||||
|
else:
|
||||||
|
on_created(rating_key)
|
||||||
|
|
||||||
|
# Remove all keys
|
||||||
|
del_keys(rating_key)
|
||||||
|
|
||||||
|
|
||||||
|
def on_created(rating_key, **kwargs):
|
||||||
|
logger.debug(u"PlexPy TimelineHandler :: Library item %s added to Plex." % str(rating_key))
|
||||||
|
pms_connect = pmsconnect.PmsConnect()
|
||||||
|
metadata = pms_connect.get_metadata_details(rating_key)
|
||||||
|
|
||||||
|
if metadata:
|
||||||
|
notify = True
|
||||||
|
|
||||||
|
data_factory = datafactory.DataFactory()
|
||||||
|
if 'child_keys' not in kwargs:
|
||||||
|
if data_factory.get_recently_added_item(rating_key):
|
||||||
|
logger.debug(u"PlexPy TimelineHandler :: Library item %s added already. Not notifying again." % str(rating_key))
|
||||||
|
notify = False
|
||||||
|
|
||||||
|
if notify:
|
||||||
|
data = {'timeline_data': metadata, 'notify_action': 'on_created'}
|
||||||
|
data.update(kwargs)
|
||||||
|
plexpy.NOTIFY_QUEUE.put(data)
|
||||||
|
|
||||||
|
all_keys = [rating_key]
|
||||||
|
if 'child_keys' in kwargs:
|
||||||
|
all_keys.extend(kwargs['child_keys'])
|
||||||
|
|
||||||
|
for key in all_keys:
|
||||||
|
data_factory.set_recently_added_item(key)
|
||||||
|
|
||||||
|
logger.debug(u"Added %s items to the recently_added database table." % str(len(all_keys)))
|
||||||
|
|
||||||
|
else:
|
||||||
|
logger.error(u"PlexPy TimelineHandler :: Unable to retrieve metadata for rating_key %s" % str(rating_key))
|
||||||
|
|
|
@ -1145,7 +1145,7 @@ def lookup_themoviedb_by_id(rating_key=None, thetvdb_id=None, imdb_id=None):
|
||||||
|
|
||||||
|
|
||||||
def get_themoviedb_info(rating_key=None, media_type=None, themoviedb_id=None):
|
def get_themoviedb_info(rating_key=None, media_type=None, themoviedb_id=None):
|
||||||
if media_type == 'show':
|
if media_type in ('show', 'season', 'episode'):
|
||||||
media_type = 'tv'
|
media_type = 'tv'
|
||||||
|
|
||||||
db = database.MonitorDatabase()
|
db = database.MonitorDatabase()
|
||||||
|
|
|
@ -2644,6 +2644,7 @@ class WebInterface(object):
|
||||||
"notify_recently_added_upgrade": checked(plexpy.CONFIG.NOTIFY_RECENTLY_ADDED_UPGRADE),
|
"notify_recently_added_upgrade": checked(plexpy.CONFIG.NOTIFY_RECENTLY_ADDED_UPGRADE),
|
||||||
"notify_group_recently_added_grandparent": checked(plexpy.CONFIG.NOTIFY_GROUP_RECENTLY_ADDED_GRANDPARENT),
|
"notify_group_recently_added_grandparent": checked(plexpy.CONFIG.NOTIFY_GROUP_RECENTLY_ADDED_GRANDPARENT),
|
||||||
"notify_group_recently_added_parent": checked(plexpy.CONFIG.NOTIFY_GROUP_RECENTLY_ADDED_PARENT),
|
"notify_group_recently_added_parent": checked(plexpy.CONFIG.NOTIFY_GROUP_RECENTLY_ADDED_PARENT),
|
||||||
|
"notify_recently_added_delay": plexpy.CONFIG.NOTIFY_RECENTLY_ADDED_DELAY,
|
||||||
"notify_concurrent_by_ip": checked(plexpy.CONFIG.NOTIFY_CONCURRENT_BY_IP),
|
"notify_concurrent_by_ip": checked(plexpy.CONFIG.NOTIFY_CONCURRENT_BY_IP),
|
||||||
"notify_concurrent_threshold": plexpy.CONFIG.NOTIFY_CONCURRENT_THRESHOLD,
|
"notify_concurrent_threshold": plexpy.CONFIG.NOTIFY_CONCURRENT_THRESHOLD,
|
||||||
"home_sections": json.dumps(plexpy.CONFIG.HOME_SECTIONS),
|
"home_sections": json.dumps(plexpy.CONFIG.HOME_SECTIONS),
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue