Compare commits

...

15 Commits

Author SHA1 Message Date
Ruud Burger 6f36f9175a
Merge pull request #7323 from horganhoozen/patch-1 5 years ago
Ruud Burger ac12dc6b95
Merge pull request #7324 from caramdache/patch-1 5 years ago
Ruud Burger 39be1c9c5e
Merge pull request #7307 from AnilDaoud/qbittorrent 5 years ago
caramdache 938654ef0b
Fix YTS domain (.ag/.am -> .mx) 5 years ago
horganhoozen a27c4d6993
Add YTS Popular Downloads as a Chart Option 5 years ago
AnilDaoud 1f721cad56 Merge remote-tracking branch 'upstream/master' into qbittorrent 5 years ago
Ruud Burger 50a26d640e
Merge pull request #7320 from rhyswilliamsza/develop 5 years ago
Rhys Williams 7c37866b54
Fixed YTS Spelling Issue 5 years ago
AnilDaoud 49acfc5990 Merge branch 'qbittorrent' 5 years ago
AnilDaoud 5bbdc3c078 set category correctly when using qbittorrent 5 years ago
AnilDaoud 51afa53f4a Merge branch 'qbittorrent' 5 years ago
AnilDaoud e9ffef869c do not require auth when calling logout 5 years ago
AnilDaoud 990715c718 Merge branches 'utf8' and 'qbittorrent' 5 years ago
AnilDaoud b4b27f0dfc qbittorrent apiv2 (4.1+) 5 years ago
AnilDaoud b8276a9613 do not choke on utf8 file names 5 years ago
  1. 8
      couchpotato/core/media/_base/providers/torrent/yts.py
  2. 70
      couchpotato/core/media/movie/providers/automation/yifypopular.py
  3. 3
      couchpotato/core/plugins/renamer.py
  4. 2
      libs/qbittorrent/__init__.py
  5. 417
      libs/qbittorrent/client.py

8
couchpotato/core/media/_base/providers/torrent/yts.py

@ -9,10 +9,10 @@ log = CPLog(__name__)
class Base(TorrentMagnetProvider): class Base(TorrentMagnetProvider):
# Only qualities allowed: 720p/1080p/3D - the rest will fail. # Only qualities allowed: 720p/1080p/3D - the rest will fail.
# All YTS.ag torrents are verified # All YTS.mx torrents are verified
urls = { urls = {
'detail': 'https://yts.am/api#list_movies', 'detail': 'https://yts.mx/api#list_movies',
'search': 'https://yts.am/api/v2/list_movies.json?query_term=%s&limit=%s&page=%s' 'search': 'https://yts.mx/api/v2/list_movies.json?query_term=%s&limit=%s&page=%s'
} }
def _search(self, movie, quality, results): def _search(self, movie, quality, results):
@ -77,7 +77,7 @@ config = [{
'tab': 'searcher', 'tab': 'searcher',
'list': 'torrent_providers', 'list': 'torrent_providers',
'name': 'YTS', 'name': 'YTS',
'description': '<a href="https://yts.ag/" target="_blank">YTS</a>', 'description': '<a href="https://yts.mx/" target="_blank">YTS</a>',
'wizard': True, 'wizard': True,
'icon': 'iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAIAAACQkWg2AAACL0lEQVR4AS1SPW/UQBAd23fxne/Ld2dvzvHuzPocEBAKokCBqG' 'icon': 'iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAIAAACQkWg2AAACL0lEQVR4AS1SPW/UQBAd23fxne/Ld2dvzvHuzPocEBAKokCBqG'
'iQ6IgACYmvUKRBFEQgKKGg4BAlUoggggYUEQpSHOI7CIEoQs/fYcbLaU/efTvvvZlnA1qydoxU5kcxX0CkgmQZtPy0hCUjvK+W' 'iQ6IgACYmvUKRBFEQgKKGg4BAlUoggggYUEQpSHOI7CIEoQs/fYcbLaU/efTvvvZlnA1qydoxU5kcxX0CkgmQZtPy0hCUjvK+W'

70
couchpotato/core/media/movie/providers/automation/yifypopular.py

@ -1,6 +1,11 @@
import traceback
import HTMLParser import HTMLParser
from bs4 import BeautifulSoup
from couchpotato import fireEvent from couchpotato import fireEvent
from couchpotato.core.logger import CPLog from couchpotato.core.logger import CPLog
from couchpotato.core.helpers.rss import RSS
from couchpotato.core.helpers.variable import tryInt
from couchpotato.core.media.movie.providers.automation.base import Automation from couchpotato.core.media.movie.providers.automation.base import Automation
log = CPLog(__name__) log = CPLog(__name__)
@ -8,10 +13,13 @@ log = CPLog(__name__)
autoload = 'YTSPopular' autoload = 'YTSPopular'
class YTSPopular(Automation): class YTSPopular(Automation, RSS):
interval = 1800 interval = 1800
url = 'https://yts.lt/' url = 'https://yts.mx/'
rss_url = 'https://yts.mx/rss'
display_url = 'https://yts.mx/'
chart_order = 2
def getIMDBids(self): def getIMDBids(self):
@ -58,7 +66,49 @@ class YTSPopular(Automation):
movies.append(imdb['imdb']) movies.append(imdb['imdb'])
return movies return movies
def getChartList(self):
cache_key = 'yts.charts'
movie_list = {
'name': 'YTS - Popular Downloads',
'url': self.display_url,
'order': self.chart_order,
'list': self.getCache(cache_key) or []
}
if not movie_list['list']:
movie_ids = []
max_items = 10
rss_movies = self.getRSSData(self.rss_url)
for movie in rss_movies:
name = self.getTextElement(movie, 'title').lower()[9:].split("(",1)[0].rstrip()
year = self.getTextElement(movie, 'title').split("(")[1].split(")")[0].rstrip()
if not name.find('/') == -1: # make sure it is not a double movie release
continue
movie = self.search(name, year)
if movie:
if movie.get('imdb') in movie_ids:
continue
is_movie = fireEvent('movie.is_movie', identifier = movie.get('imdb'), single = True)
if not is_movie:
continue
movie_ids.append(movie.get('imdb'))
movie_list['list'].append( movie )
if len(movie_list['list']) >= max_items:
break
if not movie_list['list']:
return
self.setCache(cache_key, movie_list['list'], timeout = 259200)
return [movie_list]
config = [{ config = [{
'name': 'ytspopular', 'name': 'ytspopular',
@ -68,7 +118,7 @@ config = [{
'list': 'automation_providers', 'list': 'automation_providers',
'name': 'ytspopular_automation', 'name': 'ytspopular_automation',
'label': 'YTS Popular', 'label': 'YTS Popular',
'description': 'Imports popular downloas as currently listed on YTS.', 'description': 'Imports popular downloads as currently listed on YTS.',
'options': [ 'options': [
{ {
'name': 'automation_enabled', 'name': 'automation_enabled',
@ -77,5 +127,19 @@ config = [{
}, },
], ],
}, },
{
'tab': 'display',
'list': 'charts_providers',
'name': 'yts_popular_display',
'label': 'YTS',
'description': 'Display <a href="https://yts.mx" target="_blank">Popular Downloads</a> from YTS.MX',
'options': [
{
'name': 'chart_display_enabled',
'default': False,
'type': 'enabler',
},
],
},
], ],
}] }]

3
couchpotato/core/plugins/renamer.py

@ -4,6 +4,7 @@ import re
import shutil import shutil
import time import time
import traceback import traceback
import sys
from couchpotato import get_db from couchpotato import get_db
from couchpotato.api import addApiView from couchpotato.api import addApiView
@ -31,6 +32,8 @@ class Renamer(Plugin):
checking_snatched = False checking_snatched = False
def __init__(self): def __init__(self):
reload(sys)
sys.setdefaultencoding('utf8')
addApiView('renamer.scan', self.scanView, docs = { addApiView('renamer.scan', self.scanView, docs = {
'desc': 'For the renamer to check for new files to rename in a folder', 'desc': 'For the renamer to check for new files to rename in a folder',
'params': { 'params': {

2
libs/qbittorrent/__init__.py

@ -1 +1 @@
__version__ = '0.2' __version__ = '0.3'

417
libs/qbittorrent/client.py

@ -1,24 +1,32 @@
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.'
class QBittorrentClient(object): class QBittorrentClient(object):
"""class to interact with qBittorrent WEB API""" """class to interact with qBittorrent WEB API"""
def __init__(self, url): def __init__(self, url):
if not url.endswith('/'): if not url.endswith('/'):
url += '/' url += '/'
self.url = url self.url = url + 'api/v2/'
session = requests.Session() session = requests.Session()
check_prefs = session.get(url+'query/preferences') check_prefs = session.get(self.url+'app/preferences')
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
elif check_prefs.status_code == 404:
self._is_authenticated = False
raise RuntimeError("""
This wrapper only supports qBittorrent applications
with version higher than 4.1.x.
Please use the latest qBittorrent release.
""")
else: else:
self._is_authenticated = False self._is_authenticated = False
@ -58,7 +66,7 @@ class QBittorrentClient(object):
""" """
final_url = self.url + endpoint final_url = self.url + endpoint
if not self._is_authenticated: if not self._is_authenticated and 'logout' not in endpoint:
raise LoginRequired raise LoginRequired
rq = self.session rq = self.session
@ -68,6 +76,7 @@ class QBittorrentClient(object):
request = rq.post(final_url, data, **kwargs) request = rq.post(final_url, data, **kwargs)
request.raise_for_status() request.raise_for_status()
request.encoding = 'utf_8'
if len(request.text) == 0: if len(request.text) == 0:
data = json.loads('{}') data = json.loads('{}')
@ -93,7 +102,7 @@ class QBittorrentClient(object):
: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+'login', login = self.session.post(self.url+'auth/login',
data={'username': username, data={'username': username,
'password': password}) 'password': password})
if login.text == 'Ok.': if login.text == 'Ok.':
@ -105,7 +114,7 @@ class QBittorrentClient(object):
""" """
Logout the current session. Logout the current session.
""" """
response = self._get('logout') response = self._get('auth/logout')
self._is_authenticated = False self._is_authenticated = False
return response return response
@ -114,70 +123,63 @@ class QBittorrentClient(object):
""" """
Get qBittorrent version. Get qBittorrent version.
""" """
return self._get('version/qbittorrent') 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('version/api') return self._get('app/webapiVersion')
@property def shutdown(self):
def api_min_version(self):
""" """
Get minimum WEB API version. Shutdown qBittorrent.
""" """
return self._get('version/api_min') return self._get('app/shutdown')
def shutdown(self): def get_default_save_path(self):
""" """
Shutdown qBittorrent. Get default save path.
""" """
return self._get('command/shutdown') return self._get('app/defaultSavePath')
def torrents(self, status='active', label='', sort='priority', def get_log(self, **params):
reverse=False, limit=10, offset=0): """
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):
""" """
Returns a list of torrents matching the supplied filters. Returns a list of torrents matching the supplied filters.
:param status: Current status of the torrents. :param filter: Current status of the torrents.
:param label: Fetch all torrents with the supplied label. qbittorrent < 3.3.5 :param category: Fetch all torrents with the supplied label.
:param category: Fetch all torrents with the supplied label. qbittorrent >= 3.3.5
: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).
:return: list() of torrent with matching filter. :return: list() of torrent with matching filter.
For example: qb.torrents(filter='downloading', sort='ratio').
""" """
params = {}
for name, value in filters.items():
# make sure that old 'status' argument still works
name = 'filter' if name == 'status' else name
params[name] = value
STATUS_LIST = ['all', 'downloading', 'completed', return self._get('torrents/info', params=params)
'paused', 'active', 'inactive']
if status not in STATUS_LIST:
raise ValueError("Invalid status.")
if self.api_version < 10:
params = {
'filter': status,
'label': label,
'sort': sort,
'reverse': reverse,
'limit': limit,
'offset': offset
}
elif self.api_version >= 10:
params = {
'filter': status,
'category': label,
'sort': sort,
'reverse': reverse,
'limit': limit,
'offset': offset
}
return self._get('query/torrents', params=params)
def get_torrent(self, infohash): def get_torrent(self, infohash):
""" """
@ -185,7 +187,7 @@ class QBittorrentClient(object):
:param infohash: INFO HASH of the torrent. :param infohash: INFO HASH of the torrent.
""" """
return self._get('query/propertiesGeneral/' + infohash.lower()) return self._get('torrents/properties?hash=' + infohash.lower())
def get_torrent_trackers(self, infohash): def get_torrent_trackers(self, infohash):
""" """
@ -193,7 +195,7 @@ class QBittorrentClient(object):
:param infohash: INFO HASH of the torrent. :param infohash: INFO HASH of the torrent.
""" """
return self._get('query/propertiesTrackers/' + infohash.lower()) return self._get('torrents/trackers?hash=' + infohash.lower())
def get_torrent_webseeds(self, infohash): def get_torrent_webseeds(self, infohash):
""" """
@ -201,7 +203,7 @@ class QBittorrentClient(object):
:param infohash: INFO HASH of the torrent. :param infohash: INFO HASH of the torrent.
""" """
return self._get('query/propertiesWebSeeds/' + infohash.lower()) return self._get('torrents/webseeds?hash=' + infohash.lower())
def get_torrent_files(self, infohash): def get_torrent_files(self, infohash):
""" """
@ -209,14 +211,34 @@ class QBittorrentClient(object):
:param infohash: INFO HASH of the torrent. :param infohash: INFO HASH of the torrent.
""" """
return self._get('query/propertiesFiles/' + 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('query/transferInfo') return self._get('transfer/info')
@property @property
def preferences(self): def preferences(self):
@ -239,7 +261,7 @@ class QBittorrentClient(object):
qb.preferences() qb.preferences()
""" """
prefs = self._get('query/preferences') prefs = self._get('app/preferences')
class Proxy(Client): class Proxy(Client):
""" """
@ -278,51 +300,59 @@ class QBittorrentClient(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 @ http://git.io/vEgXr Read more @ https://git.io/fxgB8
:param rid: Response ID of last request. :param rid: Response ID of last request.
""" """
return self._get('sync/maindata', params={'rid': rid}) return self._get('sync/maindata', params={'rid': rid})
def download_from_link(self, link, def sync_peers_data(self, infohash, rid=0):
save_path=None, label=''): """
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.
"""
return self._get('sync/torrentPeers', params={'hash': infohash.lower(), 'rid': rid})
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 save_path: Path to download the torrent. :param savepath: Path to download the torrent.
:param label: Label of the torrent(s). qbittorrent < 3.3.5 :param category: Label or Category of the torrent(s).
:param category: Label of the torrent(s). qbittorrent >= 3.3.5
:return: Empty JSON data. :return: Empty JSON data.
""" """
if not isinstance(link, list): # old:new format
link = [link] old_arg_map = {'save_path': 'savepath', 'label': 'category'}
data = {'urls': link}
if save_path: # convert old option names to new option names
data.update({'savepath': save_path}) options = kwargs.copy()
if self.api_version < 10 and label: for old_arg, new_arg in old_arg_map.items():
data.update({'label': label}) if options.get(old_arg) and not options.get(new_arg):
options[new_arg] = options[old_arg]
elif self.api_version >= 10 and label: options['urls'] = link
data.update({'category': label})
# workaround to send multipart/formdata request
# http://stackoverflow.com/a/23131823/4726598
dummy_file = {'_dummy': (None, '_dummy')}
return self._post('command/download', data=data) return self._post('torrents/add', data=options, files=dummy_file)
def download_from_file(self, file_buffer, def download_from_file(self, file_buffer, **kwargs):
save_path=None, label=''):
""" """
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). qbittorrent < 3.3.5 :param label: Label of the torrent(s).
:param category: Label of the torrent(s). qbittorrent >= 3.3.5
:return: Empty JSON data. :return: Empty JSON data.
""" """
@ -330,21 +360,17 @@ class QBittorrentClient(object):
torrent_files = {} torrent_files = {}
for i, f in enumerate(file_buffer): for i, f in enumerate(file_buffer):
torrent_files.update({'torrents%s' % i: f}) torrent_files.update({'torrents%s' % i: f})
print torrent_files
else: else:
torrent_files = {'torrents': file_buffer} torrent_files = {'torrents': file_buffer}
data = {} data = kwargs.copy()
if save_path: if data.get('save_path'):
data.update({'savepath': save_path}) data.update({'savepath': data['save_path']})
if self.api_version < 10 and label: if data.get('label'):
data.update({'label': label}) data.update({'category': data['label']})
elif self.api_version >= 10 and label: return self._post('torrents/add', data=data, files=torrent_files)
data.update({'category': label})
return self._post('command/upload', data=data, files=torrent_files)
def add_trackers(self, infohash, trackers): def add_trackers(self, infohash, trackers):
""" """
@ -352,13 +378,36 @@ class QBittorrentClient(object):
: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('command/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.
@ -376,13 +425,13 @@ class QBittorrentClient(object):
:param infohash: INFO HASH of torrent. :param infohash: INFO HASH of torrent.
""" """
return self._post('command/pause', data={'hash': 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._get('command/pauseAll') return self._post('torrents/pause', data={'hashes': 'all'})
def pause_multiple(self, infohash_list): def pause_multiple(self, infohash_list):
""" """
@ -390,8 +439,40 @@ class QBittorrentClient(object):
: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('command/pauseAll', data=data) return self._post('torrents/pause', data=data)
def set_category(self, infohash_list, category):
"""
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 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['category'] = category
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):
""" """
@ -399,13 +480,13 @@ class QBittorrentClient(object):
:param infohash: INFO HASH of torrent. :param infohash: INFO HASH of torrent.
""" """
return self._post('command/resume', data={'hash': 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('command/resumeAll') return self._post('torrents/resume', data={'hashes': 'all'})
def resume_multiple(self, infohash_list): def resume_multiple(self, infohash_list):
""" """
@ -413,8 +494,8 @@ class QBittorrentClient(object):
: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('command/resumeAll', data=data) return self._post('torrents/resume', data=data)
def delete(self, infohash_list): def delete(self, infohash_list):
""" """
@ -422,8 +503,16 @@ class QBittorrentClient(object):
: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('command/delete', data=data) data['deleteFiles'] = 'false'
return self._post('torrents/delete', data=data)
def delete_all(self):
"""
Delete all torrents.
"""
return self._post('torrents/delete', data={'hashes': 'all'})
def delete_permanently(self, infohash_list): def delete_permanently(self, infohash_list):
""" """
@ -431,8 +520,9 @@ class QBittorrentClient(object):
: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('command/deletePerm', data=data) data['deleteFiles'] = 'true'
return self._post('torrents/delete', data=data)
def recheck(self, infohash_list): def recheck(self, infohash_list):
""" """
@ -440,44 +530,60 @@ class QBittorrentClient(object):
: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('command/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('command/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('command/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('command/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('command/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):
""" """
@ -486,8 +592,9 @@ class QBittorrentClient(object):
: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 priority 4 is no priority set
""" """
if priority not in [0, 1, 2, 7]: if priority not in [0, 1, 2, 4, 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")
@ -496,7 +603,18 @@ class QBittorrentClient(object):
'id': file_id, 'id': file_id,
'priority': priority} 'priority': priority}
return self._post('command/setFilePrio', 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.
@ -504,7 +622,7 @@ class QBittorrentClient(object):
""" """
Get global download speed limit. Get global download speed limit.
""" """
return self._get('command/getGlobalDlLimit') return self._get('transfer/downloadLimit')
def set_global_download_limit(self, limit): def set_global_download_limit(self, limit):
""" """
@ -512,7 +630,7 @@ class QBittorrentClient(object):
:param limit: Speed limit in bytes. :param limit: Speed limit in bytes.
""" """
return self._post('command/setGlobalDlLimit', 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)
@ -521,7 +639,7 @@ class QBittorrentClient(object):
""" """
Get global upload speed limit. Get global upload speed limit.
""" """
return self._get('command/getGlobalUpLimit') return self._get('transfer/uploadLimit')
def set_global_upload_limit(self, limit): def set_global_upload_limit(self, limit):
""" """
@ -529,7 +647,7 @@ class QBittorrentClient(object):
:param limit: Speed limit in bytes. :param limit: Speed limit in bytes.
""" """
return self._post('command/setGlobalUpLimit', 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)
@ -541,8 +659,8 @@ class QBittorrentClient(object):
: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('command/getTorrentsDlLimit', 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):
""" """
@ -551,9 +669,9 @@ class QBittorrentClient(object):
: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('command/setTorrentsDlLimit', 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):
""" """
@ -561,8 +679,8 @@ class QBittorrentClient(object):
: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('command/getTorrentsUpLimit', 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):
""" """
@ -571,28 +689,30 @@ class QBittorrentClient(object):
: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('command/setTorrentsUpLimit', 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 @ http://git.io/vEgDQ 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('command/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('command/alternativeSpeedLimitsEnabled') # headers = {'content-type': 'application/x-www-form-urlencoded'}
return self._get('transfer/speedLimitsMode')
alternative_speed_status = property(get_alternative_speed_status) alternative_speed_status = property(get_alternative_speed_status)
@ -600,33 +720,44 @@ class QBittorrentClient(object):
""" """
Toggle alternative speed limits. Toggle alternative speed limits.
""" """
return self._get('command/toggleAlternativeSpeedLimits') 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('command/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('command/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=False):
""" """
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), default is false
"""
data = self._process_infohash_list(infohash_list)
data.update({'value': json.dumps(value)})
return self._post('torrents/setForceStart', data=data)
def set_super_seeding(self, infohash_list, value=False):
"""
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), default is false
""" """
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('command/setForceStart', data=data) return self._post('torrents/setSuperSeeding', data=data)

Loading…
Cancel
Save