From 381c3da31c66475d402e77782b61639caae7b009 Mon Sep 17 00:00:00 2001 From: Jonathan Wong Date: Sun, 10 Jan 2016 13:35:20 -0800 Subject: [PATCH] Add media info table to library page --- data/interfaces/default/css/plexpy.css | 37 +- data/interfaces/default/history.html | 28 +- .../default/history_table_modal.html | 23 +- data/interfaces/default/info.html | 68 +-- .../default/js/tables/history_table.js | 26 +- .../default/js/tables/history_table_modal.js | 13 +- .../interfaces/default/js/tables/libraries.js | 40 +- .../default/js/tables/media_info_table.js | 420 ++++++++++++++++++ .../interfaces/default/js/tables/plex_logs.js | 2 +- data/interfaces/default/js/tables/users.js | 22 +- data/interfaces/default/libraries.html | 31 +- data/interfaces/default/library.html | 120 ++++- .../default/library_recently_added.html | 6 +- data/interfaces/default/recently_added.html | 2 +- data/interfaces/default/user.html | 57 +-- data/interfaces/default/users.html | 6 +- plexpy/__init__.py | 12 +- plexpy/activity_pinger.py | 4 +- plexpy/activity_processor.py | 8 +- plexpy/config.py | 2 +- plexpy/datafactory.py | 115 ++--- plexpy/datatables.py | 3 +- plexpy/libraries.py | 373 +++++++++++++++- plexpy/notification_handler.py | 2 +- plexpy/plexwatch_import.py | 8 +- plexpy/pmsconnect.py | 312 ++++++++----- plexpy/users.py | 9 +- plexpy/webserve.py | 128 +++--- 28 files changed, 1415 insertions(+), 462 deletions(-) create mode 100644 data/interfaces/default/js/tables/media_info_table.js diff --git a/data/interfaces/default/css/plexpy.css b/data/interfaces/default/css/plexpy.css index 3a5a50db..d86dd165 100644 --- a/data/interfaces/default/css/plexpy.css +++ b/data/interfaces/default/css/plexpy.css @@ -71,9 +71,20 @@ img { -moz-box-shadow: 0 0 0 3px rgba(0,0,0,.2); box-shadow: 0 0 0 3px rgba(0,0,0,.2); } +.navbar-header { + position: absolute; + top: 0; + left: 15px; + width: 100%; +} .navbar-brand { padding: 5px 5px; } +.navbar-right { + position: absolute; + top: 0; + right: 15px; +} .nav > li > a { color: #999; -webkit-transition: all 0.3s ease; @@ -2542,12 +2553,22 @@ a .home-platforms-instance-list-oval:hover, width: 100%; } } +table.display, +table.display tr.shown + tr table[id^='history_child'], +table.display tr.shown + tr table[id^='media_info_child'], +table.display tr.shown + tr table[id^='media_info_child'] tr.shown + tr table[id^='media_info_child'] { + table-layout: fixed; +} +table.display.no-fixed { + table-layout: auto; +} table.display tr.shown + tr div.slider { display: none; } table.display tr.shown + tr > td { padding-top: 0; padding-bottom: 0; + padding-left: 0; } table.display tr.shown + tr:hover { background-color: rgba(255,255,255,0); @@ -2558,7 +2579,9 @@ table.display tr.shown + tr .pagination > .active > a, table.display tr.shown + tr .pagination > .active > a:hover { color: #fff; } -table.display tr.shown + tr table[id^='history_child'] td:hover a { +table.display tr.shown + tr table[id^='history_child'] td:hover a, +table.display tr.shown + tr table[id^='media_info_child'] > tr > td:hover a, +table.display tr.shown + tr table[id^='media_info_child'] tr.shown + tr table[id^='media_info_child'] td:hover a { color: #F9AA03; } table.display tr.shown + tr .pagination > .disabled > a { @@ -2569,14 +2592,22 @@ table.display tr.shown + tr .pagination > li > a:hover { } table[id^='history_child'] { margin-top: 0; - margin-left: -4px; opacity: .6; } -table[id^='history_child'] thead th { +table[id^='media_info_child'] { + margin-top: 0; +} +table[id^='history_child'] thead th, +table[id^='media_info_child'] thead th { line-height: 0; height: 0 !important; overflow: hidden; } +table[id^='media_info_child'] table[id^='media_info_child'] thead th { + line-height: 25px; + height: 35px !important; + overflow: hidden; +} #search_form { width: 300px; padding: 8px 15px; diff --git a/data/interfaces/default/history.html b/data/interfaces/default/history.html index 59cb8aa0..992f2df6 100644 --- a/data/interfaces/default/history.html +++ b/data/interfaces/default/history.html @@ -25,18 +25,18 @@ - - - - - - - - - - - - + + + + + + + + + + + + @@ -83,8 +83,8 @@ type: 'post', data: function (d) { return { - 'json_data': JSON.stringify(d), - 'media_type': media_type + json_data: JSON.stringify(d), + media_type: media_type }; } } diff --git a/data/interfaces/default/history_table_modal.html b/data/interfaces/default/history_table_modal.html index 19de1faf..54e6c0c4 100644 --- a/data/interfaces/default/history_table_modal.html +++ b/data/interfaces/default/history_table_modal.html @@ -10,14 +10,14 @@
DeleteTimeUserIP AddressPlatformPlayerTitleStartedPausedStoppedDurationDeleteTimeUserIP AddressPlatformPlayerTitleStartedPausedStoppedDuration
+
- - - - - + + + + + @@ -34,13 +34,14 @@ $(document).ready(function() { $('#date-header').html(moment('${data}','YYYY-MM-DD').format('ddd MMM Do YYYY')); history_table_modal_options.ajax = { - "url": "get_history", + url: 'get_history', type: "post", data: function ( d ) { - return { 'json_data': JSON.stringify( d ), - 'grouping': false, - 'start_date': '${data}' - }; + return { + json_data: JSON.stringify(d), + grouping: false, + start_date: '${data}' + }; } } diff --git a/data/interfaces/default/info.html b/data/interfaces/default/info.html index 2e272799..fb7d8a25 100644 --- a/data/interfaces/default/info.html +++ b/data/interfaces/default/info.html @@ -54,29 +54,29 @@ DOCUMENTATION :: END
% endif
- - % if data['media_type'] == 'library' and config['update_library_ids'] == 1: -
- Updating library ids in the database. This could take a few minutes depending on the size of your database. -
- The history table will refresh automatically when the update is complete. Please wait... -
- % endif
Watch History for ${data['title']} @@ -370,41 +362,17 @@ DOCUMENTATION :: END % if data: -% if data['media_type'] == 'library': +% if data['media_type'] == 'show' or data['media_type'] == 'artist': -% elif data['media_type'] == 'show' or data['media_type'] == 'artist': - \ No newline at end of file diff --git a/data/interfaces/default/library.html b/data/interfaces/default/library.html index fc159c40..6d02e979 100644 --- a/data/interfaces/default/library.html +++ b/data/interfaces/default/library.html @@ -67,6 +67,7 @@ DOCUMENTATION :: END
@@ -170,18 +171,62 @@ DOCUMENTATION :: END
StartedStoppedUserPlayerTitleStartedStoppedUserPlayerTitle
- - - - - - - - - - - - + + + + + + + + + + + + + + + +
DeleteTimeUserIP AddressPlatformPlayerTitleStartedPausedStoppedDurationDeleteTimeUserIP AddressPlatformPlayerTitleStartedPausedStoppedDuration
+ + + + + +
+
+
+
+
+
+ + All Media Info for + ${data['section_name']} + + +
+
+ + +
+
+
+ + + + + + + + + + + + + + + @@ -250,6 +295,7 @@ DOCUMENTATION :: END % if data: + % endif \ No newline at end of file diff --git a/data/interfaces/default/library_recently_added.html b/data/interfaces/default/library_recently_added.html index 774166e7..264bce2b 100644 --- a/data/interfaces/default/library_recently_added.html +++ b/data/interfaces/default/library_recently_added.html @@ -19,7 +19,7 @@ parent_title Returns the name of the artist. grandparent_title Returns the name of the show. media_index Returns the index number of the episode. parent_media_index Returns the index number of the season. -library_id Returns the library section number of the media item. +section_id Returns the library section number of the media item. library_name Returns the library section name of the media item. year Returns the release year of the movie, episode, or album. thumb Returns the location of the item's thumbnail. Use with pms_image_proxy. @@ -39,7 +39,11 @@ DOCUMENTATION :: END
% if item['media_type'] == 'episode': + % if item['parent_thumb']:
+ % else: +
+ % endif % elif item['media_type'] == 'movie':
% endif diff --git a/data/interfaces/default/recently_added.html b/data/interfaces/default/recently_added.html index a8fe0042..bba1601b 100644 --- a/data/interfaces/default/recently_added.html +++ b/data/interfaces/default/recently_added.html @@ -19,7 +19,7 @@ parent_title Returns the name of the artist. grandparent_title Returns the name of the show. media_index Returns the index number of the episode. parent_media_index Returns the index number of the season. -library_id Returns the library section number of the media item. +section_id Returns the library section number of the media item. library_name Returns the library section name of the media item. year Returns the release year of the movie, episode, or album. thumb Returns the location of the item's thumbnail. Use with pms_image_proxy. diff --git a/data/interfaces/default/user.html b/data/interfaces/default/user.html index 67df6981..5213c9a3 100644 --- a/data/interfaces/default/user.html +++ b/data/interfaces/default/user.html @@ -181,18 +181,18 @@ from plexpy import helpers
Added AtTitleContainerBitrateVideo CodecVideo ResolutionVideo FramerateAudio CodecAudio ChannelsFile SizeLast WatchedTotal Plays
- - - - - - - - - - - - + + + + + + + + + + + + @@ -221,17 +221,17 @@ from plexpy import helpers
DeleteTimeUserIP AddressPlatformPlayerTitleStartedPausedStoppedDurationDeleteTimeUserIP AddressPlatformPlayerTitleStartedPausedStoppedDuration
- - - - - - - - - - - + + + + + + + + + + + @@ -342,9 +342,9 @@ from plexpy import helpers type: 'post', data: function ( d ) { return { - 'json_data': JSON.stringify( d ), - 'user_id': user_id, - 'media_type': media_type + json_data: JSON.stringify( d ), + user_id: user_id, + media_type: media_type }; } } @@ -391,8 +391,9 @@ from plexpy import helpers url: 'get_user_ips', type: 'post', data: function ( d ) { - return { 'json_data': JSON.stringify( d ), - 'user_id': user_id + return { + json_data: JSON.stringify( d ), + user_id: user_id }; } } diff --git a/data/interfaces/default/users.html b/data/interfaces/default/users.html index 9302625a..a3b5dcf5 100644 --- a/data/interfaces/default/users.html +++ b/data/interfaces/default/users.html @@ -20,7 +20,7 @@
-
StateUsernameTitleTypePlatformDeviceTotal SizeTotal ItemsConvertedDownloadedCompleteStateUsernameTitleTypePlatformDeviceTotal SizeTotal ItemsConvertedDownloadedComplete
+
@@ -77,7 +77,9 @@ url: 'get_user_list', type: 'POST', data: function ( d ) { - return { 'json_data': JSON.stringify( d ) }; + return { + json_data: JSON.stringify(d) + }; } } diff --git a/plexpy/__init__.py b/plexpy/__init__.py index 83557695..3e660628 100644 --- a/plexpy/__init__.py +++ b/plexpy/__init__.py @@ -377,7 +377,7 @@ def dbcheck(): # sessions table :: This is a temp table that logs currently active sessions c_db.execute( 'CREATE TABLE IF NOT EXISTS sessions (id INTEGER PRIMARY KEY AUTOINCREMENT, ' - 'session_key INTEGER, rating_key INTEGER, library_id INTEGER, media_type TEXT, started INTEGER, ' + 'session_key INTEGER, rating_key INTEGER, section_id INTEGER, media_type TEXT, started INTEGER, ' 'paused_counter INTEGER DEFAULT 0, state TEXT, user_id INTEGER, user TEXT, friendly_name TEXT, ' 'ip_address TEXT, machine_id TEXT, player TEXT, platform TEXT, title TEXT, parent_title TEXT, ' 'grandparent_title TEXT, parent_rating_key INTEGER, grandparent_rating_key INTEGER, ' @@ -413,7 +413,7 @@ def dbcheck(): 'CREATE TABLE IF NOT EXISTS session_history_metadata (id INTEGER PRIMARY KEY, ' 'rating_key INTEGER, parent_rating_key INTEGER, grandparent_rating_key INTEGER, ' 'title TEXT, parent_title TEXT, grandparent_title TEXT, full_title TEXT, media_index INTEGER, ' - 'parent_media_index INTEGER, library_id INTEGER, thumb TEXT, parent_thumb TEXT, grandparent_thumb TEXT, ' + 'parent_media_index INTEGER, section_id INTEGER, thumb TEXT, parent_thumb TEXT, grandparent_thumb TEXT, ' '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)' @@ -594,11 +594,11 @@ def dbcheck(): # Upgrade sessions table from earlier versions try: - c_db.execute('SELECT library_id from sessions') + c_db.execute('SELECT section_id from sessions') except sqlite3.OperationalError: logger.debug(u"Altering database. Updating database table sessions.") c_db.execute( - 'ALTER TABLE sessions ADD COLUMN library_id INTEGER' + 'ALTER TABLE sessions ADD COLUMN section_id INTEGER' ) # Upgrade session_history table from earlier versions @@ -644,11 +644,11 @@ def dbcheck(): # Upgrade session_history_metadata table from earlier versions try: - c_db.execute('SELECT library_id from session_history_metadata') + c_db.execute('SELECT section_id 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 library_id INTEGER' + 'ALTER TABLE session_history_metadata ADD COLUMN section_id INTEGER' ) # Upgrade users table from earlier versions diff --git a/plexpy/activity_pinger.py b/plexpy/activity_pinger.py index b2998ca1..84474577 100644 --- a/plexpy/activity_pinger.py +++ b/plexpy/activity_pinger.py @@ -192,7 +192,7 @@ def check_recently_added(): recently_added = recently_added_list['recently_added'] for item in recently_added: - library_details = library_data.get_details(section_id=item['library_id']) + library_details = library_data.get_details(section_id=item['section_id']) if not library_details['do_notify_created']: continue @@ -221,7 +221,7 @@ def check_recently_added(): if not plexpy.CONFIG.NOTIFY_RECENTLY_ADDED_GRANDPARENT: for item in metadata: - library_details = library_data.get_details(section_id=item['library_id']) + library_details = library_data.get_details(section_id=item['section_id']) if 0 < time_threshold - int(item['added_at']) <= time_interval: logger.debug(u"PlexPy Monitor :: Library item %s has been added to Plex." % str(item['rating_key'])) diff --git a/plexpy/activity_processor.py b/plexpy/activity_processor.py index 433219cc..ebef871c 100644 --- a/plexpy/activity_processor.py +++ b/plexpy/activity_processor.py @@ -29,7 +29,7 @@ class ActivityProcessor(object): def write_session(self, session=None, notify=True): if session: values = {'session_key': session['session_key'], - 'library_id': session['library_id'], + 'section_id': session['section_id'], 'rating_key': session['rating_key'], 'media_type': session['media_type'], 'state': session['state'], @@ -104,7 +104,7 @@ class ActivityProcessor(object): user_details = user_data.get_details(user_id=session['user_id']) library_data = libraries.Libraries() - library_details = library_data.get_details(section_id=session['library_id']) + library_details = library_data.get_details(section_id=session['section_id']) if session: logging_enabled = False @@ -257,7 +257,7 @@ class ActivityProcessor(object): # logger.debug(u"PlexPy ActivityProcessor :: Attempting to write to session_history_metadata table...") query = 'INSERT INTO session_history_metadata (id, rating_key, parent_rating_key, ' \ 'grandparent_rating_key, title, parent_title, grandparent_title, full_title, media_index, ' \ - 'parent_media_index, library_id, thumb, parent_thumb, grandparent_thumb, art, media_type, ' \ + 'parent_media_index, section_id, thumb, parent_thumb, grandparent_thumb, art, media_type, ' \ 'year, originally_available_at, added_at, updated_at, last_viewed_at, content_rating, ' \ 'summary, tagline, rating, duration, guid, directors, writers, actors, genres, studio) VALUES ' \ '(last_insert_rowid(), ' \ @@ -265,7 +265,7 @@ class ActivityProcessor(object): args = [session['rating_key'], session['parent_rating_key'], session['grandparent_rating_key'], session['title'], session['parent_title'], session['grandparent_title'], full_title, - metadata['media_index'], metadata['parent_media_index'], metadata['library_id'], metadata['thumb'], + metadata['media_index'], metadata['parent_media_index'], metadata['section_id'], metadata['thumb'], metadata['parent_thumb'], metadata['grandparent_thumb'], metadata['art'], session['media_type'], metadata['year'], metadata['originally_available_at'], metadata['added_at'], metadata['updated_at'], metadata['last_viewed_at'], metadata['content_rating'], metadata['summary'], metadata['tagline'], diff --git a/plexpy/config.py b/plexpy/config.py index 3287ad4b..d9a89d4e 100644 --- a/plexpy/config.py +++ b/plexpy/config.py @@ -372,7 +372,7 @@ _CONFIG_DEFINITIONS = { 'TWITTER_ON_EXTUP': (int, 'Twitter', 0), 'TWITTER_ON_INTUP': (int, 'Twitter', 0), 'UPDATE_DB_INTERVAL': (int, 'General', 24), - 'UPDATE_LIBRARY_IDS': (int, 'General', 1), + 'UPDATE_SECTION_IDS': (int, 'General', 1), 'VERIFY_SSL_CERT': (bool_int, 'Advanced', 1), 'VIDEO_LOGGING_ENABLE': (int, 'Monitoring', 1), 'XBMC_ENABLED': (int, 'XBMC', 0), diff --git a/plexpy/datafactory.py b/plexpy/datafactory.py index 2120c603..7194c0d6 100644 --- a/plexpy/datafactory.py +++ b/plexpy/datafactory.py @@ -98,12 +98,12 @@ class DataFactory(object): for item in history: filter_duration += int(item['duration']) - if item["media_type"] == 'episode' and item["parent_thumb"]: - thumb = item["parent_thumb"] - elif item["media_type"] == 'episode': - thumb = item["grandparent_thumb"] + if item['media_type'] == 'episode' and item['parent_thumb']: + thumb = item['parent_thumb'] + elif item['media_type'] == 'episode': + thumb = item['grandparent_thumb'] else: - thumb = item["thumb"] + thumb = item['thumb'] if item['percent_complete'] >= watched_percent: watched_status = 1 @@ -113,37 +113,37 @@ class DataFactory(object): watched_status = 0 # Rename Mystery platform names - platform = common.PLATFORM_NAME_OVERRIDES.get(item["platform"], item["platform"]) + platform = common.PLATFORM_NAME_OVERRIDES.get(item['platform'], item['platform']) - row = {"reference_id": item["reference_id"], - "id": item["id"], - "date": item["date"], - "started": item["started"], - "stopped": item["stopped"], - "duration": item["duration"], - "paused_counter": item["paused_counter"], - "user_id": item["user_id"], - "user": item["user"], - "friendly_name": item["friendly_name"], - "platform": platform, - "player": item['player'], - "ip_address": item["ip_address"], - "media_type": item["media_type"], - "rating_key": item["rating_key"], - "parent_rating_key": item["parent_rating_key"], - "grandparent_rating_key": item["grandparent_rating_key"], - "full_title": item["full_title"], - "parent_title": item["parent_title"], - "year": item["year"], - "media_index": item["media_index"], - "parent_media_index": item["parent_media_index"], - "thumb": thumb, - "video_decision": item["video_decision"], - "audio_decision": item["audio_decision"], - "percent_complete": int(round(item['percent_complete'])), - "watched_status": watched_status, - "group_count": item["group_count"], - "group_ids": item["group_ids"] + row = {'reference_id': item['reference_id'], + 'id': item['id'], + 'date': item['date'], + 'started': item['started'], + 'stopped': item['stopped'], + 'duration': item['duration'], + 'paused_counter': item['paused_counter'], + 'user_id': item['user_id'], + 'user': item['user'], + 'friendly_name': item['friendly_name'], + 'platform': platform, + 'player': item['player'], + 'ip_address': item['ip_address'], + 'media_type': item['media_type'], + 'rating_key': item['rating_key'], + 'parent_rating_key': item['parent_rating_key'], + 'grandparent_rating_key': item['grandparent_rating_key'], + 'full_title': item['full_title'], + 'parent_title': item['parent_title'], + 'year': item['year'], + 'media_index': item['media_index'], + 'parent_media_index': item['parent_media_index'], + 'thumb': thumb, + 'video_decision': item['video_decision'], + 'audio_decision': item['audio_decision'], + 'percent_complete': int(round(item['percent_complete'])), + 'watched_status': watched_status, + 'group_count': item['group_count'], + 'group_ids': item['group_ids'] } rows.append(row) @@ -154,7 +154,7 @@ class DataFactory(object): 'draw': query['draw'], 'filter_duration': helpers.human_duration(filter_duration, sig='dhm'), 'total_duration': helpers.human_duration(total_duration, sig='dhm') - } + } return dict @@ -736,7 +736,7 @@ class DataFactory(object): 'session_history_metadata.parent_title, session_history_metadata.grandparent_title, ' \ 'session_history_metadata.full_title, library_sections.section_name, ' \ 'session_history_metadata.media_index, session_history_metadata.parent_media_index, ' \ - 'session_history_metadata.library_id, session_history_metadata.thumb, ' \ + 'session_history_metadata.section_id, session_history_metadata.thumb, ' \ 'session_history_metadata.parent_thumb, session_history_metadata.grandparent_thumb, ' \ 'session_history_metadata.art, session_history_metadata.media_type, session_history_metadata.year, ' \ 'session_history_metadata.originally_available_at, session_history_metadata.added_at, ' \ @@ -746,7 +746,7 @@ class DataFactory(object): 'session_history_metadata.guid, session_history_metadata.directors, session_history_metadata.writers, ' \ 'session_history_metadata.actors, session_history_metadata.genres, session_history_metadata.studio ' \ 'FROM session_history_metadata ' \ - 'JOIN library_sections ON session_history_metadata.library_id = library_sections.section_id ' \ + 'JOIN library_sections ON session_history_metadata.section_id = library_sections.section_id ' \ 'WHERE session_history_metadata.rating_key = ?' result = monitor_db.select(query=query, args=[rating_key]) else: @@ -789,7 +789,7 @@ class DataFactory(object): 'genres': genres, 'actors': actors, 'library_name': item['section_name'], - 'library_id': item['library_id'] + 'section_id': item['section_id'] } return metadata @@ -1056,7 +1056,7 @@ class DataFactory(object): # Update the session_history_metadata table query = 'UPDATE session_history_metadata SET rating_key = ?, parent_rating_key = ?, ' \ 'grandparent_rating_key = ?, title = ?, parent_title = ?, grandparent_title = ?, full_title = ?, ' \ - 'media_index = ?, parent_media_index = ?, library_id = ?, thumb = ?, parent_thumb = ?, ' \ + 'media_index = ?, parent_media_index = ?, section_id = ?, thumb = ?, parent_thumb = ?, ' \ 'grandparent_thumb = ?, art = ?, media_type = ?, year = ?, originally_available_at = ?, ' \ 'added_at = ?, updated_at = ?, last_viewed_at = ?, content_rating = ?, summary = ?, ' \ 'tagline = ?, rating = ?, duration = ?, guid = ?, directors = ?, writers = ?, actors = ?, ' \ @@ -1065,7 +1065,7 @@ class DataFactory(object): args = [metadata['rating_key'], metadata['parent_rating_key'], metadata['grandparent_rating_key'], metadata['title'], metadata['parent_title'], metadata['grandparent_title'], full_title, - metadata['media_index'], metadata['parent_media_index'], metadata['library_id'], metadata['thumb'], + metadata['media_index'], metadata['parent_media_index'], metadata['section_id'], metadata['thumb'], metadata['parent_thumb'], metadata['grandparent_thumb'], metadata['art'], metadata['media_type'], metadata['year'], metadata['originally_available_at'], metadata['added_at'], metadata['updated_at'], metadata['last_viewed_at'], metadata['content_rating'], metadata['summary'], metadata['tagline'], @@ -1073,35 +1073,4 @@ class DataFactory(object): metadata['studio'], old_rating_key] - monitor_db.action(query=query, args=args) - - def update_library_ids(self): - from plexpy import pmsconnect - - pms_connect = pmsconnect.PmsConnect() - monitor_db = database.MonitorDatabase() - - try: - query = 'SELECT id, rating_key FROM session_history_metadata WHERE library_id IS NULL' - result = monitor_db.select(query=query) - except Exception as e: - logger.warn(u"PlexPy DataFactory :: Unable to execute database query for update_library_id: %s." % e) - return None - - for item in result: - id = item['id'] - rating_key = item['rating_key'] - - result = pms_connect.get_metadata_details(rating_key=rating_key) - - if result: - metadata = result['metadata'] - - section_keys = {'id': id} - section_values = {'library_id': metadata['library_id']} - - monitor_db.upsert('session_history_metadata', key_dict=section_keys, value_dict=section_values) - else: - continue - - return True \ No newline at end of file + monitor_db.action(query=query, args=args) \ No newline at end of file diff --git a/plexpy/datatables.py b/plexpy/datatables.py index 3cf8f0ca..6c0a9b98 100644 --- a/plexpy/datatables.py +++ b/plexpy/datatables.py @@ -124,8 +124,9 @@ class DataTables(object): order += ', ' + order = order.rstrip(', ') if order: - order = 'ORDER BY ' + order.rstrip(', ') + order = 'ORDER BY ' + order # Build where parameters if parameters['search']['value']: diff --git a/plexpy/libraries.py b/plexpy/libraries.py index ce19c689..9da3a68c 100644 --- a/plexpy/libraries.py +++ b/plexpy/libraries.py @@ -60,7 +60,7 @@ class Libraries(object): join_tables=['session_history_metadata', 'session_history', 'session_history_media_info'], - join_evals=[['session_history_metadata.library_id', 'library_sections.section_id'], + join_evals=[['session_history_metadata.section_id', 'library_sections.section_id'], ['session_history_metadata.id', 'session_history.id'], ['session_history_metadata.id', 'session_history_media_info.id']], kwargs=kwargs) @@ -116,10 +116,295 @@ class Libraries(object): 'recordsTotal': query['totalCount'], 'data': rows, 'draw': query['draw'] - } + } return dict + def get_datatables_media_info(self, section_id=None, kwargs=None): + data_tables = datatables.DataTables() + + custom_where = ['library_sections.section_id', section_id] + + columns = ['session_history.id', + 'session_history.started AS last_watched', + 'COUNT(DISTINCT session_history.reference_id) AS play_count', + 'session_history_metadata.rating_key', + 'session_history_metadata.parent_rating_key', + 'session_history_metadata.grandparent_rating_key', + 'session_history_metadata.full_title', + 'session_history_metadata.year', + 'session_history_metadata.media_index', + 'session_history_metadata.parent_media_index', + 'session_history_metadata.thumb', + 'session_history_metadata.parent_thumb', + 'session_history_metadata.grandparent_thumb', + 'session_history_metadata.media_type', + 'session_history_metadata.added_at', + '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.duration AS file_size' + ] + + try: + query = data_tables.ssp_query(table_name='session_history', + columns=columns, + custom_where=[custom_where], + group_by=['session_history_metadata.rating_key'], + join_types=['JOIN', + 'JOIN', + 'JOIN'], + join_tables=['library_sections', + 'session_history_metadata', + 'session_history_media_info'], + join_evals=[['session_history_metadata.section_id', 'library_sections.section_id'], + ['session_history.id', 'session_history_metadata.id'], + ['session_history.id', 'session_history_media_info.id']], + kwargs=kwargs) + except Exception as e: + logger.warn(u"PlexPy Libraries :: Unable to execute database query for get_datatables_media_info: %s." % e) + return {'recordsFiltered': 0, + 'recordsTotal': 0, + 'draw': 0, + 'data': 'null', + 'error': 'Unable to execute database query.'} + + results = query['result'] + + rows = [] + for item in results: + if item['media_type'] == 'episode' and item['parent_thumb']: + thumb = item['parent_thumb'] + elif item['media_type'] == 'episode': + thumb = item['grandparent_thumb'] + else: + thumb = item['thumb'] + + row = {'id': item['id'], + 'last_watched': item['last_watched'], + 'added_at': item['added_at'], + 'play_count': item['play_count'], + 'media_type': item['media_type'], + 'rating_key': item['rating_key'], + 'parent_rating_key': item['parent_rating_key'], + 'grandparent_rating_key': item['grandparent_rating_key'], + 'full_title': item['full_title'], + 'year': item['year'], + 'media_index': item['media_index'], + 'parent_media_index': item['parent_media_index'], + 'thumb': thumb, + 'container': item['container'], + 'bitrate': item['bitrate'], + 'video_codec': item['video_codec'], + 'video_resolution': item['video_resolution'], + 'video_framerate': item['video_framerate'], + 'audio_codec': item['audio_codec'], + 'audio_channels': item['audio_channels'], + 'file_size': item['file_size'] + } + + rows.append(row) + + dict = {'recordsFiltered': query['filteredCount'], + 'recordsTotal': query['totalCount'], + 'data': rows, + 'draw': query['draw'] + } + + return dict + + def get_datatables_media_info2(self, section_id=None, section_type=None, rating_key=None, kwargs=None): + from plexpy import pmsconnect + import json, os + + default_return = {'recordsFiltered': 0, + 'recordsTotal': 0, + 'draw': 0, + 'data': None, + 'error': 'Unable to execute database query.'} + + if section_id and not str(section_id).isdigit(): + logger.warn(u"PlexPy Libraries :: Datatable media info called by invalid section_id provided.") + return default_return + elif rating_key and not str(rating_key).isdigit(): + logger.warn(u"PlexPy Libraries :: Datatable media info called by invalid rating_key provided.") + return default_return + + rows = [] + if rating_key: + try: + inFilePath = os.path.join(plexpy.CONFIG.CACHE_DIR,'media_info-%s_%s.json' % (section_id, rating_key)) + with open(inFilePath, 'r') as inFile: + rows = json.load(inFile) + library_count = len(rows) + except IOError as e: + logger.debug(u"PlexPy Libraries :: No JSON file for rating_key %s." % rating_key) + logger.debug(u"PlexPy Libraries :: Refreshing data and creating new JSON file for rating_key %s." % rating_key) + elif section_id: + try: + inFilePath = os.path.join(plexpy.CONFIG.CACHE_DIR,'media_info-%s.json' % section_id) + with open(inFilePath, 'r') as inFile: + rows = json.load(inFile) + library_count = len(rows) + except IOError as e: + logger.debug(u"PlexPy Libraries :: No JSON file for library section_id %s." % section_id) + logger.debug(u"PlexPy Libraries :: Refreshing data and creating new JSON file for section_id %s." % section_id) + + if not rows: + # Get the library details + library_details = self.get_details(section_id=section_id) + if library_details['section_id'] == None: + logger.warn(u"PlexPy Libraries :: Library section_id %s not found." % section_id) + return default_return + + if not section_type: + section_type = library_details['section_type'] + + # Get play counts from the database + monitor_db = database.MonitorDatabase() + + if section_type == 'show' or section_type == 'artist': + group_by = 'grandparent_rating_key' + elif section_type == 'season' or section_type == 'album': + group_by = 'parent_rating_key' + else: + group_by = 'rating_key' + + try: + query = 'SELECT MAX(session_history.started) AS last_watched, COUNT(session_history.id) AS play_count, ' \ + 'session_history.rating_key, session_history.parent_rating_key, session_history.grandparent_rating_key ' \ + 'FROM session_history ' \ + 'JOIN session_history_metadata ON session_history.id = session_history_metadata.id ' \ + 'WHERE session_history_metadata.section_id = ? ' \ + 'GROUP BY session_history.%s ' % group_by + result = monitor_db.select(query, args=[section_id]) + except Exception as e: + logger.warn(u"PlexPy Libraries :: Unable to execute database query for get_datatables_media_info2: %s." % e) + return default_return + + watched_list = {} + for item in result: + watched_list[str(item[group_by])] = {'last_watched': item['last_watched'], + 'play_count': item['play_count']} + + # Get all library children items + pms_connect = pmsconnect.PmsConnect() + + + if rating_key: + library_children = pms_connect.get_library_children(rating_key=rating_key, + get_media_info=True) + elif section_id: + library_children = pms_connect.get_library_children(section_id=section_id, + section_type=section_type, + get_media_info=True) + + if library_children: + library_count = library_children['library_count'] + children_list = library_children['childern_list'] + else: + logger.warn(u"PlexPy Libraries :: Unable to get a list of library items.") + return default_return + + rows = [] + for item in children_list: + thumb = item['thumb'] + + if item['media_type'] == 'episode' or item['media_type'] == 'track': + full_title = 'E%s - %s' % (item['media_index'], item['title']) + else: + full_title = item['title'] + + watched_item = watched_list.get(item['rating_key'], None) + if watched_item: + last_watched = watched_item['last_watched'] + play_count = watched_item['play_count'] + else: + last_watched = None + play_count = None + + row = {'section_id': library_details['section_id'], + 'section_type': library_details['section_type'], + 'last_watched': last_watched, + 'added_at': item['added_at'], + 'media_type': item['media_type'], + 'rating_key': item['rating_key'], + 'parent_rating_key': item['parent_rating_key'], + 'grandparent_rating_key': item['grandparent_rating_key'], + 'full_title': full_title, + 'title': item['title'], + 'year': item['year'], + 'media_index': item['media_index'], + 'parent_media_index': item['parent_media_index'], + 'thumb': thumb, + 'container': item.get('container', ''), + 'bitrate': item.get('bitrate', ''), + 'video_codec': item.get('video_codec', ''), + 'video_resolution': item.get('video_resolution', ''), + 'video_framerate': item.get('video_framerate', ''), + 'audio_codec': item.get('audio_codec', ''), + 'audio_channels': item.get('audio_channels', ''), + 'file_size': item.get('file_size', ''), + 'play_count': play_count + } + rows.append(row) + + if rating_key: + outFilePath = os.path.join(plexpy.CONFIG.CACHE_DIR,'media_info-%s_%s.json' % (section_id, rating_key)) + with open(outFilePath, 'w') as outFile: + json.dump(rows, outFile) + elif section_id: + outFilePath = os.path.join(plexpy.CONFIG.CACHE_DIR,'media_info-%s.json' % section_id) + with open(outFilePath, 'w') as outFile: + json.dump(rows, outFile) + + results = [] + + # Get datatables JSON data + if kwargs.get('json_data'): + json_data = helpers.process_json_kwargs(json_kwargs=kwargs.get('json_data')) + #print json_data + + # Search results + search_value = json_data['search']['value'].lower() + if search_value: + searchable_columns = [d['data'] for d in json_data['columns'] if d['searchable']] + for row in rows: + for k,v in row.iteritems(): + if k in searchable_columns and search_value in v.lower(): + results.append(row) + break + else: + results = rows + + filtered_count = len(results) + + # Sort results + sort_order = json_data['order'] + for order in reversed(sort_order): + sort_key = json_data['columns'][int(order['column'])]['data'] + reverse = True if order['dir'] == 'desc' else False + if rating_key and sort_key == 'title': + results = sorted(results, key=lambda k: int(k['media_index']), reverse=reverse) + else: + results = sorted(results, key=lambda k: k[sort_key], reverse=reverse) + + # Paginate results + results = results[json_data['start']:(json_data['start'] + json_data['length'])] + + dict = {'recordsFiltered': filtered_count, + 'recordsTotal': library_count, + 'data': results, + 'draw': int(json_data['draw']) + } + + ## Add total disk space used + return dict + def set_config(self, section_id=None, custom_thumb='', do_notify=1, keep_history=1, do_notify_created=1): if section_id: monitor_db = database.MonitorDatabase() @@ -234,7 +519,7 @@ class Libraries(object): 'keep_history': 0 } - def get_watch_time_stats(self, library_id=None): + def get_watch_time_stats(self, section_id=None): monitor_db = database.MonitorDatabase() time_queries = [1, 7, 30, 0] @@ -243,26 +528,26 @@ class Libraries(object): for days in time_queries: try: if days > 0: - if str(library_id).isdigit(): + if str(section_id).isdigit(): query = 'SELECT (SUM(stopped - started) - ' \ 'SUM(CASE WHEN paused_counter is null THEN 0 ELSE paused_counter END)) as total_time, ' \ 'COUNT(session_history.id) AS total_plays ' \ 'FROM session_history ' \ 'JOIN session_history_metadata ON session_history_metadata.id = session_history.id ' \ 'WHERE datetime(stopped, "unixepoch", "localtime") >= datetime("now", "-%s days", "localtime") ' \ - 'AND library_id = ?' % days - result = monitor_db.select(query, args=[library_id]) + 'AND section_id = ?' % days + result = monitor_db.select(query, args=[section_id]) else: result = [] else: - if str(library_id).isdigit(): + if str(section_id).isdigit(): query = 'SELECT (SUM(stopped - started) - ' \ 'SUM(CASE WHEN paused_counter is null THEN 0 ELSE paused_counter END)) as total_time, ' \ 'COUNT(session_history.id) AS total_plays ' \ 'FROM session_history ' \ 'JOIN session_history_metadata ON session_history_metadata.id = session_history.id ' \ - 'WHERE library_id = ?' - result = monitor_db.select(query, args=[library_id]) + 'WHERE section_id = ?' + result = monitor_db.select(query, args=[section_id]) else: result = [] except Exception as e: @@ -286,22 +571,22 @@ class Libraries(object): return library_watch_time_stats - def get_user_stats(self, library_id=None): + def get_user_stats(self, section_id=None): monitor_db = database.MonitorDatabase() user_stats = [] try: - if str(library_id).isdigit(): + if str(section_id).isdigit(): query = 'SELECT (CASE WHEN users.friendly_name IS NULL THEN users.username ' \ 'ELSE users.friendly_name END) AS user, users.user_id, users.thumb, COUNT(user) AS user_count ' \ 'FROM session_history ' \ 'JOIN session_history_metadata ON session_history_metadata.id = session_history.id ' \ 'JOIN users ON users.user_id = session_history.user_id ' \ - 'WHERE library_id = ? ' \ + 'WHERE section_id = ? ' \ 'GROUP BY user ' \ 'ORDER BY user_count DESC' - result = monitor_db.select(query, args=[library_id]) + result = monitor_db.select(query, args=[section_id]) else: result = [] except Exception as e: @@ -318,7 +603,7 @@ class Libraries(object): return user_stats - def get_recently_watched(self, library_id=None, limit='10'): + def get_recently_watched(self, section_id=None, limit='10'): monitor_db = database.MonitorDatabase() recently_watched = [] @@ -326,17 +611,17 @@ class Libraries(object): limit = '10' try: - if str(library_id).isdigit(): + if str(section_id).isdigit(): query = 'SELECT session_history.id, session_history.media_type, session_history.rating_key, session_history.parent_rating_key, ' \ 'title, parent_title, grandparent_title, thumb, parent_thumb, grandparent_thumb, media_index, parent_media_index, ' \ 'year, started, user ' \ 'FROM session_history_metadata ' \ 'JOIN session_history ON session_history_metadata.id = session_history.id ' \ - 'WHERE library_id = ? ' \ + 'WHERE section_id = ? ' \ 'GROUP BY (CASE WHEN session_history.media_type = "track" THEN session_history.parent_rating_key ' \ ' ELSE session_history.rating_key END) ' \ 'ORDER BY started DESC LIMIT ?' - result = monitor_db.select(query, args=[library_id, limit]) + result = monitor_db.select(query, args=[section_id, limit]) else: result = [] except Exception as e: @@ -399,18 +684,18 @@ class Libraries(object): 'WHERE session_history_media_info.id IN (SELECT session_history_media_info.id ' 'FROM session_history_media_info ' 'JOIN session_history_metadata ON session_history_media_info.id = session_history_metadata.id ' - 'WHERE session_history_metadata.library_id = ?)', [section_id]) + 'WHERE session_history_metadata.section_id = ?)', [section_id]) session_history_del = \ monitor_db.action('DELETE FROM ' 'session_history ' 'WHERE session_history.id IN (SELECT session_history.id ' 'FROM session_history ' 'JOIN session_history_metadata ON session_history.id = session_history_metadata.id ' - 'WHERE session_history_metadata.library_id = ?)', [section_id]) + 'WHERE session_history_metadata.section_id = ?)', [section_id]) session_history_metadata_del = \ monitor_db.action('DELETE FROM ' 'session_history_metadata ' - 'WHERE session_history_metadata.library_id = ?', [section_id]) + 'WHERE session_history_metadata.section_id = ?', [section_id]) return 'Deleted all items for section_id %s.' % section_id else: @@ -465,4 +750,50 @@ class Libraries(object): else: return 'Unable to re-add library, section_id or section_name not valid.' except Exception as e: - logger.warn(u"PlexPy Libraries :: Unable to execute database query for undelete: %s." % e) \ No newline at end of file + logger.warn(u"PlexPy Libraries :: Unable to execute database query for undelete: %s." % e) + + def update_section_ids(self): + from plexpy import pmsconnect + + pms_connect = pmsconnect.PmsConnect() + monitor_db = database.MonitorDatabase() + + try: + query = 'SELECT id, rating_key FROM session_history_metadata WHERE section_id IS NULL' + result = monitor_db.select(query=query) + except Exception as e: + logger.warn(u"PlexPy Libraries :: Unable to execute database query for update_section_ids: %s." % e) + return None + + for item in result: + id = item['id'] + rating_key = item['rating_key'] + + result = pms_connect.get_metadata_details(rating_key=rating_key) + + if result: + metadata = result['metadata'] + + section_keys = {'id': id} + section_values = {'section_id': metadata['section_id']} + + monitor_db.upsert('session_history_metadata', key_dict=section_keys, value_dict=section_values) + else: + continue + + return True + + def delete_datatable_media_info_cache(self, section_id=None): + import os + + try: + if section_id.isdigit(): + [os.remove(os.path.join(plexpy.CONFIG.CACHE_DIR, f)) for f in os.listdir(plexpy.CONFIG.CACHE_DIR) + if f.startswith('media_info-%s' % section_id) and f.endswith('.json')] + + logger.debug(u"PlexPy Libraries :: Deleted media info table cache for section_id %s." % section_id) + return 'Deleted media info table cache for library with id %s.' % section_id + else: + return 'Unable to delete media info table cache, section_id not valid.' + except Exception as e: + logger.warn(u"PlexPy Libraries :: Unable to delete media info table cache: %s." % e) \ No newline at end of file diff --git a/plexpy/notification_handler.py b/plexpy/notification_handler.py index 5c54b430..173069ea 100644 --- a/plexpy/notification_handler.py +++ b/plexpy/notification_handler.py @@ -31,7 +31,7 @@ def notify(stream_data=None, notify_action=None): user_details = user_data.get_details(user_id=stream_data['user_id']) library_data = libraries.Libraries() - library_details = library_data.get_details(section_id=stream_data['library_id']) + library_details = library_data.get_details(section_id=stream_data['section_id']) if not user_details['do_notify']: # logger.debug(u"PlexPy NotificationHandler :: Notifications for user '%s' is disabled." % user_details['username']) diff --git a/plexpy/plexwatch_import.py b/plexpy/plexwatch_import.py index 6959a559..533b5bdc 100644 --- a/plexpy/plexwatch_import.py +++ b/plexpy/plexwatch_import.py @@ -41,7 +41,7 @@ def extract_plexwatch_xml(xml=None): grandparent_thumb = helpers.get_xml_attr(a, 'grandparentThumb') grandparent_title = helpers.get_xml_attr(a, 'grandparentTitle') guid = helpers.get_xml_attr(a, 'guid') - library_id = helpers.get_xml_attr(a, 'librarySectionID') + section_id = helpers.get_xml_attr(a, 'librarySectionID') media_index = helpers.get_xml_attr(a, 'index') originally_available_at = helpers.get_xml_attr(a, 'originallyAvailableAt') last_viewed_at = helpers.get_xml_attr(a, 'lastViewedAt') @@ -157,7 +157,7 @@ def extract_plexwatch_xml(xml=None): 'title': title, 'tagline': tagline, 'guid': guid, - 'library_id': library_id, + 'section_id': section_id, 'media_index': media_index, 'originally_available_at': originally_available_at, 'last_viewed_at': last_viewed_at, @@ -251,6 +251,8 @@ def import_from_plexwatch(database=None, table_name=None, import_ignore_interval 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) + plexpy.schedule_job(activity_pinger.check_server_response, 'Check for server response', + hours=0, minutes=0, seconds=0) ap = activity_processor.ActivityProcessor() user_data = users.Users() @@ -372,7 +374,7 @@ def import_from_plexwatch(database=None, table_name=None, import_ignore_interval 'rating': extracted_xml['rating'], 'duration': extracted_xml['duration'], 'guid': extracted_xml['guid'], - 'library_id': extracted_xml['library_id'], + 'section_id': extracted_xml['section_id'], 'directors': extracted_xml['directors'], 'writers': extracted_xml['writers'], 'actors': extracted_xml['actors'], diff --git a/plexpy/pmsconnect.py b/plexpy/pmsconnect.py index 2af6ece0..c0320a08 100644 --- a/plexpy/pmsconnect.py +++ b/plexpy/pmsconnect.py @@ -44,11 +44,6 @@ def refresh_libraries(): server_id = plexpy.CONFIG.PMS_IDENTIFIER - if plexpy.CONFIG.HOME_LIBRARY_CARDS == ['first_run']: - populate_cards = True - else: - populate_cards = False - library_keys = [] if library_sections: @@ -56,11 +51,11 @@ def refresh_libraries(): for section in library_sections: section_keys = {'server_id': server_id, - 'section_id': section['key']} + 'section_id': section['section_id']} section_values = {'server_id': server_id, - 'section_id': section['key'], - 'section_name': section['title'], - 'section_type': section['type'], + 'section_id': section['section_id'], + 'section_name': section['section_name'], + 'section_type': section['section_type'], 'thumb': section['thumb'], 'art': section['art'], 'count': section['count'], @@ -70,13 +65,42 @@ def refresh_libraries(): monitor_db.upsert('library_sections', key_dict=section_keys, value_dict=section_values) - library_keys.append(section['key']) + library_keys.append(section['section_id']) - if populate_cards: + if plexpy.CONFIG.HOME_LIBRARY_CARDS == ['first_run']: plexpy.CONFIG.__setattr__('HOME_LIBRARY_CARDS', library_keys) plexpy.CONFIG.write() - + + if plexpy.CONFIG.UPDATE_SECTION_IDS == 1: + from plexpy import libraries + + plexpy.CONFIG.UPDATE_SECTION_IDS = -1 + + logger.info(u"PlexPy Pmsconnect :: Updating section_id's in database.") + + logger.debug(u"PlexPy Pmsconnect :: Disabling monitoring while update 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) + plexpy.schedule_job(activity_pinger.check_server_response, 'Check for server response', + hours=0, minutes=0, seconds=0) + + result = libraries.Libraries().update_section_ids() + + if result: + logger.debug(u"PlexPy Pmsconnect :: Updated all section_id's in database.") + plexpy.CONFIG.__setattr__('UPDATE_SECTION_IDS', 0) + plexpy.CONFIG.write() + else: + logger.debug(u"PlexPy Pmsconnect :: Unable to update section_id's in database.") + plexpy.CONFIG.__setattr__('UPDATE_SECTION_IDS', 1) + plexpy.CONFIG.write() + + logger.debug(u"PlexPy Pmsconnect :: Re-enabling monitoring.") + plexpy.initialize_scheduler() + logger.info(u"PlexPy Pmsconnect :: Libraries list refreshed.") else: logger.warn(u"PlexPy Pmsconnect :: Unable to refresh libraries list.") @@ -169,7 +193,7 @@ class PmsConnect(object): return request - def get_library_recently_added(self, section_key='', count='0', output_format=''): + def get_library_recently_added(self, section_id='', count='0', output_format=''): """ Return list of recently added items. @@ -178,7 +202,7 @@ class PmsConnect(object): Output: array """ - uri = '/library/sections/' + section_key + '/recentlyAdded?X-Plex-Container-Start=0&X-Plex-Container-Size=' + count + uri = '/library/sections/' + section_id + '/recentlyAdded?X-Plex-Container-Start=0&X-Plex-Container-Size=' + count request = self.request_handler.make_request(uri=uri, proto=self.protocol, request_type='GET', @@ -203,6 +227,23 @@ class PmsConnect(object): return request + def get_childrens_list(self, rating_key='', output_format=''): + """ + Return list of children in requested library item. + + Parameters required: rating_key { ratingKey of parent } + Optional parameters: output_format { dict, json } + + Output: array + """ + uri = '/library/metadata/' + rating_key + '/allLeaves' + request = self.request_handler.make_request(uri=uri, + proto=self.protocol, + request_type='GET', + output_format=output_format) + + return request + def get_server_list(self, output_format=''): """ Return list of local servers. @@ -267,7 +308,7 @@ class PmsConnect(object): return request - def get_library_list(self, section_key='', list_type='all', count='0', sort_type='', output_format=''): + def get_library_list(self, section_id='', list_type='all', count='0', sort_type='', output_format=''): """ Return list of items in library on server. @@ -275,7 +316,9 @@ class PmsConnect(object): Output: array """ - uri = '/library/sections/' + section_key + '/' + list_type +'?X-Plex-Container-Start=0&X-Plex-Container-Size=' + count + sort_type + count = '&X-Plex-Container-Size=' + count if count else '' + + uri = '/library/sections/' + section_id + '/' + list_type +'?X-Plex-Container-Start=0' + count + sort_type request = self.request_handler.make_request(uri=uri, proto=self.protocol, request_type='GET', @@ -363,7 +406,7 @@ class PmsConnect(object): return request - def get_recently_added_details(self, library_id='', count='0'): + def get_recently_added_details(self, section_id='', count='0'): """ Return processed and validated list of recently added items. @@ -371,8 +414,8 @@ class PmsConnect(object): Output: array """ - if library_id: - recent = self.get_library_recently_added(library_id, count, output_format='xml') + if section_id: + recent = self.get_library_recently_added(section_id, count, output_format='xml') else: recent = self.get_recently_added(count, output_format='xml') @@ -402,7 +445,7 @@ class PmsConnect(object): 'grandparent_title': helpers.get_xml_attr(item, 'grandparentTitle'), 'media_index': helpers.get_xml_attr(item, 'index'), 'parent_media_index': helpers.get_xml_attr(item, 'parentIndex'), - 'library_id': helpers.get_xml_attr(item, 'librarySectionID'), + 'section_id': helpers.get_xml_attr(item, 'librarySectionID'), 'library_name': helpers.get_xml_attr(item, 'librarySectionTitle'), 'year': helpers.get_xml_attr(item, 'year'), 'thumb': helpers.get_xml_attr(item, 'thumb'), @@ -424,7 +467,7 @@ class PmsConnect(object): 'grandparent_title': helpers.get_xml_attr(item, 'grandparentTitle'), 'media_index': helpers.get_xml_attr(item, 'index'), 'parent_media_index': helpers.get_xml_attr(item, 'parentIndex'), - 'library_id': helpers.get_xml_attr(item, 'librarySectionID'), + 'section_id': helpers.get_xml_attr(item, 'librarySectionID'), 'library_name': helpers.get_xml_attr(item, 'librarySectionTitle'), 'year': helpers.get_xml_attr(item, 'year'), 'thumb': helpers.get_xml_attr(item, 'thumb'), @@ -450,7 +493,7 @@ class PmsConnect(object): try: xml_head = metadata.getElementsByTagName('MediaContainer') except Exception as e: - logger.warn(u"PlexPy Pmsconnect :: Unable to parse XML for get_metadata: %s: %s." % e) + logger.warn(u"PlexPy Pmsconnect :: Unable to parse XML for get_metadata: %s." % e) return [] metadata_list = [] @@ -474,7 +517,7 @@ class PmsConnect(object): logger.debug(u"PlexPy Pmsconnect :: Metadata failed") return None - library_id = helpers.get_xml_attr(a, 'librarySectionID') + section_id = helpers.get_xml_attr(a, 'librarySectionID') library_name = helpers.get_xml_attr(a, 'librarySectionTitle') genres = [] @@ -500,7 +543,7 @@ class PmsConnect(object): if metadata_type == 'movie': metadata = {'media_type': metadata_type, - 'library_id': library_id, + 'section_id': section_id, 'library_name': library_name, 'rating_key': helpers.get_xml_attr(metadata_main, 'ratingKey'), 'parent_rating_key': helpers.get_xml_attr(metadata_main, 'parentRatingKey'), @@ -535,7 +578,7 @@ class PmsConnect(object): elif metadata_type == 'show': metadata = {'media_type': metadata_type, - 'library_id': library_id, + 'section_id': section_id, 'library_name': library_name, 'rating_key': helpers.get_xml_attr(metadata_main, 'ratingKey'), 'parent_rating_key': helpers.get_xml_attr(metadata_main, 'parentRatingKey'), @@ -572,7 +615,7 @@ class PmsConnect(object): parent_rating_key = helpers.get_xml_attr(metadata_main, 'parentRatingKey') show_details = self.get_metadata_details(parent_rating_key) metadata = {'media_type': metadata_type, - 'library_id': library_id, + 'section_id': section_id, 'library_name': library_name, 'rating_key': helpers.get_xml_attr(metadata_main, 'ratingKey'), 'parent_rating_key': helpers.get_xml_attr(metadata_main, 'parentRatingKey'), @@ -609,7 +652,7 @@ class PmsConnect(object): grandparent_rating_key = helpers.get_xml_attr(metadata_main, 'grandparentRatingKey') show_details = self.get_metadata_details(grandparent_rating_key) metadata = {'media_type': metadata_type, - 'library_id': library_id, + 'section_id': section_id, 'library_name': library_name, 'rating_key': helpers.get_xml_attr(metadata_main, 'ratingKey'), 'parent_rating_key': helpers.get_xml_attr(metadata_main, 'parentRatingKey'), @@ -644,7 +687,7 @@ class PmsConnect(object): elif metadata_type == 'artist': metadata = {'media_type': metadata_type, - 'library_id': library_id, + 'section_id': section_id, 'library_name': library_name, 'rating_key': helpers.get_xml_attr(metadata_main, 'ratingKey'), 'parent_rating_key': helpers.get_xml_attr(metadata_main, 'parentRatingKey'), @@ -681,7 +724,7 @@ class PmsConnect(object): parent_rating_key = helpers.get_xml_attr(metadata_main, 'parentRatingKey') artist_details = self.get_metadata_details(parent_rating_key) metadata = {'media_type': metadata_type, - 'library_id': library_id, + 'section_id': section_id, 'library_name': library_name, 'rating_key': helpers.get_xml_attr(metadata_main, 'ratingKey'), 'parent_rating_key': helpers.get_xml_attr(metadata_main, 'parentRatingKey'), @@ -718,7 +761,7 @@ class PmsConnect(object): parent_rating_key = helpers.get_xml_attr(metadata_main, 'parentRatingKey') album_details = self.get_metadata_details(parent_rating_key) metadata = {'media_type': metadata_type, - 'library_id': library_id, + 'section_id': section_id, 'library_name': library_name, 'rating_key': helpers.get_xml_attr(metadata_main, 'ratingKey'), 'parent_rating_key': helpers.get_xml_attr(metadata_main, 'parentRatingKey'), @@ -798,11 +841,11 @@ class PmsConnect(object): output = {'metadata': metadata_list} return output - def get_library_metadata_details(self, library_id=''): + def get_library_metadata_details(self, section_id=''): """ Return processed and validated metadata list for requested library. - Parameters required: library_id { Plex library key } + Parameters required: section_id { Plex library key } Output: array """ @@ -826,9 +869,9 @@ class PmsConnect(object): result_data = a.getElementsByTagName('Directory') for result in result_data: key = helpers.get_xml_attr(result, 'key') - if key == library_id: + if key == section_id: metadata = {'media_type': 'library', - 'library_id': helpers.get_xml_attr(result, 'key'), + 'section_id': helpers.get_xml_attr(result, 'key'), 'library': helpers.get_xml_attr(result, 'type'), 'title': helpers.get_xml_attr(result, 'title'), 'art': helpers.get_xml_attr(result, 'art'), @@ -945,7 +988,7 @@ class PmsConnect(object): machine_id = helpers.get_xml_attr(session.getElementsByTagName('Player')[0], 'machineIdentifier') session_output = {'session_key': helpers.get_xml_attr(session, 'sessionKey'), - 'library_id': helpers.get_xml_attr(session, 'librarySectionID'), + 'section_id': helpers.get_xml_attr(session, 'librarySectionID'), 'media_index': helpers.get_xml_attr(session, 'index'), 'parent_media_index': helpers.get_xml_attr(session, 'parentIndex'), 'art': helpers.get_xml_attr(session, 'art'), @@ -1067,7 +1110,7 @@ class PmsConnect(object): if helpers.get_xml_attr(session, 'type') == 'episode': session_output = {'session_key': helpers.get_xml_attr(session, 'sessionKey'), - 'library_id': helpers.get_xml_attr(session, 'librarySectionID'), + 'section_id': helpers.get_xml_attr(session, 'librarySectionID'), 'media_index': helpers.get_xml_attr(session, 'index'), 'parent_media_index': helpers.get_xml_attr(session, 'parentIndex'), 'art': helpers.get_xml_attr(session, 'art'), @@ -1125,7 +1168,7 @@ class PmsConnect(object): elif helpers.get_xml_attr(session, 'type') == 'movie': session_output = {'session_key': helpers.get_xml_attr(session, 'sessionKey'), - 'library_id': helpers.get_xml_attr(session, 'librarySectionID'), + 'section_id': helpers.get_xml_attr(session, 'librarySectionID'), 'media_index': helpers.get_xml_attr(session, 'index'), 'parent_media_index': helpers.get_xml_attr(session, 'parentIndex'), 'art': helpers.get_xml_attr(session, 'art'), @@ -1183,7 +1226,7 @@ class PmsConnect(object): elif helpers.get_xml_attr(session, 'type') == 'clip': session_output = {'session_key': helpers.get_xml_attr(session, 'sessionKey'), - 'library_id': helpers.get_xml_attr(session, 'librarySectionID'), + 'section_id': helpers.get_xml_attr(session, 'librarySectionID'), 'media_index': helpers.get_xml_attr(session, 'index'), 'parent_media_index': helpers.get_xml_attr(session, 'parentIndex'), 'art': helpers.get_xml_attr(session, 'art'), @@ -1274,7 +1317,7 @@ class PmsConnect(object): machine_id = helpers.get_xml_attr(session.getElementsByTagName('Player')[0], 'machineIdentifier') session_output = {'session_key': helpers.get_xml_attr(session, 'sessionKey'), - 'library_id': helpers.get_xml_attr(session, 'librarySectionID'), + 'section_id': helpers.get_xml_attr(session, 'librarySectionID'), 'media_index': helpers.get_xml_attr(session, 'index'), 'parent_media_index': helpers.get_xml_attr(session, 'parentIndex'), 'art': helpers.get_xml_attr(session, 'art'), @@ -1494,9 +1537,9 @@ class PmsConnect(object): if a.getElementsByTagName('Directory'): result_data = a.getElementsByTagName('Directory') for result in result_data: - libraries_output = {'key': helpers.get_xml_attr(result, 'key'), - 'type': helpers.get_xml_attr(result, 'type'), - 'title': helpers.get_xml_attr(result, 'title'), + libraries_output = {'section_id': helpers.get_xml_attr(result, 'key'), + 'section_type': helpers.get_xml_attr(result, 'type'), + 'section_name': helpers.get_xml_attr(result, 'title'), 'thumb': helpers.get_xml_attr(result, 'thumb'), 'art': helpers.get_xml_attr(result, 'art') } @@ -1509,71 +1552,123 @@ class PmsConnect(object): return output - def get_library_children(self, library_type='', section_key='', list_type='all', count='1', sort_type = ''): + def get_library_children(self, section_id='', section_type='', list_type='all', count='', rating_key='', get_media_info=False): """ Return processed and validated server library items list. - Parameters required: library_type { movie, show, episode, artist } - section_key { unique library key } + Parameters required: section_type { movie, show, episode, artist } + section_id { unique library key } Output: array """ - if library_type == 'movie': + if section_type == 'movie': sort_type = '&type=1' - elif library_type == 'show': + elif section_type == 'show': sort_type = '&type=2' - elif library_type == 'season': + elif section_type == 'season': sort_type = '&type=3' - elif library_type == 'episode': + elif section_type == 'episode': sort_type = '&type=4' - elif library_type == 'artist': + elif section_type == 'artist': sort_type = '&type=8' - elif library_type == 'album': + elif section_type == 'album': sort_type = '&type=9' - elif library_type == 'track': + elif section_type == 'track': sort_type = '&type=10' - elif library_type == 'photo': + elif section_type == 'photo': sort_type = '' - elif library_type == 'photoAlbum': + elif section_type == 'photoAlbum': sort_type = '&type=14' - elif library_type == 'picture': + elif section_type == 'picture': sort_type = '&type=13' + else: + sort_type = '' + + if str(section_id).isdigit(): + library_data = self.get_library_list(section_id, list_type, count, sort_type, output_format='xml') + elif str(rating_key).isdigit(): + library_data = self.get_children_list(rating_key, output_format='xml') + else: + logger.warn(u"PlexPy Pmsconnect :: get_library_children called by invalid section_id or rating_key provided.") + return [] - library_data = self.get_library_list(section_key, list_type, count, sort_type, output_format='xml') - try: xml_head = library_data.getElementsByTagName('MediaContainer') except Exception as e: logger.warn(u"PlexPy Pmsconnect :: Unable to parse XML for get_library_children: %s." % e) return [] - library_list = [] + childern_list = [] for a in xml_head: if a.getAttribute('size'): if a.getAttribute('size') == '0': logger.debug(u"PlexPy Pmsconnect :: No library data.") - library_list = {'library_count': '0', - 'library_list': [] + childern_list = {'library_count': '0', + 'childern_list': [] } - return library_list + return childern_list + + if rating_key: + library_count = helpers.get_xml_attr(xml_head[0], 'size') + else: + library_count = helpers.get_xml_attr(xml_head[0], 'totalSize') + + # Get show/season info from xml_head if a.getElementsByTagName('Directory'): - result_data = a.getElementsByTagName('Directory') - for result in result_data: - library_output = {'key': helpers.get_xml_attr(result, 'key'), - 'type': helpers.get_xml_attr(result, 'type'), - 'title': helpers.get_xml_attr(result, 'title'), - 'thumb': helpers.get_xml_attr(result, 'thumb') + item_main = a.getElementsByTagName('Directory') + item_main = [d for d in item_main if helpers.get_xml_attr(d, 'ratingKey')] + elif a.getElementsByTagName('Video'): + item_main = a.getElementsByTagName('Video') + elif a.getElementsByTagName('Track'): + item_main = a.getElementsByTagName('Track') + elif a.getElementsByTagName('Photo'): + item_main = a.getElementsByTagName('Photo') + else: + item_main = [] + + for item in item_main: + item_info = {'section_id': helpers.get_xml_attr(item, 'key'), + 'section_type': helpers.get_xml_attr(item, 'type'), + 'media_type': helpers.get_xml_attr(item, 'type'), + 'rating_key': helpers.get_xml_attr(item, 'ratingKey'), + 'parent_rating_key': helpers.get_xml_attr(item, 'parentRatingKey'), + 'grandparent_rating_key': helpers.get_xml_attr(item, 'grandparentRatingKey'), + 'title': helpers.get_xml_attr(item, 'title'), + 'parent_title': helpers.get_xml_attr(item, 'parentTitle'), + 'grandparent_title': helpers.get_xml_attr(item, 'grandparentTitle'), + 'media_index': helpers.get_xml_attr(item, 'index'), + 'parent_media_index': helpers.get_xml_attr(item, 'parentIndex'), + 'year': helpers.get_xml_attr(item, 'year'), + 'thumb': helpers.get_xml_attr(item, 'thumb'), + 'parent_thumb': helpers.get_xml_attr(item, 'parentThumb'), + 'grandparent_thumb': helpers.get_xml_attr(item, 'grandparentThumb'), + 'added_at': helpers.get_xml_attr(item, 'addedAt') + } + + if get_media_info: + item_media = item.getElementsByTagName('Media') + for media in item_media: + media_info = {'container': helpers.get_xml_attr(media, 'container'), + 'bitrate': helpers.get_xml_attr(media, 'bitrate'), + 'video_codec': helpers.get_xml_attr(media, 'videoCodec'), + 'video_resolution': helpers.get_xml_attr(media, 'videoResolution'), + 'video_framerate': helpers.get_xml_attr(media, 'videoFrameRate'), + 'audio_codec': helpers.get_xml_attr(media, 'audioCodec'), + 'audio_channels': helpers.get_xml_attr(media, 'audioChannels'), + 'file': helpers.get_xml_attr(media.getElementsByTagName('Part')[0], 'file'), + 'file_size': helpers.get_xml_attr(media.getElementsByTagName('Part')[0], 'size'), } - library_list.append(library_output) + item_info.update(media_info) - output = {'library_count': helpers.get_xml_attr(xml_head[0], 'totalSize'), - 'count_type': helpers.get_xml_attr(xml_head[0], 'title2'), - 'library_list': library_list + childern_list.append(item_info) + + output = {'library_count': library_count, + 'childern_list': childern_list } - + return output def get_library_details(self): @@ -1590,57 +1685,44 @@ class PmsConnect(object): libraries_list = server_libraries['libraries_list'] for library in libraries_list: - library_type = library['type'] - section_key = library['key'] - library_list = self.get_library_children(library_type, section_key) + section_type = library['section_type'] + section_id = library['section_id'] + children_list = self.get_library_children(section_id=section_id, section_type=section_type, count='1') - if library_list['library_count'] != '0': - library_stats = {'key': library['key'], - 'title': library['title'], - 'type': library_type, + if children_list['library_count'] != '0': + library_stats = {'section_id': library['section_id'], + 'section_name': library['section_name'], + 'section_type': section_type, 'thumb': library['thumb'], 'art': library['art'], - 'count': library_list['library_count'], - 'count_type': library_list['count_type'] + 'count': children_list['library_count'] } - if library_type == 'show': - parent_list = self.get_library_children(library_type='season', section_key=section_key) - parent_stats = {'parent_count': parent_list['library_count'], - 'parent_count_type': 'All Seasons' - } + if section_type == 'show': + parent_list = self.get_library_children(section_id=section_id, section_type='season', count='1') + parent_stats = {'parent_count': parent_list['library_count']} library_stats.update(parent_stats) - child_list = self.get_library_children(library_type='episode', section_key=section_key) - child_stats = {'child_count': child_list['library_count'], - 'child_count_type': 'All Episodes' - } + child_list = self.get_library_children(section_id=section_id, section_type='episode', count='1') + child_stats = {'child_count': child_list['library_count']} library_stats.update(child_stats) - if library_type == 'artist': - parent_list = self.get_library_children(library_type='album', section_key=section_key) - parent_stats = {'parent_count': parent_list['library_count'], - 'parent_count_type': 'All Seasons' - } + if section_type == 'artist': + parent_list = self.get_library_children(section_id=section_id, section_type='album', count='1') + parent_stats = {'parent_count': parent_list['library_count']} library_stats.update(parent_stats) - child_list = self.get_library_children(library_type='track', section_key=section_key) - child_stats = {'child_count': child_list['library_count'], - 'child_count_type': 'All Albums' - } + child_list = self.get_library_children(section_id=section_id, section_type='track', count='1') + child_stats = {'child_count': child_list['library_count']} library_stats.update(child_stats) - if library_type == 'photo': - parent_list = self.get_library_children(library_type='photoAlbum', section_key=section_key) - parent_stats = {'parent_count': parent_list['library_count'], - 'parent_count_type': 'All Photo Albums' - } + if section_type == 'photo': + parent_list = self.get_library_children(section_id=section_id, section_type='photoAlbum', count='1') + parent_stats = {'parent_count': parent_list['library_count']} library_stats.update(parent_stats) - child_list = self.get_library_children(library_type='picture', section_key=section_key) - child_stats = {'child_count': child_list['library_count'], - 'child_count_type': 'All Photos' - } + child_list = self.get_library_children(section_id=section_id, section_type='picture', count='1') + child_stats = {'child_count': child_list['library_count']} library_stats.update(child_stats) server_library_stats.append(library_stats) @@ -1782,7 +1864,7 @@ class PmsConnect(object): else: match_type = 'index' - library_id = None + section_id = None library_name = None # get grandparent rating key @@ -1790,7 +1872,7 @@ class PmsConnect(object): try: metadata = self.get_metadata_details(rating_key=rating_key) rating_key = metadata['metadata']['parent_rating_key'] - library_id = metadata['metadata']['library_id'] + section_id = metadata['metadata']['section_id'] library_name = metadata['metadata']['library_name'] except Exception as e: logger.warn(u"PlexPy Pmsconnect :: Unable to get parent_rating_key for get_rating_keys_list: %s." % e) @@ -1800,7 +1882,7 @@ class PmsConnect(object): try: metadata = self.get_metadata_details(rating_key=rating_key) rating_key = metadata['metadata']['grandparent_rating_key'] - library_id = metadata['metadata']['library_id'] + section_id = metadata['metadata']['section_id'] library_name = metadata['metadata']['library_name'] except Exception as e: logger.warn(u"PlexPy Pmsconnect :: Unable to get grandparent_rating_key for get_rating_keys_list: %s." % e) @@ -1875,10 +1957,10 @@ class PmsConnect(object): key_list = {key: {'rating_key': int(rating_key), 'children': parents }, - 'library_id': library_id, - 'library_name': library_name - } - + 'section_id': section_id, + 'library_name': library_name + } + return key_list def get_server_response(self): diff --git a/plexpy/users.py b/plexpy/users.py index b6d4b23f..bc71efd9 100644 --- a/plexpy/users.py +++ b/plexpy/users.py @@ -73,6 +73,11 @@ class Users(object): rows = [] for item in users: + if item['friendly_name']: + friendly_name = item['friendly_name'] + else: + friendly_name = item['username'] + if item['media_type'] == 'episode' and item['parent_thumb']: thumb = item['parent_thumb'] elif item['media_type'] == 'episode': @@ -114,7 +119,7 @@ class Users(object): 'recordsTotal': query['totalCount'], 'data': rows, 'draw': query['draw'] - } + } return dict @@ -199,7 +204,7 @@ class Users(object): 'recordsTotal': query['totalCount'], 'data': rows, 'draw': query['draw'] - } + } return dict diff --git a/plexpy/webserve.py b/plexpy/webserve.py index 94c59019..89ac44dd 100644 --- a/plexpy/webserve.py +++ b/plexpy/webserve.py @@ -234,7 +234,11 @@ class WebInterface(object): @cherrypy.expose def libraries(self): - return serve_template(templatename="libraries.html", title="Libraries") + config = { + "update_section_ids": plexpy.CONFIG.UPDATE_SECTION_IDS + } + + return serve_template(templatename="libraries.html", title="Libraries", config=config) @cherrypy.expose def get_library_list(self, **kwargs): @@ -300,10 +304,10 @@ class WebInterface(object): return status_message @cherrypy.expose - def get_library_watch_time_stats(self, library_id=None, **kwargs): + def get_library_watch_time_stats(self, section_id=None, **kwargs): library_data = libraries.Libraries() - result = library_data.get_watch_time_stats(library_id=library_id) + result = library_data.get_watch_time_stats(section_id=section_id) if result: return serve_template(templatename="user_watch_time_stats.html", data=result, title="Watch Stats") @@ -312,10 +316,10 @@ class WebInterface(object): return serve_template(templatename="user_watch_time_stats.html", data=None, title="Watch Stats") @cherrypy.expose - def get_library_user_stats(self, library_id=None, **kwargs): + def get_library_user_stats(self, section_id=None, **kwargs): library_data = libraries.Libraries() - result = library_data.get_user_stats(library_id=library_id) + result = library_data.get_user_stats(section_id=section_id) if result: return serve_template(templatename="library_user_stats.html", data=result, title="Player Stats") @@ -324,10 +328,10 @@ class WebInterface(object): return serve_template(templatename="library_user_stats.html", data=None, title="Player Stats") @cherrypy.expose - def get_library_recently_watched(self, library_id=None, limit='10', **kwargs): + def get_library_recently_watched(self, section_id=None, limit='10', **kwargs): library_data = libraries.Libraries() - result = library_data.get_recently_watched(library_id=library_id, limit=limit) + result = library_data.get_recently_watched(section_id=section_id, limit=limit) if result: return serve_template(templatename="user_recently_watched.html", data=result, title="Recently Watched") @@ -336,10 +340,10 @@ class WebInterface(object): return serve_template(templatename="user_recently_watched.html", data=None, title="Recently Watched") @cherrypy.expose - def get_library_recently_added(self, library_id=None, limit='10', **kwargs): + def get_library_recently_added(self, section_id=None, limit='10', **kwargs): - library_data = pmsconnect.PmsConnect() - result = library_data.get_recently_added_details(library_id=library_id, count=limit) + pms_connect = pmsconnect.PmsConnect() + result = pms_connect.get_recently_added_details(section_id=section_id, count=limit) if result: return serve_template(templatename="library_recently_added.html", data=result['recently_added'], title="Recently Added") @@ -347,6 +351,39 @@ class WebInterface(object): logger.warn(u"Unable to retrieve data for get_library_recently_added.") return serve_template(templatename="library_recently_added.html", data=None, title="Recently Added") + @cherrypy.expose + def get_library_media_info(self, section_id=None, **kwargs): + + library_data = libraries.Libraries() + result = library_data.get_datatables_media_info(section_id=section_id, kwargs=kwargs) + + cherrypy.response.headers['Content-type'] = 'application/json' + return json.dumps(result) + + @cherrypy.expose + def get_library_media_info2(self, section_id=None, section_type=None, rating_key=None, **kwargs): + + library_data = libraries.Libraries() + result = library_data.get_datatables_media_info2(section_id=section_id, + section_type=section_type, + rating_key=rating_key, + kwargs=kwargs) + + cherrypy.response.headers['Content-type'] = 'application/json' + return json.dumps(result) + + @cherrypy.expose + def get_library_unwatched(self, section_id=None, section_type=None, **kwargs): + + pms_connect = pmsconnect.PmsConnect() + result = pms_connect.get_library_children(section_id=section_id, + section_type=section_type, + get_media_info=True, + kwargs=kwargs) + + cherrypy.response.headers['Content-type'] = 'application/json' + return json.dumps(result) + @cherrypy.expose def delete_all_library_history(self, section_id, **kwargs): library_data = libraries.Libraries() @@ -395,6 +432,35 @@ class WebInterface(object): cherrypy.response.headers['Content-type'] = 'application/json' return json.dumps({'message': 'no data received'}) + @cherrypy.expose + def update_section_ids(self, **kwargs): + + logger.debug(u"Updating section_id's in database.") + library_data = libraries.Libraries() + result = library_data.update_section_ids() + + if result: + logger.debug(u"Updated all section_id's in database.") + plexpy.CONFIG.UPDATE_SECTION_IDS = 0 + plexpy.CONFIG.write() + return "Section ids updated." + else: + logger.debug(u"Unable to update section_id's in database.") + return "Unable to update section ids in database." + + @cherrypy.expose + def delete_datatable_media_info_cache(self, section_id, **kwargs): + library_data = libraries.Libraries() + + if section_id: + delete_row = library_data.delete_datatable_media_info_cache(section_id=section_id) + + if delete_row: + cherrypy.response.headers['Content-type'] = 'application/json' + return json.dumps({'message': delete_row}) + else: + cherrypy.response.headers['Content-type'] = 'application/json' + return json.dumps({'message': 'no data received'}) ##### Users ##### @@ -595,7 +661,7 @@ class WebInterface(object): custom_where.append(['session_history.reference_id', reference_id]) if 'section_id' in kwargs: section_id = kwargs.get('section_id', "") - custom_where.append(['session_history_metadata.library_id', section_id]) + custom_where.append(['session_history_metadata.section_id', section_id]) if 'media_type' in kwargs: media_type = kwargs.get('media_type', "") if media_type != 'all': @@ -1348,14 +1414,10 @@ class WebInterface(object): @cherrypy.expose def info(self, rating_key=None, source=None, **kwargs): - # temporary until I find a beter place to put this - #data_factory.update_library_ids() - metadata = None config = { - "pms_identifier": plexpy.CONFIG.PMS_IDENTIFIER, - "update_library_ids": plexpy.CONFIG.UPDATE_LIBRARY_IDS + "pms_identifier": plexpy.CONFIG.PMS_IDENTIFIER } if source == 'history': @@ -1371,7 +1433,6 @@ class WebInterface(object): return serve_template(templatename="info.html", data=metadata, title="Info", config=config) else: return self.update_metadata(rating_key) - #raise cherrypy.InternalRedirect("/update_metadata?rating_key=" + rating_key) @cherrypy.expose def get_item_children(self, rating_key='', **kwargs): @@ -1493,24 +1554,7 @@ class WebInterface(object): cherrypy.response.headers['Content-type'] = 'application/json' return json.dumps({'message': 'no data received'}) - @cherrypy.expose - def update_history_rating_key(self, old_rating_key, new_rating_key, media_type, **kwargs): - data_factory = datafactory.DataFactory() - pms_connect = pmsconnect.PmsConnect() - old_key_list = data_factory.get_rating_keys_list(rating_key=old_rating_key, media_type=media_type) - new_key_list = pms_connect.get_rating_keys_list(rating_key=new_rating_key, media_type=media_type) - - update_db = data_factory.update_rating_key(old_key_list=old_key_list, - new_key_list=new_key_list, - media_type=media_type) - - if update_db: - cherrypy.response.headers['Content-type'] = 'application/json' - return json.dumps({'message': update_db}) - else: - cherrypy.response.headers['Content-type'] = 'application/json' - return json.dumps({'message': 'no data received'}) # test code @cherrypy.expose @@ -1537,22 +1581,6 @@ class WebInterface(object): else: logger.warn(u"Unable to retrieve data for get_old_rating_keys.") - @cherrypy.expose - def update_library_ids(self, **kwargs): - - logger.debug(u"Updating library_id's in database.") - data_factory = datafactory.DataFactory() - result = data_factory.update_library_ids() - - if result: - logger.debug(u"Updated all library_id's in database.") - plexpy.CONFIG.UPDATE_LIBRARY_IDS = 0 - plexpy.CONFIG.write() - return "Library ids updated." - else: - logger.debug(u"Unable to update library_id's in database.") - return "Unable to update library ids in database." - ##### API #####
Edit