Example #1
0
def main():
    """
    Entry function
    """
    parser = argparse.ArgumentParser(description='Process some integers.')
    parser.add_argument(
        '-d', '--dir', type=lambda x: is_valid_directory(parser, x),
        help='the directory to hold the file structure', required=True
    )
    parser.add_argument(
        'hosts', metavar='H', type=lambda x: is_valid_host(parser, x),
        nargs='+', help='the Deluge hosts'
    )
    args = parser.parse_args()

    tracker_map = {}
    clients = []

    for host in args.hosts:
        client = DelugeRPCClient(*host)
        client.connect()

        clients.append(client)

    for entry in listdir_fullpath(args.dir):
        recursive_rm_dir(entry)

    for client in clients:
        torrents = client.call(
            'core.get_torrents_status',
            {},
            ['name', 'save_path', 'tracker_host']
        )

        for _, torrent in torrents.items():
            if torrent[b'tracker_host'] not in tracker_map:
                tracker_map[torrent[b'tracker_host'].decode('utf-8')] = []
            tracker_map[torrent[b'tracker_host'].decode('utf-8')].append(torrent)

        for tracker, torrents in tracker_map.items():
            loc = os.path.join(args.dir, tracker)
            if not os.path.exists(loc):
                os.makedirs(loc)
            for torrent in torrents:
                link_from = os.path.join(loc, torrent[b'name'].decode('utf-8'))
                link_to = os.path.join(
                    torrent[b'save_path'].decode('utf-8'),
                    torrent[b'name'].decode('utf-8')
                )
                if not os.path.exists(link_from):
                    try:
                        os.symlink(link_to, link_from)
                    except OSError as error:
                        if error.errno == errno.EEXIST:
                            os.remove(link_from)
                            os.symlink(link_to, link_from)
                        else:
                            raise error
Example #2
0
    def __init__(self, username, password, host="127.0.0.1", port=58846):
        self._username = username
        self._password = password
        self._host = host
        self._port = port

        self.__client = DelugeRPCClient(host, int(port), username, password)
Example #3
0
    def connect(self, host, username, password, test=False):
        if self.conn is not None:
            return self.connect

        if not host:
            return {'status': False, 'error': 'No host specified'}

        if not username:
            return {'status': False, 'error': 'No username specified'}

        if not password:
            return {'status': False, 'error': 'No password specified'}

        # Get port from the config
        host,portnr = host.split(':')

        # logger.info('Connecting to ' + host + ':' + portnr + ' Username: '******' Password: '******'Could not create DelugeRPCClient Object %s' % e)
            return {'status': False, 'error': e}
        else:
            try:
                self.client.connect()
            except Exception as e:
                logger.error('Could not connect to Deluge: %s' % host)
                return {'status': False, 'error': e}
            else:
                if test is True:
                    daemon_version = self.client.call('daemon.info')
                    libtorrent_version = self.client.call('core.get_libtorrent_version')
                    return {'status': True, 'daemon_version': daemon_version, 'libtorrent_version': libtorrent_version}
                else:
                    return self.client
Example #4
0
File: deluge.py Project: 2mny/mylar
    def connect(self, host, username, password):
        if self.conn is not None:
            return self.connect
	
        if not host:
            return False

        # Get port from the config
        host,portnr = host.split(':')


        #if username and password:
        # logger.info('Connecting to ' + host + ':' + portnr + ' Username: '******' Password: '******'Could not create DelugeRPCClient Object' + e)
            return False
        else:
            try:
                self.client.connect()
            except Exception as e:
                logger.error('Could not connect to Deluge ' + host)
            else:
                return self.client
Example #5
0
    def connect(self, timeout=20):
        config = cherrypy.tree.apps[''].config['opmuse']

        if 'deluge.host' not in config:
            log('Deluge not configured, skipping')
            return False

        host = config['deluge.host']
        port = config['deluge.port']
        user = config['deluge.user']
        password = config['deluge.password']

        DelugeRPCClient.timeout = timeout
        self.client = DelugeRPCClient(host, port, user, password)

        try:
            self.client.connect()
        except OSError as e:
            if e.errno == 113: # "No route to host"
                log('No route to host: %s' % host)
                return False
            else:
                raise e

        return self.client.connected
Example #6
0
def setup_platform(hass, config, add_entities, discovery_info=None):
    """Set up the Deluge switch."""
    from deluge_client import DelugeRPCClient

    name = config.get(CONF_NAME)
    host = config.get(CONF_HOST)
    username = config.get(CONF_USERNAME)
    password = config.get(CONF_PASSWORD)
    port = config.get(CONF_PORT)

    deluge_api = DelugeRPCClient(host, port, username, password)
    try:
        deluge_api.connect()
    except ConnectionRefusedError:
        _LOGGER.error("Connection to Deluge Daemon failed")
        raise PlatformNotReady

    add_entities([DelugeSwitch(deluge_api, name)])
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 prepare_config(self, config):
        config.setdefault('host', 'localhost')
        config.setdefault('port', 58846)
        return config

    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 #8
0
def torrents_status():
    STATUS_KEYS = [
    "state",
    "download_location",
    "tracker_host",
    "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"
    ]
    from deluge_client import DelugeRPCClient
    client = DelugeRPCClient('127.0.0.1', 2196, "seftembr", "TuGsFYqlNP")
    client.connect()
    print "--- ACTIVE ---"
    for (hashid, fields) in client.call('core.get_torrents_status', {"state":"Active"}, STATUS_KEYS).iteritems():
        print "%s: %s (%.2f out of %s - active for %s so far)" % (hashid, fields['name'], fields['progress'], sizeof_fmt(fields['total_size']), human_time(seconds=fields['active_time']))
    print "--- PAUSED ---"
    for (hashid, fields) in client.call('core.get_torrents_status', {"state":"Paused"}, STATUS_KEYS).iteritems():
        if fields['progress'] == 100:
            print "%s: %s (%s downloaded in %s)" % (hashid, fields['name'], sizeof_fmt(fields['total_size']), human_time(seconds=fields['active_time']))
        else:
            print "%s: %s (%.2f out of %s - was active for %s - and paused)" % (hashid, fields['name'], fields['progress'], sizeof_fmt(fields['total_size']), human_time(seconds=fields['active_time']))
Example #9
0
def setup_platform(hass, config, add_devices, discovery_info=None):
    """Set up the Deluge sensors."""
    from deluge_client import DelugeRPCClient

    name = config.get(CONF_NAME)
    host = config.get(CONF_HOST)
    username = config.get(CONF_USERNAME)
    password = config.get(CONF_PASSWORD)
    port = config.get(CONF_PORT)

    deluge_api = DelugeRPCClient(host, port, username, password)
    try:
        deluge_api.connect()
    except ConnectionRefusedError:
        _LOGGER.error("Connection to Deluge Daemon failed")
        raise PlatformNotReady
    dev = []
    for variable in config[CONF_MONITORED_VARIABLES]:
        dev.append(DelugeSensor(variable, deluge_api, name))

    add_devices(dev)
Example #10
0
 def __init__(self, host, port, username, password):
     """
     Initializes a new Deluge client.
     
     url - The url where deluge json can be reached.
     password - The password used to login
     """
     self.host = host
     self.port = port
     self.username = username
     self.password = password
     self.rpcclient = DelugeRPCClient(self.host, self.port, self.username, self.password)
Example #11
0
    def __init__(self, host, username, password, label=None):
        """
        Initializes a new Deluge client.

        url - The url where deluge json can be reached.
        password - The password used to login
        """
        host, port = host.split(':')
        self.host = host
        self.port = int(port)
        self.username = username
        self.password = password
        self.label = label
        self.rpcclient = DelugeRPCClient(self.host, self.port, self.username, self.password, decode_utf8=True)
Example #12
0
 def uploadTorrent(self, filename):
     """
     Upload a torrent to the deluge host based on the config file
     """
     print('Uploading torrent %s' % (filename))
     client = DelugeRPCClient(self.hostDeluge, self.portDeluge, self.usernameDeluge, self.passwordDeluge)
     client.connect()
     f = open(filename, 'rb')
     filedump = base64.encodestring(f.read())
     f.close()
     client.call('core.add_torrent_file', filename, filedump, {}, )
     bytes_available = client.call('core.get_free_space')
     gig_available = bytes_available/(1024.*1024*1024)
     print('There is %.1f GB available on the host \'%s\'.' % (gig_available, self.hostDeluge))
Example #13
0
    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)
Example #14
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()
Example #15
0
 def init(self):
     self.client = DelugeRPCClient(self.host, self.port, self.username,
                                   self.password)
     self.data = {}
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

    if self.per_torrent_metrics_enabled:
      per_torrent_keys = [
        (CounterMetricFamily, b'total_done', 'The amount of data downloaded for this torrent'),
        (CounterMetricFamily, b'total_size', 'The size of this torrent'),
        (CounterMetricFamily, b'total_uploaded', 'The amount of data uploaded for this torrent'),
        (GaugeMetricFamily, b'num_peers', 'The number of peers currently connected to for this torrent'),
        (GaugeMetricFamily, b'num_seeds', 'The number of seeds currently connected to for this torrent'),
        (GaugeMetricFamily, b'total_peers', 'The number of peers in the swarm for this torrent'),
        (GaugeMetricFamily, b'total_seeds', 'The number of seeds in the swarm for this torrent'),
      ]
      per_torrent_metrics = dict(generate_per_torrent_metrics(per_torrent_keys))

      for torrent_hash, torrent in client.core.get_torrents_status({}, [key[1] for key in per_torrent_keys] + [b'name']).items():
        for metric_name, metric in per_torrent_metrics.items():
          metric.add_metric(
            [
              torrent[b'name'].decode('utf-8'),
              torrent_hash.decode('utf-8')
            ],
            torrent[metric_name]
          )

      for metric in per_torrent_metrics.values():
        yield metric

    client.disconnect()
Example #17
0
from deluge_client import DelugeRPCClient
from config import config

client = DelugeRPCClient(config.delugehost.strip('"'), int(config.delugeport),
                         config.delugeuser.strip('"'),
                         config.delugepass.strip('"'))

client.connect()


def clean(id):
    client.call("core.remove_torrent", id, True)
Example #18
0
class TorrentUtils:
    client = None
    methods = []
    torrents = []

    def __init__(self, username='******', password='******', host='127.0.0.1', port=58846):
        self.checkDelugeExist()
        if username and password:
            self.client = DelugeRPCClient(host, port, username, password)
            try:
                self.client.connect()
            except ConnectionRefusedError:
                pass
            self.checkConnection()
            self.getMethods()
            self.getTorrents()

    def checkConnection(self):
        if not self.client or not self.client.connected:
            globalUtils.messageHandler('Torrent daemon not connected', tp='err')
            exit()

    @staticmethod
    def checkDelugeExist():
        if not which('deluge') or not which('deluged'):
            globalUtils.messageHandler('Deluge or Deluged daemon not installed', tp='err')
            exit()

    def getMethods(self) -> list:
        self.methods = self.client.call('daemon.get_method_list')
        return self.methods

    def getTorrents(self, fields: list = [], filters: dict = {}) -> list:
        self.torrents = self.client.call('core.get_torrents_status', filters, fields)
        return self.torrents

    def addTorrent(self, path: Union[str, Path]) -> Union[str, bool]:
        try:
            torrent = Torrent.from_file(path)
        except BencodeDecodingError:
            return False
        torrentId = torrent.info_hash
        if not self.checkTorrentExist(torrent.info_hash):
            fileEncoded = globalUtils.readFile(path)
            torrentId = self.client.call('core.add_torrent_file', '', fileEncoded, {
                'sequential_download': True,
                'prioritize_first_last': True})
            globalUtils.messageHandler(self.getTorrentName(path), '+ Download', tp='msg')
            return torrentId
        globalUtils.messageHandler(self.getTorrentName(path), 'Exist', tp='err')
        self.resumeTorrent(torrentId)
        return torrentId

    def stopTorrent(self, torrentHash: str):
        self.client.call('core.pause_torrent', [torrentHash])

    def resumeTorrent(self, torrentHash: str):
        self.client.call('core.resume_torrent', [torrentHash])

    def setTorrentOptions(self, torrentId: list, options: dict):
        self.client.call('core.set_torrent_options', [torrentId], options)

    def addPlugin(self, path: Union[str, Path]):
        fileEncoded = globalUtils.readFile(path)
        fileName = Path(path).name
        self.client.call('core.upload_plugin', fileName, fileEncoded)

    def checkTorrentExist(self, torrentHash):
        if type(torrentHash) != bytes:
            torrentHash = torrentHash.encode('UTF-8')
        return bool(torrentHash in self.torrents)

    @staticmethod
    def saveTorrentFile(torrentUrl, fileName):
        torrentData = requests.get(torrentUrl).content
        path = globalUtils.saveFile(torrentData, fileName, 'torrentFiles')
        return path

    @staticmethod
    def deleteTorrentFile(fileName):
        globalUtils.deleteFile(fileName, 'torrentFiles')

    @staticmethod
    def getTorrentName(torrent: Union[str, Path]):
        return Torrent.from_file(torrent).name

    @staticmethod
    def getSavedTorrentFiles():
        files = Path('torrentFiles').glob('*.torrent')
        filesList = []
        for f in files:
            filesList.append(str(f))
        return filesList
Example #19
0
import os
import base64
from deluge_client import DelugeRPCClient
import time

tInicial = time.time()
client = DelugeRPCClient('127.0.0.1', 58846, 'monitoria', 'monitoria')

client.connect()
print(client.connected)

path = "C:/Users/Profesor/Documents/monitoria/nueva/torrents/ubuntu.torrent"

opts = {}
opts[
    'download_location'] = "C:/Users/Profesor/Documents/monitoria/nueva/destino"

f = open(path, 'rb')
filedump = base64.encodestring(f.read())
f.close()

filename = os.path.basename(path)

a = client.call('core.add_torrent_file', filename, filedump, opts)

tFinal = time.time()

print(tFinal - tInicial)
Example #20
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
def deluge_connect(host, port, username, password):
    client = DelugeRPCClient(host, port, username, password)
    client.connect()
    assert client.connected
    return client
Example #22
0

def get_movie(my_call, search_lst):
    for item, var in my_call.items():
        search_me = str(var[b'name'], 'utf-8')
        new_srch = PTN.parse(search_me.lower())
        if 'episode' in new_srch and 'season' in new_srch:
            continue
        choice = process.extractOne(new_srch['title'], search_lst)
        if choice[1] > 95:
            print(choice)
            print(item, var)


paramiko.util.log_to_file('/tmp/paramiko.log')

transport = paramiko.Transport(("dragoncave8.ddns.net", 1889))
transport.connect(None, "retsu", "dragon1991!")

sftp = paramiko.SFTPClient.from_transport(transport)
movies = sftp.listdir("/mnt/Media/Movies")
search_lst = [PTN.parse(item.lower())['title'] for item in movies]

client = DelugeRPCClient('perses.feralhosting.com', 53305, 'retsu8',
                         'yf-AXshN8_FjXTZA')
client.connect()
my_call = client.call('core.get_torrents_status', {}, ['name', 'ratio'])

if transport is not None:
    transport.close()
Example #23
0
class Client(GenericClient, DelugeBase):
    def __init__(self, host=None, username=None, password=None):
        super(Client, self).__init__('DelugeD', host, username, password)
        self.client = None

    def setup(self):
        parsed_url = urlparse(self.host)
        if self.client and all([
                self.client.host == parsed_url.hostname, self.client.port
                == parsed_url.port, self.client.username == self.username,
                self.client.password == self.password
        ]):
            return

        self.client = DelugeRPCClient(parsed_url.hostname, parsed_url.port
                                      or 58846, self.username, self.password)

    def _get_auth(self):
        self.setup()
        if not self.client.connected:
            for attempt in range(0, 5):
                try:
                    self.client.connect()
                    break
                except FailedToReconnectException:
                    time.sleep(5)

        self.auth = self.client.connected
        return self.auth

    def _add_torrent_uri(self, result):
        remote_torrent = self.client.core.add_torrent_magnet(
            result.url, self.make_options(result))
        if not remote_torrent:
            return None

        result.hash = remote_torrent

        return remote_torrent

    def _add_torrent_file(self, result):
        if not result.content:
            result.content = {}
            return None

        remote_torrent = self.client.core.add_torrent_file(
            result.name + '.torrent', b64encode(result.content),
            self.make_options(result))
        if not remote_torrent:
            return None

        result.hash = remote_torrent

        return remote_torrent

    def _set_torrent_label(self, result):
        # No option for this built into the rpc, because it is a plugin
        label = sickbeard.TORRENT_LABEL.lower()
        if result.show.is_anime:
            label = sickbeard.TORRENT_LABEL_ANIME.lower()
        if ' ' in label:
            logger.log(
                self.name + ': Invalid label. Label must not contain a space',
                logger.ERROR)
            return False

        if label:
            try:
                labels = self.client.label.get_labels()
                if label not in labels:
                    logger.log(
                        self.name + ': ' + label +
                        " label does not exist in Deluge we must add it",
                        logger.DEBUG)
                    self.client.labels.add(label)
                    logger.log(
                        self.name + ': ' + label + " label added to Deluge",
                        logger.DEBUG)

                self.client.label.set_torrent(result.hash, label)
            except:
                logger.log(self.name + ': ' + "label plugin not detected",
                           logger.DEBUG)
                return False

        logger.log(self.name + ': ' + label + " label added to torrent",
                   logger.DEBUG)
        return True

    def testAuthentication(self):
        if self._get_auth() and self.client.daemon.info():
            return True, 'Success: Connected and Authenticated'
        else:
            return False, 'Error: Unable to Authenticate!  Please check your config!'
Example #24
0
class DelugeClient(BaseClient):
    identifier = 'deluge'

    def __init__(self, host, username, password):
        """
        Initializes a new Deluge client.
        
        url - The url where deluge json can be reached.
        password - The password used to login
        """
        host, port = host.split(':')
        self.host = host
        self.port = int(port)
        self.username = username
        self.password = password
        self.rpcclient = DelugeRPCClient(self.host, self.port, self.username,
                                         self.password)

    def _login(self):
        """
        Logs into deluge
        """
        if not self.rpcclient.connected:
            self.rpcclient.connect()

    def get_config(self):
        """
        Get the current configuration that can be used in the autotorrent config file
        """
        return {
            'host': '%s:%s' % (self.host, self.port),
            'username': self.username,
            'password': self.password,
        }

    @classmethod
    def auto_config(cls):
        """
        Tries to auto configure deluge using the .config/deluge files
        """
        config_path = os.path.expanduser('~/.config/deluge/core.conf')
        if not os.path.isfile(config_path):
            logger.debug('deluge config file was not found')
            return

        if not os.access(config_path, os.R_OK):
            logger.debug('Unable to access deluge config file at %s' %
                         config_path)
            return

        auth_path = os.path.expanduser('~/.config/deluge/auth')
        if not os.path.isfile(auth_path):
            logger.debug('deluge auth file was not found')
            return

        if not os.access(auth_path, os.R_OK):
            logger.debug('Unable to access deluge confauthig file at %s' %
                         auth_path)
            return

        with open(config_path, 'r') as f:
            config_data = f.read()

        daemon_port = re.findall('"daemon_port":\s*(\d+)', config_data)
        if not daemon_port:
            logger.debug('No deluge port, just trying to use default')
            daemon_port = 58846
        else:
            daemon_port = int(daemon_port[0])

        with open(auth_path, 'r') as f:
            auth_data = f.read()

        auth_data = auth_data.split('\n')[0].split(':')
        if len(auth_data[0]) < 2:
            logger.debug('Invalid entry found in auth file')
            return

        username = auth_data[0]
        password = auth_data[1]

        return cls('127.0.0.1:%s' % daemon_port, username, password)

    def test_connection(self):
        """
        Tests the Deluge RPC connection, returns message if found.
        """
        self._login()
        return 'Free space: %s' % humanize_bytes(
            self.rpcclient.call('core.get_free_space'))

    def get_torrents(self):
        """
        Returns a set of info hashes currently added to the client.
        """
        logger.info('Getting a list of torrent hashes')
        self._login()
        result = self.rpcclient.call('core.get_torrents_status', {}, ['name'])
        return set(x.lower().decode('ascii') for x in result.keys())

    def add_torrent(self, torrent, destination_path, files, fast_resume=True):
        """
        Add a new torrent to Deluge.
        
        torrent is the decoded file as a python object.
        destination_path is where the links are. The complete files must be linked already.
        files is a list of files found in the torrent.
        """
        name = torrent[b'info'][b'name']
        logger.info('Trying to add a new torrent to deluge: %r' % name)

        destination_path = os.path.abspath(destination_path)

        infohash = hashlib.sha1(bencode(torrent[b'info'])).hexdigest()
        encoded_torrent = base64.b64encode(bencode(torrent))

        basename = os.path.basename(destination_path)
        mapped_files = {}
        for i, f in enumerate(files):
            mapped_files[i] = os.path.join(basename, *f['path'])

        self._login()
        result = self.rpcclient.call(
            'core.add_torrent_file', 'torrent.torrent', encoded_torrent, {
                'download_location': os.path.dirname(destination_path),
                'mapped_files': mapped_files,
                'seed_mode': fast_resume
            })

        return result and result.decode('utf-8') == infohash
Example #25
0
 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()
Example #26
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 #27
0
class Deluge(IntervalModule):
    """
    Deluge torrent module
    Requires `deluge-client`

    .. rubric:: Formatters:

    * `{num_torrents}`       - number of torrents in deluge
    * `{free_space_bytes}`   - bytes free in path
    * `{used_space_bytes}`   - bytes used in path
    * `{upload_rate}` - bytes sent per second
    * `{download_rate}` - bytes received per second
    * `{total_uploaded}`     - bytes sent total
    * `{total_downloaded}`     - bytes received total

    """

    settings = (
        'format', 'color', ('rounding',
                            'number of decimal places to round numbers too'),
        ('host', 'address of deluge server (default: 127.0.0.1)'),
        ('port', 'port of deluge server (default: 58846)'),
        ('username', 'username to authenticate with deluge'),
        ('password', 'password to authenticate to deluge'),
        ('path',
         'override "download path" server-side when checking space used/free'),
        ('offline_string',
         'string to output while unable to connect to deluge daemon'))
    required = ('username', 'password')

    host = '127.0.0.1'
    port = 58846
    path = None
    color = None
    libtorrent_stats = False
    rounding = 2
    offline_string = 'offline'

    format = '⛆{num_torrents} ✇{free_space_bytes}'

    id = int(time.time())  # something random

    def init(self):
        self.client = DelugeRPCClient(self.host, self.port, self.username,
                                      self.password)
        self.data = {}

    def run(self):
        if not self.client.connected:
            try:
                self.client.connect()
            except OSError:
                self.output = {'full_text': self.offline_string}
                return

        try:
            self.data = self.get_session_statistics()

            torrents = self.get_torrents_status()
            if torrents:
                self.data['num_torrents'] = len(torrents)

            if 'free_space_bytes' in self.format:
                self.data['free_space_bytes'] = self.get_free_space(self.path)
            if 'used_space_bytes' in self.format:
                self.data['used_space_bytes'] = self.get_path_size(self.path)
        except FailedToReconnectException:
            return

        self.parse_values(self.data)

        self.output = {'full_text': self.format.format(**self.data)}
        if self.color:
            self.output['color'] = self.color

    def parse_values(self, values):
        for k, v in values.items():
            if v:
                if k in [
                        'total_upload', 'total_download', 'download_rate',
                        'upload_rate'
                ] or k.endswith('_bytes'):
                    values[k] = '{value:.{round}f}{unit}'.format(
                        round=self.rounding, **bytes_info_dict(v))

    def get_path_size(self, path=None):
        """
        get used space of path in bytes (default: download location)
        """
        if path is None:
            path = []
        return self.client.call('core.get_path_size', path)

    def get_free_space(self, path=None):
        """
        get free space of path in bytes (default: download location)
        """
        if path is None:
            path = []
        return self.client.call('core.get_free_space', path)

    def get_torrents_status(self, torrent_id=None, keys=None):
        if torrent_id is None:
            torrent_id = []
        if keys is None:
            keys = []
        return self.client.call('core.get_torrents_status', torrent_id, keys)

    def get_session_statistics(self):
        keys = [
            'upload_rate', 'download_rate', 'total_upload', 'total_download'
        ]

        out = {
        }  # some of the values from deluge-client are bytes, the others are ints - we need to decode them
        for k, v in self.client.call('core.get_session_status', keys).items():
            k = k.decode('utf-8')  # keys aswell
            if type(v) == bytes:
                out[k] = v.decode('utf-8')
            else:
                out[k] = v

        return out
Example #28
0
class DelugeClient(BaseClient):
    identifier = 'deluge'
    
    def __init__(self, host, username, password):
        """
        Initializes a new Deluge client.
        
        url - The url where deluge json can be reached.
        password - The password used to login
        """
        host, port = host.split(':')
        self.host = host
        self.port = int(port)
        self.username = username
        self.password = password
        self.rpcclient = DelugeRPCClient(self.host, self.port, self.username, self.password)
    
    def _login(self):
        """
        Logs into deluge
        """
        if not self.rpcclient.connected:
            self.rpcclient.connect()
    
    def get_config(self):
        """
        Get the current configuration that can be used in the autotorrent config file
        """
        return {
            'host': '%s:%s' % (self.host, self.port),
            'username': self.username,
            'password': self.password,
        }
    
    @classmethod
    def auto_config(cls):
        """
        Tries to auto configure deluge using the .config/deluge files
        """
        config_path = os.path.expanduser('~/.config/deluge/core.conf')
        if not os.path.isfile(config_path):
            logger.debug('deluge config file was not found')
            return
        
        if not os.access(config_path, os.R_OK):
            logger.debug('Unable to access deluge config file at %s' % config_path)
            return
        
        auth_path = os.path.expanduser('~/.config/deluge/auth')
        if not os.path.isfile(auth_path):
            logger.debug('deluge auth file was not found')
            return
        
        if not os.access(auth_path, os.R_OK):
            logger.debug('Unable to access deluge confauthig file at %s' % auth_path)
            return
        
        with open(config_path, 'r') as f:
            config_data = f.read()
        
        daemon_port = re.findall('"daemon_port":\s*(\d+)', config_data)
        if not daemon_port:
            logger.debug('No deluge port, just trying to use default')
            daemon_port = 58846
        else:
            daemon_port = int(daemon_port[0])
        
        with open(auth_path, 'r') as f:
            auth_data = f.read()
        
        auth_data = auth_data.split('\n')[0].split(':')
        if len(auth_data[0]) < 2:
            logger.debug('Invalid entry found in auth file')
            return
        
        username = auth_data[0]
        password = auth_data[1]
        
        return cls('127.0.0.1:%s' % daemon_port, username, password)
    
    def test_connection(self):
        """
        Tests the Deluge RPC connection, returns message if found.
        """
        self._login()
        return 'Free space: %s' % humanize_bytes(self.rpcclient.call('core.get_free_space'))
    
    def get_torrents(self):
        """
        Returns a set of info hashes currently added to the client.
        """
        logger.info('Getting a list of torrent hashes')
        self._login()
        result = self.rpcclient.call('core.get_torrents_status', {}, ['name'])
        return set(x.lower().decode('ascii') for x in result.keys())
    
    def add_torrent(self, torrent, destination_path, files, fast_resume=True):
        """
        Add a new torrent to Deluge.
        
        torrent is the decoded file as a python object.
        destination_path is where the links are. The complete files must be linked already.
        files is a list of files found in the torrent.
        """
        name = torrent[b'info'][b'name']
        logger.info('Trying to add a new torrent to deluge: %r' % name)
        
        destination_path = os.path.abspath(destination_path)
        
        infohash = hashlib.sha1(bencode(torrent[b'info'])).hexdigest()
        encoded_torrent = base64.b64encode(bencode(torrent))
        
        basename = os.path.basename(destination_path)
        mapped_files = {}
        for i, f in enumerate(files):
            mapped_files[i] = os.path.join(basename, *f['path'])
        
        self._login()
        result = self.rpcclient.call('core.add_torrent_file', 'torrent.torrent', encoded_torrent, {
                                                                'download_location': os.path.dirname(destination_path),
                                                                'mapped_files': mapped_files,
                                                                'seed_mode': fast_resume})
        
        return result and result.decode('utf-8') == infohash
Example #29
0
class Deluge:
    def _mkdtemp(self):
        cache_path = cherrypy.config['opmuse'].get('cache.path')
        dir = os.path.join(cache_path, 'deluge')

        if not os.path.exists(dir):
            os.mkdir(dir)

        return tempfile.mkdtemp(dir=dir)

    def connect(self, timeout=20):
        config = cherrypy.tree.apps[''].config['opmuse']

        if 'deluge.host' not in config:
            log('Deluge not configured, skipping')
            return False

        host = config['deluge.host']
        port = config['deluge.port']
        user = config['deluge.user']
        password = config['deluge.password']

        DelugeRPCClient.timeout = timeout
        self.client = DelugeRPCClient(host, port, user, password)

        try:
            self.client.connect()
        except OSError as e:
            if e.errno == 113: # "No route to host"
                log('No route to host: %s' % host)
                return False
            else:
                raise e

        return self.client.connected

    def update_torrents(self):
        torrents = self.client.call('core.get_torrents_status', {},
                                    ['name', 'files', 'save_path', 'time_added',
                                     'total_size', 'paused', 'is_finished', 'progress'])

        all_torrents = set()

        for torrent_id, in get_database().query(Torrent.torrent_id).all():
            all_torrents.add(torrent_id)

        for torrent_id, data in torrents.items():
            torrent_id = torrent_id.decode('utf-8')

            if torrent_id in all_torrents:
                all_torrents.remove(torrent_id)
                torrent = get_database().query(Torrent).filter(Torrent.torrent_id == torrent_id).one()
            else:
                torrent = Torrent()

            for file in data[b'files']:
                if Library.is_supported(file[b'path']):
                    has_supported_files = True
                    break
            else:
                has_supported_files = False

            torrent.torrent_id = torrent_id
            torrent.name = data[b'name'].decode('utf-8')
            torrent.has_supported_files = has_supported_files
            torrent.added = datetime.datetime.fromtimestamp(data[b'time_added'])
            torrent.size = data[b'total_size']
            torrent.paused = data[b'paused']
            torrent.finished = data[b'is_finished']
            torrent.progress = data[b'progress']

            get_database().add(torrent)
            get_database().commit()

        if len(all_torrents) > 0:
            (get_database().query(Torrent).filter(Torrent.torrent_id.in_(all_torrents))
                .delete(synchronize_session='fetch'))

        get_database().commit()

    def import_torrent(self, torrent_id):
        config = cherrypy.tree.apps[''].config['opmuse']
        ssh_host = config['deluge.ssh_host']

        if ssh_host is None:
            raise Exception('You need to set deluge.ssh_host')

        debug('fetching torrent %s info' % torrent_id)
        torrent = self.client.call('core.get_torrent_status', torrent_id, [])

        filelist_fd, filelist_path = tempfile.mkstemp()

        files = []

        tempdir = self._mkdtemp().encode()

        with os.fdopen(filelist_fd, 'bw') as f:
            for file in torrent[b'files']:
                path = os.path.join(torrent[b'save_path'], file[b'path'])
                f.write(path + b"\n")
                files.append(os.path.join(tempdir, path[1:]))

        try:
            debug('rsync torrent %s from %s' % (torrent_id, ssh_host))
            output = subprocess.check_output([
                'rsync',
                '-a',
                '-e', 'ssh -oBatchMode=yes -oVisualHostKey=no',
                '--files-from=%s' % filelist_path,
                '%s:/' % ssh_host,
                tempdir
            ], stderr=subprocess.STDOUT)
        except CalledProcessError as error:
            log('Failed to rsync', traceback=True)
            shutil.rmtree(tempdir)
            raise Exception(error.output.decode())
        except Exception:
            log('Failed to rsync', traceback=True)
            shutil.rmtree(tempdir)
            raise
        finally:
            os.remove(filelist_path)

        debug('done rsyncing torrent %s' % torrent_id)

        return files
Example #30
0
class DelugeHelper:
    client = None

    def __init__(self, ip, port, user, password):
        self.client = DelugeRPCClient(ip, int(port), user, password)
        self.client.connect()

    def add_torrent(self, magnetlink, download_location):
        torrent_id = self.client.call(
            'core.add_torrent_magnet', magnetlink, {
                'download_location': download_location,
                'prioritize_first_last_pieces': True,
                'sequential_download': True
            })
        time.sleep(2)
        torrent_name = str(
            self.client.call('core.get_torrent_status', torrent_id,
                             ['name']).get(b'name'), 'utf-8')
        return 'Torrent %s started' % torrent_name

    def delete_torrent(self, torrent_id):
        torrent_name = str(
            self.client.call('core.get_torrent_status', torrent_id,
                             ['name']).get(b'name'), 'utf-8')
        if self.client.call('core.remove_torrent', torrent_id, True):
            return 'Torrent %s was successfully deleted' % torrent_name
        else:
            return 'An error occurred while deleting %s' % torrent_name

    def get_torrents_to_delete(self):
        status_keys = ['name', 'total_size']
        results = self.client.call('core.get_torrents_status', {}, status_keys)
        message = 'Name - Size\n'
        for torrent_id, status in results.items():
            message += '%s - %s /del_%s \n' % (str(
                status.get(b'name'),
                'utf-8'), format_size(
                    status.get(b'total_size')), str(torrent_id).split("'")[1])
        return message

    def get_active_torrents(self):
        status_keys = [
            'name', 'download_payload_rate', 'progress', 'eta', 'total_size'
        ]
        results = self.client.call('core.get_torrents_status',
                                   {'state': 'Allocating'}, status_keys)
        results.update(
            self.client.call('core.get_torrents_status', {'state': 'Checking'},
                             status_keys))
        results.update(
            self.client.call('core.get_torrents_status',
                             {'state': 'Downloading'}, status_keys))
        results.update(
            self.client.call('core.get_torrents_status', {'state': 'Error'},
                             status_keys))
        results.update(
            self.client.call('core.get_torrents_status', {'state': 'Queued'},
                             status_keys))
        results.update(
            self.client.call('core.get_torrents_status', {'state': 'Moving'},
                             status_keys))
        message = 'Name - Downloading speed - Progress - ETA - Size\n'
        for torrent_id, status in results.items():
            message += '%s - %s - %.1f%% - %s - %s \n' % (
                str(status.get(b'name'), 'utf-8'),
                format_speed(status.get(b'download_payload_rate')),
                status.get(b'progress'), format_time(status.get(b'eta')),
                format_size(status.get(b'total_size')))
        return message

    def get_finished_torrents(self):
        status_keys = ['name', 'upload_payload_rate', 'progress', 'total_size']
        results = self.client.call('core.get_torrents_status',
                                   {'state': 'Seeding'}, status_keys)
        results.update(
            self.client.call('core.get_torrents_status', {'state': 'Paused'},
                             status_keys))
        message = 'Name - Uploading speed - Progress - Size\n'
        for torrent_id, status in results.items():
            message += '%s - %s - %.1f%% - %s \n' % (
                str(status.get(b'name'),
                    'utf-8'), format_speed(status.get(b'upload_payload_rate')),
                status.get(b'progress'), format_size(
                    status.get(b'total_size')))
        return message
Example #31
0
class Deluge(object):
    def __init__(self, host):
        # Host
        self._host = host
        # RPC Client
        self._client = None
        # Torrent Properties Cache
        self._torrent_cache = {}
        # Cache Valid Time
        self._refresh_expire_time = 30
        # Last Time of Refreshing Cache
        self._last_refresh = 0

    # Login to Deluge
    def login(self, username, password):
        # Split IP(or domain name) and port
        splits = self._host.split(':')
        host = splits[0] if len(splits) > 0 else ''
        port = int(splits[1]) if len(splits) > 1 else DEFAULT_PORT

        # Create RPC client and connect to Deluge
        self._client = DelugeRPCClient(host,
                                       port,
                                       username,
                                       password,
                                       decode_utf8=True)
        try:
            self._client.connect()
        except DelugeClientException as e:
            # Display class name of the exception if there is no error messages
            raise LoginFailure(e.args[0].split('\n')[0]
                               if len(e.args) > 0 else e.__class__.__name__)

    # A caller to call deluge api; includes exception processing
    def _call(self, method, *args, **kwargs):
        try:
            return self._client.call(method, *args, **kwargs)
        except DelugeClientException as e:
            # Raise our own exception
            raise RemoteFailure(e.args[0].split('\n')[0]
                                if len(e.args) > 0 else e.__class__.__name__)

    # Get client status
    def client_status(self):
        cs = ClientStatus()

        # Set remote free space checker
        cs.free_space = self.remote_free_space

        # Get DL/UL information
        session_stats = self._call('core.get_session_status', [
            'payload_download_rate',
            'payload_upload_rate',
            'total_download',
            'total_upload',
        ])
        cs.download_speed = session_stats['payload_download_rate']
        cs.total_downloaded = session_stats['total_download']
        cs.upload_speed = session_stats['payload_upload_rate']
        cs.total_uploaded = session_stats['total_upload']

        # Get port status
        port_is_open = self._call('core.test_listen_port')
        cs.port_status = PortStatus.Open if port_is_open else PortStatus.Closed

        return cs

    # Get Deluge version
    def version(self):
        funcs = {
            1: 'daemon.info',  # For Deluge 1.x, use daemon.info
            2: 'daemon.get_version',  # For Deluge 2.x, use daemon.get_version
        }
        ver = self._call(funcs[self._client.deluge_version])
        return ('Deluge %s' % ver)

    # Get API version
    def api_version(self):
        # Returns the protocol version
        return self._client.deluge_protocol_version if self._client.deluge_protocol_version is not None else 'not provided'

    # Get torrent list
    def torrents_list(self):
        # Save hashes
        torrents_hash = []
        # Get torrent list (and their properties)
        torrent_list = self._call(
            'core.get_torrents_status',
            {},
            [
                'active_time',
                'all_time_download',
                'download_payload_rate',
                'finished_time',
                'hash',
                'label',  # Available when the plugin 'label' is enabled
                'name',
                'num_peers',
                'num_seeds',
                'progress',
                'ratio',
                'seeding_time',
                'state',
                'time_added',
                'time_since_transfer',
                'total_peers',
                'total_seeds',
                'total_size',
                'total_uploaded',
                'trackers',
                'upload_payload_rate',
            ])
        # Save properties to cache
        self._torrent_cache = torrent_list
        self._last_refresh = time.time()
        # Return torrent hashes
        for h in torrent_list:
            torrents_hash.append(h)
        return torrents_hash

    # Get Torrent Properties
    def torrent_properties(self, torrent_hash):
        # Check cache expiration
        if time.time() - self._last_refresh > self._refresh_expire_time:
            self.torrents_list()
        # Extract properties
        torrent = self._torrent_cache[torrent_hash]
        # Create torrent object
        torrent_obj = Torrent()
        torrent_obj.hash = torrent['hash']
        torrent_obj.name = torrent['name']
        if 'label' in torrent:
            torrent_obj.category = [torrent['label']
                                    ] if len(torrent['label']) > 0 else []
        torrent_obj.tracker = [
            tracker['url'] for tracker in torrent['trackers']
        ]
        torrent_obj.status = Deluge._judge_status(torrent['state'])
        torrent_obj.size = torrent['total_size']
        torrent_obj.ratio = torrent['ratio']
        torrent_obj.uploaded = torrent['total_uploaded']
        torrent_obj.downloaded = torrent['all_time_download']
        torrent_obj.create_time = int(torrent['time_added'])
        torrent_obj.seeding_time = torrent['seeding_time']
        torrent_obj.upload_speed = torrent['upload_payload_rate']
        torrent_obj.download_speed = torrent['download_payload_rate']
        torrent_obj.seeder = torrent['total_seeds']
        torrent_obj.connected_seeder = torrent['num_seeds']
        torrent_obj.leecher = torrent['total_peers']
        torrent_obj.connected_leecher = torrent['num_peers']
        torrent_obj.average_upload_speed = torrent['total_uploaded'] / torrent[
            'active_time'] if torrent['active_time'] > 0 else 0
        if 'finished_time' in torrent:
            download_time = torrent['active_time'] - torrent['finished_time']
            torrent_obj.average_download_speed = torrent[
                'all_time_download'] / download_time if download_time > 0 else 0
        if 'time_since_transfer' in torrent:
            # Set the last active time of those never active torrents to timestamp 0
            torrent_obj.last_activity = torrent[
                'time_since_transfer'] if torrent[
                    'time_since_transfer'] > 0 else 0
        torrent_obj.progress = torrent['progress'] / 100  # Accept Range: 0-1

        return torrent_obj

    # Get free space
    def remote_free_space(self, path):
        return self._call('core.get_free_space', path)

    # Judge Torrent Status
    @staticmethod
    def _judge_status(state):
        return {
            'Allocating': TorrentStatus.Unknown,  # Ignore this state
            'Checking': TorrentStatus.Checking,
            'Downloading': TorrentStatus.Downloading,
            'Error': TorrentStatus.Error,
            'Moving': TorrentStatus.Unknown,  # Ignore this state
            'Paused': TorrentStatus.Paused,
            'Queued': TorrentStatus.Queued,
            'Seeding': TorrentStatus.Uploading,
        }[state]

    # Batch Remove Torrents
    def remove_torrents(self, torrent_hash_list, remove_data):
        if self._client.deluge_version >= 2:  # Method 'core.remove_torrents' is only available in Deluge 2.x
            failures = self._call('core.remove_torrents', torrent_hash_list,
                                  remove_data)
            failed_hash = [torrent[0] for torrent in failures]
            return (
                [
                    torrent for torrent in torrent_hash_list
                    if torrent not in failed_hash
                ],
                [{
                    'hash': torrent[0],
                    'reason': torrent[1],
                } for torrent in failures],
            )
        else:  # For Deluge 1.x, remove torrents one by one
            success_hash = []
            failures = []
            for torrent in torrent_hash_list:
                try:
                    self._call('core.remove_torrent', torrent, remove_data)
                    success_hash.append(torrent)
                except RemoteFailure as e:
                    failures.append({
                        'hash': torrent,
                        'reason': e.args[0],
                    })
            return (success_hash, failures)
Example #32
0
 def __init__(self, ip, port, user, password):
     self.client = DelugeRPCClient(ip, int(port), user, password)
     self.client.connect()
Example #33
0
    if len(sys.argv) < 4:
        log.error("Not enough command line parameters present, are you launching this from deluge?")
        sys.exit(1)

    path = str(sys.argv[3])
    torrent_name = str(sys.argv[2])
    torrent_id = str(sys.argv[1])
    delete_dir = None
    path_mapping = settings.deluge['path-mapping']

    log.debug("Path: %s." % path)
    log.debug("Torrent: %s." % torrent_name)
    log.debug("Hash: %s." % torrent_id)

    client = DelugeRPCClient(host=settings.deluge['host'], port=int(settings.deluge['port']), username=settings.deluge['user'], password=settings.deluge['pass'])
    client.connect()

    if client.connected:
        log.info("Successfully connected to Deluge")
    else:
        log.error("Failed to connect to Deluge")
        sys.exit(1)

    torrent_data = client.call('core.get_torrent_status', torrent_id, ['files', 'label'])
    try:
        torrent_files = torrent_data[b'files']
        category = torrent_data[b'label'].lower().decode()
    except:
        torrent_files = torrent_data['files']
        category = torrent_data['label'].lower()
Example #34
0
@version: 0
@autor: David Ramirez Sierra
@doc: Funciones RPC --> http://deluge.readthedocs.io/en/develop/core/rpc.html 

'''

import sys
import time
from deluge_client import DelugeRPCClient # https://github.com/JohnDoee/deluge-client

servidor='127.0.0.1'
puerto= 58846 # De tipo entero
username='******' # Se puede ver en home/.config/deluge/auth . Este es de level 10 = admin
password='******' # Se puede ver en home/.config/deluge/auth

client = DelugeRPCClient(servidor, puerto, username, password)
client.connect()

if client.connected: 
	print "Conectado a " +servidor+':'+str(puerto)

if len(sys.argv) > 1:

	if sys.argv[1] == '-add':

		if sys.argv[2] == '-magnet':
			uri = sys.argv[3]
			client.call('core.add_torrent_magnet', uri,{})
		elif sys.argv[2] == '-torrent':
			uri = sys.argv[3]
			# TODO
Example #35
0
 def login(self):
     self.client = DelugeRPCClient(host, port, username, password)
     self.client.connect()
Example #36
0
class TorrentClient(object):
    def __init__(self):
        self.conn = None
		
    def connect(self, host, username, password):
        if self.conn is not None:
            return self.connect
	
        if not host:
            return False

        # Get port from the config
        host,portnr = host.split(':')


        #if username and password:
        # logger.info('Connecting to ' + host + ':' + portnr + ' Username: '******' Password: '******'Could not create DelugeRPCClient Object' + e)
            return False
        else:
            try:
                self.client.connect()
            except Exception as e:
                logger.error('Could not connect to Deluge ' + host)
            else:
                return self.client
	
    def find_torrent(self, hash):
        logger.debug('Finding Torrent hash: ' + hash)
        torrent_info = self.get_torrent(hash)
        if torrent_info:
            return True
        else:
            return False

    def get_torrent(self, hash):
        logger.debug('Getting Torrent info from hash: ' + hash)
        try:
            torrent_info = self.client.call('core.get_torrent_status', hash, '')
        except Exception as e:
            logger.error('Could not get torrent info for ' + hash)
            return False
        else:
            if torrent_info is None:
                torrent_info = False
            return torrent_info


    def start_torrent(self, hash):
        try:
            self.find_torrent(hash)
        except Exception as e:
            return False
        else:
            try:
                self.client.call('core.resume_torrent', hash)
            except Exception as e:
                logger.error('Torrent failed to start ' + e)
            else:
                logger.info('Torrent ' + hash + ' was started')
                return True

    def stop_torrent(self, hash):
        try:
            self.client.find_torrent(hash)
        except Exception as e:
            logger.error('Torrent Not Found')
            return False
        else:
            try:
                self.client.call('core.pause_torrent', hash)
            except Exception as e:
                logger.error('Torrent failed to be stopped: ' + e)
                return False
            else:
                logger.info('Torrent ' + hash + ' was stopped')
                return True
        

    def load_torrent(self, filepath):
        
        logger.info('filepath to torrent file set to : ' + filepath)
        torrent_id = False
                
        if self.client.connected is True:
            logger.info('Checking if Torrent Exists!')
            
            if not filepath.startswith('magnet'):
                torrentcontent = open(filepath, 'rb').read()
                hash = str.lower(self.get_the_hash(filepath)) # Deluge expects a lower case hash

                logger.debug('Torrent Hash (load_torrent): "' + hash + '"')
                logger.debug('FileName (load_torrent): ' + str(os.path.basename(filepath)))


                #Check if torrent already added
                if self.find_torrent(str.lower(hash)):
                    logger.info('load_torrent: Torrent already exists!')
                    #should set something here to denote that it's already loaded, and then the failed download checker not run so it doesn't download
                    #multiple copies of the same issues that's already downloaded
                else:
                    logger.info('Torrent not added yet, trying to add it now!')
                    try:
                        torrent_id = self.client.call('core.add_torrent_file', str(os.path.basename(filepath)), base64.encodestring(torrentcontent), '')
                    except Exception as e:
                        logger.debug('Torrent not added')
                        return False
            else:
                try:
                    torrent_id = self.client.call('core.add_torrent_magnet', str(filepath), {})
                except Exception as e:
                    logger.debug('Torrent not added')
                    return False

            # If label enabled put label on torrent in Deluge
            if torrent_id and mylar.CONFIG.DELUGE_LABEL:
                logger.info ('Setting label to ' + mylar.CONFIG.DELUGE_LABEL)
                try:
                    self.client.call('label.set_torrent', torrent_id, mylar.CONFIG.DELUGE_LABEL)
                except:
                 #if label isn't set, let's try and create one.
                    try:
                        self.client.call('label.add', mylar.CONFIG.DELUGE_LABEL)
                        self.client.call('label.set_torrent', torrent_id, mylar.CONFIG.DELUGE_LABEL)
                    except:
                        logger.warn('Unable to set label - Either try to create it manually within Deluge, and/or ensure there are no spaces, capitalization or special characters in label')
                    else:
                        logger.info('Succesfully set label to ' + mylar.CONFIG.DELUGE_LABEL)

        try:
            torrent_info = self.get_torrent(torrent_id)
            logger.info('Double checking that the torrent was added.')
        except Exception as e:
            logger.warn('Torrent was not added! Please check logs')
            return False
        else:
            logger.info('Torrent successfully added!')
            return {'hash':             torrent_info['hash'],
                    'label':            mylar.CONFIG.DELUGE_LABEL,
                    'folder':           torrent_info['save_path'],
                    'total_filesize':   torrent_info['total_size'],
                    'name':             torrent_info['name'],
                    'files':            torrent_info['files'],
                    'time_started':     torrent_info['active_time'],
                    'completed':        torrent_info['is_finished']}


    def delete_torrent(self, hash, removeData=False):
        try:
            self.client.find_torrent(hash)
        except Exception as e:
            logger.error('Torrent ' + hash + ' does not exist')
            return False
        else:
            try:
                self.client.call('core.remote_torrent', hash, removeData)
            except Exception as e:
                logger.error('Unable to delete torrent ' + hash)
                return False
            else:
                logger.info('Torrent deleted ' + hash)
                return True


    def get_the_hash(self, filepath):
        import hashlib, StringIO
        import bencode

        # Open torrent file
        torrent_file = open(filepath, "rb")
        metainfo = bencode.decode(torrent_file.read())
        info = metainfo['info']
        thehash = hashlib.sha1(bencode.encode(info)).hexdigest().upper()
        logger.debug('Hash: ' + thehash)
        return thehash
Example #37
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
if len(sys.argv) < 4:
    log.error("Not enough command line parameters present, are you launching this from deluge?")
    sys.exit()

path = str(sys.argv[3])
torrent_name = str(sys.argv[2])
torrent_id = str(sys.argv[1])

log.debug("Path: %s." % path)
log.debug("Torrent: %s." % torrent_name)
log.debug("Hash: %s." % torrent_id)

client = DelugeRPCClient(
    host=settings.deluge["host"],
    port=int(settings.deluge["port"]),
    username=settings.deluge["user"],
    password=settings.deluge["pass"],
)
client.connect()

if client.connected:
    log.info("Successfully connected to Deluge")
else:
    log.error("Failed to connect to Deluge")
    sys.exit()

torrent_data = client.call("core.get_torrent_status", torrent_id, ["files", "label"])
torrent_files = torrent_data["files"]
category = torrent_data["label"].lower()

files = []
Example #39
0
import argparse
import urllib

from deluge_client import DelugeRPCClient


if __name__ == '__main__':
    parser = argparse.ArgumentParser(description='Stream something.')
    parser.add_argument('username', type=str, help='Deluge username')
    parser.add_argument('password', type=str, help='Deluge password')
    parser.add_argument('path_or_url', type=str, help='Path or URL to torrent')

    parser.add_argument('--hostname', '-o', type=str, default='localhost', help='Deluge daemon hostname or ip')
    parser.add_argument('--port', '-p', type=int, default=58846, help='Deluge daemon port')

    args = parser.parse_args()

    if args.path_or_url.startswith('http'):
        filedata = urllib.urlopen(args.path_or_url).read()
    else:
        with open(args.path_or_url, 'rb') as f:
            filedata = f.read()

    client = DelugeRPCClient(args.hostname, args.port, args.username, args.password)
    client.connect()

    result = client.streaming.stream_torrent(None, None, filedata, None, None, True)
    print(result['url'])
Example #40
0
                print("QB not found, trying deluge")
                if config["deluge"]["deluge_pass"] == "":
                    password = ""
                    if platform.system() == "Linux":
                        with open(os.getenv('HOME') + "/.config/deluge/auth",
                                  mode="r") as file:
                            auth = file.read()
                    else:
                        with open(os.getenv('APPDATA') + r'\deluge\auth',
                                  mode="r") as file:
                            auth = file.read()
                    password = auth.split(":")[1]
                    with open("config.json", mode="w") as file2:
                        config["deluge"]["deluge_pass"] = password
                        json.dump(config, file2, indent=4)
                client = DelugeRPCClient(config["deluge"]["deluge_ip"],
                                         config["deluge"]["deluge_port"],
                                         config["deluge"]["deluge_user"],
                                         config["deluge"]["deluge_pass"])
                client.connect()
                print("Connected to Deluge")
            except ConnectionRefusedError:
                print("Deluge not found")
                exit(0)

    while True:
        nomicon = loadNomicon()
        loopNomicon(client, nomicon)
        dumpNomicon(nomicon)
        time.sleep(1500)
Example #41
0
class DelugeClient:
    def __init__(self, host="", port=58846, username="", password=""):
        self.filter = {}
        self.rpc = DelugeRPCClient(
            host,
            port,
            username,
            password,
        )
        self.rpc.connect()
        if not self.rpc.connected:
            raise RuntimeError("Failed to connect to deluge rpc")

    def get_labels(self):
        labels = []
        results = self.rpc.call("label.get_labels")
        for result in results:
            labels.append(result.decode("utf-8"))
        return labels

    def search(self, filter_dict={}) -> list[Torrent]:
        results = []
        keys = ["name", "label", "progress", "save_path"]
        for filter_key in filter_dict.keys():
            if not filter_key in keys:
                keys.append(filter_key)

        if "extension" in keys:
            keys.remove("extension")
        if "file_path" in keys:
            keys.remove("file_path")

        torrents = self.rpc.call(
            "core.get_torrents_status",
            {},
            keys,
        )
        for id in torrents:
            torrent_data = {}
            for (key, value) in torrents[id].items():
                data_key = key.decode("utf-8")
                data_value = value

                try:
                    data_value = value.decode("utf-8")
                except (UnicodeDecodeError, AttributeError):
                    pass

                torrent_data[data_key] = data_value

            results.append(Torrent(id, torrent_data))

        return list(filter(lambda x: filter_torrent(x, filter_dict), results))

    def fuzzy_select(self, results: list[Torrent], query="") -> list[Torrent]:
        lines = []
        for result in results:
            lines.append(
                f"{result.id};;;{result.name};;;label: {result.label}")
        search_uuid = uuid.uuid4()
        search_filename = f"/tmp/deluge-search-{search_uuid}.tmp"
        output_filename = f"{search_filename}.out"
        search_file = open(search_filename, "w")
        search_file.write("\n".join(lines))
        search_file.close()
        cmd = f'cat {search_filename} | fzf --multi --delimiter=";;;" --with-nth=2.. --nth=1 --query="{query}" > {output_filename}'
        subprocess.call(cmd, shell=True)

        output_file = open(output_filename, "r")
        output = output_file.read()
        os.remove(search_filename)
        os.remove(output_filename)

        selected_ids = []
        selected_torrents = []
        output_lines = output.split("\n")
        for output_line in output_lines:
            selected_ids.append(output_line.split(";;;")[0])

        for selected_id in selected_ids:
            for result in results:
                if result.id == selected_id:
                    selected_torrents.append(result)

        return selected_torrents

    def move_torrents(self, ids, dest):
        self.rpc.call("core.move_storage", ids, dest)
Example #42
0
 def init(self):
     self.client = DelugeRPCClient(self.host, self.port, self.username, self.password)
     self.data = {}
def main(torrent_id, torrent_name, save_path): 
    file_extensions = ['r\d+', 'rar', 'zip']
    client = DelugeRPCClient(cfg.deluge_address, cfg.deluge_port, cfg.deluge_user, cfg.deluge_pass)
    client.connect()

    print("Starting '%s' with id='%s' at %s" % (torrent_name, torrent_id, datetime.datetime.now().strftime("%Y-%m-%d %H:%M:%S")))
    
    if not client.connected:
        print("Error connecting to deluge")
        sys.exit()
    
    #pprint.pprint(client.call('core.get_torrents_status', {}, ['name']))
    #pprint.pprint(client.call('core.get_torrent_status', torrent_id, ['files']))
    #print("|".join(file_extensions))
    
    try:
        torrent_file = client.call('core.get_torrent_status', torrent_id, ['files'])['files']
    except:
        print("Error matching torrent_id in deluge")
        sys.exit()
    
    neither_radarr_sonarr = True
    search = False
    for file in torrent_file:
        search = re.search("(" + "|".join(file_extensions) + ")$", file['path'])
        search = search.group() if search else None
        if search:
            print("Torrent contained unwanted file type:")
            print("\t" + file['path'] + "\t" + str(search))
    
            sonarr_item = search_sonarr_for_torrent_name(torrent_name)

            if not sonarr_item:
                radarr_item = search_radarr_for_torrent_name(torrent_name)

                if not radarr_item:
                    print("Torrent not found in radarr or sonarr")
                    break
                else:
                    neither_radarr_sonarr = False

            # Blacklist in sonarr
            
            if radarr_item:
                id = radarr_item['id']
                sonarr_radarr_target = delete_from_radarr
                print("\tSending to radarr background thread.")

            if sonarr_item:
                id = sonarr_item['id']
                sonarr_radarr_target = delete_from_sonarr
                print("\tSending to sonarr background thread.")

            thread = Thread(target = sonarr_radarr_target, args = (id, ))
            thread.start()
            thread.join()
            break
    
    if (not search) and (neither_radarr_sonarr):
        # Torrent is okay, lets start the download.
         print("Torrent is okay, un-pausing download. Neither radar or sonarr == %s" % (neither_radarr_sonarr))
         client.call('core.resume_torrent', [torrent_id])
    else:
        if sonarr_item:
            print("Requesting sonarr searches for the eppisode again")
            url = "http://%s:%s/sonarr/api/command?apikey=%s" % (sonarr_host, sonarr_port, cfg.sonarr_apikey)
        elif radarr_item:
            print("Requesting radarr searches for the eppisode again")
            url = "http://%s:%s/radarr/api/command?apikey=%s" % (radarr_host, radarr_port, cfg.radarr_apikey)
        else:
            print("Neither sonar or radarr... exiting...")
            sys.exit(0)
    
        data={"name": "EpisodeSearch", "episodeIds": [sonarr_item['episode']['id']]}
        #pprint.pprint(data)
        time.sleep(90)
        d = requests.post(url, json=data)
        print("\t'" + url + "', response=" + str(d.status_code) + "\r\n")
    
    print("____________________________________________\r\n")
Example #44
0
 def connect(self):
     self.client = DelugeRPCClient(self.host, int(self.port), self.username,
                                   self.password)
     self.client.connect()
     return self.client.connected
Example #45
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 prepare_config(self, config):
        config.setdefault('host', 'localhost')
        config.setdefault('port', 58846)
        return config

    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 #46
0
import requests
import json
import time
# ****************
# CHANGE INFO BELOW
# ****************
__APIURL__ = input("输入API地址(站内查看):")
__DE_URL__ = input("输入客户端IP(http://IP):")
__DE_PORT__ = input("输入客户端后端端口(非WebUI端口):")
__DE_PORT__ = int(__DE_PORT__)
__DE_USER__ = input("输入客户端用户名:")
__DE_PW__ = input("输入客户端密码:")

count = 0

client = DelugeRPCClient(__DE_URL__, __DE_PORT__, __DE_USER__, __DE_PW__)
print("Connecting to Deluge...")
client.connect()
print("Fetching DMHY torrents from Deluge...")
torrent_list = client.core.get_torrents_status({}, ['trackers'])
dmhy_torrent_hash_list = [
    hash_ for hash_ in torrent_list
    if "dmhy" in str(torrent_list[hash_][b'trackers'][0][b'url'])
]
dmhy_req_list = []
for i, hash_ in enumerate(dmhy_torrent_hash_list):
    dmhy_req_list.append({
        "jsonrpc": "2.0",
        "method": "query",
        "params": [str(hash_)[2:-1]],
        "id": i + 1
Example #47
0
class DelugeClient(object):
    def __init__(self, host, port, username, password):
        """
        Initializes a new Deluge client.
        
        url - The url where deluge json can be reached.
        password - The password used to login
        """
        self.host = host
        self.port = port
        self.username = username
        self.password = password
        self.rpcclient = DelugeRPCClient(self.host, self.port, self.username, self.password)
    
    def _login(self):
        """
        Logs into deluge
        """
        if not self.rpcclient.connected:
            self.rpcclient.connect()
    
    def test_connection(self):
        """
        Tests the Deluge RPC connection, returns message if found.
        """
        self._login()
        return 'Free space: %s' % humanize_bytes(self.rpcclient.call('core.get_free_space'))
    
    def get_torrents(self):
        """
        Returns a set of info hashes currently added to the client.
        """
        logger.info('Getting a list of torrent hashes')
        self._login()
        result = self.rpcclient.call('core.get_torrents_status', {}, ['name'])
        return set(x.lower() for x in result.keys())
    
    def add_torrent(self, torrent, destination_path, files, fast_resume=True):
        """
        Add a new torrent to Deluge.
        
        torrent is the decoded file as a python object.
        destination_path is where the links are. The complete files must be linked already.
        files is a list of files found in the torrent.
        """
        name = torrent[b'info'][b'name']
        logger.info('Trying to add a new torrent to deluge: %r' % name)
        
        destination_path = os.path.abspath(destination_path)
        
        infohash = hashlib.sha1(bencode(torrent[b'info'])).hexdigest()
        encoded_torrent = base64.b64encode(bencode(torrent))
        
        basename = os.path.basename(destination_path)
        mapped_files = {}
        for i, f in enumerate(files):
            mapped_files[i] = os.path.join(basename, *f['path'])
        
        self._login()
        result = self.rpcclient.call('core.add_torrent_file', 'torrent.torrent', encoded_torrent, {
                                                                'download_location': os.path.dirname(destination_path),
                                                                'mapped_files': mapped_files})
        
        return result and result.decode('utf-8') == infohash
Example #48
0
def main():
    parser = argparse.ArgumentParser(description="Clean up deluge torrents")
    parser.add_argument(
        "-s",
        "--server",
        action="append",
        type=DelugeUri,
        required=True,
        help=
        "Deluge host or IP addresses to connect to in the form of user:pass@hostname:port"
    )

    subparser_action = parser.add_subparsers(dest='action',
                                             help='action to take')

    parser_unreg = subparser_action.add_parser(
        'unreg',
        help='Delete torrents with "Unregistered torrent" error state')

    parser_free = subparser_action.add_parser(
        'space',
        help='Delete oldest torrents to reach a free disk space quota')
    parser_free.add_argument("-f",
                             "--free",
                             help="Target free space in GB",
                             type=int,
                             required=True)

    args = parser.parse_args()

    if not args.action:
        print("No action specified")
        sys.exit(2)

    clients = []
    futures = []
    for server in args.server:
        uri = urlparse('deluge://{}'.format(server))
        client = DelugeRPCClient(uri.hostname, uri.port if uri.port else 58846,
                                 uri.username, uri.password)
        client.connect()
        clients.append(client)

    if args.action == "unreg":
        with ThreadPoolExecutor(max_workers=10) as pool:
            futures += [pool.submit(cull_unregistered, c) for c in clients]

    elif args.action == "space":
        with ThreadPoolExecutor(max_workers=10) as pool:
            futures += [
                pool.submit(cull_by_diskspace, c, want_free=args.free * GB)
                for c in clients
            ]

    print(
        tabulate([[
            "{}:{}".format(clients[i].host, clients[i].port), "{} GB".format(
                round(
                    decodedict(clients[i].call('core.get_free_space')) / GB,
                    2)), futures[i].result()[0], "{} GB".format(
                        round(futures[i].result()[1] / GB, 2))
        ] for i in range(0, len(clients))],
                 headers=["server", "space free", "rm'd", "newly freed"]))
Example #49
0
def add_torrent(magnet_url):
    from deluge_client import DelugeRPCClient
    client = DelugeRPCClient('127.0.0.1', 2196, "seftembr", "TuGsFYqlNP")
    client.connect()
    result = client.call('core.add_torrent_magnet', magnet_url, {})
    print "Returned hash:", result
Example #50
0
class Deluge(implements(TorrentClient)):
    def __init__(self):
        self.client = DelugeRPCClient(config["deluge_hostname"],
                                      config["deluge_port"],
                                      config["deluge_username"],
                                      config["deluge_password"],
                                      decode_utf8=True,
                                      automatic_reconnect=True)

    def setup(self) -> bool:
        daemon_path = config["deluge_daemon_path"]
        if not os.path.isfile(daemon_path):
            logger.error("Deluge daemon path is invalid, cannot setup")
            return False

        config_path = os.path.join(ROOT_PATH, "deluged_config")
        logger.debug(f"Running deluge daemon with config path '{config_path}'")
        logger.debug(f'"{daemon_path}" -c "{config_path}"')
        subprocess.Popen(f'"{daemon_path}" -c "{config_path}"',
                         stdout=subprocess.PIPE,
                         shell=True)
        time.sleep(6)

        # TODO: Check if deluge has correct settings, if not change them and restart it
        # TODO: enable labels plugin
        return True

    def connect(self) -> bool:
        """Tries to connect to the service automatically"""
        try:
            self.client.connect()
            return self.client.connected
        except Exception as ex:
            logger.error(f"Could not connect to deluge daemon: {ex}")
            return False

    def run(self):
        """Tries to setup and connect automatically"""
        # Try to connect, maybe the daemon is already running
        if self.connect():
            logger.info("Deluge daemon is already running, skipping setup")
            return

        if self.setup() and self.connect():
            logger.info("Deluge daemon is up")
            return

        raise Exception("Failed to run Deluge")

    def add_torrent(self, magnet_uri: str, uid: str) -> TorrentInfo:
        # uid = uid.lower() # Labels plugin is not case sensitive
        # logger.debug(self.client.call('label.get_labels'))
        torrent_info = self.get_torrent_info(uid)
        if torrent_info:
            return torrent_info

        # https://github.com/deluge-torrent/deluge/blob/develop/deluge/core/torrent.py
        infohash = self.client.core.add_torrent_magnet(
            magnet_uri, {
                'download_location': os.path.abspath(
                    config['download_folder']),
                'stop_at_ratio': True,
                'stop_ratio': config["deluge_share_ratio"],
                'prioritize_first_last_pieces': True,
                'sequential_download': True,
                'name': uid
            })

        logger.debug(f"Torrent infohash: {infohash}")

        logger.debug(
            self.client.core.get_torrent_status(infohash, ["name", "paused"]))

        if not infohash:
            raise Exception("Unable to add torrent")

        # Set more trackers (this can speed up download)
        self.client.core.set_torrent_trackers(infohash, [{
            "url": t,
            "tier": i
        } for i, t in enumerate(TrackerList.get_list(TrackerList.Type.Best))])

        return self.get_torrent_info(uid)

    def list_torrents(self) -> List[str]:
        logger.info('Getting a list of torrent hashes')
        self._login()
        result = self.rpcclient.call('core.get_torrents_status', {}, ['name'])
        logger.debug(set(x.lower() for x in result.keys()))
        return result

    def get_torrent_info(self, uid: str) -> Optional[TorrentInfo]:
        # https://github.com/deluge-torrent/deluge/blob/develop/deluge/core/torrent.py#L1037
        result = self.client.core.get_torrents_status({'name': uid}, [
            "download_location", "download_payload_rate", "num_peers",
            "num_seeds", "ratio", "total_size", "progress", "files"
        ])

        if len(result.keys()) > 1:
            logger.error(
                f"More than one torrent with uid '{uid}'... This should not happen"
            )

        logger.debug(result)

        if result:
            hash = list(result.keys())[0]
            return TorrentInfo(hash=hash,
                               speed=result[hash]['download_payload_rate'],
                               peers=result[hash]['num_peers'],
                               seeders=result[hash]['num_seeds'],
                               ratio=result[hash]['ratio'],
                               size=result[hash]['total_size'],
                               progress=result[hash]['progress'] / 100.,
                               files=[
                                   os.path.join(
                                       result[hash]['download_location'],
                                       file['path'])
                                   for file in result[hash]['files']
                               ])

        return None

    def set_seed_ratio(self, seed_ratio):
        pass
remove = settings.deluge['remove']

if len(sys.argv) < 4:
    log.error("Not enough command line parameters present, are you launching this from deluge?")
    sys.exit()

path = str(sys.argv[3])
torrent_name = str(sys.argv[2])
torrent_id = str(sys.argv[1])
delete_dir = None

log.debug("Path: %s." % path)
log.debug("Torrent: %s." % torrent_name)
log.debug("Hash: %s." % torrent_id)

client = DelugeRPCClient(host=settings.deluge['host'], port=int(settings.deluge['port']), username=settings.deluge['user'], password=settings.deluge['pass'])
client.connect()

if client.connected:
    log.info("Successfully connected to Deluge")
else:
    log.error("Failed to connect to Deluge")
    sys.exit()

torrent_data = client.call('core.get_torrent_status', torrent_id, ['files', 'label'])
torrent_files = torrent_data['files']
category = torrent_data['label'].lower()

files = []
log.debug("List of files in torrent:")
for contents in torrent_files:
Example #52
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 #53
0
class Deluge(IntervalModule):
    """
    Deluge torrent module
    Requires `deluge-client`

    .. rubric:: Formatters:

    * `{num_torrents}`       - number of torrents in deluge
    * `{free_space_bytes}`   - bytes free in path
    * `{used_space_bytes}`   - bytes used in path
    * `{upload_rate}` - bytes sent per second
    * `{download_rate}` - bytes received per second
    * `{total_uploaded}`     - bytes sent total
    * `{total_downloaded}`     - bytes received total

    """

    settings = (
        'format',
        ('rounding', 'number of decimal places to round numbers too'),
        ('host', 'address of deluge server (default: 127.0.0.1)'),
        ('port', 'port of deluge server (default: 58846)'),
        ('username', 'username to authenticate with deluge'),
        ('password', 'password to authenticate to deluge'),
        ('path', 'override "download path" server-side when checking space used/free'),
        ('offline_string', 'string to output while unable to connect to deluge daemon')
    )
    required = ('username', 'password')

    host = '127.0.0.1'
    port = 58846
    path = None
    libtorrent_stats = False
    rounding = 2
    offline_string = 'offline'

    format = '⛆{num_torrents} ✇{free_space_bytes}'

    id = int(time.time())  # something random

    def init(self):
        self.client = DelugeRPCClient(self.host, self.port, self.username, self.password)
        self.data = {}

    def run(self):
        if not self.client.connected:
            try:
                self.client.connect()
            except OSError:
                self.output = {
                    'full_text': self.offline_string
                }
                return

        try:
            self.data = self.get_session_statistics()

            torrents = self.get_torrents_status()
            if torrents:
                self.data['num_torrents'] = len(torrents)

            if 'free_space_bytes' in self.format:
                self.data['free_space_bytes'] = self.get_free_space(self.path)
            if 'used_space_bytes' in self.format:
                self.data['used_space_bytes'] = self.get_path_size(self.path)
        except FailedToReconnectException:
            return

        self.parse_values(self.data)

        self.output = {
            'full_text': self.format.format(**self.data)
        }

    def parse_values(self, values):
        for k, v in values.items():
            if v:
                if k in ['total_upload', 'total_download', 'download_rate', 'upload_rate'] or k.endswith('_bytes'):
                    values[k] = '{value:.{round}f}{unit}'.format(round=self.rounding, **bytes_info_dict(v))

    def get_path_size(self, path=None):
        """
        get used space of path in bytes (default: download location)
        """
        if path is None:
            path = []
        return self.client.call('core.get_path_size', path)

    def get_free_space(self, path=None):
        """
        get free space of path in bytes (default: download location)
        """
        if path is None:
            path = []
        return self.client.call('core.get_free_space', path)

    def get_torrents_status(self, torrent_id=None, keys=None):
        if torrent_id is None:
            torrent_id = []
        if keys is None:
            keys = []
        return self.client.call('core.get_torrents_status', torrent_id, keys)

    def get_session_statistics(self):
        keys = ['upload_rate', 'download_rate', 'total_upload', 'total_download']

        out = {}  # some of the values from deluge-client are bytes, the others are ints - we need to decode them
        for k, v in self.client.call('core.get_session_status', keys).items():
            k = k.decode('utf-8')  # keys aswell
            if type(v) == bytes:
                out[k] = v.decode('utf-8')
            else:
                out[k] = v

        return out
Example #54
0
class Client(GenericClient, DelugeBase):
    def __init__(self, host=None, username=None, password=None):
        super().__init__('DelugeD', host, username, password)
        self.client = None

    def setup(self):
        parsed_url = urlparse(self.host)
        if self.client and all(
            [
                self.client.host == parsed_url.hostname,
                self.client.port == parsed_url.port,
                self.client.username == self.username,
                self.client.password == self.password
            ]
        ):
            return

        self.client = DelugeRPCClient(parsed_url.hostname, parsed_url.port or 58846, self.username, self.password)

    def _get_auth(self):
        self.setup()
        if not self.client.connected:
            try:
                for attempt in range(0, 5):
                    try:
                        self.client.connect()
                        break
                    except FailedToReconnectException:
                        time.sleep(5)
            except Exception as error:
                logger.debug(f"{self.name}: {error}")

        self.auth = self.client.connected
        return self.auth

    def _add_torrent_uri(self, result):
        remote_torrent = self.client.core.add_torrent_magnet(result.url, self.make_options(result))
        if not remote_torrent:
            return None

        result.hash = remote_torrent

        return remote_torrent

    def _add_torrent_file(self, result):
        if not result.content:
            result.content = {}
            return None

        remote_torrent = self.client.core.add_torrent_file(result.name + '.torrent', b64encode(result.content).decode('ascii'), self.make_options(result))
        if not remote_torrent:
            return None

        result.hash = remote_torrent

        return remote_torrent

    def _set_torrent_label(self, result):
        # No option for this built into the rpc, because it is a plugin
        label = settings.TORRENT_LABEL.lower()
        if result.show.is_anime:
            label = settings.TORRENT_LABEL_ANIME.lower()
        if ' ' in label:
            logger.exception(f'{self.name}: Invalid label. Label must not contain a space')
            return False

        if label:
            try:

                if 'label' not in [x.decode().lower() for x in self.client.core.get_available_plugins()]:
                    logger.debug(f'{self.name}: label plugin not detected')
                    return False

                self.client.core.enable_plugin('Label')
                self.client.core.enable_plugin('label')

                labels = [x.decode() for x in self.client.label.get_labels()]
                if label not in labels:
                    logger.debug(f'{self.name}: {label} label does not exist in Deluge we must add it')
                    self.client.label.add(label)
                    logger.debug(f'{self.name}: [{label}] label added to deluge')

                self.client.label.set_torrent(result.hash, label)
            except Exception as error:
                logger.info(f'{self.name}: Could not add label to torrent')
                logger.debug(error)
                # logger.debug(self.client.daemon.get_method_list())
                return False

        logger.debug(f'{self.name}: [{label}] label added to torrent')
        return True

    def testAuthentication(self):
        if self._get_auth() and self.client.daemon.info():
            return True, 'Success: Connected and Authenticated'
        else:
            return False, 'Error: Unable to Authenticate!  Please check your config!'
Example #55
0
class DelugeClientKORPI():
    """
    Class for controlling deluge client.
    """

    def __init__(self, username, password, host="127.0.0.1", port=58846):
        self._username = username
        self._password = password
        self._host = host
        self._port = port

        self.__client = DelugeRPCClient(host, int(port), username, password)

    def connect(self):
        self.__client.connect()

    def list(self):
        """Returns tuple with torrent hashes"""
        return self.__client.call("core.get_session_state")

    def status(self, thash=None):
        if thash:
            return self.__client.call('core.get_torrents_status', {"hash": thash}, [])
        else:
            return self.__client.call('core.get_torrents_status', {}, [])

    def completed(self, thash):
        """Returns % of downloaded from torrent."""
        status = self.__client.call('core.get_torrents_status', {"hash": thash}, [])

        thash = thash.encode("utf-8")
        if status[thash][b"total_wanted"] == 0:
            return 0
        else:
            return status[thash][b"total_done"] / status[thash][b"total_wanted"] * 100

    def pause(self, thash=None):
        """
        If hash not provided, pause/resume all torrents.
        Returns False if torrent(s) was paused, True otherwise.
        """
        if thash:
            status = self.status(thash)[thash.encode("utf-8")][b"paused"]
            if status:
                self.__client.call('core.resume_torrent', [thash])
            else:
                self.__client.call('core.pause_torrent', [thash])

            return status
        else:
            if self.all_paused():
                self.__client.call("core.resume_torrent", self.list())
            else:
                self.__client.call("core.pause_torrent", self.list())

            return self.all_paused()

    def add(self, magnet, directory, max_speed):
        return self.__client.call('core.add_torrent_magnet', magnet, 
            {"download_location": directory, "max_download_speed": max_speed})

    def remove(self, thash, with_files):
        """Set with_files True to remove with files"""
        if with_files == "True": with_files = True
        elif with_files == "False": with_files = False

        return self.__client.call("core.remove_torrent", thash, with_files)

    def free_space(self, directory):
        """Get free space in megabytes."""
        return self.__client.call("core.get_free_space", directory) * TO_GB

    def download_speed(self, dmax=-1):
        for thash in self.list():
            self.__client.call("core.set_torrent_max_download_speed", 
                                thash, int(dmax))

    def all_paused(self):
        return all(paused[b"paused"]
                   for _, paused in self.status().items())
def c_De():
    __APIURL__ = input("输入API地址(站内查看):")
    __DE_URL__ = input("输入客户端IP(http://IP):")
    __DE_PORT__ = input("输入客户端后端端口(非WebUI端口):")
    __DE_USER__ = input("输入客户端用户名:")
    __DE_PW__ = input("输入客户端密码:")

    count = 0

    client = DelugeRPCClient(__DE_URL__, __DE_PORT__, __DE_USER__, __DE_PW__)
    print("Connecting to Deluge...")
    client.connect()
    print("Fetching DMHY torrents from Deluge...")
    torrent_list = client.core.get_torrents_status({}, ['trackers'])
    dmhy_torrent_hash_list = [
        hash_ for hash_ in torrent_list
        if "dmhy" in str(torrent_list[hash_][b'trackers'][0][b'url'])
    ]
    dmhy_req_list = []
    for i, hash_ in enumerate(dmhy_torrent_hash_list):
        dmhy_req_list.append({
            "jsonrpc": "2.0",
            "method": "query",
            "params": [str(hash_)[2:-1]],
            "id": i + 1
        })
    print("Fetching Secure Code...")
    resp = requests.post(__APIURL__, json=dmhy_req_list)
    if resp.status_code != 200:
        raise (Exception("Error with Code {} Pls Try Again!".format(
            resp.status_code)))

    requested_secure_list = resp.json()

    error_torrent_hash_list = []
    print("Begin Updating...")
    for i, hash_ in enumerate(dmhy_torrent_hash_list):
        if "result" in requested_secure_list[i]:
            count += 1
            client.core.set_torrent_trackers(hash_, [{
                'url':
                "https://daydream.dmhy.best/announce?secure={}".format(
                    requested_secure_list[i]["result"]),
                'tier':
                0
            }])
            print("Edited Tracker for {} ({}/{})".format(
                str(hash_)[2:-1], count, len(requested_secure_list)))
        elif "error" in requested_secure_list[i]:
            print("Editing Tracker for {} failed {}. {}".format(
                str(hash_)[2:-1], requested_secure_list[i]["error"]["code"],
                requested_secure_list[i]["error"]["message"]))
            error_torrent_hash_list.append(str(hash_)[2:-1])
        else:
            print("Editing Tracker for {} failed.".format(str(hash_)[2:-1]))
            error_torrent_hash_list.append(str(hash_)[2:-1])

    print()
    print("Successfully edited {} of {} torrents with errors occurred below:".
          format(count, len(requested_secure_list)))
    for each in error_torrent_hash_list:
        print(each)

    print()
    for i in range(2):
        print("Retry Time {}".format(i + 1))

        dmhy_req_list.clear()
        dmhy_torrent_hash_list.clear()
        count = 0

        for i, hash_ in enumerate(error_torrent_hash_list):
            dmhy_torrent_hash_list.append(hash_)
            dmhy_req_list.append({
                "jsonrpc": "2.0",
                "method": "query",
                "params": [hash_],
                "id": i + 1
            })

        print("Fetching Secure Code...")
        resp = requests.post(__APIURL__, json=dmhy_req_list)

        if resp.status_code != 200:
            print("Failed to fetch secure code, retry later")
            time.sleep(20)
            continue

        requested_secure_list = resp.json()
        error_torrent_hash_list.clear()

        print("Begin Updating...")

        for i, hash_ in enumerate(dmhy_torrent_hash_list):
            if "result" in requested_secure_list[i]:
                count += 1
                client.core.set_torrent_trackers(hash_, [{
                    'url':
                    "https://daydream.dmhy.best/announce?secure={}".format(
                        requested_secure_list[i]["result"]),
                    'tier':
                    0
                }])
                print("Edited Tracker for {} ({}/{})".format(
                    str(hash_)[2:-1], count, len(requested_secure_list)))
            elif "error" in requested_secure_list[i]:
                print("Editing Tracker for {} failed {}. {}".format(
                    str(hash_)[2:-1],
                    requested_secure_list[i]["error"]["code"],
                    requested_secure_list[i]["error"]["message"]))
                error_torrent_hash_list.append(str(hash_)[2:-1])
            else:
                print("Editing Tracker for {} failed.".format(
                    str(hash_)[2:-1]))
                error_torrent_hash_list.append(str(hash_)[2:-1])

        print(
            "Successfully edited {} of {} torrents with errors occurred below:"
            .format(count, len(requested_secure_list)))
        if len(error_torrent_hash_list) == 0:
            break
    return 0
def connect_to_deluge():
    client = DelugeRPCClient(config.DLGD_HOST, config.DLGD_PORT, config.DLGD_USER, config.DLGD_PASS)
    client.connect()
    if client.connected: print "Connected to deluge daemon"

    from types import MethodType
    
    def add_torr_url(self, url):
        return self.call('core.add_torrent_url', wz.urls.url_fix(url), {})
    client.add_torr_url = MethodType(add_torr_url, client, DelugeRPCClient)

    def add_torr_file(self, file):
        f = open(file, 'rb')
        filedump = base64.encodestring(f.read())
        f.close()
        return self.call('core.add_torrent_file', file, filedump, {})
    client.add_torr_file = MethodType(add_torr_file, client, DelugeRPCClient)
    
    def add_label(self, label, options={}):
        label = normalize_label(label)
        self.call('label.add', label)
        if options:
            if options['move_completed_path']:
                    options.update({'move_completed': True, 'apply_move_completed': True})
            self.call('label.set_options', label, options)
    client.add_label = MethodType(add_label, client, DelugeRPCClient)
    
    def label_exist(self, label):
        label = normalize_label(label)
        if label in self.list_labels():
            return True
        else:
            return False
    client.label_exist = MethodType(label_exist, client, DelugeRPCClient)            
        
    def list_labels(self):
        return self.call('label.get_labels')
    client.list_labels = MethodType(list_labels, client, DelugeRPCClient)
    
    def add_tor_label(self, tor_id, label):
        return self.call('label.set_torrent', tor_id, normalize_label(label))
    client.add_tor_label = MethodType(add_tor_label, client, DelugeRPCClient)

    def session_state(self):
        return self.call('core.get_session_state')
    client.session_state = MethodType(session_state, client, DelugeRPCClient)
    
    def torrent_status(self, tid, fields = {}):
        return self.call('core.get_torrent_status', tid, fields)
    client.torrent_status = MethodType(torrent_status, client, DelugeRPCClient)

    def torrents_status(self, filters = {}, fields = []):
        return self.call('core.get_torrents_status', filters, fields)
    client.torrents_status = MethodType(torrents_status, client, DelugeRPCClient)
    
    def get_finished(self):
        torrs = torrents_status(self)
        for k,v in torrs.items():
            #print(k,v['name'])
            if v['is_finished'] == False:
                #print("Removing unfinished: " + v['name'] + " " + str(v['is_finished']))
                torrs.pop(k)
            elif v['tracker_host'] in config.REMOVE_SEEDS_EXCEPTION_TRACKERS:
                #print("Removing exception_tracker: " + v['name'])
                torrs.pop(k)
            elif not is_all_files_done(v):
                #print("Removing not_all_done: " + v['name'])
                torrs.pop(k)
        return torrs
    client.get_finished = MethodType(get_finished, client, DelugeRPCClient)
    
    def remove_finished(self):
        for k in get_finished(self):
            self.call('core.remove_torrent', k, False)
    client.remove_finished = MethodType(remove_finished, client, DelugeRPCClient)
    
    def is_all_files_done(tor):
        for i in tor['file_progress']:
            if i != 1.0: 
                return False
        return True

    return client
Example #58
0
import time
import vk_api

from deluge_client import DelugeRPCClient

vk = vk_api.VkApi(token='твой_ключ')

values = {'count': 1, 'time_offset': 5, 'filter': 'unread'}

client = DelugeRPCClient('127.0.0.1', 58846, 'pi', 'пароль_твоей_Raspberry')

client.connect()


def write_msg(user_id, msg, random):
    vk.method('messages.send', {
        'user_id': user_id,
        'message': msg,
        'random_id': random
    })


try:
    while True:
        response = vk.method('messages.getConversations', values)
        if response['items']:
            item = response['items'][0]
            last_mess = item['last_message']
            random = last_mess['random_id']
            my_id = last_mess['peer_id']
            text = last_mess['text']