From 30a1789809f8696a6617a0e3b965b1f98d6504ac Mon Sep 17 00:00:00 2001 From: Labrys of Knossos Date: Sun, 16 Dec 2018 11:31:00 -0500 Subject: [PATCH] Update transmissionrpc to 0.11 Also updates: - six-1.12.0 --- libs/transmissionrpc/client.py | 164 +++++---- libs/transmissionrpc/constants.py | 507 +++++++++++++--------------- libs/transmissionrpc/error.py | 22 +- libs/transmissionrpc/httphandler.py | 29 +- libs/transmissionrpc/session.py | 9 +- libs/transmissionrpc/torrent.py | 61 ++-- libs/transmissionrpc/utils.py | 58 ++-- 7 files changed, 394 insertions(+), 456 deletions(-) diff --git a/libs/transmissionrpc/client.py b/libs/transmissionrpc/client.py index c675c59f..3f726894 100644 --- a/libs/transmissionrpc/client.py +++ b/libs/transmissionrpc/client.py @@ -2,25 +2,25 @@ # Copyright (c) 2008-2013 Erik Svensson # Licensed under the MIT license. +import re, time, operator, warnings, os import base64 import json -import operator -import os -import re -import time -import warnings -from six import PY3, integer_types, iteritems, string_types -from six.moves.urllib_parse import urlparse -from six.moves.urllib_request import urlopen +from transmissionrpc.constants import DEFAULT_PORT, DEFAULT_TIMEOUT +from transmissionrpc.error import TransmissionError, HTTPHandlerError +from transmissionrpc.utils import LOGGER, get_arguments, make_rpc_name, argument_value_convert, rpc_bool +from transmissionrpc.httphandler import DefaultHTTPHandler +from transmissionrpc.torrent import Torrent +from transmissionrpc.session import Session -from .constants import DEFAULT_PORT, DEFAULT_TIMEOUT -from .error import HTTPHandlerError, TransmissionError -from .httphandler import DefaultHTTPHandler -from .session import Session -from .torrent import Torrent -from .utils import LOGGER, argument_value_convert, get_arguments, make_rpc_name, rpc_bool +from six import PY3, integer_types, string_types, iteritems +if PY3: + from urllib.parse import urlparse + from urllib.request import urlopen +else: + from urlparse import urlparse + from urllib2 import urlopen def debug_httperror(error): """ @@ -45,7 +45,6 @@ def debug_httperror(error): ) ) - def parse_torrent_id(arg): """Parse an torrent id or torrent hashString.""" torrent_id = None @@ -59,7 +58,7 @@ def parse_torrent_id(arg): elif isinstance(arg, string_types): try: torrent_id = int(arg) - if torrent_id >= 2 ** 31: + if torrent_id >= 2**31: torrent_id = None except (ValueError, TypeError): pass @@ -72,7 +71,6 @@ def parse_torrent_id(arg): pass return torrent_id - def parse_torrent_ids(args): """ Take things and make them valid torrent identifiers @@ -100,20 +98,19 @@ def parse_torrent_ids(args): except ValueError: pass if not addition: - raise ValueError('Invalid torrent id, {item!r}'.format(item=item)) + raise ValueError('Invalid torrent id, \"%s\"' % item) ids.extend(addition) elif isinstance(args, (list, tuple)): for item in args: ids.extend(parse_torrent_ids(item)) else: torrent_id = parse_torrent_id(args) - if torrent_id is None: + if torrent_id == None: raise ValueError('Invalid torrent id') else: ids = [torrent_id] return ids - """ Torrent ids @@ -128,27 +125,26 @@ possible to provide a argument called ``timeout``. Timeout is only effective when using Python 2.6 or later and the default timeout is 30 seconds. """ - class Client(object): """ Client is the class handling the Transmission JSON-RPC client protocol. """ - def __init__(self, address='localhost', port=DEFAULT_PORT, user=None, password=None, http_handler=None, - timeout=None): + def __init__(self, address='localhost', port=DEFAULT_PORT, user=None, password=None, http_handler=None, timeout=None): if isinstance(timeout, (integer_types, float)): self._query_timeout = float(timeout) else: self._query_timeout = DEFAULT_TIMEOUT urlo = urlparse(address) - if not urlo.scheme: - self.url = 'http://{host}:{port}/transmission/rpc/'.format(host=address, port=port) + if urlo.scheme == '': + base_url = 'http://' + address + ':' + str(port) + self.url = base_url + '/transmission/rpc' else: if urlo.port: - self.url = '{url.scheme}://{url.hostname}:{url.port}{url.path}'.format(url=urlo) + self.url = urlo.scheme + '://' + urlo.hostname + ':' + str(urlo.port) + urlo.path else: - self.url = '{url.scheme}://{url.hostname}{url.path}'.format(url=urlo) - LOGGER.info('Using custom URL {url!r}.'.format(url=self.url)) + self.url = urlo.scheme + '://' + urlo.hostname + urlo.path + LOGGER.info('Using custom URL "' + self.url + '".') if urlo.username and urlo.password: user = urlo.username password = urlo.password @@ -204,8 +200,7 @@ class Client(object): if timeout is None: timeout = self._query_timeout while True: - LOGGER.debug( - json.dumps({'url': self.url, 'headers': headers, 'query': query, 'timeout': timeout}, indent=2)) + LOGGER.debug(json.dumps({'url': self.url, 'headers': headers, 'query': query, 'timeout': timeout}, indent=2)) try: result = self.http_handler.request(self.url, query, headers, timeout) break @@ -245,25 +240,26 @@ class Client(object): elif require_ids: raise ValueError('request require ids') - query = json.dumps({'tag': self._sequence, 'method': method, 'arguments': arguments}) + query = json.dumps({'tag': self._sequence, 'method': method + , 'arguments': arguments}) self._sequence += 1 start = time.time() http_data = self._http_query(query, timeout) elapsed = time.time() - start - LOGGER.info('http request took {time:.3f} s'.format(time=elapsed)) + LOGGER.info('http request took %.3f s' % (elapsed)) try: data = json.loads(http_data) except ValueError as error: - LOGGER.error('Error: {msg}'.format(msg=error)) - LOGGER.error('Request: {request!r}'.format(request=query)) - LOGGER.error('HTTP data: {data!r}'.format(data=http_data)) + LOGGER.error('Error: ' + str(error)) + LOGGER.error('Request: \"%s\"' % (query)) + LOGGER.error('HTTP data: \"%s\"' % (http_data)) raise LOGGER.debug(json.dumps(data, indent=2)) if 'result' in data: if data['result'] != 'success': - raise TransmissionError('Query failed with result {result!r}.'.format(result=data['result'])) + raise TransmissionError('Query failed with result \"%s\".' % (data['result'])) else: raise TransmissionError('Query failed without result.') @@ -347,9 +343,8 @@ class Client(object): Add a warning to the log if the Transmission RPC version is lower then the provided version. """ if self.rpc_version < version: - LOGGER.warning('Using feature not supported by server. ' - 'RPC version for server {x}, feature introduced in {y}.'.format - (x=self.rpc_version, y=version)) + LOGGER.warning('Using feature not supported by server. RPC version for server %d, feature introduced in %d.' + % (self.rpc_version, version)) def add_torrent(self, torrent, timeout=None, **kwargs): """ @@ -409,8 +404,11 @@ class Client(object): pass if might_be_base64: torrent_data = torrent - - args = {'metainfo': torrent_data} if torrent_data else {'filename': torrent} + args = {} + if torrent_data: + args = {'metainfo': torrent_data} + else: + args = {'filename': torrent} for key, value in iteritems(kwargs): argument = make_rpc_name(key) (arg, val) = argument_value_convert('torrent-add', argument, value, self.rpc_version) @@ -474,7 +472,7 @@ class Client(object): """ self._rpc_version_warning(3) self._request('torrent-remove', - {'delete-local-data': rpc_bool(delete_data)}, ids, True, timeout=timeout) + {'delete-local-data':rpc_bool(delete_data)}, ids, True, timeout=timeout) def remove(self, ids, delete_data=False, timeout=None): """ @@ -604,34 +602,34 @@ class Client(object): the new methods. list returns a dictionary indexed by torrent id. """ warnings.warn('list has been deprecated, please use get_torrent or get_torrents instead.', DeprecationWarning) - fields = ['id', 'hashString', 'name', 'sizeWhenDone', 'leftUntilDone', - 'eta', 'status', 'rateUpload', 'rateDownload', 'uploadedEver', - 'downloadedEver', 'uploadRatio', 'queuePosition'] + fields = ['id', 'hashString', 'name', 'sizeWhenDone', 'leftUntilDone' + , 'eta', 'status', 'rateUpload', 'rateDownload', 'uploadedEver' + , 'downloadedEver', 'uploadRatio', 'queuePosition'] return self._request('torrent-get', {'fields': fields}, timeout=timeout) def get_files(self, ids=None, timeout=None): """ - Get list of files for provided torrent id(s). If ids is empty, - information for all torrents are fetched. This function returns a dictionary - for each requested torrent id holding the information about the files. + Get list of files for provided torrent id(s). If ids is empty, + information for all torrents are fetched. This function returns a dictionary + for each requested torrent id holding the information about the files. - :: + :: - { - : { - : { - 'name': , - 'size': , - 'completed': , - 'priority': , - 'selected': - } + { + : { + : { + 'name': , + 'size': , + 'completed': , + 'priority': , + 'selected': + } - ... - } + ... + } - ... - } + ... + } """ fields = ['id', 'name', 'hashString', 'files', 'priorities', 'wanted'] request_result = self._request('torrent-get', {'fields': fields}, ids, timeout=timeout) @@ -643,22 +641,22 @@ class Client(object): def set_files(self, items, timeout=None): """ Set file properties. Takes a dictionary with similar contents as the result - of `get_files`. + of `get_files`. - :: + :: - { - : { - : { - 'priority': , - 'selected': - } + { + : { + : { + 'priority': , + 'selected': + } - ... - } + ... + } - ... - } + ... + } """ if not isinstance(items, dict): raise ValueError('Invalid file description') @@ -701,8 +699,8 @@ class Client(object): def change_torrent(self, ids, timeout=None, **kwargs): """ - Change torrent parameters for the torrent(s) with the supplied id's. The - parameters are: + Change torrent parameters for the torrent(s) with the supplied id's. The + parameters are: ============================ ===== =============== ======================================================================================= Argument RPC Replaced by Description @@ -734,13 +732,13 @@ class Client(object): ``uploadLimited`` 5 - Enable upload speed limiter. ============================ ===== =============== ======================================================================================= - .. NOTE:: - transmissionrpc will try to automatically fix argument errors. + .. NOTE:: + transmissionrpc will try to automatically fix argument errors. """ args = {} for key, value in iteritems(kwargs): argument = make_rpc_name(key) - (arg, val) = argument_value_convert('torrent-set', argument, value, self.rpc_version) + (arg, val) = argument_value_convert('torrent-set' , argument, value, self.rpc_version) args[arg] = val if len(args) > 0: @@ -801,7 +799,7 @@ class Client(object): raise ValueError("Target name cannot contain a path delimiter") args = {'path': location, 'name': name} result = self._request('torrent-rename-path', args, torrent_id, True, timeout=timeout) - return result['path'], result['name'] + return (result['path'], result['name']) def queue_top(self, ids, timeout=None): """Move transfer to the top of the queue.""" @@ -812,7 +810,7 @@ class Client(object): """Move transfer to the bottom of the queue.""" self._rpc_version_warning(14) self._request('queue-move-bottom', ids=ids, require_ids=True, timeout=timeout) - + def queue_up(self, ids, timeout=None): """Move transfer up in the queue.""" self._rpc_version_warning(14) @@ -886,14 +884,14 @@ class Client(object): ================================ ===== ================= ========================================================================================================================== .. NOTE:: - transmissionrpc will try to automatically fix argument errors. + transmissionrpc will try to automatically fix argument errors. """ args = {} for key, value in iteritems(kwargs): if key == 'encryption' and value not in ['required', 'preferred', 'tolerated']: raise ValueError('Invalid encryption value') argument = make_rpc_name(key) - (arg, val) = argument_value_convert('session-set', argument, value, self.rpc_version) + (arg, val) = argument_value_convert('session-set' , argument, value, self.rpc_version) args[arg] = val if len(args) > 0: self._request('session-set', args, timeout=timeout) diff --git a/libs/transmissionrpc/constants.py b/libs/transmissionrpc/constants.py index e30f99f3..984eb44c 100644 --- a/libs/transmissionrpc/constants.py +++ b/libs/transmissionrpc/constants.py @@ -3,13 +3,11 @@ # Licensed under the MIT license. import logging - from six import iteritems LOGGER = logging.getLogger('transmissionrpc') LOGGER.setLevel(logging.ERROR) - def mirror_dict(source): """ Creates a dictionary with all values as keys and all keys as values. @@ -17,39 +15,38 @@ def mirror_dict(source): source.update(dict((value, key) for key, value in iteritems(source))) return source - DEFAULT_PORT = 9091 DEFAULT_TIMEOUT = 30.0 -TR_PRI_LOW = -1 -TR_PRI_NORMAL = 0 -TR_PRI_HIGH = 1 +TR_PRI_LOW = -1 +TR_PRI_NORMAL = 0 +TR_PRI_HIGH = 1 PRIORITY = mirror_dict({ - 'low': TR_PRI_LOW, - 'normal': TR_PRI_NORMAL, - 'high': TR_PRI_HIGH + 'low' : TR_PRI_LOW, + 'normal' : TR_PRI_NORMAL, + 'high' : TR_PRI_HIGH }) -TR_RATIOLIMIT_GLOBAL = 0 # follow the global settings -TR_RATIOLIMIT_SINGLE = 1 # override the global settings, seeding until a certain ratio -TR_RATIOLIMIT_UNLIMITED = 2 # override the global settings, seeding regardless of ratio +TR_RATIOLIMIT_GLOBAL = 0 # follow the global settings +TR_RATIOLIMIT_SINGLE = 1 # override the global settings, seeding until a certain ratio +TR_RATIOLIMIT_UNLIMITED = 2 # override the global settings, seeding regardless of ratio RATIO_LIMIT = mirror_dict({ - 'global': TR_RATIOLIMIT_GLOBAL, - 'single': TR_RATIOLIMIT_SINGLE, - 'unlimited': TR_RATIOLIMIT_UNLIMITED + 'global' : TR_RATIOLIMIT_GLOBAL, + 'single' : TR_RATIOLIMIT_SINGLE, + 'unlimited' : TR_RATIOLIMIT_UNLIMITED }) -TR_IDLELIMIT_GLOBAL = 0 # follow the global settings -TR_IDLELIMIT_SINGLE = 1 # override the global settings, seeding until a certain idle time -TR_IDLELIMIT_UNLIMITED = 2 # override the global settings, seeding regardless of activity +TR_IDLELIMIT_GLOBAL = 0 # follow the global settings +TR_IDLELIMIT_SINGLE = 1 # override the global settings, seeding until a certain idle time +TR_IDLELIMIT_UNLIMITED = 2 # override the global settings, seeding regardless of activity IDLE_LIMIT = mirror_dict({ - 'global': TR_RATIOLIMIT_GLOBAL, - 'single': TR_RATIOLIMIT_SINGLE, - 'unlimited': TR_RATIOLIMIT_UNLIMITED + 'global' : TR_RATIOLIMIT_GLOBAL, + 'single' : TR_RATIOLIMIT_SINGLE, + 'unlimited' : TR_RATIOLIMIT_UNLIMITED }) # A note on argument maps @@ -63,266 +60,236 @@ IDLE_LIMIT = mirror_dict({ # Arguments for torrent methods TORRENT_ARGS = { - 'get': { - 'activityDate': ('number', 1, None, None, None, 'Last time of upload or download activity.'), - 'addedDate': ('number', 1, None, None, None, 'The date when this torrent was first added.'), - 'announceResponse': ('string', 1, 7, None, None, 'The announce message from the tracker.'), - 'announceURL': ('string', 1, 7, None, None, 'Current announce URL.'), - 'bandwidthPriority': ('number', 5, None, None, None, 'Bandwidth priority. Low (-1), Normal (0) or High (1).'), - 'comment': ('string', 1, None, None, None, 'Torrent comment.'), - 'corruptEver': ('number', 1, None, None, None, 'Number of bytes of corrupt data downloaded.'), - 'creator': ('string', 1, None, None, None, 'Torrent creator.'), - 'dateCreated': ('number', 1, None, None, None, 'Torrent creation date.'), - 'desiredAvailable': ('number', 1, None, None, None, 'Number of bytes avalable and left to be downloaded.'), - 'doneDate': ('number', 1, None, None, None, 'The date when the torrent finished downloading.'), - 'downloadDir': ('string', 4, None, None, None, 'The directory path where the torrent is downloaded to.'), - 'downloadedEver': ('number', 1, None, None, None, 'Number of bytes of good data downloaded.'), - 'downloaders': ('number', 4, 7, None, None, 'Number of downloaders.'), - 'downloadLimit': ('number', 1, None, None, None, 'Download limit in Kbps.'), - 'downloadLimited': ('boolean', 5, None, None, None, 'Download limit is enabled'), - 'downloadLimitMode': ( - 'number', 1, 5, None, None, 'Download limit mode. 0 means global, 1 means signle, 2 unlimited.'), - 'error': ('number', 1, None, None, None, - 'Kind of error. 0 means OK, 1 means tracker warning, 2 means tracker error, 3 means local error.'), - 'errorString': ('number', 1, None, None, None, 'Error message.'), - 'eta': ('number', 1, None, None, None, - 'Estimated number of seconds left when downloading or seeding. -1 means not available and -2 means unknown.'), - 'etaIdle': ('number', 15, None, None, None, - 'Estimated number of seconds left until the idle time limit is reached. -1 means not available and -2 means unknown.'), - 'files': ( - 'array', 1, None, None, None, 'Array of file object containing key, bytesCompleted, length and name.'), - 'fileStats': ( - 'array', 5, None, None, None, 'Aray of file statistics containing bytesCompleted, wanted and priority.'), - 'hashString': ('string', 1, None, None, None, 'Hashstring unique for the torrent even between sessions.'), - 'haveUnchecked': ('number', 1, None, None, None, 'Number of bytes of partial pieces.'), - 'haveValid': ('number', 1, None, None, None, 'Number of bytes of checksum verified data.'), - 'honorsSessionLimits': ('boolean', 5, None, None, None, 'True if session upload limits are honored'), - 'id': ('number', 1, None, None, None, 'Session unique torrent id.'), - 'isFinished': ('boolean', 9, None, None, None, 'True if the torrent is finished. Downloaded and seeded.'), - 'isPrivate': ('boolean', 1, None, None, None, 'True if the torrent is private.'), - 'isStalled': ('boolean', 14, None, None, None, 'True if the torrent has stalled (been idle for a long time).'), - 'lastAnnounceTime': ('number', 1, 7, None, None, 'The time of the last announcement.'), - 'lastScrapeTime': ('number', 1, 7, None, None, 'The time af the last successful scrape.'), - 'leechers': ('number', 1, 7, None, None, 'Number of leechers.'), - 'leftUntilDone': ('number', 1, None, None, None, 'Number of bytes left until the download is done.'), - 'magnetLink': ('string', 7, None, None, None, 'The magnet link for this torrent.'), - 'manualAnnounceTime': ('number', 1, None, None, None, 'The time until you manually ask for more peers.'), - 'maxConnectedPeers': ('number', 1, None, None, None, 'Maximum of connected peers.'), - 'metadataPercentComplete': ('number', 7, None, None, None, 'Download progress of metadata. 0.0 to 1.0.'), - 'name': ('string', 1, None, None, None, 'Torrent name.'), - 'nextAnnounceTime': ('number', 1, 7, None, None, 'Next announce time.'), - 'nextScrapeTime': ('number', 1, 7, None, None, 'Next scrape time.'), - 'peer-limit': ('number', 5, None, None, None, 'Maximum number of peers.'), - 'peers': ('array', 2, None, None, None, 'Array of peer objects.'), - 'peersConnected': ('number', 1, None, None, None, 'Number of peers we are connected to.'), - 'peersFrom': ( - 'object', 1, None, None, None, 'Object containing download peers counts for different peer types.'), - 'peersGettingFromUs': ('number', 1, None, None, None, 'Number of peers we are sending data to.'), - 'peersKnown': ('number', 1, 13, None, None, 'Number of peers that the tracker knows.'), - 'peersSendingToUs': ('number', 1, None, None, None, 'Number of peers sending to us'), - 'percentDone': ('double', 5, None, None, None, 'Download progress of selected files. 0.0 to 1.0.'), - 'pieces': ('string', 5, None, None, None, 'String with base64 encoded bitfield indicating finished pieces.'), - 'pieceCount': ('number', 1, None, None, None, 'Number of pieces.'), - 'pieceSize': ('number', 1, None, None, None, 'Number of bytes in a piece.'), - 'priorities': ('array', 1, None, None, None, 'Array of file priorities.'), - 'queuePosition': ('number', 14, None, None, None, 'The queue position.'), - 'rateDownload': ('number', 1, None, None, None, 'Download rate in bps.'), - 'rateUpload': ('number', 1, None, None, None, 'Upload rate in bps.'), - 'recheckProgress': ('double', 1, None, None, None, 'Progress of recheck. 0.0 to 1.0.'), - 'secondsDownloading': ('number', 15, None, None, None, ''), - 'secondsSeeding': ('number', 15, None, None, None, ''), - 'scrapeResponse': ('string', 1, 7, None, None, 'Scrape response message.'), - 'scrapeURL': ('string', 1, 7, None, None, 'Current scrape URL'), - 'seeders': ('number', 1, 7, None, None, 'Number of seeders reported by the tracker.'), - 'seedIdleLimit': ('number', 10, None, None, None, 'Idle limit in minutes.'), - 'seedIdleMode': ('number', 10, None, None, None, 'Use global (0), torrent (1), or unlimited (2) limit.'), - 'seedRatioLimit': ('double', 5, None, None, None, 'Seed ratio limit.'), - 'seedRatioMode': ('number', 5, None, None, None, 'Use global (0), torrent (1), or unlimited (2) limit.'), - 'sizeWhenDone': ('number', 1, None, None, None, 'Size of the torrent download in bytes.'), - 'startDate': ('number', 1, None, None, None, 'The date when the torrent was last started.'), - 'status': ('number', 1, None, None, None, 'Current status, see source'), - 'swarmSpeed': ('number', 1, 7, None, None, 'Estimated speed in Kbps in the swarm.'), - 'timesCompleted': ('number', 1, 7, None, None, 'Number of successful downloads reported by the tracker.'), - 'trackers': ('array', 1, None, None, None, 'Array of tracker objects.'), - 'trackerStats': ('object', 7, None, None, None, 'Array of object containing tracker statistics.'), - 'totalSize': ('number', 1, None, None, None, 'Total size of the torrent in bytes'), - 'torrentFile': ('string', 5, None, None, None, 'Path to .torrent file.'), - 'uploadedEver': ('number', 1, None, None, None, 'Number of bytes uploaded, ever.'), - 'uploadLimit': ('number', 1, None, None, None, 'Upload limit in Kbps'), - 'uploadLimitMode': ( - 'number', 1, 5, None, None, 'Upload limit mode. 0 means global, 1 means signle, 2 unlimited.'), - 'uploadLimited': ('boolean', 5, None, None, None, 'Upload limit enabled.'), - 'uploadRatio': ('double', 1, None, None, None, 'Seed ratio.'), - 'wanted': ('array', 1, None, None, None, 'Array of booleans indicated wanted files.'), - 'webseeds': ('array', 1, None, None, None, 'Array of webseeds objects'), - 'webseedsSendingToUs': ('number', 1, None, None, None, 'Number of webseeds seeding to us.'), + 'get' : { + 'activityDate': ('number', 1, None, None, None, 'Last time of upload or download activity.'), + 'addedDate': ('number', 1, None, None, None, 'The date when this torrent was first added.'), + 'announceResponse': ('string', 1, 7, None, None, 'The announce message from the tracker.'), + 'announceURL': ('string', 1, 7, None, None, 'Current announce URL.'), + 'bandwidthPriority': ('number', 5, None, None, None, 'Bandwidth priority. Low (-1), Normal (0) or High (1).'), + 'comment': ('string', 1, None, None, None, 'Torrent comment.'), + 'corruptEver': ('number', 1, None, None, None, 'Number of bytes of corrupt data downloaded.'), + 'creator': ('string', 1, None, None, None, 'Torrent creator.'), + 'dateCreated': ('number', 1, None, None, None, 'Torrent creation date.'), + 'desiredAvailable': ('number', 1, None, None, None, 'Number of bytes avalable and left to be downloaded.'), + 'doneDate': ('number', 1, None, None, None, 'The date when the torrent finished downloading.'), + 'downloadDir': ('string', 4, None, None, None, 'The directory path where the torrent is downloaded to.'), + 'downloadedEver': ('number', 1, None, None, None, 'Number of bytes of good data downloaded.'), + 'downloaders': ('number', 4, 7, None, None, 'Number of downloaders.'), + 'downloadLimit': ('number', 1, None, None, None, 'Download limit in Kbps.'), + 'downloadLimited': ('boolean', 5, None, None, None, 'Download limit is enabled'), + 'downloadLimitMode': ('number', 1, 5, None, None, 'Download limit mode. 0 means global, 1 means signle, 2 unlimited.'), + 'error': ('number', 1, None, None, None, 'Kind of error. 0 means OK, 1 means tracker warning, 2 means tracker error, 3 means local error.'), + 'errorString': ('number', 1, None, None, None, 'Error message.'), + 'eta': ('number', 1, None, None, None, 'Estimated number of seconds left when downloading or seeding. -1 means not available and -2 means unknown.'), + 'etaIdle': ('number', 15, None, None, None, 'Estimated number of seconds left until the idle time limit is reached. -1 means not available and -2 means unknown.'), + 'files': ('array', 1, None, None, None, 'Array of file object containing key, bytesCompleted, length and name.'), + 'fileStats': ('array', 5, None, None, None, 'Aray of file statistics containing bytesCompleted, wanted and priority.'), + 'hashString': ('string', 1, None, None, None, 'Hashstring unique for the torrent even between sessions.'), + 'haveUnchecked': ('number', 1, None, None, None, 'Number of bytes of partial pieces.'), + 'haveValid': ('number', 1, None, None, None, 'Number of bytes of checksum verified data.'), + 'honorsSessionLimits': ('boolean', 5, None, None, None, 'True if session upload limits are honored'), + 'id': ('number', 1, None, None, None, 'Session unique torrent id.'), + 'isFinished': ('boolean', 9, None, None, None, 'True if the torrent is finished. Downloaded and seeded.'), + 'isPrivate': ('boolean', 1, None, None, None, 'True if the torrent is private.'), + 'isStalled': ('boolean', 14, None, None, None, 'True if the torrent has stalled (been idle for a long time).'), + 'lastAnnounceTime': ('number', 1, 7, None, None, 'The time of the last announcement.'), + 'lastScrapeTime': ('number', 1, 7, None, None, 'The time af the last successful scrape.'), + 'leechers': ('number', 1, 7, None, None, 'Number of leechers.'), + 'leftUntilDone': ('number', 1, None, None, None, 'Number of bytes left until the download is done.'), + 'magnetLink': ('string', 7, None, None, None, 'The magnet link for this torrent.'), + 'manualAnnounceTime': ('number', 1, None, None, None, 'The time until you manually ask for more peers.'), + 'maxConnectedPeers': ('number', 1, None, None, None, 'Maximum of connected peers.'), + 'metadataPercentComplete': ('number', 7, None, None, None, 'Download progress of metadata. 0.0 to 1.0.'), + 'name': ('string', 1, None, None, None, 'Torrent name.'), + 'nextAnnounceTime': ('number', 1, 7, None, None, 'Next announce time.'), + 'nextScrapeTime': ('number', 1, 7, None, None, 'Next scrape time.'), + 'peer-limit': ('number', 5, None, None, None, 'Maximum number of peers.'), + 'peers': ('array', 2, None, None, None, 'Array of peer objects.'), + 'peersConnected': ('number', 1, None, None, None, 'Number of peers we are connected to.'), + 'peersFrom': ('object', 1, None, None, None, 'Object containing download peers counts for different peer types.'), + 'peersGettingFromUs': ('number', 1, None, None, None, 'Number of peers we are sending data to.'), + 'peersKnown': ('number', 1, 13, None, None, 'Number of peers that the tracker knows.'), + 'peersSendingToUs': ('number', 1, None, None, None, 'Number of peers sending to us'), + 'percentDone': ('double', 5, None, None, None, 'Download progress of selected files. 0.0 to 1.0.'), + 'pieces': ('string', 5, None, None, None, 'String with base64 encoded bitfield indicating finished pieces.'), + 'pieceCount': ('number', 1, None, None, None, 'Number of pieces.'), + 'pieceSize': ('number', 1, None, None, None, 'Number of bytes in a piece.'), + 'priorities': ('array', 1, None, None, None, 'Array of file priorities.'), + 'queuePosition': ('number', 14, None, None, None, 'The queue position.'), + 'rateDownload': ('number', 1, None, None, None, 'Download rate in bps.'), + 'rateUpload': ('number', 1, None, None, None, 'Upload rate in bps.'), + 'recheckProgress': ('double', 1, None, None, None, 'Progress of recheck. 0.0 to 1.0.'), + 'secondsDownloading': ('number', 15, None, None, None, ''), + 'secondsSeeding': ('number', 15, None, None, None, ''), + 'scrapeResponse': ('string', 1, 7, None, None, 'Scrape response message.'), + 'scrapeURL': ('string', 1, 7, None, None, 'Current scrape URL'), + 'seeders': ('number', 1, 7, None, None, 'Number of seeders reported by the tracker.'), + 'seedIdleLimit': ('number', 10, None, None, None, 'Idle limit in minutes.'), + 'seedIdleMode': ('number', 10, None, None, None, 'Use global (0), torrent (1), or unlimited (2) limit.'), + 'seedRatioLimit': ('double', 5, None, None, None, 'Seed ratio limit.'), + 'seedRatioMode': ('number', 5, None, None, None, 'Use global (0), torrent (1), or unlimited (2) limit.'), + 'sizeWhenDone': ('number', 1, None, None, None, 'Size of the torrent download in bytes.'), + 'startDate': ('number', 1, None, None, None, 'The date when the torrent was last started.'), + 'status': ('number', 1, None, None, None, 'Current status, see source'), + 'swarmSpeed': ('number', 1, 7, None, None, 'Estimated speed in Kbps in the swarm.'), + 'timesCompleted': ('number', 1, 7, None, None, 'Number of successful downloads reported by the tracker.'), + 'trackers': ('array', 1, None, None, None, 'Array of tracker objects.'), + 'trackerStats': ('object', 7, None, None, None, 'Array of object containing tracker statistics.'), + 'totalSize': ('number', 1, None, None, None, 'Total size of the torrent in bytes'), + 'torrentFile': ('string', 5, None, None, None, 'Path to .torrent file.'), + 'uploadedEver': ('number', 1, None, None, None, 'Number of bytes uploaded, ever.'), + 'uploadLimit': ('number', 1, None, None, None, 'Upload limit in Kbps'), + 'uploadLimitMode': ('number', 1, 5, None, None, 'Upload limit mode. 0 means global, 1 means signle, 2 unlimited.'), + 'uploadLimited': ('boolean', 5, None, None, None, 'Upload limit enabled.'), + 'uploadRatio': ('double', 1, None, None, None, 'Seed ratio.'), + 'wanted': ('array', 1, None, None, None, 'Array of booleans indicated wanted files.'), + 'webseeds': ('array', 1, None, None, None, 'Array of webseeds objects'), + 'webseedsSendingToUs': ('number', 1, None, None, None, 'Number of webseeds seeding to us.'), }, 'set': { - 'bandwidthPriority': ('number', 5, None, None, None, 'Priority for this transfer.'), - 'downloadLimit': ('number', 5, None, 'speed-limit-down', None, 'Set the speed limit for download in Kib/s.'), - 'downloadLimited': ('boolean', 5, None, 'speed-limit-down-enabled', None, 'Enable download speed limiter.'), - 'files-wanted': ('array', 1, None, None, None, "A list of file id's that should be downloaded."), - 'files-unwanted': ('array', 1, None, None, None, "A list of file id's that shouldn't be downloaded."), - 'honorsSessionLimits': ('boolean', 5, None, None, None, - "Enables or disables the transfer to honour the upload limit set in the session."), - 'location': ('array', 1, None, None, None, 'Local download location.'), - 'peer-limit': ('number', 1, None, None, None, 'The peer limit for the torrents.'), - 'priority-high': ('array', 1, None, None, None, "A list of file id's that should have high priority."), - 'priority-low': ('array', 1, None, None, None, "A list of file id's that should have normal priority."), - 'priority-normal': ('array', 1, None, None, None, "A list of file id's that should have low priority."), - 'queuePosition': ('number', 14, None, None, None, 'Position of this transfer in its queue.'), - 'seedIdleLimit': ('number', 10, None, None, None, 'Seed inactivity limit in minutes.'), - 'seedIdleMode': ('number', 10, None, None, None, - 'Seed inactivity mode. 0 = Use session limit, 1 = Use transfer limit, 2 = Disable limit.'), - 'seedRatioLimit': ('double', 5, None, None, None, 'Seeding ratio.'), - 'seedRatioMode': ('number', 5, None, None, None, - 'Which ratio to use. 0 = Use session limit, 1 = Use transfer limit, 2 = Disable limit.'), - 'speed-limit-down': ('number', 1, 5, None, 'downloadLimit', 'Set the speed limit for download in Kib/s.'), - 'speed-limit-down-enabled': ('boolean', 1, 5, None, 'downloadLimited', 'Enable download speed limiter.'), - 'speed-limit-up': ('number', 1, 5, None, 'uploadLimit', 'Set the speed limit for upload in Kib/s.'), - 'speed-limit-up-enabled': ('boolean', 1, 5, None, 'uploadLimited', 'Enable upload speed limiter.'), - 'trackerAdd': ('array', 10, None, None, None, 'Array of string with announce URLs to add.'), - 'trackerRemove': ('array', 10, None, None, None, 'Array of ids of trackers to remove.'), - 'trackerReplace': ( - 'array', 10, None, None, None, 'Array of (id, url) tuples where the announce URL should be replaced.'), - 'uploadLimit': ('number', 5, None, 'speed-limit-up', None, 'Set the speed limit for upload in Kib/s.'), - 'uploadLimited': ('boolean', 5, None, 'speed-limit-up-enabled', None, 'Enable upload speed limiter.'), + 'bandwidthPriority': ('number', 5, None, None, None, 'Priority for this transfer.'), + 'downloadLimit': ('number', 5, None, 'speed-limit-down', None, 'Set the speed limit for download in Kib/s.'), + 'downloadLimited': ('boolean', 5, None, 'speed-limit-down-enabled', None, 'Enable download speed limiter.'), + 'files-wanted': ('array', 1, None, None, None, "A list of file id's that should be downloaded."), + 'files-unwanted': ('array', 1, None, None, None, "A list of file id's that shouldn't be downloaded."), + 'honorsSessionLimits': ('boolean', 5, None, None, None, "Enables or disables the transfer to honour the upload limit set in the session."), + 'location': ('array', 1, None, None, None, 'Local download location.'), + 'peer-limit': ('number', 1, None, None, None, 'The peer limit for the torrents.'), + 'priority-high': ('array', 1, None, None, None, "A list of file id's that should have high priority."), + 'priority-low': ('array', 1, None, None, None, "A list of file id's that should have normal priority."), + 'priority-normal': ('array', 1, None, None, None, "A list of file id's that should have low priority."), + 'queuePosition': ('number', 14, None, None, None, 'Position of this transfer in its queue.'), + 'seedIdleLimit': ('number', 10, None, None, None, 'Seed inactivity limit in minutes.'), + 'seedIdleMode': ('number', 10, None, None, None, 'Seed inactivity mode. 0 = Use session limit, 1 = Use transfer limit, 2 = Disable limit.'), + 'seedRatioLimit': ('double', 5, None, None, None, 'Seeding ratio.'), + 'seedRatioMode': ('number', 5, None, None, None, 'Which ratio to use. 0 = Use session limit, 1 = Use transfer limit, 2 = Disable limit.'), + 'speed-limit-down': ('number', 1, 5, None, 'downloadLimit', 'Set the speed limit for download in Kib/s.'), + 'speed-limit-down-enabled': ('boolean', 1, 5, None, 'downloadLimited', 'Enable download speed limiter.'), + 'speed-limit-up': ('number', 1, 5, None, 'uploadLimit', 'Set the speed limit for upload in Kib/s.'), + 'speed-limit-up-enabled': ('boolean', 1, 5, None, 'uploadLimited', 'Enable upload speed limiter.'), + 'trackerAdd': ('array', 10, None, None, None, 'Array of string with announce URLs to add.'), + 'trackerRemove': ('array', 10, None, None, None, 'Array of ids of trackers to remove.'), + 'trackerReplace': ('array', 10, None, None, None, 'Array of (id, url) tuples where the announce URL should be replaced.'), + 'uploadLimit': ('number', 5, None, 'speed-limit-up', None, 'Set the speed limit for upload in Kib/s.'), + 'uploadLimited': ('boolean', 5, None, 'speed-limit-up-enabled', None, 'Enable upload speed limiter.'), }, 'add': { - 'bandwidthPriority': ('number', 8, None, None, None, 'Priority for this transfer.'), - 'download-dir': ( - 'string', 1, None, None, None, 'The directory where the downloaded contents will be saved in.'), - 'cookies': ('string', 13, None, None, None, 'One or more HTTP cookie(s).'), - 'filename': ('string', 1, None, None, None, "A file path or URL to a torrent file or a magnet link."), - 'files-wanted': ('array', 1, None, None, None, "A list of file id's that should be downloaded."), - 'files-unwanted': ('array', 1, None, None, None, "A list of file id's that shouldn't be downloaded."), - 'metainfo': ('string', 1, None, None, None, 'The content of a torrent file, base64 encoded.'), - 'paused': ('boolean', 1, None, None, None, 'If True, does not start the transfer when added.'), - 'peer-limit': ('number', 1, None, None, None, 'Maximum number of peers allowed.'), - 'priority-high': ('array', 1, None, None, None, "A list of file id's that should have high priority."), - 'priority-low': ('array', 1, None, None, None, "A list of file id's that should have low priority."), - 'priority-normal': ('array', 1, None, None, None, "A list of file id's that should have normal priority."), + 'bandwidthPriority': ('number', 8, None, None, None, 'Priority for this transfer.'), + 'download-dir': ('string', 1, None, None, None, 'The directory where the downloaded contents will be saved in.'), + 'cookies': ('string', 13, None, None, None, 'One or more HTTP cookie(s).'), + 'filename': ('string', 1, None, None, None, "A file path or URL to a torrent file or a magnet link."), + 'files-wanted': ('array', 1, None, None, None, "A list of file id's that should be downloaded."), + 'files-unwanted': ('array', 1, None, None, None, "A list of file id's that shouldn't be downloaded."), + 'metainfo': ('string', 1, None, None, None, 'The content of a torrent file, base64 encoded.'), + 'paused': ('boolean', 1, None, None, None, 'If True, does not start the transfer when added.'), + 'peer-limit': ('number', 1, None, None, None, 'Maximum number of peers allowed.'), + 'priority-high': ('array', 1, None, None, None, "A list of file id's that should have high priority."), + 'priority-low': ('array', 1, None, None, None, "A list of file id's that should have low priority."), + 'priority-normal': ('array', 1, None, None, None, "A list of file id's that should have normal priority."), } } # Arguments for session methods SESSION_ARGS = { 'get': { - "alt-speed-down": ('number', 5, None, None, None, 'Alternate session download speed limit (in Kib/s).'), - "alt-speed-enabled": ( - 'boolean', 5, None, None, None, 'True if alternate global download speed limiter is ebabled.'), - "alt-speed-time-begin": ( - 'number', 5, None, None, None, 'Time when alternate speeds should be enabled. Minutes after midnight.'), - "alt-speed-time-enabled": ('boolean', 5, None, None, None, 'True if alternate speeds scheduling is enabled.'), - "alt-speed-time-end": ( - 'number', 5, None, None, None, 'Time when alternate speeds should be disabled. Minutes after midnight.'), - "alt-speed-time-day": ('number', 5, None, None, None, 'Days alternate speeds scheduling is enabled.'), - "alt-speed-up": ('number', 5, None, None, None, 'Alternate session upload speed limit (in Kib/s)'), - "blocklist-enabled": ('boolean', 5, None, None, None, 'True when blocklist is enabled.'), - "blocklist-size": ('number', 5, None, None, None, 'Number of rules in the blocklist'), - "blocklist-url": ('string', 11, None, None, None, 'Location of the block list. Updated with blocklist-update.'), - "cache-size-mb": ('number', 10, None, None, None, 'The maximum size of the disk cache in MB'), - "config-dir": ('string', 8, None, None, None, 'location of transmissions configuration directory'), - "dht-enabled": ('boolean', 6, None, None, None, 'True if DHT enabled.'), - "download-dir": ('string', 1, None, None, None, 'The download directory.'), - "download-dir-free-space": ('number', 12, None, None, None, 'Free space in the download directory, in bytes'), - "download-queue-size": ('number', 14, None, None, None, 'Number of slots in the download queue.'), - "download-queue-enabled": ('boolean', 14, None, None, None, 'True if the download queue is enabled.'), - "encryption": ( - 'string', 1, None, None, None, 'Encryption mode, one of ``required``, ``preferred`` or ``tolerated``.'), - "idle-seeding-limit": ('number', 10, None, None, None, 'Seed inactivity limit in minutes.'), - "idle-seeding-limit-enabled": ('boolean', 10, None, None, None, 'True if the seed activity limit is enabled.'), - "incomplete-dir": ( - 'string', 7, None, None, None, 'The path to the directory for incomplete torrent transfer data.'), - "incomplete-dir-enabled": ('boolean', 7, None, None, None, 'True if the incomplete dir is enabled.'), - "lpd-enabled": ('boolean', 9, None, None, None, 'True if local peer discovery is enabled.'), - "peer-limit": ('number', 1, 5, None, 'peer-limit-global', 'Maximum number of peers.'), - "peer-limit-global": ('number', 5, None, 'peer-limit', None, 'Maximum number of peers.'), - "peer-limit-per-torrent": ('number', 5, None, None, None, 'Maximum number of peers per transfer.'), - "pex-allowed": ('boolean', 1, 5, None, 'pex-enabled', 'True if PEX is allowed.'), - "pex-enabled": ('boolean', 5, None, 'pex-allowed', None, 'True if PEX is enabled.'), - "port": ('number', 1, 5, None, 'peer-port', 'Peer port.'), - "peer-port": ('number', 5, None, 'port', None, 'Peer port.'), - "peer-port-random-on-start": ( - 'boolean', 5, None, None, None, 'Enables randomized peer port on start of Transmission.'), - "port-forwarding-enabled": ('boolean', 1, None, None, None, 'True if port forwarding is enabled.'), - "queue-stalled-minutes": ( - 'number', 14, None, None, None, 'Number of minutes of idle that marks a transfer as stalled.'), - "queue-stalled-enabled": ('boolean', 14, None, None, None, 'True if stalled tracking of transfers is enabled.'), - "rename-partial-files": ('boolean', 8, None, None, None, 'True if ".part" is appended to incomplete files'), - "rpc-version": ('number', 4, None, None, None, 'Transmission RPC API Version.'), - "rpc-version-minimum": ('number', 4, None, None, None, 'Minimum accepted RPC API Version.'), - "script-torrent-done-enabled": ('boolean', 9, None, None, None, 'True if the done script is enabled.'), - "script-torrent-done-filename": ( - 'string', 9, None, None, None, 'Filename of the script to run when the transfer is done.'), - "seedRatioLimit": ('double', 5, None, None, None, 'Seed ratio limit. 1.0 means 1:1 download and upload ratio.'), - "seedRatioLimited": ('boolean', 5, None, None, None, 'True if seed ration limit is enabled.'), - "seed-queue-size": ('number', 14, None, None, None, 'Number of slots in the upload queue.'), - "seed-queue-enabled": ('boolean', 14, None, None, None, 'True if upload queue is enabled.'), - "speed-limit-down": ('number', 1, None, None, None, 'Download speed limit (in Kib/s).'), - "speed-limit-down-enabled": ('boolean', 1, None, None, None, 'True if the download speed is limited.'), - "speed-limit-up": ('number', 1, None, None, None, 'Upload speed limit (in Kib/s).'), - "speed-limit-up-enabled": ('boolean', 1, None, None, None, 'True if the upload speed is limited.'), - "start-added-torrents": ('boolean', 9, None, None, None, 'When true uploaded torrents will start right away.'), - "trash-original-torrent-files": ( - 'boolean', 9, None, None, None, 'When true added .torrent files will be deleted.'), - 'units': ('object', 10, None, None, None, 'An object containing units for size and speed.'), - 'utp-enabled': ('boolean', 13, None, None, None, 'True if Micro Transport Protocol (UTP) is enabled.'), - "version": ('string', 3, None, None, None, 'Transmission version.'), + "alt-speed-down": ('number', 5, None, None, None, 'Alternate session download speed limit (in Kib/s).'), + "alt-speed-enabled": ('boolean', 5, None, None, None, 'True if alternate global download speed limiter is ebabled.'), + "alt-speed-time-begin": ('number', 5, None, None, None, 'Time when alternate speeds should be enabled. Minutes after midnight.'), + "alt-speed-time-enabled": ('boolean', 5, None, None, None, 'True if alternate speeds scheduling is enabled.'), + "alt-speed-time-end": ('number', 5, None, None, None, 'Time when alternate speeds should be disabled. Minutes after midnight.'), + "alt-speed-time-day": ('number', 5, None, None, None, 'Days alternate speeds scheduling is enabled.'), + "alt-speed-up": ('number', 5, None, None, None, 'Alternate session upload speed limit (in Kib/s)'), + "blocklist-enabled": ('boolean', 5, None, None, None, 'True when blocklist is enabled.'), + "blocklist-size": ('number', 5, None, None, None, 'Number of rules in the blocklist'), + "blocklist-url": ('string', 11, None, None, None, 'Location of the block list. Updated with blocklist-update.'), + "cache-size-mb": ('number', 10, None, None, None, 'The maximum size of the disk cache in MB'), + "config-dir": ('string', 8, None, None, None, 'location of transmissions configuration directory'), + "dht-enabled": ('boolean', 6, None, None, None, 'True if DHT enabled.'), + "download-dir": ('string', 1, None, None, None, 'The download directory.'), + "download-dir-free-space": ('number', 12, None, None, None, 'Free space in the download directory, in bytes'), + "download-queue-size": ('number', 14, None, None, None, 'Number of slots in the download queue.'), + "download-queue-enabled": ('boolean', 14, None, None, None, 'True if the download queue is enabled.'), + "encryption": ('string', 1, None, None, None, 'Encryption mode, one of ``required``, ``preferred`` or ``tolerated``.'), + "idle-seeding-limit": ('number', 10, None, None, None, 'Seed inactivity limit in minutes.'), + "idle-seeding-limit-enabled": ('boolean', 10, None, None, None, 'True if the seed activity limit is enabled.'), + "incomplete-dir": ('string', 7, None, None, None, 'The path to the directory for incomplete torrent transfer data.'), + "incomplete-dir-enabled": ('boolean', 7, None, None, None, 'True if the incomplete dir is enabled.'), + "lpd-enabled": ('boolean', 9, None, None, None, 'True if local peer discovery is enabled.'), + "peer-limit": ('number', 1, 5, None, 'peer-limit-global', 'Maximum number of peers.'), + "peer-limit-global": ('number', 5, None, 'peer-limit', None, 'Maximum number of peers.'), + "peer-limit-per-torrent": ('number', 5, None, None, None, 'Maximum number of peers per transfer.'), + "pex-allowed": ('boolean', 1, 5, None, 'pex-enabled', 'True if PEX is allowed.'), + "pex-enabled": ('boolean', 5, None, 'pex-allowed', None, 'True if PEX is enabled.'), + "port": ('number', 1, 5, None, 'peer-port', 'Peer port.'), + "peer-port": ('number', 5, None, 'port', None, 'Peer port.'), + "peer-port-random-on-start": ('boolean', 5, None, None, None, 'Enables randomized peer port on start of Transmission.'), + "port-forwarding-enabled": ('boolean', 1, None, None, None, 'True if port forwarding is enabled.'), + "queue-stalled-minutes": ('number', 14, None, None, None, 'Number of minutes of idle that marks a transfer as stalled.'), + "queue-stalled-enabled": ('boolean', 14, None, None, None, 'True if stalled tracking of transfers is enabled.'), + "rename-partial-files": ('boolean', 8, None, None, None, 'True if ".part" is appended to incomplete files'), + "rpc-version": ('number', 4, None, None, None, 'Transmission RPC API Version.'), + "rpc-version-minimum": ('number', 4, None, None, None, 'Minimum accepted RPC API Version.'), + "script-torrent-done-enabled": ('boolean', 9, None, None, None, 'True if the done script is enabled.'), + "script-torrent-done-filename": ('string', 9, None, None, None, 'Filename of the script to run when the transfer is done.'), + "seedRatioLimit": ('double', 5, None, None, None, 'Seed ratio limit. 1.0 means 1:1 download and upload ratio.'), + "seedRatioLimited": ('boolean', 5, None, None, None, 'True if seed ration limit is enabled.'), + "seed-queue-size": ('number', 14, None, None, None, 'Number of slots in the upload queue.'), + "seed-queue-enabled": ('boolean', 14, None, None, None, 'True if upload queue is enabled.'), + "speed-limit-down": ('number', 1, None, None, None, 'Download speed limit (in Kib/s).'), + "speed-limit-down-enabled": ('boolean', 1, None, None, None, 'True if the download speed is limited.'), + "speed-limit-up": ('number', 1, None, None, None, 'Upload speed limit (in Kib/s).'), + "speed-limit-up-enabled": ('boolean', 1, None, None, None, 'True if the upload speed is limited.'), + "start-added-torrents": ('boolean', 9, None, None, None, 'When true uploaded torrents will start right away.'), + "trash-original-torrent-files": ('boolean', 9, None, None, None, 'When true added .torrent files will be deleted.'), + 'units': ('object', 10, None, None, None, 'An object containing units for size and speed.'), + 'utp-enabled': ('boolean', 13, None, None, None, 'True if Micro Transport Protocol (UTP) is enabled.'), + "version": ('string', 3, None, None, None, 'Transmission version.'), }, 'set': { - "alt-speed-down": ('number', 5, None, None, None, 'Alternate session download speed limit (in Kib/s).'), - "alt-speed-enabled": ('boolean', 5, None, None, None, 'Enables alternate global download speed limiter.'), - "alt-speed-time-begin": ( - 'number', 5, None, None, None, 'Time when alternate speeds should be enabled. Minutes after midnight.'), - "alt-speed-time-enabled": ('boolean', 5, None, None, None, 'Enables alternate speeds scheduling.'), - "alt-speed-time-end": ( - 'number', 5, None, None, None, 'Time when alternate speeds should be disabled. Minutes after midnight.'), - "alt-speed-time-day": ('number', 5, None, None, None, 'Enables alternate speeds scheduling these days.'), - "alt-speed-up": ('number', 5, None, None, None, 'Alternate session upload speed limit (in Kib/s).'), - "blocklist-enabled": ('boolean', 5, None, None, None, 'Enables the block list'), - "blocklist-url": ('string', 11, None, None, None, 'Location of the block list. Updated with blocklist-update.'), - "cache-size-mb": ('number', 10, None, None, None, 'The maximum size of the disk cache in MB'), - "dht-enabled": ('boolean', 6, None, None, None, 'Enables DHT.'), - "download-dir": ('string', 1, None, None, None, 'Set the session download directory.'), - "download-queue-size": ('number', 14, None, None, None, 'Number of slots in the download queue.'), - "download-queue-enabled": ('boolean', 14, None, None, None, 'Enables download queue.'), - "encryption": ('string', 1, None, None, None, - 'Set the session encryption mode, one of ``required``, ``preferred`` or ``tolerated``.'), - "idle-seeding-limit": ('number', 10, None, None, None, 'The default seed inactivity limit in minutes.'), - "idle-seeding-limit-enabled": ('boolean', 10, None, None, None, 'Enables the default seed inactivity limit'), - "incomplete-dir": ('string', 7, None, None, None, 'The path to the directory of incomplete transfer data.'), - "incomplete-dir-enabled": ('boolean', 7, None, None, None, - 'Enables the incomplete transfer data directory. Otherwise data for incomplete transfers are stored in the download target.'), - "lpd-enabled": ('boolean', 9, None, None, None, 'Enables local peer discovery for public torrents.'), - "peer-limit": ('number', 1, 5, None, 'peer-limit-global', 'Maximum number of peers.'), - "peer-limit-global": ('number', 5, None, 'peer-limit', None, 'Maximum number of peers.'), - "peer-limit-per-torrent": ('number', 5, None, None, None, 'Maximum number of peers per transfer.'), - "pex-allowed": ('boolean', 1, 5, None, 'pex-enabled', 'Allowing PEX in public torrents.'), - "pex-enabled": ('boolean', 5, None, 'pex-allowed', None, 'Allowing PEX in public torrents.'), - "port": ('number', 1, 5, None, 'peer-port', 'Peer port.'), - "peer-port": ('number', 5, None, 'port', None, 'Peer port.'), - "peer-port-random-on-start": ( - 'boolean', 5, None, None, None, 'Enables randomized peer port on start of Transmission.'), - "port-forwarding-enabled": ('boolean', 1, None, None, None, 'Enables port forwarding.'), - "rename-partial-files": ('boolean', 8, None, None, None, 'Appends ".part" to incomplete files'), - "queue-stalled-minutes": ( - 'number', 14, None, None, None, 'Number of minutes of idle that marks a transfer as stalled.'), - "queue-stalled-enabled": ('boolean', 14, None, None, None, 'Enable tracking of stalled transfers.'), - "script-torrent-done-enabled": ('boolean', 9, None, None, None, 'Whether or not to call the "done" script.'), - "script-torrent-done-filename": ( - 'string', 9, None, None, None, 'Filename of the script to run when the transfer is done.'), - "seed-queue-size": ('number', 14, None, None, None, 'Number of slots in the upload queue.'), - "seed-queue-enabled": ('boolean', 14, None, None, None, 'Enables upload queue.'), - "seedRatioLimit": ('double', 5, None, None, None, 'Seed ratio limit. 1.0 means 1:1 download and upload ratio.'), - "seedRatioLimited": ('boolean', 5, None, None, None, 'Enables seed ration limit.'), - "speed-limit-down": ('number', 1, None, None, None, 'Download speed limit (in Kib/s).'), - "speed-limit-down-enabled": ('boolean', 1, None, None, None, 'Enables download speed limiting.'), - "speed-limit-up": ('number', 1, None, None, None, 'Upload speed limit (in Kib/s).'), - "speed-limit-up-enabled": ('boolean', 1, None, None, None, 'Enables upload speed limiting.'), - "start-added-torrents": ('boolean', 9, None, None, None, 'Added torrents will be started right away.'), - "trash-original-torrent-files": ( - 'boolean', 9, None, None, None, 'The .torrent file of added torrents will be deleted.'), - 'utp-enabled': ('boolean', 13, None, None, None, 'Enables Micro Transport Protocol (UTP).'), + "alt-speed-down": ('number', 5, None, None, None, 'Alternate session download speed limit (in Kib/s).'), + "alt-speed-enabled": ('boolean', 5, None, None, None, 'Enables alternate global download speed limiter.'), + "alt-speed-time-begin": ('number', 5, None, None, None, 'Time when alternate speeds should be enabled. Minutes after midnight.'), + "alt-speed-time-enabled": ('boolean', 5, None, None, None, 'Enables alternate speeds scheduling.'), + "alt-speed-time-end": ('number', 5, None, None, None, 'Time when alternate speeds should be disabled. Minutes after midnight.'), + "alt-speed-time-day": ('number', 5, None, None, None, 'Enables alternate speeds scheduling these days.'), + "alt-speed-up": ('number', 5, None, None, None, 'Alternate session upload speed limit (in Kib/s).'), + "blocklist-enabled": ('boolean', 5, None, None, None, 'Enables the block list'), + "blocklist-url": ('string', 11, None, None, None, 'Location of the block list. Updated with blocklist-update.'), + "cache-size-mb": ('number', 10, None, None, None, 'The maximum size of the disk cache in MB'), + "dht-enabled": ('boolean', 6, None, None, None, 'Enables DHT.'), + "download-dir": ('string', 1, None, None, None, 'Set the session download directory.'), + "download-queue-size": ('number', 14, None, None, None, 'Number of slots in the download queue.'), + "download-queue-enabled": ('boolean', 14, None, None, None, 'Enables download queue.'), + "encryption": ('string', 1, None, None, None, 'Set the session encryption mode, one of ``required``, ``preferred`` or ``tolerated``.'), + "idle-seeding-limit": ('number', 10, None, None, None, 'The default seed inactivity limit in minutes.'), + "idle-seeding-limit-enabled": ('boolean', 10, None, None, None, 'Enables the default seed inactivity limit'), + "incomplete-dir": ('string', 7, None, None, None, 'The path to the directory of incomplete transfer data.'), + "incomplete-dir-enabled": ('boolean', 7, None, None, None, 'Enables the incomplete transfer data directory. Otherwise data for incomplete transfers are stored in the download target.'), + "lpd-enabled": ('boolean', 9, None, None, None, 'Enables local peer discovery for public torrents.'), + "peer-limit": ('number', 1, 5, None, 'peer-limit-global', 'Maximum number of peers.'), + "peer-limit-global": ('number', 5, None, 'peer-limit', None, 'Maximum number of peers.'), + "peer-limit-per-torrent": ('number', 5, None, None, None, 'Maximum number of peers per transfer.'), + "pex-allowed": ('boolean', 1, 5, None, 'pex-enabled', 'Allowing PEX in public torrents.'), + "pex-enabled": ('boolean', 5, None, 'pex-allowed', None, 'Allowing PEX in public torrents.'), + "port": ('number', 1, 5, None, 'peer-port', 'Peer port.'), + "peer-port": ('number', 5, None, 'port', None, 'Peer port.'), + "peer-port-random-on-start": ('boolean', 5, None, None, None, 'Enables randomized peer port on start of Transmission.'), + "port-forwarding-enabled": ('boolean', 1, None, None, None, 'Enables port forwarding.'), + "rename-partial-files": ('boolean', 8, None, None, None, 'Appends ".part" to incomplete files'), + "queue-stalled-minutes": ('number', 14, None, None, None, 'Number of minutes of idle that marks a transfer as stalled.'), + "queue-stalled-enabled": ('boolean', 14, None, None, None, 'Enable tracking of stalled transfers.'), + "script-torrent-done-enabled": ('boolean', 9, None, None, None, 'Whether or not to call the "done" script.'), + "script-torrent-done-filename": ('string', 9, None, None, None, 'Filename of the script to run when the transfer is done.'), + "seed-queue-size": ('number', 14, None, None, None, 'Number of slots in the upload queue.'), + "seed-queue-enabled": ('boolean', 14, None, None, None, 'Enables upload queue.'), + "seedRatioLimit": ('double', 5, None, None, None, 'Seed ratio limit. 1.0 means 1:1 download and upload ratio.'), + "seedRatioLimited": ('boolean', 5, None, None, None, 'Enables seed ration limit.'), + "speed-limit-down": ('number', 1, None, None, None, 'Download speed limit (in Kib/s).'), + "speed-limit-down-enabled": ('boolean', 1, None, None, None, 'Enables download speed limiting.'), + "speed-limit-up": ('number', 1, None, None, None, 'Upload speed limit (in Kib/s).'), + "speed-limit-up-enabled": ('boolean', 1, None, None, None, 'Enables upload speed limiting.'), + "start-added-torrents": ('boolean', 9, None, None, None, 'Added torrents will be started right away.'), + "trash-original-torrent-files": ('boolean', 9, None, None, None, 'The .torrent file of added torrents will be deleted.'), + 'utp-enabled': ('boolean', 13, None, None, None, 'Enables Micro Transport Protocol (UTP).'), }, } diff --git a/libs/transmissionrpc/error.py b/libs/transmissionrpc/error.py index 4ad079be..d4971175 100644 --- a/libs/transmissionrpc/error.py +++ b/libs/transmissionrpc/error.py @@ -2,15 +2,13 @@ # Copyright (c) 2008-2013 Erik Svensson # Licensed under the MIT license. -from six import integer_types, string_types - +from six import string_types, integer_types class TransmissionError(Exception): """ - This exception is raised when there has occurred an error related to - communication with Transmission. It is a subclass of Exception. + This exception is raised when there has occurred an error related to + communication with Transmission. It is a subclass of Exception. """ - def __init__(self, message='', original=None): Exception.__init__(self) self.message = message @@ -19,17 +17,15 @@ class TransmissionError(Exception): def __str__(self): if self.original: original_name = type(self.original).__name__ - return '{0} Original exception: {1}, "{2}"'.format(self.message, original_name, str(self.original)) + return '%s Original exception: %s, "%s"' % (self.message, original_name, str(self.original)) else: return self.message - class HTTPHandlerError(Exception): """ - This exception is raised when there has occurred an error related to - the HTTP handler. It is a subclass of Exception. + This exception is raised when there has occurred an error related to + the HTTP handler. It is a subclass of Exception. """ - def __init__(self, httpurl=None, httpcode=None, httpmsg=None, httpheaders=None, httpdata=None): Exception.__init__(self) self.url = '' @@ -49,10 +45,10 @@ class HTTPHandlerError(Exception): self.data = httpdata def __repr__(self): - return ''.format(self.code, self.message) + return '' % (self.code, self.message) def __str__(self): - return 'HTTPHandlerError {0:d}: {1}'.format(self.code, self.message) + return 'HTTPHandlerError %d: %s' % (self.code, self.message) def __unicode__(self): - return 'HTTPHandlerError {0:d}: {1}'.format(self.code, self.message) + return 'HTTPHandlerError %d: %s' % (self.code, self.message) diff --git a/libs/transmissionrpc/httphandler.py b/libs/transmissionrpc/httphandler.py index 5ec981a3..47c5326d 100644 --- a/libs/transmissionrpc/httphandler.py +++ b/libs/transmissionrpc/httphandler.py @@ -4,24 +4,25 @@ import sys -from six.moves.http_client import BadStatusLine -from six.moves.urllib_error import HTTPError, URLError -from six.moves.urllib_request import ( - HTTPBasicAuthHandler, - HTTPDigestAuthHandler, - HTTPPasswordMgrWithDefaultRealm, - Request, - build_opener, -) +from transmissionrpc.error import HTTPHandlerError -from .error import HTTPHandlerError +from six import PY3 +if PY3: + from urllib.request import Request, build_opener, \ + HTTPPasswordMgrWithDefaultRealm, HTTPBasicAuthHandler, HTTPDigestAuthHandler + from urllib.error import HTTPError, URLError + from http.client import BadStatusLine +else: + from urllib2 import Request, build_opener, \ + HTTPPasswordMgrWithDefaultRealm, HTTPBasicAuthHandler, HTTPDigestAuthHandler + from urllib2 import HTTPError, URLError + from httplib import BadStatusLine class HTTPHandler(object): """ Prototype for HTTP handling. """ - def set_authentication(self, uri, login, password): """ Transmission use basic authentication in earlier versions and digest @@ -44,12 +45,10 @@ class HTTPHandler(object): """ raise NotImplementedError("Bad HTTPHandler, failed to implement request.") - class DefaultHTTPHandler(HTTPHandler): """ The default HTTP handler provided with transmissionrpc. """ - def __init__(self): HTTPHandler.__init__(self) self.http_opener = build_opener() @@ -77,7 +76,7 @@ class DefaultHTTPHandler(HTTPHandler): if hasattr(error.reason, 'args') and isinstance(error.reason.args, tuple) and len(error.reason.args) == 2: raise HTTPHandlerError(httpcode=error.reason.args[0], httpmsg=error.reason.args[1]) else: - raise HTTPHandlerError(httpmsg='urllib2.URLError: {error.reason}'.format(error=error)) + raise HTTPHandlerError(httpmsg='urllib2.URLError: %s' % (error.reason)) except BadStatusLine as error: - raise HTTPHandlerError(httpmsg='httplib.BadStatusLine: {error.line}'.format(error=error)) + raise HTTPHandlerError(httpmsg='httplib.BadStatusLine: %s' % (error.line)) return response.read().decode('utf-8') diff --git a/libs/transmissionrpc/session.py b/libs/transmissionrpc/session.py index 2e13a06b..eb01ce15 100644 --- a/libs/transmissionrpc/session.py +++ b/libs/transmissionrpc/session.py @@ -2,10 +2,9 @@ # Copyright (c) 2008-2013 Erik Svensson # Licensed under the MIT license. -from six import integer_types, iteritems - -from .utils import Field +from transmissionrpc.utils import Field +from six import iteritems, integer_types class Session(object): """ @@ -27,12 +26,12 @@ class Session(object): try: return self._fields[name].value except KeyError: - raise AttributeError('No attribute {0}'.format(name)) + raise AttributeError('No attribute %s' % name) def __str__(self): text = '' for key in sorted(self._fields.keys()): - text += "{0:32}: {1}\n".format(key[-32:], self._fields[key].value) + text += "% 32s: %s\n" % (key[-32:], self._fields[key].value) return text def _update_fields(self, other): diff --git a/libs/transmissionrpc/torrent.py b/libs/transmissionrpc/torrent.py index 56821b05..eee66809 100644 --- a/libs/transmissionrpc/torrent.py +++ b/libs/transmissionrpc/torrent.py @@ -2,27 +2,25 @@ # Copyright (c) 2008-2013 Erik Svensson # Licensed under the MIT license. -import datetime -import sys +import sys, datetime -from six import integer_types, iteritems, string_types, text_type +from transmissionrpc.constants import PRIORITY, RATIO_LIMIT, IDLE_LIMIT +from transmissionrpc.utils import Field, format_timedelta -from .constants import IDLE_LIMIT, PRIORITY, RATIO_LIMIT -from .utils import Field, format_timedelta +from six import integer_types, string_types, text_type, iteritems def get_status_old(code): """Get the torrent status using old status codes""" mapping = { - (1 << 0): 'check pending', - (1 << 1): 'checking', - (1 << 2): 'downloading', - (1 << 3): 'seeding', - (1 << 4): 'stopped', + (1<<0): 'check pending', + (1<<1): 'checking', + (1<<2): 'downloading', + (1<<3): 'seeding', + (1<<4): 'stopped', } return mapping[code] - def get_status_new(code): """Get the torrent status using new status codes""" mapping = { @@ -36,7 +34,6 @@ def get_status_new(code): } return mapping[code] - class Torrent(object): """ Torrent is a class holding the data received from Transmission regarding a bittorrent transfer. @@ -74,14 +71,14 @@ class Torrent(object): tid = self._fields['id'].value name = self._get_name_string() if isinstance(name, str): - return ''.format(tid, name) + return '' % (tid, name) else: - return ''.format(tid) + return '' % (tid) def __str__(self): name = self._get_name_string() if isinstance(name, str): - return 'Torrent \"{0}\"'.format(name) + return 'Torrent \"%s\"' % (name) else: return 'Torrent' @@ -92,7 +89,7 @@ class Torrent(object): try: return self._fields[name].value except KeyError: - raise AttributeError('No attribute {0}'.format(name)) + raise AttributeError('No attribute %s' % name) def _rpc_version(self): """Get the Transmission RPC API version.""" @@ -102,9 +99,8 @@ class Torrent(object): def _dirty_fields(self): """Enumerate changed fields""" - outgoing_keys = ['bandwidthPriority', 'downloadLimit', 'downloadLimited', 'peer_limit', 'queuePosition', - 'seedIdleLimit', 'seedIdleMode', 'seedRatioLimit', 'seedRatioMode', 'uploadLimit', - 'uploadLimited'] + outgoing_keys = ['bandwidthPriority', 'downloadLimit', 'downloadLimited', 'peer_limit', 'queuePosition' + , 'seedIdleLimit', 'seedIdleMode', 'seedRatioLimit', 'seedRatioMode', 'uploadLimit', 'uploadLimited'] fields = [] for key in outgoing_keys: if key in self._fields and self._fields[key].dirty: @@ -125,6 +121,7 @@ class Torrent(object): """ Update the torrent data from a Transmission JSON-RPC arguments dictionary """ + fields = None if isinstance(other, dict): for key, value in iteritems(other): self._fields[key.replace('-', '_')] = Field(value, False) @@ -134,7 +131,7 @@ class Torrent(object): else: raise ValueError('Cannot update with supplied data') self._incoming_pending = False - + def _status(self): """Get the torrent status""" code = self._fields['status'].value @@ -267,14 +264,13 @@ class Torrent(object): self._fields['downloadLimited'] = Field(True, True) self._fields['downloadLimit'] = Field(limit, True) self._push() - elif limit is None: + elif limit == None: self._fields['downloadLimited'] = Field(False, True) self._push() else: raise ValueError("Not a valid limit") - download_limit = property(_get_download_limit, _set_download_limit, None, - "Download limit in Kbps or None. This is a mutator.") + download_limit = property(_get_download_limit, _set_download_limit, None, "Download limit in Kbps or None. This is a mutator.") def _get_peer_limit(self): """ @@ -311,7 +307,7 @@ class Torrent(object): self._push() priority = property(_get_priority, _set_priority, None - , "Bandwidth priority as string. Can be one of 'low', 'normal', 'high'. This is a mutator.") + , "Bandwidth priority as string. Can be one of 'low', 'normal', 'high'. This is a mutator.") def _get_seed_idle_limit(self): """ @@ -330,7 +326,7 @@ class Torrent(object): raise ValueError("Not a valid limit") seed_idle_limit = property(_get_seed_idle_limit, _set_seed_idle_limit, None - , "Torrent seed idle limit in minutes. Also see seed_idle_mode. This is a mutator.") + , "Torrent seed idle limit in minutes. Also see seed_idle_mode. This is a mutator.") def _get_seed_idle_mode(self): """ @@ -349,7 +345,7 @@ class Torrent(object): raise ValueError("Not a valid limit") seed_idle_mode = property(_get_seed_idle_mode, _set_seed_idle_mode, None, - """ + """ Seed idle mode as string. Can be one of 'global', 'single' or 'unlimited'. * global, use session seed idle limit. @@ -358,7 +354,7 @@ class Torrent(object): This is a mutator. """ - ) + ) def _get_seed_ratio_limit(self): """ @@ -377,7 +373,7 @@ class Torrent(object): raise ValueError("Not a valid limit") seed_ratio_limit = property(_get_seed_ratio_limit, _set_seed_ratio_limit, None - , "Torrent seed ratio limit as float. Also see seed_ratio_mode. This is a mutator.") + , "Torrent seed ratio limit as float. Also see seed_ratio_mode. This is a mutator.") def _get_seed_ratio_mode(self): """ @@ -396,7 +392,7 @@ class Torrent(object): raise ValueError("Not a valid limit") seed_ratio_mode = property(_get_seed_ratio_mode, _set_seed_ratio_mode, None, - """ + """ Seed ratio mode as string. Can be one of 'global', 'single' or 'unlimited'. * global, use session seed ratio limit. @@ -405,7 +401,7 @@ class Torrent(object): This is a mutator. """ - ) + ) def _get_upload_limit(self): """ @@ -426,14 +422,13 @@ class Torrent(object): self._fields['uploadLimited'] = Field(True, True) self._fields['uploadLimit'] = Field(limit, True) self._push() - elif limit is None: + elif limit == None: self._fields['uploadLimited'] = Field(False, True) self._push() else: raise ValueError("Not a valid limit") - upload_limit = property(_get_upload_limit, _set_upload_limit, None, - "Upload limit in Kbps or None. This is a mutator.") + upload_limit = property(_get_upload_limit, _set_upload_limit, None, "Upload limit in Kbps or None. This is a mutator.") def _get_queue_position(self): """Get the queue position for this torrent.""" diff --git a/libs/transmissionrpc/utils.py b/libs/transmissionrpc/utils.py index e2ad309c..b8e37dfa 100644 --- a/libs/transmissionrpc/utils.py +++ b/libs/transmissionrpc/utils.py @@ -2,19 +2,15 @@ # Copyright (c) 2008-2013 Erik Svensson # Licensed under the MIT license. -import datetime -import logging -import socket +import socket, datetime, logging from collections import namedtuple +import transmissionrpc.constants as constants +from transmissionrpc.constants import LOGGER -from six import iteritems, string_types - -from . import constants -from .constants import LOGGER +from six import string_types, iteritems UNITS = ['B', 'KiB', 'MiB', 'GiB', 'TiB', 'PiB', 'EiB'] - def format_size(size): """ Format byte size into IEC prefixes, B, KiB, MiB ... @@ -24,16 +20,14 @@ def format_size(size): while size >= 1024.0 and i < len(UNITS): i += 1 size /= 1024.0 - return size, UNITS[i] - + return (size, UNITS[i]) def format_speed(size): """ Format bytes per second speed into IEC prefixes, B/s, KiB/s, MiB/s ... """ (size, unit) = format_size(size) - return size, '{unit}/s'.format(unit=unit) - + return (size, unit + '/s') def format_timedelta(delta): """ @@ -41,8 +35,7 @@ def format_timedelta(delta): """ minutes, seconds = divmod(delta.seconds, 60) hours, minutes = divmod(minutes, 60) - return '{0:d} {1:02d}:{2:02d}:{3:02d}'.format(delta.days, hours, minutes, seconds) - + return '%d %02d:%02d:%02d' % (delta.days, hours, minutes, seconds) def format_timestamp(timestamp, utc=False): """ @@ -57,14 +50,12 @@ def format_timestamp(timestamp, utc=False): else: return '-' - class INetAddressError(Exception): """ Error parsing / generating a internet address. """ pass - def inet_address(address, default_port, default_address='localhost'): """ Parse internet address. @@ -81,19 +72,18 @@ def inet_address(address, default_port, default_address='localhost'): try: port = int(addr[1]) except ValueError: - raise INetAddressError('Invalid address "{0}".'.format(address)) + raise INetAddressError('Invalid address "%s".' % address) if len(addr[0]) == 0: addr = default_address else: addr = addr[0] else: - raise INetAddressError('Invalid address "{0}".'.format(address)) + raise INetAddressError('Invalid address "%s".' % address) try: socket.getaddrinfo(addr, port, socket.AF_INET, socket.SOCK_STREAM) except socket.gaierror: - raise INetAddressError('Cannot look up address "{0}".'.format(address)) - return addr, port - + raise INetAddressError('Cannot look up address "%s".' % address) + return (addr, port) def rpc_bool(arg): """ @@ -106,31 +96,27 @@ def rpc_bool(arg): arg = arg.lower() in ['true', 'yes'] return 1 if bool(arg) else 0 - TR_TYPE_MAP = { - 'number': int, - 'string': str, + 'number' : int, + 'string' : str, 'double': float, - 'boolean': rpc_bool, + 'boolean' : rpc_bool, 'array': list, 'object': dict } - def make_python_name(name): """ Convert Transmission RPC name to python compatible name. """ return name.replace('-', '_') - def make_rpc_name(name): """ Convert python compatible name to Transmission RPC name. """ return name.replace('_', '-') - def argument_value_convert(method, argument, value, rpc_version): """ Check and fix Transmission RPC issues with regards to methods, arguments and values. @@ -140,7 +126,7 @@ def argument_value_convert(method, argument, value, rpc_version): elif method in ('session-get', 'session-set'): args = constants.SESSION_ARGS[method[-3:]] else: - return ValueError('Method "{0}" not supported'.format(method)) + return ValueError('Method "%s" not supported' % (method)) if argument in args: info = args[argument] invalid_version = True @@ -156,18 +142,19 @@ def argument_value_convert(method, argument, value, rpc_version): if invalid_version: if replacement: LOGGER.warning( - 'Replacing requested argument "{0}" with "{1}".'.format(argument, replacement)) + 'Replacing requested argument "%s" with "%s".' + % (argument, replacement)) argument = replacement info = args[argument] else: raise ValueError( - 'Method "{0}" Argument "{1}" does not exist in version {2:d}.'.format(method, argument, rpc_version)) - return argument, TR_TYPE_MAP[info[0]](value) + 'Method "%s" Argument "%s" does not exist in version %d.' + % (method, argument, rpc_version)) + return (argument, TR_TYPE_MAP[info[0]](value)) else: raise ValueError('Argument "%s" does not exists for method "%s".', (argument, method)) - def get_arguments(method, rpc_version): """ Get arguments for method in specified Transmission RPC version. @@ -177,7 +164,7 @@ def get_arguments(method, rpc_version): elif method in ('session-get', 'session-set'): args = constants.SESSION_ARGS[method[-3:]] else: - return ValueError('Method "{0}" not supported'.format(method)) + return ValueError('Method "%s" not supported' % (method)) accessible = [] for argument, info in iteritems(args): valid_version = True @@ -189,7 +176,6 @@ def get_arguments(method, rpc_version): accessible.append(argument) return accessible - def add_stdout_logger(level='debug'): """ Add a stdout target for the transmissionrpc logging. @@ -204,7 +190,6 @@ def add_stdout_logger(level='debug'): loghandler.setLevel(loglevel) trpc_logger.addHandler(loghandler) - def add_file_logger(filepath, level='debug'): """ Add a stdout target for the transmissionrpc logging. @@ -219,5 +204,4 @@ def add_file_logger(filepath, level='debug'): loghandler.setLevel(loglevel) trpc_logger.addHandler(loghandler) - Field = namedtuple('Field', ['value', 'dirty'])