diff --git a/deluge/plugins/autoadd/autoadd/core.py b/deluge/plugins/autoadd/autoadd/core.py index 259ca9042..af5bc279c 100644 --- a/deluge/plugins/autoadd/autoadd/core.py +++ b/deluge/plugins/autoadd/autoadd/core.py @@ -44,6 +44,7 @@ from deluge.log import getPluginLogger from deluge.plugins.pluginbase import CorePluginBase import deluge.component as component import deluge.configmanager +from deluge.common import AUTH_LEVEL_ADMIN from deluge.core.rpcserver import export from twisted.internet.task import LoopingCall, deferLater from twisted.internet import reactor @@ -61,6 +62,7 @@ OPTIONS_AVAILABLE = { #option: builtin "path":False, "append_extension":False, "copy_torrent": False, + "delete_copy_torrent_toggle": False, "abspath":False, "download_location":True, "max_download_speed":True, @@ -100,6 +102,10 @@ class Core(CorePluginBase): self.config.save() self.watchdirs = self.config["watchdirs"] + component.get("EventManager").register_event_handler( + "PreTorrentRemovedEvent", self.__on_pre_torrent_removed + ) + # Dict of Filename:Attempts self.invalid_torrents = {} # Loopingcall timers for each enabled watchdir @@ -107,13 +113,16 @@ class Core(CorePluginBase): deferLater(reactor, 5, self.enable_looping) def enable_looping(self): - #Enable all looping calls for enabled watchdirs here + # Enable all looping calls for enabled watchdirs here for watchdir_id, watchdir in self.watchdirs.iteritems(): if watchdir['enabled']: self.enable_watchdir(watchdir_id) def disable(self): #disable all running looping calls + component.get("EventManager").deregister_event_handler( + "PreTorrentRemovedEvent", self.__on_pre_torrent_removed + ) for loopingcall in self.update_timers.itervalues(): loopingcall.stop() self.config.save() @@ -165,16 +174,19 @@ class Core(CorePluginBase): raise e # Get the info to see if any exceptions are raised - info = lt.torrent_info(lt.bdecode(filedump)) + lt.torrent_info(lt.bdecode(filedump)) return filedump def update_watchdir(self, watchdir_id): """Check the watch folder for new torrents to add.""" + log.trace("Updating watchdir id: %s", watchdir_id) watchdir_id = str(watchdir_id) watchdir = self.watchdirs[watchdir_id] if not watchdir['enabled']: # We shouldn't be updating because this watchdir is not enabled + log.debug("Watchdir id %s is not enabled. Disabling it.", + watchdir_id) self.disable_watchdir(watchdir_id) return @@ -193,15 +205,17 @@ class Core(CorePluginBase): if OPTIONS_AVAILABLE.get(option): if watchdir.get(option+'_toggle', True): opts[option] = value - for filename in os.listdir(watchdir["abspath"]): - if filename.split(".")[-1] == "torrent": - try: - filepath = os.path.join(watchdir["abspath"], filename) - except UnicodeDecodeError, e: - log.error("Unable to auto add torrent due to improper " - "filename encoding: %s", e) - continue + try: + filepath = os.path.join(watchdir["abspath"], filename) + except UnicodeDecodeError, e: + log.error("Unable to auto add torrent due to improper " + "filename encoding: %s", e) + continue + if os.path.isdir(filepath): + # Skip directories + continue + elif os.path.splitext(filename)[1] == ".torrent": try: filedump = self.load_torrent(filepath) except (RuntimeError, Exception), e: @@ -212,6 +226,9 @@ class Core(CorePluginBase): if filename in self.invalid_torrents: self.invalid_torrents[filename] += 1 if self.invalid_torrents[filename] >= MAX_NUM_ATTEMPTS: + log.warning("Maximum attepts reached while trying " + "to add the torrent file with the path" + " %s", filepath) os.rename(filepath, filepath + ".invalid") del self.invalid_torrents[filename] else: @@ -236,14 +253,19 @@ class Core(CorePluginBase): component.get("TorrentManager").queue_top(torrent_id) else: component.get("TorrentManager").queue_bottom(torrent_id) - # Rename or delete the torrent once added to deluge. + + # Rename, copy or delete the torrent once added to deluge. if watchdir.get('append_extension_toggle'): if not watchdir.get('append_extension'): watchdir['append_extension'] = ".added" os.rename(filepath, filepath + watchdir['append_extension']) elif watchdir.get('copy_torrent_toggle'): copy_torrent_path = watchdir['copy_torrent'] - os.rename(filepath, copy_torrent_path) + log.debug("Moving added torrent file \"%s\" to \"%s\"", + os.path.basename(filepath), copy_torrent_path) + os.rename( + filepath, os.path.join(copy_torrent_path, filename) + ) else: os.remove(filepath) @@ -298,7 +320,22 @@ class Core(CorePluginBase): @export def get_watchdirs(self): - return self.watchdirs.keys() + rpcserver = component.get("RPCServer") + session_user = rpcserver.get_session_user() + session_auth_level = rpcserver.get_session_auth_level() + if session_auth_level == AUTH_LEVEL_ADMIN: + log.debug("\n\nCurrent logged in user %s is an ADMIN, send all " + "watchdirs", session_user) + return self.watchdirs + + watchdirs = {} + for watchdir_id, watchdir in self.watchdirs.iteritems(): + if watchdir.get("owner", "localclient") == session_user: + watchdirs[watchdir_id] = watchdir + + log.debug("\n\nCurrent logged in user %s is not an ADMIN, send only " + "his watchdirs: %s", session_user, watchdirs.keys()) + return watchdirs def _make_unicode(self, options): opts = {} @@ -348,6 +385,30 @@ class Core(CorePluginBase): config['watchdirs'][watchdir_id]['owner'] = 'localclient' return config - ### XXX: Handle torrent finished / remove torrent file per whatchdir - ### deluge/core/torrentmanager.py: - ### filename = self.torrents[torrent_id].filename + def __on_pre_torrent_removed(self, torrent_id): + try: + torrent = component.get("TorrentManager")[torrent_id] + except KeyError: + log.warning("Unable to remove torrent file for torrent id %s. It" + "was already deleted from the TorrentManager", + torrent_id) + return + torrent_fname = torrent.filename + for watchdir in self.watchdirs.itervalues(): + if not watchdir.get('copy_torrent_toggle', False): + # This watchlist does copy torrents + continue + elif not watchdir.get('delete_copy_torrent_toggle', False): + # This watchlist is not set to delete finished torrents + continue + copy_torrent_path = watchdir['copy_torrent'] + torrent_fname_path = os.path.join(copy_torrent_path, torrent_fname) + if os.path.isfile(torrent_fname_path): + try: + os.remove(torrent_fname_path) + log.info("Removed torrent file \"%s\" from \"%s\"", + torrent_fname, copy_torrent_path) + break + except OSError, e: + log.info("Failed to removed torrent file \"%s\" from " + "\"%s\": %s", torrent_fname, copy_torrent_path, e) diff --git a/deluge/plugins/autoadd/autoadd/data/autoadd_options.glade b/deluge/plugins/autoadd/autoadd/data/autoadd_options.glade index 58545ebe8..8e69ba9a6 100644 --- a/deluge/plugins/autoadd/autoadd/data/autoadd_options.glade +++ b/deluge/plugins/autoadd/autoadd/data/autoadd_options.glade @@ -3,6 +3,7 @@ + False 6 AutoAdd Error False @@ -12,40 +13,11 @@ True - - - True - - - True - gtk-dialog-error - - - False - 0 - - - - - True - 0.46000000834465027 - Error - True - - - False - False - 1 - - - - - 2 - - + False True + False end @@ -55,6 +27,7 @@ True True False + False True @@ -67,14 +40,53 @@ False + True end 0 + + + True + False + + + True + False + gtk-dialog-error + + + False + True + 0 + + + + + True + False + 0.46000000834465027 + Error + True + + + False + False + 1 + + + + + True + True + 2 + + + False Watch Folder Properties False True @@ -83,9 +95,75 @@ True + False + + + True + False + end + + + gtk-cancel + True + True + True + False + False + True + + + + False + False + 0 + + + + + gtk-add + True + True + True + False + False + True + + + + False + False + 1 + + + + + gtk-apply + True + True + True + False + False + True + + + + False + False + 2 + + + + + False + True + end + 0 + + True + False True @@ -93,44 +171,60 @@ True + False 6 True + False 0 none True + False 12 True + False True + False True True + False + False + True + True + True + True 0 True + False select-folder Select A Folder + True + True 1 + True + True 0 @@ -140,6 +234,7 @@ True True False + False True True @@ -157,6 +252,7 @@ True + False <b>Watch Folder</b> True @@ -166,6 +262,7 @@ + True False 0 @@ -173,15 +270,18 @@ True + False 0 none True + False 12 True + False @@ -189,6 +289,7 @@ True + False <b>Owner</b> True @@ -198,51 +299,64 @@ + True + True 1 True + False 0 none True + False 12 True + False True + False Delete .torrent after adding True True False + False True + True + True 0 True + False Append extension after adding: True True False + False True isnt_append_extension + True + True 0 @@ -252,19 +366,28 @@ True .added + False + False + True + True + True + True 1 + True + True 1 True + False 2 2 @@ -273,6 +396,7 @@ True True False + False True isnt_append_extension @@ -281,23 +405,33 @@ True + False True True + False + False + True + True + True + True 0 True + False select-folder Select A Folder + True + True 1 @@ -316,6 +450,7 @@ True Delete the copy of the torrent file created when the torrent is removed + False True @@ -327,6 +462,8 @@ created when the torrent is removed + True + True 2 @@ -339,6 +476,7 @@ created when the torrent is removed True + False <b>Torrent File Action</b> True @@ -348,27 +486,33 @@ created when the torrent is removed + True + True 2 True + False 0 none True + False 12 True + False Set download location True True False + False True True @@ -382,28 +526,39 @@ created when the torrent is removed True + False True True + False + False + True + True + True + True 0 True + False select-folder Select A Folder + True + True 1 + True False 1 @@ -415,6 +570,7 @@ created when the torrent is removed True + False <b>Download Location</b> True @@ -424,6 +580,7 @@ created when the torrent is removed + True False 3 @@ -431,21 +588,25 @@ created when the torrent is removed True + False 0 none True + False 12 True + False Set move completed location True True False + False True True @@ -459,23 +620,33 @@ created when the torrent is removed True + False True True + False + False + True + True + True + True 0 True + False select-folder Select A Folder + True + True 1 @@ -484,6 +655,7 @@ created when the torrent is removed False False False + False True True True @@ -496,6 +668,7 @@ created when the torrent is removed + True False 1 @@ -507,6 +680,7 @@ created when the torrent is removed True + False <b>Move Completed</b> True @@ -516,27 +690,32 @@ created when the torrent is removed + True False 4 + False 0 none True + False 12 True + False Label: True True False + False True True @@ -550,8 +729,20 @@ created when the torrent is removed True + False + + + False + False + False + True + True + + + True + True 1 @@ -562,6 +753,7 @@ created when the torrent is removed True + False <b>Label</b> True @@ -571,6 +763,8 @@ created when the torrent is removed + True + True 5 @@ -579,6 +773,7 @@ created when the torrent is removed True + False Main @@ -589,6 +784,7 @@ created when the torrent is removed True + False 6 @@ -596,24 +792,30 @@ created when the torrent is removed True + False 0 none True + False 12 True + False 3 4 3 + 2 + 4 Max Upload Speed: True True False + False True True @@ -631,6 +833,7 @@ created when the torrent is removed True True False + False True True @@ -648,6 +851,7 @@ created when the torrent is removed True True False + False True True @@ -663,6 +867,10 @@ created when the torrent is removed True True + False + False + True + True 0 -1 10000 1 10 0 1 1 @@ -677,6 +885,10 @@ created when the torrent is removed True True + False + False + True + True 0 -1 10000 1 10 0 1 1 @@ -693,6 +905,10 @@ created when the torrent is removed True True + False + False + True + True 0 -1 10000 1 10 0 1 @@ -708,6 +924,10 @@ created when the torrent is removed True True + False + False + True + True 0 -1 10000 1 10 0 1 @@ -722,6 +942,7 @@ created when the torrent is removed True + False 0 5 KiB/s @@ -736,6 +957,7 @@ created when the torrent is removed True + False 0 5 KiB/s @@ -755,6 +977,7 @@ created when the torrent is removed True True False + False True True @@ -777,6 +1000,7 @@ created when the torrent is removed True + False <b>Bandwidth</b> True @@ -786,32 +1010,41 @@ created when the torrent is removed + True + True 1 True + False 0 none True + False 12 True + False 5 4 + 2 + 4 True + False Stop seed at ratio: True True False + False True True @@ -827,6 +1060,7 @@ created when the torrent is removed True + False 0 0 12 @@ -836,6 +1070,7 @@ created when the torrent is removed True True False + False True True @@ -852,6 +1087,7 @@ created when the torrent is removed True True False + False True True @@ -868,6 +1104,7 @@ created when the torrent is removed False True False + False True True True @@ -886,6 +1123,7 @@ created when the torrent is removed False True False + False True True True @@ -904,6 +1142,10 @@ created when the torrent is removed True True + False + False + True + True 2 0 100 0.10000000149 10 0 1 1 @@ -919,6 +1161,7 @@ created when the torrent is removed True + False True @@ -926,10 +1169,13 @@ created when the torrent is removed True True False + False True True + True + True 0 @@ -939,10 +1185,13 @@ created when the torrent is removed True True False + False True auto_managed + True + True 1 @@ -961,6 +1210,7 @@ created when the torrent is removed False True False + False True True True @@ -980,6 +1230,7 @@ created when the torrent is removed True True False + False True @@ -987,6 +1238,7 @@ created when the torrent is removed True + False True @@ -994,10 +1246,13 @@ created when the torrent is removed True True False + False True True + True + True 0 @@ -1007,10 +1262,13 @@ created when the torrent is removed True True False + False True add_paused + True + True 1 @@ -1026,6 +1284,7 @@ created when the torrent is removed True True False + False True @@ -1037,6 +1296,7 @@ created when the torrent is removed True + False True @@ -1044,10 +1304,13 @@ created when the torrent is removed True True False + False True True + True + True 0 @@ -1057,10 +1320,13 @@ created when the torrent is removed True True False + False True queue_to_top + True + True 1 @@ -1103,6 +1369,7 @@ created when the torrent is removed True + False <b>Queue</b> True @@ -1112,6 +1379,8 @@ created when the torrent is removed + True + True 2 @@ -1123,6 +1392,7 @@ created when the torrent is removed True + False Options @@ -1133,81 +1403,29 @@ created when the torrent is removed + True + True 0 True + False + True + True 1 + True + True 2 - - - True - end - - - gtk-cancel - True - True - True - False - True - - - - False - False - 0 - - - - - gtk-add - True - True - True - False - True - - - - False - False - 1 - - - - - gtk-apply - True - True - True - False - True - - - - False - False - 2 - - - - - False - end - 0 - - diff --git a/deluge/plugins/autoadd/autoadd/gtkui.py b/deluge/plugins/autoadd/autoadd/gtkui.py index 8ee1aff98..18ce63f7b 100644 --- a/deluge/plugins/autoadd/autoadd/gtkui.py +++ b/deluge/plugins/autoadd/autoadd/gtkui.py @@ -88,10 +88,6 @@ class OptionsDialog(): self.watchdir_id = None self.load_options(options) - - # Not implemented feateures present in UI - self.glade.get_widget("delete_copy_torrent_toggle").hide() - self.dialog.run() def load_options(self, options): @@ -108,6 +104,9 @@ class OptionsDialog(): self.glade.get_widget('copy_torrent_toggle').set_active( options.get('copy_torrent_toggle', False) ) + self.glade.get_widget('delete_copy_torrent_toggle').set_active( + options.get('delete_copy_torrent_toggle', False) + ) self.accounts.clear() self.labels.clear() combobox = self.glade.get_widget('OwnerCombobox') @@ -162,6 +161,13 @@ class OptionsDialog(): selected_idx = idx self.glade.get_widget('OwnerCombobox').set_active(selected_idx) + def on_accounts_failure(failure): + log.debug("Failed to get accounts!!! %s", failure) + iter = self.accounts.append() + self.accounts.set_value(iter, 0, client.get_auth_user()) + self.glade.get_widget('OwnerCombobox').set_active(0) + self.glade.get_widget('OwnerCombobox').set_sensitive(False) + def on_labels(labels): log.debug("Got Labels: %s", labels) for label in labels: @@ -182,9 +188,15 @@ class OptionsDialog(): self.glade.get_widget('label_toggle').set_active(False) client.core.get_enabled_plugins().addCallback(on_get_enabled_plugins) - client.core.get_known_accounts().addCallback( - on_accounts, options.get('owner', 'localclient') - ).addErrback(on_failure) + if client.get_auth_level() == deluge.common.AUTH_LEVEL_ADMIN: + client.core.get_known_accounts().addCallback( + on_accounts, options.get('owner', 'localclient') + ).addErrback(on_accounts_failure) + else: + iter = self.accounts.append() + self.accounts.set_value(iter, 0, client.get_auth_user()) + self.glade.get_widget('OwnerCombobox').set_active(0) + self.glade.get_widget('OwnerCombobox').set_sensitive(False) def set_sensitive(self): maintoggles = ['download_location', 'append_extension', @@ -255,7 +267,9 @@ class OptionsDialog(): self.err_dialog.hide() def on_add(self, Event=None): - client.autoadd.add(self.generate_opts()).addCallbacks(self.on_added, self.on_error_show) + client.autoadd.add( + self.generate_opts() + ).addCallbacks(self.on_added, self.on_error_show) def on_cancel(self, Event=None): self.dialog.destroy() @@ -266,14 +280,20 @@ class OptionsDialog(): options['enabled'] = self.glade.get_widget('enabled').get_active() if client.is_localhost(): options['path'] = self.glade.get_widget('path_chooser').get_filename() - options['download_location'] = self.glade.get_widget('download_location_chooser').get_filename() - options['move_completed_path'] = self.glade.get_widget('move_completed_path_chooser').get_filename() - options['copy_torrent'] = self.glade.get_widget('copy_torrent_chooser').get_filename() + options['download_location'] = self.glade.get_widget( + 'download_location_chooser').get_filename() + options['move_completed_path'] = self.glade.get_widget( + 'move_completed_path_chooser').get_filename() + options['copy_torrent'] = self.glade.get_widget( + 'copy_torrent_chooser').get_filename() else: options['path'] = self.glade.get_widget('path_entry').get_text() - options['download_location'] = self.glade.get_widget('download_location_entry').get_text() - options['move_completed_path'] = self.glade.get_widget('move_completed_path_entry').get_text() - options['copy_torrent'] = self.glade.get_widget('copy_torrent_entry').get_text() + options['download_location'] = self.glade.get_widget( + 'download_location_entry').get_text() + options['move_completed_path'] = self.glade.get_widget( + 'move_completed_path_entry').get_text() + options['copy_torrent'] = self.glade.get_widget( + 'copy_torrent_entry').get_text() options['label'] = self.glade.get_widget('label').child.get_text().lower() options['append_extension'] = self.glade.get_widget('append_extension').get_text() @@ -281,7 +301,8 @@ class OptionsDialog(): self.glade.get_widget('OwnerCombobox').get_active()][0] for key in ['append_extension_toggle', 'download_location_toggle', - 'label_toggle', 'copy_torrent_toggle']: + 'label_toggle', 'copy_torrent_toggle', + 'delete_copy_torrent_toggle']: options[key] = self.glade.get_widget(key).get_active() for id in self.spin_ids: @@ -307,9 +328,15 @@ class GtkUI(GtkPluginBase): }) self.opts_dialog = OptionsDialog() - component.get("PluginManager").register_hook("on_apply_prefs", self.on_apply_prefs) - component.get("PluginManager").register_hook("on_show_prefs", self.on_show_prefs) - client.register_event_handler("AutoaddOptionsChangedEvent", self.on_options_changed_event) + component.get("PluginManager").register_hook( + "on_apply_prefs", self.on_apply_prefs + ) + component.get("PluginManager").register_hook( + "on_show_prefs", self.on_show_prefs + ) + client.register_event_handler( + "AutoaddOptionsChangedEvent", self.on_options_changed_event + ) self.watchdirs = {} @@ -330,14 +357,20 @@ class GtkUI(GtkPluginBase): self.create_columns(self.treeView) sw.add(self.treeView) sw.show_all() - component.get("Preferences").add_page("AutoAdd", self.glade.get_widget("prefs_box")) + component.get("Preferences").add_page( + "AutoAdd", self.glade.get_widget("prefs_box") + ) self.on_show_prefs() def disable(self): component.get("Preferences").remove_page("AutoAdd") - component.get("PluginManager").deregister_hook("on_apply_prefs", self.on_apply_prefs) - component.get("PluginManager").deregister_hook("on_show_prefs", self.on_show_prefs) + component.get("PluginManager").deregister_hook( + "on_apply_prefs", self.on_apply_prefs + ) + component.get("PluginManager").deregister_hook( + "on_show_prefs", self.on_show_prefs + ) def create_model(self): store = gtk.ListStore(str, bool, str, str) @@ -418,14 +451,14 @@ class GtkUI(GtkPluginBase): client.autoadd.set_options(watchdir_id, watchdir) def on_show_prefs(self): - client.autoadd.get_config().addCallback(self.cb_get_config) + client.autoadd.get_watchdirs().addCallback(self.cb_get_config) def on_options_changed_event(self): - client.autoadd.get_config().addCallback(self.cb_get_config) + client.autoadd.get_watchdirs().addCallback(self.cb_get_config) - def cb_get_config(self, config): + def cb_get_config(self, watchdirs): """callback for on show_prefs""" - self.watchdirs = config.get('watchdirs', {}) + self.watchdirs = watchdirs self.store.clear() for watchdir_id, watchdir in self.watchdirs.iteritems(): self.store.append([