コード例 #1
0
    def on_button_edithost_clicked(self, widget=None):
        log.debug('on_button_edithost_clicked')
        model, row = self.treeview.get_selection().get_selected()
        status = model[row][HOSTLIST_COL_STATUS]
        host_id = model[row][HOSTLIST_COL_ID]

        if status == 'Connected':
            def on_disconnect(reason):
                self._update_host_status()
            client.disconnect().addCallback(on_disconnect)
            return

        host_info = [
            self.liststore[row][HOSTLIST_COL_HOST],
            self.liststore[row][HOSTLIST_COL_PORT],
            self.liststore[row][HOSTLIST_COL_USER],
            self.liststore[row][HOSTLIST_COL_PASS]]
        new_host_info = self._run_addhost_dialog(edit_host_info=host_info)
        if new_host_info:
            hostname, port, username, password = new_host_info
            try:
                self.hostlist.update_host(host_id, hostname, port, username, password)
            except ValueError as ex:
                ErrorDialog(_('Error Updating Host'), ex).run()
            else:
                self.liststore[row] = host_id, hostname, port, username, password, '', ''
                self._update_host_status()
コード例 #2
0
ファイル: connect.py プロジェクト: s0undt3ch/Deluge
    def handle(self, host="127.0.0.1:58846", username="", password="", **options):
        self.console = component.get("ConsoleUI")
        try:
            host, port = host.split(":")
        except ValueError:
            port = 58846
        else:
            port = int(port)

        def do_connect():
            d = client.connect(host, port, username, password)
            def on_connect(result):
                self.console.write("{!success!}Connected to %s:%s!" % (host, port))
                component.start()

            def on_connect_fail(result):
                self.console.write("{!error!}Failed to connect to %s:%s with reason: %s" % (host, port, result.value.args[0]))

            d.addCallback(on_connect)
            d.addErrback(on_connect_fail)
            return d

        if client.connected():
            def on_disconnect(result):
                do_connect()
            client.disconnect().addCallback(on_disconnect)
        else:
            do_connect()
コード例 #3
0
ファイル: deluge.py プロジェクト: tubedogg/Flexget
 def on_get_torrents_status(torrents):
     config_path = os.path.expanduser(config.get('config_path', ''))
     for hash, torrent_dict in torrents.items():
         # Make sure it has a url so no plugins crash
         entry = Entry(deluge_id=hash, url='')
         if config_path:
             torrent_path = os.path.join(config_path, 'state', hash + '.torrent')
             if os.path.isfile(torrent_path):
                 entry['location'] = torrent_path
                 if not torrent_path.startswith('/'):
                     torrent_path = '/' + torrent_path
                 entry['url'] = 'file://' + torrent_path
             else:
                 log.warning('Did not find torrent file at %s' % torrent_path)
         for key, value in torrent_dict.items():
             if key in self.settings_map:
                 flexget_key = self.settings_map[key]
             else:
                 flexget_key = self.extra_settings_map[key]
             if isinstance(flexget_key, tuple):
                 flexget_key, format_func = flexget_key
                 value = format_func(value)
             entry[flexget_key] = value
         self.entries.append(entry)
     client.disconnect()
コード例 #4
0
ファイル: filter_deluge.py プロジェクト: wlof/tvrenamr
        def on_torrents_status(result):
            """
            Callback for the torrent_status() method.
            This method contains the actual ratio checking and is_finished.
 
            Once the list has been compiled the method defined in `cb_method` is called.
            """
            torrent_filelist = []
            for torrent_id, status in result.items():
                # Meh, float should be fine for this. Not mission critical.
                # We're going to ignore anything that hasn't either met our
                # ratio or is not yet finished.
                if float(ratio) > float(status['ratio']) \
                    or status['is_finished'] is False:
                        for f in status['files']:
                            torrent_filelist.append(os.path.join(status['save_path'], f['path']))
                                
            client.disconnect()
            reactor.stop()
 
            # Catch system exits and ignore them.
            try:
                cb_method(path, ignore_filelist=torrent_filelist)
            except exceptions.SystemExit:
                pass
コード例 #5
0
    def on_button_connect_clicked(self, widget=None):
        model, row = self.hostlist.get_selection().get_selected()
        if not row:
            return
        status = model[row][HOSTLIST_COL_STATUS]
        if status == _("Connected"):
            def on_disconnect(reason):
                self.__update_list()
            client.disconnect().addCallback(on_disconnect)
            return

        host_id = model[row][HOSTLIST_COL_ID]
        host = model[row][HOSTLIST_COL_HOST]
        port = model[row][HOSTLIST_COL_PORT]
        user = model[row][HOSTLIST_COL_USER]
        password = model[row][HOSTLIST_COL_PASS]

        if status == _("Offline") and \
                    self.builder.get_object("chk_autostart").get_active() and \
                    host in ("127.0.0.1", "localhost"):
            if not self.start_daemon(port, deluge.configmanager.get_config_dir()):
                log.debug("Failed to auto-start daemon")
                return
            return self.__connect(
                host_id, host, port, user, password, try_counter=6
            )
        return self.__connect(host_id, host, port, user, password)
コード例 #6
0
ファイル: mainwindow.py プロジェクト: NoGare/deluge1
    def quit(self, shutdown=False):
        """
        Quits the GtkUI

        :param shutdown: whether or not to shutdown the daemon as well
        :type shutdown: boolean
        """
        if shutdown:

            def on_daemon_shutdown(result):
                try:
                    reactor.stop()
                except ReactorNotRunning:
                    log.debug("Attempted to stop the reactor but it is not running...")

            client.daemon.shutdown().addCallback(on_daemon_shutdown)
            return
        if client.is_classicmode():
            reactor.stop()
            return
        if not client.connected():
            reactor.stop()
            return

        def on_client_disconnected(result):
            reactor.stop()

        client.disconnect().addCallback(on_client_disconnected)
コード例 #7
0
def endSession(esresult):
    if esresult:
        log.info(esresult)
        reactor.stop()
    else:
        client.disconnect()
        printSuccess(None, False, "Client disconnected.")
        reactor.stop()
コード例 #8
0
ファイル: deluge-remote.py プロジェクト: nathan-hoad/makeme
def on_done(value, message):
    global finished_count
    finished_count += 1
    print "finished_count %d out of %d" % (finished_count, method_count)
    stderr_print(message)

    if finished_count == method_count:
        client.disconnect()
        reactor.stop()
コード例 #9
0
ファイル: json_api.py プロジェクト: deluge-torrent/deluge
    def disable(self):
        client.deregister_event_handler('PluginEnabledEvent', self._json.get_remote_methods)
        client.deregister_event_handler('PluginDisabledEvent', self._json.get_remote_methods)

        if client.is_standalone():
            component.get('Web.PluginManager').stop()
        else:
            client.disconnect()
            client.set_disconnect_callback(None)
コード例 #10
0
ファイル: filter_deluge.py プロジェクト: wlof/tvrenamr
    def on_connect_fail(result):
        """
        Callback method for an unsuccessful connection to Deluge.
        """
        print "Failed to connect to the Deluge daemon, sure it's running?"
        print 'Exiting...'
 
        client.disconnect()
        reactor.stop()
        sys.exit()
コード例 #11
0
ファイル: conkyDeluge.py プロジェクト: k2s/conkyDeluge
    def on_get_torrents_status(self, torrents_status):

        self.torrents_status = torrents_status

        #for torrentid in torrents_status:
        #print torrentid
        #torrent_status =  torrents_status[torrentid]

        # Disconnect from the daemon once we successfully connect
        client.disconnect()
        # Stop the twisted main loop and exit
        reactor.stop()
コード例 #12
0
 def on_add_success(result):
   if not result:
     log.info("add torrent successful, was already enqueued")
     client.disconnect()
     reactor.stop()
   else:
     new_id = result
     c = client.core.set_torrent_move_completed_path(result, completed_dir)
     c.addCallback(lambda a: on_set_1(result, a))
     c.addErrback(on_add_fail)
     log.info("added new torrent: " + repr(result))
   new_id=None
コード例 #13
0
ファイル: eventview.py プロジェクト: Ashod/Deluge
    def _doRead(self):
        c = self.stdscr.getch()

        if c > 31 and c < 256:
            if chr(c) == 'Q':
                from twisted.internet import reactor
                if client.connected():
                    def on_disconnect(result):
                        reactor.stop()
                    client.disconnect().addCallback(on_disconnect)
                else:
                    reactor.stop()
                return
            elif chr(c) == 'q':
                self.back_to_overview()
                return

        if c == 27:
            self.back_to_overview()
            return

        # TODO: Scroll event list
        jumplen = self.rows - 3
        num_events = len( component.get("ConsoleUI").events )

        if c == curses.KEY_UP:
            self.offset -= 1
        elif c == curses.KEY_PPAGE:
            self.offset -= jumplen
        elif c == curses.KEY_HOME:
            self.offset = 0
        elif c == curses.KEY_DOWN:
            self.offset += 1
        elif c == curses.KEY_NPAGE:
            self.offset += jumplen
        elif c == curses.KEY_END:
            self.offset += num_events
        elif c == ord('j'):
            self.offset -= 1
        elif c == ord('k'):
            self.offset += 1

        if self.offset <= 0:
            self.offset = 0
        elif num_events > self.rows - 3:
            if self.offset > num_events - self.rows + 3:
                self.offset = num_events - self.rows + 3
        else:
            self.offset = 0

        self.refresh()
コード例 #14
0
ファイル: connectionmanager.py プロジェクト: laanwj/deluge
    def on_button_connect_clicked(self, widget=None):
        model, row = self.hostlist.get_selection().get_selected()
        if not row:
            return
        status = model[row][HOSTLIST_COL_STATUS]
        if status == "Connected":
            def on_disconnect(reason):
                self.__update_list()
            client.disconnect().addCallback(on_disconnect)
            return

        host_id = model[row][HOSTLIST_COL_ID]
        host = model[row][HOSTLIST_COL_HOST]
        port = model[row][HOSTLIST_COL_PORT]
        user = model[row][HOSTLIST_COL_USER]
        password = model[row][HOSTLIST_COL_PASS]

        if status == "Offline" and self.glade.get_widget("chk_autostart").get_active() and\
            host in ("127.0.0.1", "localhost"):
            # We need to start this localhost
            self.start_daemon(port, deluge.configmanager.get_config_dir())

            def on_connect_fail(result, try_counter):
                log.error("Connection to host failed..")
                # We failed connecting to the daemon, but lets try again
                if try_counter:
                    log.info("Retrying connection.. Retries left: %s", try_counter)
                    try_counter -= 1
                    import time
                    time.sleep(0.5)
                    do_retry_connect(try_counter)
                return result
            def do_retry_connect(try_counter):
                log.debug("user: %s pass: %s", user, password)
                d = client.connect(host, port, user, password)
                d.addCallback(self.__on_connected, host_id)
                d.addErrback(on_connect_fail, try_counter)

            do_retry_connect(6)


        def do_connect(*args):
            client.connect(host, port, user, password).addCallback(self.__on_connected, host_id)

        if client.connected():
            client.disconnect().addCallback(do_connect)
        else:
            do_connect()

        self.connection_manager.response(gtk.RESPONSE_OK)
コード例 #15
0
ファイル: mainwindow.py プロジェクト: deluge-torrent/deluge
        def quit_gtkui():
            def stop_gtk_reactor(result=None):
                self.restart = restart
                try:
                    reactor.callLater(0, reactor.fireSystemEvent, 'gtkui_close')
                except ReactorNotRunning:
                    log.debug('Attempted to stop the reactor but it is not running...')

            if shutdown:
                client.daemon.shutdown().addCallback(stop_gtk_reactor)
            elif not client.is_standalone() and client.connected():
                client.disconnect().addCallback(stop_gtk_reactor)
            else:
                stop_gtk_reactor()
コード例 #16
0
    def on_get_torrent_value(value):
	apagar=1
	for torrent in value:
		if value[torrent]["progress"] <>100 :
	        	apagar=0
			print value[torrent]["name"]
			break
	if apagar==1:
		#print "apague"
		bus = dbus.SystemBus()
		shut = bus.get_object('org.freedesktop.Hal','/org/freedesktop/Hal/devices/computer')
		shutr =  dbus.Interface(shut , 'org.freedesktop.Hal.Device.SystemPowerManagement')
		shutr.Shutdown()
        client.disconnect()
        reactor.stop()
コード例 #17
0
ファイル: connect.py プロジェクト: EiNSTeiN-/deluge-gtk3
    def handle(self, host="127.0.0.1:58846", username="", password="", **options):
        self.console = component.get("ConsoleUI")
        try:
            host, port = host.split(":")
        except ValueError:
            port = 58846
        else:
            port = int(port)

        def do_connect():
            d = client.connect(host, port, username, password)
            def on_connect(result):
                if self.console.interactive:
                    self.console.write("{!success!}Connected to %s:%s" % (host, port))
                return component.start()

            def on_connect_fail(result):
                try:
                    msg = result.value.exception_msg
                except:
                    msg = result.value.args[0]
                self.console.write("{!error!}Failed to connect to %s:%s with reason: %s" % (host, port, msg))
                return result

            d.addCallback(on_connect)
            d.addErrback(on_connect_fail)
            return d

        if client.connected():
            def on_disconnect(result):
                self.console.statusbars.update_statusbars()
                return do_connect()
            return client.disconnect().addCallback(on_disconnect)
        else:
            return do_connect()
コード例 #18
0
ファイル: quit.py プロジェクト: Ashod/Deluge
 def handle(self, *args, **options):
     if client.connected():
         def on_disconnect(result):
             reactor.stop()
         return client.disconnect().addCallback(on_disconnect)
     else:
         reactor.stop()
コード例 #19
0
    def on_button_edithost_clicked(self, widget=None):
        log.debug("on_button_edithost_clicked")
        model, row = self.hostlist.get_selection().get_selected()
        status = model[row][HOSTLIST_COL_STATUS]
        if status == _("Connected"):
            def on_disconnect(reason):
                self.__update_list()
            client.disconnect().addCallback(on_disconnect)
            return

        dialog = self.builder.get_object("addhost_dialog")
        dialog.set_transient_for(self.connection_manager)
        dialog.set_position(gtk.WIN_POS_CENTER_ON_PARENT)
        hostname_entry = self.builder.get_object("entry_hostname")
        port_spinbutton = self.builder.get_object("spinbutton_port")
        username_entry = self.builder.get_object("entry_username")
        password_entry = self.builder.get_object("entry_password")
        button_addhost_save = self.builder.get_object("button_addhost_save")
        button_addhost_save.show()
        button_addhost_add = self.builder.get_object("button_addhost_add")
        button_addhost_add.hide()

        username_entry.set_text(self.liststore[row][HOSTLIST_COL_USER])
        password_entry.set_text(self.liststore[row][HOSTLIST_COL_PASS])
        hostname_entry.set_text(self.liststore[row][HOSTLIST_COL_HOST])
        port_spinbutton.set_value(self.liststore[row][HOSTLIST_COL_PORT])

        response = dialog.run()

        if response == 2:
            self.liststore[row][HOSTLIST_COL_HOST] = hostname_entry.get_text()
            self.liststore[row][HOSTLIST_COL_PORT] = port_spinbutton.get_value_as_int()
            self.liststore[row][HOSTLIST_COL_USER] = username_entry.get_text()
            self.liststore[row][HOSTLIST_COL_PASS] = password_entry.get_text()
            self.liststore[row][HOSTLIST_COL_STATUS] = _("Offline")

        # Save the host list to file
        self.__save_hostlist()

        # Update the status of the hosts
        self.__update_list()

        username_entry.set_text("")
        password_entry.set_text("")
        hostname_entry.set_text("")
        port_spinbutton.set_value(58846)
        dialog.hide()
コード例 #20
0
ファイル: test_client.py プロジェクト: deluge-torrent/deluge
 def test_connect_with_password(self):
     username, password = get_localhost_auth()
     yield client.connect('localhost', self.listen_port, username=username, password=password)
     yield client.core.create_account('testuser', 'testpw', 'DEFAULT')
     yield client.disconnect()
     ret = yield client.connect('localhost', self.listen_port, username='******', password='******')
     self.assertEqual(ret, AUTH_LEVEL_NORMAL)
     yield
コード例 #21
0
ファイル: preferences.py プロジェクト: NoGare/deluge1
    def _doRead(self):
        c = self.stdscr.getch()

        if self.popup:
            if self.popup.handle_read(c):
                self.popup = None
            self.refresh()
            return

        if c > 31 and c < 256:
            if chr(c) == 'Q':
                from twisted.internet import reactor
                if client.connected():
                    def on_disconnect(result):
                        reactor.stop()
                    client.disconnect().addCallback(on_disconnect)
                else:
                    reactor.stop()            
                return
            elif chr(c) == 'h':
                self.popup = Popup(self,"Preferences Help")
                for l in HELP_LINES:
                    self.popup.add_line(l)

        if c == 9:
            self.active_zone += 1
            if self.active_zone > ZONE.ACTIONS:
                self.active_zone = ZONE.CATEGORIES

        elif c == curses.KEY_BTAB:
            self.active_zone -= 1
            if self.active_zone < ZONE.CATEGORIES:
                self.active_zone = ZONE.ACTIONS

        elif c == 114 and isinstance(self.panes[self.cur_cat],CachePane):
            client.core.get_cache_status().addCallback(self.panes[self.cur_cat].update_cache_status)

        else:
            if self.active_zone == ZONE.CATEGORIES:
                self.__category_read(c)
            elif self.active_zone == ZONE.PREFRENCES:
                self.__prefs_read(c)
            elif self.active_zone == ZONE.ACTIONS:
                self.__actions_read(c)

        self.refresh()
コード例 #22
0
    def on_button_connect_clicked(self, checked=False):
        host = self.selectedItem() # NB: get it before accept closes and deletes the dialog
        self.accept()

        if client.connected():
            yield client.disconnect()

        component.get("ConnectionManager").connect(host.config_tuple(), autostart=not host.is_alive())
コード例 #23
0
ファイル: json_api.py プロジェクト: deluge-torrent/deluge
    def disconnect(self):
        """
        Disconnect the web interface from the connected daemon.
        """
        d = client.disconnect()

        def on_disconnect(reason):
            return str(reason)
        d.addCallback(on_disconnect)
        return d
コード例 #24
0
ファイル: main.py プロジェクト: deluge-torrent/deluge
 def quit(self):
     if client.connected():
         def on_disconnect(result):
             reactor.stop()
         return client.disconnect().addCallback(on_disconnect)
     else:
         try:
             reactor.stop()
         except error.ReactorNotRunning:
             pass
コード例 #25
0
ファイル: mainwindow.py プロジェクト: s0undt3ch/Deluge
    def quit(self, shutdown=False):
        """
        Quits the GtkUI

        :param shutdown: whether or not to shutdown the daemon as well
        :type shutdown: boolean
        """
        if shutdown:
            def on_daemon_shutdown(result):
                reactor.stop()
            client.daemon.shutdown().addCallback(on_daemon_shutdown)
            return
        if client.is_classicmode():
            reactor.stop()
            return
        if not client.connected():
            reactor.stop()
            return
        def on_client_disconnected(result):
            reactor.stop()
        client.disconnect().addCallback(on_client_disconnected)
コード例 #26
0
    def __connect(self, host_id, host, port, username, password,
                  skip_authentication=False, try_counter=0):
        def do_connect(*args):
            d = client.connect(host, port, username, password, skip_authentication)
            d.addCallback(self.__on_connected, host_id)
            d.addErrback(self.__on_connected_failed, host_id, host, port,
                         username, password, try_counter)
            return d

        if client.connected():
            return client.disconnect().addCallback(do_connect)
        else:
            return do_connect()
コード例 #27
0
def process_torrents():
 
    client_connected = False
 
    try:
        yield client.connect(host=deluge_host, username=deluge_username, password=deluge_password)
        client_connected = True
        log.info("Connected to deluge")
        torrents = yield client.core.get_torrents_status({}, ['name','label','progress','save_path','state','files'])
 
        downloads = [{
               'id' : id,
               'location' : torrent['save_path'] + '/' + torrent['name'],
               'label' : torrent['label']
            } for id, torrent in torrents.iteritems() if torrent['progress'] == 100 and torrent['label'].startswith('download')]
 
        log.info('List of torrents to download: %s', downloads)
 
        for torrent in downloads:
            log.info('Downloading torrent: %s', torrent)
 
            remote_location = torrent['location'].replace(' ', '\ ').replace('(', '\(').replace(')', '\)').replace('&', '\&').replace('[', '\[').replace(']', '\]').replace('\'', '\\\'')
            save_location = complete_dir + '/' + torrent['label']
 
            log.info('Remote location: %s', remote_location)
            log.info('Save location: %s', save_location)
 
            source = rsync_username + "@" + deluge_host + ":" + remote_location
            result = sshpass("-p", rsync_password, "rsync", "-hre", "ssh -o StrictHostKeyChecking=no", "-T", partial_dir, "--partial", "--progress", source, save_location)
            log.info('Got rsync result: %s', result)
            if (result.exit_code == 0):
                log.info('Remove label from torrent: %s', torrent)
                yield client.label.set_torrent(torrent['id'], 'No Label')
 
    except Exception as err:
        log.exception("Error downloading torrent")
 
    finally:
        if client_connected:
            log.info('Disconnecting deluge client')
            yield client.disconnect()
        log.info('Stopping reactor')
        reactor.stop()
コード例 #28
0
    def _connect(self, host_id, username=None, password=None, try_counter=0):
        def do_connect(result, username=None, password=None, *args):
            log.debug('Attempting to connect to daemon...')
            for host_entry in self.hostlist.config['hosts']:
                if host_entry[0] == host_id:
                    __, host, port, host_user, host_pass = host_entry

            username = username if username else host_user
            password = password if password else host_pass

            d = client.connect(host, port, username, password)
            d.addCallback(self._on_connect, host_id)
            d.addErrback(self._on_connect_fail, host_id, try_counter)
            return d

        if client.connected():
            return client.disconnect().addCallback(do_connect, username, password)
        else:
            return do_connect(None, username, password)
コード例 #29
0
ファイル: connect.py プロジェクト: deluge-torrent/deluge
    def handle(self, options):
        self.console = component.get('ConsoleUI')

        host = options.host
        try:
            host, port = host.split(':')
            port = int(port)
        except ValueError:
            port = 58846

        def do_connect():
            d = client.connect(host, port, options.username, options.password)

            def on_connect(result):
                if self.console.interactive:
                    self.console.write('{!success!}Connected to %s:%s!' % (host, port))
                return component.start()

            def on_connect_fail(result):
                try:
                    msg = result.value.exception_msg
                except AttributeError:
                    msg = result.value.message
                self.console.write('{!error!}Failed to connect to %s:%s with reason: %s' % (host, port, msg))
                return result

            d.addCallbacks(on_connect, on_connect_fail)
            return d

        if client.connected():

            def on_disconnect(result):
                if self.console.statusbars:
                    self.console.statusbars.update_statusbars()
                return do_connect()
            return client.disconnect().addCallback(on_disconnect)
        else:
            return do_connect()
コード例 #30
0
    def on_button_connect_clicked(self, widget=None):
        """Button handler for connect to or disconnect from daemon."""
        model, row = self.treeview.get_selection().get_selected()
        if not row:
            return

        host_id, host, port, __, __, status, __ = model[row]
        # If status is connected then connect button disconnects instead.
        if status == 'Connected':
            def on_disconnect(reason):
                self._update_host_status()
            return client.disconnect().addCallback(on_disconnect)

        try_counter = 0
        auto_start = self.builder.get_object('chk_autostart').get_active()
        if auto_start and host in LOCALHOST and status == 'Offline':
            # Start the local daemon and then connect with retries set.
            if self.start_daemon(port, get_config_dir()):
                try_counter = 6
            else:
                # Don't attempt to connect to offline daemon.
                return

        self._connect(host_id, try_counter=try_counter)
コード例 #31
0
 def disconnect_client(result):
     return client.disconnect()
コード例 #32
0
def get_torrent_data(torrent_id):
    print torrent_id
    client.disconnect()
    reactor.stop()
コード例 #33
0
 def on_set_2(new_id, result):
     client.disconnect()
     reactor.stop()
コード例 #34
0
 def on_add_fail(result):
     log.info("add torrent failed: " + repr(result) + str(result))
     client.disconnect()
     reactor.stop()
コード例 #35
0
    def on_connect_success(self, result, task, config):
        """Gets called when successfully connected to a daemon."""
        from deluge.ui.client import client
        from twisted.internet import reactor, defer

        if not result:
            log.debug('on_connect_success returned a failed result. BUG?')

        if task.manager.options.test:
            log.debug('Test connection to deluge daemon successful.')
            client.disconnect()
            return

        def format_label(label):
            """Makes a string compliant with deluge label naming rules"""
            return re.sub('[^\w-]+', '_', label.lower())

        def set_torrent_options(torrent_id, entry, opts):
            """Gets called when a torrent was added to the daemon."""
            dlist = []
            if not torrent_id:
                log.error('There was an error adding %s to deluge.' %
                          entry['title'])
                # TODO: Fail entry? How can this happen still now?
                return
            log.info('%s successfully added to deluge.' % entry['title'])
            entry['deluge_id'] = torrent_id

            def create_path(result, path):
                """Creates the specified path if deluge is older than 1.3"""
                from deluge.common import VersionSplit
                # Before 1.3, deluge would not create a non-existent move directory, so we need to.
                if VersionSplit('1.3.0') > VersionSplit(self.deluge_version):
                    if client.is_localhost():
                        if not os.path.isdir(path):
                            log.debug('path %s doesn\'t exist, creating' %
                                      path)
                            os.makedirs(path)
                    else:
                        log.warning(
                            'If path does not exist on the machine running the daemon, move will fail.'
                        )

            if opts.get('movedone'):
                dlist.append(
                    version_deferred.addCallback(create_path,
                                                 opts['movedone']))
                dlist.append(
                    client.core.set_torrent_move_completed(torrent_id, True))
                dlist.append(
                    client.core.set_torrent_move_completed_path(
                        torrent_id, opts['movedone']))
                log.debug('%s move on complete set to %s' %
                          (entry['title'], opts['movedone']))
            if opts.get('label'):

                def apply_label(result, torrent_id, label):
                    """Gets called after labels and torrent were added to deluge."""
                    return client.label.set_torrent(torrent_id, label)

                dlist.append(
                    label_deferred.addCallback(apply_label, torrent_id,
                                               opts['label']))
            if opts.get('queuetotop') is not None:
                if opts['queuetotop']:
                    dlist.append(client.core.queue_top([torrent_id]))
                    log.debug('%s moved to top of queue' % entry['title'])
                else:
                    dlist.append(client.core.queue_bottom([torrent_id]))
                    log.debug('%s moved to bottom of queue' % entry['title'])

            def on_get_torrent_status(status):
                """Gets called with torrent status, including file info.
                Sets the torrent options which require knowledge of the current status of the torrent."""

                main_file_dlist = []

                # Determine where the file should be
                move_now_path = None
                if opts.get('movedone'):
                    if status['progress'] == 100:
                        move_now_path = opts['movedone']
                    else:
                        # Deluge will unset the move completed option if we move the storage, forgo setting proper
                        # path, in favor of leaving proper final location.
                        log.debug(
                            'Not moving storage for %s, as this will prevent movedone.'
                            % entry['title'])
                elif opts.get('path'):
                    move_now_path = opts['path']

                if move_now_path and os.path.normpath(
                        move_now_path) != os.path.normpath(
                            status['save_path']):
                    main_file_dlist.append(
                        version_deferred.addCallback(create_path,
                                                     move_now_path))
                    log.debug('Moving storage for %s to %s' %
                              (entry['title'], move_now_path))
                    main_file_dlist.append(
                        client.core.move_storage([torrent_id], move_now_path))

                if opts.get('content_filename') or opts.get('main_file_only'):

                    def file_exists():
                        # Checks the download path as well as the move completed path for existence of the file
                        if os.path.exists(
                                os.path.join(status['save_path'], filename)):
                            return True
                        elif status.get('move_on_completed') and status.get(
                                'move_on_completed_path'):
                            if os.path.exists(
                                    os.path.join(
                                        status['move_on_completed_path'],
                                        filename)):
                                return True
                        else:
                            return False

                    for file in status['files']:
                        # Only rename file if it is > 90% of the content
                        if file['size'] > (status['total_size'] * 0.9):
                            if opts.get('content_filename'):
                                filename = opts[
                                    'content_filename'] + os.path.splitext(
                                        file['path'])[1]
                                counter = 1
                                if client.is_localhost():
                                    while file_exists():
                                        # Try appending a (#) suffix till a unique filename is found
                                        filename = ''.join([
                                            opts['content_filename'], '(',
                                            str(counter), ')',
                                            os.path.splitext(file['path'])[1]
                                        ])
                                        counter += 1
                                else:
                                    log.debug(
                                        'Cannot ensure content_filename is unique '
                                        'when adding to a remote deluge daemon.'
                                    )
                                log.debug(
                                    'File %s in %s renamed to %s' %
                                    (file['path'], entry['title'], filename))
                                main_file_dlist.append(
                                    client.core.rename_files(
                                        torrent_id,
                                        [(file['index'], filename)]))
                            if opts.get('main_file_only'):
                                file_priorities = [
                                    1 if f['index'] == file['index'] else 0
                                    for f in status['files']
                                ]
                                main_file_dlist.append(
                                    client.core.set_torrent_file_priorities(
                                        torrent_id, file_priorities))
                            break
                    else:
                        log.warning(
                            'No files in %s are > 90%% of content size, no files renamed.'
                            % entry['title'])

                return defer.DeferredList(main_file_dlist)

            status_keys = [
                'files', 'total_size', 'save_path', 'move_on_completed_path',
                'move_on_completed', 'progress'
            ]
            dlist.append(
                client.core.get_torrent_status(
                    torrent_id,
                    status_keys).addCallback(on_get_torrent_status))

            return defer.DeferredList(dlist)

        def on_fail(result, task, entry):
            """Gets called when daemon reports a failure adding the torrent."""
            log.info('%s was not added to deluge! %s' %
                     (entry['title'], result))
            entry.fail('Could not be added to deluge')

        # dlist is a list of deferreds that must complete before we exit
        dlist = []
        # loop through entries to get a list of labels to add
        labels = set([
            format_label(entry['label']) for entry in task.accepted
            if entry.get('label')
        ])
        if config.get('label'):
            labels.add(format_label(config['label']))
        label_deferred = defer.succeed(True)
        if labels:
            # Make sure the label plugin is available and enabled, then add appropriate labels

            def on_get_enabled_plugins(plugins):
                """Gets called with the list of enabled deluge plugins."""
                def on_label_enabled(result):
                    """ This runs when we verify the label plugin is enabled. """
                    def on_get_labels(d_labels):
                        """Gets available labels from deluge, and adds any new labels we need."""
                        dlist = []
                        for label in labels:
                            if not label in d_labels:
                                log.debug('Adding the label %s to deluge' %
                                          label)
                                dlist.append(client.label.add(label))
                        return defer.DeferredList(dlist)

                    return client.label.get_labels().addCallback(on_get_labels)

                if 'Label' in plugins:
                    return on_label_enabled(True)
                else:
                    # Label plugin isn't enabled, so we check if it's available and enable it.

                    def on_get_available_plugins(plugins):
                        """Gets plugins available to deluge, enables Label plugin if available."""
                        if 'Label' in plugins:
                            log.debug('Enabling label plugin in deluge')
                            return client.core.enable_plugin(
                                'Label').addCallback(on_label_enabled)
                        else:
                            log.error(
                                'Label plugin is not installed in deluge')

                    return client.core.get_available_plugins().addCallback(
                        on_get_available_plugins)

            label_deferred = client.core.get_enabled_plugins().addCallback(
                on_get_enabled_plugins)
            dlist.append(label_deferred)

        def on_get_daemon_info(ver):
            """Gets called with the daemon version info, stores it in self."""
            log.debug('deluge version %s' % ver)
            self.deluge_version = ver

        version_deferred = client.daemon.info().addCallback(on_get_daemon_info)
        dlist.append(version_deferred)

        def on_get_session_state(torrent_ids):
            """Gets called with a list of torrent_ids loaded in the deluge session.
            Adds new torrents and modifies the settings for ones already in the session."""
            dlist = []
            # add the torrents
            for entry in task.accepted:

                def add_entry(entry, opts):
                    """Adds an entry to the deluge session"""
                    magnet, filedump = None, None
                    if entry.get('url', '').startswith('magnet:'):
                        magnet = entry['url']
                    else:
                        if not os.path.exists(entry['file']):
                            entry.fail(
                                'Downloaded temp file \'%s\' doesn\'t exist!' %
                                entry['file'])
                            del (entry['file'])
                            return
                        with open(entry['file'], 'rb') as f:
                            filedump = base64.encodestring(f.read())

                    log.verbose('Adding %s to deluge.' % entry['title'])
                    if magnet:
                        return client.core.add_torrent_magnet(magnet, opts)
                    else:
                        return client.core.add_torrent_file(
                            entry['title'], filedump, opts)

                # Generate deluge options dict for torrent add
                add_opts = {}
                try:
                    path = entry.render(entry.get('path', config['path']))
                    if path:
                        add_opts['download_location'] = pathscrub(
                            os.path.expanduser(path))
                except RenderError as e:
                    log.error('Could not set path for %s: %s' %
                              (entry['title'], e))
                for fopt, dopt in self.options.iteritems():
                    value = entry.get(fopt, config.get(fopt))
                    if value is not None:
                        add_opts[dopt] = value
                        if fopt == 'ratio':
                            add_opts['stop_at_ratio'] = True
                # Make another set of options, that get set after the torrent has been added
                modify_opts = {
                    'label':
                    format_label(entry.get('label', config['label'])),
                    'queuetotop':
                    entry.get('queuetotop', config.get('queuetotop')),
                    'main_file_only':
                    entry.get('main_file_only',
                              config.get('main_file_only', False))
                }
                try:
                    movedone = entry.render(
                        entry.get('movedone', config['movedone']))
                    modify_opts['movedone'] = pathscrub(
                        os.path.expanduser(movedone))
                except RenderError as e:
                    log.error('Error setting movedone for %s: %s' %
                              (entry['title'], e))
                try:
                    content_filename = entry.get(
                        'content_filename', config.get('content_filename', ''))
                    modify_opts['content_filename'] = pathscrub(
                        entry.render(content_filename))
                except RenderError as e:
                    log.error('Error setting content_filename for %s: %s' %
                              (entry['title'], e))

                torrent_id = entry.get('deluge_id') or entry.get(
                    'torrent_info_hash')
                torrent_id = torrent_id and torrent_id.lower()
                if torrent_id in torrent_ids:
                    log.info(
                        '%s is already loaded in deluge, setting options' %
                        entry['title'])
                    # Entry has a deluge id, verify the torrent is still in the deluge session and apply options
                    # Since this is already loaded in deluge, we may also need to change the path
                    modify_opts['path'] = add_opts.pop('download_location',
                                                       None)
                    dlist.extend([
                        set_torrent_options(torrent_id, entry, modify_opts),
                        client.core.set_torrent_options([torrent_id], add_opts)
                    ])
                else:
                    dlist.append(
                        add_entry(entry, add_opts).addCallbacks(
                            set_torrent_options,
                            on_fail,
                            callbackArgs=(entry, modify_opts),
                            errbackArgs=(task, entry)))
            return defer.DeferredList(dlist)

        dlist.append(
            client.core.get_session_state().addCallback(on_get_session_state))

        def on_complete(result):
            """Gets called when all of our tasks for deluge daemon are complete."""
            client.disconnect()

        tasks = defer.DeferredList(dlist).addBoth(on_complete)

        def on_timeout(result):
            """Gets called if tasks have not completed in 30 seconds.
            Should only happen when something goes wrong."""
            log.error('Timed out while adding torrents to deluge.')
            log.debug('dlist: %s' % result.resultList)
            client.disconnect()

        # Schedule a disconnect to happen if FlexGet hangs while connected to Deluge
        # Leave the timeout long, to give time for possible lookups to occur
        reactor.callLater(300, lambda: tasks.called or on_timeout(tasks))
コード例 #36
0
    def _doRead(self):
        c = self.stdscr.getch()

        if self.popup:
            if self.popup.handle_read(c):
                self.popup = None
            self.refresh()
            return

        if c > 31 and c < 256:
            if chr(c) == 'Q':
                from twisted.internet import reactor
                if client.connected():

                    def on_disconnect(result):
                        reactor.stop()

                    client.disconnect().addCallback(on_disconnect)
                else:
                    reactor.stop()
                return
            elif chr(c) == 'q':
                self.back_to_overview()
                return

        # Navigate the torrent list
        if c == curses.KEY_UP:
            self.scroll_list_up(1)
        elif c == curses.KEY_PPAGE:
            #self.scroll_list_up(self._listing_space-2)
            self.scroll_list_up(self.rows // 2)
        elif c == curses.KEY_HOME:
            self.scroll_list_up(len(self.formatted_rows))
        elif c == curses.KEY_DOWN:
            self.scroll_list_down(1)
        elif c == curses.KEY_NPAGE:
            #self.scroll_list_down(self._listing_space-2)
            self.scroll_list_down(self.rows // 2)
        elif c == curses.KEY_END:
            self.scroll_list_down(len(self.formatted_rows))
        elif c == curses.KEY_RIGHT:
            if self.cursel < len(self.listing_dirs):
                self._enter_dir()
        elif c == curses.KEY_LEFT:
            self._go_up()
        # Enter Key
        elif c == curses.KEY_ENTER or c == 10:
            self._perform_action()
        #Escape
        elif c == 27:
            self.back_to_overview()
        else:
            if c > 31 and c < 256:
                if chr(c) == 'h':
                    self.popup = MessagePopup(self,
                                              "Help",
                                              HELP_STR,
                                              width_req=0.75)
                elif chr(c) == '>':
                    if self.sort_column == "date":
                        self.reverse_sort = not self.reverse_sort
                    else:
                        self.sort_column = "date"
                        self.reverse_sort = True
                    self.__sort_rows()
                elif chr(c) == '<':
                    if self.sort_column == "name":
                        self.reverse_sort = not self.reverse_sort
                    else:
                        self.sort_column = "name"
                        self.reverse_sort = False
                    self.__sort_rows()
                elif chr(c) == 'm':
                    s = self.raw_rows[self.cursel][0]
                    if s in self.marked:
                        self.marked.remove(s)
                    else:
                        self.marked.add(s)

                    self.last_mark = self.cursel
                elif chr(c) == 'j':
                    self.scroll_list_up(1)
                elif chr(c) == 'k':
                    self.scroll_list_down(1)
                elif chr(c) == 'M':
                    if self.last_mark != -1:
                        if self.last_mark > self.cursel:
                            m = range(self.cursel, self.last_mark)
                        else:
                            m = range(self.last_mark, self.cursel + 1)

                        for i in m:
                            s = self.raw_rows[i][0]
                            self.marked.add(s)
                elif chr(c) == 'c':
                    self.marked.clear()

        self.refresh()
コード例 #37
0
 def on_complete(result):
     """Gets called when all of our tasks for deluge daemon are complete."""
     client.disconnect()
コード例 #38
0
 def on_timeout(result):
     """Gets called if tasks have not completed in 30 seconds.
     Should only happen when something goes wrong."""
     log.error('Timed out while adding torrents to deluge.')
     log.debug('dlist: %s' % result.resultList)
     client.disconnect()
コード例 #39
0
 def disconnect_client(self, *args):
     return client.disconnect()
コード例 #40
0
def stop_reactor():
    client.disconnect().addCallback(lambda ignore: reactor.stop())
    LOGGER.info('Disconnecting from client')
    LOGGER.info('Stopping reactor')
コード例 #41
0
 def on_get_torrent_status(torrent):
     print torrent["label"]
     client.disconnect()
     reactor.stop()
コード例 #42
0
 def dl_finish(result):
     print "All deferred calls have fired, exiting program..."
     client.disconnect()
     # Stop the twisted main loop and exit
     reactor.stop()
コード例 #43
0
ファイル: deluge.py プロジェクト: paulcunnane/Flexget
    def on_connect_success(self, result, task, config):
        """Gets called when successfully connected to a daemon."""
        from deluge.ui.client import client
        from twisted.internet import reactor, defer

        if not result:
            log.debug('on_connect_success returned a failed result. BUG?')

        if task.options.test:
            log.debug('Test connection to deluge daemon successful.')
            client.disconnect()
            return

        def format_label(label):
            """Makes a string compliant with deluge label naming rules"""
            return re.sub('[^\w-]+', '_', label.lower())

        def set_torrent_options(torrent_id, entry, opts):
            """Gets called when a torrent was added to the daemon."""
            dlist = []
            if not torrent_id:
                log.error('There was an error adding %s to deluge.' %
                          entry['title'])
                # TODO: Fail entry? How can this happen still now?
                return
            log.info('%s successfully added to deluge.' % entry['title'])
            entry['deluge_id'] = torrent_id

            def create_path(result, path):
                """Creates the specified path if deluge is older than 1.3"""
                from deluge.common import VersionSplit
                # Before 1.3, deluge would not create a non-existent move directory, so we need to.
                if VersionSplit('1.3.0') > VersionSplit(self.deluge_version):
                    if client.is_localhost():
                        if not os.path.isdir(path):
                            log.debug('path %s doesn\'t exist, creating' %
                                      path)
                            os.makedirs(path)
                    else:
                        log.warning(
                            'If path does not exist on the machine running the daemon, move will fail.'
                        )

            if opts.get('movedone'):
                dlist.append(
                    version_deferred.addCallback(create_path,
                                                 opts['movedone']))
                dlist.append(
                    client.core.set_torrent_move_completed(torrent_id, True))
                dlist.append(
                    client.core.set_torrent_move_completed_path(
                        torrent_id, opts['movedone']))
                log.debug('%s move on complete set to %s' %
                          (entry['title'], opts['movedone']))
            if opts.get('label'):

                def apply_label(result, torrent_id, label):
                    """Gets called after labels and torrent were added to deluge."""
                    return client.label.set_torrent(torrent_id, label)

                dlist.append(
                    label_deferred.addCallback(apply_label, torrent_id,
                                               opts['label']))
            if opts.get('queuetotop') is not None:
                if opts['queuetotop']:
                    dlist.append(client.core.queue_top([torrent_id]))
                    log.debug('%s moved to top of queue' % entry['title'])
                else:
                    dlist.append(client.core.queue_bottom([torrent_id]))
                    log.debug('%s moved to bottom of queue' % entry['title'])

            def on_get_torrent_status(status):
                """Gets called with torrent status, including file info.
                Sets the torrent options which require knowledge of the current status of the torrent."""

                main_file_dlist = []

                # Determine where the file should be
                move_now_path = None
                if opts.get('movedone'):
                    if status['progress'] == 100:
                        move_now_path = opts['movedone']
                    else:
                        # Deluge will unset the move completed option if we move the storage, forgo setting proper
                        # path, in favor of leaving proper final location.
                        log.debug(
                            'Not moving storage for %s, as this will prevent movedone.'
                            % entry['title'])
                elif opts.get('path'):
                    move_now_path = opts['path']

                if move_now_path and os.path.normpath(
                        move_now_path) != os.path.normpath(
                            status['save_path']):
                    main_file_dlist.append(
                        version_deferred.addCallback(create_path,
                                                     move_now_path))
                    log.debug('Moving storage for %s to %s' %
                              (entry['title'], move_now_path))
                    main_file_dlist.append(
                        client.core.move_storage([torrent_id], move_now_path))

                if opts.get('content_filename') or opts.get('main_file_only'):

                    def file_exists(filename):
                        # Checks the download path as well as the move completed path for existence of the file
                        if os.path.exists(
                                os.path.join(status['save_path'], filename)):
                            return True
                        elif status.get('move_on_completed') and status.get(
                                'move_on_completed_path'):
                            if os.path.exists(
                                    os.path.join(
                                        status['move_on_completed_path'],
                                        filename)):
                                return True
                        else:
                            return False

                    def unused_name(name):
                        # If on local computer, tries appending a (#) suffix until a unique filename is found
                        if client.is_localhost():
                            counter = 2
                            while file_exists(name):
                                name = ''.join([
                                    os.path.splitext(name)[0], " (",
                                    str(counter), ')',
                                    os.path.splitext(name)[1]
                                ])
                                counter += 1
                        else:
                            log.debug(
                                'Cannot ensure content_filename is unique '
                                'when adding to a remote deluge daemon.')
                        return name

                    def rename(file, new_name):
                        # Renames a file in torrent
                        main_file_dlist.append(
                            client.core.rename_files(
                                torrent_id, [(file['index'], new_name)]))
                        log.debug('File %s in %s renamed to %s' %
                                  (file['path'], entry['title'], new_name))

                    # find a file that makes up more than main_file_ratio (default: 90%) of the total size
                    main_file = None
                    for file in status['files']:
                        if file['size'] > (status['total_size'] *
                                           opts.get('main_file_ratio')):
                            main_file = file
                            break

                    if main_file is not None:
                        # proceed with renaming only if such a big file is found

                        # find the subtitle file
                        keep_subs = opts.get('keep_subs')
                        sub_file = None
                        if keep_subs:
                            sub_exts = [".srt", ".sub"]
                            for file in status['files']:
                                ext = os.path.splitext(file['path'])[1]
                                if ext in sub_exts:
                                    sub_file = file
                                    break

                        # check for single file torrents so we dont add unnecessary folders
                        if (os.path.dirname(main_file['path'])
                                is not ("" or "/")):
                            # check for top folder in user config
                            if (opts.get('content_filename')
                                    and os.path.dirname(
                                        opts['content_filename']) is not ""):
                                top_files_dir = os.path.dirname(
                                    opts['content_filename']) + "/"
                            else:
                                top_files_dir = os.path.dirname(
                                    main_file['path']) + "/"
                        else:
                            top_files_dir = "/"

                        if opts.get('content_filename'):
                            # rename the main file
                            big_file_name = (
                                top_files_dir +
                                os.path.basename(opts['content_filename']) +
                                os.path.splitext(main_file['path'])[1])
                            big_file_name = unused_name(big_file_name)
                            rename(main_file, big_file_name)

                            # rename subs along with the main file
                            if sub_file is not None and keep_subs:
                                sub_file_name = (
                                    os.path.splitext(big_file_name)[0] +
                                    os.path.splitext(sub_file['path'])[1])
                                rename(sub_file, sub_file_name)

                        if opts.get('main_file_only'):
                            # download only the main file (and subs)
                            file_priorities = [
                                1 if f == main_file or
                                (f == sub_file and keep_subs) else 0
                                for f in status['files']
                            ]
                            main_file_dlist.append(
                                client.core.set_torrent_file_priorities(
                                    torrent_id, file_priorities))

                            if opts.get('hide_sparse_files'):
                                # hide the other sparse files that are not supposed to download but are created anyway
                                # http://dev.deluge-torrent.org/ticket/1827
                                # Made sparse files behave better with deluge http://flexget.com/ticket/2881
                                sparse_files = [
                                    f for f in status['files']
                                    if f != main_file and (
                                        f != sub_file or (not keep_subs))
                                ]
                                rename_pairs = [
                                    (f['index'],
                                     top_files_dir + ".sparse_files/" +
                                     os.path.basename(f['path']))
                                    for f in sparse_files
                                ]
                                main_file_dlist.append(
                                    client.core.rename_files(
                                        torrent_id, rename_pairs))
                    else:
                        log.warning(
                            'No files in "%s" are > %d%% of content size, no files renamed.'
                            % (entry['title'],
                               opts.get('main_file_ratio') * 100))

                return defer.DeferredList(main_file_dlist)

            status_keys = [
                'files', 'total_size', 'save_path', 'move_on_completed_path',
                'move_on_completed', 'progress'
            ]
            dlist.append(
                client.core.get_torrent_status(
                    torrent_id,
                    status_keys).addCallback(on_get_torrent_status))

            return defer.DeferredList(dlist)

        def on_fail(result, task, entry):
            """Gets called when daemon reports a failure adding the torrent."""
            log.info('%s was not added to deluge! %s' %
                     (entry['title'], result))
            entry.fail('Could not be added to deluge')

        # dlist is a list of deferreds that must complete before we exit
        dlist = []
        # loop through entries to get a list of labels to add
        labels = set([
            format_label(entry['label']) for entry in task.accepted
            if entry.get('label')
        ])
        if config.get('label'):
            labels.add(format_label(config['label']))
        label_deferred = defer.succeed(True)
        if labels:
            # Make sure the label plugin is available and enabled, then add appropriate labels

            def on_get_enabled_plugins(plugins):
                """Gets called with the list of enabled deluge plugins."""
                def on_label_enabled(result):
                    """ This runs when we verify the label plugin is enabled. """
                    def on_get_labels(d_labels):
                        """Gets available labels from deluge, and adds any new labels we need."""
                        dlist = []
                        for label in labels:
                            if label not in d_labels:
                                log.debug('Adding the label %s to deluge' %
                                          label)
                                dlist.append(client.label.add(label))
                        return defer.DeferredList(dlist)

                    return client.label.get_labels().addCallback(on_get_labels)

                if 'Label' in plugins:
                    return on_label_enabled(True)
                else:
                    # Label plugin isn't enabled, so we check if it's available and enable it.

                    def on_get_available_plugins(plugins):
                        """Gets plugins available to deluge, enables Label plugin if available."""
                        if 'Label' in plugins:
                            log.debug('Enabling label plugin in deluge')
                            return client.core.enable_plugin(
                                'Label').addCallback(on_label_enabled)
                        else:
                            log.error(
                                'Label plugin is not installed in deluge')

                    return client.core.get_available_plugins().addCallback(
                        on_get_available_plugins)

            label_deferred = client.core.get_enabled_plugins().addCallback(
                on_get_enabled_plugins)
            dlist.append(label_deferred)

        def on_get_daemon_info(ver):
            """Gets called with the daemon version info, stores it in self."""
            log.debug('deluge version %s' % ver)
            self.deluge_version = ver

        version_deferred = client.daemon.info().addCallback(on_get_daemon_info)
        dlist.append(version_deferred)

        def on_get_session_state(torrent_ids):
            """Gets called with a list of torrent_ids loaded in the deluge session.
            Adds new torrents and modifies the settings for ones already in the session."""
            dlist = []
            # add the torrents
            for entry in task.accepted:

                @defer.inlineCallbacks
                def _wait_for_metadata(torrent_id, timeout):
                    log.verbose('Waiting %d seconds for "%s" to magnetize' %
                                (timeout, entry['title']))
                    for _ in range(timeout):
                        time.sleep(1)
                        try:
                            status = yield client.core.get_torrent_status(
                                torrent_id, ['files'])
                        except Exception as err:
                            log.error('wait_for_metadata Error: %s' % err)
                            break
                        if len(status['files']) > 0:
                            log.info('"%s" magnetization successful' %
                                     (entry['title']))
                            break
                    else:
                        log.warning(
                            '"%s" did not magnetize before the timeout elapsed, '
                            'file list unavailable for processing.' %
                            entry['title'])

                    defer.returnValue(torrent_id)

                def add_entry(entry, opts):
                    """Adds an entry to the deluge session"""
                    magnet, filedump = None, None
                    if entry.get('url', '').startswith('magnet:'):
                        magnet = entry['url']
                    else:
                        if not os.path.exists(entry['file']):
                            entry.fail(
                                'Downloaded temp file \'%s\' doesn\'t exist!' %
                                entry['file'])
                            del (entry['file'])
                            return
                        with open(entry['file'], 'rb') as f:
                            filedump = base64.encodestring(f.read())

                    log.verbose('Adding %s to deluge.' % entry['title'])
                    if magnet:
                        d = client.core.add_torrent_magnet(magnet, opts)
                        if config.get('magnetization_timeout'):
                            d.addCallback(_wait_for_metadata,
                                          config['magnetization_timeout'])
                        return d
                    else:
                        return client.core.add_torrent_file(
                            entry['title'], filedump, opts)

                # Generate deluge options dict for torrent add
                add_opts = {}
                try:
                    path = entry.render(entry.get('path', config['path']))
                    if path:
                        add_opts['download_location'] = pathscrub(
                            os.path.expanduser(path))
                except RenderError as e:
                    log.error('Could not set path for %s: %s' %
                              (entry['title'], e))
                for fopt, dopt in self.options.items():
                    value = entry.get(fopt, config.get(fopt))
                    if value is not None:
                        add_opts[dopt] = value
                        if fopt == 'ratio':
                            add_opts['stop_at_ratio'] = True
                # Make another set of options, that get set after the torrent has been added
                modify_opts = {
                    'label':
                    format_label(entry.get('label', config['label'])),
                    'queuetotop':
                    entry.get('queuetotop', config.get('queuetotop')),
                    'main_file_only':
                    entry.get('main_file_only',
                              config.get('main_file_only', False)),
                    'main_file_ratio':
                    entry.get('main_file_ratio',
                              config.get('main_file_ratio')),
                    'hide_sparse_files':
                    entry.get('hide_sparse_files',
                              config.get('hide_sparse_files', True)),
                    'keep_subs':
                    entry.get('keep_subs', config.get('keep_subs', True))
                }
                try:
                    movedone = entry.render(
                        entry.get('movedone', config['movedone']))
                    modify_opts['movedone'] = pathscrub(
                        os.path.expanduser(movedone))
                except RenderError as e:
                    log.error('Error setting movedone for %s: %s' %
                              (entry['title'], e))
                try:
                    content_filename = entry.get(
                        'content_filename', config.get('content_filename', ''))
                    modify_opts['content_filename'] = pathscrub(
                        entry.render(content_filename))
                except RenderError as e:
                    log.error('Error setting content_filename for %s: %s' %
                              (entry['title'], e))

                torrent_id = entry.get('deluge_id') or entry.get(
                    'torrent_info_hash')
                torrent_id = torrent_id and torrent_id.lower()
                if torrent_id in torrent_ids:
                    log.info(
                        '%s is already loaded in deluge, setting options' %
                        entry['title'])
                    # Entry has a deluge id, verify the torrent is still in the deluge session and apply options
                    # Since this is already loaded in deluge, we may also need to change the path
                    modify_opts['path'] = add_opts.pop('download_location',
                                                       None)
                    dlist.extend([
                        set_torrent_options(torrent_id, entry, modify_opts),
                        client.core.set_torrent_options([torrent_id], add_opts)
                    ])
                else:
                    dlist.append(
                        add_entry(entry, add_opts).addCallbacks(
                            set_torrent_options,
                            on_fail,
                            callbackArgs=(entry, modify_opts),
                            errbackArgs=(task, entry)))
            return defer.DeferredList(dlist)

        dlist.append(
            client.core.get_session_state().addCallback(on_get_session_state))

        def on_complete(result):
            """Gets called when all of our tasks for deluge daemon are complete."""
            client.disconnect()

        tasks = defer.DeferredList(dlist).addBoth(on_complete)

        def on_timeout(result):
            """Gets called if tasks have not completed in 30 seconds.
            Should only happen when something goes wrong."""
            log.error('Timed out while adding torrents to deluge.')
            log.debug('dlist: %s' % result.resultList)
            client.disconnect()

        # Schedule a disconnect to happen if FlexGet hangs while connected to Deluge
        # Leave the timeout long, to give time for possible lookups to occur
        reactor.callLater(600, lambda: tasks.called or on_timeout(tasks))