def _request(self, method, arguments={}, ids=[], require_ids=False, timeout=None): """Send json-rpc request to Transmission using http POST""" if not isinstance(method, (str, unicode)): raise ValueError('request takes method as string') if not isinstance(arguments, dict): raise ValueError('request takes arguments as dict') ids = self._format_ids(ids) if len(ids) > 0: arguments['ids'] = ids elif require_ids: raise ValueError('request require ids') 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 logger.info('http request took %.3f s' % (elapsed)) try: data = json.loads(http_data) except ValueError, e: logger.error('Error: ' + str(e)) logger.error('Request: \"%s\"' % (query)) logger.error('HTTP data: \"%s\"' % (http_data)) raise
def __init__(self, address='localhost', port=DEFAULT_PORT, user=None, password=None, http_handler=None, timeout=None): if isinstance(timeout, (int, long, float)): self._query_timeout = float(timeout) else: self._query_timeout = DEFAULT_TIMEOUT urlo = urlparse.urlparse(address) if urlo.scheme == '': base_url = 'http://' + address + ':' + str(port) self.url = base_url + '/transmission/rpc' else: if urlo.port: self.url = urlo.scheme + '://' + urlo.hostname + ':' + str(urlo.port) + urlo.path else: self.url = urlo.scheme + '://' + urlo.hostname + urlo.path logger.info('Using custom URL "' + self.url + '".') if urlo.username and urlo.password: user = urlo.username password = urlo.password elif urlo.username or urlo.password: logger.warning('Either user or password missing, not using authentication.') if http_handler == None: self.http_handler = DefaultHTTPHandler() else: if hasattr(http_handler, 'set_authentication') and hasattr(http_handler, 'request'): self.http_handler = http_handler else: raise ValueError('Invalid HTTP handler.') if user and password: self.http_handler.set_authentication(self.url, user, password) elif user or password: logger.warning('Either user or password missing, not using authentication.') self._sequence = 0 self.session = Session() self.session_id = 0 self.protocol_version = None self.get_session() self.torrent_get_arguments = get_arguments('torrent-get' , self.rpc_version)
def _http_query(self, query, timeout=None): headers = {'x-transmission-session-id': self.session_id} request_count = 0 if timeout == None: timeout = self._query_timeout while True: 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, error: if error.code == 409: logger.info('Server responded with 409, trying to set session-id.') if request_count > 1: raise TransmissionError('Session ID negotiation failed.', error) if 'x-transmission-session-id' in error.headers: self.session_id = error.headers['x-transmission-session-id'] headers = {'x-transmission-session-id': self.session_id} else: raise TransmissionError('Unknown conflict.', error) else: raise TransmissionError('Request failed.', error) self._debug_httperror(error) request_count = request_count + 1