diff --git a/libs/rtorrent/__init__.py b/libs/rtorrent/__init__.py index 2c0f3fa..4aec991 100755 --- a/libs/rtorrent/__init__.py +++ b/libs/rtorrent/__init__.py @@ -22,8 +22,8 @@ import os.path import time import xmlrpclib -from rtorrent.common import find_torrent, \ - is_valid_port, convert_version_tuple_to_str +from rtorrent.common import find_torrent, join_uri, \ + update_uri, is_valid_port, convert_version_tuple_to_str from rtorrent.lib.torrentparser import TorrentParser from rtorrent.lib.xmlrpc.http import HTTPServerProxy from rtorrent.lib.xmlrpc.scgi import SCGIServerProxy @@ -48,18 +48,18 @@ class RTorrent: def __init__(self, uri, username=None, password=None, verify=False, sp=None, sp_kwargs=None): - self.uri = uri # : From X{__init__(self, url)} + self.uri = self._transform_uri(uri) # : From X{__init__(self, url)} self.username = username self.password = password - self.schema = urllib.splittype(uri)[0] + self.scheme = urllib.splittype(self.uri)[0] if sp: self.sp = sp - elif self.schema in ['http', 'https']: + elif self.scheme in ['http', 'https']: self.sp = HTTPServerProxy - elif self.schema == 'scgi': + elif self.scheme == 'scgi': self.sp = SCGIServerProxy else: raise NotImplementedError() @@ -74,10 +74,23 @@ class RTorrent: if verify is True: self._verify_conn() + def _transform_uri(self, uri): + scheme = urllib.splittype(uri)[0] + + if scheme == 'httprpc' or scheme.startswith('httprpc+'): + # Try find HTTPRPC transport (token after '+' in 'httprpc+https'), otherwise assume HTTP + transport = scheme[scheme.index('+') + 1:] if '+' in scheme else 'http' + + # Transform URI with new path and scheme + uri = join_uri(uri, 'plugins/httprpc/action.php', construct=False) + return update_uri(uri, scheme=transport) + + return uri + def _get_conn(self): """Get ServerProxy instance""" if self.username is not None and self.password is not None: - if self.schema == 'scgi': + if self.scheme == 'scgi': raise NotImplementedError() return self.sp( diff --git a/libs/rtorrent/common.py b/libs/rtorrent/common.py index 371c71c..668865b 100755 --- a/libs/rtorrent/common.py +++ b/libs/rtorrent/common.py @@ -17,7 +17,8 @@ # LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION # OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION # WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - +import urlparse +import os from rtorrent.compat import is_py3 @@ -84,3 +85,67 @@ def safe_repr(fmt, *args, **kwargs): return out.encode("utf-8") else: return fmt.format(*args, **kwargs) + + +def split_path(path): + fragments = path.split('/') + + if len(fragments) == 1: + return fragments + + if not fragments[-1]: + return fragments[:-1] + + return fragments + + +def join_path(base, path): + # Return if we have a new absolute path + if os.path.isabs(path): + return path + + # non-absolute base encountered + if base and not os.path.isabs(base): + raise NotImplementedError() + + return '/'.join(split_path(base) + split_path(path)) + + +def join_uri(base, uri, construct=True): + p_uri = urlparse.urlparse(uri) + + # Return if there is nothing to join + if not p_uri.path: + return base + + scheme, netloc, path, params, query, fragment = urlparse.urlparse(base) + + # Switch to 'uri' parts + _, _, _, params, query, fragment = p_uri + + path = join_path(path, p_uri.path) + + result = urlparse.ParseResult(scheme, netloc, path, params, query, fragment) + + if not construct: + return result + + # Construct from parts + return urlparse.urlunparse(result) + + +def update_uri(uri, construct=True, **kwargs): + if isinstance(uri, urlparse.ParseResult): + uri = dict(uri._asdict()) + + if type(uri) is not dict: + raise ValueError("Unknown URI type") + + uri.update(kwargs) + + result = urlparse.ParseResult(**uri) + + if not construct: + return result + + return urlparse.urlunparse(result)