class OutputDeluge(DelugePlugin): """Add the torrents directly to deluge, supporting custom save paths.""" def validator(self): from flexget import validator root = validator.factory() root.accept('boolean') deluge = root.accept('dict') self.validate_connection_info(deluge) deluge.accept('path', key='path', allow_replacement=True) deluge.accept('path', key='movedone', allow_replacement=True) deluge.accept('text', key='label') deluge.accept('boolean', key='queuetotop') deluge.accept('boolean', key='automanaged') deluge.accept('number', key='maxupspeed') deluge.accept('number', key='maxdownspeed') deluge.accept('integer', key='maxconnections') deluge.accept('integer', key='maxupslots') deluge.accept('number', key='ratio') deluge.accept('boolean', key='removeatratio') deluge.accept('boolean', key='addpaused') deluge.accept('boolean', key='compact') deluge.accept('text', key='content_filename') deluge.accept('boolean', key='main_file_only') deluge.accept('boolean', key='enabled') return root def prepare_config(self, config): if isinstance(config, bool): config = {'enabled': config} self.prepare_connection_info(config) config.setdefault('enabled', True) config.setdefault('path', '') config.setdefault('movedone', '') config.setdefault('label', '') return config def __init__(self): self.deluge12 = None self.deluge_version = None self.options = { 'maxupspeed': 'max_upload_speed', 'maxdownspeed': 'max_download_speed', 'maxconnections': 'max_connections', 'maxupslots': 'max_upload_slots', 'automanaged': 'auto_managed', 'ratio': 'stop_ratio', 'removeatratio': 'remove_at_ratio', 'addpaused': 'add_paused', 'compact': 'compact_allocation' } @priority(120) def on_process_start(self, task, config): """ Detect what version of deluge is loaded. """ if self.deluge12 is None: logger = log.info if task.manager.options.test else log.debug try: log.debug('Looking for deluge 1.1 API') from deluge.ui.client import sclient log.debug('1.1 API found') except ImportError: log.debug('Looking for deluge 1.2 API') DelugePlugin.on_process_start(self, task, config) logger('Using deluge 1.2 api') self.deluge12 = True else: logger('Using deluge 1.1 api') self.deluge12 = False @priority(120) def on_task_download(self, task, config): """ Call download plugin to generate the temp files we will load into deluge then verify they are valid torrents """ import deluge.ui.common config = self.prepare_config(config) if not config['enabled']: return # If the download plugin is not enabled, we need to call it to get our temp .torrent files if not 'download' in task.config: download = get_plugin_by_name('download') for entry in task.accepted: if not entry.get('deluge_id'): download.instance.get_temp_file(task, entry, handle_magnets=True) # Check torrent files are valid for entry in task.accepted: if os.path.exists(entry.get('file', '')): # Check if downloaded file is a valid torrent file try: deluge.ui.common.TorrentInfo(entry['file']) except Exception: task.fail(entry, 'Invalid torrent file') log.error('Torrent file appears invalid for: %s', entry['title']) @priority(135) def on_task_output(self, task, config): """Add torrents to deluge at exit.""" config = self.prepare_config(config) # don't add when learning if task.manager.options.learn: return if not config['enabled'] or not (task.accepted or task.manager.options.test): return add_to_deluge = self.connect if self.deluge12 else self.add_to_deluge11 add_to_deluge(task, config) # Clean up temp file if download plugin is not configured for this task if not 'download' in task.config: for entry in task.accepted + task.failed: if os.path.exists(entry.get('file', '')): os.remove(entry['file']) del (entry['file']) def add_to_deluge11(self, task, config): """Add torrents to deluge using deluge 1.1.x api.""" try: from deluge.ui.client import sclient except: raise PluginError('Deluge module required', log) sclient.set_core_uri() for entry in task.accepted: try: before = sclient.get_session_state() except Exception, (errno, msg): raise PluginError( 'Could not communicate with deluge core. %s' % msg, log) if task.manager.options.test: return opts = {} path = entry.get('path', config['path']) if path: try: opts['download_location'] = os.path.expanduser( entry.render(path)) except RenderError, 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: opts[dopt] = value if fopt == 'ratio': opts['stop_at_ratio'] = True # check that file is downloaded if not 'file' in entry: task.fail(entry, 'file missing?') continue # see that temp file is present if not os.path.exists(entry['file']): tmp_path = os.path.join(task.manager.config_base, 'temp') log.debug('entry: %s' % entry) log.debug('temp: %s' % ', '.join(os.listdir(tmp_path))) task.fail( entry, 'Downloaded temp file \'%s\' doesn\'t exist!?' % entry['file']) continue sclient.add_torrent_file([entry['file']], [opts]) log.info('%s torrent added to deluge with options %s' % (entry['title'], opts)) movedone = entry.get('movedone', config['movedone']) label = entry.get('label', config['label']).lower() queuetotop = entry.get('queuetotop', config.get('queuetotop')) # Sometimes deluge takes a moment to add the torrent, wait a second. time.sleep(2) after = sclient.get_session_state() for item in after: # find torrentid of just added torrent if not item in before: try: movedone = entry.render(movedone) except RenderError, e: log.error('Could not set movedone for %s: %s' % (entry['title'], e)) movedone = '' if movedone: movedone = os.path.expanduser(movedone) if not os.path.isdir(movedone): log.debug( 'movedone path %s doesn\'t exist, creating' % movedone) os.makedirs(movedone) log.debug('%s move on complete set to %s' % (entry['title'], movedone)) sclient.set_torrent_move_on_completed(item, True) sclient.set_torrent_move_on_completed_path( item, movedone) if label: if not 'label' in sclient.get_enabled_plugins(): sclient.enable_plugin('label') if not label in sclient.label_get_labels(): sclient.label_add(label) log.debug('%s label set to \'%s\'' % (entry['title'], label)) sclient.label_set_torrent(item, label) if queuetotop: log.debug('%s moved to top of queue' % entry['title']) sclient.queue_top([item]) break
def add_to_deluge11(self, task, config): """Add torrents to deluge using deluge 1.1.x api.""" try: from deluge.ui.client import sclient except: raise PluginError('Deluge module required', log) sclient.set_core_uri() for entry in task.accepted: try: before = sclient.get_session_state() except Exception, (errno, msg): raise PluginError('Could not communicate with deluge core. %s' % msg, log) if task.manager.options.test: return opts = {} path = entry.get('path', config['path']) if path: try: opts['download_location'] = os.path.expanduser(entry.render(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: opts[dopt] = value if fopt == 'ratio': opts['stop_at_ratio'] = True # check that file is downloaded if not 'file' in entry: entry.fail('file missing?') continue # see that temp file is present if not os.path.exists(entry['file']): tmp_path = os.path.join(task.manager.config_base, 'temp') log.debug('entry: %s' % entry) log.debug('temp: %s' % ', '.join(os.listdir(tmp_path))) entry.fail('Downloaded temp file \'%s\' doesn\'t exist!?' % entry['file']) continue sclient.add_torrent_file([entry['file']], [opts]) log.info('%s torrent added to deluge with options %s' % (entry['title'], opts)) movedone = entry.get('movedone', config['movedone']) label = entry.get('label', config['label']).lower() queuetotop = entry.get('queuetotop', config.get('queuetotop')) # Sometimes deluge takes a moment to add the torrent, wait a second. time.sleep(2) after = sclient.get_session_state() for item in after: # find torrentid of just added torrent if not item in before: try: movedone = entry.render(movedone) except RenderError as e: log.error('Could not set movedone for %s: %s' % (entry['title'], e)) movedone = '' if movedone: movedone = os.path.expanduser(movedone) if not os.path.isdir(movedone): log.debug('movedone path %s doesn\'t exist, creating' % movedone) os.makedirs(movedone) log.debug('%s move on complete set to %s' % (entry['title'], movedone)) sclient.set_torrent_move_on_completed(item, True) sclient.set_torrent_move_on_completed_path(item, movedone) if label: if not 'label' in sclient.get_enabled_plugins(): sclient.enable_plugin('label') if not label in sclient.label_get_labels(): sclient.label_add(label) log.debug('%s label set to \'%s\'' % (entry['title'], label)) sclient.label_set_torrent(item, label) if queuetotop: log.debug('%s moved to top of queue' % entry['title']) sclient.queue_top([item]) break else: log.info('%s is already loaded in deluge. Cannot change label, movedone, or queuetotop' % entry['title'])
def add_to_deluge11(self, task, config): """Add torrents to deluge using deluge 1.1.x api.""" try: from deluge.ui.client import sclient except: raise plugin.PluginError('Deluge module required', log) sclient.set_core_uri() for entry in task.accepted: try: before = sclient.get_session_state() except Exception as e: (errno, msg) = e.args raise plugin.PluginError('Could not communicate with deluge core. %s' % msg, log) if task.options.test: return opts = {} path = entry.get('path', config['path']) if path: try: opts['download_location'] = os.path.expanduser(entry.render(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: opts[dopt] = value if fopt == 'ratio': opts['stop_at_ratio'] = True # check that file is downloaded if not 'file' in entry: entry.fail('file missing?') continue # see that temp file is present if not os.path.exists(entry['file']): tmp_path = os.path.join(task.manager.config_base, 'temp') log.debug('entry: %s' % entry) log.debug('temp: %s' % ', '.join(os.listdir(tmp_path))) entry.fail('Downloaded temp file \'%s\' doesn\'t exist!?' % entry['file']) continue sclient.add_torrent_file([entry['file']], [opts]) log.info('%s torrent added to deluge with options %s' % (entry['title'], opts)) movedone = entry.get('movedone', config['movedone']) label = entry.get('label', config['label']).lower() queuetotop = entry.get('queuetotop', config.get('queuetotop')) # Sometimes deluge takes a moment to add the torrent, wait a second. time.sleep(2) after = sclient.get_session_state() for item in after: # find torrentid of just added torrent if not item in before: try: movedone = entry.render(movedone) except RenderError as e: log.error('Could not set movedone for %s: %s' % (entry['title'], e)) movedone = '' if movedone: movedone = os.path.expanduser(movedone) if not os.path.isdir(movedone): log.debug('movedone path %s doesn\'t exist, creating' % movedone) os.makedirs(movedone) log.debug('%s move on complete set to %s' % (entry['title'], movedone)) sclient.set_torrent_move_on_completed(item, True) sclient.set_torrent_move_on_completed_path(item, movedone) if label: if not 'label' in sclient.get_enabled_plugins(): sclient.enable_plugin('label') if not label in sclient.label_get_labels(): sclient.label_add(label) log.debug('%s label set to \'%s\'' % (entry['title'], label)) sclient.label_set_torrent(item, label) if queuetotop: log.debug('%s moved to top of queue' % entry['title']) sclient.queue_top([item]) break else: log.info('%s is already loaded in deluge. Cannot change label, movedone, or queuetotop' % entry['title'])