diff --git a/jellypy/__init__.py b/jellypy/__init__.py
index 2b575e3a..85b68764 100644
--- a/jellypy/__init__.py
+++ b/jellypy/__init__.py
@@ -47,7 +47,6 @@ from jellypy import newsletters
from jellypy import newsletter_handler
from jellypy import notification_handler
from jellypy import notifiers
-from jellypy import plextv
from jellypy import users
from jellypy import versioncheck
from jellypy import web_socket
@@ -426,8 +425,9 @@ def initialize_scheduler():
hours=backup_hours, minutes=0, seconds=0, args=(True, True))
if WS_CONNECTED and CONFIG.PMS_IP and CONFIG.PMS_TOKEN:
- schedule_job(plextv.get_server_resources, 'Refresh Plex server URLs',
- hours=12 * (not bool(CONFIG.PMS_URL_MANUAL)), minutes=0, seconds=0)
+ # TODO: Jellyfin
+ # schedule_job(plextv.get_server_resources, 'Refresh Plex server URLs',
+ # hours=12 * (not bool(CONFIG.PMS_URL_MANUAL)), minutes=0, seconds=0)
schedule_job(activity_pinger.check_server_updates, 'Check for Plex updates',
hours=pms_update_check_hours * bool(CONFIG.MONITOR_PMS_UPDATES), minutes=0, seconds=0)
@@ -448,8 +448,9 @@ def initialize_scheduler():
else:
# Cancel all jobs
- schedule_job(plextv.get_server_resources, 'Refresh Plex server URLs',
- hours=0, minutes=0, seconds=0)
+ # TODO: Jellyfin
+ # schedule_job(plextv.get_server_resources, 'Refresh Plex server URLs',
+ # hours=0, minutes=0, seconds=0)
schedule_job(activity_pinger.check_server_updates, 'Check for Plex updates',
hours=0, minutes=0, seconds=0)
@@ -532,7 +533,9 @@ def start():
def startup_refresh():
# Get the real PMS urls for SSL and remote access
if CONFIG.PMS_TOKEN and CONFIG.PMS_IP and CONFIG.PMS_PORT:
- plextv.get_server_resources()
+ pass
+ # TODO: Jellyfin
+ # plextv.get_server_resources()
# Connect server after server resource is refreshed
if CONFIG.FIRST_RUN_COMPLETE:
diff --git a/jellypy/activity_handler.py b/jellypy/activity_handler.py
index e19488f8..bdb5d7f5 100644
--- a/jellypy/activity_handler.py
+++ b/jellypy/activity_handler.py
@@ -27,7 +27,6 @@ from jellypy import datafactory
from jellypy import helpers
from jellypy import logger
from jellypy import notification_handler
-from jellypy import pmsconnect
ACTIVITY_SCHED = None
@@ -60,27 +59,29 @@ class ActivityHandler(object):
def get_metadata(self, skip_cache=False):
cache_key = None if skip_cache else self.get_session_key()
- pms_connect = pmsconnect.PmsConnect()
- metadata = pms_connect.get_metadata_details(rating_key=self.get_rating_key(), cache_key=cache_key)
-
- if metadata:
- return metadata
+ # TODO: Jellyfin
+ # pms_connect = pmsconnect.PmsConnect()
+ # metadata = pms_connect.get_metadata_details(rating_key=self.get_rating_key(), cache_key=cache_key)
+ #
+ # if metadata:
+ # return metadata
return None
def get_live_session(self, skip_cache=False):
- pms_connect = pmsconnect.PmsConnect()
- session_list = pms_connect.get_current_activity(skip_cache=skip_cache)
-
- if session_list:
- for session in session_list['sessions']:
- if int(session['session_key']) == self.get_session_key():
- # Live sessions don't have rating keys in sessions
- # Get it from the websocket data
- if not session['rating_key']:
- session['rating_key'] = self.get_rating_key()
- session['rating_key_websocket'] = self.get_rating_key()
- return session
+ # TODO: Jellyfin
+ # pms_connect = pmsconnect.PmsConnect()
+ # session_list = pms_connect.get_current_activity(skip_cache=skip_cache)
+ #
+ # if session_list:
+ # for session in session_list['sessions']:
+ # if int(session['session_key']) == self.get_session_key():
+ # # Live sessions don't have rating keys in sessions
+ # # Get it from the websocket data
+ # if not session['rating_key']:
+ # session['rating_key'] = self.get_rating_key()
+ # session['rating_key_websocket'] = self.get_rating_key()
+ # return session
return None
@@ -390,11 +391,12 @@ class TimelineHandler(object):
return None
def get_metadata(self):
- pms_connect = pmsconnect.PmsConnect()
- metadata = pms_connect.get_metadata_details(self.get_rating_key())
-
- if metadata:
- return metadata
+ # TODO: Jellyfin
+ # pms_connect = pmsconnect.PmsConnect()
+ # metadata = pms_connect.get_metadata_details(self.get_rating_key())
+ #
+ # if metadata:
+ # return metadata
return None
@@ -522,9 +524,11 @@ class ReachabilityHandler(object):
return False
def remote_access_enabled(self):
- pms_connect = pmsconnect.PmsConnect()
- pref = pms_connect.get_server_pref(pref='PublishServerOnPlexOnlineKey')
- return helpers.bool_true(pref)
+ return False
+ # TODO: Jellyfin
+ # pms_connect = pmsconnect.PmsConnect()
+ # pref = pms_connect.get_server_pref(pref='PublishServerOnPlexOnlineKey')
+ # return helpers.bool_true(pref)
def on_down(self, server_response):
jellypy.NOTIFY_QUEUE.put({'notify_action': 'on_extdown', 'remote_access_info': server_response})
@@ -541,39 +545,40 @@ class ReachabilityHandler(object):
if self.is_reachable() and jellypy.PLEX_REMOTE_ACCESS_UP:
return
- pms_connect = pmsconnect.PmsConnect()
- server_response = pms_connect.get_server_response()
-
- if server_response:
- # Waiting for port mapping
- if server_response['mapping_state'] == 'waiting':
- logger.warn("Tautulli ReachabilityHandler :: Remote access waiting for port mapping.")
-
- elif jellypy.PLEX_REMOTE_ACCESS_UP is not False and server_response['reason']:
- logger.warn("Tautulli ReachabilityHandler :: Remote access failed: %s" % server_response['reason'])
- logger.info("Tautulli ReachabilityHandler :: Plex remote access is down.")
-
- jellypy.PLEX_REMOTE_ACCESS_UP = False
-
- if not ACTIVITY_SCHED.get_job('on_extdown'):
- logger.debug("Tautulli ReachabilityHandler :: Schedule remote access down callback in %d seconds.",
- jellypy.CONFIG.NOTIFY_REMOTE_ACCESS_THRESHOLD)
- schedule_callback('on_extdown', func=self.on_down, args=[server_response],
- seconds=jellypy.CONFIG.NOTIFY_REMOTE_ACCESS_THRESHOLD)
-
- elif jellypy.PLEX_REMOTE_ACCESS_UP is False and not server_response['reason']:
- logger.info("Tautulli ReachabilityHandler :: Plex remote access is back up.")
-
- jellypy.PLEX_REMOTE_ACCESS_UP = True
-
- if ACTIVITY_SCHED.get_job('on_extdown'):
- logger.debug("Tautulli ReachabilityHandler :: Cancelling scheduled remote access down callback.")
- schedule_callback('on_extdown', remove_job=True)
- else:
- self.on_up(server_response)
-
- elif jellypy.PLEX_REMOTE_ACCESS_UP is None:
- jellypy.PLEX_REMOTE_ACCESS_UP = self.is_reachable()
+ # TODO: Jellyfin
+ # pms_connect = pmsconnect.PmsConnect()
+ # server_response = pms_connect.get_server_response()
+ #
+ # if server_response:
+ # # Waiting for port mapping
+ # if server_response['mapping_state'] == 'waiting':
+ # logger.warn("Tautulli ReachabilityHandler :: Remote access waiting for port mapping.")
+ #
+ # elif jellypy.PLEX_REMOTE_ACCESS_UP is not False and server_response['reason']:
+ # logger.warn("Tautulli ReachabilityHandler :: Remote access failed: %s" % server_response['reason'])
+ # logger.info("Tautulli ReachabilityHandler :: Plex remote access is down.")
+ #
+ # jellypy.PLEX_REMOTE_ACCESS_UP = False
+ #
+ # if not ACTIVITY_SCHED.get_job('on_extdown'):
+ # logger.debug("Tautulli ReachabilityHandler :: Schedule remote access down callback in %d seconds.",
+ # jellypy.CONFIG.NOTIFY_REMOTE_ACCESS_THRESHOLD)
+ # schedule_callback('on_extdown', func=self.on_down, args=[server_response],
+ # seconds=jellypy.CONFIG.NOTIFY_REMOTE_ACCESS_THRESHOLD)
+ #
+ # elif jellypy.PLEX_REMOTE_ACCESS_UP is False and not server_response['reason']:
+ # logger.info("Tautulli ReachabilityHandler :: Plex remote access is back up.")
+ #
+ # jellypy.PLEX_REMOTE_ACCESS_UP = True
+ #
+ # if ACTIVITY_SCHED.get_job('on_extdown'):
+ # logger.debug("Tautulli ReachabilityHandler :: Cancelling scheduled remote access down callback.")
+ # schedule_callback('on_extdown', remove_job=True)
+ # else:
+ # self.on_up(server_response)
+ #
+ # elif jellypy.PLEX_REMOTE_ACCESS_UP is None:
+ # jellypy.PLEX_REMOTE_ACCESS_UP = self.is_reachable()
def del_keys(key):
@@ -670,41 +675,42 @@ def clear_recently_added_queue(rating_key, title):
def on_created(rating_key, **kwargs):
logger.debug("Tautulli TimelineHandler :: Library item %s added to Plex." % str(rating_key))
- pms_connect = pmsconnect.PmsConnect()
- metadata = pms_connect.get_metadata_details(rating_key)
-
- if metadata:
- notify = True
- # now = helpers.timestamp()
- #
- # if helpers.cast_to_int(metadata['added_at']) < now - 86400: # Updated more than 24 hours ago
- # logger.debug("Tautulli TimelineHandler :: Library item %s added more than 24 hours ago. Not notifying."
- # % str(rating_key))
- # notify = False
-
- data_factory = datafactory.DataFactory()
- if 'child_keys' not in kwargs:
- if data_factory.get_recently_added_item(rating_key):
- logger.debug("Tautulli TimelineHandler :: Library item %s added already. Not notifying again."
- % str(rating_key))
- notify = False
-
- if notify:
- data = {'timeline_data': metadata, 'notify_action': 'on_created'}
- data.update(kwargs)
- jellypy.NOTIFY_QUEUE.put(data)
-
- all_keys = [rating_key]
- if 'child_keys' in kwargs:
- all_keys.extend(kwargs['child_keys'])
-
- for key in all_keys:
- data_factory.set_recently_added_item(key)
-
- logger.debug("Added %s items to the recently_added database table." % str(len(all_keys)))
-
- else:
- logger.error("Tautulli TimelineHandler :: Unable to retrieve metadata for rating_key %s" % str(rating_key))
+ # TODO: Jellyfin
+ # pms_connect = pmsconnect.PmsConnect()
+ # metadata = pms_connect.get_metadata_details(rating_key)
+ #
+ # if metadata:
+ # notify = True
+ # # now = helpers.timestamp()
+ # #
+ # # if helpers.cast_to_int(metadata['added_at']) < now - 86400: # Updated more than 24 hours ago
+ # # logger.debug("Tautulli TimelineHandler :: Library item %s added more than 24 hours ago. Not notifying."
+ # # % str(rating_key))
+ # # notify = False
+ #
+ # data_factory = datafactory.DataFactory()
+ # if 'child_keys' not in kwargs:
+ # if data_factory.get_recently_added_item(rating_key):
+ # logger.debug("Tautulli TimelineHandler :: Library item %s added already. Not notifying again."
+ # % str(rating_key))
+ # notify = False
+ #
+ # if notify:
+ # data = {'timeline_data': metadata, 'notify_action': 'on_created'}
+ # data.update(kwargs)
+ # jellypy.NOTIFY_QUEUE.put(data)
+ #
+ # all_keys = [rating_key]
+ # if 'child_keys' in kwargs:
+ # all_keys.extend(kwargs['child_keys'])
+ #
+ # for key in all_keys:
+ # data_factory.set_recently_added_item(key)
+ #
+ # logger.debug("Added %s items to the recently_added database table." % str(len(all_keys)))
+ #
+ # else:
+ # logger.error("Tautulli TimelineHandler :: Unable to retrieve metadata for rating_key %s" % str(rating_key))
def delete_metadata_cache(session_key):
diff --git a/jellypy/activity_pinger.py b/jellypy/activity_pinger.py
index a692e964..e3ced372 100644
--- a/jellypy/activity_pinger.py
+++ b/jellypy/activity_pinger.py
@@ -23,8 +23,6 @@ from jellypy import database
from jellypy import helpers
from jellypy import logger
from jellypy import notification_handler
-from jellypy import plextv
-from jellypy import pmsconnect
from jellypy import web_socket
monitor_lock = threading.Lock()
@@ -43,8 +41,10 @@ def check_active_sessions(ws_request=False):
for stream in db_streams:
activity_handler.delete_metadata_cache(stream['session_key'])
- pms_connect = pmsconnect.PmsConnect()
- session_list = pms_connect.get_current_activity()
+ # TODO: Jellyfin
+ # pms_connect = pmsconnect.PmsConnect()
+ # session_list = pms_connect.get_current_activity()
+ session_list = None
logger.debug("Tautulli Monitor :: Checking for active streams.")
@@ -229,8 +229,10 @@ def connect_server(log=True, startup=False):
if log:
logger.info("Tautulli Monitor :: Checking for Plex Cloud server status...")
- plex_tv = plextv.PlexTV()
- status = plex_tv.get_cloud_server_status()
+ # TODO: Jellyfin
+ # plex_tv = plextv.PlexTV()
+ # status = plex_tv.get_cloud_server_status()
+ status = None
if status is True:
logger.info("Tautulli Monitor :: Plex Cloud server is active.")
@@ -261,16 +263,17 @@ def check_server_updates():
with monitor_lock:
logger.info("Tautulli Monitor :: Checking for PMS updates...")
- plex_tv = plextv.PlexTV()
- download_info = plex_tv.get_plex_downloads()
-
- if download_info:
- logger.info("Tautulli Monitor :: Current PMS version: %s", jellypy.CONFIG.PMS_VERSION)
-
- if download_info['update_available']:
- logger.info("Tautulli Monitor :: PMS update available version: %s", download_info['version'])
-
- jellypy.NOTIFY_QUEUE.put({'notify_action': 'on_pmsupdate', 'pms_download_info': download_info})
-
- else:
- logger.info("Tautulli Monitor :: No PMS update available.")
+ # TODO: Jellyfin
+ # plex_tv = plextv.PlexTV()
+ # download_info = plex_tv.get_plex_downloads()
+ #
+ # if download_info:
+ # logger.info("Tautulli Monitor :: Current PMS version: %s", jellypy.CONFIG.PMS_VERSION)
+ #
+ # if download_info['update_available']:
+ # logger.info("Tautulli Monitor :: PMS update available version: %s", download_info['version'])
+ #
+ # jellypy.NOTIFY_QUEUE.put({'notify_action': 'on_pmsupdate', 'pms_download_info': download_info})
+ #
+ # else:
+ # logger.info("Tautulli Monitor :: No PMS update available.")
diff --git a/jellypy/activity_processor.py b/jellypy/activity_processor.py
index d20c12d4..cc66cceb 100644
--- a/jellypy/activity_processor.py
+++ b/jellypy/activity_processor.py
@@ -22,7 +22,6 @@ from jellypy import database
from jellypy import helpers
from jellypy import libraries
from jellypy import logger
-from jellypy import pmsconnect
from jellypy import users
@@ -260,19 +259,20 @@ class ActivityProcessor(object):
if not is_import:
logger.debug(
"Tautulli ActivityProcessor :: Fetching metadata for item ratingKey %s" % session['rating_key'])
- pms_connect = pmsconnect.PmsConnect()
- if session['live']:
- metadata = pms_connect.get_metadata_details(rating_key=str(session['rating_key']),
- cache_key=session['session_key'],
- return_cache=True)
- else:
- metadata = pms_connect.get_metadata_details(rating_key=str(session['rating_key']))
- if not metadata:
- return False
- else:
- media_info = {}
- if 'media_info' in metadata and len(metadata['media_info']) > 0:
- media_info = metadata['media_info'][0]
+ # TODO: Jellyfin
+ # pms_connect = pmsconnect.PmsConnect()
+ # if session['live']:
+ # metadata = pms_connect.get_metadata_details(rating_key=str(session['rating_key']),
+ # cache_key=session['session_key'],
+ # return_cache=True)
+ # else:
+ # metadata = pms_connect.get_metadata_details(rating_key=str(session['rating_key']))
+ # if not metadata:
+ # return False
+ # else:
+ # media_info = {}
+ # if 'media_info' in metadata and len(metadata['media_info']) > 0:
+ # media_info = metadata['media_info'][0]
else:
metadata = import_metadata
## TODO: Fix media info from imports. Temporary media info from import session.
diff --git a/jellypy/api2.py b/jellypy/api2.py
index 88978c03..8ee12770 100644
--- a/jellypy/api2.py
+++ b/jellypy/api2.py
@@ -40,7 +40,6 @@ from jellypy import notification_handler
from jellypy import notifiers
from jellypy import newsletter_handler
from jellypy import newsletters
-from jellypy import plextv
from jellypy import users
from jellypy.password import check_hash
@@ -451,11 +450,13 @@ class API2(object):
mobile_app.set_temp_device_token(True)
- plex_server = plextv.get_server_resources(return_info=True)
+ # TODO: Jellyfin
+ # plex_server = plextv.get_server_resources(return_info=True)
tautulli = jellypy.get_tautulli_info()
data = {"server_id": jellypy.CONFIG.PMS_UUID}
- data.update(plex_server)
+ # TODO: Jellyfin
+ # data.update(plex_server)
data.update(tautulli)
return data
diff --git a/jellypy/datafactory.py b/jellypy/datafactory.py
index a521415e..1e225f6e 100644
--- a/jellypy/datafactory.py
+++ b/jellypy/datafactory.py
@@ -25,7 +25,6 @@ from jellypy import database
from jellypy import datatables
from jellypy import helpers
from jellypy import logger
-from jellypy import pmsconnect
from jellypy import session
@@ -1589,7 +1588,7 @@ class DataFactory(object):
return key_list
def update_metadata(self, old_key_list='', new_key_list='', media_type=''):
- pms_connect = pmsconnect.PmsConnect()
+ # TODO: pms_connect = pmsconnect.PmsConnect()
monitor_db = database.MonitorDatabase()
# function to map rating keys pairs
@@ -1608,37 +1607,38 @@ class DataFactory(object):
if old_key_list and new_key_list:
mapping = get_pairs(old_key_list, new_key_list)
- if mapping:
- logger.info("Tautulli DataFactory :: Updating metadata in the database.")
- for old_key, new_key in mapping.items():
- metadata = pms_connect.get_metadata_details(new_key)
-
- if metadata:
- if metadata['media_type'] == 'show' or metadata['media_type'] == 'artist':
- # check grandparent_rating_key (2 tables)
- monitor_db.action(
- 'UPDATE session_history SET grandparent_rating_key = ? WHERE grandparent_rating_key = ?',
- [new_key, old_key])
- monitor_db.action(
- 'UPDATE session_history_metadata SET grandparent_rating_key = ? WHERE grandparent_rating_key = ?',
- [new_key, old_key])
- elif metadata['media_type'] == 'season' or metadata['media_type'] == 'album':
- # check parent_rating_key (2 tables)
- monitor_db.action(
- 'UPDATE session_history SET parent_rating_key = ? WHERE parent_rating_key = ?',
- [new_key, old_key])
- monitor_db.action(
- 'UPDATE session_history_metadata SET parent_rating_key = ? WHERE parent_rating_key = ?',
- [new_key, old_key])
- else:
- # check rating_key (2 tables)
- monitor_db.action('UPDATE session_history SET rating_key = ? WHERE rating_key = ?',
- [new_key, old_key])
- monitor_db.action('UPDATE session_history_media_info SET rating_key = ? WHERE rating_key = ?',
- [new_key, old_key])
-
- # update session_history_metadata table
- self.update_metadata_details(old_key, new_key, metadata)
+ # TODO: Jellyfin
+ # if mapping:
+ # logger.info("Tautulli DataFactory :: Updating metadata in the database.")
+ # for old_key, new_key in mapping.items():
+ # metadata = pms_connect.get_metadata_details(new_key)
+ #
+ # if metadata:
+ # if metadata['media_type'] == 'show' or metadata['media_type'] == 'artist':
+ # # check grandparent_rating_key (2 tables)
+ # monitor_db.action(
+ # 'UPDATE session_history SET grandparent_rating_key = ? WHERE grandparent_rating_key = ?',
+ # [new_key, old_key])
+ # monitor_db.action(
+ # 'UPDATE session_history_metadata SET grandparent_rating_key = ? WHERE grandparent_rating_key = ?',
+ # [new_key, old_key])
+ # elif metadata['media_type'] == 'season' or metadata['media_type'] == 'album':
+ # # check parent_rating_key (2 tables)
+ # monitor_db.action(
+ # 'UPDATE session_history SET parent_rating_key = ? WHERE parent_rating_key = ?',
+ # [new_key, old_key])
+ # monitor_db.action(
+ # 'UPDATE session_history_metadata SET parent_rating_key = ? WHERE parent_rating_key = ?',
+ # [new_key, old_key])
+ # else:
+ # # check rating_key (2 tables)
+ # monitor_db.action('UPDATE session_history SET rating_key = ? WHERE rating_key = ?',
+ # [new_key, old_key])
+ # monitor_db.action('UPDATE session_history_media_info SET rating_key = ? WHERE rating_key = ?',
+ # [new_key, old_key])
+ #
+ # # update session_history_metadata table
+ # self.update_metadata_details(old_key, new_key, metadata)
return 'Updated metadata in database.'
else:
@@ -1886,23 +1886,24 @@ class DataFactory(object):
def set_recently_added_item(self, rating_key=''):
monitor_db = database.MonitorDatabase()
- pms_connect = pmsconnect.PmsConnect()
- metadata = pms_connect.get_metadata_details(rating_key)
-
- keys = {'rating_key': metadata['rating_key']}
-
- values = {'added_at': metadata['added_at'],
- 'section_id': metadata['section_id'],
- 'parent_rating_key': metadata['parent_rating_key'],
- 'grandparent_rating_key': metadata['grandparent_rating_key'],
- 'media_type': metadata['media_type'],
- 'media_info': json.dumps(metadata['media_info'])
- }
-
- try:
- monitor_db.upsert(table_name='recently_added', key_dict=keys, value_dict=values)
- except Exception as e:
- logger.warn("Tautulli DataFactory :: Unable to execute database query for set_recently_added_item: %s." % e)
- return False
+ # TODO: Jellyfin
+ # pms_connect = pmsconnect.PmsConnect()
+ # metadata = pms_connect.get_metadata_details(rating_key)
+ #
+ # keys = {'rating_key': metadata['rating_key']}
+ #
+ # values = {'added_at': metadata['added_at'],
+ # 'section_id': metadata['section_id'],
+ # 'parent_rating_key': metadata['parent_rating_key'],
+ # 'grandparent_rating_key': metadata['grandparent_rating_key'],
+ # 'media_type': metadata['media_type'],
+ # 'media_info': json.dumps(metadata['media_info'])
+ # }
+ #
+ # try:
+ # monitor_db.upsert(table_name='recently_added', key_dict=keys, value_dict=values)
+ # except Exception as e:
+ # logger.warn("Tautulli DataFactory :: Unable to execute database query for set_recently_added_item: %s." % e)
+ # return False
return True
diff --git a/jellypy/libraries.py b/jellypy/libraries.py
index 4d0a76d6..6b3caa3a 100644
--- a/jellypy/libraries.py
+++ b/jellypy/libraries.py
@@ -25,8 +25,6 @@ from jellypy import database
from jellypy import datatables
from jellypy import helpers
from jellypy import logger
-from jellypy import plextv
-from jellypy import pmsconnect
from jellypy import session
from jellypy import users
from jellypy.jellyfin import Jellyfin
@@ -1159,7 +1157,7 @@ class Libraries(object):
monitor_db = database.MonitorDatabase()
# Refresh the PMS_URL to make sure the server_id is updated
- plextv.get_server_resources()
+ # TODO: plextv.get_server_resources()
server_id = jellypy.CONFIG.PMS_IDENTIFIER
diff --git a/jellypy/newsletters.py b/jellypy/newsletters.py
index aef9aafc..ae2b76ed 100644
--- a/jellypy/newsletters.py
+++ b/jellypy/newsletters.py
@@ -32,7 +32,6 @@ from jellypy import helpers
from jellypy import libraries
from jellypy import logger
from jellypy import newsletter_handler
-from jellypy import pmsconnect
from jellypy.notifiers import send_notification, EMAIL
AGENT_IDS = {
@@ -693,7 +692,8 @@ class RecentlyAdded(Newsletter):
def _get_recently_added(self, media_type=None):
from jellypy.notification_handler import format_group_index
- pms_connect = pmsconnect.PmsConnect()
+ # TODO: Jellyfin
+ # pms_connect = pmsconnect.PmsConnect()
recently_added = []
done = False
diff --git a/jellypy/notification_handler.py b/jellypy/notification_handler.py
index aab495dc..5364a4f2 100644
--- a/jellypy/notification_handler.py
+++ b/jellypy/notification_handler.py
@@ -39,7 +39,6 @@ from jellypy import datafactory
from jellypy import logger
from jellypy import helpers
from jellypy import notifiers
-from jellypy import pmsconnect
from jellypy import request
from jellypy.newsletter_handler import notify as notify_newsletter
@@ -164,18 +163,20 @@ def notify_conditions(notify_action=None, stream_data=None, timeline_data=None):
# return False
if notify_action == 'on_concurrent':
- pms_connect = pmsconnect.PmsConnect()
- result = pms_connect.get_current_activity()
-
- user_sessions = []
- if result:
- user_sessions = [s for s in result['sessions'] if s['user_id'] == stream_data['user_id']]
-
- if jellypy.CONFIG.NOTIFY_CONCURRENT_BY_IP:
- evaluated = len(
- Counter(s['ip_address'] for s in user_sessions)) >= jellypy.CONFIG.NOTIFY_CONCURRENT_THRESHOLD
- else:
- evaluated = len(user_sessions) >= jellypy.CONFIG.NOTIFY_CONCURRENT_THRESHOLD
+ pass
+ # TODO: Jellyfin
+ # pms_connect = pmsconnect.PmsConnect()
+ # result = pms_connect.get_current_activity()
+ #
+ # user_sessions = []
+ # if result:
+ # user_sessions = [s for s in result['sessions'] if s['user_id'] == stream_data['user_id']]
+ #
+ # if jellypy.CONFIG.NOTIFY_CONCURRENT_BY_IP:
+ # evaluated = len(
+ # Counter(s['ip_address'] for s in user_sessions)) >= jellypy.CONFIG.NOTIFY_CONCURRENT_THRESHOLD
+ # else:
+ # evaluated = len(user_sessions) >= jellypy.CONFIG.NOTIFY_CONCURRENT_THRESHOLD
elif notify_action == 'on_newdevice':
data_factory = datafactory.DataFactory()
@@ -536,10 +537,11 @@ def build_media_notify_params(notify_action=None, session=None, timeline=None, m
notify_params.update(media_part_info)
child_metadata = grandchild_metadata = []
- for key in kwargs.pop('child_keys', []):
- child_metadata.append(pmsconnect.PmsConnect().get_metadata_details(rating_key=key))
- for key in kwargs.pop('grandchild_keys', []):
- grandchild_metadata.append(pmsconnect.PmsConnect().get_metadata_details(rating_key=key))
+ # TODO: Jellyfin
+ # for key in kwargs.pop('child_keys', []):
+ # child_metadata.append(pmsconnect.PmsConnect().get_metadata_details(rating_key=key))
+ # for key in kwargs.pop('grandchild_keys', []):
+ # grandchild_metadata.append(pmsconnect.PmsConnect().get_metadata_details(rating_key=key))
# Session values
session = session or {}
@@ -1097,7 +1099,8 @@ def build_server_notify_params(notify_action=None, **kwargs):
date_format = jellypy.CONFIG.DATE_FORMAT.replace('Do', '')
time_format = jellypy.CONFIG.TIME_FORMAT.replace('Do', '')
- update_channel = pmsconnect.PmsConnect().get_server_update_channel()
+ # TODO: Jellyfin
+ # update_channel = pmsconnect.PmsConnect().get_server_update_channel()
pms_download_info = defaultdict(str, kwargs.pop('pms_download_info', {}))
plexpy_download_info = defaultdict(str, kwargs.pop('plexpy_download_info', {}))
@@ -1146,7 +1149,8 @@ def build_server_notify_params(notify_action=None, **kwargs):
'update_url': pms_download_info['download_url'],
'update_release_date': arrow.get(pms_download_info['release_date']).format(date_format)
if pms_download_info['release_date'] else '',
- 'update_channel': 'Beta' if update_channel == 'beta' else 'Public',
+ # TODO: Jellyfin
+ # 'update_channel': 'Beta' if update_channel == 'beta' else 'Public',
'update_platform': pms_download_info['platform'],
'update_distro': pms_download_info['distro'],
'update_distro_build': pms_download_info['build'],
@@ -1410,32 +1414,34 @@ def get_img_info(img=None, rating_key=None, title='', width=1000, height=1500,
img_info = database_img_info[0]
elif not database_img_info and img:
- pms_connect = pmsconnect.PmsConnect()
- result = pms_connect.get_image(refresh=True, **image_info)
-
- if result and result[0]:
- img_url = delete_hash = ''
-
- if service == 'imgur':
- img_url, delete_hash = helpers.upload_to_imgur(img_data=result[0],
- img_title=title,
- rating_key=rating_key,
- fallback=fallback)
- elif service == 'cloudinary':
- img_url = helpers.upload_to_cloudinary(img_data=result[0],
- img_title=title,
- rating_key=rating_key,
- fallback=fallback)
-
- if img_url:
- img_hash = set_hash_image_info(**image_info)
- data_factory.set_img_info(img_hash=img_hash,
- img_title=title,
- img_url=img_url,
- delete_hash=delete_hash,
- service=service)
-
- img_info = {'img_title': title, 'img_url': img_url}
+ pass
+ # TODO: Jellyfin
+ # pms_connect = pmsconnect.PmsConnect()
+ # result = pms_connect.get_image(refresh=True, **image_info)
+ #
+ # if result and result[0]:
+ # img_url = delete_hash = ''
+ #
+ # if service == 'imgur':
+ # img_url, delete_hash = helpers.upload_to_imgur(img_data=result[0],
+ # img_title=title,
+ # rating_key=rating_key,
+ # fallback=fallback)
+ # elif service == 'cloudinary':
+ # img_url = helpers.upload_to_cloudinary(img_data=result[0],
+ # img_title=title,
+ # rating_key=rating_key,
+ # fallback=fallback)
+ #
+ # if img_url:
+ # img_hash = set_hash_image_info(**image_info)
+ # data_factory.set_img_info(img_hash=img_hash,
+ # img_title=title,
+ # img_url=img_url,
+ # delete_hash=delete_hash,
+ # service=service)
+ #
+ # img_info = {'img_title': title, 'img_url': img_url}
if img_info['img_url'] and service == 'cloudinary':
# Transform image using Cloudinary
diff --git a/jellypy/notifiers.py b/jellypy/notifiers.py
index 0bd87ce7..f685a492 100644
--- a/jellypy/notifiers.py
+++ b/jellypy/notifiers.py
@@ -61,7 +61,6 @@ from jellypy import database
from jellypy import helpers
from jellypy import logger
from jellypy import mobile_app
-from jellypy import pmsconnect
from jellypy import request
from jellypy import users
@@ -1517,29 +1516,30 @@ class GROUPME(Notifier):
if self.config['incl_poster'] and kwargs.get('parameters'):
pretty_metadata = PrettyMetadata(kwargs.get('parameters'))
- # Retrieve the poster from Plex
- result = pmsconnect.PmsConnect().get_image(img=pretty_metadata.parameters.get('poster_thumb', ''))
- if result and result[0]:
- poster_content = result[0]
- else:
- poster_content = ''
- logger.error("Tautulli Notifiers :: Unable to retrieve image for {name}.".format(name=self.NAME))
-
- if poster_content:
- headers = {'X-Access-Token': self.config['access_token'],
- 'Content-Type': 'image/png'}
-
- r = requests.post('https://image.groupme.com/pictures', headers=headers, data=poster_content)
-
- if r.status_code == 200:
- logger.info("Tautulli Notifiers :: {name} poster sent.".format(name=self.NAME))
- r_content = r.json()
- data['attachments'] = [{'type': 'image',
- 'url': r_content['payload']['picture_url']}]
- else:
- logger.error("Tautulli Notifiers :: {name} poster failed: "
- "[{r.status_code}] {r.reason}".format(name=self.NAME, r=r))
- logger.debug("Tautulli Notifiers :: Request response: {}".format(request.server_message(r, True)))
+ # TODO: Jellyfin
+ # # Retrieve the poster from Plex
+ # result = pmsconnect.PmsConnect().get_image(img=pretty_metadata.parameters.get('poster_thumb', ''))
+ # if result and result[0]:
+ # poster_content = result[0]
+ # else:
+ # poster_content = ''
+ # logger.error("Tautulli Notifiers :: Unable to retrieve image for {name}.".format(name=self.NAME))
+ #
+ # if poster_content:
+ # headers = {'X-Access-Token': self.config['access_token'],
+ # 'Content-Type': 'image/png'}
+ #
+ # r = requests.post('https://image.groupme.com/pictures', headers=headers, data=poster_content)
+ #
+ # if r.status_code == 200:
+ # logger.info("Tautulli Notifiers :: {name} poster sent.".format(name=self.NAME))
+ # r_content = r.json()
+ # data['attachments'] = [{'type': 'image',
+ # 'url': r_content['payload']['picture_url']}]
+ # else:
+ # logger.error("Tautulli Notifiers :: {name} poster failed: "
+ # "[{r.status_code}] {r.reason}".format(name=self.NAME, r=r))
+ # logger.debug("Tautulli Notifiers :: Request response: {}".format(request.server_message(r, True)))
return self.make_request('https://api.groupme.com/v3/bots/post', json=data)
diff --git a/jellypy/plextv.py b/jellypy/plextv.py
deleted file mode 100644
index 5a39ff6a..00000000
--- a/jellypy/plextv.py
+++ /dev/null
@@ -1,978 +0,0 @@
-# -*- coding: utf-8 -*-
-
-# This file is part of Tautulli.
-#
-# Tautulli is free software: you can redistribute it and/or modify
-# it under the terms of the GNU General Public License as published by
-# the Free Software Foundation, either version 3 of the License, or
-# (at your option) any later version.
-#
-# Tautulli is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-# GNU General Public License for more details.
-#
-# You should have received a copy of the GNU General Public License
-# along with Tautulli. If not, see .
-
-import json
-
-import jellypy
-
-from jellypy import common
-from jellypy import helpers
-from jellypy import http_handler
-from jellypy import logger
-from jellypy import users
-from jellypy import pmsconnect
-from jellypy import session
-
-
-def get_server_resources(return_presence=False, return_server=False, return_info=False, **kwargs):
- if not return_presence and not return_info:
- logger.info("Tautulli PlexTV :: Requesting resources for server...")
-
- server = {'pms_name': jellypy.CONFIG.PMS_NAME,
- 'pms_version': jellypy.CONFIG.PMS_VERSION,
- 'pms_platform': jellypy.CONFIG.PMS_PLATFORM,
- 'pms_ip': jellypy.CONFIG.PMS_IP,
- 'pms_port': jellypy.CONFIG.PMS_PORT,
- 'pms_ssl': jellypy.CONFIG.PMS_SSL,
- 'pms_is_remote': jellypy.CONFIG.PMS_IS_REMOTE,
- 'pms_is_cloud': jellypy.CONFIG.PMS_IS_CLOUD,
- 'pms_url': jellypy.CONFIG.PMS_URL,
- 'pms_url_manual': jellypy.CONFIG.PMS_URL_MANUAL,
- 'pms_identifier': jellypy.CONFIG.PMS_IDENTIFIER,
- 'pms_plexpass': jellypy.CONFIG.PMS_PLEXPASS
- }
-
- if return_info:
- return server
-
- if kwargs:
- server.update(kwargs)
- for k in ['pms_ssl', 'pms_is_remote', 'pms_is_cloud', 'pms_url_manual']:
- server[k] = int(server[k])
-
- if server['pms_url_manual'] and server['pms_ssl'] or server['pms_is_cloud']:
- scheme = 'https'
- else:
- scheme = 'http'
-
- fallback_url = '{scheme}://{hostname}:{port}'.format(scheme=scheme,
- hostname=server['pms_ip'],
- port=server['pms_port'])
-
- plex_tv = PlexTV()
- result = plex_tv.get_server_connections(pms_identifier=server['pms_identifier'],
- pms_ip=server['pms_ip'],
- pms_port=server['pms_port'],
- include_https=server['pms_ssl'])
-
- if result:
- connections = result.pop('connections', [])
- server.update(result)
- presence = server.pop('pms_presence', 0)
- else:
- connections = []
- presence = 0
-
- if return_presence:
- return presence
-
- plexpass = plex_tv.get_plexpass_status()
- server['pms_plexpass'] = int(plexpass)
-
- # Only need to retrieve PMS_URL if using SSL
- if not server['pms_url_manual'] and server['pms_ssl']:
- if connections:
- if server['pms_is_remote']:
- # Get all remote connections
- conns = [c for c in connections if
- c['local'] == '0' and ('plex.direct' in c['uri'] or 'plex.service' in c['uri'])]
- else:
- # Get all local connections
- conns = [c for c in connections if
- c['local'] == '1' and ('plex.direct' in c['uri'] or 'plex.service' in c['uri'])]
-
- if conns:
- # Get connection with matching address, otherwise return first connection
- conn = next((c for c in conns if c['address'] == server['pms_ip']
- and c['port'] == str(server['pms_port'])), conns[0])
- server['pms_url'] = conn['uri']
- logger.info("Tautulli PlexTV :: Server URL retrieved.")
-
- # get_server_urls() failed or PMS_URL not found, fallback url doesn't use SSL
- if not server['pms_url']:
- server['pms_url'] = fallback_url
- logger.warn("Tautulli PlexTV :: Unable to retrieve server URLs. Using user-defined value without SSL.")
-
- # Not using SSL, remote has no effect
- else:
- server['pms_url'] = fallback_url
- logger.info("Tautulli PlexTV :: Using user-defined URL.")
-
- if return_server:
- return server
-
- logger.info("Tautulli PlexTV :: Selected server: %s (%s) (%s - Version %s)",
- server['pms_name'], server['pms_url'], server['pms_platform'], server['pms_version'])
-
- jellypy.CONFIG.process_kwargs(server)
- jellypy.CONFIG.write()
-
-
-class PlexTV(object):
- """
- Plex.tv authentication
- """
-
- def __init__(self, username=None, password=None, token=None, headers=None):
- self.username = username
- self.password = password
- self.token = token
-
- self.urls = 'https://plex.tv'
- self.timeout = jellypy.CONFIG.PMS_TIMEOUT
- self.ssl_verify = jellypy.CONFIG.VERIFY_SSL_CERT
-
- if self.username is None and self.password is None:
- if not self.token:
- # Check if we should use the admin token, or the guest server token
- if session.get_session_user_id():
- user_data = users.Users()
- user_tokens = user_data.get_tokens(user_id=session.get_session_user_id())
- self.token = user_tokens['server_token']
- else:
- self.token = jellypy.CONFIG.PMS_TOKEN
-
- if not self.token:
- logger.error("Tautulli PlexTV :: PlexTV called, but no token provided.")
- return
-
- self.request_handler = http_handler.HTTPHandler(urls=self.urls,
- token=self.token,
- timeout=self.timeout,
- ssl_verify=self.ssl_verify,
- headers=headers)
-
- def get_plex_auth(self, output_format='raw'):
- uri = '/api/v2/users/signin'
- headers = {'Content-Type': 'application/x-www-form-urlencoded; charset=UTF-8',
- 'Accept': 'application/xml'}
- data = {'login': self.username,
- 'password': self.password,
- 'rememberMe': True}
-
- request = self.request_handler.make_request(uri=uri,
- request_type='POST',
- headers=headers,
- data=data,
- output_format=output_format,
- no_token=True,
- encode_multipart=False)
-
- return request
-
- def get_token(self):
- plextv_response = self.get_plex_auth(output_format='xml')
-
- if plextv_response:
- try:
- xml_head = plextv_response.getElementsByTagName('user')
- if xml_head:
- user = {'auth_token': xml_head[0].getAttribute('authToken'),
- 'user_id': xml_head[0].getAttribute('id')
- }
- else:
- logger.warn("Tautulli PlexTV :: Could not get Plex authentication token.")
- except Exception as e:
- logger.warn("Tautulli PlexTV :: Unable to parse XML for get_token: %s." % e)
- return None
-
- return user
- else:
- return None
-
- def get_plexpy_pms_token(self, force=False):
- if force:
- logger.debug("Tautulli PlexTV :: Forcing refresh of Plex.tv token.")
- devices_list = self.get_devices_list()
- device_id = next((d for d in devices_list if d['device_identifier'] == jellypy.CONFIG.PMS_UUID), {}).get(
- 'device_id', None)
-
- if device_id:
- logger.debug("Tautulli PlexTV :: Removing Tautulli from Plex.tv devices.")
- try:
- self.delete_plextv_device(device_id=device_id)
- except:
- logger.error("Tautulli PlexTV :: Failed to remove Tautulli from Plex.tv devices.")
- return None
- else:
- logger.warn("Tautulli PlexTV :: No existing Tautulli device found.")
-
- logger.info("Tautulli PlexTV :: Fetching a new Plex.tv token for Tautulli.")
- user = self.get_token()
- if user:
- token = user['auth_token']
- jellypy.CONFIG.__setattr__('PMS_TOKEN', token)
- jellypy.CONFIG.write()
- logger.info("Tautulli PlexTV :: Updated Plex.tv token for Tautulli.")
- return token
-
- def get_server_token(self):
- servers = self.get_plextv_resources(output_format='xml')
- server_token = ''
-
- try:
- xml_head = servers.getElementsByTagName('Device')
- except Exception as e:
- logger.warn("Tautulli PlexTV :: Unable to parse XML for get_server_token: %s." % e)
- return None
-
- for a in xml_head:
- if helpers.get_xml_attr(a, 'clientIdentifier') == jellypy.CONFIG.PMS_IDENTIFIER \
- and 'server' in helpers.get_xml_attr(a, 'provides'):
- server_token = helpers.get_xml_attr(a, 'accessToken')
- break
-
- return server_token
-
- def get_plextv_pin(self, pin='', output_format=''):
- if pin:
- uri = '/api/v2/pins/' + pin
- request = self.request_handler.make_request(uri=uri,
- request_type='GET',
- output_format=output_format,
- no_token=True)
- else:
- uri = '/api/v2/pins?strong=true'
- request = self.request_handler.make_request(uri=uri,
- request_type='POST',
- output_format=output_format,
- no_token=True)
- return request
-
- def get_pin(self, pin=''):
- plextv_response = self.get_plextv_pin(pin=pin,
- output_format='xml')
-
- if plextv_response:
- try:
- xml_head = plextv_response.getElementsByTagName('pin')
- if xml_head:
- pin = {'id': xml_head[0].getAttribute('id'),
- 'code': xml_head[0].getAttribute('code'),
- 'token': xml_head[0].getAttribute('authToken')
- }
- return pin
- else:
- logger.warn("Tautulli PlexTV :: Could not get Plex authentication pin.")
- return None
-
- except Exception as e:
- logger.warn("Tautulli PlexTV :: Unable to parse XML for get_pin: %s." % e)
- return None
-
- else:
- return None
-
- def get_plextv_user_data(self):
- plextv_response = self.get_plex_auth(output_format='dict')
-
- if plextv_response:
- return plextv_response
- else:
- return []
-
- def get_plextv_friends(self, output_format=''):
- uri = '/api/users'
- request = self.request_handler.make_request(uri=uri,
- request_type='GET',
- output_format=output_format)
-
- return request
-
- def get_plextv_user_details(self, output_format=''):
- uri = '/users/account'
- request = self.request_handler.make_request(uri=uri,
- request_type='GET',
- output_format=output_format)
-
- return request
-
- def get_plextv_devices_list(self, output_format=''):
- uri = '/devices.xml'
- request = self.request_handler.make_request(uri=uri,
- request_type='GET',
- output_format=output_format)
-
- return request
-
- def get_plextv_server_list(self, output_format=''):
- uri = '/pms/servers.xml'
- request = self.request_handler.make_request(uri=uri,
- request_type='GET',
- output_format=output_format)
-
- return request
-
- def get_plextv_shared_servers(self, machine_id='', output_format=''):
- uri = '/api/servers/%s/shared_servers' % machine_id
- request = self.request_handler.make_request(uri=uri,
- request_type='GET',
- output_format=output_format)
-
- return request
-
- def get_plextv_sync_lists(self, machine_id='', output_format=''):
- uri = '/servers/%s/sync_lists' % machine_id
- request = self.request_handler.make_request(uri=uri,
- request_type='GET',
- output_format=output_format)
-
- return request
-
- def get_plextv_resources(self, include_https=False, output_format=''):
- if include_https:
- uri = '/api/resources?includeHttps=1'
- else:
- uri = '/api/resources'
- request = self.request_handler.make_request(uri=uri,
- request_type='GET',
- output_format=output_format)
-
- return request
-
- def get_plextv_downloads(self, plexpass=False, output_format=''):
- if plexpass:
- uri = '/api/downloads/5.json?channel=plexpass'
- else:
- uri = '/api/downloads/1.json'
- request = self.request_handler.make_request(uri=uri,
- request_type='GET',
- output_format=output_format)
-
- return request
-
- def delete_plextv_device(self, device_id='', output_format=''):
- uri = '/devices/%s.xml' % device_id
- request = self.request_handler.make_request(uri=uri,
- request_type='DELETE',
- output_format=output_format)
-
- return request
-
- def delete_plextv_device_sync_lists(self, client_id='', output_format=''):
- uri = '/devices/%s/sync_items' % client_id
- request = self.request_handler.make_request(uri=uri,
- request_type='GET',
- output_format=output_format)
-
- return request
-
- def delete_plextv_sync(self, client_id='', sync_id='', output_format=''):
- uri = '/devices/%s/sync_items/%s' % (client_id, sync_id)
- request = self.request_handler.make_request(uri=uri,
- request_type='DELETE',
- output_format=output_format)
-
- return request
-
- def cloud_server_status(self, output_format=''):
- uri = '/api/v2/cloud_server'
- request = self.request_handler.make_request(uri=uri,
- request_type='GET',
- output_format=output_format)
-
- return request
-
- def get_plextv_geoip(self, ip_address='', output_format=''):
- uri = '/api/v2/geoip?ip_address=%s' % ip_address
- request = self.request_handler.make_request(uri=uri,
- request_type='GET',
- output_format=output_format)
-
- return request
-
- def get_full_users_list(self):
- own_account = self.get_plextv_user_details(output_format='xml')
- friends_list = self.get_plextv_friends(output_format='xml')
- shared_servers = self.get_plextv_shared_servers(machine_id=jellypy.CONFIG.PMS_IDENTIFIER,
- output_format='xml')
-
- users_list = []
-
- try:
- xml_head = own_account.getElementsByTagName('user')
- except Exception as e:
- logger.warn("Tautulli PlexTV :: Unable to parse own account XML for get_full_users_list: %s." % e)
- return []
-
- for a in xml_head:
- own_details = {"user_id": helpers.get_xml_attr(a, 'id'),
- "username": helpers.get_xml_attr(a, 'username'),
- "thumb": helpers.get_xml_attr(a, 'thumb'),
- "email": helpers.get_xml_attr(a, 'email'),
- "is_active": 1,
- "is_admin": 1,
- "is_home_user": helpers.get_xml_attr(a, 'home'),
- "is_allow_sync": 1,
- "is_restricted": helpers.get_xml_attr(a, 'restricted'),
- "filter_all": helpers.get_xml_attr(a, 'filterAll'),
- "filter_movies": helpers.get_xml_attr(a, 'filterMovies'),
- "filter_tv": helpers.get_xml_attr(a, 'filterTelevision'),
- "filter_music": helpers.get_xml_attr(a, 'filterMusic'),
- "filter_photos": helpers.get_xml_attr(a, 'filterPhotos'),
- "user_token": helpers.get_xml_attr(a, 'authToken'),
- "server_token": helpers.get_xml_attr(a, 'authToken'),
- "shared_libraries": None,
- }
-
- users_list.append(own_details)
-
- try:
- xml_head = friends_list.getElementsByTagName('User')
- except Exception as e:
- logger.warn("Tautulli PlexTV :: Unable to parse friends list XML for get_full_users_list: %s." % e)
- return []
-
- for a in xml_head:
- friend = {"user_id": helpers.get_xml_attr(a, 'id'),
- "username": helpers.get_xml_attr(a, 'title'),
- "thumb": helpers.get_xml_attr(a, 'thumb'),
- "email": helpers.get_xml_attr(a, 'email'),
- "is_active": 1,
- "is_admin": 0,
- "is_home_user": helpers.get_xml_attr(a, 'home'),
- "is_allow_sync": helpers.get_xml_attr(a, 'allowSync'),
- "is_restricted": helpers.get_xml_attr(a, 'restricted'),
- "filter_all": helpers.get_xml_attr(a, 'filterAll'),
- "filter_movies": helpers.get_xml_attr(a, 'filterMovies'),
- "filter_tv": helpers.get_xml_attr(a, 'filterTelevision'),
- "filter_music": helpers.get_xml_attr(a, 'filterMusic'),
- "filter_photos": helpers.get_xml_attr(a, 'filterPhotos')
- }
-
- users_list.append(friend)
-
- try:
- xml_head = shared_servers.getElementsByTagName('SharedServer')
- except Exception as e:
- logger.warn("Tautulli PlexTV :: Unable to parse shared server list XML for get_full_users_list: %s." % e)
- return []
-
- user_map = {}
- for a in xml_head:
- user_id = helpers.get_xml_attr(a, 'userID')
- server_token = helpers.get_xml_attr(a, 'accessToken')
-
- sections = a.getElementsByTagName('Section')
- shared_libraries = [helpers.get_xml_attr(s, 'key')
- for s in sections if helpers.get_xml_attr(s, 'shared') == '1']
-
- user_map[user_id] = {'server_token': server_token,
- 'shared_libraries': shared_libraries}
-
- for u in users_list:
- d = user_map.get(u['user_id'], {})
- u.update(d)
-
- return users_list
-
- def get_synced_items(self, machine_id=None, client_id_filter=None, user_id_filter=None,
- rating_key_filter=None, sync_id_filter=None):
-
- if not machine_id:
- machine_id = jellypy.CONFIG.PMS_IDENTIFIER
-
- if isinstance(rating_key_filter, list):
- rating_key_filter = [str(k) for k in rating_key_filter]
- elif rating_key_filter:
- rating_key_filter = [str(rating_key_filter)]
-
- if isinstance(user_id_filter, list):
- user_id_filter = [str(k) for k in user_id_filter]
- elif user_id_filter:
- user_id_filter = [str(user_id_filter)]
-
- sync_list = self.get_plextv_sync_lists(machine_id, output_format='xml')
- user_data = users.Users()
-
- synced_items = []
-
- try:
- xml_head = sync_list.getElementsByTagName('SyncList')
- except Exception as e:
- logger.warn("Tautulli PlexTV :: Unable to parse XML for get_synced_items: %s." % e)
- return {}
-
- for a in xml_head:
- client_id = helpers.get_xml_attr(a, 'clientIdentifier')
-
- # Filter by client_id
- if client_id_filter and str(client_id_filter) != client_id:
- continue
-
- sync_list_id = helpers.get_xml_attr(a, 'id')
- sync_device = a.getElementsByTagName('Device')
-
- for device in sync_device:
- device_user_id = helpers.get_xml_attr(device, 'userID')
- try:
- device_username = user_data.get_details(user_id=device_user_id)['username']
- device_friendly_name = user_data.get_details(user_id=device_user_id)['friendly_name']
- except:
- device_username = ''
- device_friendly_name = ''
- device_name = helpers.get_xml_attr(device, 'name')
- device_product = helpers.get_xml_attr(device, 'product')
- device_product_version = helpers.get_xml_attr(device, 'productVersion')
- device_platform = helpers.get_xml_attr(device, 'platform')
- device_platform_version = helpers.get_xml_attr(device, 'platformVersion')
- device_type = helpers.get_xml_attr(device, 'device')
- device_model = helpers.get_xml_attr(device, 'model')
- device_last_seen = helpers.get_xml_attr(device, 'lastSeenAt')
-
- # Filter by user_id
- if user_id_filter and device_user_id not in user_id_filter:
- continue
-
- for synced in a.getElementsByTagName('SyncItems'):
- sync_item = synced.getElementsByTagName('SyncItem')
- for item in sync_item:
-
- for location in item.getElementsByTagName('Location'):
- clean_uri = helpers.get_xml_attr(location, 'uri').split('%2F')
-
- rating_key = next((clean_uri[(idx + 1) % len(clean_uri)]
- for idx, item in enumerate(clean_uri) if item == 'metadata'), None)
-
- # Filter by rating_key
- if rating_key_filter and rating_key not in rating_key_filter:
- continue
-
- sync_id = helpers.get_xml_attr(item, 'id')
-
- # Filter by sync_id
- if sync_id_filter and str(sync_id_filter) != sync_id:
- continue
-
- sync_version = helpers.get_xml_attr(item, 'version')
- sync_root_title = helpers.get_xml_attr(item, 'rootTitle')
- sync_title = helpers.get_xml_attr(item, 'title')
- sync_metadata_type = helpers.get_xml_attr(item, 'metadataType')
- sync_content_type = helpers.get_xml_attr(item, 'contentType')
-
- for status in item.getElementsByTagName('Status'):
- status_failure_code = helpers.get_xml_attr(status, 'failureCode')
- status_failure = helpers.get_xml_attr(status, 'failure')
- status_state = helpers.get_xml_attr(status, 'state')
- status_item_count = helpers.get_xml_attr(status, 'itemsCount')
- status_item_complete_count = helpers.get_xml_attr(status, 'itemsCompleteCount')
- status_item_downloaded_count = helpers.get_xml_attr(status, 'itemsDownloadedCount')
- status_item_ready_count = helpers.get_xml_attr(status, 'itemsReadyCount')
- status_item_successful_count = helpers.get_xml_attr(status, 'itemsSuccessfulCount')
- status_total_size = helpers.get_xml_attr(status, 'totalSize')
- status_item_download_percent_complete = helpers.get_percent(
- status_item_downloaded_count, status_item_count)
-
- for settings in item.getElementsByTagName('MediaSettings'):
- settings_video_bitrate = helpers.get_xml_attr(settings, 'maxVideoBitrate')
- settings_video_quality = helpers.get_xml_attr(settings, 'videoQuality')
- settings_video_resolution = helpers.get_xml_attr(settings, 'videoResolution')
- settings_audio_boost = helpers.get_xml_attr(settings, 'audioBoost')
- settings_audio_bitrate = helpers.get_xml_attr(settings, 'musicBitrate')
- settings_photo_quality = helpers.get_xml_attr(settings, 'photoQuality')
- settings_photo_resolution = helpers.get_xml_attr(settings, 'photoResolution')
-
- sync_details = {"device_name": device_name,
- "platform": device_platform,
- "user_id": device_user_id,
- "user": device_friendly_name,
- "username": device_username,
- "root_title": sync_root_title,
- "sync_title": sync_title,
- "metadata_type": sync_metadata_type,
- "content_type": sync_content_type,
- "rating_key": rating_key,
- "state": status_state,
- "item_count": status_item_count,
- "item_complete_count": status_item_complete_count,
- "item_downloaded_count": status_item_downloaded_count,
- "item_downloaded_percent_complete": status_item_download_percent_complete,
- "video_bitrate": settings_video_bitrate,
- "audio_bitrate": settings_audio_bitrate,
- "photo_quality": settings_photo_quality,
- "video_quality": settings_video_quality,
- "total_size": status_total_size,
- "failure": status_failure,
- "client_id": client_id,
- "sync_id": sync_id
- }
-
- synced_items.append(sync_details)
-
- return session.filter_session_info(synced_items, filter_key='user_id')
-
- def delete_sync(self, client_id, sync_id):
- logger.info("Tautulli PlexTV :: Deleting sync item '%s'." % sync_id)
- self.delete_plextv_sync(client_id=client_id, sync_id=sync_id)
-
- def get_server_connections(self, pms_identifier='', pms_ip='', pms_port=32400, include_https=True):
-
- if not pms_identifier:
- logger.error("Tautulli PlexTV :: Unable to retrieve server connections: no pms_identifier provided.")
- return {}
-
- plextv_resources = self.get_plextv_resources(include_https=include_https,
- output_format='xml')
- try:
- xml_head = plextv_resources.getElementsByTagName('Device')
- except Exception as e:
- logger.warn("Tautulli PlexTV :: Unable to parse XML for get_server_urls: %s." % e)
- return {}
-
- # Function to get all connections for a device
- def get_connections(device):
- conn = []
- connections = device.getElementsByTagName('Connection')
-
- server = {'pms_identifier': helpers.get_xml_attr(device, 'clientIdentifier'),
- 'pms_name': helpers.get_xml_attr(device, 'name'),
- 'pms_version': helpers.get_xml_attr(device, 'productVersion'),
- 'pms_platform': helpers.get_xml_attr(device, 'platform'),
- 'pms_presence': helpers.get_xml_attr(device, 'presence'),
- 'pms_is_cloud': 1 if helpers.get_xml_attr(device, 'platform') == 'Cloud' else 0
- }
-
- for c in connections:
- server_details = {'protocol': helpers.get_xml_attr(c, 'protocol'),
- 'address': helpers.get_xml_attr(c, 'address'),
- 'port': helpers.get_xml_attr(c, 'port'),
- 'uri': helpers.get_xml_attr(c, 'uri'),
- 'local': helpers.get_xml_attr(c, 'local')
- }
- conn.append(server_details)
-
- server['connections'] = conn
- return server
-
- server = {}
-
- # Try to match the device
- for a in xml_head:
- if helpers.get_xml_attr(a, 'clientIdentifier') == pms_identifier:
- server = get_connections(a)
- break
-
- # Else no device match found
- if not server:
- # Try to match the PMS_IP and PMS_PORT
- for a in xml_head:
- if helpers.get_xml_attr(a, 'provides') == 'server':
- connections = a.getElementsByTagName('Connection')
-
- for connection in connections:
- if helpers.get_xml_attr(connection, 'address') == pms_ip and \
- helpers.get_xml_attr(connection, 'port') == str(pms_port):
- server = get_connections(a)
- break
-
- if server.get('connections'):
- break
-
- return server
-
- def get_server_times(self):
- servers = self.get_plextv_server_list(output_format='xml')
- server_times = {}
-
- try:
- xml_head = servers.getElementsByTagName('Server')
- except Exception as e:
- logger.warn("Tautulli PlexTV :: Unable to parse XML for get_server_times: %s." % e)
- return {}
-
- for a in xml_head:
- if helpers.get_xml_attr(a, 'machineIdentifier') == jellypy.CONFIG.PMS_IDENTIFIER:
- server_times = {"created_at": helpers.get_xml_attr(a, 'createdAt'),
- "updated_at": helpers.get_xml_attr(a, 'updatedAt'),
- "version": helpers.get_xml_attr(a, 'version')
- }
- break
-
- return server_times
-
- def discover(self, include_cloud=True, all_servers=False):
- """ Query plex for all servers online. Returns the ones you own in a selectize format """
-
- # Try to discover localhost server
- local_machine_identifier = None
- request_handler = http_handler.HTTPHandler(urls='http://127.0.0.1:32400', timeout=1,
- ssl_verify=False, silent=True)
- request = request_handler.make_request(uri='/identity', request_type='GET', output_format='xml')
- if request:
- xml_head = request.getElementsByTagName('MediaContainer')[0]
- local_machine_identifier = xml_head.getAttribute('machineIdentifier')
-
- local_server = {'httpsRequired': '0',
- 'clientIdentifier': local_machine_identifier,
- 'label': 'Local',
- 'ip': '127.0.0.1',
- 'port': '32400',
- 'uri': 'http://127.0.0.1:32400',
- 'local': '1',
- 'value': '127.0.0.1:32400',
- 'is_cloud': False
- }
-
- servers = self.get_plextv_resources(include_https=True, output_format='xml')
- clean_servers = []
-
- try:
- xml_head = servers.getElementsByTagName('MediaContainer')
- except Exception as e:
- logger.warn("Tautulli PlexTV :: Failed to get servers from plex: %s." % e)
- return []
-
- for a in xml_head:
- if a.getAttribute('size'):
- if a.getAttribute('size') == '0':
- return []
-
- if a.getElementsByTagName('Device'):
- devices = a.getElementsByTagName('Device')
-
- for d in devices:
- if helpers.get_xml_attr(d, 'presence') == '1' and \
- helpers.get_xml_attr(d, 'owned') == '1' and \
- helpers.get_xml_attr(d, 'provides') == 'server':
-
- is_cloud = (helpers.get_xml_attr(d, 'platform').lower() == 'cloud')
- if not include_cloud and is_cloud:
- continue
-
- connections = d.getElementsByTagName('Connection')
-
- for c in connections:
- if not all_servers:
- # If this is a remote server don't show any local IPs.
- if helpers.get_xml_attr(d, 'publicAddressMatches') == '0' and \
- helpers.get_xml_attr(c, 'local') == '1':
- continue
-
- # If this is a local server don't show any remote IPs.
- if helpers.get_xml_attr(d, 'publicAddressMatches') == '1' and \
- helpers.get_xml_attr(c, 'local') == '0':
- continue
-
- if helpers.get_xml_attr(d, 'clientIdentifier') == local_machine_identifier:
- local_server['httpsRequired'] = helpers.get_xml_attr(d, 'httpsRequired')
- local_server['label'] = helpers.get_xml_attr(d, 'name')
- clean_servers.append(local_server)
- local_machine_identifier = None
-
- server = {'httpsRequired': '1' if is_cloud else helpers.get_xml_attr(d, 'httpsRequired'),
- 'clientIdentifier': helpers.get_xml_attr(d, 'clientIdentifier'),
- 'label': helpers.get_xml_attr(d, 'name'),
- 'ip': helpers.get_xml_attr(c, 'address'),
- 'port': helpers.get_xml_attr(c, 'port'),
- 'uri': helpers.get_xml_attr(c, 'uri'),
- 'local': helpers.get_xml_attr(c, 'local'),
- 'value': helpers.get_xml_attr(c, 'address') + ':' + helpers.get_xml_attr(c,
- 'port'),
- 'is_cloud': is_cloud
- }
- clean_servers.append(server)
-
- if local_machine_identifier:
- clean_servers.append(local_server)
-
- clean_servers.sort(key=lambda s: (s['label'], -int(s['local']), s['ip']))
-
- return clean_servers
-
- def get_plex_downloads(self):
- logger.debug("Tautulli PlexTV :: Retrieving current server version.")
-
- pms_connect = pmsconnect.PmsConnect()
- pms_connect.set_server_version()
-
- update_channel = pms_connect.get_server_update_channel()
-
- logger.debug("Tautulli PlexTV :: Plex update channel is %s." % update_channel)
- plex_downloads = self.get_plextv_downloads(plexpass=(update_channel == 'beta'))
-
- try:
- available_downloads = json.loads(plex_downloads)
- except Exception as e:
- logger.warn("Tautulli PlexTV :: Unable to load JSON for get_plex_updates.")
- return {}
-
- # Get the updates for the platform
- pms_platform = common.PMS_PLATFORM_NAME_OVERRIDES.get(jellypy.CONFIG.PMS_PLATFORM, jellypy.CONFIG.PMS_PLATFORM)
- platform_downloads = available_downloads.get('computer').get(pms_platform) or \
- available_downloads.get('nas').get(pms_platform)
-
- if not platform_downloads:
- logger.error("Tautulli PlexTV :: Unable to retrieve Plex updates: Could not match server platform: %s."
- % pms_platform)
- return {}
-
- v_old = helpers.cast_to_int(
- "".join(v.zfill(4) for v in jellypy.CONFIG.PMS_VERSION.split('-')[0].split('.')[:4]))
- v_new = helpers.cast_to_int(
- "".join(v.zfill(4) for v in platform_downloads.get('version', '').split('-')[0].split('.')[:4]))
-
- if not v_old:
- logger.error("Tautulli PlexTV :: Unable to retrieve Plex updates: Invalid current server version: %s."
- % jellypy.CONFIG.PMS_VERSION)
- return {}
- if not v_new:
- logger.error("Tautulli PlexTV :: Unable to retrieve Plex updates: Invalid new server version: %s."
- % platform_downloads.get('version'))
- return {}
-
- # Get proper download
- releases = platform_downloads.get('releases', [{}])
- release = next((r for r in releases if r['distro'] == jellypy.CONFIG.PMS_UPDATE_DISTRO and
- r['build'] == jellypy.CONFIG.PMS_UPDATE_DISTRO_BUILD), releases[0])
-
- download_info = {'update_available': v_new > v_old,
- 'platform': platform_downloads.get('name'),
- 'release_date': platform_downloads.get('release_date'),
- 'version': platform_downloads.get('version'),
- 'requirements': platform_downloads.get('requirements'),
- 'extra_info': platform_downloads.get('extra_info'),
- 'changelog_added': platform_downloads.get('items_added'),
- 'changelog_fixed': platform_downloads.get('items_fixed'),
- 'label': release.get('label'),
- 'distro': release.get('distro'),
- 'distro_build': release.get('build'),
- 'download_url': release.get('url'),
- }
-
- return download_info
-
- def get_plexpass_status(self):
- account_data = self.get_plextv_user_details(output_format='xml')
-
- try:
- subscription = account_data.getElementsByTagName('subscription')
- except Exception as e:
- logger.warn("Tautulli PlexTV :: Unable to parse XML for get_plexpass_status: %s." % e)
- return False
-
- if subscription and helpers.get_xml_attr(subscription[0], 'active') == '1':
- jellypy.CONFIG.__setattr__('PMS_PLEXPASS', 1)
- jellypy.CONFIG.write()
- return True
- else:
- logger.debug("Tautulli PlexTV :: Plex Pass subscription not found.")
- jellypy.CONFIG.__setattr__('PMS_PLEXPASS', 0)
- jellypy.CONFIG.write()
- return False
-
- def get_devices_list(self):
- devices = self.get_plextv_devices_list(output_format='xml')
-
- try:
- xml_head = devices.getElementsByTagName('Device')
- except Exception as e:
- logger.warn("Tautulli PlexTV :: Unable to parse XML for get_devices_list: %s." % e)
- return []
-
- devices_list = []
- for a in xml_head:
- device = {"device_name": helpers.get_xml_attr(a, 'name'),
- "product": helpers.get_xml_attr(a, 'product'),
- "product_version": helpers.get_xml_attr(a, 'productVersion'),
- "platform": helpers.get_xml_attr(a, 'platform'),
- "platform_version": helpers.get_xml_attr(a, 'platformVersion'),
- "device": helpers.get_xml_attr(a, 'device'),
- "model": helpers.get_xml_attr(a, 'model'),
- "vendor": helpers.get_xml_attr(a, 'vendor'),
- "provides": helpers.get_xml_attr(a, 'provides'),
- "device_identifier": helpers.get_xml_attr(a, 'clientIdentifier'),
- "device_id": helpers.get_xml_attr(a, 'id'),
- "token": helpers.get_xml_attr(a, 'token')
- }
- devices_list.append(device)
-
- return devices_list
-
- def get_cloud_server_status(self):
- cloud_status = self.cloud_server_status(output_format='xml')
-
- try:
- status_info = cloud_status.getElementsByTagName('info')
- except Exception as e:
- logger.warn("Tautulli PlexTV :: Unable to parse XML for get_cloud_server_status: %s." % e)
- return False
-
- for info in status_info:
- servers = info.getElementsByTagName('server')
- for s in servers:
- if helpers.get_xml_attr(s, 'address') == jellypy.CONFIG.PMS_IP:
- if helpers.get_xml_attr(info, 'running') == '1':
- return True
- else:
- return False
-
- def get_plex_account_details(self):
- account_data = self.get_plextv_user_details(output_format='xml')
-
- try:
- xml_head = account_data.getElementsByTagName('user')
- except Exception as e:
- logger.warn("Tautulli PlexTV :: Unable to parse XML for get_plex_account_details: %s." % e)
- return None
-
- for a in xml_head:
- account_details = {"user_id": helpers.get_xml_attr(a, 'id'),
- "username": helpers.get_xml_attr(a, 'username'),
- "thumb": helpers.get_xml_attr(a, 'thumb'),
- "email": helpers.get_xml_attr(a, 'email'),
- "is_home_user": helpers.get_xml_attr(a, 'home'),
- "is_restricted": helpers.get_xml_attr(a, 'restricted'),
- "filter_all": helpers.get_xml_attr(a, 'filterAll'),
- "filter_movies": helpers.get_xml_attr(a, 'filterMovies'),
- "filter_tv": helpers.get_xml_attr(a, 'filterTelevision'),
- "filter_music": helpers.get_xml_attr(a, 'filterMusic'),
- "filter_photos": helpers.get_xml_attr(a, 'filterPhotos'),
- "user_token": helpers.get_xml_attr(a, 'authToken')
- }
- return account_details
-
- def get_geoip_lookup(self, ip_address=''):
- if not ip_address or not helpers.is_valid_ip(ip_address):
- return
-
- geoip_data = self.get_plextv_geoip(ip_address=ip_address, output_format='xml')
-
- try:
- xml_head = geoip_data.getElementsByTagName('location')
- except Exception as e:
- logger.warn(u"Tautulli PlexTV :: Unable to parse XML for get_geoip_lookup: %s." % e)
- return None
-
- for a in xml_head:
- coordinates = helpers.get_xml_attr(a, 'coordinates').split(',')
- latitude = longitude = None
- if len(coordinates) == 2:
- latitude, longitude = [helpers.cast_to_float(c) for c in coordinates]
-
- geo_info = {"code": helpers.get_xml_attr(a, 'code') or None,
- "country": helpers.get_xml_attr(a, 'country') or None,
- "region": helpers.get_xml_attr(a, 'subdivisions') or None,
- "city": helpers.get_xml_attr(a, 'city') or None,
- "postal_code": helpers.get_xml_attr(a, 'postal_code') or None,
- "timezone": helpers.get_xml_attr(a, 'time_zone') or None,
- "latitude": latitude,
- "longitude": longitude,
- "continent": None, # keep for backwards compatibility with GeoLite2
- "accuracy": None # keep for backwards compatibility with GeoLite2
- }
-
- return geo_info
diff --git a/jellypy/pmsconnect.py b/jellypy/pmsconnect.py
deleted file mode 100644
index 5edb8a8d..00000000
--- a/jellypy/pmsconnect.py
+++ /dev/null
@@ -1,3173 +0,0 @@
-# -*- coding: utf-8 -*-
-
-# This file is part of Tautulli.
-#
-# Tautulli is free software: you can redistribute it and/or modify
-# it under the terms of the GNU General Public License as published by
-# the Free Software Foundation, either version 3 of the License, or
-# (at your option) any later version.
-#
-# Tautulli is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-# GNU General Public License for more details.
-#
-# You should have received a copy of the GNU General Public License
-# along with Tautulli. If not, see .
-
-import json
-import os
-from urllib.parse import quote_plus, quote, urlencode
-from xml.dom.minidom import Node
-
-import jellypy
-from jellypy import activity_processor
-from jellypy import common
-from jellypy import helpers
-from jellypy import http_handler
-from jellypy import libraries
-from jellypy import logger
-from jellypy import plextv
-from jellypy import session
-from jellypy import users
-
-
-def get_server_friendly_name():
- logger.info("Tautulli Pmsconnect :: Requesting name from server...")
- server_name = PmsConnect().get_server_pref(pref='FriendlyName')
-
- # If friendly name is blank
- if not server_name:
- servers_info = PmsConnect().get_servers_info()
- for server in servers_info:
- if server['machine_identifier'] == jellypy.CONFIG.PMS_IDENTIFIER:
- server_name = server['name']
- break
-
- if server_name and server_name != jellypy.CONFIG.PMS_NAME:
- jellypy.CONFIG.__setattr__('PMS_NAME', server_name)
- jellypy.CONFIG.write()
- logger.info("Tautulli Pmsconnect :: Server name retrieved.")
-
- return server_name
-
-
-class PmsConnect(object):
- """
- Retrieve data from Plex Server
- """
-
- def __init__(self, url=None, token=None):
- self.url = url
- self.token = token
-
- if not self.url and jellypy.CONFIG.PMS_URL:
- self.url = jellypy.CONFIG.PMS_URL
- elif not self.url:
- self.url = 'http://{hostname}:{port}'.format(hostname=jellypy.CONFIG.PMS_IP,
- port=jellypy.CONFIG.PMS_PORT)
- self.timeout = jellypy.CONFIG.PMS_TIMEOUT
-
- if not self.token:
- # Check if we should use the admin token, or the guest server token
- if session.get_session_user_id():
- user_data = users.Users()
- user_tokens = user_data.get_tokens(user_id=session.get_session_user_id())
- self.token = user_tokens['server_token']
- else:
- self.token = jellypy.CONFIG.PMS_TOKEN
-
- self.request_handler = http_handler.HTTPHandler(urls=self.url,
- token=self.token,
- timeout=self.timeout)
-
- def get_sessions(self, output_format=''):
- """
- Return current sessions.
-
- Optional parameters: output_format { dict, json }
-
- Output: array
- """
- uri = '/status/sessions'
- request = self.request_handler.make_request(uri=uri,
- request_type='GET',
- output_format=output_format)
-
- return request
-
- def get_sessions_terminate(self, session_id='', reason='', output_format=''):
- """
- Return current sessions.
-
- Optional parameters: output_format { dict, json }
-
- Output: array
- """
- uri = '/status/sessions/terminate?sessionId=%s&reason=%s' % (session_id, quote_plus(reason))
- request = self.request_handler.make_request(uri=uri,
- request_type='GET',
- output_format=output_format)
-
- return request
-
- def get_metadata(self, rating_key='', output_format=''):
- """
- Return metadata for request item.
-
- Parameters required: rating_key { Plex ratingKey }
- Optional parameters: output_format { dict, json }
-
- Output: array
- """
- uri = '/library/metadata/' + rating_key
- request = self.request_handler.make_request(uri=uri,
- request_type='GET',
- output_format=output_format)
-
- return request
-
- def get_metadata_children(self, rating_key='', output_format=''):
- """
- Return metadata for children of the request item.
-
- Parameters required: rating_key { Plex ratingKey }
- Optional parameters: output_format { dict, json }
-
- Output: array
- """
- uri = '/library/metadata/' + rating_key + '/children'
- request = self.request_handler.make_request(uri=uri,
- request_type='GET',
- output_format=output_format)
-
- return request
-
- def get_metadata_grandchildren(self, rating_key='', output_format=''):
- """
- Return metadata for graandchildren of the request item.
-
- Parameters required: rating_key { Plex ratingKey }
- Optional parameters: output_format { dict, json }
-
- Output: array
- """
- uri = '/library/metadata/' + rating_key + '/grandchildren'
- request = self.request_handler.make_request(uri=uri,
- request_type='GET',
- output_format=output_format)
-
- return request
-
- def get_playlist_items(self, rating_key='', output_format=''):
- """
- Return metadata for items of the requested playlist.
-
- Parameters required: rating_key { Plex ratingKey }
- Optional parameters: output_format { dict, json }
-
- Output: array
- """
- uri = '/playlists/' + rating_key + '/items'
- request = self.request_handler.make_request(uri=uri,
- request_type='GET',
- output_format=output_format)
-
- return request
-
- def get_recently_added(self, start='0', count='0', output_format=''):
- """
- Return list of recently added items.
-
- Parameters required: count { number of results to return }
- Optional parameters: output_format { dict, json }
-
- Output: array
- """
- uri = '/library/recentlyAdded?X-Plex-Container-Start=%s&X-Plex-Container-Size=%s' % (start, count)
- request = self.request_handler.make_request(uri=uri,
- request_type='GET',
- output_format=output_format)
-
- return request
-
- def get_library_recently_added(self, section_id='', start='0', count='0', output_format=''):
- """
- Return list of recently added items.
-
- Parameters required: count { number of results to return }
- Optional parameters: output_format { dict, json }
-
- Output: array
- """
- uri = '/library/sections/%s/recentlyAdded?X-Plex-Container-Start=%s&X-Plex-Container-Size=%s' % (
- section_id, start, count)
- request = self.request_handler.make_request(uri=uri,
- request_type='GET',
- output_format=output_format)
-
- return request
-
- def get_children_list_related(self, rating_key='', output_format=''):
- """
- Return list of related children in requested collection item.
-
- Parameters required: rating_key { ratingKey of parent }
- Optional parameters: output_format { dict, json }
-
- Output: array
- """
- uri = '/hubs/metadata/' + rating_key + '/related'
- request = self.request_handler.make_request(uri=uri,
- request_type='GET',
- output_format=output_format)
-
- 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,
- request_type='GET',
- output_format=output_format)
-
- return request
-
- def get_server_list(self, output_format=''):
- """
- Return list of local servers.
-
- Optional parameters: output_format { dict, json }
-
- Output: array
- """
- uri = '/servers'
- request = self.request_handler.make_request(uri=uri,
- request_type='GET',
- output_format=output_format)
-
- return request
-
- def get_server_prefs(self, output_format=''):
- """
- Return the local servers preferences.
-
- Optional parameters: output_format { dict, json }
-
- Output: array
- """
- uri = '/:/prefs'
- request = self.request_handler.make_request(uri=uri,
- request_type='GET',
- output_format=output_format)
-
- return request
-
- def get_local_server_identity(self, output_format=''):
- """
- Return the local server identity.
-
- Optional parameters: output_format { dict, json }
-
- Output: array
- """
- uri = '/identity'
- request = self.request_handler.make_request(uri=uri,
- request_type='GET',
- output_format=output_format)
-
- return request
-
- def get_libraries_list(self, output_format=''):
- """
- Return list of libraries on server.
-
- Optional parameters: output_format { dict, json }
-
- Output: array
- """
- uri = '/library/sections'
- request = self.request_handler.make_request(uri=uri,
- request_type='GET',
- output_format=output_format)
-
- return request
-
- def get_library_list(self, section_id='', list_type='all', count='0', sort_type='', label_key='', output_format=''):
- """
- Return list of items in library on server.
-
- Optional parameters: output_format { dict, json }
-
- Output: array
- """
- count = '&X-Plex-Container-Size=' + count if count else ''
- label_key = '&label=' + label_key if label_key else ''
-
- uri = '/library/sections/' + section_id + '/' + list_type + '?X-Plex-Container-Start=0' + count + sort_type + label_key
- request = self.request_handler.make_request(uri=uri,
- request_type='GET',
- output_format=output_format)
-
- return request
-
- def get_library_labels(self, section_id='', output_format=''):
- """
- Return list of labels for a library on server.
-
- Optional parameters: output_format { dict, json }
-
- Output: array
- """
- uri = '/library/sections/' + section_id + '/label'
- request = self.request_handler.make_request(uri=uri,
- request_type='GET',
- output_format=output_format)
-
- return request
-
- def get_sync_item(self, sync_id='', output_format=''):
- """
- Return sync item details.
-
- Parameters required: sync_id { unique sync id for item }
- Optional parameters: output_format { dict, json }
-
- Output: array
- """
- uri = '/sync/items/' + sync_id
- request = self.request_handler.make_request(uri=uri,
- request_type='GET',
- output_format=output_format)
-
- return request
-
- def get_sync_transcode_queue(self, output_format=''):
- """
- Return sync transcode queue.
-
- Optional parameters: output_format { dict, json }
-
- Output: array
- """
- uri = '/sync/transcodeQueue'
- request = self.request_handler.make_request(uri=uri,
- request_type='GET',
- output_format=output_format)
-
- return request
-
- def get_search(self, query='', limit='', output_format=''):
- """
- Return search results.
-
- Optional parameters: output_format { dict, json }
-
- Output: array
- """
- uri = '/hubs/search?query=' + quote(query.encode('utf8')) + '&limit=' + limit + '&includeCollections=1'
- request = self.request_handler.make_request(uri=uri,
- request_type='GET',
- output_format=output_format)
-
- return request
-
- def get_account(self, output_format=''):
- """
- Return account details.
-
- Optional parameters: output_format { dict, json }
-
- Output: array
- """
- uri = '/myplex/account'
- request = self.request_handler.make_request(uri=uri,
- request_type='GET',
- output_format=output_format)
-
- return request
-
- def put_refresh_reachability(self):
- """
- Refresh Plex remote access port mapping.
-
- Optional parameters: None
-
- Output: None
- """
- uri = '/myplex/refreshReachability'
- request = self.request_handler.make_request(uri=uri,
- request_type='PUT')
-
- return request
-
- def put_updater(self, output_format=''):
- """
- Refresh updater status.
-
- Optional parameters: output_format { dict, json }
-
- Output: array
- """
- uri = '/updater/check?download=0'
- request = self.request_handler.make_request(uri=uri,
- request_type='PUT',
- output_format=output_format)
-
- return request
-
- def get_updater(self, output_format=''):
- """
- Return updater status.
-
- Optional parameters: output_format { dict, json }
-
- Output: array
- """
- uri = '/updater/status'
- request = self.request_handler.make_request(uri=uri,
- request_type='GET',
- output_format=output_format)
-
- return request
-
- def get_hub_recently_added(self, start='0', count='0', media_type='', other_video=False, output_format=''):
- """
- Return Plex hub recently added.
-
- Parameters required: start { item number to start from }
- count { number of results to return }
- media_type { str }
- Optional parameters: output_format { dict, json }
-
- Output: array
- """
- personal = '&personal=1' if other_video else ''
- uri = '/hubs/home/recentlyAdded?X-Plex-Container-Start=%s&X-Plex-Container-Size=%s&type=%s%s' \
- % (start, count, media_type, personal)
- request = self.request_handler.make_request(uri=uri,
- request_type='GET',
- output_format=output_format)
-
- return request
-
- def get_recently_added_details(self, start='0', count='0', media_type='', section_id=''):
- """
- Return processed and validated list of recently added items.
-
- Parameters required: count { number of results to return }
-
- Output: array
- """
- media_types = ('movie', 'show', 'artist', 'other_video')
- recents_list = []
-
- if media_type in media_types:
- other_video = False
- if media_type == 'movie':
- media_type = '1'
- elif media_type == 'show':
- media_type = '2'
- elif media_type == 'artist':
- media_type = '8'
- elif media_type == 'other_video':
- media_type = '1'
- other_video = True
- recent = self.get_hub_recently_added(start, count, media_type, other_video, output_format='xml')
- elif section_id:
- recent = self.get_library_recently_added(section_id, start, count, output_format='xml')
- else:
- for media_type in media_types:
- recents = self.get_recently_added_details(start, count, media_type)
- recents_list += recents['recently_added']
-
- output = {'recently_added': sorted(recents_list, key=lambda k: k['added_at'], reverse=True)[:int(count)]}
- return output
-
- try:
- xml_head = recent.getElementsByTagName('MediaContainer')
- except Exception as e:
- logger.warn("Tautulli Pmsconnect :: Unable to parse XML for get_recently_added: %s." % e)
- return []
-
- for a in xml_head:
- if a.getAttribute('size'):
- if a.getAttribute('size') == '0':
- output = {'recently_added': []}
- return output
-
- recents_main = []
- if a.getElementsByTagName('Directory'):
- recents_main += a.getElementsByTagName('Directory')
- if a.getElementsByTagName('Video'):
- recents_main += a.getElementsByTagName('Video')
-
- for m in recents_main:
- directors = []
- writers = []
- actors = []
- genres = []
- labels = []
- collections = []
- guids = []
-
- if m.getElementsByTagName('Director'):
- for director in m.getElementsByTagName('Director'):
- directors.append(helpers.get_xml_attr(director, 'tag'))
-
- if m.getElementsByTagName('Writer'):
- for writer in m.getElementsByTagName('Writer'):
- writers.append(helpers.get_xml_attr(writer, 'tag'))
-
- if m.getElementsByTagName('Role'):
- for actor in m.getElementsByTagName('Role'):
- actors.append(helpers.get_xml_attr(actor, 'tag'))
-
- if m.getElementsByTagName('Genre'):
- for genre in m.getElementsByTagName('Genre'):
- genres.append(helpers.get_xml_attr(genre, 'tag'))
-
- if m.getElementsByTagName('Label'):
- for label in m.getElementsByTagName('Label'):
- labels.append(helpers.get_xml_attr(label, 'tag'))
-
- if m.getElementsByTagName('Collection'):
- for collection in m.getElementsByTagName('Collection'):
- collections.append(helpers.get_xml_attr(collection, 'tag'))
-
- if m.getElementsByTagName('Guid'):
- for guid in m.getElementsByTagName('Guid'):
- guids.append(helpers.get_xml_attr(guid, 'id'))
-
- recent_item = {'media_type': helpers.get_xml_attr(m, 'type'),
- 'section_id': helpers.get_xml_attr(m, 'librarySectionID'),
- 'library_name': helpers.get_xml_attr(m, 'librarySectionTitle'),
- 'rating_key': helpers.get_xml_attr(m, 'ratingKey'),
- 'parent_rating_key': helpers.get_xml_attr(m, 'parentRatingKey'),
- 'grandparent_rating_key': helpers.get_xml_attr(m, 'grandparentRatingKey'),
- 'title': helpers.get_xml_attr(m, 'title'),
- 'parent_title': helpers.get_xml_attr(m, 'parentTitle'),
- 'grandparent_title': helpers.get_xml_attr(m, 'grandparentTitle'),
- 'original_title': helpers.get_xml_attr(m, 'originalTitle'),
- 'sort_title': helpers.get_xml_attr(m, 'titleSort'),
- 'media_index': helpers.get_xml_attr(m, 'index'),
- 'parent_media_index': helpers.get_xml_attr(m, 'parentIndex'),
- 'studio': helpers.get_xml_attr(m, 'studio'),
- 'content_rating': helpers.get_xml_attr(m, 'contentRating'),
- 'summary': helpers.get_xml_attr(m, 'summary'),
- 'tagline': helpers.get_xml_attr(m, 'tagline'),
- 'rating': helpers.get_xml_attr(m, 'rating'),
- 'rating_image': helpers.get_xml_attr(m, 'ratingImage'),
- 'audience_rating': helpers.get_xml_attr(m, 'audienceRating'),
- 'audience_rating_image': helpers.get_xml_attr(m, 'audienceRatingImage'),
- 'user_rating': helpers.get_xml_attr(m, 'userRating'),
- 'duration': helpers.get_xml_attr(m, 'duration'),
- 'year': helpers.get_xml_attr(m, 'year'),
- 'thumb': helpers.get_xml_attr(m, 'thumb'),
- 'parent_thumb': helpers.get_xml_attr(m, 'parentThumb'),
- 'grandparent_thumb': helpers.get_xml_attr(m, 'grandparentThumb'),
- 'art': helpers.get_xml_attr(m, 'art'),
- 'banner': helpers.get_xml_attr(m, 'banner'),
- 'originally_available_at': helpers.get_xml_attr(m, 'originallyAvailableAt'),
- 'added_at': helpers.get_xml_attr(m, 'addedAt'),
- 'updated_at': helpers.get_xml_attr(m, 'updatedAt'),
- 'last_viewed_at': helpers.get_xml_attr(m, 'lastViewedAt'),
- 'guid': helpers.get_xml_attr(m, 'guid'),
- 'directors': directors,
- 'writers': writers,
- 'actors': actors,
- 'genres': genres,
- 'labels': labels,
- 'collections': collections,
- 'guids': guids,
- 'full_title': helpers.get_xml_attr(m, 'title'),
- 'child_count': helpers.get_xml_attr(m, 'childCount')
- }
-
- recents_list.append(recent_item)
-
- output = {'recently_added': sorted(recents_list, key=lambda k: k['added_at'], reverse=True)}
-
- return output
-
- def get_metadata_details(self, rating_key='', sync_id='', plex_guid='', section_id='',
- skip_cache=False, cache_key=None, return_cache=False, media_info=True):
- """
- Return processed and validated metadata list for requested item.
-
- Parameters required: rating_key { Plex ratingKey }
-
- Output: array
- """
- metadata = {}
-
- if not skip_cache and cache_key:
- in_file_folder = os.path.join(jellypy.CONFIG.CACHE_DIR, 'session_metadata')
- in_file_path = os.path.join(in_file_folder, 'metadata-sessionKey-%s.json' % cache_key)
-
- if not os.path.exists(in_file_folder):
- os.mkdir(in_file_folder)
-
- try:
- with open(in_file_path, 'r') as inFile:
- metadata = json.load(inFile)
- except (IOError, ValueError) as e:
- pass
-
- if metadata:
- _cache_time = metadata.pop('_cache_time', 0)
- # Return cached metadata if less than cache_seconds ago
- if return_cache or helpers.timestamp() - _cache_time <= jellypy.CONFIG.METADATA_CACHE_SECONDS:
- return metadata
-
- if rating_key:
- metadata_xml = self.get_metadata(str(rating_key), output_format='xml')
- elif sync_id:
- metadata_xml = self.get_sync_item(str(sync_id), output_format='xml')
- elif plex_guid.startswith(('plex://movie', 'plex://episode')):
- rating_key = plex_guid.rsplit('/', 1)[-1]
- plextv_metadata = PmsConnect(url='https://metadata.provider.plex.tv', token=jellypy.CONFIG.PMS_TOKEN)
- metadata_xml = plextv_metadata.get_metadata(rating_key, output_format='xml')
- else:
- return metadata
-
- try:
- xml_head = metadata_xml.getElementsByTagName('MediaContainer')
- except Exception as e:
- logger.warn("Tautulli Pmsconnect :: Unable to parse XML for get_metadata_details: %s." % e)
- return {}
-
- for a in xml_head:
- if a.getAttribute('size'):
- if a.getAttribute('size') == '0':
- return metadata
-
- if a.getElementsByTagName('Directory'):
- metadata_main_list = a.getElementsByTagName('Directory')
- elif a.getElementsByTagName('Video'):
- metadata_main_list = a.getElementsByTagName('Video')
- elif a.getElementsByTagName('Track'):
- metadata_main_list = a.getElementsByTagName('Track')
- elif a.getElementsByTagName('Photo'):
- metadata_main_list = a.getElementsByTagName('Photo')
- elif a.getElementsByTagName('Playlist'):
- metadata_main_list = a.getElementsByTagName('Playlist')
- else:
- logger.debug("Tautulli Pmsconnect :: Metadata failed")
- return {}
-
- if sync_id and len(metadata_main_list) > 1:
- for metadata_main in metadata_main_list:
- if helpers.get_xml_attr(metadata_main, 'ratingKey') == rating_key:
- break
- else:
- metadata_main = metadata_main_list[0]
-
- metadata_type = helpers.get_xml_attr(metadata_main, 'type')
- if metadata_main.nodeName == 'Directory' and metadata_type == 'photo':
- metadata_type = 'photo_album'
-
- section_id = helpers.get_xml_attr(a, 'librarySectionID') or section_id
- library_name = helpers.get_xml_attr(a, 'librarySectionTitle')
-
- if not library_name and section_id:
- library_data = libraries.Libraries().get_details(section_id)
- library_name = library_data['section_name']
-
- directors = []
- writers = []
- actors = []
- genres = []
- labels = []
- collections = []
- guids = []
-
- if metadata_main.getElementsByTagName('Director'):
- for director in metadata_main.getElementsByTagName('Director'):
- directors.append(helpers.get_xml_attr(director, 'tag'))
-
- if metadata_main.getElementsByTagName('Writer'):
- for writer in metadata_main.getElementsByTagName('Writer'):
- writers.append(helpers.get_xml_attr(writer, 'tag'))
-
- if metadata_main.getElementsByTagName('Role'):
- for actor in metadata_main.getElementsByTagName('Role'):
- actors.append(helpers.get_xml_attr(actor, 'tag'))
-
- if metadata_main.getElementsByTagName('Genre'):
- for genre in metadata_main.getElementsByTagName('Genre'):
- genres.append(helpers.get_xml_attr(genre, 'tag'))
-
- if metadata_main.getElementsByTagName('Label'):
- for label in metadata_main.getElementsByTagName('Label'):
- labels.append(helpers.get_xml_attr(label, 'tag'))
-
- if metadata_main.getElementsByTagName('Collection'):
- for collection in metadata_main.getElementsByTagName('Collection'):
- collections.append(helpers.get_xml_attr(collection, 'tag'))
-
- if metadata_main.getElementsByTagName('Guid'):
- for guid in metadata_main.getElementsByTagName('Guid'):
- guids.append(helpers.get_xml_attr(guid, 'id'))
-
- if metadata_type == 'movie':
- metadata = {'media_type': metadata_type,
- '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'),
- 'grandparent_rating_key': helpers.get_xml_attr(metadata_main, 'grandparentRatingKey'),
- 'title': helpers.get_xml_attr(metadata_main, 'title'),
- 'parent_title': helpers.get_xml_attr(metadata_main, 'parentTitle'),
- 'grandparent_title': helpers.get_xml_attr(metadata_main, 'grandparentTitle'),
- 'original_title': helpers.get_xml_attr(metadata_main, 'originalTitle'),
- 'sort_title': helpers.get_xml_attr(metadata_main, 'titleSort'),
- 'media_index': helpers.get_xml_attr(metadata_main, 'index'),
- 'parent_media_index': helpers.get_xml_attr(metadata_main, 'parentIndex'),
- 'studio': helpers.get_xml_attr(metadata_main, 'studio'),
- 'content_rating': helpers.get_xml_attr(metadata_main, 'contentRating'),
- 'summary': helpers.get_xml_attr(metadata_main, 'summary'),
- 'tagline': helpers.get_xml_attr(metadata_main, 'tagline'),
- 'rating': helpers.get_xml_attr(metadata_main, 'rating'),
- 'rating_image': helpers.get_xml_attr(metadata_main, 'ratingImage'),
- 'audience_rating': helpers.get_xml_attr(metadata_main, 'audienceRating'),
- 'audience_rating_image': helpers.get_xml_attr(metadata_main, 'audienceRatingImage'),
- 'user_rating': helpers.get_xml_attr(metadata_main, 'userRating'),
- 'duration': helpers.get_xml_attr(metadata_main, 'duration'),
- 'year': helpers.get_xml_attr(metadata_main, 'year'),
- 'thumb': helpers.get_xml_attr(metadata_main, 'thumb'),
- 'parent_thumb': helpers.get_xml_attr(metadata_main, 'parentThumb'),
- 'grandparent_thumb': helpers.get_xml_attr(metadata_main, 'grandparentThumb'),
- 'art': helpers.get_xml_attr(metadata_main, 'art'),
- 'banner': helpers.get_xml_attr(metadata_main, 'banner'),
- 'originally_available_at': helpers.get_xml_attr(metadata_main, 'originallyAvailableAt'),
- 'added_at': helpers.get_xml_attr(metadata_main, 'addedAt'),
- 'updated_at': helpers.get_xml_attr(metadata_main, 'updatedAt'),
- 'last_viewed_at': helpers.get_xml_attr(metadata_main, 'lastViewedAt'),
- 'guid': helpers.get_xml_attr(metadata_main, 'guid'),
- 'parent_guid': helpers.get_xml_attr(metadata_main, 'parentGuid'),
- 'grandparent_guid': helpers.get_xml_attr(metadata_main, 'grandparentGuid'),
- 'directors': directors,
- 'writers': writers,
- 'actors': actors,
- 'genres': genres,
- 'labels': labels,
- 'collections': collections,
- 'guids': guids,
- 'full_title': helpers.get_xml_attr(metadata_main, 'title'),
- 'children_count': helpers.cast_to_int(helpers.get_xml_attr(metadata_main, 'leafCount')),
- 'live': int(helpers.get_xml_attr(metadata_main, 'live') == '1')
- }
-
- elif metadata_type == 'show':
- # Workaround for for duration sometimes reported in minutes for a show
- duration = helpers.get_xml_attr(metadata_main, 'duration')
- if duration.isdigit() and int(duration) < 1000:
- duration = str(int(duration) * 60 * 1000)
-
- metadata = {'media_type': metadata_type,
- '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'),
- 'grandparent_rating_key': helpers.get_xml_attr(metadata_main, 'grandparentRatingKey'),
- 'title': helpers.get_xml_attr(metadata_main, 'title'),
- 'parent_title': helpers.get_xml_attr(metadata_main, 'parentTitle'),
- 'grandparent_title': helpers.get_xml_attr(metadata_main, 'grandparentTitle'),
- 'original_title': helpers.get_xml_attr(metadata_main, 'originalTitle'),
- 'sort_title': helpers.get_xml_attr(metadata_main, 'titleSort'),
- 'media_index': helpers.get_xml_attr(metadata_main, 'index'),
- 'parent_media_index': helpers.get_xml_attr(metadata_main, 'parentIndex'),
- 'studio': helpers.get_xml_attr(metadata_main, 'studio'),
- 'content_rating': helpers.get_xml_attr(metadata_main, 'contentRating'),
- 'summary': helpers.get_xml_attr(metadata_main, 'summary'),
- 'tagline': helpers.get_xml_attr(metadata_main, 'tagline'),
- 'rating': helpers.get_xml_attr(metadata_main, 'rating'),
- 'rating_image': helpers.get_xml_attr(metadata_main, 'ratingImage'),
- 'audience_rating': helpers.get_xml_attr(metadata_main, 'audienceRating'),
- 'audience_rating_image': helpers.get_xml_attr(metadata_main, 'audienceRatingImage'),
- 'user_rating': helpers.get_xml_attr(metadata_main, 'userRating'),
- 'duration': duration,
- 'year': helpers.get_xml_attr(metadata_main, 'year'),
- 'thumb': helpers.get_xml_attr(metadata_main, 'thumb'),
- 'parent_thumb': helpers.get_xml_attr(metadata_main, 'parentThumb'),
- 'grandparent_thumb': helpers.get_xml_attr(metadata_main, 'grandparentThumb'),
- 'art': helpers.get_xml_attr(metadata_main, 'art'),
- 'banner': helpers.get_xml_attr(metadata_main, 'banner'),
- 'originally_available_at': helpers.get_xml_attr(metadata_main, 'originallyAvailableAt'),
- 'added_at': helpers.get_xml_attr(metadata_main, 'addedAt'),
- 'updated_at': helpers.get_xml_attr(metadata_main, 'updatedAt'),
- 'last_viewed_at': helpers.get_xml_attr(metadata_main, 'lastViewedAt'),
- 'guid': helpers.get_xml_attr(metadata_main, 'guid'),
- 'parent_guid': helpers.get_xml_attr(metadata_main, 'parentGuid'),
- 'grandparent_guid': helpers.get_xml_attr(metadata_main, 'grandparentGuid'),
- 'directors': directors,
- 'writers': writers,
- 'actors': actors,
- 'genres': genres,
- 'labels': labels,
- 'collections': collections,
- 'guids': guids,
- 'full_title': helpers.get_xml_attr(metadata_main, 'title'),
- 'children_count': helpers.cast_to_int(helpers.get_xml_attr(metadata_main, 'leafCount')),
- 'live': int(helpers.get_xml_attr(metadata_main, 'live') == '1')
- }
-
- elif metadata_type == 'season':
- parent_rating_key = helpers.get_xml_attr(metadata_main, 'parentRatingKey')
- parent_guid = helpers.get_xml_attr(metadata_main, 'parentGuid')
- show_details = {}
- if plex_guid and parent_guid:
- show_details = self.get_metadata_details(plex_guid=parent_guid)
- elif not plex_guid and parent_rating_key:
- show_details = self.get_metadata_details(parent_rating_key)
-
- metadata = {'media_type': metadata_type,
- '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'),
- 'grandparent_rating_key': helpers.get_xml_attr(metadata_main, 'grandparentRatingKey'),
- 'title': helpers.get_xml_attr(metadata_main, 'title'),
- 'parent_title': helpers.get_xml_attr(metadata_main, 'parentTitle'),
- 'grandparent_title': helpers.get_xml_attr(metadata_main, 'grandparentTitle'),
- 'original_title': helpers.get_xml_attr(metadata_main, 'originalTitle'),
- 'sort_title': helpers.get_xml_attr(metadata_main, 'titleSort'),
- 'media_index': helpers.get_xml_attr(metadata_main, 'index'),
- 'parent_media_index': helpers.get_xml_attr(metadata_main, 'parentIndex'),
- 'studio': show_details.get('studio', ''),
- 'content_rating': show_details.get('content_rating', ''),
- 'summary': show_details.get('summary', ''),
- 'tagline': helpers.get_xml_attr(metadata_main, 'tagline'),
- 'rating': helpers.get_xml_attr(metadata_main, 'rating'),
- 'rating_image': helpers.get_xml_attr(metadata_main, 'ratingImage'),
- 'audience_rating': helpers.get_xml_attr(metadata_main, 'audienceRating'),
- 'audience_rating_image': helpers.get_xml_attr(metadata_main, 'audienceRatingImage'),
- 'user_rating': helpers.get_xml_attr(metadata_main, 'userRating'),
- 'duration': show_details.get('duration', ''),
- 'year': helpers.get_xml_attr(metadata_main, 'year'),
- 'thumb': helpers.get_xml_attr(metadata_main, 'thumb'),
- 'parent_thumb': helpers.get_xml_attr(metadata_main, 'parentThumb'),
- 'grandparent_thumb': helpers.get_xml_attr(metadata_main, 'grandparentThumb'),
- 'art': helpers.get_xml_attr(metadata_main, 'art'),
- 'banner': show_details.get('banner', ''),
- 'originally_available_at': helpers.get_xml_attr(metadata_main, 'originallyAvailableAt'),
- 'added_at': helpers.get_xml_attr(metadata_main, 'addedAt'),
- 'updated_at': helpers.get_xml_attr(metadata_main, 'updatedAt'),
- 'last_viewed_at': helpers.get_xml_attr(metadata_main, 'lastViewedAt'),
- 'guid': helpers.get_xml_attr(metadata_main, 'guid'),
- 'parent_guid': helpers.get_xml_attr(metadata_main, 'parentGuid'),
- 'grandparent_guid': helpers.get_xml_attr(metadata_main, 'grandparentGuid'),
- 'directors': show_details.get('directors', []),
- 'writers': show_details.get('writers', []),
- 'actors': show_details.get('actors', []),
- 'genres': show_details.get('genres', []),
- 'labels': show_details.get('labels', []),
- 'collections': show_details.get('collections', []),
- 'guids': show_details.get('guids', []),
- 'full_title': '{} - {}'.format(helpers.get_xml_attr(metadata_main, 'parentTitle'),
- helpers.get_xml_attr(metadata_main, 'title')),
- 'children_count': helpers.cast_to_int(helpers.get_xml_attr(metadata_main, 'leafCount')),
- 'live': int(helpers.get_xml_attr(metadata_main, 'live') == '1')
- }
-
- elif metadata_type == 'episode':
- grandparent_rating_key = helpers.get_xml_attr(metadata_main, 'grandparentRatingKey')
- grandparent_guid = helpers.get_xml_attr(metadata_main, 'grandparentGuid')
- show_details = {}
- if plex_guid and grandparent_guid:
- show_details = self.get_metadata_details(plex_guid=grandparent_guid)
- elif not plex_guid and grandparent_rating_key:
- show_details = self.get_metadata_details(grandparent_rating_key)
-
- parent_rating_key = helpers.get_xml_attr(metadata_main, 'parentRatingKey')
- parent_media_index = helpers.get_xml_attr(metadata_main, 'parentIndex')
- parent_thumb = helpers.get_xml_attr(metadata_main, 'parentThumb')
-
- if not plex_guid and not parent_rating_key:
- # Try getting the parent_rating_key from the parent_thumb
- if parent_thumb.startswith('/library/metadata/'):
- parent_rating_key = parent_thumb.split('/')[3]
-
- # Try getting the parent_rating_key from the grandparent's children
- if not parent_rating_key and grandparent_rating_key:
- children_list = self.get_item_children(grandparent_rating_key)
- parent_rating_key = next((c['rating_key'] for c in children_list['children_list']
- if c['media_index'] == parent_media_index), '')
-
- metadata = {'media_type': metadata_type,
- 'section_id': section_id,
- 'library_name': library_name,
- 'rating_key': helpers.get_xml_attr(metadata_main, 'ratingKey'),
- 'parent_rating_key': parent_rating_key,
- 'grandparent_rating_key': helpers.get_xml_attr(metadata_main, 'grandparentRatingKey'),
- 'title': helpers.get_xml_attr(metadata_main, 'title'),
- 'parent_title': 'Season %s' % helpers.get_xml_attr(metadata_main, 'parentIndex'),
- 'grandparent_title': helpers.get_xml_attr(metadata_main, 'grandparentTitle'),
- 'original_title': helpers.get_xml_attr(metadata_main, 'originalTitle'),
- 'sort_title': helpers.get_xml_attr(metadata_main, 'titleSort'),
- 'media_index': helpers.get_xml_attr(metadata_main, 'index'),
- 'parent_media_index': parent_media_index,
- 'studio': show_details.get('studio', ''),
- 'content_rating': helpers.get_xml_attr(metadata_main, 'contentRating'),
- 'summary': helpers.get_xml_attr(metadata_main, 'summary'),
- 'tagline': helpers.get_xml_attr(metadata_main, 'tagline'),
- 'rating': helpers.get_xml_attr(metadata_main, 'rating'),
- 'rating_image': helpers.get_xml_attr(metadata_main, 'ratingImage'),
- 'audience_rating': helpers.get_xml_attr(metadata_main, 'audienceRating'),
- 'audience_rating_image': helpers.get_xml_attr(metadata_main, 'audienceRatingImage'),
- 'user_rating': helpers.get_xml_attr(metadata_main, 'userRating'),
- 'duration': helpers.get_xml_attr(metadata_main, 'duration'),
- 'year': helpers.get_xml_attr(metadata_main, 'year'),
- 'thumb': helpers.get_xml_attr(metadata_main, 'thumb'),
- 'parent_thumb': parent_thumb,
- 'grandparent_thumb': helpers.get_xml_attr(metadata_main, 'grandparentThumb'),
- 'art': helpers.get_xml_attr(metadata_main, 'art'),
- 'banner': show_details.get('banner', ''),
- 'originally_available_at': helpers.get_xml_attr(metadata_main, 'originallyAvailableAt'),
- 'added_at': helpers.get_xml_attr(metadata_main, 'addedAt'),
- 'updated_at': helpers.get_xml_attr(metadata_main, 'updatedAt'),
- 'last_viewed_at': helpers.get_xml_attr(metadata_main, 'lastViewedAt'),
- 'guid': helpers.get_xml_attr(metadata_main, 'guid'),
- 'parent_guid': helpers.get_xml_attr(metadata_main, 'parentGuid'),
- 'grandparent_guid': helpers.get_xml_attr(metadata_main, 'grandparentGuid'),
- 'directors': directors,
- 'writers': writers,
- 'actors': show_details.get('actors', []),
- 'genres': show_details.get('genres', []),
- 'labels': show_details.get('labels', []),
- 'collections': show_details.get('collections', []),
- 'guids': show_details.get('guids', []),
- 'full_title': '{} - {}'.format(helpers.get_xml_attr(metadata_main, 'grandparentTitle'),
- helpers.get_xml_attr(metadata_main, 'title')),
- 'children_count': helpers.cast_to_int(helpers.get_xml_attr(metadata_main, 'leafCount')),
- 'live': int(helpers.get_xml_attr(metadata_main, 'live') == '1')
- }
-
- elif metadata_type == 'artist':
- metadata = {'media_type': metadata_type,
- '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'),
- 'grandparent_rating_key': helpers.get_xml_attr(metadata_main, 'grandparentRatingKey'),
- 'title': helpers.get_xml_attr(metadata_main, 'title'),
- 'parent_title': helpers.get_xml_attr(metadata_main, 'parentTitle'),
- 'grandparent_title': helpers.get_xml_attr(metadata_main, 'grandparentTitle'),
- 'original_title': helpers.get_xml_attr(metadata_main, 'originalTitle'),
- 'sort_title': helpers.get_xml_attr(metadata_main, 'titleSort'),
- 'media_index': helpers.get_xml_attr(metadata_main, 'index'),
- 'parent_media_index': helpers.get_xml_attr(metadata_main, 'parentIndex'),
- 'studio': helpers.get_xml_attr(metadata_main, 'studio'),
- 'content_rating': helpers.get_xml_attr(metadata_main, 'contentRating'),
- 'summary': helpers.get_xml_attr(metadata_main, 'summary'),
- 'tagline': helpers.get_xml_attr(metadata_main, 'tagline'),
- 'rating': helpers.get_xml_attr(metadata_main, 'rating'),
- 'rating_image': helpers.get_xml_attr(metadata_main, 'ratingImage'),
- 'audience_rating': helpers.get_xml_attr(metadata_main, 'audienceRating'),
- 'audience_rating_image': helpers.get_xml_attr(metadata_main, 'audienceRatingImage'),
- 'user_rating': helpers.get_xml_attr(metadata_main, 'userRating'),
- 'duration': helpers.get_xml_attr(metadata_main, 'duration'),
- 'year': helpers.get_xml_attr(metadata_main, 'year'),
- 'thumb': helpers.get_xml_attr(metadata_main, 'thumb'),
- 'parent_thumb': helpers.get_xml_attr(metadata_main, 'parentThumb'),
- 'grandparent_thumb': helpers.get_xml_attr(metadata_main, 'grandparentThumb'),
- 'art': helpers.get_xml_attr(metadata_main, 'art'),
- 'banner': helpers.get_xml_attr(metadata_main, 'banner'),
- 'originally_available_at': helpers.get_xml_attr(metadata_main, 'originallyAvailableAt'),
- 'added_at': helpers.get_xml_attr(metadata_main, 'addedAt'),
- 'updated_at': helpers.get_xml_attr(metadata_main, 'updatedAt'),
- 'last_viewed_at': helpers.get_xml_attr(metadata_main, 'lastViewedAt'),
- 'guid': helpers.get_xml_attr(metadata_main, 'guid'),
- 'parent_guid': helpers.get_xml_attr(metadata_main, 'parentGuid'),
- 'grandparent_guid': helpers.get_xml_attr(metadata_main, 'grandparentGuid'),
- 'directors': directors,
- 'writers': writers,
- 'actors': actors,
- 'genres': genres,
- 'labels': labels,
- 'collections': collections,
- 'guids': guids,
- 'full_title': helpers.get_xml_attr(metadata_main, 'title'),
- 'children_count': helpers.cast_to_int(helpers.get_xml_attr(metadata_main, 'leafCount')),
- 'live': int(helpers.get_xml_attr(metadata_main, 'live') == '1')
- }
-
- elif metadata_type == 'album':
- parent_rating_key = helpers.get_xml_attr(metadata_main, 'parentRatingKey')
- artist_details = self.get_metadata_details(parent_rating_key) if parent_rating_key else {}
- metadata = {'media_type': metadata_type,
- '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'),
- 'grandparent_rating_key': helpers.get_xml_attr(metadata_main, 'grandparentRatingKey'),
- 'title': helpers.get_xml_attr(metadata_main, 'title'),
- 'parent_title': helpers.get_xml_attr(metadata_main, 'parentTitle'),
- 'grandparent_title': helpers.get_xml_attr(metadata_main, 'grandparentTitle'),
- 'original_title': helpers.get_xml_attr(metadata_main, 'originalTitle'),
- 'sort_title': helpers.get_xml_attr(metadata_main, 'titleSort'),
- 'media_index': helpers.get_xml_attr(metadata_main, 'index'),
- 'parent_media_index': helpers.get_xml_attr(metadata_main, 'parentIndex'),
- 'studio': helpers.get_xml_attr(metadata_main, 'studio'),
- 'content_rating': helpers.get_xml_attr(metadata_main, 'contentRating'),
- 'summary': helpers.get_xml_attr(metadata_main, 'summary') or artist_details.get('summary', ''),
- 'tagline': helpers.get_xml_attr(metadata_main, 'tagline'),
- 'rating': helpers.get_xml_attr(metadata_main, 'rating'),
- 'rating_image': helpers.get_xml_attr(metadata_main, 'ratingImage'),
- 'audience_rating': helpers.get_xml_attr(metadata_main, 'audienceRating'),
- 'audience_rating_image': helpers.get_xml_attr(metadata_main, 'audienceRatingImage'),
- 'user_rating': helpers.get_xml_attr(metadata_main, 'userRating'),
- 'duration': helpers.get_xml_attr(metadata_main, 'duration'),
- 'year': helpers.get_xml_attr(metadata_main, 'year'),
- 'thumb': helpers.get_xml_attr(metadata_main, 'thumb'),
- 'parent_thumb': helpers.get_xml_attr(metadata_main, 'parentThumb'),
- 'grandparent_thumb': helpers.get_xml_attr(metadata_main, 'grandparentThumb'),
- 'art': helpers.get_xml_attr(metadata_main, 'art'),
- 'banner': artist_details.get('banner', ''),
- 'originally_available_at': helpers.get_xml_attr(metadata_main, 'originallyAvailableAt'),
- 'added_at': helpers.get_xml_attr(metadata_main, 'addedAt'),
- 'updated_at': helpers.get_xml_attr(metadata_main, 'updatedAt'),
- 'last_viewed_at': helpers.get_xml_attr(metadata_main, 'lastViewedAt'),
- 'guid': helpers.get_xml_attr(metadata_main, 'guid'),
- 'parent_guid': helpers.get_xml_attr(metadata_main, 'parentGuid'),
- 'grandparent_guid': helpers.get_xml_attr(metadata_main, 'grandparentGuid'),
- 'directors': directors,
- 'writers': writers,
- 'actors': actors,
- 'genres': genres,
- 'labels': labels,
- 'collections': collections,
- 'guids': guids,
- 'full_title': '{} - {}'.format(helpers.get_xml_attr(metadata_main, 'parentTitle'),
- helpers.get_xml_attr(metadata_main, 'title')),
- 'children_count': helpers.cast_to_int(helpers.get_xml_attr(metadata_main, 'leafCount')),
- 'live': int(helpers.get_xml_attr(metadata_main, 'live') == '1')
- }
-
- elif metadata_type == 'track':
- parent_rating_key = helpers.get_xml_attr(metadata_main, 'parentRatingKey')
- album_details = self.get_metadata_details(parent_rating_key) if parent_rating_key else {}
- track_artist = helpers.get_xml_attr(metadata_main, 'originalTitle') or \
- helpers.get_xml_attr(metadata_main, 'grandparentTitle')
- metadata = {'media_type': metadata_type,
- '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'),
- 'grandparent_rating_key': helpers.get_xml_attr(metadata_main, 'grandparentRatingKey'),
- 'title': helpers.get_xml_attr(metadata_main, 'title'),
- 'parent_title': helpers.get_xml_attr(metadata_main, 'parentTitle'),
- 'grandparent_title': helpers.get_xml_attr(metadata_main, 'grandparentTitle'),
- 'original_title': helpers.get_xml_attr(metadata_main, 'originalTitle'),
- 'sort_title': helpers.get_xml_attr(metadata_main, 'titleSort'),
- 'media_index': helpers.get_xml_attr(metadata_main, 'index'),
- 'parent_media_index': helpers.get_xml_attr(metadata_main, 'parentIndex'),
- 'studio': helpers.get_xml_attr(metadata_main, 'studio'),
- 'content_rating': helpers.get_xml_attr(metadata_main, 'contentRating'),
- 'summary': helpers.get_xml_attr(metadata_main, 'summary'),
- 'tagline': helpers.get_xml_attr(metadata_main, 'tagline'),
- 'rating': helpers.get_xml_attr(metadata_main, 'rating'),
- 'rating_image': helpers.get_xml_attr(metadata_main, 'ratingImage'),
- 'audience_rating': helpers.get_xml_attr(metadata_main, 'audienceRating'),
- 'audience_rating_image': helpers.get_xml_attr(metadata_main, 'audienceRatingImage'),
- 'user_rating': helpers.get_xml_attr(metadata_main, 'userRating'),
- 'duration': helpers.get_xml_attr(metadata_main, 'duration'),
- 'year': album_details.get('year', ''),
- 'thumb': helpers.get_xml_attr(metadata_main, 'thumb'),
- 'parent_thumb': helpers.get_xml_attr(metadata_main, 'parentThumb'),
- 'grandparent_thumb': helpers.get_xml_attr(metadata_main, 'grandparentThumb'),
- 'art': helpers.get_xml_attr(metadata_main, 'art'),
- 'banner': album_details.get('banner', ''),
- 'originally_available_at': helpers.get_xml_attr(metadata_main, 'originallyAvailableAt'),
- 'added_at': helpers.get_xml_attr(metadata_main, 'addedAt'),
- 'updated_at': helpers.get_xml_attr(metadata_main, 'updatedAt'),
- 'last_viewed_at': helpers.get_xml_attr(metadata_main, 'lastViewedAt'),
- 'guid': helpers.get_xml_attr(metadata_main, 'guid'),
- 'parent_guid': helpers.get_xml_attr(metadata_main, 'parentGuid'),
- 'grandparent_guid': helpers.get_xml_attr(metadata_main, 'grandparentGuid'),
- 'directors': directors,
- 'writers': writers,
- 'actors': actors,
- 'genres': album_details.get('genres', []),
- 'labels': album_details.get('labels', []),
- 'collections': album_details.get('collections', []),
- 'guids': album_details.get('guids', []),
- 'full_title': '{} - {}'.format(helpers.get_xml_attr(metadata_main, 'title'),
- track_artist),
- 'children_count': helpers.cast_to_int(helpers.get_xml_attr(metadata_main, 'leafCount')),
- 'live': int(helpers.get_xml_attr(metadata_main, 'live') == '1')
- }
-
- elif metadata_type == 'photo_album':
- metadata = {'media_type': metadata_type,
- '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'),
- 'grandparent_rating_key': helpers.get_xml_attr(metadata_main, 'grandparentRatingKey'),
- 'title': helpers.get_xml_attr(metadata_main, 'title'),
- 'parent_title': helpers.get_xml_attr(metadata_main, 'parentTitle'),
- 'grandparent_title': helpers.get_xml_attr(metadata_main, 'grandparentTitle'),
- 'original_title': helpers.get_xml_attr(metadata_main, 'originalTitle'),
- 'sort_title': helpers.get_xml_attr(metadata_main, 'titleSort'),
- 'media_index': helpers.get_xml_attr(metadata_main, 'index'),
- 'parent_media_index': helpers.get_xml_attr(metadata_main, 'parentIndex'),
- 'studio': helpers.get_xml_attr(metadata_main, 'studio'),
- 'content_rating': helpers.get_xml_attr(metadata_main, 'contentRating'),
- 'summary': helpers.get_xml_attr(metadata_main, 'summary'),
- 'tagline': helpers.get_xml_attr(metadata_main, 'tagline'),
- 'rating': helpers.get_xml_attr(metadata_main, 'rating'),
- 'rating_image': helpers.get_xml_attr(metadata_main, 'ratingImage'),
- 'audience_rating': helpers.get_xml_attr(metadata_main, 'audienceRating'),
- 'audience_rating_image': helpers.get_xml_attr(metadata_main, 'audienceRatingImage'),
- 'user_rating': helpers.get_xml_attr(metadata_main, 'userRating'),
- 'duration': helpers.get_xml_attr(metadata_main, 'duration'),
- 'year': helpers.get_xml_attr(metadata_main, 'year'),
- 'thumb': helpers.get_xml_attr(metadata_main, 'thumb'),
- 'parent_thumb': helpers.get_xml_attr(metadata_main, 'parentThumb'),
- 'grandparent_thumb': helpers.get_xml_attr(metadata_main, 'grandparentThumb'),
- 'art': helpers.get_xml_attr(metadata_main, 'art'),
- 'banner': helpers.get_xml_attr(metadata_main, 'banner'),
- 'originally_available_at': helpers.get_xml_attr(metadata_main, 'originallyAvailableAt'),
- 'added_at': helpers.get_xml_attr(metadata_main, 'addedAt'),
- 'updated_at': helpers.get_xml_attr(metadata_main, 'updatedAt'),
- 'last_viewed_at': helpers.get_xml_attr(metadata_main, 'lastViewedAt'),
- 'guid': helpers.get_xml_attr(metadata_main, 'guid'),
- 'parent_guid': helpers.get_xml_attr(metadata_main, 'parentGuid'),
- 'grandparent_guid': helpers.get_xml_attr(metadata_main, 'grandparentGuid'),
- 'directors': directors,
- 'writers': writers,
- 'actors': actors,
- 'genres': genres,
- 'labels': labels,
- 'collections': collections,
- 'guids': guids,
- 'full_title': helpers.get_xml_attr(metadata_main, 'title'),
- 'children_count': helpers.cast_to_int(helpers.get_xml_attr(metadata_main, 'leafCount')),
- 'live': int(helpers.get_xml_attr(metadata_main, 'live') == '1')
- }
-
- elif metadata_type == 'photo':
- parent_rating_key = helpers.get_xml_attr(metadata_main, 'parentRatingKey')
- photo_album_details = self.get_metadata_details(parent_rating_key) if parent_rating_key else {}
- metadata = {'media_type': metadata_type,
- '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'),
- 'grandparent_rating_key': helpers.get_xml_attr(metadata_main, 'grandparentRatingKey'),
- 'title': helpers.get_xml_attr(metadata_main, 'title'),
- 'parent_title': helpers.get_xml_attr(metadata_main, 'parentTitle'),
- 'grandparent_title': helpers.get_xml_attr(metadata_main, 'grandparentTitle'),
- 'original_title': helpers.get_xml_attr(metadata_main, 'originalTitle'),
- 'sort_title': helpers.get_xml_attr(metadata_main, 'titleSort'),
- 'media_index': helpers.get_xml_attr(metadata_main, 'index'),
- 'parent_media_index': helpers.get_xml_attr(metadata_main, 'parentIndex'),
- 'studio': helpers.get_xml_attr(metadata_main, 'studio'),
- 'content_rating': helpers.get_xml_attr(metadata_main, 'contentRating'),
- 'summary': helpers.get_xml_attr(metadata_main, 'summary'),
- 'tagline': helpers.get_xml_attr(metadata_main, 'tagline'),
- 'rating': helpers.get_xml_attr(metadata_main, 'rating'),
- 'rating_image': helpers.get_xml_attr(metadata_main, 'ratingImage'),
- 'audience_rating': helpers.get_xml_attr(metadata_main, 'audienceRating'),
- 'audience_rating_image': helpers.get_xml_attr(metadata_main, 'audienceRatingImage'),
- 'user_rating': helpers.get_xml_attr(metadata_main, 'userRating'),
- 'duration': helpers.get_xml_attr(metadata_main, 'duration'),
- 'year': helpers.get_xml_attr(metadata_main, 'year'),
- 'thumb': helpers.get_xml_attr(metadata_main, 'thumb'),
- 'parent_thumb': helpers.get_xml_attr(metadata_main, 'parentThumb'),
- 'grandparent_thumb': helpers.get_xml_attr(metadata_main, 'grandparentThumb'),
- 'art': helpers.get_xml_attr(metadata_main, 'art'),
- 'banner': photo_album_details.get('banner', ''),
- 'originally_available_at': helpers.get_xml_attr(metadata_main, 'originallyAvailableAt'),
- 'added_at': helpers.get_xml_attr(metadata_main, 'addedAt'),
- 'updated_at': helpers.get_xml_attr(metadata_main, 'updatedAt'),
- 'last_viewed_at': helpers.get_xml_attr(metadata_main, 'lastViewedAt'),
- 'guid': helpers.get_xml_attr(metadata_main, 'guid'),
- 'parent_guid': helpers.get_xml_attr(metadata_main, 'parentGuid'),
- 'grandparent_guid': helpers.get_xml_attr(metadata_main, 'grandparentGuid'),
- 'directors': directors,
- 'writers': writers,
- 'actors': actors,
- 'genres': photo_album_details.get('genres', []),
- 'labels': photo_album_details.get('labels', []),
- 'collections': photo_album_details.get('collections', []),
- 'guids': photo_album_details.get('guids', []),
- 'full_title': '{} - {}'.format(
- helpers.get_xml_attr(metadata_main, 'parentTitle') or library_name,
- helpers.get_xml_attr(metadata_main, 'title')),
- 'children_count': helpers.cast_to_int(helpers.get_xml_attr(metadata_main, 'leafCount')),
- 'live': int(helpers.get_xml_attr(metadata_main, 'live') == '1')
- }
-
- elif metadata_type == 'collection':
- metadata = {'media_type': metadata_type,
- 'sub_media_type': helpers.get_xml_attr(metadata_main, 'subtype'),
- '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'),
- 'grandparent_rating_key': helpers.get_xml_attr(metadata_main, 'grandparentRatingKey'),
- 'title': helpers.get_xml_attr(metadata_main, 'title'),
- 'parent_title': helpers.get_xml_attr(metadata_main, 'parentTitle'),
- 'grandparent_title': helpers.get_xml_attr(metadata_main, 'grandparentTitle'),
- 'original_title': helpers.get_xml_attr(metadata_main, 'originalTitle'),
- 'sort_title': helpers.get_xml_attr(metadata_main, 'titleSort'),
- 'media_index': helpers.get_xml_attr(metadata_main, 'index'),
- 'parent_media_index': helpers.get_xml_attr(metadata_main, 'parentIndex'),
- 'studio': helpers.get_xml_attr(metadata_main, 'studio'),
- 'content_rating': helpers.get_xml_attr(metadata_main, 'contentRating'),
- 'summary': helpers.get_xml_attr(metadata_main, 'summary'),
- 'tagline': helpers.get_xml_attr(metadata_main, 'tagline'),
- 'rating': helpers.get_xml_attr(metadata_main, 'rating'),
- 'rating_image': helpers.get_xml_attr(metadata_main, 'ratingImage'),
- 'audience_rating': helpers.get_xml_attr(metadata_main, 'audienceRating'),
- 'audience_rating_image': helpers.get_xml_attr(metadata_main, 'audienceRatingImage'),
- 'user_rating': helpers.get_xml_attr(metadata_main, 'userRating'),
- 'duration': helpers.get_xml_attr(metadata_main, 'duration'),
- 'year': helpers.get_xml_attr(metadata_main, 'year'),
- 'min_year': helpers.get_xml_attr(metadata_main, 'minYear'),
- 'max_year': helpers.get_xml_attr(metadata_main, 'maxYear'),
- 'thumb': helpers.get_xml_attr(metadata_main, 'thumb').split('?')[0],
- 'parent_thumb': helpers.get_xml_attr(metadata_main, 'parentThumb'),
- 'grandparent_thumb': helpers.get_xml_attr(metadata_main, 'grandparentThumb'),
- 'art': helpers.get_xml_attr(metadata_main, 'art'),
- 'banner': helpers.get_xml_attr(metadata_main, 'banner'),
- 'originally_available_at': helpers.get_xml_attr(metadata_main, 'originallyAvailableAt'),
- 'added_at': helpers.get_xml_attr(metadata_main, 'addedAt'),
- 'updated_at': helpers.get_xml_attr(metadata_main, 'updatedAt'),
- 'last_viewed_at': helpers.get_xml_attr(metadata_main, 'lastViewedAt'),
- 'guid': helpers.get_xml_attr(metadata_main, 'guid'),
- 'parent_guid': helpers.get_xml_attr(metadata_main, 'parentGuid'),
- 'grandparent_guid': helpers.get_xml_attr(metadata_main, 'grandparentGuid'),
- 'child_count': helpers.get_xml_attr(metadata_main, 'childCount'),
- 'directors': directors,
- 'writers': writers,
- 'actors': actors,
- 'genres': genres,
- 'labels': labels,
- 'collections': collections,
- 'guids': guids,
- 'full_title': helpers.get_xml_attr(metadata_main, 'title'),
- 'children_count': helpers.cast_to_int(helpers.get_xml_attr(metadata_main, 'childCount')),
- 'live': int(helpers.get_xml_attr(metadata_main, 'live') == '1')
- }
-
- elif metadata_type == 'playlist':
- metadata = {'media_type': metadata_type,
- 'section_id': section_id,
- 'library_name': library_name,
- 'rating_key': helpers.get_xml_attr(metadata_main, 'ratingKey'),
- 'guid': helpers.get_xml_attr(metadata_main, 'guid'),
- 'title': helpers.get_xml_attr(metadata_main, 'title'),
- 'summary': helpers.get_xml_attr(metadata_main, 'summary'),
- 'duration': helpers.get_xml_attr(metadata_main, 'duration'),
- 'composite': helpers.get_xml_attr(metadata_main, 'composite'),
- 'thumb': helpers.get_xml_attr(metadata_main, 'composite'),
- 'added_at': helpers.get_xml_attr(metadata_main, 'addedAt'),
- 'updated_at': helpers.get_xml_attr(metadata_main, 'updatedAt'),
- 'last_viewed_at': helpers.get_xml_attr(metadata_main, 'lastViewedAt'),
- 'children_count': helpers.cast_to_int(helpers.get_xml_attr(metadata_main, 'leafCount')),
- 'smart': helpers.cast_to_int(helpers.get_xml_attr(metadata_main, 'smart')),
- 'playlist_type': helpers.get_xml_attr(metadata_main, 'playlistType'),
- 'live': int(helpers.get_xml_attr(metadata_main, 'live') == '1')
- }
-
- elif metadata_type == 'clip':
- metadata = {'media_type': metadata_type,
- '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'),
- 'grandparent_rating_key': helpers.get_xml_attr(metadata_main, 'grandparentRatingKey'),
- 'title': helpers.get_xml_attr(metadata_main, 'title'),
- 'parent_title': helpers.get_xml_attr(metadata_main, 'parentTitle'),
- 'grandparent_title': helpers.get_xml_attr(metadata_main, 'grandparentTitle'),
- 'original_title': helpers.get_xml_attr(metadata_main, 'originalTitle'),
- 'sort_title': helpers.get_xml_attr(metadata_main, 'titleSort'),
- 'media_index': helpers.get_xml_attr(metadata_main, 'index'),
- 'parent_media_index': helpers.get_xml_attr(metadata_main, 'parentIndex'),
- 'studio': helpers.get_xml_attr(metadata_main, 'studio'),
- 'content_rating': helpers.get_xml_attr(metadata_main, 'contentRating'),
- 'summary': helpers.get_xml_attr(metadata_main, 'summary'),
- 'tagline': helpers.get_xml_attr(metadata_main, 'tagline'),
- 'rating': helpers.get_xml_attr(metadata_main, 'rating'),
- 'rating_image': helpers.get_xml_attr(metadata_main, 'ratingImage'),
- 'audience_rating': helpers.get_xml_attr(metadata_main, 'audienceRating'),
- 'audience_rating_image': helpers.get_xml_attr(metadata_main, 'audienceRatingImage'),
- 'user_rating': helpers.get_xml_attr(metadata_main, 'userRating'),
- 'duration': helpers.get_xml_attr(metadata_main, 'duration'),
- 'year': helpers.get_xml_attr(metadata_main, 'year'),
- 'thumb': helpers.get_xml_attr(metadata_main, 'thumb'),
- 'parent_thumb': helpers.get_xml_attr(metadata_main, 'parentThumb'),
- 'grandparent_thumb': helpers.get_xml_attr(metadata_main, 'grandparentThumb'),
- 'art': helpers.get_xml_attr(metadata_main, 'art'),
- 'banner': helpers.get_xml_attr(metadata_main, 'banner'),
- 'originally_available_at': helpers.get_xml_attr(metadata_main, 'originallyAvailableAt'),
- 'added_at': helpers.get_xml_attr(metadata_main, 'addedAt'),
- 'updated_at': helpers.get_xml_attr(metadata_main, 'updatedAt'),
- 'last_viewed_at': helpers.get_xml_attr(metadata_main, 'lastViewedAt'),
- 'guid': helpers.get_xml_attr(metadata_main, 'guid'),
- 'parent_guid': helpers.get_xml_attr(metadata_main, 'parentGuid'),
- 'grandparent_guid': helpers.get_xml_attr(metadata_main, 'grandparentGuid'),
- 'directors': directors,
- 'writers': writers,
- 'actors': actors,
- 'genres': genres,
- 'labels': labels,
- 'collections': collections,
- 'guids': guids,
- 'full_title': helpers.get_xml_attr(metadata_main, 'title'),
- 'extra_type': helpers.get_xml_attr(metadata_main, 'extraType'),
- 'sub_type': helpers.get_xml_attr(metadata_main, 'subtype'),
- 'live': int(helpers.get_xml_attr(metadata_main, 'live') == '1')
- }
-
- else:
- return metadata
-
- # Get additional metadata from metadata.provider.plex.tv
- if not plex_guid and metadata['live']:
- metadata['section_id'] = common.LIVE_TV_SECTION_ID
- metadata['library_name'] = common.LIVE_TV_SECTION_NAME
-
- plextv_metadata = self.get_metadata_details(plex_guid=metadata['guid'])
- if plextv_metadata:
- keys_to_update = ['summary', 'rating', 'thumb', 'grandparent_thumb', 'duration',
- 'guid', 'grandparent_guid', 'genres']
- for key in keys_to_update:
- metadata[key] = plextv_metadata[key]
- metadata['originally_available_at'] = helpers.iso_to_YMD(plextv_metadata['originally_available_at'])
-
- if metadata and media_info:
- medias = []
- media_items = metadata_main.getElementsByTagName('Media')
- for media in media_items:
- video_full_resolution_scan_type = ''
-
- parts = []
- part_items = media.getElementsByTagName('Part')
- for part in part_items:
-
- streams = []
- stream_items = part.getElementsByTagName('Stream')
- for stream in stream_items:
- if helpers.get_xml_attr(stream, 'streamType') == '1':
- video_scan_type = helpers.get_xml_attr(stream, 'scanType')
- video_full_resolution_scan_type = (video_full_resolution_scan_type or video_scan_type)
-
- streams.append({'id': helpers.get_xml_attr(stream, 'id'),
- 'type': helpers.get_xml_attr(stream, 'streamType'),
- 'video_codec': helpers.get_xml_attr(stream, 'codec'),
- 'video_codec_level': helpers.get_xml_attr(stream, 'level'),
- 'video_bitrate': helpers.get_xml_attr(stream, 'bitrate'),
- 'video_bit_depth': helpers.get_xml_attr(stream, 'bitDepth'),
- 'video_chroma_subsampling': helpers.get_xml_attr(stream,
- 'chromaSubsampling'),
- 'video_color_primaries': helpers.get_xml_attr(stream, 'colorPrimaries'),
- 'video_color_range': helpers.get_xml_attr(stream, 'colorRange'),
- 'video_color_space': helpers.get_xml_attr(stream, 'colorSpace'),
- 'video_color_trc': helpers.get_xml_attr(stream, 'colorTrc'),
- 'video_frame_rate': helpers.get_xml_attr(stream, 'frameRate'),
- 'video_ref_frames': helpers.get_xml_attr(stream, 'refFrames'),
- 'video_height': helpers.get_xml_attr(stream, 'height'),
- 'video_width': helpers.get_xml_attr(stream, 'width'),
- 'video_language': helpers.get_xml_attr(stream, 'language'),
- 'video_language_code': helpers.get_xml_attr(stream, 'languageCode'),
- 'video_profile': helpers.get_xml_attr(stream, 'profile'),
- 'video_scan_type': helpers.get_xml_attr(stream, 'scanType'),
- 'selected': int(helpers.get_xml_attr(stream, 'selected') == '1')
- })
-
- elif helpers.get_xml_attr(stream, 'streamType') == '2':
- streams.append({'id': helpers.get_xml_attr(stream, 'id'),
- 'type': helpers.get_xml_attr(stream, 'streamType'),
- 'audio_codec': helpers.get_xml_attr(stream, 'codec'),
- 'audio_bitrate': helpers.get_xml_attr(stream, 'bitrate'),
- 'audio_bitrate_mode': helpers.get_xml_attr(stream, 'bitrateMode'),
- 'audio_channels': helpers.get_xml_attr(stream, 'channels'),
- 'audio_channel_layout': helpers.get_xml_attr(stream, 'audioChannelLayout'),
- 'audio_sample_rate': helpers.get_xml_attr(stream, 'samplingRate'),
- 'audio_language': helpers.get_xml_attr(stream, 'language'),
- 'audio_language_code': helpers.get_xml_attr(stream, 'languageCode'),
- 'audio_profile': helpers.get_xml_attr(stream, 'profile'),
- 'selected': int(helpers.get_xml_attr(stream, 'selected') == '1')
- })
-
- elif helpers.get_xml_attr(stream, 'streamType') == '3':
- streams.append({'id': helpers.get_xml_attr(stream, 'id'),
- 'type': helpers.get_xml_attr(stream, 'streamType'),
- 'subtitle_codec': helpers.get_xml_attr(stream, 'codec'),
- 'subtitle_container': helpers.get_xml_attr(stream, 'container'),
- 'subtitle_format': helpers.get_xml_attr(stream, 'format'),
- 'subtitle_forced': int(helpers.get_xml_attr(stream, 'forced') == '1'),
- 'subtitle_location': 'external' if helpers.get_xml_attr(stream,
- 'key') else 'embedded',
- 'subtitle_language': helpers.get_xml_attr(stream, 'language'),
- 'subtitle_language_code': helpers.get_xml_attr(stream, 'languageCode'),
- 'selected': int(helpers.get_xml_attr(stream, 'selected') == '1')
- })
-
- parts.append({'id': helpers.get_xml_attr(part, 'id'),
- 'file': helpers.get_xml_attr(part, 'file'),
- 'file_size': helpers.get_xml_attr(part, 'size'),
- 'indexes': int(helpers.get_xml_attr(part, 'indexes') == 'sd'),
- 'streams': streams,
- 'selected': int(helpers.get_xml_attr(part, 'selected') == '1')
- })
-
- video_resolution = helpers.get_xml_attr(media, 'videoResolution').lower().rstrip('ip')
- video_full_resolution = common.VIDEO_RESOLUTION_OVERRIDES.get(
- video_resolution, video_resolution + (video_full_resolution_scan_type[:1] or 'p')
- )
-
- audio_channels = helpers.get_xml_attr(media, 'audioChannels')
-
- media_info = {'id': helpers.get_xml_attr(media, 'id'),
- 'container': helpers.get_xml_attr(media, 'container'),
- 'bitrate': helpers.get_xml_attr(media, 'bitrate'),
- 'height': helpers.get_xml_attr(media, 'height'),
- 'width': helpers.get_xml_attr(media, 'width'),
- 'aspect_ratio': helpers.get_xml_attr(media, 'aspectRatio'),
- 'video_codec': helpers.get_xml_attr(media, 'videoCodec'),
- 'video_resolution': video_resolution,
- 'video_full_resolution': video_full_resolution,
- 'video_framerate': helpers.get_xml_attr(media, 'videoFrameRate'),
- 'video_profile': helpers.get_xml_attr(media, 'videoProfile'),
- 'audio_codec': helpers.get_xml_attr(media, 'audioCodec'),
- 'audio_channels': audio_channels,
- 'audio_channel_layout': common.AUDIO_CHANNELS.get(audio_channels, audio_channels),
- 'audio_profile': helpers.get_xml_attr(media, 'audioProfile'),
- 'optimized_version': int(helpers.get_xml_attr(media, 'proxyType') == '42'),
- 'channel_call_sign': helpers.get_xml_attr(media, 'channelCallSign'),
- 'channel_identifier': helpers.get_xml_attr(media, 'channelIdentifier'),
- 'channel_thumb': helpers.get_xml_attr(media, 'channelThumb'),
- 'parts': parts
- }
-
- medias.append(media_info)
-
- metadata['media_info'] = medias
-
- if metadata:
- if cache_key:
- metadata['_cache_time'] = helpers.timestamp()
-
- out_file_folder = os.path.join(jellypy.CONFIG.CACHE_DIR, 'session_metadata')
- out_file_path = os.path.join(out_file_folder, 'metadata-sessionKey-%s.json' % cache_key)
-
- if not os.path.exists(out_file_folder):
- os.mkdir(out_file_folder)
-
- try:
- with open(out_file_path, 'w') as outFile:
- json.dump(metadata, outFile)
- except (IOError, ValueError) as e:
- logger.error("Tautulli Pmsconnect :: Unable to create cache file for metadata (sessionKey %s): %s"
- % (cache_key, e))
-
- return metadata
- else:
- return metadata
-
- def get_metadata_children_details(self, rating_key='', get_children=False):
- """
- Return processed and validated metadata list for all children of requested item.
-
- Parameters required: rating_key { Plex ratingKey }
-
- Output: array
- """
- metadata = self.get_metadata_children(str(rating_key), output_format='xml')
-
- try:
- xml_head = metadata.getElementsByTagName('MediaContainer')
- except Exception as e:
- logger.warn("Tautulli Pmsconnect :: Unable to parse XML for get_metadata_children: %s." % e)
- return []
-
- metadata_list = []
-
- for a in xml_head:
- if a.getAttribute('size'):
- if a.getAttribute('size') == '0':
- return metadata_list
-
- if a.getElementsByTagName('Video'):
- metadata_main = a.getElementsByTagName('Video')
- for item in metadata_main:
- child_rating_key = helpers.get_xml_attr(item, 'ratingKey')
- metadata = self.get_metadata_details(str(child_rating_key))
- if metadata:
- metadata_list.append(metadata)
-
- elif a.getElementsByTagName('Track'):
- metadata_main = a.getElementsByTagName('Track')
- for item in metadata_main:
- child_rating_key = helpers.get_xml_attr(item, 'ratingKey')
- metadata = self.get_metadata_details(str(child_rating_key))
- if metadata:
- metadata_list.append(metadata)
-
- elif get_children and a.getElementsByTagName('Directory'):
- dir_main = a.getElementsByTagName('Directory')
- metadata_main = [d for d in dir_main if helpers.get_xml_attr(d, 'ratingKey')]
- for item in metadata_main:
- child_rating_key = helpers.get_xml_attr(item, 'ratingKey')
- metadata = self.get_metadata_children_details(str(child_rating_key), get_children)
- if metadata:
- metadata_list.extend(metadata)
-
- return metadata_list
-
- def get_library_metadata_details(self, section_id=''):
- """
- Return processed and validated metadata list for requested library.
-
- Parameters required: section_id { Plex library key }
-
- Output: array
- """
- libraries_data = self.get_libraries_list(output_format='xml')
-
- try:
- xml_head = libraries_data.getElementsByTagName('MediaContainer')
- except Exception as e:
- logger.warn("Tautulli Pmsconnect :: Unable to parse XML for get_library_metadata_details: %s." % e)
- return []
-
- metadata_list = []
-
- for a in xml_head:
- if a.getAttribute('size'):
- if a.getAttribute('size') == '0':
- metadata_list = {'metadata': None}
- return metadata_list
-
- if a.getElementsByTagName('Directory'):
- result_data = a.getElementsByTagName('Directory')
- for result in result_data:
- key = helpers.get_xml_attr(result, 'key')
- if key == section_id:
- metadata = {'media_type': 'library',
- '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'),
- 'thumb': helpers.get_xml_attr(result, 'thumb')
- }
- if metadata['library'] == 'movie':
- metadata['section_type'] = 'movie'
- elif metadata['library'] == 'show':
- metadata['section_type'] = 'episode'
- elif metadata['library'] == 'artist':
- metadata['section_type'] = 'track'
-
- metadata_list = {'metadata': metadata}
-
- return metadata_list
-
- def get_current_activity(self, skip_cache=False):
- """
- Return processed and validated session list.
-
- Output: array
- """
- session_data = self.get_sessions(output_format='xml')
-
- try:
- xml_head = session_data.getElementsByTagName('MediaContainer')
- except Exception as e:
- logger.warn("Tautulli Pmsconnect :: Unable to parse XML for get_current_activity: %s." % e)
- return []
-
- session_list = []
-
- for a in xml_head:
- if a.getAttribute('size'):
- if a.getAttribute('size') == '0':
- session_list = {'stream_count': '0',
- 'sessions': []
- }
- return session_list
-
- if a.getElementsByTagName('Track'):
- session_data = a.getElementsByTagName('Track')
- for session_ in session_data:
- # Filter out background theme music sessions
- if helpers.get_xml_attr(session_, 'guid').startswith('library://'):
- continue
- session_output = self.get_session_each(session_, skip_cache=skip_cache)
- session_list.append(session_output)
- if a.getElementsByTagName('Video'):
- session_data = a.getElementsByTagName('Video')
- for session_ in session_data:
- session_output = self.get_session_each(session_, skip_cache=skip_cache)
- session_list.append(session_output)
- if a.getElementsByTagName('Photo'):
- session_data = a.getElementsByTagName('Photo')
- for session_ in session_data:
- session_output = self.get_session_each(session_, skip_cache=skip_cache)
- session_list.append(session_output)
-
- session_list = sorted(session_list, key=lambda k: k['session_key'])
-
- output = {'stream_count': helpers.get_xml_attr(xml_head[0], 'size'),
- 'sessions': session.mask_session_info(session_list)
- }
-
- return output
-
- def get_session_each(self, session=None, skip_cache=False):
- """
- Return selected data from current sessions.
- This function processes and validates session data
-
- Parameters required: session { the session dictionary }
- Output: dict
- """
-
- # Get the source media type
- media_type = helpers.get_xml_attr(session, 'type')
- rating_key = helpers.get_xml_attr(session, 'ratingKey')
- session_key = helpers.get_xml_attr(session, 'sessionKey')
-
- # Get the user details
- user_info = session.getElementsByTagName('User')[0]
- user_id = helpers.get_xml_attr(user_info, 'id')
- if user_id == '1': # Admin user
- user_details = users.Users().get_details(user=helpers.get_xml_attr(user_info, 'title'))
- else:
- user_details = users.Users().get_details(user_id=user_id)
-
- # Get the player details
- player_info = session.getElementsByTagName('Player')[0]
-
- # Override platform names
- platform = helpers.get_xml_attr(player_info, 'platform')
- platform = common.PLATFORM_NAME_OVERRIDES.get(platform, platform)
- if not platform and helpers.get_xml_attr(player_info, 'product') == 'DLNA':
- platform = 'DLNA'
-
- platform_name = next((v for k, v in common.PLATFORM_NAMES.items() if k in platform.lower()), 'default')
-
- player_details = {'ip_address': helpers.get_xml_attr(player_info, 'address').split('::ffff:')[-1],
- 'ip_address_public':
- helpers.get_xml_attr(player_info, 'remotePublicAddress').split('::ffff:')[-1],
- 'device': helpers.get_xml_attr(player_info, 'device'),
- 'platform': platform,
- 'platform_name': platform_name,
- 'platform_version': helpers.get_xml_attr(player_info, 'platformVersion'),
- 'product': helpers.get_xml_attr(player_info, 'product'),
- 'product_version': helpers.get_xml_attr(player_info, 'version'),
- 'profile': helpers.get_xml_attr(player_info, 'profile'),
- 'player': helpers.get_xml_attr(player_info, 'title') or helpers.get_xml_attr(player_info,
- 'product'),
- 'machine_id': helpers.get_xml_attr(player_info, 'machineIdentifier'),
- 'state': helpers.get_xml_attr(player_info, 'state'),
- 'local': int(helpers.get_xml_attr(player_info, 'local') == '1'),
- 'relayed': helpers.get_xml_attr(player_info, 'relayed', default_return=None),
- 'secure': helpers.get_xml_attr(player_info, 'secure', default_return=None)
- }
-
- # Get the session details
- if session.getElementsByTagName('Session'):
- session_info = session.getElementsByTagName('Session')[0]
-
- session_details = {'session_id': helpers.get_xml_attr(session_info, 'id'),
- 'bandwidth': helpers.get_xml_attr(session_info, 'bandwidth'),
- 'location': helpers.get_xml_attr(session_info, 'location')
- }
- else:
- session_details = {'session_id': '',
- 'bandwidth': '',
- 'location': 'lan' if player_details['local'] else 'wan'
- }
-
- # Check if using Plex Relay
- if player_details['relayed'] is None:
- player_details['relayed'] = int(session_details['location'] != 'lan' and
- player_details['ip_address_public'] == '127.0.0.1')
-
- else:
- player_details['relayed'] = helpers.cast_to_int(player_details['relayed'])
-
- # Check if secure connection
- if player_details['secure'] is not None:
- player_details['secure'] = int(player_details['secure'] == '1')
-
- # Get the transcode details
- if session.getElementsByTagName('TranscodeSession'):
- transcode_session = True
-
- transcode_info = session.getElementsByTagName('TranscodeSession')[0]
-
- transcode_progress = helpers.get_xml_attr(transcode_info, 'progress')
- transcode_speed = helpers.get_xml_attr(transcode_info, 'speed')
-
- transcode_details = {'transcode_key': helpers.get_xml_attr(transcode_info, 'key'),
- 'transcode_throttled': int(helpers.get_xml_attr(transcode_info, 'throttled') == '1'),
- 'transcode_progress': int(round(helpers.cast_to_float(transcode_progress), 0)),
- 'transcode_speed': str(round(helpers.cast_to_float(transcode_speed), 1)),
- 'transcode_audio_channels': helpers.get_xml_attr(transcode_info, 'audioChannels'),
- 'transcode_audio_codec': helpers.get_xml_attr(transcode_info, 'audioCodec'),
- 'transcode_video_codec': helpers.get_xml_attr(transcode_info, 'videoCodec'),
- 'transcode_width': helpers.get_xml_attr(transcode_info, 'width'),
- # Blank but keep for backwards compatibility
- 'transcode_height': helpers.get_xml_attr(transcode_info, 'height'),
- # Blank but keep backwards compatibility
- 'transcode_container': helpers.get_xml_attr(transcode_info, 'container'),
- 'transcode_protocol': helpers.get_xml_attr(transcode_info, 'protocol'),
- 'transcode_hw_requested': int(
- helpers.get_xml_attr(transcode_info, 'transcodeHwRequested') == '1'),
- 'transcode_hw_decode': helpers.get_xml_attr(transcode_info, 'transcodeHwDecoding'),
- 'transcode_hw_decode_title': helpers.get_xml_attr(transcode_info,
- 'transcodeHwDecodingTitle'),
- 'transcode_hw_encode': helpers.get_xml_attr(transcode_info, 'transcodeHwEncoding'),
- 'transcode_hw_encode_title': helpers.get_xml_attr(transcode_info,
- 'transcodeHwEncodingTitle'),
- 'transcode_hw_full_pipeline': int(
- helpers.get_xml_attr(transcode_info, 'transcodeHwFullPipeline') == '1'),
- 'audio_decision': helpers.get_xml_attr(transcode_info, 'audioDecision'),
- 'video_decision': helpers.get_xml_attr(transcode_info, 'videoDecision'),
- 'subtitle_decision': helpers.get_xml_attr(transcode_info, 'subtitleDecision'),
- 'throttled': '1' if helpers.get_xml_attr(transcode_info, 'throttled') == '1' else '0'
- # Keep for backwards compatibility
- }
- else:
- transcode_session = False
-
- transcode_details = {'transcode_key': '',
- 'transcode_throttled': 0,
- 'transcode_progress': 0,
- 'transcode_speed': '',
- 'transcode_audio_channels': '',
- 'transcode_audio_codec': '',
- 'transcode_video_codec': '',
- 'transcode_width': '',
- 'transcode_height': '',
- 'transcode_container': '',
- 'transcode_protocol': '',
- 'transcode_hw_requested': 0,
- 'transcode_hw_decode': '',
- 'transcode_hw_decode_title': '',
- 'transcode_hw_encode': '',
- 'transcode_hw_encode_title': '',
- 'transcode_hw_full_pipeline': 0,
- 'audio_decision': 'direct play',
- 'video_decision': 'direct play',
- 'subtitle_decision': '',
- 'throttled': '0' # Keep for backwards compatibility
- }
-
- # Check HW decoding/encoding
- transcode_details['transcode_hw_decoding'] = int(
- transcode_details['transcode_hw_decode'].lower() in common.HW_DECODERS)
- transcode_details['transcode_hw_encoding'] = int(
- transcode_details['transcode_hw_encode'].lower() in common.HW_ENCODERS)
-
- # Determine if a synced version is being played
- sync_id = synced_session_data = synced_item_details = None
- if media_type not in ('photo', 'clip') \
- and not session.getElementsByTagName('Session') \
- and not session.getElementsByTagName('TranscodeSession') \
- and helpers.get_xml_attr(session, 'ratingKey').isdigit() \
- and jellypy.CONFIG.PMS_PLEXPASS:
- plex_tv = plextv.PlexTV()
- parent_rating_key = helpers.get_xml_attr(session, 'parentRatingKey')
- grandparent_rating_key = helpers.get_xml_attr(session, 'grandparentRatingKey')
-
- synced_items = plex_tv.get_synced_items(client_id_filter=player_details['machine_id'],
- rating_key_filter=[rating_key, parent_rating_key,
- grandparent_rating_key])
- if synced_items:
- synced_item_details = synced_items[0]
- sync_id = synced_item_details['sync_id']
- synced_xml = self.get_sync_item(sync_id=sync_id, output_format='xml')
- synced_xml_head = synced_xml.getElementsByTagName('MediaContainer')
-
- synced_xml_items = []
- if synced_xml_head[0].getElementsByTagName('Track'):
- synced_xml_items = synced_xml_head[0].getElementsByTagName('Track')
- elif synced_xml_head[0].getElementsByTagName('Video'):
- synced_xml_items = synced_xml_head[0].getElementsByTagName('Video')
-
- for synced_session_data in synced_xml_items:
- if helpers.get_xml_attr(synced_session_data, 'ratingKey') == rating_key:
- break
-
- # Figure out which version is being played
- if sync_id and synced_session_data:
- media_info_all = synced_session_data.getElementsByTagName('Media')
- else:
- media_info_all = session.getElementsByTagName('Media')
- stream_media_info = next((m for m in media_info_all if helpers.get_xml_attr(m, 'selected') == '1'),
- media_info_all[0])
- part_info_all = stream_media_info.getElementsByTagName('Part')
- stream_media_parts_info = next((p for p in part_info_all if helpers.get_xml_attr(p, 'selected') == '1'),
- part_info_all[0])
-
- # Get the stream details
- video_stream_info = audio_stream_info = subtitle_stream_info = None
- for stream in stream_media_parts_info.getElementsByTagName('Stream'):
- if helpers.get_xml_attr(stream, 'streamType') == '1':
- if video_stream_info is None or helpers.get_xml_attr(stream, 'selected') == '1':
- video_stream_info = stream
-
- elif helpers.get_xml_attr(stream, 'streamType') == '2':
- if audio_stream_info is None or helpers.get_xml_attr(stream, 'selected') == '1':
- audio_stream_info = stream
-
- elif helpers.get_xml_attr(stream, 'streamType') == '3':
- if subtitle_stream_info is None or helpers.get_xml_attr(stream, 'selected') == '1':
- subtitle_stream_info = stream
-
- video_id = audio_id = subtitle_id = None
- if video_stream_info:
- video_id = helpers.get_xml_attr(video_stream_info, 'id')
- video_details = {'stream_video_bitrate': helpers.get_xml_attr(video_stream_info, 'bitrate'),
- 'stream_video_bit_depth': helpers.get_xml_attr(video_stream_info, 'bitDepth'),
- 'stream_video_chroma_subsampling': helpers.get_xml_attr(video_stream_info,
- 'chromaSubsampling'),
- 'stream_video_color_primaries': helpers.get_xml_attr(video_stream_info, 'colorPrimaries'),
- 'stream_video_color_range': helpers.get_xml_attr(video_stream_info, 'colorRange'),
- 'stream_video_color_space': helpers.get_xml_attr(video_stream_info, 'colorSpace'),
- 'stream_video_color_trc': helpers.get_xml_attr(video_stream_info, 'colorTrc'),
- 'stream_video_codec_level': helpers.get_xml_attr(video_stream_info, 'level'),
- 'stream_video_ref_frames': helpers.get_xml_attr(video_stream_info, 'refFrames'),
- 'stream_video_language': helpers.get_xml_attr(video_stream_info, 'language'),
- 'stream_video_language_code': helpers.get_xml_attr(video_stream_info, 'languageCode'),
- 'stream_video_scan_type': helpers.get_xml_attr(video_stream_info, 'scanType'),
- 'stream_video_decision': helpers.get_xml_attr(video_stream_info,
- 'decision') or 'direct play'
- }
- else:
- video_details = {'stream_video_bitrate': '',
- 'stream_video_bit_depth': '',
- 'stream_video_chroma_subsampling': '',
- 'stream_video_color_primaries': '',
- 'stream_video_color_range': '',
- 'stream_video_color_space': '',
- 'stream_video_color_trc': '',
- 'stream_video_codec_level': '',
- 'stream_video_ref_frames': '',
- 'stream_video_language': '',
- 'stream_video_language_code': '',
- 'stream_video_scan_type': '',
- 'stream_video_decision': ''
- }
-
- if audio_stream_info:
- audio_id = helpers.get_xml_attr(audio_stream_info, 'id')
- audio_details = {'stream_audio_bitrate': helpers.get_xml_attr(audio_stream_info, 'bitrate'),
- 'stream_audio_bitrate_mode': helpers.get_xml_attr(audio_stream_info, 'bitrateMode'),
- 'stream_audio_sample_rate': helpers.get_xml_attr(audio_stream_info, 'samplingRate'),
- 'stream_audio_channel_layout_': helpers.get_xml_attr(audio_stream_info,
- 'audioChannelLayout'),
- 'stream_audio_language': helpers.get_xml_attr(audio_stream_info, 'language'),
- 'stream_audio_language_code': helpers.get_xml_attr(audio_stream_info, 'languageCode'),
- 'stream_audio_decision': helpers.get_xml_attr(audio_stream_info,
- 'decision') or 'direct play'
- }
- else:
- audio_details = {'stream_audio_bitrate': '',
- 'stream_audio_bitrate_mode': '',
- 'stream_audio_sample_rate': '',
- 'stream_audio_channel_layout_': '',
- 'stream_audio_language': '',
- 'stream_audio_language_code': '',
- 'stream_audio_decision': ''
- }
-
- if subtitle_stream_info:
- subtitle_id = helpers.get_xml_attr(subtitle_stream_info, 'id')
- subtitle_selected = helpers.get_xml_attr(subtitle_stream_info, 'selected')
- subtitle_details = {'stream_subtitle_codec': helpers.get_xml_attr(subtitle_stream_info, 'codec'),
- 'stream_subtitle_container': helpers.get_xml_attr(subtitle_stream_info, 'container'),
- 'stream_subtitle_format': helpers.get_xml_attr(subtitle_stream_info, 'format'),
- 'stream_subtitle_forced': int(
- helpers.get_xml_attr(subtitle_stream_info, 'forced') == '1'),
- 'stream_subtitle_location': helpers.get_xml_attr(subtitle_stream_info, 'location'),
- 'stream_subtitle_language': helpers.get_xml_attr(subtitle_stream_info, 'language'),
- 'stream_subtitle_language_code': helpers.get_xml_attr(subtitle_stream_info,
- 'languageCode'),
- 'stream_subtitle_decision': helpers.get_xml_attr(subtitle_stream_info, 'decision'),
- 'stream_subtitle_transient': int(
- helpers.get_xml_attr(subtitle_stream_info, 'transient') == '1')
- }
- else:
- subtitle_selected = None
- subtitle_details = {'stream_subtitle_codec': '',
- 'stream_subtitle_container': '',
- 'stream_subtitle_format': '',
- 'stream_subtitle_forced': 0,
- 'stream_subtitle_location': '',
- 'stream_subtitle_language': '',
- 'stream_subtitle_language_code': '',
- 'stream_subtitle_decision': '',
- 'stream_subtitle_transient': 0
- }
-
- # Get the bif thumbnail
- indexes = helpers.get_xml_attr(stream_media_parts_info, 'indexes')
- view_offset = helpers.get_xml_attr(session, 'viewOffset')
- if indexes == 'sd':
- part_id = helpers.get_xml_attr(stream_media_parts_info, 'id')
- bif_thumb = '/library/parts/{part_id}/indexes/sd/{view_offset}'.format(part_id=part_id,
- view_offset=view_offset)
- else:
- bif_thumb = ''
-
- stream_video_width = helpers.get_xml_attr(stream_media_info, 'width')
- if helpers.cast_to_int(stream_video_width) >= 3840:
- stream_video_resolution = '4k'
- else:
- stream_video_resolution = helpers.get_xml_attr(stream_media_info, 'videoResolution').lower().rstrip('ip')
-
- stream_audio_channels = helpers.get_xml_attr(stream_media_info, 'audioChannels')
-
- stream_details = {'stream_container': helpers.get_xml_attr(stream_media_info, 'container'),
- 'stream_bitrate': helpers.get_xml_attr(stream_media_info, 'bitrate'),
- 'stream_aspect_ratio': helpers.get_xml_attr(stream_media_info, 'aspectRatio'),
- 'stream_audio_codec': helpers.get_xml_attr(stream_media_info, 'audioCodec'),
- 'stream_audio_channels': stream_audio_channels,
- 'stream_audio_channel_layout': audio_details.get(
- 'stream_audio_channel_layout_') or common.AUDIO_CHANNELS.get(stream_audio_channels,
- stream_audio_channels),
- 'stream_video_codec': helpers.get_xml_attr(stream_media_info, 'videoCodec'),
- 'stream_video_framerate': helpers.get_xml_attr(stream_media_info, 'videoFrameRate'),
- 'stream_video_resolution': stream_video_resolution,
- 'stream_video_height': helpers.get_xml_attr(stream_media_info, 'height'),
- 'stream_video_width': helpers.get_xml_attr(stream_media_info, 'width'),
- 'stream_duration': helpers.get_xml_attr(stream_media_info,
- 'duration') or helpers.get_xml_attr(session,
- 'duration'),
- 'stream_container_decision': 'direct play' if sync_id else helpers.get_xml_attr(
- stream_media_parts_info, 'decision').replace('directplay', 'direct play'),
- 'optimized_version': int(helpers.get_xml_attr(stream_media_info, 'proxyType') == '42'),
- 'optimized_version_title': helpers.get_xml_attr(stream_media_info, 'title'),
- 'synced_version': 1 if sync_id else 0,
- 'live': int(helpers.get_xml_attr(session, 'live') == '1'),
- 'live_uuid': helpers.get_xml_attr(stream_media_info, 'uuid'),
- 'indexes': int(indexes == 'sd'),
- 'bif_thumb': bif_thumb,
- 'subtitles': 1 if subtitle_id and subtitle_selected else 0
- }
-
- # Get the source media info
- source_media_details = source_media_part_details = \
- source_video_details = source_audio_details = source_subtitle_details = {}
-
- if not helpers.get_xml_attr(session, 'ratingKey').isdigit():
- channel_stream = 1
-
- audio_channels = helpers.get_xml_attr(stream_media_info, 'audioChannels')
- metadata_details = {'media_type': media_type,
- 'section_id': helpers.get_xml_attr(session, 'librarySectionID'),
- 'library_name': helpers.get_xml_attr(session, 'librarySectionTitle'),
- 'rating_key': helpers.get_xml_attr(session, 'ratingKey'),
- 'parent_rating_key': helpers.get_xml_attr(session, 'parentRatingKey'),
- 'grandparent_rating_key': helpers.get_xml_attr(session, 'grandparentRatingKey'),
- 'title': helpers.get_xml_attr(session, 'title'),
- 'parent_title': helpers.get_xml_attr(session, 'parentTitle'),
- 'grandparent_title': helpers.get_xml_attr(session, 'grandparentTitle'),
- 'original_title': helpers.get_xml_attr(session, 'originalTitle'),
- 'sort_title': helpers.get_xml_attr(session, 'titleSort'),
- 'media_index': helpers.get_xml_attr(session, 'index'),
- 'parent_media_index': helpers.get_xml_attr(session, 'parentIndex'),
- 'studio': helpers.get_xml_attr(session, 'studio'),
- 'content_rating': helpers.get_xml_attr(session, 'contentRating'),
- 'summary': helpers.get_xml_attr(session, 'summary'),
- 'tagline': helpers.get_xml_attr(session, 'tagline'),
- 'rating': helpers.get_xml_attr(session, 'rating'),
- 'rating_image': helpers.get_xml_attr(session, 'ratingImage'),
- 'audience_rating': helpers.get_xml_attr(session, 'audienceRating'),
- 'audience_rating_image': helpers.get_xml_attr(session, 'audienceRatingImage'),
- 'user_rating': helpers.get_xml_attr(session, 'userRating'),
- 'duration': helpers.get_xml_attr(session, 'duration'),
- 'year': helpers.get_xml_attr(session, 'year'),
- 'thumb': helpers.get_xml_attr(session, 'thumb'),
- 'parent_thumb': helpers.get_xml_attr(session, 'parentThumb'),
- 'grandparent_thumb': helpers.get_xml_attr(session, 'grandparentThumb'),
- 'art': helpers.get_xml_attr(session, 'art'),
- 'banner': helpers.get_xml_attr(session, 'banner'),
- 'originally_available_at': helpers.get_xml_attr(session, 'originallyAvailableAt'),
- 'added_at': helpers.get_xml_attr(session, 'addedAt'),
- 'updated_at': helpers.get_xml_attr(session, 'updatedAt'),
- 'last_viewed_at': helpers.get_xml_attr(session, 'lastViewedAt'),
- 'guid': helpers.get_xml_attr(session, 'guid'),
- 'directors': [],
- 'writers': [],
- 'actors': [],
- 'genres': [],
- 'labels': [],
- 'full_title': helpers.get_xml_attr(session, 'title'),
- 'container': helpers.get_xml_attr(stream_media_info, 'container') \
- or helpers.get_xml_attr(stream_media_parts_info, 'container'),
- 'bitrate': helpers.get_xml_attr(stream_media_info, 'bitrate'),
- 'height': helpers.get_xml_attr(stream_media_info, 'height'),
- 'width': helpers.get_xml_attr(stream_media_info, 'width'),
- 'aspect_ratio': helpers.get_xml_attr(stream_media_info, 'aspectRatio'),
- 'video_codec': helpers.get_xml_attr(stream_media_info, 'videoCodec'),
- 'video_resolution': helpers.get_xml_attr(stream_media_info, 'videoResolution').lower(),
- 'video_full_resolution': helpers.get_xml_attr(stream_media_info,
- 'videoResolution').lower(),
- 'video_framerate': helpers.get_xml_attr(stream_media_info, 'videoFrameRate'),
- 'video_profile': helpers.get_xml_attr(stream_media_info, 'videoProfile'),
- 'audio_codec': helpers.get_xml_attr(stream_media_info, 'audioCodec'),
- 'audio_channels': audio_channels,
- 'audio_channel_layout': common.AUDIO_CHANNELS.get(audio_channels, audio_channels),
- 'audio_profile': helpers.get_xml_attr(stream_media_info, 'audioProfile'),
- 'channel_icon': helpers.get_xml_attr(session, 'sourceIcon'),
- 'channel_title': helpers.get_xml_attr(session, 'sourceTitle'),
- 'extra_type': helpers.get_xml_attr(session, 'extraType'),
- 'sub_type': helpers.get_xml_attr(session, 'subtype')
- }
- else:
- channel_stream = 0
-
- media_id = helpers.get_xml_attr(stream_media_info, 'id')
- part_id = helpers.get_xml_attr(stream_media_parts_info, 'id')
-
- if sync_id:
- metadata_details = self.get_metadata_details(rating_key=rating_key, sync_id=sync_id,
- skip_cache=skip_cache, cache_key=session_key)
- else:
- metadata_details = self.get_metadata_details(rating_key=rating_key,
- skip_cache=skip_cache, cache_key=session_key)
-
- # Get the media info, fallback to first item if match id is not found
- source_medias = metadata_details.pop('media_info', [])
- source_media_details = next((m for m in source_medias if m['id'] == media_id),
- next((m for m in source_medias), {}))
- source_media_parts = source_media_details.pop('parts', [])
- source_media_part_details = next((p for p in source_media_parts if p['id'] == part_id),
- next((p for p in source_media_parts), {}))
- source_media_part_streams = source_media_part_details.pop('streams', [])
-
- source_video_details = {'id': '',
- 'type': '',
- 'video_codec': '',
- 'video_codec_level': '',
- 'video_bitrate': '',
- 'video_bit_depth': '',
- 'video_chroma_subsampling': '',
- 'video_color_primaries': '',
- 'video_color_range': '',
- 'video_color_space': '',
- 'video_color_trc': '',
- 'video_frame_rate': '',
- 'video_ref_frames': '',
- 'video_height': '',
- 'video_width': '',
- 'video_language': '',
- 'video_language_code': '',
- 'video_scan_type': '',
- 'video_profile': ''
- }
- source_audio_details = {'id': '',
- 'type': '',
- 'audio_codec': '',
- 'audio_bitrate': '',
- 'audio_bitrate_mode': '',
- 'audio_channels': '',
- 'audio_channel_layout': '',
- 'audio_sample_rate': '',
- 'audio_language': '',
- 'audio_language_code': '',
- 'audio_profile': ''
- }
- source_subtitle_details = {'id': '',
- 'type': '',
- 'subtitle_codec': '',
- 'subtitle_container': '',
- 'subtitle_format': '',
- 'subtitle_forced': 0,
- 'subtitle_location': '',
- 'subtitle_language': '',
- 'subtitle_language_code': ''
- }
- if video_id:
- source_video_details = next((p for p in source_media_part_streams if p['id'] == video_id),
- next((p for p in source_media_part_streams if p['type'] == '1'),
- source_video_details))
- if audio_id:
- source_audio_details = next((p for p in source_media_part_streams if p['id'] == audio_id),
- next((p for p in source_media_part_streams if p['type'] == '2'),
- source_audio_details))
- if subtitle_id:
- source_subtitle_details = next((p for p in source_media_part_streams if p['id'] == subtitle_id),
- next((p for p in source_media_part_streams if p['type'] == '3'),
- source_subtitle_details))
-
- # Override the thumb for clips
- if media_type == 'clip' and metadata_details.get('extra_type') and metadata_details['art']:
- metadata_details['thumb'] = metadata_details['art'].replace('/art', '/thumb')
-
- # Overrides for live sessions
- if stream_details['live'] and transcode_session:
- stream_details['stream_container_decision'] = 'transcode'
- stream_details['stream_container'] = transcode_details['transcode_container']
-
- video_details['stream_video_decision'] = transcode_details['video_decision']
- stream_details['stream_video_codec'] = transcode_details['transcode_video_codec']
-
- audio_details['stream_audio_decision'] = transcode_details['audio_decision']
- stream_details['stream_audio_codec'] = transcode_details['transcode_audio_codec']
- stream_details['stream_audio_channels'] = transcode_details['transcode_audio_channels']
- stream_details['stream_audio_channel_layout'] = common.AUDIO_CHANNELS.get(
- transcode_details['transcode_audio_channels'], transcode_details['transcode_audio_channels'])
-
- # Generate a combined transcode decision value
- if video_details['stream_video_decision'] == 'transcode' or audio_details[
- 'stream_audio_decision'] == 'transcode':
- transcode_decision = 'transcode'
- elif video_details['stream_video_decision'] == 'copy' or audio_details['stream_audio_decision'] == 'copy':
- transcode_decision = 'copy'
- else:
- transcode_decision = 'direct play'
-
- stream_details['transcode_decision'] = transcode_decision
- stream_details['container_decision'] = stream_details['stream_container_decision']
-
- # Override * in audio codecs
- if stream_details['stream_audio_codec'] == '*':
- stream_details['stream_audio_codec'] = source_audio_details.get('audio_codec', '')
- if transcode_details['transcode_audio_codec'] == '*':
- transcode_details['transcode_audio_codec'] = source_audio_details.get('audio_codec', '')
-
- # Override * in video codecs
- if stream_details['stream_video_codec'] == '*':
- stream_details['stream_video_codec'] = source_video_details.get('video_codec', '')
- if transcode_details['transcode_video_codec'] == '*':
- transcode_details['transcode_video_codec'] = source_video_details.get('video_codec', '')
-
- if media_type in ('movie', 'episode', 'clip'):
- # Set the full resolution by combining stream_video_resolution and stream_video_scan_type
- stream_details['stream_video_full_resolution'] = common.VIDEO_RESOLUTION_OVERRIDES.get(
- stream_details['stream_video_resolution'],
- stream_details['stream_video_resolution'] + (video_details['stream_video_scan_type'][:1] or 'p'))
-
- if helpers.cast_to_int(source_video_details.get('video_bit_depth')) > 8 \
- and source_video_details.get('video_color_space') == 'bt2020nc':
- stream_details['video_dynamic_range'] = 'HDR'
- else:
- stream_details['video_dynamic_range'] = 'SDR'
-
- if stream_details['video_dynamic_range'] == 'HDR' \
- and video_details['stream_video_decision'] != 'transcode' \
- or helpers.cast_to_int(video_details['stream_video_bit_depth']) > 8 \
- and video_details['stream_video_color_space'] == 'bt2020nc':
- stream_details['stream_video_dynamic_range'] = 'HDR'
- else:
- stream_details['stream_video_dynamic_range'] = 'SDR'
- else:
- stream_details['video_dynamic_range'] = ''
- stream_details['stream_video_dynamic_range'] = ''
-
- # Get the quality profile
- if media_type in ('movie', 'episode', 'clip') and 'stream_bitrate' in stream_details:
- if sync_id:
- quality_profile = 'Original'
-
- synced_item_bitrate = helpers.cast_to_int(synced_item_details['video_bitrate'])
- try:
- synced_bitrate = max(b for b in common.VIDEO_QUALITY_PROFILES if b <= synced_item_bitrate)
- synced_version_profile = common.VIDEO_QUALITY_PROFILES[synced_bitrate]
- except ValueError:
- synced_version_profile = 'Original'
- else:
- synced_version_profile = ''
-
- stream_bitrate = helpers.cast_to_int(stream_details['stream_bitrate'])
- source_bitrate = helpers.cast_to_int(source_media_details.get('bitrate'))
- try:
- quailtiy_bitrate = min(
- b for b in common.VIDEO_QUALITY_PROFILES if stream_bitrate <= b <= source_bitrate)
- quality_profile = common.VIDEO_QUALITY_PROFILES[quailtiy_bitrate]
- except ValueError:
- quality_profile = 'Original'
-
- if stream_details['optimized_version']:
- source_bitrate = helpers.cast_to_int(source_media_details.get('bitrate'))
- optimized_version_profile = '{} Mbps {}'.format(round(source_bitrate / 1000.0, 1),
- source_media_details.get('video_full_resolution'))
- else:
- optimized_version_profile = ''
-
- elif media_type == 'track' and 'stream_bitrate' in stream_details:
- if sync_id:
- quality_profile = 'Original'
-
- synced_item_bitrate = helpers.cast_to_int(synced_item_details['audio_bitrate'])
- try:
- synced_bitrate = max(b for b in common.AUDIO_QUALITY_PROFILES if b <= synced_item_bitrate)
- synced_version_profile = common.AUDIO_QUALITY_PROFILES[synced_bitrate]
- except ValueError:
- synced_version_profile = 'Original'
- else:
- synced_version_profile = ''
-
- stream_bitrate = helpers.cast_to_int(stream_details['stream_bitrate'])
- source_bitrate = helpers.cast_to_int(source_media_details.get('bitrate'))
- try:
- quailtiy_bitrate = min(
- b for b in common.AUDIO_QUALITY_PROFILES if stream_bitrate <= b <= source_bitrate)
- quality_profile = common.AUDIO_QUALITY_PROFILES[quailtiy_bitrate]
- except ValueError:
- quality_profile = 'Original'
-
- optimized_version_profile = ''
-
- elif media_type == 'photo':
- quality_profile = 'Original'
- synced_version_profile = ''
- optimized_version_profile = ''
-
- else:
- quality_profile = 'Unknown'
- synced_version_profile = ''
- optimized_version_profile = ''
-
- # Entire session output (single dict for backwards compatibility)
- session_output = {'session_key': session_key,
- 'media_type': media_type,
- 'view_offset': view_offset,
- 'progress_percent': str(helpers.get_percent(view_offset, stream_details['stream_duration'])),
- 'quality_profile': quality_profile,
- 'synced_version_profile': synced_version_profile,
- 'optimized_version_profile': optimized_version_profile,
- 'user': user_details['username'], # Keep for backwards compatibility
- 'channel_stream': channel_stream
- }
-
- session_output.update(metadata_details)
- session_output.update(source_media_details)
- session_output.update(source_media_part_details)
- session_output.update(source_video_details)
- session_output.update(source_audio_details)
- session_output.update(source_subtitle_details)
- session_output.update(user_details)
- session_output.update(player_details)
- session_output.update(session_details)
- session_output.update(transcode_details)
- session_output.update(stream_details)
- session_output.update(video_details)
- session_output.update(audio_details)
- session_output.update(subtitle_details)
-
- return session_output
-
- def terminate_session(self, session_key='', session_id='', message=''):
- """
- Terminates a streaming session.
-
- Output: bool
- """
- plex_tv = plextv.PlexTV()
- if not plex_tv.get_plexpass_status():
- msg = 'No Plex Pass subscription'
- logger.warn("Tautulli Pmsconnect :: Failed to terminate session: %s." % msg)
- return msg
-
- message = message.encode('utf-8') or 'The server owner has ended the stream.'
-
- ap = activity_processor.ActivityProcessor()
-
- if session_key:
- session = ap.get_session_by_key(session_key=session_key)
- if session and not session_id:
- session_id = session['session_id']
-
- elif session_id:
- session = ap.get_session_by_id(session_id=session_id)
- if session and not session_key:
- session_key = session['session_key']
-
- else:
- session = session_key = session_id = None
-
- if not session:
- msg = 'Invalid session_key (%s) or session_id (%s)' % (session_key, session_id)
- logger.warn("Tautulli Pmsconnect :: Failed to terminate session: %s." % msg)
- return msg
-
- if session_id:
- logger.info("Tautulli Pmsconnect :: Terminating session %s (session_id %s)." % (session_key, session_id))
- result = self.get_sessions_terminate(session_id=session_id, reason=message)
- return True
- else:
- msg = 'Missing session_id'
- logger.warn("Tautulli Pmsconnect :: Failed to terminate session: %s." % msg)
- return msg
-
- def get_item_children(self, rating_key='', media_type=None, get_grandchildren=False):
- """
- Return processed and validated children list.
-
- Output: array
- """
- if media_type == 'playlist':
- children_data = self.get_playlist_items(rating_key, output_format='xml')
- elif get_grandchildren:
- children_data = self.get_metadata_grandchildren(rating_key, output_format='xml')
- else:
- children_data = self.get_metadata_children(rating_key, output_format='xml')
-
- try:
- xml_head = children_data.getElementsByTagName('MediaContainer')
- except Exception as e:
- logger.warn("Tautulli Pmsconnect :: Unable to parse XML for get_item_children: %s." % e)
- return []
-
- children_list = []
-
- for a in xml_head:
- if a.getAttribute('size'):
- if a.getAttribute('size') == '0':
- logger.debug("Tautulli Pmsconnect :: No children data.")
- children_list = {'children_count': 0,
- 'children_list': []
- }
- return children_list
-
- result_data = []
-
- for x in a.childNodes:
- if x.nodeType == Node.ELEMENT_NODE and x.tagName in ('Directory', 'Video', 'Track', 'Photo'):
- result_data.append(x)
-
- if result_data:
- for m in result_data:
- directors = []
- writers = []
- actors = []
- genres = []
- labels = []
-
- if m.getElementsByTagName('Director'):
- for director in m.getElementsByTagName('Director'):
- directors.append(helpers.get_xml_attr(director, 'tag'))
-
- if m.getElementsByTagName('Writer'):
- for writer in m.getElementsByTagName('Writer'):
- writers.append(helpers.get_xml_attr(writer, 'tag'))
-
- if m.getElementsByTagName('Role'):
- for actor in m.getElementsByTagName('Role'):
- actors.append(helpers.get_xml_attr(actor, 'tag'))
-
- if m.getElementsByTagName('Genre'):
- for genre in m.getElementsByTagName('Genre'):
- genres.append(helpers.get_xml_attr(genre, 'tag'))
-
- if m.getElementsByTagName('Label'):
- for label in m.getElementsByTagName('Label'):
- labels.append(helpers.get_xml_attr(label, 'tag'))
-
- media_type = helpers.get_xml_attr(m, 'type')
- if m.nodeName == 'Directory' and media_type == 'photo':
- media_type = 'photo_album'
-
- children_output = {'media_type': media_type,
- 'section_id': helpers.get_xml_attr(m, 'librarySectionID'),
- 'library_name': helpers.get_xml_attr(m, 'librarySectionTitle'),
- 'rating_key': helpers.get_xml_attr(m, 'ratingKey'),
- 'parent_rating_key': helpers.get_xml_attr(m, 'parentRatingKey'),
- 'grandparent_rating_key': helpers.get_xml_attr(m, 'grandparentRatingKey'),
- 'title': helpers.get_xml_attr(m, 'title'),
- 'parent_title': helpers.get_xml_attr(m, 'parentTitle'),
- 'grandparent_title': helpers.get_xml_attr(m, 'grandparentTitle'),
- 'original_title': helpers.get_xml_attr(m, 'originalTitle'),
- 'sort_title': helpers.get_xml_attr(m, 'titleSort'),
- 'media_index': helpers.get_xml_attr(m, 'index'),
- 'parent_media_index': helpers.get_xml_attr(m, 'parentIndex'),
- 'studio': helpers.get_xml_attr(m, 'studio'),
- 'content_rating': helpers.get_xml_attr(m, 'contentRating'),
- 'summary': helpers.get_xml_attr(m, 'summary'),
- 'tagline': helpers.get_xml_attr(m, 'tagline'),
- 'rating': helpers.get_xml_attr(m, 'rating'),
- 'rating_image': helpers.get_xml_attr(m, 'ratingImage'),
- 'audience_rating': helpers.get_xml_attr(m, 'audienceRating'),
- 'audience_rating_image': helpers.get_xml_attr(m, 'audienceRatingImage'),
- 'user_rating': helpers.get_xml_attr(m, 'userRating'),
- 'duration': helpers.get_xml_attr(m, 'duration'),
- 'year': helpers.get_xml_attr(m, 'year'),
- 'thumb': helpers.get_xml_attr(m, 'thumb'),
- 'parent_thumb': helpers.get_xml_attr(m, 'parentThumb'),
- 'grandparent_thumb': helpers.get_xml_attr(m, 'grandparentThumb'),
- 'art': helpers.get_xml_attr(m, 'art'),
- 'banner': helpers.get_xml_attr(m, 'banner'),
- 'originally_available_at': helpers.get_xml_attr(m, 'originallyAvailableAt'),
- 'added_at': helpers.get_xml_attr(m, 'addedAt'),
- 'updated_at': helpers.get_xml_attr(m, 'updatedAt'),
- 'last_viewed_at': helpers.get_xml_attr(m, 'lastViewedAt'),
- 'guid': helpers.get_xml_attr(m, 'guid'),
- 'directors': directors,
- 'writers': writers,
- 'actors': actors,
- 'genres': genres,
- 'labels': labels,
- 'full_title': helpers.get_xml_attr(m, 'title')
- }
- children_list.append(children_output)
-
- output = {'children_count': helpers.cast_to_int(helpers.get_xml_attr(xml_head[0], 'size')),
- 'children_type': helpers.get_xml_attr(xml_head[0], 'viewGroup'),
- 'title': helpers.get_xml_attr(xml_head[0], 'title2'),
- 'children_list': children_list
- }
-
- return output
-
- def get_item_children_related(self, rating_key=''):
- """
- Return processed and validated children list.
-
- Output: array
- """
- children_data = self.get_children_list_related(rating_key, output_format='xml')
-
- try:
- xml_head = children_data.getElementsByTagName('MediaContainer')
- except Exception as e:
- logger.warn("Tautulli Pmsconnect :: Unable to parse XML for get_item_children_related: %s." % e)
- return []
-
- children_results_list = {'movie': [],
- 'show': [],
- 'season': [],
- 'episode': [],
- 'artist': [],
- 'album': [],
- 'track': [],
- }
-
- for a in xml_head:
- section_id = helpers.get_xml_attr(a, 'librarySectionID')
- hubs = a.getElementsByTagName('Hub')
-
- for h in hubs:
- size = helpers.get_xml_attr(h, 'size')
- media_type = helpers.get_xml_attr(h, 'type')
- title = helpers.get_xml_attr(h, 'title')
- hub_identifier = helpers.get_xml_attr(h, 'hubIdentifier')
-
- if size == '0' or not hub_identifier.startswith('collection.related') or \
- media_type not in children_results_list:
- continue
-
- result_data = []
-
- if h.getElementsByTagName('Video'):
- result_data = h.getElementsByTagName('Video')
- if h.getElementsByTagName('Directory'):
- result_data = h.getElementsByTagName('Directory')
- if h.getElementsByTagName('Track'):
- result_data = h.getElementsByTagName('Track')
-
- for result in result_data:
- children_output = {'section_id': section_id,
- 'rating_key': helpers.get_xml_attr(result, 'ratingKey'),
- 'parent_rating_key': helpers.get_xml_attr(result, 'parentRatingKey'),
- 'media_index': helpers.get_xml_attr(result, 'index'),
- 'title': helpers.get_xml_attr(result, 'title'),
- 'parent_title': helpers.get_xml_attr(result, 'parentTitle'),
- 'year': helpers.get_xml_attr(result, 'year'),
- 'thumb': helpers.get_xml_attr(result, 'thumb'),
- 'parent_thumb': helpers.get_xml_attr(a, 'thumb'),
- 'duration': helpers.get_xml_attr(result, 'duration')
- }
- children_results_list[media_type].append(children_output)
-
- output = {'results_count': sum(len(v) for k, v in children_results_list.items()),
- 'results_list': children_results_list,
- }
-
- return output
-
- def get_servers_info(self):
- """
- Return the list of local servers.
-
- Output: array
- """
- recent = self.get_server_list(output_format='xml')
-
- try:
- xml_head = recent.getElementsByTagName('Server')
- except Exception as e:
- logger.warn("Tautulli Pmsconnect :: Unable to parse XML for get_server_list: %s." % e)
- return []
-
- server_info = []
- for a in xml_head:
- output = {"name": helpers.get_xml_attr(a, 'name'),
- "machine_identifier": helpers.get_xml_attr(a, 'machineIdentifier'),
- "host": helpers.get_xml_attr(a, 'host'),
- "port": helpers.get_xml_attr(a, 'port'),
- "version": helpers.get_xml_attr(a, 'version')
- }
-
- server_info.append(output)
-
- return server_info
-
- def get_server_identity(self):
- """
- Return the local machine identity.
-
- Output: dict
- """
- identity = self.get_local_server_identity(output_format='xml')
-
- try:
- xml_head = identity.getElementsByTagName('MediaContainer')
- except Exception as e:
- logger.warn("Tautulli Pmsconnect :: Unable to parse XML for get_local_server_identity: %s." % e)
- return {}
-
- server_identity = {}
- for a in xml_head:
- server_identity = {"machine_identifier": helpers.get_xml_attr(a, 'machineIdentifier'),
- "version": helpers.get_xml_attr(a, 'version')
- }
-
- return server_identity
-
- def get_server_pref(self, pref=None):
- """
- Return a specified server preference.
-
- Parameters required: pref { name of preference }
-
- Output: string
- """
- if pref:
- prefs = self.get_server_prefs(output_format='xml')
-
- try:
- xml_head = prefs.getElementsByTagName('Setting')
- except Exception as e:
- logger.warn("Tautulli Pmsconnect :: Unable to parse XML for get_local_server_name: %s." % e)
- return ''
-
- pref_value = 'None'
- for a in xml_head:
- if helpers.get_xml_attr(a, 'id') == pref:
- pref_value = helpers.get_xml_attr(a, 'value')
- break
-
- return pref_value
- else:
- logger.debug("Tautulli Pmsconnect :: Server preferences queried but no parameter received.")
- return None
-
- def get_server_children(self):
- """
- Return processed and validated server libraries list.
-
- Output: array
- """
- libraries_data = self.get_libraries_list(output_format='xml')
-
- try:
- xml_head = libraries_data.getElementsByTagName('MediaContainer')
- except Exception as e:
- logger.warn("Tautulli Pmsconnect :: Unable to parse XML for get_libraries_list: %s." % e)
- return []
-
- libraries_list = []
-
- for a in xml_head:
- if a.getAttribute('size'):
- if a.getAttribute('size') == '0':
- logger.debug("Tautulli Pmsconnect :: No libraries data.")
- libraries_list = {'libraries_count': '0',
- 'libraries_list': []
- }
- return libraries_list
-
- if a.getElementsByTagName('Directory'):
- result_data = a.getElementsByTagName('Directory')
- for result in result_data:
- 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'),
- 'agent': helpers.get_xml_attr(result, 'agent'),
- 'thumb': helpers.get_xml_attr(result, 'thumb'),
- 'art': helpers.get_xml_attr(result, 'art')
- }
- libraries_list.append(libraries_output)
-
- output = {'libraries_count': helpers.get_xml_attr(xml_head[0], 'size'),
- 'title': helpers.get_xml_attr(xml_head[0], 'title1'),
- 'libraries_list': libraries_list
- }
-
- return output
-
- def get_library_children_details(self, section_id='', section_type='', list_type='all', count='',
- rating_key='', label_key='', get_media_info=False):
- """
- Return processed and validated server library items list.
-
- Parameters required: section_type { movie, show, episode, artist }
- section_id { unique library key }
-
- Output: array
- """
-
- if section_type == 'movie':
- sort_type = '&type=1'
- elif section_type == 'show':
- sort_type = '&type=2'
- elif section_type == 'season':
- sort_type = '&type=3'
- elif section_type == 'episode':
- sort_type = '&type=4'
- elif section_type == 'artist':
- sort_type = '&type=8'
- elif section_type == 'album':
- sort_type = '&type=9'
- elif section_type == 'track':
- sort_type = '&type=10'
- elif section_type == 'photo':
- sort_type = ''
- elif section_type == 'photo_album':
- sort_type = '&type=14'
- elif section_type == 'picture':
- sort_type = '&type=13&clusterZoomLevel=1'
- elif section_type == 'clip':
- sort_type = '&type=12&clusterZoomLevel=1'
- else:
- sort_type = ''
-
- if str(section_id).isdigit():
- library_data = self.get_library_list(str(section_id), list_type, count, sort_type, label_key,
- output_format='xml')
- elif str(rating_key).isdigit():
- library_data = self.get_metadata_children(str(rating_key), output_format='xml')
- else:
- logger.warn(
- "Tautulli Pmsconnect :: get_library_children called by invalid section_id or rating_key provided.")
- return []
-
- try:
- xml_head = library_data.getElementsByTagName('MediaContainer')
- except Exception as e:
- logger.warn("Tautulli Pmsconnect :: Unable to parse XML for get_library_children_details: %s." % e)
- return []
-
- children_list = []
-
- for a in xml_head:
- if a.getAttribute('size'):
- if a.getAttribute('size') == '0':
- logger.debug("Tautulli Pmsconnect :: No library data.")
- children_list = {'library_count': '0',
- 'children_list': []
- }
- return children_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
-
- item_main = []
- if a.getElementsByTagName('Directory'):
- dir_main = a.getElementsByTagName('Directory')
- item_main += [d for d in dir_main if helpers.get_xml_attr(d, 'ratingKey')]
- if a.getElementsByTagName('Video'):
- item_main += a.getElementsByTagName('Video')
- if a.getElementsByTagName('Track'):
- item_main += a.getElementsByTagName('Track')
- if a.getElementsByTagName('Photo'):
- item_main += a.getElementsByTagName('Photo')
-
- for item in item_main:
- media_type = helpers.get_xml_attr(item, 'type')
- if item.nodeName == 'Directory' and media_type == 'photo':
- media_type = 'photo_album'
-
- item_info = {'section_id': helpers.get_xml_attr(a, 'librarySectionID'),
- 'media_type': media_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'),
- 'original_title': helpers.get_xml_attr(item, 'originalTitle'),
- 'sort_title': helpers.get_xml_attr(item, 'titleSort'),
- '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, 'thumb'),
- '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').lower(),
- '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'),
- }
- item_info.update(media_info)
-
- children_list.append(item_info)
-
- output = {'library_count': library_count,
- 'children_list': children_list
- }
-
- return output
-
- def get_library_details(self):
- """
- Return processed and validated library statistics.
-
- Output: array
- """
- server_libraries = self.get_server_children()
-
- server_library_stats = []
-
- if server_libraries and server_libraries['libraries_count'] != '0':
- libraries_list = server_libraries['libraries_list']
-
- for library in libraries_list:
- section_type = library['section_type']
- section_id = library['section_id']
- children_list = self.get_library_children_details(section_id=section_id, section_type=section_type,
- count='1')
-
- if children_list:
- library_stats = {'section_id': section_id,
- 'section_name': library['section_name'],
- 'section_type': section_type,
- 'agent': library['agent'],
- 'thumb': library['thumb'],
- 'art': library['art'],
- 'count': children_list['library_count'],
- 'is_active': 1
- }
-
- if section_type == 'show':
- parent_list = self.get_library_children_details(section_id=section_id, section_type='season',
- count='1')
- if parent_list:
- parent_stats = {'parent_count': parent_list['library_count']}
- library_stats.update(parent_stats)
-
- child_list = self.get_library_children_details(section_id=section_id, section_type='episode',
- count='1')
- if child_list:
- child_stats = {'child_count': child_list['library_count']}
- library_stats.update(child_stats)
-
- if section_type == 'artist':
- parent_list = self.get_library_children_details(section_id=section_id, section_type='album',
- count='1')
- if parent_list:
- parent_stats = {'parent_count': parent_list['library_count']}
- library_stats.update(parent_stats)
-
- child_list = self.get_library_children_details(section_id=section_id, section_type='track',
- count='1')
- if child_list:
- child_stats = {'child_count': child_list['library_count']}
- library_stats.update(child_stats)
-
- if section_type == 'photo':
- parent_list = self.get_library_children_details(section_id=section_id, section_type='picture',
- count='1')
- if parent_list:
- parent_stats = {'parent_count': parent_list['library_count']}
- library_stats.update(parent_stats)
-
- child_list = self.get_library_children_details(section_id=section_id, section_type='clip',
- count='1')
- if child_list:
- child_stats = {'child_count': child_list['library_count']}
- library_stats.update(child_stats)
-
- server_library_stats.append(library_stats)
-
- return server_library_stats
-
- def get_library_label_details(self, section_id=''):
- labels_data = self.get_library_labels(section_id=str(section_id), output_format='xml')
-
- try:
- xml_head = labels_data.getElementsByTagName('MediaContainer')
- except Exception as e:
- logger.warn("Tautulli Pmsconnect :: Unable to parse XML for get_library_label_details: %s." % e)
- return None
-
- labels_list = []
-
- for a in xml_head:
- if a.getAttribute('size'):
- if a.getAttribute('size') == '0':
- logger.debug("Tautulli Pmsconnect :: No labels data.")
- return labels_list
-
- if a.getElementsByTagName('Directory'):
- labels_main = a.getElementsByTagName('Directory')
- for item in labels_main:
- label = {'label_key': helpers.get_xml_attr(item, 'key'),
- 'label_title': helpers.get_xml_attr(item, 'title')
- }
- labels_list.append(label)
-
- return labels_list
-
- def get_image(self, img=None, width=1000, height=1500, opacity=None, background=None, blur=None,
- img_format='png', clip=False, refresh=False, **kwargs):
- """
- Return image data as array.
- Array contains the image content type and image binary
-
- Parameters required: img { Plex image location }
- Optional parameters: width { the image width }
- height { the image height }
- opacity { the image opacity 0-100 }
- background { the image background HEX }
- blur { the image blur 0-100 }
- Output: array
- """
-
- width = width or 1000
- height = height or 1500
-
- if img:
- web_img = img.startswith('http')
-
- if refresh and not web_img:
- img = '{}/{}'.format(img.rstrip('/'), helpers.timestamp())
-
- if web_img:
- params = {'url': '%s' % img}
- elif clip:
- params = {'url': '%s&%s' % (img, urlencode({'X-Plex-Token': self.token}))}
- else:
- params = {'url': 'http://127.0.0.1:32400%s?%s' % (img, urlencode({'X-Plex-Token': self.token}))}
-
- params['width'] = width
- params['height'] = height
- params['format'] = img_format
-
- if opacity:
- params['opacity'] = opacity
- if background:
- params['background'] = background
- if blur:
- params['blur'] = blur
-
- uri = '/photo/:/transcode?%s' % urlencode(params)
- result = self.request_handler.make_request(uri=uri,
- request_type='GET',
- return_type=True)
-
- if result is None:
- return
- else:
- return result[0], result[1]
-
- else:
- logger.error("Tautulli Pmsconnect :: Image proxy queried but no input received.")
-
- def get_search_results(self, query='', limit=''):
- """
- Return processed list of search results.
-
- Output: array
- """
- search_results = self.get_search(query=query, limit=limit, output_format='xml')
-
- try:
- xml_head = search_results.getElementsByTagName('MediaContainer')
- except Exception as e:
- logger.warn("Tautulli Pmsconnect :: Unable to parse XML for get_search_result: %s." % e)
- return []
-
- search_results_list = {'movie': [],
- 'show': [],
- 'season': [],
- 'episode': [],
- 'artist': [],
- 'album': [],
- 'track': [],
- 'collection': []
- }
-
- for a in xml_head:
- hubs = a.getElementsByTagName('Hub')
-
- for h in hubs:
- if helpers.get_xml_attr(h, 'size') == '0' or \
- helpers.get_xml_attr(h, 'type') not in search_results_list:
- continue
-
- if h.getElementsByTagName('Video'):
- result_data = h.getElementsByTagName('Video')
- for result in result_data:
- rating_key = helpers.get_xml_attr(result, 'ratingKey')
- metadata = self.get_metadata_details(rating_key=rating_key)
- search_results_list[metadata['media_type']].append(metadata)
-
- if h.getElementsByTagName('Directory'):
- result_data = h.getElementsByTagName('Directory')
- for result in result_data:
- rating_key = helpers.get_xml_attr(result, 'ratingKey')
- metadata = self.get_metadata_details(rating_key=rating_key)
- search_results_list[metadata['media_type']].append(metadata)
-
- if metadata['media_type'] == 'show':
- show_seasons = self.get_item_children(rating_key=metadata['rating_key'])
- if show_seasons['children_count'] != 0:
- for season in show_seasons['children_list']:
- if season['rating_key']:
- metadata = self.get_metadata_details(rating_key=season['rating_key'])
- search_results_list['season'].append(metadata)
-
- if h.getElementsByTagName('Track'):
- result_data = h.getElementsByTagName('Track')
- for result in result_data:
- rating_key = helpers.get_xml_attr(result, 'ratingKey')
- metadata = self.get_metadata_details(rating_key=rating_key)
- search_results_list[metadata['media_type']].append(metadata)
-
- output = {'results_count': sum(len(s) for s in search_results_list.values()),
- 'results_list': search_results_list
- }
-
- return output
-
- def get_rating_keys_list(self, rating_key='', media_type=''):
- """
- Return processed list of grandparent/parent/child rating keys.
-
- Output: array
- """
-
- if media_type == 'movie':
- key_list = {0: {'rating_key': int(rating_key)}}
- return key_list
-
- if media_type == 'artist' or media_type == 'album' or media_type == 'track':
- match_type = 'title'
- else:
- match_type = 'index'
-
- section_id = None
- library_name = None
-
- # get grandparent rating key
- if media_type == 'season' or media_type == 'album':
- try:
- metadata = self.get_metadata_details(rating_key=rating_key)
- rating_key = metadata['parent_rating_key']
- section_id = metadata['section_id']
- library_name = metadata['library_name']
- except Exception as e:
- logger.warn("Tautulli Pmsconnect :: Unable to get parent_rating_key for get_rating_keys_list: %s." % e)
- return {}
-
- elif media_type == 'episode' or media_type == 'track':
- try:
- metadata = self.get_metadata_details(rating_key=rating_key)
- rating_key = metadata['grandparent_rating_key']
- section_id = metadata['section_id']
- library_name = metadata['library_name']
- except Exception as e:
- logger.warn(
- "Tautulli Pmsconnect :: Unable to get grandparent_rating_key for get_rating_keys_list: %s." % e)
- return {}
-
- # get parent_rating_keys
- metadata = self.get_metadata_children(str(rating_key), output_format='xml')
-
- try:
- xml_head = metadata.getElementsByTagName('MediaContainer')
- except Exception as e:
- logger.warn("Tautulli Pmsconnect :: Unable to parse XML for get_rating_keys_list: %s." % e)
- return {}
-
- for a in xml_head:
- if a.getAttribute('size'):
- if a.getAttribute('size') == '0':
- return {}
-
- title = helpers.get_xml_attr(a, 'title2')
-
- if a.getElementsByTagName('Directory'):
- parents_metadata = a.getElementsByTagName('Directory')
- else:
- parents_metadata = []
-
- parents = {}
- for item in parents_metadata:
- parent_rating_key = helpers.get_xml_attr(item, 'ratingKey')
- parent_index = helpers.get_xml_attr(item, 'index')
- parent_title = helpers.get_xml_attr(item, 'title')
-
- if parent_rating_key:
- # get rating_keys
- metadata = self.get_metadata_children(str(parent_rating_key), output_format='xml')
-
- try:
- xml_head = metadata.getElementsByTagName('MediaContainer')
- except Exception as e:
- logger.warn("Tautulli Pmsconnect :: Unable to parse XML for get_rating_keys_list: %s." % e)
- return {}
-
- for a in xml_head:
- if a.getAttribute('size'):
- if a.getAttribute('size') == '0':
- return {}
-
- if a.getElementsByTagName('Video'):
- children_metadata = a.getElementsByTagName('Video')
- elif a.getElementsByTagName('Track'):
- children_metadata = a.getElementsByTagName('Track')
- else:
- children_metadata = []
-
- children = {}
- for item in children_metadata:
- child_rating_key = helpers.get_xml_attr(item, 'ratingKey')
- child_index = helpers.get_xml_attr(item, 'index')
- child_title = helpers.get_xml_attr(item, 'title')
-
- if child_rating_key:
- key = int(child_index) if child_index else child_title
- children.update({key: {'rating_key': int(child_rating_key)}})
-
- key = int(parent_index) if match_type == 'index' else parent_title
- parents.update({key:
- {'rating_key': int(parent_rating_key),
- 'children': children}
- })
-
- key = 0 if match_type == 'index' else title
- key_list = {key: {'rating_key': int(rating_key),
- 'children': parents},
- 'section_id': section_id,
- 'library_name': library_name
- }
-
- return key_list
-
- def get_server_response(self):
- account_data = self.get_account(output_format='xml')
-
- try:
- xml_head = account_data.getElementsByTagName('MyPlex')
- except Exception as e:
- logger.warn("Tautulli Pmsconnect :: Unable to parse XML for get_server_response: %s." % e)
- return None
-
- server_response = {}
-
- for a in xml_head:
- server_response = {'mapping_state': helpers.get_xml_attr(a, 'mappingState'),
- 'mapping_error': helpers.get_xml_attr(a, 'mappingError'),
- 'sign_in_state': helpers.get_xml_attr(a, 'signInState'),
- 'public_address': helpers.get_xml_attr(a, 'publicAddress'),
- 'public_port': helpers.get_xml_attr(a, 'publicPort'),
- 'private_address': helpers.get_xml_attr(a, 'privateAddress'),
- 'private_port': helpers.get_xml_attr(a, 'privatePort')
- }
-
- if server_response['mapping_state'] == 'unknown':
- server_response['reason'] = 'Plex remote access port mapping unknown'
- elif server_response['mapping_state'] not in ('mapped', 'waiting'):
- server_response['reason'] = 'Plex remote access port not mapped'
- elif server_response['mapping_error'] == 'unreachable':
- server_response['reason'] = 'Plex remote access port mapped, ' \
- 'but the port is unreachable from Plex.tv'
- elif server_response['mapping_error'] == 'publisherror':
- server_response['reason'] = 'Plex remote access port mapped, ' \
- 'but failed to publish the port to Plex.tv'
- else:
- server_response['reason'] = ''
-
- return server_response
-
- def get_update_staus(self):
- # Refresh the Plex updater status first
- self.put_updater()
- updater_status = self.get_updater(output_format='xml')
-
- try:
- xml_head = updater_status.getElementsByTagName('MediaContainer')
- except Exception as e:
- logger.warn("Tautulli Pmsconnect :: Unable to parse XML for get_update_staus: %s." % e)
-
- # Catch the malformed XML on certain PMX version.
- # XML parser helper returns empty list if there is an error parsing XML
- if updater_status == []:
- logger.warn(
- "Plex API updater XML is broken on the current PMS version. Please update your PMS manually.")
- logger.info("Tautulli is unable to check for Plex updates. Disabling check for Plex updates.")
-
- # Disable check for Plex updates
- jellypy.CONFIG.MONITOR_PMS_UPDATES = 0
- jellypy.initialize_scheduler()
- jellypy.CONFIG.write()
-
- return {}
-
- updater_info = {}
- for a in xml_head:
- if a.getElementsByTagName('Release'):
- release = a.getElementsByTagName('Release')
- for item in release:
- updater_info = {'can_install': helpers.get_xml_attr(a, 'canInstall'),
- 'download_url': helpers.get_xml_attr(a, 'downloadURL'),
- 'version': helpers.get_xml_attr(item, 'version'),
- 'state': helpers.get_xml_attr(item, 'state'),
- 'changelog': helpers.get_xml_attr(item, 'fixed')
- }
-
- return updater_info
-
- def set_server_version(self):
- identity = self.get_server_identity()
- version = identity.get('version', jellypy.CONFIG.PMS_VERSION)
-
- jellypy.CONFIG.__setattr__('PMS_VERSION', version)
- jellypy.CONFIG.write()
-
- def get_server_update_channel(self):
- if jellypy.CONFIG.PMS_UPDATE_CHANNEL == 'plex':
- update_channel_value = self.get_server_pref('ButlerUpdateChannel')
-
- if update_channel_value == '8':
- return 'beta'
- else:
- return 'public'
-
- return jellypy.CONFIG.PMS_UPDATE_CHANNEL
diff --git a/jellypy/users.py b/jellypy/users.py
index c6eaa321..b6982494 100644
--- a/jellypy/users.py
+++ b/jellypy/users.py
@@ -25,7 +25,6 @@ from jellypy import datatables
from jellypy import helpers
from jellypy import libraries
from jellypy import logger
-from jellypy import plextv
from jellypy import session
diff --git a/jellypy/webauth.py b/jellypy/webauth.py
index efd36d0b..cf547045 100644
--- a/jellypy/webauth.py
+++ b/jellypy/webauth.py
@@ -33,7 +33,6 @@ from jellypy.database import MonitorDatabase
from jellypy.helpers import timestamp
from jellypy.password import check_hash
from jellypy.users import Users, refresh_users
-from jellypy.plextv import PlexTV
# Monkey patch SameSite support into cookies.
# https://stackoverflow.com/a/50813092
@@ -51,21 +50,22 @@ def plex_user_login(username=None, password=None, token=None, headers=None):
user_token = None
user_id = None
- # Try to login to Plex.tv to check if the user has a vaild account
- if username and password:
- plex_tv = PlexTV(username=username, password=password, headers=headers)
- plex_user = plex_tv.get_token()
- if plex_user:
- user_token = plex_user['auth_token']
- user_id = plex_user['user_id']
- elif token:
- plex_tv = PlexTV(token=token, headers=headers)
- plex_user = plex_tv.get_plex_account_details()
- if plex_user:
- user_token = token
- user_id = plex_user['user_id']
- else:
- return None
+ # TODO: Jellyfin
+ # # Try to login to Plex.tv to check if the user has a vaild account
+ # if username and password:
+ # plex_tv = PlexTV(username=username, password=password, headers=headers)
+ # plex_user = plex_tv.get_token()
+ # if plex_user:
+ # user_token = plex_user['auth_token']
+ # user_id = plex_user['user_id']
+ # elif token:
+ # plex_tv = PlexTV(token=token, headers=headers)
+ # plex_user = plex_tv.get_plex_account_details()
+ # if plex_user:
+ # user_token = token
+ # user_id = plex_user['user_id']
+ # else:
+ # return None
if user_token and user_id:
# Try to retrieve the user from the database.
@@ -86,10 +86,12 @@ def plex_user_login(username=None, password=None, token=None, headers=None):
if not jellypy.CONFIG.ALLOW_GUEST_ACCESS:
return None
- # The user is in the database, and guest access is enabled, so try to retrieve a server token.
- # If a server token is returned, then the user is a valid friend of the server.
- plex_tv = PlexTV(token=user_token, headers=headers)
- server_token = plex_tv.get_server_token()
+ # TODO: Jellyfin
+ # # The user is in the database, and guest access is enabled, so try to retrieve a server token.
+ # # If a server token is returned, then the user is a valid friend of the server.
+ # plex_tv = PlexTV(token=user_token, headers=headers)
+ # server_token = plex_tv.get_server_token()
+ server_token = None
if server_token:
# Register the new user / update the access tokens.
diff --git a/jellypy/webserve.py b/jellypy/webserve.py
index 7837a254..ca121895 100644
--- a/jellypy/webserve.py
+++ b/jellypy/webserve.py
@@ -44,7 +44,6 @@ from jellypy import datafactory
from jellypy import exporter
from jellypy import graphs
from jellypy import helpers
-from jellypy import http_handler
from jellypy import libraries
from jellypy import log_reader
from jellypy import logger
@@ -53,14 +52,11 @@ from jellypy import newsletter_handler
from jellypy import newsletters
from jellypy import notification_handler
from jellypy import notifiers
-from jellypy import plextv
-from jellypy import pmsconnect
from jellypy import users
from jellypy import versioncheck
-from jellypy import web_socket
from jellypy import webstart
from jellypy.api2 import API2
-from jellypy.helpers import checked, addtoapi, get_ip, create_https_certificates, build_datatables_json, sanitize_out
+from jellypy.helpers import checked, addtoapi, create_https_certificates, build_datatables_json, sanitize_out
from jellypy.password import make_hash
from jellypy.session import get_session_info, get_session_user_id, allow_session_user, allow_session_library
from jellypy.webauth import AuthController, requireAuth, member_of, check_auth
@@ -213,9 +209,11 @@ class WebInterface(object):
include_cloud = not (include_cloud == 'false')
all_servers = not (all_servers == 'false')
- plex_tv = plextv.PlexTV()
- servers_list = plex_tv.discover(include_cloud=include_cloud,
- all_servers=all_servers)
+ # TODO: Jellyfin
+ # plex_tv = plextv.PlexTV()
+ # servers_list = plex_tv.discover(include_cloud=include_cloud,
+ # all_servers=all_servers)
+ servers_list = None
if servers_list:
return servers_list
@@ -273,28 +271,30 @@ class WebInterface(object):
@cherrypy.expose
@requireAuth()
def get_current_activity(self, **kwargs):
-
- pms_connect = pmsconnect.PmsConnect(token=jellypy.CONFIG.PMS_TOKEN)
- result = pms_connect.get_current_activity()
-
- if result:
- return serve_template(templatename="current_activity.html", data=result)
- else:
- logger.warn("Unable to retrieve data for get_current_activity.")
- return serve_template(templatename="current_activity.html", data=None)
+ pass
+ # TODO: Jellyfin
+ # pms_connect = pmsconnect.PmsConnect(token=jellypy.CONFIG.PMS_TOKEN)
+ # result = pms_connect.get_current_activity()
+ #
+ # if result:
+ # return serve_template(templatename="current_activity.html", data=result)
+ # else:
+ # logger.warn("Unable to retrieve data for get_current_activity.")
+ # return serve_template(templatename="current_activity.html", data=None)
@cherrypy.expose
@requireAuth()
def get_current_activity_instance(self, session_key=None, **kwargs):
-
- pms_connect = pmsconnect.PmsConnect(token=jellypy.CONFIG.PMS_TOKEN)
- result = pms_connect.get_current_activity()
-
- if result:
- session = next((s for s in result['sessions'] if s['session_key'] == session_key), None)
- return serve_template(templatename="current_activity_instance.html", session=session)
- else:
- return serve_template(templatename="current_activity_instance.html", session=None)
+ pass
+ # TODO: Jellyfin
+ # pms_connect = pmsconnect.PmsConnect(token=jellypy.CONFIG.PMS_TOKEN)
+ # result = pms_connect.get_current_activity()
+ #
+ # if result:
+ # session = next((s for s in result['sessions'] if s['session_key'] == session_key), None)
+ # return serve_template(templatename="current_activity_instance.html", session=session)
+ # else:
+ # return serve_template(templatename="current_activity_instance.html", session=None)
@cherrypy.expose
@cherrypy.tools.json_out()
@@ -315,15 +315,16 @@ class WebInterface(object):
None
```
"""
- pms_connect = pmsconnect.PmsConnect()
- result = pms_connect.terminate_session(session_key=session_key, session_id=session_id, message=message)
-
- if result is True:
- return {'result': 'success', 'message': 'Session terminated.'}
- elif result:
- return {'result': 'error', 'message': 'Failed to terminate session: {}.'.format(result)}
- else:
- return {'result': 'error', 'message': 'Failed to terminate session.'}
+ # TODO: Jellyfin
+ # pms_connect = pmsconnect.PmsConnect()
+ # result = pms_connect.terminate_session(session_key=session_key, session_id=session_id, message=message)
+ #
+ # if result is True:
+ # return {'result': 'success', 'message': 'Session terminated.'}
+ # elif result:
+ # return {'result': 'error', 'message': 'Failed to terminate session: {}.'.format(result)}
+ # else:
+ # return {'result': 'error', 'message': 'Failed to terminate session.'}
@cherrypy.expose
@cherrypy.tools.json_out()
@@ -368,18 +369,19 @@ class WebInterface(object):
@cherrypy.expose
@requireAuth()
def get_recently_added(self, count='0', media_type='', **kwargs):
-
- try:
- pms_connect = pmsconnect.PmsConnect()
- result = pms_connect.get_recently_added_details(count=count, media_type=media_type)
- except IOError as e:
- return serve_template(templatename="recently_added.html", data=None)
-
- if result:
- return serve_template(templatename="recently_added.html", data=result['recently_added'])
- else:
- logger.warn("Unable to retrieve data for get_recently_added.")
- return serve_template(templatename="recently_added.html", data=None)
+ pass
+ # TODO: Jellyfin
+ # try:
+ # pms_connect = pmsconnect.PmsConnect()
+ # result = pms_connect.get_recently_added_details(count=count, media_type=media_type)
+ # except IOError as e:
+ # return serve_template(templatename="recently_added.html", data=None)
+ #
+ # if result:
+ # return serve_template(templatename="recently_added.html", data=result['recently_added'])
+ # else:
+ # logger.warn("Unable to retrieve data for get_recently_added.")
+ # return serve_template(templatename="recently_added.html", data=None)
@cherrypy.expose
@cherrypy.tools.json_out()
@@ -688,8 +690,10 @@ class WebInterface(object):
return serve_template(templatename="library_recently_added.html", data=None, title="Recently Added")
if section_id:
- pms_connect = pmsconnect.PmsConnect()
- result = pms_connect.get_recently_added_details(section_id=section_id, count=limit)
+ pass
+ # TODO: Jellyfin
+ # pms_connect = pmsconnect.PmsConnect()
+ # result = pms_connect.get_recently_added_details(section_id=section_id, count=limit)
else:
result = None
@@ -2589,8 +2593,10 @@ class WebInterface(object):
if get_session_user_id():
user_id = get_session_user_id()
- plex_tv = plextv.PlexTV(token=jellypy.CONFIG.PMS_TOKEN)
- result = plex_tv.get_synced_items(machine_id=machine_id, user_id_filter=user_id)
+ # TODO: Jellyfin
+ # plex_tv = plextv.PlexTV(token=jellypy.CONFIG.PMS_TOKEN)
+ # result = plex_tv.get_synced_items(machine_id=machine_id, user_id_filter=user_id)
+ result = None
if result:
output = {"data": result}
@@ -2620,8 +2626,9 @@ class WebInterface(object):
```
"""
if client_id and sync_id:
- plex_tv = plextv.PlexTV()
- delete_row = plex_tv.delete_sync(client_id=client_id, sync_id=sync_id)
+ # TODO: Jellyfin
+ # plex_tv = plextv.PlexTV()
+ # delete_row = plex_tv.delete_sync(client_id=client_id, sync_id=sync_id)
return {'result': 'success', 'message': 'Synced item deleted successfully.'}
else:
return {'result': 'error', 'message': 'Missing client ID and sync ID.'}
@@ -3273,9 +3280,11 @@ class WebInterface(object):
# Get new server URLs for SSL communications and get new server friendly name
if server_changed:
- plextv.get_server_resources()
- if jellypy.WS_CONNECTED:
- web_socket.reconnect()
+ pass
+ # TODO: Jellyfin
+ # plextv.get_server_resources()
+ # if jellypy.WS_CONNECTED:
+ # web_socket.reconnect()
# If first run, start websocket
if first_run:
@@ -3304,7 +3313,9 @@ class WebInterface(object):
@cherrypy.tools.json_out()
@requireAuth(member_of("admin"))
def get_server_resources(self, **kwargs):
- return plextv.get_server_resources(return_server=True, **kwargs)
+ pass
+ # TODO: Jellyfin
+ # return plextv.get_server_resources(return_server=True, **kwargs)
@cherrypy.expose
@cherrypy.tools.json_out()
@@ -3338,18 +3349,20 @@ class WebInterface(object):
@cherrypy.tools.json_out()
@requireAuth(member_of("admin"))
def get_server_update_params(self, **kwargs):
- plex_tv = plextv.PlexTV()
- plexpass = plex_tv.get_plexpass_status()
-
- update_channel = pmsconnect.PmsConnect().get_server_update_channel()
-
- return {'plexpass': plexpass,
- 'pms_platform': common.PMS_PLATFORM_NAME_OVERRIDES.get(
- jellypy.CONFIG.PMS_PLATFORM, jellypy.CONFIG.PMS_PLATFORM),
- 'pms_update_channel': jellypy.CONFIG.PMS_UPDATE_CHANNEL,
- 'pms_update_distro': jellypy.CONFIG.PMS_UPDATE_DISTRO,
- 'pms_update_distro_build': jellypy.CONFIG.PMS_UPDATE_DISTRO_BUILD,
- 'plex_update_channel': 'plexpass' if update_channel == 'beta' else 'public'}
+ pass
+ # TODO: Jellyfin
+ # plex_tv = plextv.PlexTV()
+ # plexpass = plex_tv.get_plexpass_status()
+ #
+ # update_channel = pmsconnect.PmsConnect().get_server_update_channel()
+ #
+ # return {'plexpass': plexpass,
+ # 'pms_platform': common.PMS_PLATFORM_NAME_OVERRIDES.get(
+ # jellypy.CONFIG.PMS_PLATFORM, jellypy.CONFIG.PMS_PLATFORM),
+ # 'pms_update_channel': jellypy.CONFIG.PMS_UPDATE_CHANNEL,
+ # 'pms_update_distro': jellypy.CONFIG.PMS_UPDATE_DISTRO,
+ # 'pms_update_distro_build': jellypy.CONFIG.PMS_UPDATE_DISTRO_BUILD,
+ # 'plex_update_channel': 'plexpass' if update_channel == 'beta' else 'public'}
@cherrypy.expose
@cherrypy.tools.json_out()
@@ -3988,8 +4001,10 @@ class WebInterface(object):
if not username and not password:
return None
- plex_tv = plextv.PlexTV(username=username, password=password)
- result = plex_tv.get_token()
+ # TODO: Jellyfin
+ # plex_tv = plextv.PlexTV(username=username, password=password)
+ # result = plex_tv.get_token()
+ result = None
if result:
return result['auth_token']
@@ -4007,8 +4022,10 @@ class WebInterface(object):
force = helpers.bool_true(force)
- plex_tv = plextv.PlexTV(username=username, password=password)
- token = plex_tv.get_plexpy_pms_token(force=force)
+ # TODO: Jellyfin
+ # plex_tv = plextv.PlexTV(username=username, password=password)
+ # token = plex_tv.get_plexpy_pms_token(force=force)
+ token = None
if token:
return {'result': 'success', 'message': 'Authentication successful.', 'token': token}
@@ -4040,30 +4057,32 @@ class WebInterface(object):
# Attempt to get the pms_identifier from plex.tv if the server is published
# Works for all PMS SSL settings
if not identifier and hostname and port:
- plex_tv = plextv.PlexTV()
- servers = plex_tv.discover()
- ip_address = get_ip(hostname)
-
- for server in servers:
- if (server['ip'] == hostname or server['ip'] == ip_address) and server['port'] == port:
- identifier = server['clientIdentifier']
- break
-
- # Fallback to checking /identity endpoint if the server is unpublished
- # Cannot set SSL settings on the PMS if unpublished so 'http' is okay
- if not identifier:
- scheme = 'https' if helpers.cast_to_int(ssl) else 'http'
- url = '{scheme}://{hostname}:{port}'.format(scheme=scheme, hostname=hostname, port=port)
- uri = '/identity'
-
- request_handler = http_handler.HTTPHandler(urls=url,
- ssl_verify=False)
- request = request_handler.make_request(uri=uri,
- request_type='GET',
- output_format='xml')
- if request:
- xml_head = request.getElementsByTagName('MediaContainer')[0]
- identifier = xml_head.getAttribute('machineIdentifier')
+ pass
+ # TODO: Jellyfin
+ # plex_tv = plextv.PlexTV()
+ # servers = plex_tv.discover()
+ # ip_address = get_ip(hostname)
+ #
+ # for server in servers:
+ # if (server['ip'] == hostname or server['ip'] == ip_address) and server['port'] == port:
+ # identifier = server['clientIdentifier']
+ # break
+ #
+ # # Fallback to checking /identity endpoint if the server is unpublished
+ # # Cannot set SSL settings on the PMS if unpublished so 'http' is okay
+ # if not identifier:
+ # scheme = 'https' if helpers.cast_to_int(ssl) else 'http'
+ # url = '{scheme}://{hostname}:{port}'.format(scheme=scheme, hostname=hostname, port=port)
+ # uri = '/identity'
+ #
+ # request_handler = http_handler.HTTPHandler(urls=url,
+ # ssl_verify=False)
+ # request = request_handler.make_request(uri=uri,
+ # request_type='GET',
+ # output_format='xml')
+ # if request:
+ # xml_head = request.getElementsByTagName('MediaContainer')[0]
+ # identifier = xml_head.getAttribute('machineIdentifier')
result = {'identifier': identifier}
@@ -4128,9 +4147,10 @@ class WebInterface(object):
}
```
"""
- server = plextv.get_server_resources(return_info=True)
- server.pop('pms_is_cloud', None)
- return server
+ # TODO: Jellyfin
+ # server = plextv.get_server_resources(return_info=True)
+ # server.pop('pms_is_cloud', None)
+ # return server
@cherrypy.expose
@requireAuth(member_of("admin"))
@@ -4147,14 +4167,15 @@ class WebInterface(object):
```
"""
- pms_connect = pmsconnect.PmsConnect()
- result = pms_connect.get_server_pref(pref=pref)
-
- if result:
- return result
- else:
- logger.warn("Unable to retrieve data for get_server_pref.")
- return result
+ # TODO: Jellyfin
+ # pms_connect = pmsconnect.PmsConnect()
+ # result = pms_connect.get_server_pref(pref=pref)
+ #
+ # if result:
+ # return result
+ # else:
+ # logger.warn("Unable to retrieve data for get_server_pref.")
+ # return result
@cherrypy.expose
@cherrypy.tools.json_out()
@@ -4346,10 +4367,11 @@ class WebInterface(object):
else:
user_info = {}
- # Try to get metadata from the Plex server first
- if rating_key:
- pms_connect = pmsconnect.PmsConnect()
- metadata = pms_connect.get_metadata_details(rating_key=rating_key, section_id=section_id)
+ # TODO: Jellyfin
+ # # Try to get metadata from the Plex server first
+ # if rating_key:
+ # pms_connect = pmsconnect.PmsConnect()
+ # metadata = pms_connect.get_metadata_details(rating_key=rating_key, section_id=section_id)
# If the item is not found on the Plex server, get the metadata from history
if not metadata and source == 'history':
@@ -4378,28 +4400,30 @@ class WebInterface(object):
@cherrypy.expose
@requireAuth()
def get_item_children(self, rating_key='', media_type=None, **kwargs):
-
- pms_connect = pmsconnect.PmsConnect()
- result = pms_connect.get_item_children(rating_key=rating_key, media_type=media_type)
-
- if result:
- return serve_template(templatename="info_children_list.html", data=result,
- media_type=media_type, title="Children List")
- else:
- logger.warn("Unable to retrieve data for get_item_children.")
- return serve_template(templatename="info_children_list.html", data=None, title="Children List")
+ pass
+ # TODO: Jellyfin
+ # pms_connect = pmsconnect.PmsConnect()
+ # result = pms_connect.get_item_children(rating_key=rating_key, media_type=media_type)
+ #
+ # if result:
+ # return serve_template(templatename="info_children_list.html", data=result,
+ # media_type=media_type, title="Children List")
+ # else:
+ # logger.warn("Unable to retrieve data for get_item_children.")
+ # return serve_template(templatename="info_children_list.html", data=None, title="Children List")
@cherrypy.expose
@requireAuth()
def get_item_children_related(self, rating_key='', title='', **kwargs):
-
- pms_connect = pmsconnect.PmsConnect()
- result = pms_connect.get_item_children_related(rating_key=rating_key)
-
- if result:
- return serve_template(templatename="info_collection_list.html", data=result, title=title)
- else:
- return serve_template(templatename="info_collection_list.html", data=None, title=title)
+ pass
+ # TODO: Jellyfin
+ # pms_connect = pmsconnect.PmsConnect()
+ # result = pms_connect.get_item_children_related(rating_key=rating_key)
+ #
+ # if result:
+ # return serve_template(templatename="info_collection_list.html", data=result, title=title)
+ # else:
+ # return serve_template(templatename="info_collection_list.html", data=None, title=title)
@cherrypy.expose
@cherrypy.tools.json_out()
@@ -4423,24 +4447,25 @@ class WebInterface(object):
}
```
"""
- if rating_key:
- pms_connect = pmsconnect.PmsConnect()
- metadata = pms_connect.get_metadata_details(rating_key=rating_key)
- data = {'timeline_data': metadata, 'notify_action': 'on_created', 'manual_trigger': True}
-
- if metadata['media_type'] not in ('movie', 'episode', 'track'):
- children = pms_connect.get_item_children(rating_key=rating_key)
- child_keys = [child['rating_key'] for child in children['children_list'] if child['rating_key']]
- data['child_keys'] = child_keys
-
- if notifier_id:
- data['notifier_id'] = notifier_id
-
- jellypy.NOTIFY_QUEUE.put(data)
- return {'result': 'success', 'message': 'Notification queued.'}
-
- else:
- return {'result': 'error', 'message': 'Notification failed.'}
+ # TODO: Jellyfin
+ # if rating_key:
+ # pms_connect = pmsconnect.PmsConnect()
+ # metadata = pms_connect.get_metadata_details(rating_key=rating_key)
+ # data = {'timeline_data': metadata, 'notify_action': 'on_created', 'manual_trigger': True}
+ #
+ # if metadata['media_type'] not in ('movie', 'episode', 'track'):
+ # children = pms_connect.get_item_children(rating_key=rating_key)
+ # child_keys = [child['rating_key'] for child in children['children_list'] if child['rating_key']]
+ # data['child_keys'] = child_keys
+ #
+ # if notifier_id:
+ # data['notifier_id'] = notifier_id
+ #
+ # jellypy.NOTIFY_QUEUE.put(data)
+ # return {'result': 'success', 'message': 'Notification queued.'}
+ #
+ # else:
+ # return {'result': 'error', 'message': 'Notification failed.'}
@cherrypy.expose
def pms_image_proxy(self, **kwargs):
@@ -4535,16 +4560,18 @@ class WebInterface(object):
except NotFound:
# the image does not exist, download it from pms
try:
- pms_connect = pmsconnect.PmsConnect()
- result = pms_connect.get_image(img=img,
- width=width,
- height=height,
- opacity=opacity,
- background=background,
- blur=blur,
- img_format=img_format,
- clip=clip,
- refresh=refresh)
+ # TODO: Jellyfin
+ # pms_connect = pmsconnect.PmsConnect()
+ # result = pms_connect.get_image(img=img,
+ # width=width,
+ # height=height,
+ # opacity=opacity,
+ # background=background,
+ # blur=blur,
+ # img_format=img_format,
+ # clip=clip,
+ # refresh=refresh)
+ result = None
if result and result[0]:
cherrypy.response.headers['Content-type'] = result[1]
@@ -4807,35 +4834,37 @@ class WebInterface(object):
}
```
"""
- pms_connect = pmsconnect.PmsConnect()
- result = pms_connect.get_search_results(query=query, limit=limit)
-
- if result:
- return result
- else:
- logger.warn("Unable to retrieve data for search_results.")
- return result
+ # TODO: Jellyfin
+ # pms_connect = pmsconnect.PmsConnect()
+ # result = pms_connect.get_search_results(query=query, limit=limit)
+ #
+ # if result:
+ # return result
+ # else:
+ # logger.warn("Unable to retrieve data for search_results.")
+ # return result
@cherrypy.expose
@requireAuth()
def get_search_results_children(self, query='', limit='', media_type=None, season_index=None, **kwargs):
+ pass
+ # TODO: Jellyfin
+ # pms_connect = pmsconnect.PmsConnect()
+ # result = pms_connect.get_search_results(query=query, limit=limit)
+ #
+ # if media_type:
+ # result['results_list'] = {media_type: result['results_list'][media_type]}
+ # if media_type == 'season' and season_index:
+ # result['results_list']['season'] = [season for season in result['results_list']['season']
+ # if season['media_index'] == season_index]
+ #
+ # if result:
+ # return serve_template(templatename="info_search_results_list.html", data=result, title="Search Result List")
+ # else:
+ # logger.warn("Unable to retrieve data for get_search_results_children.")
+ # return serve_template(templatename="info_search_results_list.html", data=None, title="Search Result List")
- pms_connect = pmsconnect.PmsConnect()
- result = pms_connect.get_search_results(query=query, limit=limit)
-
- if media_type:
- result['results_list'] = {media_type: result['results_list'][media_type]}
- if media_type == 'season' and season_index:
- result['results_list']['season'] = [season for season in result['results_list']['season']
- if season['media_index'] == season_index]
-
- if result:
- return serve_template(templatename="info_search_results_list.html", data=result, title="Search Result List")
- else:
- logger.warn("Unable to retrieve data for get_search_results_children.")
- return serve_template(templatename="info_search_results_list.html", data=None, title="Search Result List")
-
- ##### Update Metadata #####
+ # Update Metadata
@cherrypy.expose
@requireAuth(member_of("admin"))
@@ -4876,21 +4905,22 @@ class WebInterface(object):
None
```
"""
- if new_rating_key:
- 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)
-
- result = data_factory.update_metadata(old_key_list=old_key_list,
- new_key_list=new_key_list,
- media_type=media_type)
-
- if result:
- return {'message': result}
- else:
- return {'message': 'no data received'}
+ # TODO: Jellyfin
+ # if new_rating_key:
+ # 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)
+ #
+ # result = data_factory.update_metadata(old_key_list=old_key_list,
+ # new_key_list=new_key_list,
+ # media_type=media_type)
+ #
+ # if result:
+ # return {'message': result}
+ # else:
+ # return {'message': 'no data received'}
# test code
@cherrypy.expose
@@ -4913,15 +4943,15 @@ class WebInterface(object):
{}
```
"""
-
- pms_connect = pmsconnect.PmsConnect()
- result = pms_connect.get_rating_keys_list(rating_key=rating_key, media_type=media_type)
-
- if result:
- return result
- else:
- logger.warn("Unable to retrieve data for get_new_rating_keys.")
- return result
+ # TODO: Jellyfin
+ # pms_connect = pmsconnect.PmsConnect()
+ # result = pms_connect.get_rating_keys_list(rating_key=rating_key, media_type=media_type)
+ #
+ # if result:
+ # return result
+ # else:
+ # logger.warn("Unable to retrieve data for get_new_rating_keys.")
+ # return result
@cherrypy.expose
@cherrypy.tools.json_out()
@@ -4958,14 +4988,15 @@ class WebInterface(object):
@requireAuth(member_of("admin"))
def get_pms_sessions_json(self, **kwargs):
""" Get all the current sessions. """
- pms_connect = pmsconnect.PmsConnect()
- result = pms_connect.get_sessions('json')
-
- if result:
- return result
- else:
- logger.warn("Unable to retrieve data for get_pms_sessions_json.")
- return False
+ # TODO: Jellyfin
+ # pms_connect = pmsconnect.PmsConnect()
+ # result = pms_connect.get_sessions('json')
+ #
+ # if result:
+ # return result
+ # else:
+ # logger.warn("Unable to retrieve data for get_pms_sessions_json.")
+ # return False
@cherrypy.expose
@cherrypy.tools.json_out()
@@ -5127,15 +5158,16 @@ class WebInterface(object):
}
```
"""
- pms_connect = pmsconnect.PmsConnect()
- metadata = pms_connect.get_metadata_details(rating_key=rating_key,
- sync_id=sync_id)
-
- if metadata:
- return metadata
- else:
- logger.warn("Unable to retrieve data for get_metadata_details.")
- return metadata
+ # TODO: Jellyfin
+ # pms_connect = pmsconnect.PmsConnect()
+ # metadata = pms_connect.get_metadata_details(rating_key=rating_key,
+ # sync_id=sync_id)
+ #
+ # if metadata:
+ # return metadata
+ # else:
+ # logger.warn("Unable to retrieve data for get_metadata_details.")
+ # return metadata
@cherrypy.expose
@cherrypy.tools.json_out()
@@ -5218,86 +5250,90 @@ class WebInterface(object):
}
```
"""
- # For backwards compatibility
- if 'type' in kwargs:
- media_type = kwargs['type']
-
- pms_connect = pmsconnect.PmsConnect()
- result = pms_connect.get_recently_added_details(start=start, count=count, media_type=media_type,
- section_id=section_id)
-
- if result:
- return result
- else:
- logger.warn("Unable to retrieve data for get_recently_added_details.")
- return result
+ # TODO: Jellyfin
+ # # For backwards compatibility
+ # if 'type' in kwargs:
+ # media_type = kwargs['type']
+ #
+ # pms_connect = pmsconnect.PmsConnect()
+ # result = pms_connect.get_recently_added_details(start=start, count=count, media_type=media_type,
+ # section_id=section_id)
+ #
+ # if result:
+ # return result
+ # else:
+ # logger.warn("Unable to retrieve data for get_recently_added_details.")
+ # return result
@cherrypy.expose
@cherrypy.tools.json_out()
@requireAuth(member_of("admin"))
def get_friends_list(self, **kwargs):
""" Get the friends list of the server owner for Plex.tv. """
-
- plex_tv = plextv.PlexTV()
- result = plex_tv.get_plextv_friends('json')
-
- if result:
- return result
- else:
- logger.warn("Unable to retrieve data for get_friends_list.")
+ # TODO: Jellyfin
+ # plex_tv = plextv.PlexTV()
+ # result = plex_tv.get_plextv_friends('json')
+ #
+ # if result:
+ # return result
+ # else:
+ # logger.warn("Unable to retrieve data for get_friends_list.")
@cherrypy.expose
@cherrypy.tools.json_out()
@requireAuth(member_of("admin"))
def get_user_details(self, **kwargs):
""" Get all details about a the server's owner from Plex.tv. """
-
- plex_tv = plextv.PlexTV()
- result = plex_tv.get_plextv_user_details('json')
-
- if result:
- return result
- else:
- logger.warn("Unable to retrieve data for get_user_details.")
+ # TODO: Jellyfin
+ # plex_tv = plextv.PlexTV()
+ # result = plex_tv.get_plextv_user_details('json')
+ #
+ # if result:
+ # return result
+ # else:
+ # logger.warn("Unable to retrieve data for get_user_details.")
@cherrypy.expose
@cherrypy.tools.json_out()
@requireAuth(member_of("admin"))
def get_server_list(self, **kwargs):
""" Find all servers published on Plex.tv """
-
- plex_tv = plextv.PlexTV()
- result = plex_tv.get_plextv_server_list('json')
-
- if result:
- return result
- else:
- logger.warn("Unable to retrieve data for get_server_list.")
+ # TODO: Jellyfin
+ # plex_tv = plextv.PlexTV()
+ # result = plex_tv.get_plextv_server_list('json')
+ #
+ # if result:
+ # return result
+ # else:
+ # logger.warn("Unable to retrieve data for get_server_list.")
@cherrypy.expose
@cherrypy.tools.json_out()
@requireAuth(member_of("admin"))
def get_sync_lists(self, machine_id='', **kwargs):
""" Get all items that are currently synced from the PMS. """
- plex_tv = plextv.PlexTV()
- result = plex_tv.get_plextv_sync_lists(machine_id=machine_id, output_format='json')
-
- if result:
- return result
- else:
- logger.warn("Unable to retrieve data for get_sync_lists.")
+ # TODO: Jellyfin
+ # plex_tv = plextv.PlexTV()
+ # result = plex_tv.get_plextv_sync_lists(machine_id=machine_id, output_format='json')
+ #
+ # if result:
+ # return result
+ # else:
+ # logger.warn("Unable to retrieve data for get_sync_lists.")
@cherrypy.expose
@cherrypy.tools.json_out()
@requireAuth(member_of("admin"))
def get_servers(self, **kwargs):
- pms_connect = pmsconnect.PmsConnect()
- result = pms_connect.get_server_list(output_format='json')
-
- if result:
- return result
- else:
- logger.warn("Unable to retrieve data for get_servers.")
+ pass
+ # TODO: Jellyfin
+ # pms_connect = pmsconnect.PmsConnect()
+ # result = pms_connect.get_server_list(output_format='json')
+ #
+ # if result:
+ # return result
+ # else:
+ # logger.warn("Unable to retrieve data for get_servers.")
@cherrypy.expose
@cherrypy.tools.json_out()
@@ -5324,14 +5360,15 @@ class WebInterface(object):
]
```
"""
- pms_connect = pmsconnect.PmsConnect()
- result = pms_connect.get_servers_info()
-
- if result:
- return result
- else:
- logger.warn("Unable to retrieve data for get_servers_info.")
- return result
+ # TODO: Jellyfin
+ # pms_connect = pmsconnect.PmsConnect()
+ # result = pms_connect.get_servers_info()
+ #
+ # if result:
+ # return result
+ # else:
+ # logger.warn("Unable to retrieve data for get_servers_info.")
+ # return result
@cherrypy.expose
@cherrypy.tools.json_out()
@@ -5355,14 +5392,15 @@ class WebInterface(object):
]
```
"""
- pms_connect = pmsconnect.PmsConnect()
- result = pms_connect.get_server_identity()
-
- if result:
- return result
- else:
- logger.warn("Unable to retrieve data for get_server_identity.")
- return result
+ # TODO: Jellyfin
+ # pms_connect = pmsconnect.PmsConnect()
+ # result = pms_connect.get_server_identity()
+ #
+ # if result:
+ # return result
+ # else:
+ # logger.warn("Unable to retrieve data for get_server_identity.")
+ # return result
@cherrypy.expose
@cherrypy.tools.json_out()
@@ -5382,13 +5420,14 @@ class WebInterface(object):
string: "Winterfell-Server"
```
"""
- result = pmsconnect.get_server_friendly_name()
-
- if result:
- return result
- else:
- logger.warn("Unable to retrieve data for get_server_friendly_name.")
- return result
+ # TODO: Jellyfin
+ # result = pmsconnect.get_server_friendly_name()
+ #
+ # if result:
+ # return result
+ # else:
+ # logger.warn("Unable to retrieve data for get_server_friendly_name.")
+ # return result
@cherrypy.expose
@cherrypy.tools.json_out()
@@ -5653,45 +5692,46 @@ class WebInterface(object):
}
```
"""
- try:
- pms_connect = pmsconnect.PmsConnect(token=jellypy.CONFIG.PMS_TOKEN)
- result = pms_connect.get_current_activity()
-
- if result:
- if session_key:
- return next((s for s in result['sessions'] if s['session_key'] == session_key), {})
- if session_id:
- return next((s for s in result['sessions'] if s['session_id'] == session_id), {})
-
- counts = {'stream_count_direct_play': 0,
- 'stream_count_direct_stream': 0,
- 'stream_count_transcode': 0,
- 'total_bandwidth': 0,
- 'lan_bandwidth': 0,
- 'wan_bandwidth': 0}
-
- for s in result['sessions']:
- if s['transcode_decision'] == 'transcode':
- counts['stream_count_transcode'] += 1
- elif s['transcode_decision'] == 'copy':
- counts['stream_count_direct_stream'] += 1
- else:
- counts['stream_count_direct_play'] += 1
-
- counts['total_bandwidth'] += helpers.cast_to_int(s['bandwidth'])
- if s['location'] == 'lan':
- counts['lan_bandwidth'] += helpers.cast_to_int(s['bandwidth'])
- else:
- counts['wan_bandwidth'] += helpers.cast_to_int(s['bandwidth'])
-
- result.update(counts)
-
- return result
- else:
- logger.warn("Unable to retrieve data for get_activity.")
- return {}
- except Exception as e:
- logger.exception("Unable to retrieve data for get_activity: %s" % e)
+ # TODO: Jellyfin
+ # try:
+ # pms_connect = pmsconnect.PmsConnect(token=jellypy.CONFIG.PMS_TOKEN)
+ # result = pms_connect.get_current_activity()
+ #
+ # if result:
+ # if session_key:
+ # return next((s for s in result['sessions'] if s['session_key'] == session_key), {})
+ # if session_id:
+ # return next((s for s in result['sessions'] if s['session_id'] == session_id), {})
+ #
+ # counts = {'stream_count_direct_play': 0,
+ # 'stream_count_direct_stream': 0,
+ # 'stream_count_transcode': 0,
+ # 'total_bandwidth': 0,
+ # 'lan_bandwidth': 0,
+ # 'wan_bandwidth': 0}
+ #
+ # for s in result['sessions']:
+ # if s['transcode_decision'] == 'transcode':
+ # counts['stream_count_transcode'] += 1
+ # elif s['transcode_decision'] == 'copy':
+ # counts['stream_count_direct_stream'] += 1
+ # else:
+ # counts['stream_count_direct_play'] += 1
+ #
+ # counts['total_bandwidth'] += helpers.cast_to_int(s['bandwidth'])
+ # if s['location'] == 'lan':
+ # counts['lan_bandwidth'] += helpers.cast_to_int(s['bandwidth'])
+ # else:
+ # counts['wan_bandwidth'] += helpers.cast_to_int(s['bandwidth'])
+ #
+ # result.update(counts)
+ #
+ # return result
+ # else:
+ # logger.warn("Unable to retrieve data for get_activity.")
+ # return {}
+ # except Exception as e:
+ # logger.exception("Unable to retrieve data for get_activity: %s" % e)
@cherrypy.expose
@cherrypy.tools.json_out()
@@ -5724,14 +5764,15 @@ class WebInterface(object):
]
```
"""
- pms_connect = pmsconnect.PmsConnect()
- result = pms_connect.get_library_details()
-
- if result:
- return result
- else:
- logger.warn("Unable to retrieve data for get_full_libraries_list.")
- return result
+ # TODO: Jellyfin
+ # pms_connect = pmsconnect.PmsConnect()
+ # result = pms_connect.get_library_details()
+ #
+ # if result:
+ # return result
+ # else:
+ # logger.warn("Unable to retrieve data for get_full_libraries_list.")
+ # return result
@cherrypy.expose
@cherrypy.tools.json_out()
@@ -5830,27 +5871,29 @@ class WebInterface(object):
]
```
"""
- plex_tv = plextv.PlexTV()
- result = plex_tv.get_synced_items(machine_id=machine_id, user_id_filter=user_id)
-
- if result:
- return result
- else:
- logger.warn("Unable to retrieve data for get_synced_items.")
- return result
+ # TODO: Jellyfin
+ # plex_tv = plextv.PlexTV()
+ # result = plex_tv.get_synced_items(machine_id=machine_id, user_id_filter=user_id)
+ #
+ # if result:
+ # return result
+ # else:
+ # logger.warn("Unable to retrieve data for get_synced_items.")
+ # return result
@cherrypy.expose
@cherrypy.tools.json_out()
@requireAuth(member_of("admin"))
def get_sync_transcode_queue(self, **kwargs):
""" Return details for currently syncing items. """
- pms_connect = pmsconnect.PmsConnect()
- result = pms_connect.get_sync_transcode_queue(output_format='json')
-
- if result:
- return result
- else:
- logger.warn("Unable to retrieve data for get_sync_transcode_queue.")
+ # TODO: Jellyfin
+ # pms_connect = pmsconnect.PmsConnect()
+ # result = pms_connect.get_sync_transcode_queue(output_format='json')
+ #
+ # if result:
+ # return result
+ # else:
+ # logger.warn("Unable to retrieve data for get_sync_transcode_queue.")
@cherrypy.expose
@cherrypy.tools.json_out()
@@ -6046,9 +6089,10 @@ class WebInterface(object):
}
```
"""
- plex_tv = plextv.PlexTV()
- result = plex_tv.get_plex_downloads()
- return result
+ # TODO: Jellyfin
+ # plex_tv = plextv.PlexTV()
+ # result = plex_tv.get_plex_downloads()
+ # return result
@cherrypy.expose
@cherrypy.tools.json_out()
@@ -6078,20 +6122,21 @@ class WebInterface(object):
}
```
"""
- message = ''
- if not ip_address:
- message = 'No IP address provided.'
- elif not helpers.is_valid_ip(ip_address):
- message = 'Invalid IP address provided: %s' % ip_address
-
- if message:
- return {'result': 'error', 'message': message}
-
- plex_tv = plextv.PlexTV()
- geo_info = plex_tv.get_geoip_lookup(ip_address)
- if geo_info:
- return {'result': 'success', 'data': geo_info}
- return {'result': 'error', 'message': 'Failed to lookup GeoIP info for address: %s' % ip_address}
+ # TODO: Jellyfin
+ # message = ''
+ # if not ip_address:
+ # message = 'No IP address provided.'
+ # elif not helpers.is_valid_ip(ip_address):
+ # message = 'Invalid IP address provided: %s' % ip_address
+ #
+ # if message:
+ # return {'result': 'error', 'message': message}
+ #
+ # plex_tv = plextv.PlexTV()
+ # geo_info = plex_tv.get_geoip_lookup(ip_address)
+ # if geo_info:
+ # return {'result': 'success', 'data': geo_info}
+ # return {'result': 'error', 'message': 'Failed to lookup GeoIP info for address: %s' % ip_address}
@cherrypy.expose
@cherrypy.tools.json_out()