added qbittorrent-python
This commit is contained in:
@@ -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
|
||||||
Reference in New Issue
Block a user