From e4b6d61098a2260cee8f23bb676ecf6aecaa3a1b Mon Sep 17 00:00:00 2001 From: JonnyWong16 Date: Wed, 19 Feb 2020 23:57:55 -0800 Subject: [PATCH] Add option to retrieve history using guid --- plexpy/__init__.py | 11 ++++++++++- plexpy/datafactory.py | 41 +++++++++++++++++++++++++++++------------ plexpy/libraries.py | 7 +++++-- plexpy/users.py | 7 ++++++- plexpy/webserve.py | 7 +++++-- 5 files changed, 55 insertions(+), 18 deletions(-) diff --git a/plexpy/__init__.py b/plexpy/__init__.py index d105bac9..acffc115 100644 --- a/plexpy/__init__.py +++ b/plexpy/__init__.py @@ -585,7 +585,7 @@ def dbcheck(): 'media_index INTEGER, parent_media_index INTEGER, ' 'thumb TEXT, parent_thumb TEXT, grandparent_thumb TEXT, year INTEGER, ' 'parent_rating_key INTEGER, grandparent_rating_key INTEGER, ' - 'originally_available_at TEXT, added_at INTEGER, ' + 'originally_available_at TEXT, added_at INTEGER, guid TEXT, ' 'view_offset INTEGER DEFAULT 0, duration INTEGER, video_decision TEXT, audio_decision TEXT, ' 'transcode_decision TEXT, container TEXT, bitrate INTEGER, width INTEGER, height INTEGER, ' 'video_codec TEXT, video_bitrate INTEGER, video_resolution TEXT, video_width INTEGER, video_height INTEGER, ' @@ -1249,6 +1249,15 @@ def dbcheck(): 'ALTER TABLE sessions ADD COLUMN added_at INTEGER' ) + # Upgrade sessions table from earlier versions + try: + c_db.execute('SELECT guid FROM sessions') + except sqlite3.OperationalError: + logger.debug(u"Altering database. Updating database table sessions.") + c_db.execute( + 'ALTER TABLE sessions ADD COLUMN guid TEXT' + ) + # Upgrade session_history table from earlier versions try: c_db.execute('SELECT reference_id FROM session_history') diff --git a/plexpy/datafactory.py b/plexpy/datafactory.py index 430d592c..70cf8264 100644 --- a/plexpy/datafactory.py +++ b/plexpy/datafactory.py @@ -98,6 +98,7 @@ class DataFactory(object): 'session_history_metadata.live', 'session_history_metadata.added_at', 'session_history_metadata.originally_available_at', + 'session_history_metadata.guid', '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', @@ -149,6 +150,7 @@ class DataFactory(object): 'live', 'added_at', 'originally_available_at', + 'guid', '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', @@ -255,6 +257,7 @@ class DataFactory(object): 'parent_media_index': item['parent_media_index'], 'thumb': thumb, 'originally_available_at': item['originally_available_at'], + 'guid': item['guid'], 'transcode_decision': item['transcode_decision'], 'percent_complete': int(round(item['percent_complete'])), 'watched_status': watched_status, @@ -298,7 +301,7 @@ class DataFactory(object): top_movies = [] try: query = 'SELECT t.id, t.full_title, t.rating_key, t.thumb, t.section_id, ' \ - 't.art, t.media_type, t.content_rating, t.labels, t.started, t.live, ' \ + 't.art, t.media_type, t.content_rating, t.labels, t.started, t.live, t.guid, ' \ 'MAX(t.started) AS last_watch, COUNT(t.id) AS total_plays, SUM(t.d) AS total_duration ' \ 'FROM (SELECT *, SUM(CASE WHEN stopped > 0 THEN (stopped - started) - ' \ ' (CASE WHEN paused_counter IS NULL THEN 0 ELSE paused_counter END) ELSE 0 END) ' \ @@ -336,6 +339,7 @@ class DataFactory(object): 'platform': '', 'platform': '', 'live': item['live'], + 'guid': item['guid'], 'row_id': item['id'] } top_movies.append(row) @@ -349,7 +353,7 @@ class DataFactory(object): popular_movies = [] try: query = 'SELECT t.id, t.full_title, t.rating_key, t.thumb, t.section_id, ' \ - 't.art, t.media_type, t.content_rating, t.labels, t.started, t.live, ' \ + 't.art, t.media_type, t.content_rating, t.labels, t.started, t.live, t.guid, ' \ 'COUNT(DISTINCT t.user_id) AS users_watched, ' \ 'MAX(t.started) AS last_watch, COUNT(t.id) as total_plays, SUM(t.d) AS total_duration ' \ 'FROM (SELECT *, SUM(CASE WHEN stopped > 0 THEN (stopped - started) - ' \ @@ -386,6 +390,7 @@ class DataFactory(object): 'friendly_name': '', 'platform': '', 'live': item['live'], + 'guid': item['guid'], 'row_id': item['id'] } popular_movies.append(row) @@ -398,7 +403,7 @@ class DataFactory(object): top_tv = [] try: query = 'SELECT t.id, t.grandparent_title, t.grandparent_rating_key, t.grandparent_thumb, t.section_id, ' \ - 't.rating_key, t.art, t.media_type, t.content_rating, t.labels, t.started, t.live, ' \ + 't.rating_key, t.art, t.media_type, t.content_rating, t.labels, t.started, t.live, t.guid, ' \ 'MAX(t.started) AS last_watch, COUNT(t.id) AS total_plays, SUM(t.d) AS total_duration ' \ 'FROM (SELECT *, SUM(CASE WHEN stopped > 0 THEN (stopped - started) - ' \ ' (CASE WHEN paused_counter IS NULL THEN 0 ELSE paused_counter END) ELSE 0 END) ' \ @@ -435,6 +440,7 @@ class DataFactory(object): 'friendly_name': '', 'platform': '', 'live': item['live'], + 'guid': item['guid'], 'row_id': item['id'] } top_tv.append(row) @@ -448,7 +454,7 @@ class DataFactory(object): popular_tv = [] try: query = 'SELECT t.id, t.grandparent_title, t.grandparent_rating_key, t.grandparent_thumb, t.section_id, ' \ - 't.rating_key, t.art, t.media_type, t.content_rating, t.labels, t.started, t.live, ' \ + 't.rating_key, t.art, t.media_type, t.content_rating, t.labels, t.started, t.live, t.guid, ' \ 'COUNT(DISTINCT t.user_id) AS users_watched, ' \ 'MAX(t.started) AS last_watch, COUNT(t.id) as total_plays, SUM(t.d) AS total_duration ' \ 'FROM (SELECT *, SUM(CASE WHEN stopped > 0 THEN (stopped - started) - ' \ @@ -485,6 +491,7 @@ class DataFactory(object): 'friendly_name': '', 'platform': '', 'live': item['live'], + 'guid': item['guid'], 'row_id': item['id'] } popular_tv.append(row) @@ -498,7 +505,7 @@ class DataFactory(object): try: query = 'SELECT t.id, t.grandparent_title, t.original_title, ' \ 't.grandparent_rating_key, t.grandparent_thumb, t.section_id, ' \ - 't.art, t.media_type, t.content_rating, t.labels, t.started, t.live, ' \ + 't.art, t.media_type, t.content_rating, t.labels, t.started, t.live, t.guid, ' \ 'MAX(t.started) AS last_watch, COUNT(t.id) AS total_plays, SUM(t.d) AS total_duration ' \ 'FROM (SELECT *, SUM(CASE WHEN stopped > 0 THEN (stopped - started) - ' \ ' (CASE WHEN paused_counter IS NULL THEN 0 ELSE paused_counter END) ELSE 0 END) ' \ @@ -535,6 +542,7 @@ class DataFactory(object): 'friendly_name': '', 'platform': '', 'live': item['live'], + 'guid': item['guid'], 'row_id': item['id'] } top_music.append(row) @@ -549,7 +557,7 @@ class DataFactory(object): try: query = 'SELECT t.id, t.grandparent_title, t.original_title, ' \ 't.grandparent_rating_key, t.grandparent_thumb, t.section_id, ' \ - 't.art, t.media_type, t.content_rating, t.labels, t.started, t.live, ' \ + 't.art, t.media_type, t.content_rating, t.labels, t.started, t.live, t.guid, ' \ 'COUNT(DISTINCT t.user_id) AS users_watched, ' \ 'MAX(t.started) AS last_watch, COUNT(t.id) as total_plays, SUM(t.d) AS total_duration ' \ 'FROM (SELECT *, SUM(CASE WHEN stopped > 0 THEN (stopped - started) - ' \ @@ -586,6 +594,7 @@ class DataFactory(object): 'friendly_name': '', 'platform': '', 'live': item['live'], + 'guid': item['guid'], 'row_id': item['id'] } popular_music.append(row) @@ -702,7 +711,7 @@ class DataFactory(object): try: query = 'SELECT t.id, t.full_title, t.rating_key, t.thumb, t.grandparent_thumb, ' \ 't.user, t.user_id, t.custom_avatar_url as user_thumb, t.player, t.section_id, ' \ - 't.art, t.media_type, t.content_rating, t.labels, t.live, ' \ + 't.art, t.media_type, t.content_rating, t.labels, t.live, t.guid, ' \ '(CASE WHEN t.friendly_name IS NULL THEN t.username ELSE t.friendly_name END) ' \ ' AS friendly_name, ' \ 'MAX(t.started) AS last_watch, ' \ @@ -749,6 +758,7 @@ class DataFactory(object): 'labels': item['labels'].split(';') if item['labels'] else (), 'last_watch': item['last_watch'], 'live': item['live'], + 'guid': item['guid'], 'player': item['player'] } last_watched.append(row) @@ -1011,10 +1021,17 @@ class DataFactory(object): stream_output = {k: v or '' for k, v in stream_output.iteritems()} return stream_output - def get_metadata_details(self, rating_key): + def get_metadata_details(self, rating_key='', guid=''): monitor_db = database.MonitorDatabase() - if rating_key: + if rating_key or guid: + if guid: + where = 'session_history_metadata.guid LIKE ?' + args = [guid.split('?')[0] + '%'] # SQLite LIKE wildcard + else: + where = 'session_history_metadata.rating_key = ?' + args = [rating_key] + query = 'SELECT session_history_metadata.id, ' \ 'session_history_metadata.rating_key, session_history_metadata.parent_rating_key, ' \ 'session_history_metadata.grandparent_rating_key, session_history_metadata.title, ' \ @@ -1039,10 +1056,10 @@ class DataFactory(object): 'session_history_metadata.channel_thumb ' \ 'FROM session_history_metadata ' \ 'JOIN session_history_media_info ON session_history_metadata.id = session_history_media_info.id ' \ - 'WHERE session_history_metadata.rating_key = ? ' \ + 'WHERE %s ' \ 'ORDER BY session_history_metadata.id DESC ' \ - 'LIMIT 1' - result = monitor_db.select(query=query, args=[rating_key]) + 'LIMIT 1' % where + result = monitor_db.select(query=query, args=args) else: result = [] diff --git a/plexpy/libraries.py b/plexpy/libraries.py index 297879a0..f1e7dfd1 100644 --- a/plexpy/libraries.py +++ b/plexpy/libraries.py @@ -288,6 +288,7 @@ class Libraries(object): 'session_history_metadata.live', 'session_history_metadata.added_at', 'session_history_metadata.originally_available_at', + 'session_history_metadata.guid', 'library_sections.do_notify', 'library_sections.do_notify_created', 'library_sections.keep_history' @@ -353,6 +354,7 @@ class Libraries(object): 'labels': item['labels'].split(';') if item['labels'] else (), 'live': item['live'], 'originally_available_at': item['originally_available_at'], + 'guid': item['guid'], 'do_notify': helpers.checked(item['do_notify']), 'do_notify_created': helpers.checked(item['do_notify_created']), 'keep_history': helpers.checked(item['keep_history']) @@ -704,7 +706,7 @@ class Libraries(object): 'deleted_section': 0 } - if not section_id or helpers.cast_to_int(section_id) <= 0: + if not section_id: return default_return def get_library_details(section_id=section_id): @@ -884,7 +886,7 @@ class Libraries(object): try: if str(section_id).isdigit(): - query = 'SELECT session_history.id, session_history.media_type, ' \ + query = 'SELECT session_history.id, session_history.media_type, guid, ' \ 'session_history.rating_key, session_history.parent_rating_key, session_history.grandparent_rating_key, ' \ 'title, parent_title, grandparent_title, original_title, ' \ 'thumb, parent_thumb, grandparent_thumb, media_index, parent_media_index, ' \ @@ -924,6 +926,7 @@ class Libraries(object): 'year': row['year'], 'originally_available_at': row['originally_available_at'], 'live': row['live'], + 'guid': row['guid'], 'time': row['started'], 'user': row['user'], 'section_id': row['section_id'], diff --git a/plexpy/users.py b/plexpy/users.py index f913176f..35e19201 100644 --- a/plexpy/users.py +++ b/plexpy/users.py @@ -119,6 +119,7 @@ class Users(object): 'session_history_metadata.live', 'session_history_metadata.added_at', 'session_history_metadata.originally_available_at', + 'session_history_metadata.guid', 'session_history_media_info.transcode_decision', 'users.do_notify as do_notify', 'users.keep_history as keep_history', @@ -184,6 +185,7 @@ class Users(object): 'parent_media_index': item['parent_media_index'], 'live': item['live'], 'originally_available_at': item['originally_available_at'], + 'guid': item['guid'], 'transcode_decision': item['transcode_decision'], 'do_notify': helpers.checked(item['do_notify']), 'keep_history': helpers.checked(item['keep_history']), @@ -233,6 +235,7 @@ class Users(object): 'session_history_metadata.live', 'session_history_metadata.added_at', 'session_history_metadata.originally_available_at', + 'session_history_metadata.guid', 'session_history_media_info.transcode_decision', 'session_history.user', 'session_history.user_id as custom_user_id', @@ -289,6 +292,7 @@ class Users(object): 'parent_media_index': item['parent_media_index'], 'live': item['live'], 'originally_available_at': item['originally_available_at'], + 'guid': item['guid'], 'transcode_decision': item['transcode_decision'], 'friendly_name': item['friendly_name'], 'user_id': item['custom_user_id'] @@ -544,7 +548,7 @@ class Users(object): try: if str(user_id).isdigit(): - query = 'SELECT session_history.id, session_history.media_type, ' \ + query = 'SELECT session_history.id, session_history.media_type, guid, ' \ 'session_history.rating_key, session_history.parent_rating_key, session_history.grandparent_rating_key, ' \ 'title, parent_title, grandparent_title, original_title, ' \ 'thumb, parent_thumb, grandparent_thumb, media_index, parent_media_index, ' \ @@ -585,6 +589,7 @@ class Users(object): 'year': row['year'], 'originally_available_at': row['originally_available_at'], 'live': row['live'], + 'guid': row['guid'], 'time': row['started'], 'user': row['user'] } diff --git a/plexpy/webserve.py b/plexpy/webserve.py index 3e954695..d4b98302 100644 --- a/plexpy/webserve.py +++ b/plexpy/webserve.py @@ -1719,6 +1719,9 @@ class WebInterface(object): if 'year' in kwargs: year = kwargs.get('year', '') custom_where.append(['session_history_metadata.year', year]) + if 'guid' in kwargs: + guid = kwargs.get('guid', '').split('?')[0] + '%' # SQLite LIKE wildcard + custom_where.append(['session_history_metadata.guid', guid]) data_factory = datafactory.DataFactory() history = data_factory.get_datatables_history(kwargs=kwargs, custom_where=custom_where, grouping=grouping) @@ -3913,7 +3916,7 @@ class WebInterface(object): @cherrypy.expose @requireAuth() - def info(self, rating_key=None, source=None, **kwargs): + def info(self, rating_key=None, guid=None, source=None, **kwargs): if rating_key and not str(rating_key).isdigit(): raise cherrypy.HTTPRedirect(plexpy.HTTP_ROOT) @@ -3926,7 +3929,7 @@ class WebInterface(object): if source == 'history': data_factory = datafactory.DataFactory() - metadata = data_factory.get_metadata_details(rating_key=rating_key) + metadata = data_factory.get_metadata_details(rating_key=rating_key, guid=guid) if metadata: poster_info = data_factory.get_poster_info(metadata=metadata) metadata.update(poster_info)