Example #1
0
    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()))
Example #2
0
    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)
Example #3
0
    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")
Example #4
0
    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
Example #5
0
    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()))