Updates python-qbittorrent to 0.4.3

This commit is contained in:
Labrys of Knossos 2022-11-28 21:52:04 -05:00
commit 3a2e09c26e
11 changed files with 329 additions and 101 deletions

BIN
libs/common/bin/beet.exe Normal file

Binary file not shown.

Binary file not shown.

Binary file not shown.

BIN
libs/common/bin/mid3cp.exe Normal file

Binary file not shown.

Binary file not shown.

BIN
libs/common/bin/mid3v2.exe Normal file

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

View file

@ -1,6 +1,7 @@
import requests import requests
import json import json
class LoginRequired(Exception): class LoginRequired(Exception):
def __str__(self): def __str__(self):
return 'Please login first.' return 'Please login first.'
@ -8,14 +9,27 @@ class LoginRequired(Exception):
class Client(object): class Client(object):
"""class to interact with qBittorrent WEB API""" """class to interact with qBittorrent WEB API"""
def __init__(self, url): def __init__(self, url, verify=True, timeout=None):
"""
Initialize the client
:param url: Base URL of the qBittorrent WEB API
:param verify: Boolean to specify if SSL verification should be done.
Defaults to True.
:param timeout: How many seconds to wait for the server to send data
before giving up, as a float, or a
`(connect timeout, read timeout)` tuple.
Defaults to None.
"""
if not url.endswith('/'): if not url.endswith('/'):
url += '/' url += '/'
self.url = url self.url = url + 'api/v2/'
self.verify = verify
self.timeout = timeout
session = requests.Session() session = requests.Session()
check_prefs = session.get(url+'api/v2/app/preferences') prefs_url = self.url + 'app/preferences'
check_prefs = session.get(prefs_url, verify=self.verify, timeout=self.timeout)
if check_prefs.status_code == 200: if check_prefs.status_code == 200:
self._is_authenticated = True self._is_authenticated = True
self.session = session self.session = session
@ -23,9 +37,9 @@ class Client(object):
elif check_prefs.status_code == 404: elif check_prefs.status_code == 404:
self._is_authenticated = False self._is_authenticated = False
raise RuntimeError(""" raise RuntimeError("""
This wrapper only supports qBittorrent applications with This wrapper only supports qBittorrent applications
version higher than 4.1.0 (which implemented Web API v2.0). with version higher than 4.1.x.
Please use the latest qBittorrent release. Please use the latest qBittorrent release.
""") """)
else: else:
@ -34,8 +48,10 @@ class Client(object):
def _get(self, endpoint, **kwargs): def _get(self, endpoint, **kwargs):
""" """
Method to perform GET request on the API. Method to perform GET request on the API.
:param endpoint: Endpoint of the API. :param endpoint: Endpoint of the API.
:param kwargs: Other keyword arguments for requests. :param kwargs: Other keyword arguments for requests.
:return: Response of the GET request. :return: Response of the GET request.
""" """
return self._request(endpoint, 'get', **kwargs) return self._request(endpoint, 'get', **kwargs)
@ -43,9 +59,11 @@ class Client(object):
def _post(self, endpoint, data, **kwargs): def _post(self, endpoint, data, **kwargs):
""" """
Method to perform POST request on the API. Method to perform POST request on the API.
:param endpoint: Endpoint of the API. :param endpoint: Endpoint of the API.
:param data: POST DATA for the request. :param data: POST DATA for the request.
:param kwargs: Other keyword arguments for requests. :param kwargs: Other keyword arguments for requests.
:return: Response of the POST request. :return: Response of the POST request.
""" """
return self._request(endpoint, 'post', data, **kwargs) return self._request(endpoint, 'post', data, **kwargs)
@ -53,10 +71,12 @@ class Client(object):
def _request(self, endpoint, method, data=None, **kwargs): def _request(self, endpoint, method, data=None, **kwargs):
""" """
Method to hanle both GET and POST requests. Method to hanle both GET and POST requests.
:param endpoint: Endpoint of the API. :param endpoint: Endpoint of the API.
:param method: Method of HTTP request. :param method: Method of HTTP request.
:param data: POST DATA for the request. :param data: POST DATA for the request.
:param kwargs: Other keyword arguments. :param kwargs: Other keyword arguments.
:return: Response for the request. :return: Response for the request.
""" """
final_url = self.url + endpoint final_url = self.url + endpoint
@ -64,11 +84,12 @@ class Client(object):
if not self._is_authenticated: if not self._is_authenticated:
raise LoginRequired raise LoginRequired
rq = self.session kwargs['verify'] = self.verify
kwargs['timeout'] = self.timeout
if method == 'get': if method == 'get':
request = rq.get(final_url, **kwargs) request = self.session.get(final_url, **kwargs)
else: else:
request = rq.post(final_url, data, **kwargs) request = self.session.post(final_url, data, **kwargs)
request.raise_for_status() request.raise_for_status()
request.encoding = 'utf_8' request.encoding = 'utf_8'
@ -86,17 +107,21 @@ class Client(object):
def login(self, username='admin', password='admin'): def login(self, username='admin', password='admin'):
""" """
Method to authenticate the qBittorrent Client. Method to authenticate the qBittorrent Client.
Declares a class attribute named ``session`` which Declares a class attribute named ``session`` which
stores the authenticated session if the login is correct. stores the authenticated session if the login is correct.
Else, shows the login error. Else, shows the login error.
:param username: Username. :param username: Username.
:param password: Password. :param password: Password.
:return: Response to login request to the API. :return: Response to login request to the API.
""" """
self.session = requests.Session() self.session = requests.Session()
login = self.session.post(self.url+'api/v2/auth/login', login = self.session.post(self.url + 'auth/login',
data={'username': username, data={'username': username,
'password': password}) 'password': password},
verify=self.verify)
if login.text == 'Ok.': if login.text == 'Ok.':
self._is_authenticated = True self._is_authenticated = True
else: else:
@ -106,7 +131,7 @@ class Client(object):
""" """
Logout the current session. Logout the current session.
""" """
response = self._get('api/v2/auth/logout') response = self._get('auth/logout')
self._is_authenticated = False self._is_authenticated = False
return response return response
@ -115,32 +140,55 @@ class Client(object):
""" """
Get qBittorrent version. Get qBittorrent version.
""" """
return self._get('api/v2/app/version') return self._get('app/version')
@property @property
def api_version(self): def api_version(self):
""" """
Get WEB API version. Get WEB API version.
""" """
return self._get('api/v2/app/webapiVersion') return self._get('app/webapiVersion')
def shutdown(self): def shutdown(self):
""" """
Shutdown qBittorrent. Shutdown qBittorrent.
""" """
return self._get('api/v2/app/shutdown') return self._get('app/shutdown')
def get_default_save_path(self):
"""
Get default save path.
"""
return self._get('app/defaultSavePath')
def get_log(self, **params):
"""
Returns a list of log entries matching the supplied params.
:param normal: Include normal messages (default: true).
:param info: Include info messages (default: true).
:param warning: Include warning messages (default: true).
:param critical: Include critical messages (default: true).
:param last_known_id: Exclude messages with "message id" <= last_known_id (default: -1).
:return: list().
For example: qb.get_log(normal='true', info='true')
"""
return self._get('log/main', params=params)
def torrents(self, **filters): def torrents(self, **filters):
""" """
Returns a list of torrents matching the supplied filters. Returns a list of torrents matching the supplied filters.
:param filter: Current status of the torrents. :param filter: Current status of the torrents.
:param category: Fetch all torrents with the supplied label. :param category: Fetch all torrents with the supplied label.
:param sort: Sort torrents by. :param sort: Sort torrents by.
:param reverse: Enable reverse sorting. :param reverse: Enable reverse sorting.
:param limit: Limit the number of torrents returned. :param limit: Limit the number of torrents returned.
:param offset: Set offset (if less than 0, offset from end). :param offset: Set offset (if less than 0, offset from end).
:param hashes: Filter by hashes. Can contain multiple hashes separated by |.
:return: list() of torrent with matching filter. :return: list() of torrent with matching filter.
For example: qb.torrents(filter='downloading', sort='ratio').
""" """
params = {} params = {}
for name, value in filters.items(): for name, value in filters.items():
@ -148,42 +196,65 @@ class Client(object):
name = 'filter' if name == 'status' else name name = 'filter' if name == 'status' else name
params[name] = value params[name] = value
return self._get('api/v2/torrents/info', params=params) return self._get('torrents/info', params=params)
def get_torrent(self, infohash): def get_torrent(self, infohash):
""" """
Get details of the torrent. Get details of the torrent.
:param infohash: INFO HASH of the torrent. :param infohash: INFO HASH of the torrent.
""" """
return self._get('api/v2/torrents/properties', params={'hash': infohash.lower()}) return self._get('torrents/properties?hash=' + infohash.lower())
def get_torrent_trackers(self, infohash): def get_torrent_trackers(self, infohash):
""" """
Get trackers for the torrent. Get trackers for the torrent.
:param infohash: INFO HASH of the torrent. :param infohash: INFO HASH of the torrent.
""" """
return self._get('api/v2/torrents/trackers', params={'hash': infohash.lower()}) return self._get('torrents/trackers?hash=' + infohash.lower())
def get_torrent_webseeds(self, infohash): def get_torrent_webseeds(self, infohash):
""" """
Get webseeds for the torrent. Get webseeds for the torrent.
:param infohash: INFO HASH of the torrent. :param infohash: INFO HASH of the torrent.
""" """
return self._get('api/v2/torrents/webseeds', params={'hash': infohash.lower()}) return self._get('torrents/webseeds?hash=' + infohash.lower())
def get_torrent_files(self, infohash): def get_torrent_files(self, infohash):
""" """
Get list of files for the torrent. Get list of files for the torrent.
:param infohash: INFO HASH of the torrent. :param infohash: INFO HASH of the torrent.
""" """
return self._get('api/v2/torrents/files', params={'hash': infohash.lower()}) return self._get('torrents/files?hash=' + infohash.lower())
def get_torrent_piece_states(self, infohash):
"""
Get list of all pieces (in order) of a specific torrent.
:param infohash: INFO HASH of the torrent.
:return: array of states (integers).
"""
return self._get('torrents/pieceStates?hash=' + infohash.lower())
def get_torrent_piece_hashes(self, infohash):
"""
Get list of all hashes (in order) of a specific torrent.
:param infohash: INFO HASH of the torrent.
:return: array of hashes (strings).
"""
return self._get('torrents/pieceHashes?hash=' + infohash.lower())
@property @property
def global_transfer_info(self): def global_transfer_info(self):
""" """
Get JSON data of the global transfer info of qBittorrent. :return: dict{} of the global transfer info of qBittorrent.
""" """
return self._get('api/v2/transfer/info') return self._get('transfer/info')
@property @property
def preferences(self): def preferences(self):
@ -192,31 +263,43 @@ class Client(object):
Can also be used to assign individual preferences. Can also be used to assign individual preferences.
For setting multiple preferences at once, For setting multiple preferences at once,
see ``set_preferences`` method. see ``set_preferences`` method.
Note: Even if this is a ``property``, Note: Even if this is a ``property``,
to fetch the current preferences dict, you are required to fetch the current preferences dict, you are required
to call it like a bound method. to call it like a bound method.
Wrong:: Wrong::
qb.preferences qb.preferences
Right:: Right::
qb.preferences() qb.preferences()
""" """
prefs = self._get('api/v2/app/preferences') prefs = self._get('app/preferences')
class Proxy(Client): class Proxy(Client):
""" """
Proxy class to to allow assignment of individual preferences. Proxy class to to allow assignment of individual preferences.
this class overrides some methods to ease things. this class overrides some methods to ease things.
Because of this, settings can be assigned like:: Because of this, settings can be assigned like::
In [5]: prefs = qb.preferences() In [5]: prefs = qb.preferences()
In [6]: prefs['autorun_enabled'] In [6]: prefs['autorun_enabled']
Out[6]: True Out[6]: True
In [7]: prefs['autorun_enabled'] = False In [7]: prefs['autorun_enabled'] = False
In [8]: prefs['autorun_enabled'] In [8]: prefs['autorun_enabled']
Out[8]: False Out[8]: False
""" """
def __init__(self, url, prefs, auth, session): def __init__(self, url, prefs, auth, session):
super(Proxy, self).__init__(url) self.url = url
self.prefs = prefs self.prefs = prefs
self._is_authenticated = auth self._is_authenticated = auth
self.session = session self.session = session
@ -233,77 +316,118 @@ class Client(object):
return Proxy(self.url, prefs, self._is_authenticated, self.session) return Proxy(self.url, prefs, self._is_authenticated, self.session)
def sync(self, rid=0): def sync_main_data(self, rid=0):
""" """
Sync the torrents by supplied LAST RESPONSE ID. Sync the torrents main data by supplied LAST RESPONSE ID.
Read more @ https://git.io/fxgB8 Read more @ https://git.io/fxgB8
:param rid: Response ID of last request. :param rid: Response ID of last request.
""" """
return self._get('api/v2/sync/maindata', params={'rid': rid}) return self._get('sync/maindata', params={'rid': rid})
def sync_peers_data(self, infohash, rid=0):
"""
Sync the torrent peers data by supplied LAST RESPONSE ID.
Read more @ https://git.io/fxgBg
:param infohash: INFO HASH of torrent.
:param rid: Response ID of last request.
"""
params = {'hash': infohash.lower(), 'rid': rid}
return self._get('sync/torrentPeers', params=params)
def download_from_link(self, link, **kwargs): def download_from_link(self, link, **kwargs):
""" """
Download torrent using a link. Download torrent using a link.
:param link: URL Link or list of. :param link: URL Link or list of.
:param savepath: Path to download the torrent. :param savepath: Path to download the torrent.
:param category: Label or Category of the torrent(s). :param category: Label or Category of the torrent(s).
:return: Empty JSON data. :return: Empty JSON data.
""" """
# qBittorrent requires adds to be done with multipath/form-data # old:new format
# POST requests for both URLs and .torrent files. Info on this old_arg_map = {'save_path': 'savepath'} # , 'label': 'category'}
# can be found here, and here:
# http://docs.python-requests.org/en/master/user/quickstart/#post-a-multipart-encoded-file # convert old option names to new option names
# http://docs.python-requests.org/en/master/user/advanced/#post-multiple-multipart-encoded-files options = kwargs.copy()
for old_arg, new_arg in old_arg_map.items():
if options.get(old_arg) and not options.get(new_arg):
options[new_arg] = options[old_arg]
if isinstance(link, list): if isinstance(link, list):
links = '\n'.join(link) options['urls'] = "\n".join(link)
else: else:
links = link options['urls'] = link
torrent_data = {}
torrent_data['urls'] = (None, links) # workaround to send multipart/formdata request
for k, v in kwargs.iteritems(): # http://stackoverflow.com/a/23131823/4726598
torrent_data[k] = (None, v) dummy_file = {'_dummy': (None, '_dummy')}
return self._post('api/v2/torrents/add', data=None, files=torrent_data)
return self._post('torrents/add', data=options, files=dummy_file)
def download_from_file(self, file_buffer, **kwargs): def download_from_file(self, file_buffer, **kwargs):
""" """
Download torrent using a file. Download torrent using a file.
:param file_buffer: Single file() buffer or list of. :param file_buffer: Single file() buffer or list of.
:param save_path: Path to download the torrent. :param save_path: Path to download the torrent.
:param label: Label of the torrent(s). :param label: Label of the torrent(s).
:return: Empty JSON data. :return: Empty JSON data.
""" """
# qBittorrent requires adds to be done with multipath/form-data
# POST requests for both URLs and .torrent files. Info on this
# can be found here, and here:
# http://docs.python-requests.org/en/master/user/quickstart/#post-a-multipart-encoded-file
# http://docs.python-requests.org/en/master/user/advanced/#post-multiple-multipart-encoded-files
if isinstance(file_buffer, list): if isinstance(file_buffer, list):
torrent_data = [] torrent_files = {}
for f in file_buffer: for i, f in enumerate(file_buffer):
fname = f.name torrent_files.update({'torrents%s' % i: f})
torrent_data.append(('torrents', (fname, f)))
else: else:
fname = file_buffer.name torrent_files = {'torrents': file_buffer}
torrent_data = [('torrents', (fname, file_buffer))]
for k, v in kwargs.iteritems():
torrent_data.append((k, (None, v)))
return self._post('api/v2/torrents/add', data=None, files=torrent_data) data = kwargs.copy()
if data.get('save_path'):
data.update({'savepath': data['save_path']})
return self._post('torrents/add', data=data, files=torrent_files)
def add_trackers(self, infohash, trackers): def add_trackers(self, infohash, trackers):
""" """
Add trackers to a torrent. Add trackers to a torrent.
:param infohash: INFO HASH of torrent. :param infohash: INFO HASH of torrent.
:param trackers: Trackers. :param trackers: Trackers.
:note %0A (aka LF newline) between trackers. Ampersand in tracker urls MUST be escaped.
""" """
data = {'hash': infohash.lower(), data = {'hash': infohash.lower(),
'urls': trackers} 'urls': trackers}
return self._post('api/v2/torrents/addTrackers', data=data) return self._post('torrents/addTrackers', data=data)
def set_torrent_location(self, infohash_list, location):
"""
Set the location for the torrent
:param infohash: INFO HASH of torrent.
:param location: /mnt/nfs/media.
"""
data = self._process_infohash_list(infohash_list)
data['location'] = location
return self._post('torrents/setLocation', data=data)
def set_torrent_name(self, infohash, name):
"""
Set the name for the torrent
:param infohash: INFO HASH of torrent.
:param name: Whatever_name_you_want.
"""
data = {'hash': infohash.lower(),
'name': name}
return self._post('torrents/rename', data=data)
@staticmethod @staticmethod
def _process_infohash_list(infohash_list): def _process_infohash_list(infohash_list):
""" """
Method to convert the infohash_list to qBittorrent API friendly values. Method to convert the infohash_list to qBittorrent API friendly values.
:param infohash_list: List of infohash. :param infohash_list: List of infohash.
""" """
if isinstance(infohash_list, list): if isinstance(infohash_list, list):
@ -315,122 +439,193 @@ class Client(object):
def pause(self, infohash): def pause(self, infohash):
""" """
Pause a torrent. Pause a torrent.
:param infohash: INFO HASH of torrent. :param infohash: INFO HASH of torrent.
""" """
return self._post('api/v2/torrents/pause', data={'hashes': infohash.lower()}) return self._post('torrents/pause', data={'hashes': infohash.lower()})
def pause_all(self): def pause_all(self):
""" """
Pause all torrents. Pause all torrents.
""" """
return self._post('api/v2/torrents/pause', data={'hashes': 'all'}) return self._post('torrents/pause', data={'hashes': 'all'})
def pause_multiple(self, infohash_list): def pause_multiple(self, infohash_list):
""" """
Pause multiple torrents. Pause multiple torrents.
:param infohash_list: Single or list() of infohashes. :param infohash_list: Single or list() of infohashes.
""" """
data = self._process_infohash_list(infohash_list) data = self._process_infohash_list(infohash_list)
return self._post('api/v2/torrents/pause', data=data) return self._post('torrents/pause', data=data)
def set_category(self, infohash_list, category): def set_category(self, infohash_list, category):
""" """
Set the category on multiple torrents. Set the category on multiple torrents.
The category must exist before using set_category. As of v2.1.0,the API
returns a 409 Client Error for any valid category name that doesn't
already exist.
:param infohash_list: Single or list() of infohashes. :param infohash_list: Single or list() of infohashes.
:param category: If category is set to empty string '',
the torrent(s) specified is/are removed from all categories.
""" """
data = self._process_infohash_list(infohash_list) data = self._process_infohash_list(infohash_list)
data['category'] = category data['category'] = category
return self._post('api/v2/torrents/setCategory', data=data) return self._post('torrents/setCategory', data=data)
def create_category(self, category):
"""
Create a new category
:param category: category to create
"""
return self._post('torrents/createCategory', data={'category': category.lower()})
def remove_category(self, categories):
"""
Remove categories
:param categories: can contain multiple cateogies separated by \n (%0A urlencoded).
"""
return self._post('torrents/removeCategories', data={'categories': categories})
def resume(self, infohash): def resume(self, infohash):
""" """
Resume a paused torrent. Resume a paused torrent.
:param infohash: INFO HASH of torrent. :param infohash: INFO HASH of torrent.
""" """
return self._post('api/v2/torrents/resume', data={'hashes': infohash.lower()}) return self._post('torrents/resume', data={'hashes': infohash.lower()})
def resume_all(self): def resume_all(self):
""" """
Resume all torrents. Resume all torrents.
""" """
return self._get('api/v2/torrents/resume', data={'hashes': 'all'}) return self._post('torrents/resume', data={'hashes': 'all'})
def resume_multiple(self, infohash_list): def resume_multiple(self, infohash_list):
""" """
Resume multiple paused torrents. Resume multiple paused torrents.
:param infohash_list: Single or list() of infohashes. :param infohash_list: Single or list() of infohashes.
""" """
data = self._process_infohash_list(infohash_list) data = self._process_infohash_list(infohash_list)
return self._post('api/v2/torrents/resume', data=data) return self._post('torrents/resume', data=data)
def delete(self, infohash_list): def delete(self, infohash_list):
""" """
Delete torrents. Delete torrents. Does not remove files.
:param infohash_list: Single or list() of infohashes. :param infohash_list: Single or list() of infohashes.
""" """
data = self._process_infohash_list(infohash_list) return self._delete(infohash_list)
data['deleteFiles'] = 'false'
return self._post('api/v2/torrents/delete', data=data) def delete_all(self):
"""
Delete all torrents. Does not remove files.
"""
return self._delete('all')
def delete_permanently(self, infohash_list): def delete_permanently(self, infohash_list):
""" """
Permanently delete torrents. Permanently delete torrents. Removes files.
*** WARNING : This will instruct qBittorrent to delete files
*** from your hard disk. Use with caution.
:param infohash_list: Single or list() of infohashes. :param infohash_list: Single or list() of infohashes.
""" """
return self._delete(infohash_list, True)
def delete_all_permanently(self):
"""
Permanently delete torrents.
"""
return self._delete('all', True)
def _delete(self, infohash_list, delete_files=False):
"""
Delete torrents.
:param infohash_list: Single or list() of infohashes.
:param delete_files: Whether to delete files along with torrent.
"""
data = self._process_infohash_list(infohash_list) data = self._process_infohash_list(infohash_list)
data['deleteFiles'] = 'true' data['deleteFiles'] = json.dumps(delete_files)
return self._post('api/v2/torrents/delete', data=data) return self._post('torrents/delete', data=data)
def recheck(self, infohash_list): def recheck(self, infohash_list):
""" """
Recheck torrents. Recheck torrents.
:param infohash_list: Single or list() of infohashes. :param infohash_list: Single or list() of infohashes.
""" """
data = self._process_infohash_list(infohash_list) data = self._process_infohash_list(infohash_list)
return self._post('api/v2/torrents/recheck', data=data) return self._post('torrents/recheck', data=data)
def recheck_all(self):
"""
Recheck all torrents.
"""
return self._post('torrents/recheck', data={'hashes': 'all'})
def reannounce(self, infohash_list):
"""
Recheck all torrents.
:param infohash_list: Single or list() of infohashes; pass 'all' for all torrents.
"""
data = self._process_infohash_list(infohash_list)
return self._post('torrents/reannounce', data=data)
def increase_priority(self, infohash_list): def increase_priority(self, infohash_list):
""" """
Increase priority of torrents. Increase priority of torrents.
:param infohash_list: Single or list() of infohashes.
:param infohash_list: Single or list() of infohashes; pass 'all' for all torrents.
""" """
data = self._process_infohash_list(infohash_list) data = self._process_infohash_list(infohash_list)
return self._post('api/v2/torrents/increasePrio', data=data) return self._post('torrents/increasePrio', data=data)
def decrease_priority(self, infohash_list): def decrease_priority(self, infohash_list):
""" """
Decrease priority of torrents. Decrease priority of torrents.
:param infohash_list: Single or list() of infohashes.
:param infohash_list: Single or list() of infohashes; pass 'all' for all torrents.
""" """
data = self._process_infohash_list(infohash_list) data = self._process_infohash_list(infohash_list)
return self._post('api/v2/torrents/decreasePrio', data=data) return self._post('torrents/decreasePrio', data=data)
def set_max_priority(self, infohash_list): def set_max_priority(self, infohash_list):
""" """
Set torrents to maximum priority level. Set torrents to maximum priority level.
:param infohash_list: Single or list() of infohashes.
:param infohash_list: Single or list() of infohashes; pass 'all' for all torrents.
""" """
data = self._process_infohash_list(infohash_list) data = self._process_infohash_list(infohash_list)
return self._post('api/v2/torrents/topPrio', data=data) return self._post('torrents/topPrio', data=data)
def set_min_priority(self, infohash_list): def set_min_priority(self, infohash_list):
""" """
Set torrents to minimum priority level. Set torrents to minimum priority level.
:param infohash_list: Single or list() of infohashes.
:param infohash_list: Single or list() of infohashes; pass 'all' for all torrents.
""" """
data = self._process_infohash_list(infohash_list) data = self._process_infohash_list(infohash_list)
return self._post('api/v2/torrents/bottomPrio', data=data) return self._post('torrents/bottomPrio', data=data)
def set_file_priority(self, infohash, file_id, priority): def set_file_priority(self, infohash, file_id, priority):
""" """
Set file of a torrent to a supplied priority level. Set file of a torrent to a supplied priority level.
:param infohash: INFO HASH of torrent. :param infohash: INFO HASH of torrent.
:param file_id: ID of the file to set priority. :param file_id: ID of the file to set priority.
:param priority: Priority level of the file. :param priority: Priority level of the file.
:note Priorities Don't download, Normal, High, Maximum
in 3.2.0-4.1+ are 0, 1, 6, 7 and in 3.1.x are 0, 1, 2, 7
""" """
if priority not in [0, 1, 6, 7]: if priority not in [0, 1, 2, 4, 6, 7]:
raise ValueError("Invalid priority, refer WEB-UI docs for info.") raise ValueError("Invalid priority, refer WEB-UI docs for info.")
elif not isinstance(file_id, int): elif not isinstance(file_id, int):
raise TypeError("File ID must be an int") raise TypeError("File ID must be an int")
@ -439,7 +634,18 @@ class Client(object):
'id': file_id, 'id': file_id,
'priority': priority} 'priority': priority}
return self._post('api/v2/torrents/filePrio', data=data) return self._post('torrents/filePrio', data=data)
def set_automatic_torrent_management(self, infohash_list, enable='false'):
"""
Set the category on multiple torrents.
:param infohash_list: Single or list() of infohashes.
:param enable: is a boolean, affects the torrents listed in infohash_list, default is 'false'
"""
data = self._process_infohash_list(infohash_list)
data['enable'] = enable
return self._post('torrents/setAutoManagement', data=data)
# Get-set global download and upload speed limits. # Get-set global download and upload speed limits.
@ -447,14 +653,15 @@ class Client(object):
""" """
Get global download speed limit. Get global download speed limit.
""" """
return self._get('api/v2/transfer/downloadLimit') return self._get('transfer/downloadLimit')
def set_global_download_limit(self, limit): def set_global_download_limit(self, limit):
""" """
Set global download speed limit. Set global download speed limit.
:param limit: Speed limit in bytes. :param limit: Speed limit in bytes.
""" """
return self._post('api/v2/transfer/setDownloadLimit', data={'limit': limit}) return self._post('transfer/setDownloadLimit', data={'limit': limit})
global_download_limit = property(get_global_download_limit, global_download_limit = property(get_global_download_limit,
set_global_download_limit) set_global_download_limit)
@ -463,14 +670,15 @@ class Client(object):
""" """
Get global upload speed limit. Get global upload speed limit.
""" """
return self._get('api/v2/transfer/uploadLimit') return self._get('transfer/uploadLimit')
def set_global_upload_limit(self, limit): def set_global_upload_limit(self, limit):
""" """
Set global upload speed limit. Set global upload speed limit.
:param limit: Speed limit in bytes. :param limit: Speed limit in bytes.
""" """
return self._post('api/v2/transfer/setUploadLimit', data={'limit': limit}) return self._post('transfer/setUploadLimit', data={'limit': limit})
global_upload_limit = property(get_global_upload_limit, global_upload_limit = property(get_global_upload_limit,
set_global_upload_limit) set_global_upload_limit)
@ -479,56 +687,62 @@ class Client(object):
def get_torrent_download_limit(self, infohash_list): def get_torrent_download_limit(self, infohash_list):
""" """
Get download speed limit of the supplied torrents. Get download speed limit of the supplied torrents.
:param infohash_list: Single or list() of infohashes. :param infohash_list: Single or list() of infohashes.
""" """
data = self._process_infohash_list(infohash_list) data = self._process_infohash_list(infohash_list)
return self._post('api/v2/torrents/downloadLimit', data=data) return self._post('torrents/downloadLimit', data=data)
def set_torrent_download_limit(self, infohash_list, limit): def set_torrent_download_limit(self, infohash_list, limit):
""" """
Set download speed limit of the supplied torrents. Set download speed limit of the supplied torrents.
:param infohash_list: Single or list() of infohashes. :param infohash_list: Single or list() of infohashes.
:param limit: Speed limit in bytes. :param limit: Speed limit in bytes.
""" """
data = self._process_infohash_list(infohash_list) data = self._process_infohash_list(infohash_list)
data.update({'limit': limit}) data.update({'limit': limit})
return self._post('api/v2/torrents/setDownloadLimit', data=data) return self._post('torrents/setDownloadLimit', data=data)
def get_torrent_upload_limit(self, infohash_list): def get_torrent_upload_limit(self, infohash_list):
""" """
Get upoload speed limit of the supplied torrents. Get upoload speed limit of the supplied torrents.
:param infohash_list: Single or list() of infohashes. :param infohash_list: Single or list() of infohashes.
""" """
data = self._process_infohash_list(infohash_list) data = self._process_infohash_list(infohash_list)
return self._post('api/v2/torrents/uploadLimit', data=data) return self._post('torrents/uploadLimit', data=data)
def set_torrent_upload_limit(self, infohash_list, limit): def set_torrent_upload_limit(self, infohash_list, limit):
""" """
Set upload speed limit of the supplied torrents. Set upload speed limit of the supplied torrents.
:param infohash_list: Single or list() of infohashes. :param infohash_list: Single or list() of infohashes.
:param limit: Speed limit in bytes. :param limit: Speed limit in bytes.
""" """
data = self._process_infohash_list(infohash_list) data = self._process_infohash_list(infohash_list)
data.update({'limit': limit}) data.update({'limit': limit})
return self._post('api/v2/torrents/setUploadLimit', data=data) return self._post('torrents/setUploadLimit', data=data)
# setting preferences # setting preferences
def set_preferences(self, **kwargs): def set_preferences(self, **kwargs):
""" """
Set preferences of qBittorrent. Set preferences of qBittorrent.
Read all possible preferences @ https://git.io/fx2Y9 Read all possible preferences @ https://git.io/fx2Y9
:param kwargs: set preferences in kwargs form. :param kwargs: set preferences in kwargs form.
""" """
json_data = "json={}".format(json.dumps(kwargs)) json_data = "json={}".format(json.dumps(kwargs))
headers = {'content-type': 'application/x-www-form-urlencoded'} headers = {'content-type': 'application/x-www-form-urlencoded'}
return self._post('api/v2/app/setPreferences', data=json_data, return self._post('app/setPreferences', data=json_data,
headers=headers) headers=headers)
def get_alternative_speed_status(self): def get_alternative_speed_status(self):
""" """
Get Alternative speed limits. (1/0) Get Alternative speed limits. (1/0)
""" """
return self._get('api/v2/transfer/speedLimitsMode')
return self._get('transfer/speedLimitsMode')
alternative_speed_status = property(get_alternative_speed_status) alternative_speed_status = property(get_alternative_speed_status)
@ -536,30 +750,44 @@ class Client(object):
""" """
Toggle alternative speed limits. Toggle alternative speed limits.
""" """
return self._get('api/v2/transfer/toggleSpeedLimitsMode') return self._get('transfer/toggleSpeedLimitsMode')
def toggle_sequential_download(self, infohash_list): def toggle_sequential_download(self, infohash_list):
""" """
Toggle sequential download in supplied torrents. Toggle sequential download in supplied torrents.
:param infohash_list: Single or list() of infohashes.
:param infohash_list: Single or list() of infohashes; pass 'all' for all torrents.
""" """
data = self._process_infohash_list(infohash_list) data = self._process_infohash_list(infohash_list)
return self._post('api/v2/torrents/toggleSequentialDownload', data=data) return self._post('torrents/toggleSequentialDownload', data=data)
def toggle_first_last_piece_priority(self, infohash_list): def toggle_first_last_piece_priority(self, infohash_list):
""" """
Toggle first/last piece priority of supplied torrents. Toggle first/last piece priority of supplied torrents.
:param infohash_list: Single or list() of infohashes.
:param infohash_list: Single or list() of infohashes; pass 'all' for all torrents.
""" """
data = self._process_infohash_list(infohash_list) data = self._process_infohash_list(infohash_list)
return self._post('api/v2/torrents/toggleFirstLastPiecePrio', data=data) return self._post('torrents/toggleFirstLastPiecePrio', data=data)
def force_start(self, infohash_list, value=True): def force_start(self, infohash_list, value):
""" """
Force start selected torrents. Force start selected torrents.
:param infohash_list: Single or list() of infohashes.
:param infohash_list: Single or list() of infohashes; pass 'all' for all torrents.
:param value: Force start value (bool) :param value: Force start value (bool)
""" """
data = self._process_infohash_list(infohash_list) data = self._process_infohash_list(infohash_list)
data.update({'value': json.dumps(value)}) data.update({'value': json.dumps(value)})
return self._post('api/v2/torrents/setForceStart', data=data) return self._post('torrents/setForceStart', data=data)
def set_super_seeding(self, infohash_list, value):
"""
Set super seeding for selected torrents.
:param infohash_list: Single or list() of infohashes; pass 'all' for all torrents.
:param value: Force start value (bool)
"""
data = self._process_infohash_list(infohash_list)
data.update({'value': json.dumps(value)})
return self._post('torrents/setSuperSeeding', data=data)