From 66c1fd6593b0c2b9db89812aac6beecf01b8703d Mon Sep 17 00:00:00 2001 From: JonnyWong16 Date: Sun, 16 Feb 2020 14:54:48 -0800 Subject: [PATCH] Save Live TV sessions to the database --- plexpy/__init__.py | 38 ++++++++++++++++++++++++++++++++++-- plexpy/activity_processor.py | 13 ++++++++++-- plexpy/datafactory.py | 10 +++++++++- plexpy/pmsconnect.py | 9 +++++---- 4 files changed, 61 insertions(+), 9 deletions(-) diff --git a/plexpy/__init__.py b/plexpy/__init__.py index 63a93802..15188922 100644 --- a/plexpy/__init__.py +++ b/plexpy/__init__.py @@ -604,7 +604,8 @@ def dbcheck(): 'transcode_hw_decoding INTEGER, transcode_hw_encoding INTEGER, ' 'optimized_version INTEGER, optimized_version_profile TEXT, optimized_version_title TEXT, ' 'synced_version INTEGER, synced_version_profile TEXT, ' - 'live INTEGER, live_uuid TEXT, secure INTEGER, relayed INTEGER, ' + 'live INTEGER, live_uuid TEXT, channel_call_sign TEXT, channel_identifier TEXT, channel_thumb TEXT, ' + 'secure INTEGER, relayed INTEGER, ' 'buffer_count INTEGER DEFAULT 0, buffer_last_triggered INTEGER, last_paused INTEGER, watched INTEGER DEFAULT 0, ' 'write_attempts INTEGER DEFAULT 0, raw_stream_info TEXT)' ) @@ -652,7 +653,7 @@ def dbcheck(): 'art TEXT, media_type TEXT, year INTEGER, originally_available_at TEXT, added_at INTEGER, updated_at INTEGER, ' 'last_viewed_at INTEGER, content_rating TEXT, summary TEXT, tagline TEXT, rating TEXT, ' 'duration INTEGER DEFAULT 0, guid TEXT, directors TEXT, writers TEXT, actors TEXT, genres TEXT, studio TEXT, ' - 'labels TEXT)' + 'labels TEXT, live INTEGER DEFAULT 0, channel_call_sign TEXT, channel_identifier TEXT, channel_thumb TEXT)' ) # users table :: This table keeps record of the friends list @@ -1220,6 +1221,21 @@ def dbcheck(): 'ALTER TABLE sessions ADD COLUMN stream_video_dynamic_range TEXT' ) + # Upgrade sessions table from earlier versions + try: + c_db.execute('SELECT channel_identifier FROM sessions') + except sqlite3.OperationalError: + logger.debug(u"Altering database. Updating database table sessions.") + c_db.execute( + 'ALTER TABLE sessions ADD COLUMN channel_call_sign TEXT' + ) + c_db.execute( + 'ALTER TABLE sessions ADD COLUMN channel_identifier TEXT' + ) + c_db.execute( + 'ALTER TABLE sessions ADD COLUMN channel_thumb TEXT' + ) + # Upgrade session_history table from earlier versions try: c_db.execute('SELECT reference_id FROM session_history') @@ -1327,6 +1343,24 @@ def dbcheck(): 'ALTER TABLE session_history_metadata ADD COLUMN original_title TEXT' ) + # Upgrade session_history_metadata table from earlier versions + try: + c_db.execute('SELECT live FROM session_history_metadata') + except sqlite3.OperationalError: + logger.debug(u"Altering database. Updating database table session_history_metadata.") + c_db.execute( + 'ALTER TABLE session_history_metadata ADD COLUMN live INTEGER DEFAULT 0' + ) + c_db.execute( + 'ALTER TABLE session_history_metadata ADD COLUMN channel_call_sign TEXT' + ) + c_db.execute( + 'ALTER TABLE session_history_metadata ADD COLUMN channel_identifier TEXT' + ) + c_db.execute( + 'ALTER TABLE session_history_metadata ADD COLUMN channel_thumb TEXT' + ) + # Upgrade session_history_media_info table from earlier versions try: c_db.execute('SELECT transcode_decision FROM session_history_media_info') diff --git a/plexpy/activity_processor.py b/plexpy/activity_processor.py index 03df9fb5..5c84dfbf 100644 --- a/plexpy/activity_processor.py +++ b/plexpy/activity_processor.py @@ -235,7 +235,12 @@ class ActivityProcessor(object): if not is_import: logger.debug(u"Tautulli ActivityProcessor :: Fetching metadata for item ratingKey %s" % session['rating_key']) pms_connect = pmsconnect.PmsConnect() - metadata = pms_connect.get_metadata_details(rating_key=str(session['rating_key'])) + if session['live']: + metadata = pms_connect.get_metadata_details(rating_key=str(session['rating_key']), + cache_key=session['session_key'], + skip_cache_time=True) + else: + metadata = pms_connect.get_metadata_details(rating_key=str(session['rating_key'])) if not metadata: return False else: @@ -453,7 +458,11 @@ class ActivityProcessor(object): 'actors': actors, 'genres': genres, 'studio': metadata['studio'], - 'labels': labels + 'labels': labels, + 'live': session['live'], + 'channel_call_sign': metadata['channel_call_sign'], + 'channel_identifier': metadata['channel_identifier'], + 'channel_thumb': metadata['channel_thumb'] } # logger.debug(u"Tautulli ActivityProcessor :: Writing sessionKey %s session_history_metadata transaction..." diff --git a/plexpy/datafactory.py b/plexpy/datafactory.py index 1e635e0f..e35a3dbd 100644 --- a/plexpy/datafactory.py +++ b/plexpy/datafactory.py @@ -94,6 +94,7 @@ class DataFactory(object): 'session_history_metadata.thumb', 'session_history_metadata.parent_thumb', 'session_history_metadata.grandparent_thumb', + 'session_history_metadata.live', 'MAX((CASE WHEN (view_offset IS NULL OR view_offset = "") THEN 0.1 ELSE view_offset * 1.0 END) / \ (CASE WHEN (session_history_metadata.duration IS NULL OR session_history_metadata.duration = "") \ THEN 1.0 ELSE session_history_metadata.duration * 1.0 END) * 100) AS percent_complete', @@ -142,6 +143,7 @@ class DataFactory(object): 'thumb', 'parent_thumb', 'grandparent_thumb', + 'live', 'MAX((CASE WHEN (view_offset IS NULL OR view_offset = "") THEN 0.1 ELSE view_offset * 1.0 END) / \ (CASE WHEN (duration IS NULL OR duration = "") \ THEN 1.0 ELSE duration * 1.0 END) * 100) AS percent_complete', @@ -206,6 +208,9 @@ class DataFactory(object): else: thumb = item['thumb'] + if item['live']: + item['percent_complete'] = 100 + if item['percent_complete'] >= watched_percent[item['media_type']]: watched_status = 1 elif item['percent_complete'] >= watched_percent[item['media_type']]/2: @@ -230,6 +235,7 @@ class DataFactory(object): 'product': item['product'], 'player': item['player'], 'ip_address': item['ip_address'], + 'live': item['live'], 'media_type': item['media_type'], 'rating_key': item['rating_key'], 'parent_rating_key': item['parent_rating_key'], @@ -1016,7 +1022,9 @@ class DataFactory(object): 'session_history_media_info.container, session_history_media_info.bitrate, ' \ 'session_history_media_info.video_codec, session_history_media_info.video_resolution, ' \ 'session_history_media_info.video_framerate, session_history_media_info.audio_codec, ' \ - 'session_history_media_info.audio_channels ' \ + 'session_history_media_info.audio_channels, session_history_metadata.live, ' \ + 'session_history_metadata.channel_call_sign, session_history_metadata.channel_identifier, ' \ + 'session_history_metadata.channel_thumb ' \ 'FROM session_history_metadata ' \ 'JOIN library_sections ON session_history_metadata.section_id = library_sections.section_id ' \ 'JOIN session_history_media_info ON session_history_metadata.id = session_history_media_info.id ' \ diff --git a/plexpy/pmsconnect.py b/plexpy/pmsconnect.py index fdca4d2e..d83cfd16 100644 --- a/plexpy/pmsconnect.py +++ b/plexpy/pmsconnect.py @@ -571,7 +571,7 @@ class PmsConnect(object): return output - def get_metadata_details(self, rating_key='', sync_id='', cache_key=None, media_info=True): + def get_metadata_details(self, rating_key='', sync_id='', cache_key=None, skip_cache_time=False, media_info=True): """ Return processed and validated metadata list for requested item. @@ -597,7 +597,7 @@ class PmsConnect(object): if metadata: _cache_time = metadata.pop('_cache_time', 0) # Return cached metadata if less than METADATA_CACHE_SECONDS ago - if int(time.time()) - _cache_time <= plexpy.CONFIG.METADATA_CACHE_SECONDS: + if skip_cache_time or int(time.time()) - _cache_time <= plexpy.CONFIG.METADATA_CACHE_SECONDS: return metadata if rating_key: @@ -641,8 +641,6 @@ class PmsConnect(object): if metadata_main.nodeName == 'Directory' and metadata_type == 'photo': metadata_type = 'photo_album' - live = int(helpers.get_xml_attr(metadata_main, 'live') == '1') - section_id = helpers.get_xml_attr(a, 'librarySectionID') library_name = helpers.get_xml_attr(a, 'librarySectionTitle') @@ -1344,7 +1342,10 @@ class PmsConnect(object): 'parts': parts } + live = int(helpers.get_xml_attr(metadata_main, 'live') == '1') + if live: + media_info['live'] = live media_info['channel_call_sign'] = helpers.get_xml_attr(media, 'channelCallSign') media_info['channel_identifier'] = helpers.get_xml_attr(media, 'channelIdentifier') media_info['channel_thumb'] = helpers.get_xml_attr(media, 'channelThumb')