Example #1
0
def dwnTorrent(magnet, hash, dir):
    client = DelugeRPCClient(dHost, dPort, dUser, dPass)
    try:
        client.connect()
    except:
        return

    path = ''
    torrent = client.call('core.get_torrent_status', hash, [])

    if torrent:
        percent = float(torrent[b'file_progress'][0] * 100)
        #msg = 'already in deluge ({0})'.format(percent)
    else:
        client.call('core.add_torrent_magnet', magnet,
                    {'download_location': dir})
        #msg = 'not found, adding to deluge'

        #waiting for the files to appear
        while not (client.call('core.get_torrent_status', hash, [])[b'files']):
            time.sleep(2)
        else:
            files = client.call('core.get_torrent_status', hash, [])[b'files']

            for format in video_formats:
                for file in files:
                    if format in file[b'path'].decode('utf-8'):
                        path = file[b'path'].replace(b'/',
                                                     b'\\').decode('utf-8')

    client.disconnect()
    return path
Example #2
0
def downloadTorrent(url):
	url = url + "&authkey=" + AuthKey + "&torrent_pass="******"Downloading: " + url)
	client = DelugeRPCClient(DelugeIp, DelugePort, DelugeUser, DelugePass)
	client.connect()
	hash = client.core.add_torrent_url(url, [], [])
	print("Hash: " + str(hash))
	client.disconnect()
Example #3
0
def get_progress(hash):
    client = DelugeRPCClient(dHost, dPort, dUser, dPass)
    try:
        client.connect()
    except ValueError as err:
        if ('already-connected SSLSocket' in str(err)):
            pass

    torrent = client.call('core.get_torrent_status', hash, [])
    percent = float(torrent[b'progress'])

    client.disconnect()
    return ('%.2f' % percent)
Example #4
0
class DelugeConnect:
    def __init__(self, host, port, username, password):
        self.host = host
        self.port = port
        self.username = username
        self.password = password

    def connect(self):
        #connect based on the host:port and username and password
        self.client = DelugeRPCClient(self.host,
                                      self.port,
                                      self.username,
                                      self.password,
                                      automatic_reconnect=True)
        #please recommend everyone else to make a proper client username and password
        try:
            self.client.connect()
            return "Client connected."
        except Exception as e:
            print(e)
            return "Cannot connect, something is wrong."

    def add_torrent(self, filename):
        torrent = open(filename, 'r').read()
        print(torrent)
        metadata = base64.b64encode(torrent)
        #this function is to add torrent based on the existing torrent file in the name of add_torrent
        return self.client.core.add_torrent_file(filename, metadata, {})

    def get_torrent_status(self):
        raw_progress = self.client.core.get_torrents_status(
            {}, ['name', 'progress'])
        list_of_progress = []
        for a in raw_progress.items():
            list_of_progress.append(a[1])
        return list_of_progress
        #this function is to get the torrent status from a specified ip address

    def disconnect(self):
        try:
            self.client.disconnect()
            return "Disconnected"
        except Exception as e:
            print(e)
            return "Cannot be disconnected, maybe it's already disconnected?"
Example #5
0
class DefineDelugeInterface:
    def __init__(self, address, port, username, password):

        # The actual interface with the deluge daemon, via the RPCClient package
        # This object captures the interface (including address & credentials) to be
        # opened, closed, and used to pass messages to the daemon
        self.delugeinterface = DelugeDaemonInterface(address, port, username,
                                                     password)

        # The deluge keys used for gaining overall session data via the 'core.get_session_status' call
        self.delugekeysforsessioninfo = [
            "payload_download_rate", "payload_upload_rate",
            "total_payload_upload"
        ]

        # The deluge keys used for gaining detailed data about a single torrent via the 'core.get_torrent_status' call
        self.delugekeysfortorrentinfo = [
            "state", "save_path", "name", "total_size", "progress", "eta",
            "files", "tracker_status", "is_finished", "time_added",
            "num_seeds", "num_peers"
        ]

        # The full list deluge keys available for gaining detailed data about a single torrent via the
        # 'core.get_torrent_status' call
        self.alldelugekeysavailablefortorrentinfo = [
            "state", "save_path", "tracker", "tracker_status", "next_announce",
            "name", "total_size", "progress", "num_seeds", "total_seeds",
            "num_peers", "total_peers", "eta", "download_payload_rate",
            "upload_payload_rate", "ratio", "distributed_copies", "num_pieces",
            "piece_length", "total_done", "files", "file_priorities",
            "file_progress", "peers", "is_seed", "is_finished", "active_time",
            "seeding_time"
        ]

# =========================================================================================
# Opens a connection with the deluge daemon, for messages to be passed to/from it
# =========================================================================================

    def openconnection(self):

        # Logging.printout("- Connecting to Deluge Daemon&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<small>(" + reasontext + ")</small>")
        try:
            while self.delugeinterface.connected == False:
                self.delugeinterface.connect()
        # print "========================================================="
        # print self.delugeinterface.call('client.api_methods')
        # print "========================================================="
        # WORKS! print self.delugeinterface.call('core.get_free_space')
        # print "========================================================="
        # WORKS! print self.delugeinterface.call('core.get_config')
        # print "========================================================="
            outcome = self.delugeinterface.connected
        except Exception as errortype:
            outcome = None
            print(
                "DELUGE INTERFACE ERROR: Trying to connect to deluge client (",
                errortype, ")")

        return outcome

# =========================================================================================
# Closes the open connection with the deluge daemon
# =========================================================================================

    def closeconnection(self):

        try:
            while self.delugeinterface.connected == True:
                self.delugeinterface.disconnect()
            outcome = self.delugeinterface.connected
        except Exception as errortype:
            outcome = None
            print(
                "DELUGE INTERFACE ERROR: Trying to disconnect from deluge client (",
                errortype, ")")

        return outcome

# =========================================================================================
# Returns a list of strings, one per torrent, providing the GUID of each torrent
# =========================================================================================

    def retrievetorrentlist(self):

        try:
            outcome = []
            rawtorrentlist = self.delugeinterface.call(
                'core.get_session_state')

            for rawtorrentid in rawtorrentlist:
                outcome.append(rawtorrentid.decode("ascii", "ignore"))

        except Exception as errortype:
            print("DELUGE INTERFACE ERROR: Trying to retrieve torrent list (",
                  errortype, ")")
            outcome = None

        return outcome

# =========================================================================================
# Returns a structured/layered dictionary of information about a specified (by GUID) torrent
# =========================================================================================

    def retrievetorrentdata(self, torrentid):

        try:
            outcome = {}
            rawtorrentdata = self.delugeinterface.call(
                'core.get_torrent_status', torrentid,
                self.delugekeysfortorrentinfo)

            for itemkey in rawtorrentdata:
                itemdata = rawtorrentdata[itemkey]
                newkeyname = itemkey.decode("utf-8", "ignore")

                if isinstance(itemdata, bytes) == True:
                    outcome[newkeyname] = itemdata.decode("utf-8", "ignore")

                elif isinstance(itemdata, tuple) == True:
                    newlist = []
                    for subitem in itemdata:
                        newsubdictionary = {}
                        for subitemkey in subitem:
                            newsubitemkey = subitemkey.decode(
                                "utf-8", "ignore")
                            if isinstance(subitem[subitemkey], bytes) == True:
                                newsubitemdata = subitem[subitemkey].decode(
                                    "utf-8", "ignore")
                            else:
                                newsubitemdata = subitem[subitemkey]
                            newsubdictionary[newsubitemkey] = newsubitemdata
                        newlist.append(newsubdictionary)
                    outcome[newkeyname] = newlist

                else:
                    outcome[newkeyname] = itemdata

        except Exception as errortype:
            print(
                "DELUGE INTERFACE ERROR: Trying to retrieve torrent data for "
                + torrentid + " (", errortype, ")")
            outcome = None

        return outcome

# =========================================================================================
# Adds a new torrent to the daemon, using the specified link URL
# Returns the GUID of the added torrent
# =========================================================================================

    def addtorrentlink(self, linkstring):

        try:
            if linkstring[:7] == "magnet:":
                newtorrentid = self.delugeinterface.call(
                    'core.add_torrent_magnet', linkstring, {})
            else:
                newtorrentid = self.delugeinterface.call(
                    'core.add_torrent_url', linkstring, {})
            outcome = newtorrentid.decode("ascii", "ignore")

        except Exception as errortype:
            print("DELUGE INTERFACE ERROR: Trying to add new torrent (",
                  errortype, ")")
            outcome = None

        return outcome

# =========================================================================================
# Instigates a recheck of the specified (by GUID) torrent
# (Returns the RPCClient response, an unknown object)
# =========================================================================================

    def rechecktorrent(self, torrentids):

        try:
            outcome = self.delugeinterface.call('core.force_recheck',
                                                torrentids)
        except Exception as errortype:
            print(
                "DELUGE INTERFACE ERROR: Trying to force recheck of torrent " +
                torrentids + " (", errortype, ")")
            outcome = None
        return outcome

# =========================================================================================
# Pauses the specified (by GUID) torrent
# If "ALL" is specified, all torrents in the daemon are paused
# (Returns the RPCClient response, an unknown object)
# =========================================================================================

    def pausetorrent(self, torrentid):

        try:
            if torrentid == "ALL":
                outcome = self.delugeinterface.call('core.pause_all_torrents')
            else:
                outcome = self.delugeinterface.call('core.pause_torrent',
                                                    [torrentid])
        except Exception as errortype:
            print(
                "DELUGE INTERFACE ERROR: Trying to pause torrent " +
                torrentid + " (", errortype, ")")
            outcome = None

        return outcome

# =========================================================================================
# Unpauses the specified (by GUID) torrent
# If "ALL" is specified, all torrents in the daemon are unpaused
# (Returns the RPCClient response, an unknown object)
# =========================================================================================

    def resumetorrent(self, torrentid):

        try:
            if torrentid == "ALL":
                outcome = self.delugeinterface.call('core.resume_all_torrents')
            else:
                outcome = self.delugeinterface.call('core.resume_torrent',
                                                    [torrentid])

        except Exception as errortype:
            print(
                "DELUGE INTERFACE ERROR: Trying to resume torrent " +
                torrentid + " (", errortype, ")")
            outcome = None

        return outcome

# =========================================================================================
# Deletes the specified (by GUID) torrent
# (Returns the RPCClient response, an unknown object)
# =========================================================================================

    def deletetorrent(self, torrentid):

        try:
            outcome = self.delugeinterface.call('core.remove_torrent',
                                                torrentid, True)
        except Exception as errortype:
            print(
                "DELUGE INTERFACE ERROR: Trying to delete torrent " +
                torrentid + " (", errortype, ")")
            outcome = None

        return outcome

# =========================================================================================
# Returns a dictionary of information about the daemon session
# =========================================================================================

    def retrievesessiondata(self):

        try:
            rawstats1 = self.delugeinterface.call(
                'core.get_session_status', self.delugekeysforsessioninfo)
            rawstats2 = self.delugeinterface.call('core.get_free_space')

            outcome = {}
            outcome['uploadspeed'] = rawstats1[b'payload_upload_rate']
            outcome['downloadspeed'] = rawstats1[b'payload_download_rate']
            outcome['uploadedtotal'] = rawstats1[b'total_payload_upload']
            outcome['freespace'] = rawstats2 / 1000000000

        except Exception as errortype:
            print("DELUGE INTERFACE ERROR: Trying to retrieve session data (",
                  errortype, ")")
            outcome = None

        return outcome
Example #6
0
class DelugeRPC(object):
    """Deluge RPC client class."""

    def __init__(self, host='localhost', port=58846, username=None, password=None):
        """Constructor.

        :param host:
        :type host: str
        :param port:
        :type port: int
        :param username:
        :type username: str
        :param password:
        :type password: str
        """
        super(DelugeRPC, self).__init__()
        self.host = host
        self.port = int(port)
        self.username = username
        self.password = password

    def connect(self):
        """Connect to the host using synchronousdeluge API."""
        self.client = DelugeRPCClient(self.host, self.port, self.username, self.password, decode_utf8=True)
        self.client.connect()

    def test(self):
        """Test connection.

        :return:
        :rtype: bool
        """
        try:
            self.connect()
        except Exception:
            return False
        else:
            return True

    def remove_torrent_data(self, torrent_id):
        """Remove torrent from client using given info_hash.

        :param torrent_id:
        :type torrent_id: str
        :return:
        :rtype: str or bool
        """
        try:
            self.connect()
            self.client.core.remove_torrent(torrent_id, True)
        except Exception:
            return False
        else:
            return True
        finally:
            if self.client:
                self.disconnect()

    def move_storage(self, torrent_id, location):
        """Move torrent to new location and return torrent id/hash.

        :param torrent_id:
        :type torrent_id: str
        :param location:
        :type location: str
        :return:
        :rtype: str or bool
        """
        try:
            self.connect()
            self.client.core.move_storage([torrent_id], location)
        except Exception:
            return False
        else:
            return True
        finally:
            if self.client:
                self.disconnect()

    def add_torrent_magnet(self, torrent, options, info_hash):
        """Add Torrent magnet and return torrent id/hash.

        :param torrent:
        :type torrent: str
        :param options:
        :type options: dict
        :param info_hash:
        :type info_hash: str
        :return:
        :rtype: str or bool
        """
        try:
            self.connect()
            torrent_id = self.client.core.add_torrent_magnet(torrent, options)
            if not torrent_id:
                torrent_id = self._check_torrent(info_hash)
        except Exception:
            raise
            return False
        else:
            return torrent_id
        finally:
            if self.client:
                self.disconnect()

    def add_torrent_file(self, filename, torrent, options, info_hash):
        """Add Torrent file and return torrent id/hash.

        :param filename:
        :type filename: str
        :param torrent:
        :type torrent: str
        :param options:
        :type options: dict
        :param info_hash:
        :type info_hash: str
        :return:
        :rtype: str or bool
        """
        try:
            self.connect()
            torrent_id = self.client.core.add_torrent_file(filename, b64encode(torrent), options)
            if not torrent_id:
                torrent_id = self._check_torrent(info_hash)
        except Exception:
            return False
        else:
            return torrent_id
        finally:
            if self.client:
                self.disconnect()

    def set_torrent_label(self, torrent_id, label):
        """Set Torrent label.

        :param torrent_id:
        :type torrent_id: str
        :param label:
        :type label: str
        :return:
        :rtype: bool
        """
        try:
            self.connect()
            self.client.label.set_torrent(torrent_id, label)
        except Exception:
            return False
        else:
            return True
        finally:
            if self.client:
                self.disconnect()

    def set_torrent_path(self, torrent_id, path):
        """Set Torrent path.

        :param torrent_id:
        :type torrent_id: str
        :param path:
        :type path: str
        :return:
        :rtype: bool
        """
        try:
            self.connect()
            self.client.core.set_torrent_move_completed_path(torrent_id, path)
            self.client.core.set_torrent_move_completed(torrent_id, 1)
        except Exception:
            return False
        else:
            return True
        finally:
            if self.client:
                self.disconnect()

    def set_torrent_priority(self, torrent_id, priority):
        """Set Torrent priority.

        :param torrent_id:
        :type torrent_id: str
        :param priority:
        :type priority: bool
        :return:
        :rtype: bool
        """
        try:
            self.connect()
            if priority:
                self.client.core.queue_top([torrent_id])
        except Exception:
            return False
        else:
            return True
        finally:
            if self.client:
                self.disconnect()

    def set_torrent_ratio(self, torrent_id, ratio):
        """Set Torrent ratio.

        :param torrent_id:
        :type torrent_id: str
        :param ratio:
        :type ratio: float
        :return:
        :rtype: bool
        """
        try:
            self.connect()
            self.client.core.set_torrent_stop_at_ratio(torrent_id, True)
            self.client.core.set_torrent_stop_ratio(torrent_id, ratio)
        except Exception:
            return False
        else:
            return True
        finally:
            if self.client:
                self.disconnect()

    def pause_torrent(self, torrent_ids):
        """Pause torrent.

        :param torrent_ids:
        :type torrent_ids: list of str
        :return:
        :rtype: bool
        """
        try:
            self.connect()
            self.client.core.pause_torrent(torrent_ids)
        except Exception:
            return False
        else:
            return True
        finally:
            if self.client:
                self.disconnect()

    def disconnect(self):
        """Disconnect RPC client."""
        self.client.disconnect()

    def _check_torrent(self, info_hash):
        torrent_id = self.client.core.get_torrent_status(info_hash, {})
        if torrent_id.get('hash'):
            log.debug('DelugeD: Torrent already exists in Deluge')
            return info_hash
        return False

    def get_all_torrents(self):
        """Get all torrents in client.

        :return:
        :rtype: bool
        """
        try:
            self.connect()
            torrents_data = self.client.core.get_torrents_status({}, ('name', 'hash', 'progress', 'state',
                                                                      'ratio', 'stop_ratio', 'is_seed', 'is_finished',
                                                                      'paused', 'files'))
        except Exception:
            return False
        else:
            return torrents_data
        finally:
            if self.client:
                self.disconnect()
Example #7
0
class DelugePlugin(object):
    """Base class for deluge plugins, contains settings and methods for connecting to a deluge daemon."""
    def on_task_start(self, task, config):
        """Raise a DependencyError if our dependencies aren't available"""
        try:
            from deluge_client import DelugeRPCClient
        except ImportError as e:
            log.debug('Error importing deluge-client: %s' % e)
            raise plugin.DependencyError(
                'deluge', 'deluge-client',
                'deluge-client >=1.5 is required. `pip install deluge-client` to install.',
                log)
        config = self.prepare_config(config)

        if config['host'] in ['localhost', '127.0.0.1'
                              ] and not config.get('username'):
            # If an username is not specified, we have to do a lookup for the localclient username/password
            auth = self.get_localhost_auth()
            if auth and auth[0]:
                config['username'], config['password'] = auth
            else:
                raise plugin.PluginError(
                    'Unable to get local authentication info for Deluge. You may need to '
                    'specify an username and password from your Deluge auth file.'
                )

        self.client = DelugeRPCClient(config['host'],
                                      config['port'],
                                      config['username'],
                                      config['password'],
                                      decode_utf8=True)

    def on_task_abort(self, task, config):
        pass

    def prepare_config(self, config):
        config.setdefault('host', 'localhost')
        config.setdefault('port', 58846)
        return config

    def connect(self):
        """Connects to the deluge daemon and runs on_connect_success """

        self.client.connect()

        if not self.client.connected:
            raise plugin.PluginError('Deluge failed to connect.')

    def disconnect(self):
        self.client.disconnect()

    def get_torrents_status(self, fields, filters=None):
        """Fetches all torrents and their requested fields optionally filtered"""
        if filters is None:
            filters = {}
        return self.client.call('core.get_torrents_status', filters, fields)

    @staticmethod
    def get_localhost_auth():
        if sys.platform.startswith('win'):
            auth_file = os.path.join(os.getenv('APPDATA'), 'deluge', 'auth')
        else:
            auth_file = os.path.expanduser('~/.config/deluge/auth')

        with open(auth_file) as auth:
            for line in auth:
                line = line.strip()
                if line.startswith('#') or not line:
                    # This is a comment or blank line
                    continue

                lsplit = line.split(':')
                if lsplit[0] == 'localclient':
                    username, password = lsplit[:2]
                    return username, password
Example #8
0
class DelugePlugin(object):
    """Base class for deluge plugins, contains settings and methods for connecting to a deluge daemon."""

    def on_task_start(self, task, config):
        """Raise a DependencyError if our dependencies aren't available"""
        try:
            from deluge_client import DelugeRPCClient
        except ImportError as e:
            log.debug('Error importing deluge-client: %s' % e)
            raise plugin.DependencyError('deluge', 'deluge-client',
                                         'deluge-client >=1.5 is required. `pip install deluge-client` to install.',
                                         log)
        config = self.prepare_config(config)

        if config['host'] in ['localhost', '127.0.0.1'] and not config.get('username'):
            # If an username is not specified, we have to do a lookup for the localclient username/password
            auth = self.get_localhost_auth()
            if auth and auth[0]:
                config['username'], config['password'] = auth
            else:
                raise plugin.PluginError('Unable to get local authentication info for Deluge. You may need to '
                                         'specify an username and password from your Deluge auth file.')

        self.client = DelugeRPCClient(config['host'], config['port'], config['username'], config['password'],
                                      decode_utf8=True)

    def on_task_abort(self, task, config):
        pass

    def prepare_config(self, config):
        config.setdefault('host', 'localhost')
        config.setdefault('port', 58846)
        return config

    def connect(self):
        """Connects to the deluge daemon and runs on_connect_success """

        self.client.connect()

        if not self.client.connected:
            raise plugin.PluginError('Deluge failed to connect.')

    def disconnect(self):
        self.client.disconnect()

    def get_torrents_status(self, fields, filters=None):
        """Fetches all torrents and their requested fields optionally filtered"""
        if filters is None:
            filters = {}
        return self.client.call('core.get_torrents_status', filters, fields)

    @staticmethod
    def get_localhost_auth():
        if sys.platform.startswith('win'):
            auth_file = os.path.join(os.getenv('APPDATA'), 'deluge', 'auth')
        else:
            auth_file = os.path.expanduser('~/.config/deluge/auth')
        if not os.path.isfile(auth_file):
            return None

        with open(auth_file) as auth:
            for line in auth:
                line = line.strip()
                if line.startswith('#') or not line:
                    # This is a comment or blank line
                    continue

                lsplit = line.split(':')
                if lsplit[0] == 'localclient':
                    username, password = lsplit[:2]
                    return username, password
Example #9
0
class DelugeService:
    # list of deluge filed - https://libtorrent.org/single-page-ref.html

    def __init__(self, config):
        self._deluge_client = DelugeRPCClient(config.get('deluge', 'host'),
                                              int(config.get('deluge',
                                                             'port')),
                                              config.get('deluge', 'username'),
                                              config.get('deluge', 'password'),
                                              decode_utf8=True)
        self._deluge_client.connect()
        self._label_enable = False
        try:
            self._label_enable = bool(
                strtobool(config.get('deluge', 'LabelEnable',
                                     fallback='false')))
        except ValueError:
            pass

        self._label_id = config.get('deluge', 'LabelId', fallback=None)

        if self._is_label_enabled():
            self.create_label(self._label_id)

    def add_torrent_magnet(self, magnet_url: str) -> str:
        # https://github.com/deluge-torrent/deluge/blob/deluge-2.0.3/deluge/core/core.py#L556
        torrent_id = self._deluge_client.core.add_torrent_magnet(
            magnet_url, {})
        if self._is_label_enabled():
            self.set_torrent_label(torrent_id, self._label_id)
        return torrent_id

    def add_torrent_file(self, file_name: str, file_base64_str: str) -> str:
        # https://github.com/deluge-torrent/deluge/blob/deluge-2.0.3/deluge/core/core.py#L407
        torrent_id = self._deluge_client.core.add_torrent_file(
            file_name, file_base64_str, {})
        if self._is_label_enabled():
            self.set_torrent_label(torrent_id, self._label_id)
        return torrent_id

    def create_label(self, label_id: str):
        # https://github.com/deluge-torrent/deluge/blob/deluge-2.0.3/deluge/plugins/Label/deluge_label/core.py#L178
        try:
            self._deluge_client.label.add(label_id)
        except Exception as e:
            if 'Exception: Label already exists' not in str(e):
                raise e

    def delete_label(self, label_id: str):
        # https://github.com/deluge-torrent/deluge/blob/deluge-2.0.3/deluge/plugins/Label/deluge_label/core.py#L193
        try:
            self._deluge_client.label.remove(label_id)
        except Exception as e:
            if 'Exception: Unknown Label' not in str(e):
                raise e

    def get_labels(self) -> List[str]:
        # https://github.com/deluge-torrent/deluge/blob/deluge-2.0.3/deluge/plugins/Label/deluge_label/core.py#L173
        return self._deluge_client.label.get_labels()

    def set_torrent_label(self, torrent_id: str, label_id: str):
        # https://github.com/deluge-torrent/deluge/blob/deluge-2.0.3/deluge/plugins/Label/deluge_label/core.py#L312
        self._deluge_client.label.set_torrent(torrent_id, label_id)

    def delete_torrent(self, torrent_id: str):
        # https://github.com/deluge-torrent/deluge/blob/deluge-2.0.3/deluge/core/core.py#L574
        self._deluge_client.core.remove_torrent(torrent_id, False)

    def torrent_name_by_id(self, torrent_id: str) -> str:
        # https://github.com/deluge-torrent/deluge/blob/deluge-2.0.3/deluge/core/core.py#L758
        return self._deluge_client.core.get_torrent_status(
            torrent_id, ['name'])['name']

    def torrent_status(self, torrent_id: str) -> Dict[str, str]:
        # https://github.com/deluge-torrent/deluge/blob/deluge-2.0.3/deluge/core/core.py#L758
        return self._deluge_client.core.get_torrent_status(
            torrent_id, ['name', 'state'])

    def torrents_status(self, torrent_ids: List[str]) -> List[Dict[str, str]]:
        fields = ['name', 'state', 'progress', 'completed_time', 'time_added']
        torrents_dict = self._deluge_client.core.get_torrents_status(
            {"id": [i for i in torrent_ids]}, fields)
        return DelugeService._dict_key_to_obj(torrents_dict)

    def labeled_torrents(self) -> List[Dict[str, str]]:
        if self._is_label_enabled():
            fields = [
                'name', 'state', 'progress', 'completed_time', 'time_added'
            ]
            labeled_torrents = self._deluge_client.core.get_torrents_status(
                {'label': self._label_id}, fields)
            return DelugeService._dict_key_to_obj(labeled_torrents)
        else:
            return []

    def stop_download_torrents(self):
        self._deluge_client.core.set_config({'max_download_speed': "0"})

    def resume_download_torrents(self):
        self._deluge_client.core.set_config({'max_download_speed': "-1"})

    def _is_label_enabled(self) -> bool:
        if self._label_enable and self._label_id:
            return True
        else:
            return False

    @staticmethod
    def _dict_key_to_obj(d) -> List[Dict[str, str]]:
        if not d or not len(d):
            return []
        torrents = []
        for key, value in d.items():
            value['_id'] = key
            torrents.append(value)
        return torrents

    def disconnect(self):
        self._deluge_client.disconnect()
DelugeIp = "<Deluge IP>"
DelugePort = <Deluge Port>
DelugeUser = "******"
DelugePass = "******"

client = DelugeRPCClient(DelugeIp, DelugePort, DelugeUser, DelugePass)
client.connect()

mtvTorrents = client.core.get_torrents_status({"tracker_host": "morethantv.net"}, ["total_wanted"])
mtvTotalSize = 0
for i in mtvTorrents:
	mtvTotalSize += int(mtvTorrents[i]["total_wanted"])
mtvTotalSize = mtvTotalSize / 1024 / 1024 / 1024
print("MTV:   " + str(mtvTotalSize))

ptpTorrents = client.core.get_torrents_status({"tracker_host": "passthepopcorn.me"}, ["total_wanted"])
ptpTotalSize = 0
for i in ptpTorrents:
	ptpTotalSize += int(ptpTorrents[i]["total_wanted"])
ptpTotalSize = ptpTotalSize / 1024 / 1024 / 1024
print("PTP:   " + str(ptpTotalSize))

torrents = client.core.get_torrents_status({}, ["total_wanted"])
totalSize = 0
for i in torrents:
	totalSize += int(torrents[i]["total_wanted"])
totalSize = totalSize / 1024 / 1024 / 1024
print("Total: " + str(totalSize))

client.disconnect()
Example #11
0
class DelugeClient(BTClientBase):
    def __init__(self, rpc_address, rpc_port, username, password, config=None):
        if config is None:
            self.use_config = False
            self.rpc_address = rpc_address
            self.rpc_port = int(rpc_port)
            self.username = username
            self.password = password

            self.client = DelugeRPCClient(self.rpc_address,
                                          self.rpc_port,
                                          self.username,
                                          self.password,
                                          automatic_reconnect=True)
            self.connected = False
        else:
            self.use_config = True
            self.config = config

    def connect(self):
        self.client.connect()
        self.connected = self.client.connected

        if self.connected:
            ret = ClientRet(ret_type=2)
        else:
            ret = ClientRet(ret_type=-2)
        return ret

    def add_torrent(self, torrent_path, download_path=None):
        if not self.connected:
            ret = ClientRet(ret_type=-2)
            return ret

        options = {
        }  # Ref: https://github.com/deluge-torrent/deluge/blob/1.3-stable/deluge/core/torrent.py
        options['add_paused'] = False
        if download_path is not None:
            options['download_location'] = str(Path(download_path).resolve())

        abs_torrent_path = str(Path(torrent_path).resolve())
        torrent_content = open(abs_torrent_path, 'rb').read()
        torrent_base64 = base64.b64encode(torrent_content)

        torrent_idx = self.client.core.add_torrent_file(
            filename=abs_torrent_path,
            filedump=torrent_base64,
            options=options)

        if torrent_idx is not None:
            ret = ClientRet(ret_type=3, ret_value=torrent_idx.decode())
        else:
            ret = ClientRet(ret_type=-3)

        return ret

    def list_torrents(self):
        if not self.connected:
            ret = ClientRet(ret_type=-2)
            return ret

        torrent_id_list = self.client.core.get_session_state()
        session_status = {}
        for idx in torrent_id_list:
            torrent_status_raw = self.client.core.get_torrent_status(
                torrent_id=idx, keys=bt_client.client_base.torrent_status_key)
            torrent_status = TorrentStatus(
                torrent_id=idx.decode(),
                is_finished=torrent_status_raw['is_finished'.encode()],
                name=torrent_status_raw['name'.encode()].decode())
            session_status[torrent_status.torrent_id] = torrent_status

        ret = ClientRet(ret_type=4, ret_value=session_status)

        return ret

    def get_torrent_status(
        self, idx
    ):  # All the value inputted and returned back should be string, not bytearray
        if not self.connected:
            ret = ClientRet(ret_type=-2)
            return ret

        idx = idx.encode()  # Convert to byte array for Deluge
        torrent_status_raw = self.client.core.get_torrent_status(
            torrent_id=idx, keys=bt_client.client_base.torrent_status_key)
        torrent_status = TorrentStatus(
            torrent_id=idx.decode(),
            is_finished=torrent_status_raw[
                'is_finished'.encode()],  # Decode bytearray to string
            name=torrent_status_raw[
                'name'.encode()].decode())  # Decode bytearray to string

        ret = ClientRet(ret_type=6, ret_value=torrent_status)
        return ret

    def del_torrent(self, idx, remove_data=True):
        if not self.connected:
            ret = ClientRet(ret_type=-2)
            return ret

        idx_byte = str(idx).encode()
        torrent_id_list = self.client.core.get_session_state()
        if idx_byte in torrent_id_list:
            self.client.core.remove_torrent(torrent_id=idx_byte,
                                            remove_data=remove_data)
            tlist = self.client.core.get_session_state()
            if idx not in tlist:
                ret = ClientRet(ret_type=5)
                return ret
            else:
                ret = ClientRet(ret_type=-5)
                return ret
        else:
            ret = ClientRet(ret_type=-5)
            return ret

    def disconnect(self):
        if self.connected:
            self.client.disconnect()
            self.connected = False
        ret = ClientRet(ret_type=0)
        return ret
Example #12
0
import shutil
import xmlrpclib
from deluge_client import DelugeRPCClient

DelugeIp = "<Deluge IP>"
DelugePort = <Deluge Port>
DelugeUser = "******"
DelugePass = "******"
DelugeStatePath = "/home/user1/.config/deluge/state/"
rTorrentUrl = "https://<Username>:<Password>@<XmlRpc Url>
TorrentLabel = "Archive/MoreThanTV"
TorrentPath = "/home/user1/torrents/rtorrent/archive/morethantv/"
TempPath = "/home/user1/scripts/ruTorrentXmlRpc/temp/"

if not os.path.exists(TempPath):
	os.makedirs(TempPath)

dClient = DelugeRPCClient(DelugeIp, DelugePort, DelugeUser, DelugePass)
dClient.connect()
rClient = xmlrpclib.ServerProxy(rTorrentUrl);

torrents = dClient.core.get_torrents_status({"tracker_host": "morethantv.net"}, [])
for t in torrents:
	print([t])
	dClient.core.move_storage([t], TorrentPath)
	shutil.copyfile(DelugeStatePath + str(t) + ".torrent", TempPath + str(t) + ".torrent") 
	dClient.core.remove_torrent(t, False)
	rClient.load_start_verbose(TempPath + str(t) + ".torrent", "d.custom1.set=" + TorrentLabel, "d.directory.set=" + TorrentPath, "d.delete_tied=")

dClient.disconnect()
Example #13
0
class DelugeRPC(object):
    """Deluge RPC client class."""

    def __init__(self, host='localhost', port=58846, username=None, password=None):
        """Constructor.

        :param host:
        :type host: str
        :param port:
        :type port: int
        :param username:
        :type username: str
        :param password:
        :type password: str
        """
        super(DelugeRPC, self).__init__()
        self.host = host
        self.port = int(port)
        self.username = username
        self.password = password

    def connect(self):
        """Connect to the host using synchronousdeluge API."""
        self.client = DelugeRPCClient(self.host, self.port, self.username, self.password, decode_utf8=True)
        self.client.connect()

    def test(self):
        """Test connection.

        :return:
        :rtype: bool
        """
        try:
            self.connect()
        except Exception:
            return False
        else:
            return True

    def remove_torrent_data(self, torrent_id):
        """Remove torrent from client using given info_hash.

        :param torrent_id:
        :type torrent_id: str
        :return:
        :rtype: str or bool
        """
        try:
            self.connect()
            self.client.core.remove_torrent(torrent_id, True)
        except Exception:
            return False
        else:
            return True
        finally:
            if self.client:
                self.disconnect()

    def move_storage(self, torrent_id, location):
        """Move torrent to new location and return torrent id/hash.

        :param torrent_id:
        :type torrent_id: str
        :param location:
        :type location: str
        :return:
        :rtype: str or bool
        """
        try:
            self.connect()
            self.client.core.move_storage(torrent_id, location)
        except Exception:
            return False
        else:
            return True
        finally:
            if self.client:
                self.disconnect()

    def add_torrent_magnet(self, torrent, options, info_hash):
        """Add Torrent magnet and return torrent id/hash.

        :param torrent:
        :type torrent: str
        :param options:
        :type options: dict
        :param info_hash:
        :type info_hash: str
        :return:
        :rtype: str or bool
        """
        try:
            self.connect()
            torrent_id = self.client.core.add_torrent_magnet(torrent, options)
            if not torrent_id:
                torrent_id = self._check_torrent(info_hash)
        except Exception:
            raise
            return False
        else:
            return torrent_id
        finally:
            if self.client:
                self.disconnect()

    def add_torrent_file(self, filename, torrent, options, info_hash):
        """Add Torrent file and return torrent id/hash.

        :param filename:
        :type filename: str
        :param torrent:
        :type torrent: str
        :param options:
        :type options: dict
        :param info_hash:
        :type info_hash: str
        :return:
        :rtype: str or bool
        """
        try:
            self.connect()
            torrent_id = self.client.core.add_torrent_file(filename, b64encode(torrent), options)
            if not torrent_id:
                torrent_id = self._check_torrent(info_hash)
        except Exception:
            return False
        else:
            return torrent_id
        finally:
            if self.client:
                self.disconnect()

    def set_torrent_label(self, torrent_id, label):
        """Set Torrent label.

        :param torrent_id:
        :type torrent_id: str
        :param label:
        :type label: str
        :return:
        :rtype: bool
        """
        try:
            self.connect()
            self.client.label.set_torrent(torrent_id, label)
        except Exception:
            return False
        else:
            return True
        finally:
            if self.client:
                self.disconnect()

    def set_torrent_path(self, torrent_id, path):
        """Set Torrent path.

        :param torrent_id:
        :type torrent_id: str
        :param path:
        :type path: str
        :return:
        :rtype: bool
        """
        try:
            self.connect()
            self.client.core.set_torrent_move_completed_path(torrent_id, path)
            self.client.core.set_torrent_move_completed(torrent_id, 1)
        except Exception:
            return False
        else:
            return True
        finally:
            if self.client:
                self.disconnect()

    def set_torrent_priority(self, torrent_id, priority):
        """Set Torrent priority.

        :param torrent_id:
        :type torrent_id: str
        :param priority:
        :type priority: bool
        :return:
        :rtype: bool
        """
        try:
            self.connect()
            if priority:
                self.client.core.queue_top([torrent_id])
        except Exception:
            return False
        else:
            return True
        finally:
            if self.client:
                self.disconnect()

    def set_torrent_ratio(self, torrent_id, ratio):
        """Set Torrent ratio.

        :param torrent_id:
        :type torrent_id: str
        :param ratio:
        :type ratio: float
        :return:
        :rtype: bool
        """
        try:
            self.connect()
            self.client.core.set_torrent_stop_at_ratio(torrent_id, True)
            self.client.core.set_torrent_stop_ratio(torrent_id, ratio)
        except Exception:
            return False
        else:
            return True
        finally:
            if self.client:
                self.disconnect()

    def pause_torrent(self, torrent_ids):
        """Pause torrent.

        :param torrent_ids:
        :type torrent_ids: list of str
        :return:
        :rtype: bool
        """
        try:
            self.connect()
            self.client.core.pause_torrent(torrent_ids)
        except Exception:
            return False
        else:
            return True
        finally:
            if self.client:
                self.disconnect()

    def disconnect(self):
        """Disconnect RPC client."""
        self.client.disconnect()

    def _check_torrent(self, info_hash):
        torrent_id = self.client.core.get_torrent_status(info_hash, {})
        if torrent_id.get('hash'):
            log.debug('DelugeD: Torrent already exists in Deluge')
            return info_hash
        return False

    def get_all_torrents(self):
        """Get all torrents in client.

        :return:
        :rtype: bool
        """
        try:
            self.connect()
            torrents_data = self.client.core.get_torrents_status({}, ('name', 'hash', 'progress', 'state',
                                                                      'ratio', 'stop_ratio', 'is_seed', 'is_finished',
                                                                      'paused', 'files'))
        except Exception:
            return False
        else:
            return torrents_data
        finally:
            if self.client:
                self.disconnect()
Example #14
0
class DelugeRPC(object):
    """Deluge RPC client class."""

    def __init__(self, host='localhost', port=58846, username=None, password=None):
        """Deluge RPC Constructor.

        :param host:
        :type host: str
        :param port:
        :type port: int
        :param username:
        :type username: str
        :param password:
        :type password: str
        """
        super(DelugeRPC, self).__init__()
        self.host = host
        self.port = int(port)
        self.username = username
        self.password = password

    def connect(self):
        """Connect to the host using synchronousdeluge API."""
        try:
            self.client = DelugeRPCClient(self.host, self.port, self.username, self.password, decode_utf8=True)
            self.client.connect()
        except Exception as error:
            log.warning('Error while trying to connect to deluge daemon. Error: {error}', {'error': error})
            raise

    def disconnect(self):
        """Disconnect RPC client."""
        self.client.disconnect()

    def test(self):
        """Test connection.

        :return:
        :rtype: bool
        """
        try:
            self.connect()
        except Exception:
            return False
        else:
            return True

    def move_storage(self, torrent_id, location):
        """Move torrent to new location and return torrent id/hash.

        :param torrent_id:
        :type torrent_id: str
        :param location:
        :type location: str
        :return:
        :rtype: str or bool
        """
        try:
            self.connect()
            self.client.core.move_storage([torrent_id], location)
        except Exception:
            return False
        else:
            return True
        finally:
            if self.client:
                self.disconnect()

    def add_torrent_magnet(self, torrent, options, info_hash):
        """Add Torrent magnet and return torrent id/hash.

        :param torrent:
        :type torrent: str
        :param options:
        :type options: dict
        :param info_hash:
        :type info_hash: str
        :return:
        :rtype: str or bool
        """
        try:
            self.connect()
            torrent_id = self.client.core.add_torrent_magnet(torrent, options)
        except Exception:
            return False
        else:
            return torrent_id
        finally:
            if self.client:
                self.disconnect()

    def add_torrent_file(self, filename, torrent, options, info_hash):
        """Add Torrent file and return torrent id/hash.

        :param filename:
        :type filename: str
        :param torrent:
        :type torrent: str
        :param options:
        :type options: dict
        :param info_hash:
        :type info_hash: str
        :return:
        :rtype: str or bool
        """
        try:
            self.connect()
            torrent_id = self.client.core.add_torrent_file(filename, b64encode(torrent), options)
        except Exception:
            return False
        else:
            return torrent_id
        finally:
            if self.client:
                self.disconnect()

    def set_torrent_label(self, torrent_id, label):
        """Set Torrent label.

        :param torrent_id:
        :type torrent_id: str
        :param label:
        :type label: str
        :return:
        :rtype: bool
        """
        try:
            self.connect()
            self.client.label.set_torrent(torrent_id, label)
        except Exception:
            return False
        else:
            return True
        finally:
            if self.client:
                self.disconnect()

    def set_torrent_path(self, torrent_id, path):
        """Set Torrent path.

        :param torrent_id:
        :type torrent_id: str
        :param path:
        :type path: str
        :return:
        :rtype: bool
        """
        try:
            self.connect()
            self.client.core.set_torrent_move_completed_path(torrent_id, path)
            self.client.core.set_torrent_move_completed(torrent_id, 1)
        except Exception:
            return False
        else:
            return True
        finally:
            if self.client:
                self.disconnect()

    def set_torrent_priority(self, torrent_id, priority):
        """Set Torrent priority.

        :param torrent_id:
        :type torrent_id: str
        :param priority:
        :type priority: bool
        :return:
        :rtype: bool
        """
        try:
            self.connect()
            if priority:
                self.client.core.queue_top([torrent_id])
        except Exception:
            return False
        else:
            return True
        finally:
            if self.client:
                self.disconnect()

    def set_torrent_ratio(self, torrent_id, ratio):
        """Set Torrent ratio.

        :param torrent_id:
        :type torrent_id: str
        :param ratio:
        :type ratio: float
        :return:
        :rtype: bool
        """
        try:
            self.connect()
            self.client.core.set_torrent_stop_at_ratio(torrent_id, True)
            self.client.core.set_torrent_stop_ratio(torrent_id, ratio)
        except Exception:
            return False
        else:
            return True
        finally:
            if self.client:
                self.disconnect()

    def remove_torrent_data(self, torrent_id):
        """Remove torrent from client and disk using given info_hash.

        :param torrent_id:
        :type torrent_id: str
        :return:
        :rtype: str or bool
        """
        try:
            self.connect()
            self.client.core.remove_torrent(torrent_id, True)
        except Exception:
            return False
        else:
            return True
        finally:
            if self.client:
                self.disconnect()

    def remove_torrent(self, torrent_id):
        """Remove torrent from client using given info_hash.

        :param torrent_id:
        :type torrent_id: str
        :return:
        :rtype: str or bool
        """
        try:
            self.connect()
            self.client.core.remove_torrent(torrent_id, False)
        except Exception:
            return False
        else:
            return True
        finally:
            if self.client:
                self.disconnect()

    def pause_torrent(self, torrent_ids):
        """Pause torrent.

        :param torrent_ids:
        :type torrent_ids: list of str
        :return:
        :rtype: bool
        """
        try:
            self.connect()
            self.client.core.pause_torrent(torrent_ids)
        except Exception:
            return False
        else:
            return True
        finally:
            if self.client:
                self.disconnect()

    def _torrent_properties(self, info_hash):
        """Get torrent properties."""
        try:
            self.connect()
            log.debug('Checking DelugeD torrent {hash} status.', {'hash': info_hash})
            torrent_data = self.client.core.get_torrent_status(
                info_hash, ('name', 'hash', 'progress', 'state', 'ratio', 'stop_ratio',
                            'is_seed', 'is_finished', 'paused', 'files', 'download_location'))
        except RequestException as error:
            raise DownloadClientConnectionException(f'Error while fetching torrent info_hash {info_hash}. Error: {error}')
        except Exception:
            log.warning('Error while fetching torrent {hash} status.', {'hash': info_hash})
            return
        else:
            return torrent_data
        finally:
            if self.client:
                self.disconnect()
Example #15
0
class DelugeRPC(object):
    host = 'localhost'
    port = 58846
    username = None
    password = None
    client = None

    def __init__(self,
                 host='localhost',
                 port=58846,
                 username=None,
                 password=None):
        super(DelugeRPC, self).__init__()

        self.host = host
        self.port = port
        self.username = username
        self.password = password

    def connect(self):
        self.client = DelugeRPCClient(self.host, int(self.port), self.username,
                                      self.password)
        self.client.connect()
        return self.client.connected

    def disconnect(self):
        self.client.disconnect()

    def test(self):
        try:
            return self.connect()
        except Exception:
            return False

    def add_torrent_magnet(self, torrent, options, torrent_hash):
        try:
            if not self.connect():
                return False

            torrent_id = self.client.core.add_torrent_magnet(torrent,
                                                             options).get()
            if not torrent_id:
                torrent_id = self._check_torrent(torrent_hash)
        except Exception:
            return False
        finally:
            if self.client:
                self.disconnect()

        return torrent_id

    def add_torrent_file(self, filename, torrent, options, torrent_hash):
        try:
            if not self.connect():
                return False

            torrent_id = self.client.core.add_torrent_file(
                filename, b64encode(torrent), options).get()
            if not torrent_id:
                torrent_id = self._check_torrent(torrent_hash)
        except Exception:
            return False
        finally:
            if self.client:
                self.disconnect()

        return torrent_id

    def set_torrent_label(self, torrent_id, label):
        try:
            if not self.connect():
                return False

            self.client.label.set_torrent(torrent_id, label).get()
        except Exception:
            return False
        finally:
            if self.client:
                self.disconnect()

        return True

    def set_torrent_path(self, torrent_id, path):
        try:
            if not self.connect():
                return False

            self.client.core.set_torrent_move_completed_path(torrent_id,
                                                             path).get()
            self.client.core.set_torrent_move_completed(torrent_id, 1).get()
        except Exception:
            return False
        finally:
            if self.client:
                self.disconnect()

        return True

    def set_torrent_priority(self, torrent_ids, priority):
        try:
            if not self.connect():
                return False

            if priority:
                self.client.core.queue_top([torrent_ids]).get()
        except Exception as err:
            return False
        finally:
            if self.client:
                self.disconnect()
        return True

    def set_torrent_ratio(self, torrent_ids, ratio):
        try:
            if not self.connect():
                return False

            self.client.core.set_torrent_stop_at_ratio(torrent_ids, True).get()
            self.client.core.set_torrent_stop_ratio(torrent_ids, ratio).get()
        except Exception as err:
            return False
        finally:
            if self.client:
                self.disconnect()

        return True

    def pause_torrent(self, torrent_ids):
        try:
            if not self.connect():
                return False

            self.client.core.pause_torrent(torrent_ids).get()
        except Exception:
            return False
        finally:
            if self.client:
                self.disconnect()

        return True

    def _check_torrent(self, torrent_hash):
        torrent_id = self.client.core.get_torrent_status(torrent_hash,
                                                         {}).get()
        if torrent_id['hash']:
            sickrage.app.log.debug('DelugeD: Torrent already exists in Deluge')
            return torrent_hash

        return False
Example #16
0
    def collect(self):
        deluge_host = os.environ.get('DELUGE_HOST', '127.0.0.1')
        client = DelugeRPCClient(deluge_host, self.rpc_port, self.rpc_user,
                                 self.rpc_password)
        client.connect()

        libtorrent_metrics = get_libtorrent_metrics_meta()
        libtorrent_metric_values = client.call('core.get_session_status', [])

        for metric, metric_type in libtorrent_metrics.items():
            encoded_name = metric.encode('ascii')
            if encoded_name in libtorrent_metric_values:
                yield metric_type('deluge_libtorrent_{}'.format(
                    metric.replace('.', '_')),
                                  'libtorrent metric {}'.format(metric),
                                  value=libtorrent_metric_values[encoded_name])

        yield new_metric_with_labels_and_value(
            GaugeMetricFamily,
            'deluge_info',
            'Deluge information',
            labels={
                'version':
                client.call('daemon.info').decode('utf-8'),
                'libtorrent_version':
                client.call('core.get_libtorrent_version').decode('utf-8'),
            },
            value=1)

        for key, value in client.call('core.get_config').items():
            if isinstance(value, (int, float, bool)):
                yield GaugeMetricFamily(
                    'deluge_config_{}'.format(key.decode('utf-8')),
                    'Value of the deluge config setting {}'.format(
                        key.decode('utf-8')),
                    value=value)

        torrents_by_state = {
            'downloading': 0,
            'seeding': 0,
            'paused': 0,
            'checking': 0,
            'queued': 0,
            'error': 0,
            'active': 0,

            # not the prometheus way, but the states above (as defined by deluge) are already overlapping, so sum() over them is already meaningless
            'total': 0,
        }
        torrents_by_label = defaultdict(int)
        for torrent in client.core.get_torrents_status({}, [
                b'label', b'state', b'download_payload_rate',
                b'upload_payload_rate'
        ]).values():
            if b'label' in torrent:
                torrents_by_label[torrent[b'label'].decode('utf-8')] += 1
            torrents_by_state[torrent[b'state'].decode('utf-8').lower()] += 1
            torrents_by_state['total'] += 1
            if torrent[b'download_payload_rate'] > 0 or torrent[
                    b'upload_payload_rate'] > 0:
                torrents_by_state['active'] += 1

        if len(torrents_by_label) > 0:
            torrents_by_label_metric = GaugeMetricFamily(
                'deluge_torrents_by_label',
                'The number of torrents for each label assigned to a torrent using the deluge label plugin',
                labels=['label'])
            for label, count in torrents_by_label.items():
                torrents_by_label_metric.add_metric([label], count)
            yield torrents_by_label_metric

        torrents_metric = GaugeMetricFamily(
            'deluge_torrents',
            'The number of torrents in a specific state (note: some states overlap)',
            labels=['state'])
        for state, torrent_count in torrents_by_state.items():
            torrents_metric.add_metric([state], torrent_count)
        yield torrents_metric

        client.disconnect()
Example #17
0
    def collect(self):
        deluge_host = os.environ.get('DELUGE_HOST', '127.0.0.1')
        client = DelugeRPCClient(deluge_host, self.rpc_port, self.rpc_user,
                                 self.rpc_password)
        client.connect()

        libtorrent_status_metrics = get_libtorrent_status_metrics_meta()
        libtorrent_status_metric_source_names = [
            x['source'] for x in libtorrent_status_metrics.values()
        ]

        libtorrent_status_metric_values = client.call(
            'core.get_session_status', libtorrent_status_metric_source_names)

        for metric, props in libtorrent_status_metrics.items():
            if props['type'] is None:
                continue

            value = libtorrent_status_metric_values[props['source']]
            if 'conv' in props:
                value = props['conv'](value)
            yield props['type']('deluge_libtorrent_{}'.format(metric),
                                props['help'],
                                value=value)

        for direction in ['upload', 'download']:
            transfer_metric = CounterMetricFamily(
                'deluge_libtorrent_{}_bytes_total'.format(direction),
                'Total bytes {}ed for all torrents.'.format(direction),
                labels=['type'])
            for traffic_type in ['payload', 'ip_overhead', 'dht', 'tracker']:
                transfer_metric.add_metric(
                    [traffic_type],
                    libtorrent_status_metric_values['total_{}_{}'.format(
                        traffic_type, direction).encode('ascii')])
            yield transfer_metric

        yield new_metric_with_labels_and_value(
            GaugeMetricFamily,
            'deluge_info',
            'Deluge information',
            labels={
                'version':
                client.call('daemon.info').decode('utf-8'),
                'libtorrent_version':
                client.call('core.get_libtorrent_version').decode('utf-8'),
            },
            value=1)

        for key, value in client.call('core.get_config').items():
            if isinstance(value, (int, float, bool)):
                yield GaugeMetricFamily(
                    'deluge_config_{}'.format(key.decode('utf-8')),
                    'Value of the deluge config setting {}'.format(
                        key.decode('utf-8')),
                    value=value)

        torrents_by_state = {
            'downloading': 0,
            'seeding': 0,
            'paused': 0,
            'checking': 0,
            'queued': 0,
            'error': 0,
            'active': 0,

            # not the prometheus way, but the states above (as defined by deluge) are already overlapping, so sum() over them is already meaningless
            'total': 0,
        }
        torrents_by_label = defaultdict(int)
        for torrent in client.core.get_torrents_status({}, [
                b'label', b'state', b'download_payload_rate',
                b'upload_payload_rate'
        ]).values():
            if b'label' in torrent:
                torrents_by_label[torrent[b'label'].decode('utf-8')] += 1
            torrents_by_state[torrent[b'state'].decode('utf-8').lower()] += 1
            torrents_by_state['total'] += 1
            if torrent[b'download_payload_rate'] > 0 or torrent[
                    b'upload_payload_rate'] > 0:
                torrents_by_state['active'] += 1

        if len(torrents_by_label) > 0:
            torrents_by_label_metric = GaugeMetricFamily(
                'deluge_torrents_by_label',
                'The number of torrents for each label assigned to a torrent using the deluge label plugin',
                labels=['label'])
            for label, count in torrents_by_label.items():
                torrents_by_label_metric.add_metric([label], count)
            yield torrents_by_label_metric

        torrents_metric = GaugeMetricFamily(
            'deluge_torrents',
            'The number of torrents in a specific state (note: some states overlap)',
            labels=['state'])
        for state, torrent_count in torrents_by_state.items():
            torrents_metric.add_metric([state], torrent_count)
        yield torrents_metric

        client.disconnect()