From b9f47df930e7c3b6384da70605ed7c82c64ecf8d Mon Sep 17 00:00:00 2001 From: Jonathan Wong Date: Sun, 25 Oct 2015 17:21:49 -0700 Subject: [PATCH] Update activity_pinger for recently added --- data/interfaces/default/recently_added.html | 12 ++--- plexpy/__init__.py | 2 + plexpy/activity_handler.py | 4 +- plexpy/activity_pinger.py | 46 +++++++++++++++++- plexpy/notification_handler.py | 17 ++----- plexpy/plexwatch_import.py | 4 +- plexpy/pmsconnect.py | 52 ++++++++++++++++++++- 7 files changed, 111 insertions(+), 26 deletions(-) diff --git a/data/interfaces/default/recently_added.html b/data/interfaces/default/recently_added.html index 4f11db4b..f961801a 100644 --- a/data/interfaces/default/recently_added.html +++ b/data/interfaces/default/recently_added.html @@ -11,13 +11,13 @@ data[array_index] :: Usable parameters == Global keys == rating_key Returns the unique identifier for the media item. -type Returns the type of media. Either 'movie' or 'season'. +media_type Returns the media type of media. Either 'movie' or 'season' or 'album'. thumb Returns the location of the item's thumbnail. Use with pms_image_proxy. added_at Returns the time when the media was added to the library. title Returns the name of the movie or season. parent_title Returns the name of the TV Show a season belongs too. -== Only if 'type' is 'movie' == +== Only if 'media_type' is 'movie' == year Returns the movie release year. DOCUMENTATION :: END @@ -29,7 +29,7 @@ DOCUMENTATION :: END % for item in data:
  • - % if item['type'] == 'season' or item['type'] == 'movie': + % if item['media_type'] == 'season' or item['media_type'] == 'movie':
    @@ -43,16 +43,16 @@ DOCUMENTATION :: END
    - % if item['type'] == 'season': + % if item['media_type'] == 'season':

    ${item['parent_title']}

    ${item['title']}

    - % elif item['type'] == 'movie': + % elif item['media_type'] == 'movie':

    ${item['title']}

    ${item['year']}

    % endif
    - % elif item['type'] == 'album': + % elif item['media_type'] == 'album':
    diff --git a/plexpy/__init__.py b/plexpy/__init__.py index 5d2216c4..0c277473 100644 --- a/plexpy/__init__.py +++ b/plexpy/__init__.py @@ -286,6 +286,8 @@ def initialize_scheduler(): if not CONFIG.MONITORING_USE_WEBSOCKET or POLLING_FAILOVER: schedule_job(activity_pinger.check_active_sessions, 'Check for active sessions', hours=0, minutes=0, seconds=seconds) + schedule_job(activity_pinger.check_recently_added, 'Check for recently added items', + hours=0, minutes=0, seconds=seconds) # Refresh the users list if CONFIG.REFRESH_USERS_INTERVAL: diff --git a/plexpy/activity_handler.py b/plexpy/activity_handler.py index a6dc8d17..e9536451 100644 --- a/plexpy/activity_handler.py +++ b/plexpy/activity_handler.py @@ -256,11 +256,9 @@ class TimelineHandler(object): this_state = self.timeline['state'] this_type = self.timeline['type'] this_metadataState = self.timeline.get('metadataState', None) - this_section_id = self.timeline['sectionID'] - this_rating_key = self.timeline['itemID'] # state: 5: done processing metadata # type: 1: movie, 2: tv show, 4: episode, 8: artist, 10: track types = [1, 2, 4, 8, 10] if this_state == 5 and this_type in types and not this_metadataState: - self.on_created() + self.on_created() \ No newline at end of file diff --git a/plexpy/activity_pinger.py b/plexpy/activity_pinger.py index 1b99cf05..686b80d6 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 @@ -162,3 +162,47 @@ def check_active_sessions(ws_request=False): monitor_process.write_session(session) else: logger.debug(u"PlexPy Monitor :: Unable to read session list.") + + +def check_recently_added(): + + with monitor_lock: + current_time = int(time.time()) + + pms_connect = pmsconnect.PmsConnect() + recently_added_list = pms_connect.get_recently_added_details(count='10') + + if recently_added_list: + recently_added = recently_added_list['recently_added'] + + for item in recently_added: + if int(item['added_at']) >= current_time - plexpy.CONFIG.MONITORING_INTERVAL: + if item['media_type'] == 'movie': + metadata_list = pms_connect.get_metadata_details(item['rating_key']) + if metadata_list: + metadata = [metadata_list['metadata']] + else: + logger.error(u"PlexPy Monitor :: Unable to retrieve metadata for rating_key %s" % str(item['rating_key'])) + + elif plexpy.CONFIG.NOTIFY_RECENTLY_ADDED_GRANDPARENT: + metadata_list = pms_connect.get_metadata_details(item['parent_rating_key']) + if metadata_list: + metadata = [metadata_list['metadata']] + else: + logger.error(u"PlexPy Monitor :: Unable to retrieve metadata for parent_rating_key %s" % str(item['parent_rating_key'])) + + else: + metadata_list = pms_connect.get_metadata_children_details(item['rating_key']) + if metadata_list: + metadata = metadata_list['metadata'] + else: + logger.error(u"PlexPy Monitor :: Unable to retrieve children metadata for rating_key" % str(item['rating_key'])) + + for item in metadata: + if (plexpy.CONFIG.NOTIFY_RECENTLY_ADDED_GRANDPARENT and int(item['updated_at']) >= current_time - plexpy.CONFIG.MONITORING_INTERVAL) \ + or (not plexpy.CONFIG.NOTIFY_RECENTLY_ADDED_GRANDPARENT and int(item['added_at']) >= current_time - plexpy.CONFIG.MONITORING_INTERVAL): + logger.debug(u"PlexPy Monitor :: Library item %s has been added to Plex." % str(item['rating_key'])) + + # Fire off notifications + threading.Thread(target=notification_handler.notify_timeline, + kwargs=dict(timeline_data=item, notify_action='created')).start() diff --git a/plexpy/notification_handler.py b/plexpy/notification_handler.py index ce8692c0..e114bc62 100644 --- a/plexpy/notification_handler.py +++ b/plexpy/notification_handler.py @@ -172,19 +172,10 @@ def notify_timeline(timeline_data=None, notify_action=None): if timeline_data and notify_action: for agent in notifiers.available_notification_agents(): if agent['on_created'] and notify_action == 'created': - if plexpy.CONFIG.NOTIFY_RECENTLY_ADDED_GRANDPARENT \ - and (timeline_data['media_type'] == 'movie' or timeline_data['media_type'] == 'show' \ - or timeline_data['media_type'] == 'artist'): - # Build and send notification - notify_strings = build_notify_text(session=timeline_data, state=notify_action) - notifiers.send_notification(config_id=agent['id'], - subject=notify_strings[0], - body=notify_strings[1]) - # Set the notification state in the db - set_notify_state(session=timeline_data, state=notify_action, agent_info=agent) - elif not plexpy.CONFIG.NOTIFY_RECENTLY_ADDED_GRANDPARENT \ - and (timeline_data['media_type'] == 'movie' or timeline_data['media_type'] == 'episode' \ - or timeline_data['media_type'] == 'track'): + if (plexpy.CONFIG.NOTIFY_RECENTLY_ADDED_GRANDPARENT \ + and (timeline_data['media_type'] == 'movie' or timeline_data['media_type'] == 'show' or timeline_data['media_type'] == 'artist')) \ + or (not plexpy.CONFIG.NOTIFY_RECENTLY_ADDED_GRANDPARENT \ + and (timeline_data['media_type'] == 'movie' or timeline_data['media_type'] == 'episode' or timeline_data['media_type'] == 'track')): # Build and send notification notify_strings = build_notify_text(session=timeline_data, state=notify_action) notifiers.send_notification(config_id=agent['id'], diff --git a/plexpy/plexwatch_import.py b/plexpy/plexwatch_import.py index 7df5b355..e50c3ca4 100644 --- a/plexpy/plexwatch_import.py +++ b/plexpy/plexwatch_import.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 @@ -247,6 +247,8 @@ def import_from_plexwatch(database=None, table_name=None, import_ignore_interval logger.debug(u"PlexPy Importer :: Disabling monitoring while import in progress.") plexpy.schedule_job(activity_pinger.check_active_sessions, 'Check for active sessions', hours=0, minutes=0, seconds=0) + plexpy.schedule_job(activity_pinger.check_recently_added, 'Check for recently added items', + hours=0, minutes=0, seconds=0) ap = activity_processor.ActivityProcessor() user_data = users.Users() diff --git a/plexpy/pmsconnect.py b/plexpy/pmsconnect.py index 6ef4cfdf..36939bfa 100644 --- a/plexpy/pmsconnect.py +++ b/plexpy/pmsconnect.py @@ -281,10 +281,13 @@ class PmsConnect(object): recents_main = a.getElementsByTagName('Directory') for item in recents_main: recent_type = helpers.get_xml_attr(item, 'type') - recent_items = {'type': recent_type, + recent_items = {'media_type': recent_type, 'rating_key': helpers.get_xml_attr(item, 'ratingKey'), + 'parent_rating_key': helpers.get_xml_attr(item, 'parentRatingKey'), 'title': helpers.get_xml_attr(item, 'title'), 'parent_title': helpers.get_xml_attr(item, 'parentTitle'), + 'library_id': helpers.get_xml_attr(item, 'librarySectionID'), + 'library_title': helpers.get_xml_attr(item, 'librarySectionTitle'), 'thumb': helpers.get_xml_attr(item, 'thumb'), 'added_at': helpers.get_xml_attr(item, 'addedAt') } @@ -296,10 +299,12 @@ class PmsConnect(object): recent_type = helpers.get_xml_attr(item, 'type') if recent_type == 'movie': - recent_items = {'type': recent_type, + recent_items = {'media_type': recent_type, 'rating_key': helpers.get_xml_attr(item, 'ratingKey'), 'title': helpers.get_xml_attr(item, 'title'), 'parent_title': helpers.get_xml_attr(item, 'parentTitle'), + 'library_id': helpers.get_xml_attr(item, 'librarySectionID'), + 'library_title': helpers.get_xml_attr(item, 'librarySectionTitle'), 'year': helpers.get_xml_attr(item, 'year'), 'thumb': helpers.get_xml_attr(item, 'thumb'), 'added_at': helpers.get_xml_attr(item, 'addedAt') @@ -595,6 +600,49 @@ class PmsConnect(object): return metadata_list + """ + Return processed and validated metadata list for all children of requested item. + + Parameters required: rating_key { Plex ratingKey } + + Output: array + """ + def get_metadata_children_details(self, rating_key=''): + metadata = self.get_metadata_children(str(rating_key), output_format='xml') + + try: + xml_head = metadata.getElementsByTagName('MediaContainer') + except: + logger.warn("Unable to parse XML for get_metadata_children.") + return [] + + metadata_list = [] + + for a in xml_head: + if a.getAttribute('size'): + if a.getAttribute('size') == '0': + metadata_list = {'metadata': None} + return metadata_list + + if a.getElementsByTagName('Video'): + metadata_main = a.getElementsByTagName('Video') + for item in metadata_main: + child_rating_key = helpers.get_xml_attr(item, 'ratingKey') + metadata = self.get_metadata_details(str(child_rating_key)) + if metadata: + metadata_list.append(metadata['metadata']) + + elif a.getElementsByTagName('Track'): + metadata_main = a.getElementsByTagName('Track') + for item in metadata_main: + child_rating_key = helpers.get_xml_attr(item, 'ratingKey') + metadata = self.get_metadata_details(str(child_rating_key)) + if metadata: + metadata_list.append(metadata['metadata']) + + output = {'metadata': metadata_list} + return output + """ Return processed and validated session list.