def _action(self, action, params=None, params_str=None): args = [] if params: for k, v in params.items(): if utorrent.is_list_type(v): for i in v: args.append( "{}={}".format(utorrent._url_quote(str(k)), utorrent._url_quote(self._action_val(i))) ) else: args.append("{}={}".format(utorrent._url_quote(str(k)), utorrent._url_quote(self._action_val(v)))) if params_str: params_str = "&" + params_str else: params_str = "" if action == "list": args.insert(0, "token=" + self._token) args.insert(1, "list=1") section = "gui/" elif action == "proxy": section = "proxy" else: args.insert(0, "token=" + self._token) args.insert(1, "action=" + utorrent._url_quote(str(action))) section = "gui/" return section + "?" + "&".join(args) + params_str
def settings_set( self, settings ): args = [] for k, v in settings.items( ): if isinstance( v, bool ): v = int( v ) args.append( "s={}&v={}".format( utorrent._url_quote( k ), utorrent._url_quote( str( v ) ) ) ) self.do_action( "setsetting", params_str = "&".join( args ) )
def _make_request( self, loc, headers, data = None, retry = True ): last_e = None utserver_retry = False retries = 0 max_retries = self._retry_max if retry else 1 try: while retries < max_retries or utserver_retry: try: self._request.data = data self._connection.request( self._request.get_method( ), self._request.selector + loc, self._request.data, headers ) resp = self._connection.getresponse( ) if resp.status == 400: last_e = utorrent.uTorrentError( resp.read( ).decode( "utf8" ).strip( ) ) # if uTorrent server alpha is bound to the same port as WebUI then it will respond with "invalid request" to the first request in the connection # apparently this is no longer the case, TODO: remove this hack if ( not self._utorrent or type( self._utorrent ) == utorrent.uTorrent.LinuxServer ) and not utserver_retry: utserver_retry = True continue raise last_e elif resp.status == 404 or resp.status == 401: raise utorrent.uTorrentError( "Request {}: {}".format( loc, resp.reason ) ) elif resp.status != 200 and resp.status != 206: raise utorrent.uTorrentError( "{}: {}".format( resp.reason, resp.status ) ) self._cookies.extract_cookies( resp, self._request ) if len( self._cookies ) > 0: self._request.add_header( "Cookie", "; ".join( ["{}={}".format( utorrent._url_quote( c.name ), utorrent._url_quote( c.value ) ) for c in self._cookies] ) ) return resp # retry when utorrent returns bad data except ( http.client.CannotSendRequest, http.client.BadStatusLine ) as e: last_e = e self._connection.close( ) # name resolution failed except socket.gaierror as e: raise utorrent.uTorrentError( e.strerror ) # socket errors except socket.error as e: # retry on timeout if str( e ) == "timed out": # some peculiar handling for timeout error last_e = utorrent.uTorrentError( "Timeout after {} tries".format( max_retries ) ) self._connection.close( ) # retry after pause on specific windows errors elif e.errno == 10053 or e.errno == 10054: # Windows specific socket errors: # 10053 - An established connection was aborted by the software in your host machine # 10054 - An existing connection was forcibly closed by the remote host last_e = e self._connection.close( ) time.sleep( 2 ) elif e.errno == errno.ECONNREFUSED or e.errno == errno.ECONNRESET or errno == errno.EHOSTUNREACH: raise utorrent.uTorrentError( e.strerror ) else: raise e retries += 1 if last_e: raise last_e except Exception as e: self._connection.close( ) raise e return None
def _action(self, action, params=None, params_str=None): args = [] if params: for k, v in params.items(): if utorrent.is_list_type(v): for i in v: args.append("{}={}".format( utorrent._url_quote(str(k)), utorrent._url_quote(self._action_val(i)))) else: args.append("{}={}".format( utorrent._url_quote(str(k)), utorrent._url_quote(self._action_val(v)))) if params_str: params_str = "&" + params_str else: params_str = "" if action == "list": args.insert(0, "token=" + self._token) args.insert(1, "list=1") section = "gui/" elif action == "proxy": section = "proxy" else: args.insert(0, "token=" + self._token) args.insert(1, "action=" + utorrent._url_quote(str(action))) section = "gui/" return section + "?" + "&".join(args) + params_str
def settings_set(self, settings): args = [] for k, v in settings.items(): if isinstance(v, bool): v = int(v) args.append("s={}&v={}".format(utorrent._url_quote(k), utorrent._url_quote(str(v)))) self.do_action("setsetting", params_str="&".join(args))
def torrent_get_magnet( self, torrents, self_tracker = False ): out = { } tors = self.torrent_list( ) for t in torrents: t = t.upper( ) self.check_hash( t ) if t in tors: if self_tracker: trackers = [self._connection.request_obj.get_full_url( ) + "announce"] else: trackers = self.torrent_info( t )[t].trackers trackers = "&".join( [""] + ["tr=" + utorrent._url_quote( t ) for t in trackers] ) out[t] = "magnet:?xt=urn:btih:{}&dn={}{}".format( utorrent._url_quote( t.lower( ) ), utorrent._url_quote( tors[t].name ), trackers ) return out
def torrent_set_props( self, props ): """ [ { "hash" : [ { "prop_name" : "prop_value" }, ... ] }, ... ] """ args = [] for arg in props: for hsh, t_prop in arg.items( ): for name, value in t_prop.items( ): args.append( "hash={}&s={}&v={}".format( utorrent._url_quote( hsh ), utorrent._url_quote( name ), utorrent._url_quote( str( value ) ) ) ) self.do_action( "setprops", params_str = "&".join( args ) )
def torrent_set_props(self, props): """ [ { "hash" : [ { "prop_name" : "prop_value" }, ... ] }, ... ] """ args = [] for arg in props: for hsh, t_prop in arg.items(): for name, value in t_prop.items(): args.append("hash={}&s={}&v={}".format( utorrent._url_quote(hsh), utorrent._url_quote(name), utorrent._url_quote(str(value)))) self.do_action("setprops", params_str="&".join(args))
def torrent_get_magnet(self, torrents, self_tracker=False): out = {} tors = self.torrent_list() for t in torrents: t = t.upper() self.check_hash(t) if t in tors: if self_tracker: trackers = [ self._connection.request_obj.get_full_url() + "announce" ] else: trackers = self.torrent_info(t)[t].trackers trackers = "&".join( [""] + ["tr=" + utorrent._url_quote(t) for t in trackers]) out[t] = "magnet:?xt=urn:btih:{}&dn={}{}".format( utorrent._url_quote(t.lower()), utorrent._url_quote(tors[t].name), trackers) return out
def _create_torrent_upload( self, torrent_data, torrent_filename ): out = "\r\n".join( ( "--{{BOUNDARY}}", 'Content-Disposition: form-data; name="torrent_file"; filename="{}"'.format( utorrent._url_quote( torrent_filename ) ), "Content-Type: application/x-bittorrent", "", torrent_data.decode( "latin1" ), "--{{BOUNDARY}}", "", ) ) return out
def _create_torrent_upload(self, torrent_data, torrent_filename): out = "\r\n".join(( "--{{BOUNDARY}}", 'Content-Disposition: form-data; name="torrent_file"; filename="{}"' .format(utorrent._url_quote(torrent_filename)), "Content-Type: application/x-bittorrent", "", torrent_data.decode("latin1"), "--{{BOUNDARY}}", "", )) return out
def file_set_priority( self, files ): args = [] filecount_cache = { } for hsh, prio in files.items( ): parent_hash, index = self.parse_hash_prop( hsh ) if not isinstance( prio, utorrent.priority.Priority ): prio = utorrent.priority.Priority( prio ) if index is None: if not parent_hash in filecount_cache: filecount_cache[parent_hash] = len( self.file_list( parent_hash )[parent_hash] ) for i in range( filecount_cache[parent_hash] ): args.append( "hash={}&p={}&f={}".format( utorrent._url_quote( parent_hash ), utorrent._url_quote( str( prio.value ) ), utorrent._url_quote( str( i ) ) ) ) else: args.append( "hash={}&p={}&f={}".format( utorrent._url_quote( parent_hash ), utorrent._url_quote( str( prio.value ) ), utorrent._url_quote( str( index ) ) ) ) self.do_action( "setprio", params_str = "&".join( args ) )
def file_set_priority(self, files): args = [] filecount_cache = {} for hsh, prio in files.items(): parent_hash, index = self.parse_hash_prop(hsh) if not isinstance(prio, utorrent.priority.Priority): prio = utorrent.priority.Priority(prio) if index is None: if not parent_hash in filecount_cache: filecount_cache[parent_hash] = len( self.file_list(parent_hash)[parent_hash]) for i in range(filecount_cache[parent_hash]): args.append("hash={}&p={}&f={}".format( utorrent._url_quote(parent_hash), utorrent._url_quote(str(prio.value)), utorrent._url_quote(str(i)))) else: args.append("hash={}&p={}&f={}".format( utorrent._url_quote(parent_hash), utorrent._url_quote(str(prio.value)), utorrent._url_quote(str(index)))) self.do_action("setprio", params_str="&".join(args))