def default(self, *args, **kwargs): self.ensure_pms_data() query_params = "&".join("=".join([k, v]) for k, v in kwargs.items()) path = "/".join(args) + ("?" + query_params if query_params else "") # print(args, path) if not path: path = self.plugin["key"][1:] try: return self.render_plugin(path) except (HTTPError, Timeout) as e: if isinstance(e, HTTPError): if e.response.status_code == 401: message("Access denied on {}".format(self.server_name), "ERROR") print("Access denied when accessing {}," " going to server selection".format( mask_str(self.server_name))) self.server_name = None self.connection = None raise cherrypy.HTTPRedirect(cherrypy.url("/servers")) elif e.response.status_code == 404: raise cherrypy.HTTPRedirect(cherrypy.url("/plugins")) else: message("Timeout on {}".format(self.server_name), "WARNING") print( "Error when connecting to '{}', trying other connection to: {}" .format(mask_url(self.server_addr), mask_str(self.server_name))) return self.discover_pms(self.server_name) except: print("Something went wrong. {}".format(traceback.format_exc()))
def choose_plugin(self, key=None, identifier=None, default_identifier=None): plugins = [] try: plugins = self.plugins = self.server_plugins.get("Directory", []) except HTTPError as e: if e.response.status_code == 401: print( "Access denied when accessing plugins on {}, going to server selection" .format(mask_str(self.server_name))) message( "Access denied for plugins on {}".format(self.server_name), "ERROR") raise cherrypy.HTTPRedirect(cherrypy.url("/servers")) if (key and identifier) or default_identifier: ident = identifier or default_identifier for plugin in plugins: if plugin["identifier"] == ident: self.plugin = plugin print("Plugin chosen: {}".format(plugin["title"])) raise cherrypy.HTTPRedirect(cherrypy.url("/")) template = env.get_template('plugins.jinja2') return template.render(plex_headers_json=json.dumps(self.plex_headers), **self.default_context)
def server_plugins(self): if not self.server_addr: con = self.connection.copy() con["uri"] = mask_url(con.get("uri", "")) con["address"] = mask_str(con.get("address", "")) print("No server address set, redirecting to root. Connection: {!r}".format(con)) raise cherrypy.HTTPRedirect(cherrypy.url("/")) return self.plex_dispatch("channels/all")
def discover_pms(self, server_name=None, server_addr=None, blacklist_addr=None): try: r = self.session.get( "https://plex.tv/api/resources?includeHttps=1&includeRelay=1", headers=self.full_headers, timeout=self.plextv_timeout) r.raise_for_status() except (HTTPError, Timeout) as e: if isinstance(e, HTTPError): if e.response.status_code == 401: self.plex_token = None self.server_name = None self.connection = None print("Access denied when accessing {}, going to login". format(self.server_name)) raise cherrypy.HTTPRedirect(cherrypy.url("/token")) raise content = xmltodict.parse(r.content, attr_prefix="", force_list=("Device", "Connection")) servers = OrderedDict() # import pprint # pprint.pprint(content) use_connection = None connections = [] for device in content["MediaContainer"].get("Device", []): if device.get("provides") != "server" or not bool( device.get("presence")): continue public_address_matches = device.get("publicAddressMatches", "0") == "1" https_required = device.get("httpsRequired", "0") == "1" for connection in device.get("Connection", []): connection["unavailable"] = False if not public_address_matches and connection.get("local", "0") == "1": continue elif https_required and connection.get("protocol", "http") != "https": continue if device["name"] not in servers: if self.only_owned and not device.get("owned", "0") == "1": continue servers[device["name"]] = { "connections": [], "owned": device.get("owned", "0") == "1", "publicAddress": device.get("publicAddress", None), "publicAddressMatches": public_address_matches } if blacklist_addr and connection["uri"] in blacklist_addr: print("{}: {} on blacklist, skipping".format( mask_str(device["name"]), mask_url(connection["uri"]))) connection["unavailable"] = True continue servers[device["name"]]["connections"].append(connection) if server_name and server_name == device["name"]: if server_addr and connection["uri"] == server_addr: use_connection = connection elif server_addr and server_addr == "relay" and connection.get( "relay") == "1": use_connection = connection elif not server_addr: use_connection = connection if use_connection: connections = device["Connection"] break if server_name and use_connection: self.server_name = server_name self.connection = use_connection self.connections = connections server_addr = use_connection["uri"] print("Server set to: {}, {}".format(mask_str(server_name), mask_url(server_addr))) print("Verifying {}: {}".format(mask_str(server_name), mask_url(server_addr))) try: self.session.get(self.server_addr + "servers", headers=self.full_headers, **self.req_defaults) except HTTPError as e: if e.response.status_code == 401: self.plex_token = None self.server_name = None self.connection = None print("Access denied when accessing {}, going to login". format(mask_str(self.server_name))) raise cherrypy.HTTPRedirect(cherrypy.url("/token")) except Timeout as e: if not blacklist_addr: blacklist_addr = [] blacklist_addr.append(server_addr) print("{}: Blacklisting {} due to: {!r}".format( mask_str(server_name), mask_url(server_addr), type(e))) return self.discover_pms(server_name=server_name, server_addr=None, blacklist_addr=blacklist_addr) print("Verified {}: {}".format(mask_str(server_name), mask_url(server_addr))) self.plugin = None message("Successfully connected to {}".format(self.server_name), "SUCCESS") raise cherrypy.HTTPRedirect(cherrypy.url("/")) return servers
def default(self, *args, **kwargs): self.ensure_pms_data() query_params = "&".join("=".join([k, v]) for k, v in kwargs.items()) path = "/".join(args) + ("?" + query_params if query_params else "") # print(args, path) if not path: path = self.plugin["key"][1:] try: return self.render_plugin(path) except (HTTPError, Timeout, requests.exceptions.SSLError) as e: urlTried = getattr(getattr(e, "request", ""), "url", None) if urlTried: urlTried = mask_url(urlTried) try: if not isinstance(e, Timeout): if hasattr(e.response, "status_code"): if e.response.status_code == 401: message( "Access denied on {}".format(self.server_name), "ERROR") print("Access denied when accessing {}," " going to server selection".format( mask_str(self.server_name))) self.server_name = None self.connection = None raise cherrypy.HTTPRedirect( cherrypy.url("/servers")) elif e.response.status_code == 404: raise cherrypy.HTTPRedirect(cherrypy.url("/")) else: message("Timeout on {}".format(self.server_name), "WARNING") if hasattr(e.response, "text") and e.response.text: print("Plugin response: {}".format(e.response.text)) if hasattr(e.response, "status_code") and e.response.status_code != 500: message( "Error on {} (see log): {}".format( self.server_name, e), "ERROR") traceback.print_exc() print( "Error when connecting to '{}', trying other connection to: {}" .format(mask_url(self.server_addr), mask_str(self.server_name))) return self.discover_pms(self.server_name) else: message( "Plugin error on {} (see log): {}".format( self.server_name, e), "ERROR") traceback.print_exc() raise cherrypy.HTTPRedirect(cherrypy.url("/")) except cherrypy.HTTPRedirect: # intercept redirects to avoid infinite redirects lastUrls = cherrypy.session.get("last_urls", []) lastUrls.append(urlTried) if lastUrls.count(urlTried) > 2: print("Tried to reach {} 3 times. Not retrying.".format( urlTried)) message( "Tried to reach {} 3 times. Not retrying.".format( urlTried), "ERROR") cherrypy.session["last_urls"] = [] return self.discover_pms(self.server_name) cherrypy.session["last_urls"] = lastUrls raise except HTTPRedirect: raise except: print("Something went wrong. {}".format(traceback.format_exc()))