From f7a7f161470a31938e80e5bf300c9307ac29c59f Mon Sep 17 00:00:00 2001
From: Matt <matt@mattcarey.me>
Date: Sat, 21 Jan 2017 17:18:00 -0500
Subject: [PATCH] Added support for rTorrent

---
 clients/rtorrent.py | 58 +++++++++++++++++++++++++++++++++++++++++++++
 clients/utorrent.py |  3 +--
 config.ini          |  8 +++----
 influxdbSeedbox.py  | 14 ++++++++++-
 requirements.txt    |  3 ++-
 5 files changed, 77 insertions(+), 9 deletions(-)
 create mode 100644 clients/rtorrent.py

diff --git a/clients/rtorrent.py b/clients/rtorrent.py
new file mode 100644
index 0000000..b199e9f
--- /dev/null
+++ b/clients/rtorrent.py
@@ -0,0 +1,58 @@
+from rtorrent import RTorrent
+from clients.torrentclient import TorrentClient
+import sys
+from urllib.parse import urlsplit
+
+
+class rTorrentClient(TorrentClient):
+
+    def __init__(self, logger, username=None, password=None, url=None, hostname=None):
+
+        TorrentClient.__init__(self, logger, username=username, password=password, url=url, hostname=hostname)
+        self.torrent_client = 'rTorrent'
+        self._authenticate()
+        self.rtorrent = None
+
+        self._authenticate()
+
+    def _authenticate(self):
+        """
+        Setup connection to rTorrent XMLRPC server
+        :return:
+        """
+
+        try:
+            self.rtorrent = RTorrent(self.url)
+        except ConnectionRefusedError as e:
+            self.send_log('Failed to connect to rTorrent.  Aborting', 'critical')
+            sys.exit(1)
+
+        self.send_log('Successfully connected to rTorrent', 'info')
+
+    def _build_torrent_list(self, torrents):
+        """
+        Take the resulting torrent list and create a consistent structure shared through all clients
+        :return:
+        """
+        self.send_log('Structuring list of torrents', 'debug')
+
+        for torrent in torrents:
+            self.torrent_list[torrent.info_hash] = {}
+            self.torrent_list[torrent.info_hash]['name'] = torrent.name
+            self.torrent_list[torrent.info_hash]['total_size'] = torrent.size_bytes
+            self.torrent_list[torrent.info_hash]['progress'] = round((torrent.bytes_done / torrent.size_bytes * 100), 2)
+            self.torrent_list[torrent.info_hash]['total_downloaded'] = torrent.bytes_done
+            self.torrent_list[torrent.info_hash]['total_uploaded'] = 1 # TODO Need to figure out where to get this
+            self.torrent_list[torrent.info_hash]['ratio'] = torrent.ratio
+            self.torrent_list[torrent.info_hash]['total_seeds'] = 'N/A'
+            self.torrent_list[torrent.info_hash]['state'] = torrent.get_state()
+            self.torrent_list[torrent.info_hash]['tracker'] = urlsplit(torrent.get_trackers()[0].url).netloc
+            self.torrent_list[torrent.info_hash]['total_files'] = torrent.size_files
+
+
+    def get_all_torrents(self):
+        """
+        Return list of all torrents
+        :return:
+        """
+        self._build_torrent_list(self.rtorrent.torrents)
diff --git a/clients/utorrent.py b/clients/utorrent.py
index 1d30a23..d98f2bb 100644
--- a/clients/utorrent.py
+++ b/clients/utorrent.py
@@ -68,8 +68,7 @@ class UTorrentClient(TorrentClient):
         :return:
         """
 
-        msg = 'Structuring list of torrents'
-        self.send_log(msg, 'debug')
+        self.send_log('Structuring list of torrents', 'debug')
 
         for torrent in torrents:
             self.torrent_list[torrent[0]] = {}
diff --git a/config.ini b/config.ini
index 0c12b4e..45900ba 100644
--- a/config.ini
+++ b/config.ini
@@ -15,7 +15,8 @@ Verify_SSL = False
 
 [TORRENTCLIENT]
 # Leave blank to auto pick server
-# Valid options are deluge, utorrent
+# Valid Options: deluge, utorrent, rtorrent
+# Deluge only needs password, uTorrent needs user and password, rtorrent needs neither
 Client = utorrent
 Username = admin
 Password =
@@ -26,12 +27,9 @@ Url =
 
 [LOGGING]
 Enable = True
-
 # Valid Options: critical, error, warning, info, debug
 Level = error
-
 LogFile = output.log
-
 # Removes things such as server names and ip addresses from logs
 CensorLogs = False
 
@@ -42,4 +40,4 @@ CensorLogs = False
 # WARNING: 2
 # ERROR: 3
 # CRITICAL: 4
-PrintThreshold = 0
\ No newline at end of file
+PrintThreshold = 2
\ No newline at end of file
diff --git a/influxdbSeedbox.py b/influxdbSeedbox.py
index 23ea24e..7ee02b5 100644
--- a/influxdbSeedbox.py
+++ b/influxdbSeedbox.py
@@ -13,6 +13,7 @@ from influxdb.exceptions import InfluxDBClientError, InfluxDBServerError
 
 # TODO Move urlopen login in each method call to one central method
 # TODO Validate that we get a valid URL from config
+# TODO Deal with multiple trackers per torrent
 
 __author__ = 'barry'
 class configManager():
@@ -21,7 +22,7 @@ class configManager():
 
     def __init__(self, config):
 
-        self.valid_torrent_clients = ['deluge', 'utorrent']
+        self.valid_torrent_clients = ['deluge', 'utorrent', 'rtorrent']
         self.valid_log_levels = {
             'DEBUG': 0,
             'INFO': 1,
@@ -127,6 +128,7 @@ class influxdbSeedbox():
                                            password=self.config.tor_client_password,
                                            url=self.config.tor_client_url,
                                            hostname=self.config.hostname)
+
         elif self.config.tor_client == 'utorrent':
             from clients.utorrent import UTorrentClient
             print('Generating uTorrent Client')
@@ -136,6 +138,15 @@ class influxdbSeedbox():
                                            url=self.config.tor_client_url,
                                            hostname=self.config.hostname)
 
+        elif self.config.tor_client == 'rtorrent':
+            from clients.rtorrent import rTorrentClient
+            print('Generating rTorrent Client')
+            self.tor_client = rTorrentClient(self.send_log,
+                                             username=None,
+                                             password=None,
+                                             url=self.config.tor_client_url,
+                                             hostname=self.config.hostname)
+
     def _set_logging(self):
         """
         Create the logger object if enabled in the config
@@ -257,6 +268,7 @@ def main():
 
     parser = argparse.ArgumentParser(description="A tool to send Torrent Client statistics to InfluxDB")
     parser.add_argument('--config', default='config.ini', dest='config', help='Specify a custom location for the config file')
+    parser.add_argument('--silent', default=False, dest='config', help='Surpress All Output')
     args = parser.parse_args()
     monitor = influxdbSeedbox(config=args.config)
     monitor.run()
diff --git a/requirements.txt b/requirements.txt
index 7738dea..10dcfc8 100644
--- a/requirements.txt
+++ b/requirements.txt
@@ -1,2 +1,3 @@
 influxdb
-beautifulsoup4
\ No newline at end of file
+beautifulsoup4
+rtorrent-python
\ No newline at end of file
-- 
GitLab