From 88741e121c24d8a7e143597d561f78268fb9f086 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=81ukasz=20=C5=BBarnowiecki?= Date: Mon, 27 Apr 2020 16:17:46 +0200 Subject: [PATCH] Add rTorrent backend --- backends/rtorrent.py | 93 ++++++++++++++++++++++++++++++++++++++++++++ tdpt.ini.template | 24 ++++++++---- 2 files changed, 110 insertions(+), 7 deletions(-) create mode 100644 backends/rtorrent.py diff --git a/backends/rtorrent.py b/backends/rtorrent.py new file mode 100644 index 0000000..4627b82 --- /dev/null +++ b/backends/rtorrent.py @@ -0,0 +1,93 @@ +import datetime +import math +import xmlrpc.client + + +class Client: + + def __init__(self, config): + url = f'http://{config["host"]}:{config["port"]}/RPC2' + self.config = config + self.proxy = xmlrpc.client.ServerProxy(url, verbose=False) + + def add_torrent(self, torrent, timeout=None, **kwargs): + self.proxy.load.start_verbose( + '', + torrent.file_path, + [f'd.custom1.set={self.config["set_label"]}']) + + def get_torrents(self): + yield from map(lambda torrent: Torrent(torrent, self.proxy), + self.proxy.download_list()) + + +class Torrent: + + PROPERTIES = { + 'chunk_size': 0, + 'completed_bytes': 1, + 'completed_chunks': 2, + 'down.rate': 3, + 'incomplete': 4, + 'is_active': 5, + 'is_open': 6, + 'name': 7, + 'peers_connected': 8, + 'size_bytes': 9, + 'size_chunks': 10, + } + + def __init__(self, torrent, proxy): + self.torrent = torrent + self.proxy = proxy + + self.multicall = xmlrpc.client.MultiCall(self.proxy) + for prop in self.PROPERTIES: + getattr(self.multicall, 'd.' + prop)(self.torrent) + self.update() + + def is_downloading(self): + return (self.__get_prop('down.rate') and + self.__get_prop('is_open') and + self.__get_prop('is_active')) + + def update(self): + try: + self.data = tuple(self.multicall()) + except: + raise KeyError + + @property + def download_rate(self): + return self.__get_prop('down.rate') + + @property + def eta(self): + if self.__get_prop('down.rate') == 0: + return 'Unavailable' + chunks_left = (self.__get_prop('size_chunks') - + self.__get_prop('completed_chunks')) + down_rate = (chunks_left * + self.__get_prop('chunk_size') / + self.__get_prop('down.rate')) + return datetime.timedelta(seconds=math.floor(down_rate)) + + @property + def id(self): + return self.torrent + + @property + def name(self): + return self.__get_prop('name') + + @property + def peers_connected(self): + return self.__get_prop('peers_connected') + + @property + def percent_done(self): + return (self.__get_prop('completed_bytes') / + self.__get_prop('size_bytes')) + + def __get_prop(self, prop): + return self.data[self.PROPERTIES[prop]] diff --git a/tdpt.ini.template b/tdpt.ini.template index 1138d50..bd71d10 100644 --- a/tdpt.ini.template +++ b/tdpt.ini.template @@ -1,19 +1,29 @@ [General] # Specifies from which torrent client data should be fetched. -backend = Transmission -# When transmission is done with downloading it will execute command or -# script specified in this parameter. With the following environment +# Currently supported are +# * Transmission +# * rTorrent +# You must further uncomment section for that client down below. +#backend = +# When torrent client is done with downloading it will execute command +# or script specified in this parameter. With the following environment # variables: # TORRENT_NAME - name of the torrent that was downloaded #call_on_finish = -[Transmission] -host = 127.0.0.1 -port = 9091 +#[Transmission] +#host = 127.0.0.1 +#port = 9091 + +#[rTorrent] +#host = 127.0.0.1 +#port = 8080 +# Will set label to uploaded torrent visible in ruTorrent. +#set_label = tacajushi-telegram [Telegram] # You can obtain it by asking several question to @BotFather and -# creating your own bot +# creating your own bot. bot_token = # Every user or group has this parameter. If you don't know it ask