# This file is part of PlexPy. # # PlexPy is free software: you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation, either version 3 of the License, or # (at your option) any later version. # # PlexPy 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 PlexPy. If not, see . from plexpy import logger, notifiers, plextv, pmsconnect, plexwatch, db, common, log_reader from plexpy.helpers import checked, radio from mako.lookup import TemplateLookup from mako import exceptions import plexpy import cherrypy import hashlib import random import json import os try: # pylint:disable=E0611 # ignore this error because we are catching the ImportError from collections import OrderedDict # pylint:enable=E0611 except ImportError: # Python 2.6.x fallback, from libs from ordereddict import OrderedDict def serve_template(templatename, **kwargs): interface_dir = os.path.join(str(plexpy.PROG_DIR), 'data/interfaces/') template_dir = os.path.join(str(interface_dir), plexpy.CONFIG.INTERFACE) _hplookup = TemplateLookup(directories=[template_dir]) try: template = _hplookup.get_template(templatename) return template.render(**kwargs) except: return exceptions.html_error_template().render() class WebInterface(object): def __init__(self): self.interface_dir = os.path.join(str(plexpy.PROG_DIR), 'data/') @cherrypy.expose def index(self): raise cherrypy.HTTPRedirect("home") @cherrypy.expose def home(self): if plexpy.CONFIG.PLEXWATCH_DATABASE == '': raise cherrypy.HTTPRedirect("config") else: return serve_template(templatename="index.html", title="Home") @cherrypy.expose def get_date_formats(self): if plexpy.CONFIG.DATE_FORMAT: date_format = plexpy.CONFIG.DATE_FORMAT else: date_format = 'YYYY-MM-DD' if plexpy.CONFIG.TIME_FORMAT: time_format = plexpy.CONFIG.TIME_FORMAT else: time_format = 'HH:mm' formats = {'date_format': date_format, 'time_format': time_format} cherrypy.response.headers['Content-type'] = 'application/json' return json.dumps(formats) @cherrypy.expose def home_stats(self, time_range='30', **kwargs): plex_watch = plexwatch.PlexWatch() stats_data = plex_watch.get_home_stats(time_range) return serve_template(templatename="home_stats.html", title="Stats", data=stats_data) @cherrypy.expose def history(self): return serve_template(templatename="history.html", title="History") @cherrypy.expose def users(self): return serve_template(templatename="users.html", title="Users") @cherrypy.expose def graphs(self): return serve_template(templatename="graphs.html", title="Graphs") @cherrypy.expose def sync(self): return serve_template(templatename="sync.html", title="Synced Items") @cherrypy.expose def user(self, user=None): try: plex_watch = plexwatch.PlexWatch() user_details = plex_watch.get_user_details(user) except: logger.warn("Unable to retrieve friendly name for user %s " % user) return serve_template(templatename="user.html", title="User", data=user_details) @cherrypy.expose def edit_user(self, user=None, friendly_name=None, **kwargs): if user and friendly_name: try: plex_watch = plexwatch.PlexWatch() plex_watch.set_user_friendly_name(user, friendly_name) status_message = "Successfully updated user." return status_message except: status_message = "Failed to updated user." return status_message elif user and not friendly_name: try: plex_watch = plexwatch.PlexWatch() result = {'user': user, 'friendly_name': plex_watch.get_user_friendly_name(user) } status_message = "" except: result = {'user': user, 'friendly_name': '' } status_message = "There was an error." return serve_template(templatename="edit_user.html", title="Edit User", data=result, status_message=status_message) else: return serve_template(templatename="edit_user.html", title="Edit User", data=user, status_message='Unknown error.') @cherrypy.expose def get_stream_data(self, row_id=None, user=None, **kwargs): plex_watch = plexwatch.PlexWatch() stream_data = plex_watch.get_stream_details(row_id) return serve_template(templatename="stream_data.html", title="Stream Data", data=stream_data, user=user) @cherrypy.expose def get_user_list(self, start=0, length=100, **kwargs): plex_watch = plexwatch.PlexWatch() users = plex_watch.get_user_list(start, length, kwargs) cherrypy.response.headers['Content-type'] = 'application/json' return json.dumps(users) @cherrypy.expose def checkGithub(self): from plexpy import versioncheck versioncheck.checkGithub() raise cherrypy.HTTPRedirect("home") @cherrypy.expose def logs(self): return serve_template(templatename="logs.html", title="Log", lineList=plexpy.LOG_LIST) @cherrypy.expose def clearLogs(self): plexpy.LOG_LIST = [] logger.info("Web logs cleared") raise cherrypy.HTTPRedirect("logs") @cherrypy.expose def toggleVerbose(self): plexpy.VERBOSE = not plexpy.VERBOSE logger.initLogger(console=not plexpy.QUIET, log_dir=plexpy.CONFIG.LOG_DIR, verbose=plexpy.VERBOSE) logger.info("Verbose toggled, set to %s", plexpy.VERBOSE) logger.debug("If you read this message, debug logging is available") raise cherrypy.HTTPRedirect("logs") @cherrypy.expose def getLog(self, start=0, length=100, **kwargs): start = int(start) length = int(length) search_value = "" search_regex = "" order_column = 0 order_dir = "desc" if 'order[0][dir]' in kwargs: order_dir = kwargs.get('order[0][dir]', "desc") if 'order[0][column]' in kwargs: order_column = kwargs.get('order[0][column]', "0") if 'search[value]' in kwargs: search_value = kwargs.get('search[value]', "") if 'search[regex]' in kwargs: search_regex = kwargs.get('search[regex]', "") filtered = [] if search_value == "": filtered = plexpy.LOG_LIST[::] else: filtered = [row for row in plexpy.LOG_LIST for column in row if search_value.lower() in column.lower()] sortcolumn = 0 if order_column == '1': sortcolumn = 2 elif order_column == '2': sortcolumn = 1 filtered.sort(key=lambda x: x[sortcolumn], reverse=order_dir == "desc") rows = filtered[start:(start + length)] rows = [[row[0], row[2], row[1]] for row in rows] return json.dumps({ 'recordsFiltered': len(filtered), 'recordsTotal': len(plexpy.LOG_LIST), 'data': rows, }) @cherrypy.expose def get_plex_log(self, window=1000, **kwargs): log_lines = [] try: log_lines = {'data': log_reader.get_log_tail(window=window)} except: logger.warn("Unable to retrieve Plex Logs.") cherrypy.response.headers['Content-type'] = 'application/json' return json.dumps(log_lines) @cherrypy.expose def generateAPI(self): apikey = hashlib.sha224(str(random.getrandbits(256))).hexdigest()[0:32] logger.info("New API generated") return apikey @cherrypy.expose def config(self): interface_dir = os.path.join(plexpy.PROG_DIR, 'data/interfaces/') interface_list = [name for name in os.listdir(interface_dir) if os.path.isdir(os.path.join(interface_dir, name))] # Initialise blank passwords so we do not expose them in the html forms # but users are still able to clear them if plexpy.CONFIG.HTTP_PASSWORD != '': http_password = ' ' else: http_password = '' config = { "http_host": plexpy.CONFIG.HTTP_HOST, "http_username": plexpy.CONFIG.HTTP_USERNAME, "http_port": plexpy.CONFIG.HTTP_PORT, "http_password": http_password, "launch_browser": checked(plexpy.CONFIG.LAUNCH_BROWSER), "enable_https": checked(plexpy.CONFIG.ENABLE_HTTPS), "https_cert": plexpy.CONFIG.HTTPS_CERT, "https_key": plexpy.CONFIG.HTTPS_KEY, "api_enabled": checked(plexpy.CONFIG.API_ENABLED), "api_key": plexpy.CONFIG.API_KEY, "update_db_interval": plexpy.CONFIG.UPDATE_DB_INTERVAL, "freeze_db": checked(plexpy.CONFIG.FREEZE_DB), "log_dir": plexpy.CONFIG.LOG_DIR, "cache_dir": plexpy.CONFIG.CACHE_DIR, "interface_list": interface_list, "growl_enabled": checked(plexpy.CONFIG.GROWL_ENABLED), "growl_host": plexpy.CONFIG.GROWL_HOST, "growl_password": plexpy.CONFIG.GROWL_PASSWORD, "prowl_enabled": checked(plexpy.CONFIG.PROWL_ENABLED), "prowl_keys": plexpy.CONFIG.PROWL_KEYS, "prowl_priority": plexpy.CONFIG.PROWL_PRIORITY, "xbmc_enabled": checked(plexpy.CONFIG.XBMC_ENABLED), "xbmc_host": plexpy.CONFIG.XBMC_HOST, "xbmc_username": plexpy.CONFIG.XBMC_USERNAME, "xbmc_password": plexpy.CONFIG.XBMC_PASSWORD, "plex_enabled": checked(plexpy.CONFIG.PLEX_ENABLED), "plex_client_host": plexpy.CONFIG.PLEX_CLIENT_HOST, "plex_username": plexpy.CONFIG.PLEX_USERNAME, "plex_password": plexpy.CONFIG.PLEX_PASSWORD, "nma_enabled": checked(plexpy.CONFIG.NMA_ENABLED), "nma_apikey": plexpy.CONFIG.NMA_APIKEY, "nma_priority": int(plexpy.CONFIG.NMA_PRIORITY), "pushalot_enabled": checked(plexpy.CONFIG.PUSHALOT_ENABLED), "pushalot_apikey": plexpy.CONFIG.PUSHALOT_APIKEY, "pushover_enabled": checked(plexpy.CONFIG.PUSHOVER_ENABLED), "pushover_keys": plexpy.CONFIG.PUSHOVER_KEYS, "pushover_apitoken": plexpy.CONFIG.PUSHOVER_APITOKEN, "pushover_priority": plexpy.CONFIG.PUSHOVER_PRIORITY, "pushbullet_enabled": checked(plexpy.CONFIG.PUSHBULLET_ENABLED), "pushbullet_apikey": plexpy.CONFIG.PUSHBULLET_APIKEY, "pushbullet_deviceid": plexpy.CONFIG.PUSHBULLET_DEVICEID, "twitter_enabled": checked(plexpy.CONFIG.TWITTER_ENABLED), "osx_notify_enabled": checked(plexpy.CONFIG.OSX_NOTIFY_ENABLED), "osx_notify_app": plexpy.CONFIG.OSX_NOTIFY_APP, "boxcar_enabled": checked(plexpy.CONFIG.BOXCAR_ENABLED), "boxcar_token": plexpy.CONFIG.BOXCAR_TOKEN, "cache_sizemb": plexpy.CONFIG.CACHE_SIZEMB, "email_enabled": checked(plexpy.CONFIG.EMAIL_ENABLED), "email_from": plexpy.CONFIG.EMAIL_FROM, "email_to": plexpy.CONFIG.EMAIL_TO, "email_smtp_server": plexpy.CONFIG.EMAIL_SMTP_SERVER, "email_smtp_user": plexpy.CONFIG.EMAIL_SMTP_USER, "email_smtp_password": plexpy.CONFIG.EMAIL_SMTP_PASSWORD, "email_smtp_port": int(plexpy.CONFIG.EMAIL_SMTP_PORT), "email_tls": checked(plexpy.CONFIG.EMAIL_TLS), "pms_ip": plexpy.CONFIG.PMS_IP, "pms_logs_folder": plexpy.CONFIG.PMS_LOGS_FOLDER, "pms_port": plexpy.CONFIG.PMS_PORT, "pms_token": plexpy.CONFIG.PMS_TOKEN, "pms_use_bif": checked(plexpy.CONFIG.PMS_USE_BIF), "pms_uuid": plexpy.CONFIG.PMS_UUID, "plexwatch_database": plexpy.CONFIG.PLEXWATCH_DATABASE, "date_format": plexpy.CONFIG.DATE_FORMAT, "time_format": plexpy.CONFIG.TIME_FORMAT, "grouping_global_history": checked(plexpy.CONFIG.GROUPING_GLOBAL_HISTORY), "grouping_user_history": checked(plexpy.CONFIG.GROUPING_USER_HISTORY), "grouping_charts": checked(plexpy.CONFIG.GROUPING_CHARTS) } return serve_template(templatename="config.html", title="Settings", config=config) @cherrypy.expose def configUpdate(self, **kwargs): # Handle the variable config options. Note - keys with False values aren't getting passed checked_configs = [ "launch_browser", "enable_https", "api_enabled", "freeze_db", "growl_enabled", "prowl_enabled", "xbmc_enabled", "plex_enabled", "nma_enabled", "pushalot_enabled", "pushover_enabled", "pushbullet_enabled", "twitter_enabled", "osx_notify_enabled", "boxcar_enabled", "email_enabled", "email_tls", "grouping_global_history", "grouping_user_history", "grouping_charts", "pms_use_bif" ] for checked_config in checked_configs: if checked_config not in kwargs: # checked items should be zero or one. if they were not sent then the item was not checked kwargs[checked_config] = 0 # If http password exists in config, do not overwrite when blank value received if kwargs['http_password'] == ' ' and plexpy.CONFIG.HTTP_PASSWORD != '': kwargs['http_password'] = plexpy.CONFIG.HTTP_PASSWORD for plain_config, use_config in [(x[4:], x) for x in kwargs if x.startswith('use_')]: # the use prefix is fairly nice in the html, but does not match the actual config kwargs[plain_config] = kwargs[use_config] del kwargs[use_config] plexpy.CONFIG.process_kwargs(kwargs) # Write the config plexpy.CONFIG.write() # Check if we have our users table plexwatch.check_db_tables() # Reconfigure scheduler plexpy.initialize_scheduler() raise cherrypy.HTTPRedirect("config") @cherrypy.expose def do_state_change(self, signal, title, timer): plexpy.SIGNAL = signal message = title + '...' return serve_template(templatename="shutdown.html", title=title, message=message, timer=timer) @cherrypy.expose def get_history(self, start=0, length=100, custom_where='', **kwargs): if 'user' in kwargs: user = kwargs.get('user', "") custom_where = 'user = "%s"' % user if 'rating_key' in kwargs: rating_key = kwargs.get('rating_key', "") custom_where = 'rating_key = %s' % rating_key if 'grandparent_rating_key' in kwargs: rating_key = kwargs.get('grandparent_rating_key', "") custom_where = 'grandparent_rating_key = %s' % rating_key plex_watch = plexwatch.PlexWatch() history = plex_watch.get_history(start, length, kwargs, custom_where) cherrypy.response.headers['Content-type'] = 'application/json' return json.dumps(history) @cherrypy.expose def get_stream_details(self, rating_key=0, **kwargs): plex_watch = plexwatch.PlexWatch() stream_details = plex_watch.get_stream_details(rating_key) cherrypy.response.headers['Content-type'] = 'application/json' return json.dumps(stream_details) @cherrypy.expose def shutdown(self): return self.do_state_change('shutdown', 'Shutting Down', 15) @cherrypy.expose def restart(self): return self.do_state_change('restart', 'Restarting', 30) @cherrypy.expose def update(self): return self.do_state_change('update', 'Updating', 120) @cherrypy.expose def api(self, *args, **kwargs): from plexpy.api import Api a = Api() a.checkParams(*args, **kwargs) return a.fetchData() @cherrypy.expose def twitterStep1(self): cherrypy.response.headers['Cache-Control'] = "max-age=0,no-cache,no-store" tweet = notifiers.TwitterNotifier() return tweet._get_authorization() @cherrypy.expose def twitterStep2(self, key): cherrypy.response.headers['Cache-Control'] = "max-age=0,no-cache,no-store" tweet = notifiers.TwitterNotifier() result = tweet._get_credentials(key) logger.info(u"result: " + str(result)) if result: return "Key verification successful" else: return "Unable to verify key" @cherrypy.expose def testTwitter(self): cherrypy.response.headers['Cache-Control'] = "max-age=0,no-cache,no-store" tweet = notifiers.TwitterNotifier() result = tweet.test_notify() if result: return "Tweet successful, check your twitter to make sure it worked" else: return "Error sending tweet" @cherrypy.expose def osxnotifyregister(self, app): cherrypy.response.headers['Cache-Control'] = "max-age=0,no-cache,no-store" from osxnotify import registerapp as osxnotify result, msg = osxnotify.registerapp(app) if result: osx_notify = notifiers.OSX_NOTIFY() osx_notify.notify('Registered', result, 'Success :-)') logger.info('Registered %s, to re-register a different app, delete this app first' % result) else: logger.warn(msg) return msg @cherrypy.expose def get_pms_token(self): token = plextv.PlexTV() result = token.get_token() if result: return result else: logger.warn('Unable to retrieve Plex.tv token.') return False @cherrypy.expose def get_pms_sessions_json(self, **kwargs): pms_connect = pmsconnect.PmsConnect() result = pms_connect.get_sessions('json') if result: cherrypy.response.headers['Content-type'] = 'application/json' return result else: logger.warn('Unable to retrieve data.') return False @cherrypy.expose def get_current_activity(self, **kwargs): try: pms_connect = pmsconnect.PmsConnect() result = pms_connect.get_current_activity() except: return serve_template(templatename="current_activity.html", data=None) if result: return serve_template(templatename="current_activity.html", data=result) else: return serve_template(templatename="current_activity.html", data=None) logger.warn('Unable to retrieve data.') @cherrypy.expose def get_current_activity_header(self, **kwargs): try: pms_connect = pmsconnect.PmsConnect() result = pms_connect.get_current_activity() except IOError, e: return serve_template(templatename="current_activity_header.html", data=None) if result: return serve_template(templatename="current_activity_header.html", data=result['stream_count']) else: return serve_template(templatename="current_activity_header.html", data=None) logger.warn('Unable to retrieve data.') @cherrypy.expose def get_recently_added(self, count='0', **kwargs): try: pms_connect = pmsconnect.PmsConnect() result = pms_connect.get_recently_added_details(count) except IOError, e: return serve_template(templatename="recently_added.html", data=None) if result: return serve_template(templatename="recently_added.html", data=result['recently_added']) else: return serve_template(templatename="recently_added.html", data=None) logger.warn('Unable to retrieve data.') @cherrypy.expose def pms_image_proxy(self, img='', width='0', height='0', fallback=None, **kwargs): if img != '': try: pms_connect = pmsconnect.PmsConnect() result = pms_connect.get_image(img, width, height) cherrypy.response.headers['Content-type'] = result[0] return result[1] except: logger.warn('Image proxy queried but errors occured.') if fallback == 'poster': logger.info('Trying fallback image...') try: fallback_image = open(self.interface_dir + common.DEFAULT_POSTER_THUMB, 'rb') cherrypy.response.headers['Content-type'] = 'image/png' return fallback_image except IOError, e: logger.error('Unable to read fallback image. %s' % e) return None else: logger.warn('Image proxy queried but no parameters received.') return None @cherrypy.expose def info(self, rating_key='', **kwargs): pms_connect = pmsconnect.PmsConnect() result = pms_connect.get_metadata_details(rating_key) if result: return serve_template(templatename="info.html", data=result['metadata'], title="Info") else: return serve_template(templatename="info.html", data=None, title="Info") logger.warn('Unable to retrieve data.') @cherrypy.expose def get_user_recently_watched(self, user=None, limit='10', **kwargs): plex_watch = plexwatch.PlexWatch() result = plex_watch.get_recently_watched(user, limit) if result: return serve_template(templatename="user_recently_watched.html", data=result, title="Recently Watched") else: return serve_template(templatename="user_recently_watched.html", data=None, title="Recently Watched") logger.warn('Unable to retrieve data.') @cherrypy.expose def get_user_watch_time_stats(self, user=None, **kwargs): plex_watch = plexwatch.PlexWatch() result = plex_watch.get_user_watch_time_stats(user) if result: return serve_template(templatename="user_watch_time_stats.html", data=result, title="Watch Stats") else: return serve_template(templatename="user_watch_time_stats.html", data=None, title="Watch Stats") logger.warn('Unable to retrieve data.') @cherrypy.expose def get_user_platform_stats(self, user=None, **kwargs): plex_watch = plexwatch.PlexWatch() result = plex_watch.get_user_platform_stats(user) if result: return serve_template(templatename="user_platform_stats.html", data=result, title="Platform Stats") else: return serve_template(templatename="user_platform_stats.html", data=None, title="Platform Stats") logger.warn('Unable to retrieve data.') @cherrypy.expose def get_children(self, rating_key='', **kwargs): pms_connect = pmsconnect.PmsConnect() result = pms_connect.get_season_children(rating_key) if result: return serve_template(templatename="info_episode_list.html", data=result, title="Episode List") else: return serve_template(templatename="info_episode_list.html", data=None, title="Episode List") logger.warn('Unable to retrieve data.') @cherrypy.expose def get_metadata_json(self, rating_key='', **kwargs): pms_connect = pmsconnect.PmsConnect() result = pms_connect.get_metadata(rating_key, 'json') if result: cherrypy.response.headers['Content-type'] = 'application/json' return result else: logger.warn('Unable to retrieve data.') @cherrypy.expose def get_metadata_xml(self, rating_key='', **kwargs): pms_connect = pmsconnect.PmsConnect() result = pms_connect.get_metadata(rating_key) if result: cherrypy.response.headers['Content-type'] = 'application/xml' return result else: logger.warn('Unable to retrieve data.') @cherrypy.expose def get_recently_added_json(self, count='0', **kwargs): pms_connect = pmsconnect.PmsConnect() result = pms_connect.get_recently_added(count, 'json') if result: cherrypy.response.headers['Content-type'] = 'application/json' return result else: logger.warn('Unable to retrieve data.') @cherrypy.expose def get_episode_list_json(self, rating_key='', **kwargs): pms_connect = pmsconnect.PmsConnect() result = pms_connect.get_episode_list(rating_key, 'json') if result: cherrypy.response.headers['Content-type'] = 'application/json' return result else: logger.warn('Unable to retrieve data.') @cherrypy.expose def get_stream(self, row_id='', **kwargs): plex_watch = plexwatch.PlexWatch() result = plex_watch.get_stream_details('122') if result: cherrypy.response.headers['Content-type'] = 'application/json' return result else: logger.warn('Unable to retrieve data.') @cherrypy.expose def get_user_ips(self, start=0, length=100, custom_where='', **kwargs): if 'user' in kwargs: user = kwargs.get('user', "") custom_where = 'user = "%s"' % user plex_watch = plexwatch.PlexWatch() history = plex_watch.get_user_unique_ips(start, length, kwargs, custom_where) cherrypy.response.headers['Content-type'] = 'application/json' return json.dumps(history) @cherrypy.expose def get_watched(self, user=None, limit='10', **kwargs): plex_watch = plexwatch.PlexWatch() result = plex_watch.get_recently_watched(user, limit) if result: cherrypy.response.headers['Content-type'] = 'application/json' return json.dumps(result) else: logger.warn('Unable to retrieve data.') @cherrypy.expose def get_time_stats(self, user=None, **kwargs): plex_watch = plexwatch.PlexWatch() result = plex_watch.get_user_watch_time_stats(user) if result: cherrypy.response.headers['Content-type'] = 'application/json' return json.dumps(result) else: logger.warn('Unable to retrieve data.') @cherrypy.expose def get_platform_stats(self, user=None, **kwargs): plex_watch = plexwatch.PlexWatch() result = plex_watch.get_user_platform_stats(user) if result: cherrypy.response.headers['Content-type'] = 'application/json' return json.dumps(result) else: logger.warn('Unable to retrieve data.') @cherrypy.expose def get_user_gravatar_image(self, user=None, **kwargs): plex_watch = plexwatch.PlexWatch() result = plex_watch.get_user_gravatar_image(user) if result: cherrypy.response.headers['Content-type'] = 'application/json' return json.dumps(result) else: logger.warn('Unable to retrieve data.') @cherrypy.expose def get_home_stats(self, time_range='30', **kwargs): plex_watch = plexwatch.PlexWatch() result = plex_watch.get_home_stats(time_range) if result: cherrypy.response.headers['Content-type'] = 'application/json' return json.dumps(result) else: logger.warn('Unable to retrieve data.') @cherrypy.expose def get_plays_by_date(self, time_range='30', **kwargs): plex_watch = plexwatch.PlexWatch() result = plex_watch.get_total_plays_per_day(time_range) if result: cherrypy.response.headers['Content-type'] = 'application/json' return json.dumps(result) else: logger.warn('Unable to retrieve data.') @cherrypy.expose def get_plays_by_dayofweek(self, time_range='30', **kwargs): plex_watch = plexwatch.PlexWatch() result = plex_watch.get_total_plays_per_dayofweek(time_range) if result: cherrypy.response.headers['Content-type'] = 'application/json' return json.dumps(result) else: logger.warn('Unable to retrieve data.') @cherrypy.expose def get_plays_by_hourofday(self, time_range='30', **kwargs): plex_watch = plexwatch.PlexWatch() result = plex_watch.get_total_plays_per_hourofday(time_range) if result: cherrypy.response.headers['Content-type'] = 'application/json' return json.dumps(result) else: logger.warn('Unable to retrieve data.') @cherrypy.expose def get_friends_list(self, **kwargs): plex_tv = plextv.PlexTV() result = plex_tv.get_plextv_friends('json') if result: cherrypy.response.headers['Content-type'] = 'application/json' return result else: logger.warn('Unable to retrieve data.') @cherrypy.expose def get_user_details(self, **kwargs): plex_tv = plextv.PlexTV() result = plex_tv.get_plextv_user_details('json') if result: cherrypy.response.headers['Content-type'] = 'application/json' return result else: logger.warn('Unable to retrieve data.') @cherrypy.expose def get_server_list(self, **kwargs): plex_tv = plextv.PlexTV() result = plex_tv.get_plextv_server_list('json') if result: cherrypy.response.headers['Content-type'] = 'application/json' return result else: logger.warn('Unable to retrieve data.') @cherrypy.expose def get_sync_lists(self, machine_id='', **kwargs): plex_tv = plextv.PlexTV() result = plex_tv.get_plextv_sync_lists(machine_id=machine_id, output_format='json') if result: cherrypy.response.headers['Content-type'] = 'application/json' return result else: logger.warn('Unable to retrieve data.') @cherrypy.expose def get_servers(self, **kwargs): pms_connect = pmsconnect.PmsConnect() result = pms_connect.get_server_list(output_format='json') if result: cherrypy.response.headers['Content-type'] = 'application/json' return result else: logger.warn('Unable to retrieve data.') @cherrypy.expose def get_servers_info(self, **kwargs): pms_connect = pmsconnect.PmsConnect() result = pms_connect.get_servers_info() if result: cherrypy.response.headers['Content-type'] = 'application/json' return json.dumps(result) else: logger.warn('Unable to retrieve data.') @cherrypy.expose def get_server_prefs(self, **kwargs): pms_connect = pmsconnect.PmsConnect() result = pms_connect.get_server_prefs(output_format='json') if result: cherrypy.response.headers['Content-type'] = 'application/json' return result else: logger.warn('Unable to retrieve data.') @cherrypy.expose def get_activity(self, **kwargs): pms_connect = pmsconnect.PmsConnect() result = pms_connect.get_current_activity() if result: cherrypy.response.headers['Content-type'] = 'application/json' return json.dumps(result) else: logger.warn('Unable to retrieve data.') @cherrypy.expose def get_full_users_list(self, **kwargs): plex_tv = plextv.PlexTV() result = plex_tv.get_full_users_list() if result: cherrypy.response.headers['Content-type'] = 'application/json' return json.dumps(result) else: logger.warn('Unable to retrieve data.') @cherrypy.expose def refresh_users_list(self, **kwargs): plex_tv = plextv.PlexTV() result = plex_tv.get_full_users_list() myDB = db.DBConnection() for item in result: control_value_dict = {"username": item['username']} new_value_dict = {"user_id": item['user_id'], "username": item['username'], "thumb": item['thumb'], "email": item['email'], "is_home_user": item['is_home_user'], "is_allow_sync": item['is_allow_sync'], "is_restricted": item['is_restricted'] } myDB.upsert('plexpy_users', new_value_dict, control_value_dict) logger.info("Users list refreshed.") raise cherrypy.HTTPRedirect("users") @cherrypy.expose def get_sync(self, machine_id=None, user_id=None, **kwargs): pms_connect = pmsconnect.PmsConnect() server_id = pms_connect.get_server_identity() plex_tv = plextv.PlexTV() if not machine_id: result = plex_tv.get_synced_items(machine_id=server_id['machine_identifier'], user_id=user_id) else: result = plex_tv.get_synced_items(machine_id=machine_id, user_id=user_id) if result: output = {"data": result} else: logger.warn('Unable to retrieve sync data for user.') output = {"data": []} cherrypy.response.headers['Content-type'] = 'application/json' return json.dumps(output)