def signin(cls, username, password): """Summary Args: username (str): username password (str): password Returns: class: MyPlexAccount Raises: BadRequest: (HTTPCODE) http codename Unauthorized: (HTTPCODE) http codename """ if 'X-Plex-Token' in plexapi.BASE_HEADERS: del plexapi.BASE_HEADERS['X-Plex-Token'] auth = (username, password) log.info('POST %s', cls.SIGNIN) response = requests.post(cls.SIGNIN, headers=plexapi.BASE_HEADERS, auth=auth, timeout=TIMEOUT) if response.status_code != requests.codes.created: codename = codes.get(response.status_code)[0] if response.status_code == 401: raise Unauthorized('(%s) %s' % (response.status_code, codename)) raise BadRequest('(%s) %s' % (response.status_code, codename)) data = ElementTree.fromstring(response.text.encode('utf8')) return cls(data, cls.SIGNIN)
def query(self, key, method=None, headers=None, timeout=None, **kwargs): """ Main method used to handle HTTPS requests to the Plex server. This method helps by encoding the response to utf-8 and parsing the returned XML into and ElementTree object. Returns None if no data exists in the response. """ url = self.url(key) method = method or self._session.get timeout = timeout or TIMEOUT log.debug('%s %s', method.__name__.upper(), url) headers = self._headers(**headers or {}) response = method(url, headers=headers, timeout=timeout, **kwargs) if response.status_code not in (200, 201, 204): codename = codes.get(response.status_code)[0] errtext = response.text.replace('\n', ' ') message = '(%s) %s; %s %s' % (response.status_code, codename, response.url, errtext) if response.status_code == 401: raise Unauthorized(message) elif response.status_code == 404: raise NotFound(message) else: raise BadRequest(message) data = response.text.encode('utf8') return ElementTree.fromstring(data) if data.strip() else None
def signin(cls, username=None, password=None, session=None): """ Returns a new :class:`~myplex.MyPlexAccount` object by connecting to MyPlex with the specified username and password. This is essentially logging into MyPlex and often the very first entry point to using this API. Parameters: username (str): Your MyPlex.tv username. If not specified, it will check the config.ini file. password (str): Your MyPlex.tv password. If not specified, it will check the config.ini file. Raises: :class:`~plexapi.exceptions.Unauthorized`: (401) If the username or password are invalid. :class:`~plexapi.exceptions.BadRequest`: If any other errors occured not allowing us to log into MyPlex.tv. """ if 'X-Plex-Token' in plexapi.BASE_HEADERS: del plexapi.BASE_HEADERS['X-Plex-Token'] username = username or CONFIG.get('authentication.username') password = password or CONFIG.get('authentication.password') auth = (username, password) log.info('POST %s', cls.SIGNIN) sess = session or requests.Session() response = sess.post(cls.SIGNIN, headers=plexapi.BASE_HEADERS, auth=auth, timeout=TIMEOUT) if response.status_code != requests.codes.created: codename = codes.get(response.status_code)[0] if response.status_code == 401: raise Unauthorized('(%s) %s' % (response.status_code, codename)) raise BadRequest('(%s) %s' % (response.status_code, codename)) data = ElementTree.fromstring(response.text.encode('utf8')) return MyPlexAccount(data, cls.SIGNIN, session=sess)
def query(self, path, method=None, headers=None, **kwargs): """Main method used to handle http connection to PMS. encodes the response to utf-8 and parses the xml returned from PMS into a Element Args: path (str): relative path to PMS, fx /search?query=HELLO method (None, optional): requests.method, requests.put headers (None, optional): Headers that will be passed to PMS **kwargs (dict): Used for filter and sorting. Raises: BadRequest: fx (404) Not Found Returns: xml.etree.ElementTree.Element or None """ url = self.url(path) method = method or self.session.get log.info('%s %s', method.__name__.upper(), url) h = self.headers().copy() if headers: h.update(headers) response = method(url, headers=h, timeout=TIMEOUT, **kwargs) if response.status_code not in [200, 201]: codename = codes.get(response.status_code)[0] raise BadRequest('(%s) %s' % (response.status_code, codename)) data = response.text.encode('utf8') return ElementTree.fromstring(data) if data else None
def query(self, path, method=None, headers=None, **kwargs): """ Main method used to handle HTTPS requests to the Plex server. This method helps by encoding the response to utf-8 and parsing the returned XML into and ElementTree object. Returns None if no data exists in the response. Parameters: path (str): Relative path to query on the server api (ex: '/search?query=HELLO') method (func): requests.method to use for this query (request.get or requests.put; defaults to get) headers (dict): Optionally include additional headers for this request. **kwargs (dict): Optionally include additional kwargs for in the specified reuqest method. These kwargs are simply passed through to method(). Raises: :class:`~plexapi.exceptions.BadRequest`: Raised when response is not in (200, 201). """ url = self.url(path) method = method or self.session.get log.info('%s %s', method.__name__.upper(), url) h = self.headers().copy() if headers: h.update(headers) response = method(url, headers=h, timeout=TIMEOUT, **kwargs) #print(response.url) if response.status_code not in [200, 201]: # pragma: no cover codename = codes.get(response.status_code)[0] raise BadRequest('(%s) %s %s' % (response.status_code, codename, response.url)) data = response.text.encode('utf8') return ElementTree.fromstring(data) if data else None
def _get_exception(self, headers, status_code=None, data=None): """ Helper method to parse an error string send by the server and transform it into the corresponding rucio exception. :param headers: The http response header containing the Rucio exception details. :param status_code: The http status code. :param data: The data with the ExceptionMessage. :return: A rucio exception class and an error string. """ data = parse_response(data) if 'ExceptionClass' not in data: if 'ExceptionMessage' not in data: human_http_code = _codes.get( status_code, None) # NOQA, pylint: disable-msg=W0612 return getattr( exception, 'RucioException' ), 'no error information passed (http status code: %(status_code)s %(human_http_code)s)' % locals( ) return getattr(exception, 'RucioException'), data['ExceptionMessage'] exc_cls = None try: exc_cls = getattr(exception, data['ExceptionClass']) except AttributeError: return getattr(exception, 'RucioException'), data['ExceptionMessage'] return exc_cls, data['ExceptionMessage']
def get_code_desc(status_code): items = _codes.get(status_code) if items: item = items[0] item = item.replace('_', ' ') item = item.upper() return item
def query(self, path, method=None, headers=None, **kwargs): """Used to fetch relative paths to pms. Args: path (str): Relative path method (None, optional): requests.post etc headers (None, optional): Set headers manually **kwargs (TYPE): Passord to the http request used for filter, sorting. Returns: Element Raises: BadRequest: Http error and code """ url = self.url(path) method = method or self.session.get log.info('%s %s', method.__name__.upper(), url) headers = dict(self.headers(), **(headers or {})) # remove hack response = method(url, headers=headers, timeout=TIMEOUT, **kwargs) if response.status_code not in [200, 201]: codename = codes.get(response.status_code)[0] raise BadRequest('(%s) %s' % (response.status_code, codename)) data = response.text.encode('utf8') return ElementTree.fromstring(data) if data else None
def sendClientCommand(self, command, args=None): url = '%s%s' % (self.url(command), utils.joinArgs(args)) log.info('GET %s', url) response = requests.get(url, timeout=TIMEOUT) if response.status_code != requests.codes.ok: codename = codes.get(response.status_code)[0] raise BadRequest('(%s) %s' % (response.status_code, codename)) data = response.text.encode('utf8') return ElementTree.fromstring(data) if data else None
def query(self, path, method=None, **kwargs): url = self.url(path) method = method or self.session.get log.info('%s %s', method.__name__.upper(), url) response = method(url, headers=self.headers(), timeout=TIMEOUT, **kwargs) if response.status_code not in [200, 201]: codename = codes.get(response.status_code)[0] raise BadRequest('(%s) %s' % (response.status_code, codename)) data = response.text.encode('utf8') return ElementTree.fromstring(data) if data else None
def query(self, path, method=requests.get): global TOTAL_QUERIES TOTAL_QUERIES += 1 url = self.url(path) log.info('%s %s', method.__name__.upper(), url) response = method(url, headers=self.headers(), timeout=TIMEOUT) if response.status_code not in [200, 201]: codename = codes.get(response.status_code)[0] raise BadRequest('(%s) %s' % (response.status_code, codename)) data = response.text.encode('utf8') return ElementTree.fromstring(data) if data else None
def claimToken(self): """ Returns a str, a new "claim-token", which you can use to register your new Plex Server instance to your account. See: https://hub.docker.com/r/plexinc/pms-docker/, https://www.plex.tv/claim/ """ response = self._session.get('https://plex.tv/api/claim/token.json', headers=self._headers(), timeout=TIMEOUT) if response.status_code not in (200, 201, 204): # pragma: no cover codename = codes.get(response.status_code)[0] errtext = response.text.replace('\n', ' ') raise BadRequest('(%s) %s %s; %s' % (response.status_code, codename, response.url, errtext)) return response.json()['token']
def query(self, path, method=None, headers=None, **kwargs): url = self.url(path) method = method or self.session.get log.info('%s %s', method.__name__.upper(), url) headers = dict(self.headers(), **(headers or {})) response = method(url, headers=headers, timeout=TIMEOUT, **kwargs) if response.status_code not in [200, 201]: codename = codes.get(response.status_code)[0] raise BadRequest('(%s) %s' % (response.status_code, codename)) data = response.text.encode('utf8') return ElementTree.fromstring(data) if data else None
def query(self, url, method=None, headers=None, timeout=None, **kwargs): method = method or self._session.get timeout = timeout or TIMEOUT log.debug('%s %s %s', method.__name__.upper(), url, kwargs.get('json', '')) headers = self._headers(**headers or {}) response = method(url, headers=headers, timeout=timeout, **kwargs) if response.status_code not in (200, 201, 204): # pragma: no cover codename = codes.get(response.status_code)[0] errtext = response.text.replace('\n', ' ') raise BadRequest('(%s) %s %s; %s' % (response.status_code, codename, response.url, errtext)) data = response.text.encode('utf8') return ElementTree.fromstring(data) if data.strip() else None
def _signin(self, username, password): auth = (username, password) log.info('POST %s', self.SIGNIN) response = requests.post(self.SIGNIN, headers=plexapi.BASE_HEADERS, auth=auth, timeout=TIMEOUT) if response.status_code != requests.codes.created: codename = codes.get(response.status_code)[0] raise BadRequest('(%s) %s' % (response.status_code, codename)) self.response = response data = response.text.encode('utf8') return ElementTree.fromstring(data)
def query(self, url, method=None, headers=None, timeout=None, **kwargs): method = method or self._session.get timeout = timeout or TIMEOUT log.debug('%s %s %s', method.__name__.upper(), url, kwargs.get('json', '')) headers = self._headers(**headers or {}) response = method(url, headers=headers, timeout=timeout, **kwargs) if response.status_code not in (200, 201, 204): # pragma: no cover codename = codes.get(response.status_code)[0] errtext = response.text.replace('\n', ' ') log.warning('BadRequest (%s) %s %s; %s' % (response.status_code, codename, response.url, errtext)) raise BadRequest('(%s) %s %s; %s' % (response.status_code, codename, response.url, errtext)) data = response.text.encode('utf8') return ElementTree.fromstring(data) if data.strip() else None
def signin(cls, username, password): if 'X-Plex-Token' in plexapi.BASE_HEADERS: del plexapi.BASE_HEADERS['X-Plex-Token'] auth = (username, password) log.info('POST %s', cls.SIGNIN) response = requests.post(cls.SIGNIN, headers=plexapi.BASE_HEADERS, auth=auth, timeout=TIMEOUT) if response.status_code != requests.codes.created: codename = codes.get(response.status_code)[0] if response.status_code == 401: raise Unauthorized('(%s) %s' % (response.status_code, codename)) raise BadRequest('(%s) %s' % (response.status_code, codename)) data = ElementTree.fromstring(response.text.encode('utf8')) return cls(data, cls.SIGNIN)
def query(self, url, method=None, headers=None, **kwargs): method = method or self._session.get delim = '&' if '?' in url else '?' url = '%s%sX-Plex-Token=%s' % (url, delim, self._token) log.debug('%s %s', method.__name__.upper(), url) allheaders = BASE_HEADERS.copy() allheaders.update(headers or {}) response = method(url, headers=allheaders, timeout=TIMEOUT, **kwargs) if response.status_code not in (200, 201): codename = codes.get(response.status_code)[0] log.warn('BadRequest (%s) %s %s' % (response.status_code, codename, response.url)) raise BadRequest('(%s) %s' % (response.status_code, codename)) data = response.text.encode('utf8') return ElementTree.fromstring(data) if data.strip() else None
def sendCommand(self, command, args=None): url = '%s%s' % (self.url(command), utils.joinArgs(args)) log.info('GET %s', url) headers = plexapi.BASE_HEADERS headers['X-Plex-Target-Client-Identifier'] = self.clientIdentifier response = requests.get(url, headers=headers, timeout=TIMEOUT) if response.status_code != requests.codes.ok: codename = codes.get(response.status_code)[0] raise BadRequest('(%s) %s' % (response.status_code, codename)) data = response.text.encode('utf8') if data: try: return ElementTree.fromstring(data) except: pass return None
def query(self, path, method=None, headers=None, timeout=None, **kwargs): """ Main method used to handle HTTPS requests to the Plex client. This method helps by encoding the response to utf-8 and parsing the returned XML into and ElementTree object. Returns None if no data exists in the response. """ url = self.url(path) method = method or self._session.get timeout = timeout or TIMEOUT log.debug('%s %s', method.__name__.upper(), url) headers = self._headers(**headers or {}) response = method(url, headers=headers, timeout=timeout, **kwargs) if response.status_code not in (200, 201): codename = codes.get(response.status_code)[0] log.warn('BadRequest (%s) %s %s' % (response.status_code, codename, response.url)) raise BadRequest('(%s) %s' % (response.status_code, codename)) data = response.text.encode('utf8') return ElementTree.fromstring(data) if data.strip() else None
def query(self, key, method=None, headers=None, timeout=None, **kwargs): """ Main method used to handle HTTPS requests to the Plex server. This method helps by encoding the response to utf-8 and parsing the returned XML into and ElementTree object. Returns None if no data exists in the response. """ url = self.url(key) method = method or self._session.get timeout = timeout or TIMEOUT log.debug('%s %s', method.__name__.upper(), url) headers = self._headers(**headers or {}) response = method(url, headers=headers, timeout=timeout, **kwargs) if response.status_code not in (200, 201): codename = codes.get(response.status_code)[0] errtext = response.text.replace('\n', ' ') log.warning('BadRequest (%s) %s %s; %s' % (response.status_code, codename, response.url, errtext)) raise BadRequest('(%s) %s; %s %s' % (response.status_code, codename, response.url, errtext)) data = response.text.encode('utf8') return ElementTree.fromstring(data) if data.strip() else None
def _get_exception(self, headers, status_code=None): """ Helper method to parse an error string send by the server and transform it into the corresponding rucio exception. :param headers: The http response header containing the Rucio exception details. :return: A rucio exception class and an error string. """ if 'ExceptionClass' not in headers: if 'ExceptionMessage' not in headers: human_http_code = _codes.get(status_code, None) # NOQA return getattr(exception, 'RucioException'), 'no error information passed (http status code: %(status_code)s %(human_http_code)s)' % locals() return getattr(exception, 'RucioException'), headers['ExceptionMessage'] exc_cls = None try: exc_cls = getattr(exception, headers['ExceptionClass']) except AttributeError: return getattr(exception, 'RucioException'), headers['ExceptionMessage'] return exc_cls, headers['ExceptionMessage']
def query(self, path, method=None, headers=None, **kwargs): """ Returns an ElementTree object containing the response from the specified request path. Parameters: path (str): Relative path to query. method (func): `self.session.get` or `self.session.post` headers (dict): Additional headers to include or override in the request. **kwargs (TYPE): Additional arguments to inclde in the request.<method> call. Raises: :class:`~plexapi.exceptions.BadRequest`: When the response is not in [200, 201] """ url = self.url(path) method = method or self.session.get log.info('%s %s', method.__name__.upper(), url) headers = dict(self.headers(), **(headers or {})) # remove hack response = method(url, headers=headers, timeout=TIMEOUT, **kwargs) if response.status_code not in [200, 201]: codename = codes.get(response.status_code)[0] raise BadRequest('(%s) %s' % (response.status_code, codename)) data = response.text.encode('utf8') return ElementTree.fromstring(data) if data else None