def _http_query(self, query, timeout=None): """ Query Transmission through HTTP. """ headers = {"x-transmission-session-id": str(self.session_id)} result = {} request_count = 0 if timeout is None: timeout = self._query_timeout use_logger = is_logger_configured() while True: if use_logger: LOGGER.debug( json.dumps( { "url": self.url, "headers": headers, "query": query, "timeout": timeout, }, indent=2, )) try: result = self.http_handler.request(self.url, query, headers, timeout) break except HTTPHandlerError as error: if error.code == 409: if use_logger: LOGGER.info( "Server responded with 409, trying to set session-id." ) if request_count > 1: raise TransmissionError( "Session ID negotiation failed.", error) session_id = None for key in list(error.headers.keys()): if key.lower() == "x-transmission-session-id": session_id = error.headers[key] self.session_id = session_id headers = { "x-transmission-session-id": str(self.session_id) } if session_id is None: if use_logger: debug_httperror(error) raise TransmissionError("Unknown conflict.", error) else: if use_logger: debug_httperror(error) raise TransmissionError("Request failed.", error) request_count += 1 return result
def _http_query(self, query, timeout=None): """ Query Transmission through HTTP. """ headers = {'x-transmission-session-id': str(self.session_id)} result = {} request_count = 0 if timeout is None: timeout = self._query_timeout use_logger = is_logger_configured() while True: if use_logger: LOGGER.debug( json.dumps({ 'url': self.url, 'headers': headers, 'query': query, 'timeout': timeout }, indent=2)) try: result = self.http_handler.request(self.url, query, headers, timeout) break except HTTPHandlerError as error: if error.code == 409: if use_logger: LOGGER.info( 'Server responded with 409, trying to set session-id.' ) if request_count > 1: raise TransmissionError( 'Session ID negotiation failed.', error) session_id = None for key in list(error.headers.keys()): if key.lower() == 'x-transmission-session-id': session_id = error.headers[key] self.session_id = session_id headers = { 'x-transmission-session-id': str(self.session_id) } if session_id is None: if use_logger: debug_httperror(error) raise TransmissionError('Unknown conflict.', error) else: if use_logger: debug_httperror(error) raise TransmissionError('Request failed.', error) request_count += 1 return result
def _request(self, method, arguments=None, ids=None, require_ids=False, timeout=None): """ Send json-rpc request to Transmission using http POST """ if not isinstance(method, string_types): raise ValueError('request takes method as string') if arguments is None: arguments = {} if not isinstance(arguments, dict): raise ValueError('request takes arguments as dict') ids = parse_torrent_ids(ids) if len(ids) > 0: arguments['ids'] = ids elif require_ids: raise ValueError('request require ids') use_logger = is_logger_configured() query = json.dumps({ 'tag': self._sequence, 'method': method, 'arguments': arguments }) self._sequence += 1 start = time.time() http_data = self._http_query(query, timeout) elapsed = time.time() - start if use_logger: LOGGER.info('http request took %.3f s' % (elapsed)) try: data = json.loads(http_data) except ValueError as error: if use_logger: LOGGER.error('Error: ' + str(error)) LOGGER.error('Request: \"%s\"' % (query)) LOGGER.error('HTTP data: \"%s\"' % (http_data)) raise if use_logger: LOGGER.debug(json.dumps(data, indent=2)) if 'result' in data: if data['result'] != 'success': raise TransmissionError('Query failed with result \"%s\".' % (data['result'])) else: raise TransmissionError('Query failed without result.') results = {} if method == 'torrent-get': for item in data['arguments']['torrents']: results[item['id']] = Torrent(self, item) if self.protocol_version == 2 and 'peers' not in item: self.protocol_version = 1 elif method == 'torrent-add': item = None if 'torrent-added' in data['arguments']: item = data['arguments']['torrent-added'] elif 'torrent-duplicate' in data['arguments']: item = data['arguments']['torrent-duplicate'] if item: results[item['id']] = Torrent(self, item) else: raise TransmissionError('Invalid torrent-add response.') elif method == 'session-get': self._update_session(data['arguments']) elif method == 'session-stats': # older versions of T has the return data in "session-stats" if 'session-stats' in data['arguments']: self._update_session(data['arguments']['session-stats']) else: self._update_session(data['arguments']) elif method in ('port-test', 'blocklist-update', 'free-space', 'torrent-rename-path'): results = data['arguments'] else: return None return results
def _request(self, method, arguments=None, ids=None, require_ids=False, timeout=None): """ Send json-rpc request to Transmission using http POST """ if not isinstance(method, string_types): raise ValueError('request takes method as string') if arguments is None: arguments = {} if not isinstance(arguments, dict): raise ValueError('request takes arguments as dict') ids = parse_torrent_ids(ids) if len(ids) > 0: arguments['ids'] = ids elif require_ids: raise ValueError('request require ids') use_logger = is_logger_configured() query = json.dumps({'tag': self._sequence, 'method': method , 'arguments': arguments}) self._sequence += 1 start = time.time() http_data = self._http_query(query, timeout) elapsed = time.time() - start if use_logger: LOGGER.info('http request took %.3f s' % (elapsed)) try: data = json.loads(http_data) except ValueError as error: if use_logger: LOGGER.error('Error: ' + str(error)) LOGGER.error('Request: \"%s\"' % (query)) LOGGER.error('HTTP data: \"%s\"' % (http_data)) raise if use_logger: LOGGER.debug(json.dumps(data, indent=2)) if 'result' in data: if data['result'] != 'success': raise TransmissionError('Query failed with result \"%s\".' % (data['result'])) else: raise TransmissionError('Query failed without result.') results = {} if method == 'torrent-get': for item in data['arguments']['torrents']: results[item['id']] = Torrent(self, item) if self.protocol_version == 2 and 'peers' not in item: self.protocol_version = 1 elif method == 'torrent-add': item = None if 'torrent-added' in data['arguments']: item = data['arguments']['torrent-added'] elif 'torrent-duplicate' in data['arguments']: item = data['arguments']['torrent-duplicate'] if item: results[item['id']] = Torrent(self, item) else: raise TransmissionError('Invalid torrent-add response.') elif method == 'session-get': self._update_session(data['arguments']) elif method == 'session-stats': # older versions of T has the return data in "session-stats" if 'session-stats' in data['arguments']: self._update_session(data['arguments']['session-stats']) else: self._update_session(data['arguments']) elif method in ('port-test', 'blocklist-update', 'free-space', 'torrent-rename-path'): results = data['arguments'] else: return None return results
def _request(self, method, arguments=None, ids=None, require_ids=False, timeout=None): """ Send json-rpc request to Transmission using http POST """ if not isinstance(method, str): raise ValueError("request takes method as string") if arguments is None: arguments = {} if not isinstance(arguments, dict): raise ValueError("request takes arguments as dict") ids = parse_torrent_ids(ids) if ids: arguments["ids"] = ids elif require_ids: raise ValueError("request require ids") use_logger = is_logger_configured() query = json.dumps({ "tag": self._sequence, "method": method, "arguments": arguments }) self._sequence += 1 start = time.time() http_data = self._http_query(query, timeout) if isinstance(http_data, bytes): http_data = str(http_data, encoding="utf-8", errors="replace") http_data = "".join( list(filter(lambda c: unicodedata.category(c)[0] != "C", http_data))) elapsed = time.time() - start if use_logger: LOGGER.info("http request took %.3f s", elapsed) try: data = json.loads(http_data) except ValueError as error: if use_logger: LOGGER.error("Error: %s", str(error)) LOGGER.error('Request: "%s"', query) LOGGER.error('HTTP data: "%s"', http_data) raise if use_logger: LOGGER.debug(json.dumps(data, indent=2)) if "result" in data: if data["result"] != "success": raise TransmissionError('Query failed with result "%s".' % (data["result"])) else: raise TransmissionError("Query failed without result.") results = {} if method == "torrent-get": for item in data["arguments"]["torrents"]: results[item["id"]] = Torrent(self, item) if self.protocol_version == 2 and "peers" not in item: self.protocol_version = 1 elif method == "torrent-add": item = None if "torrent-added" in data["arguments"]: item = data["arguments"]["torrent-added"] elif "torrent-duplicate" in data["arguments"]: item = data["arguments"]["torrent-duplicate"] if item: results[item["id"]] = Torrent(self, item) else: raise TransmissionError("Invalid torrent-add response.") elif method == "session-get": self._update_session(data["arguments"]) elif method == "session-stats": # older versions of T has the return data in "session-stats" if "session-stats" in data["arguments"]: self._update_session(data["arguments"]["session-stats"]) else: self._update_session(data["arguments"]) elif method in ( "port-test", "blocklist-update", "free-space", "torrent-rename-path", ): results = data["arguments"] else: return None return results