6 changed files with 180 additions and 0 deletions
@ -0,0 +1 @@ |
|||
__version__ = '0.1' |
@ -0,0 +1,62 @@ |
|||
from urlparse import urljoin |
|||
import logging |
|||
|
|||
log = logging.getLogger(__name__) |
|||
|
|||
|
|||
class Base(object): |
|||
properties = {} |
|||
|
|||
def __init__(self, url, session, client=None): |
|||
self._client = client |
|||
self._url = url |
|||
self._session = session |
|||
|
|||
@staticmethod |
|||
def _convert(response, response_type): |
|||
if response_type == 'json': |
|||
try: |
|||
return response.json() |
|||
except ValueError: |
|||
pass |
|||
|
|||
return response |
|||
|
|||
def _get(self, path='', response_type='json', **kwargs): |
|||
r = self._session.get(urljoin(self._url, path), **kwargs) |
|||
return self._convert(r, response_type) |
|||
|
|||
def _post(self, path='', response_type='json', data=None, **kwargs): |
|||
r = self._session.post(urljoin(self._url, path), data, **kwargs) |
|||
return self._convert(r, response_type) |
|||
|
|||
def _fill(self, data): |
|||
for key, value in data.items(): |
|||
if self.set_property(self, key, value): |
|||
continue |
|||
|
|||
log.debug('%s is missing item with key "%s" and value %s', self.__class__, key, repr(value)) |
|||
|
|||
@classmethod |
|||
def parse(cls, client, data): |
|||
obj = cls(client._url, client._session, client) |
|||
obj._fill(data) |
|||
|
|||
return obj |
|||
|
|||
@classmethod |
|||
def set_property(cls, obj, key, value): |
|||
prop = cls.properties.get(key, {}) |
|||
|
|||
if prop.get('key'): |
|||
key = prop['key'] |
|||
|
|||
if not hasattr(obj, key): |
|||
return False |
|||
|
|||
|
|||
if prop.get('parse'): |
|||
value = prop['parse'](value) |
|||
|
|||
setattr(obj, key, value) |
|||
return True |
@ -0,0 +1,33 @@ |
|||
from qbittorrent.base import Base |
|||
from qbittorrent.torrent import Torrent |
|||
from requests import Session |
|||
from requests.auth import HTTPDigestAuth |
|||
|
|||
|
|||
class QBittorrentClient(Base): |
|||
def __init__(self, url, username=None, password=None): |
|||
super(QBittorrentClient, self).__init__(url, Session()) |
|||
|
|||
if username and password: |
|||
self._session.auth = HTTPDigestAuth(username, password) |
|||
|
|||
def test_connection(self): |
|||
r = self._get(response_type='response') |
|||
|
|||
return r.status_code == 200 |
|||
|
|||
def add_file(self, file): |
|||
self._post('command/upload', files={'torrent': file}) |
|||
|
|||
def add_url(self, urls): |
|||
if type(urls) is not list: |
|||
urls = [urls] |
|||
|
|||
urls = '%0A'.join(urls) |
|||
|
|||
self._post('command/download', data={'urls': urls}) |
|||
|
|||
def get_torrents(self): |
|||
r = self._get('json/torrents') |
|||
|
|||
return [Torrent.parse(self, x) for x in r] |
@ -0,0 +1,13 @@ |
|||
from qbittorrent.base import Base |
|||
|
|||
|
|||
class File(Base): |
|||
def __init__(self, url, session, client=None): |
|||
super(File, self).__init__(url, session, client) |
|||
|
|||
self.name = None |
|||
|
|||
self.progress = None |
|||
self.priority = None |
|||
|
|||
self.is_seed = None |
@ -0,0 +1,7 @@ |
|||
def try_convert(value, to_type, default=None): |
|||
try: |
|||
return to_type(value) |
|||
except ValueError: |
|||
return default |
|||
except TypeError: |
|||
return default |
@ -0,0 +1,64 @@ |
|||
from qbittorrent.base import Base |
|||
from qbittorrent.file import File |
|||
from qbittorrent.helpers import try_convert |
|||
|
|||
|
|||
class Torrent(Base): |
|||
properties = { |
|||
'num_seeds': { |
|||
'key': 'seeds', |
|||
'parse': lambda value: try_convert(value, int) |
|||
}, |
|||
'num_leechs': { |
|||
'key': 'leechs', |
|||
'parse': lambda value: try_convert(value, int) |
|||
}, |
|||
'ratio': { |
|||
'parse': lambda value: try_convert(value, float) |
|||
} |
|||
} |
|||
|
|||
def __init__(self, url, session, client=None): |
|||
super(Torrent, self).__init__(url, session, client) |
|||
|
|||
self.hash = None |
|||
self.name = None |
|||
|
|||
self.state = None |
|||
self.ratio = None |
|||
self.progress = None |
|||
self.priority = None |
|||
|
|||
self.seeds = None |
|||
self.leechs = None |
|||
|
|||
# |
|||
# Commands |
|||
# |
|||
|
|||
def pause(self): |
|||
self._post('command/pause', data={'hash': self.hash}) |
|||
|
|||
def resume(self): |
|||
self._post('command/resume', data={'hash': self.hash}) |
|||
|
|||
def remove(self): |
|||
self._post('command/delete', data={'hashes': self.hash}) |
|||
|
|||
def delete(self): |
|||
self._post('command/deletePerm', data={'hashes': self.hash}) |
|||
|
|||
def recheck(self): |
|||
self._post('command/recheck', data={'hash': self.hash}) |
|||
|
|||
# |
|||
# Fetch details |
|||
# |
|||
|
|||
def get_files(self): |
|||
r = self._get('json/propertiesFiles/%s' % self.hash) |
|||
|
|||
return [File.parse(self._client, x) for x in r] |
|||
|
|||
def get_trackers(self): |
|||
pass |
Loading…
Reference in new issue