diff --git a/glade/dgtkpref.glade b/glade/dgtkpref.glade index 7a804ae21..6ce72d743 100644 --- a/glade/dgtkpref.glade +++ b/glade/dgtkpref.glade @@ -656,6 +656,7 @@ their share ratio reaches: True gtk-preferences True + diff --git a/plugins/ExamplePlugin/plugin.py b/plugins/ExamplePlugin/plugin.py index 980d13315..2eb8b7831 100644 --- a/plugins/ExamplePlugin/plugin.py +++ b/plugins/ExamplePlugin/plugin.py @@ -1,7 +1,8 @@ #!/usr/bin/python class plugin_Example: - def __init__(self, deluge_core, deluge_interface): + def __init__(self, path, deluge_core, deluge_interface): + self.path = path self.core = deluge_core self.interface = deluge_interface print "Example Plugin loaded" diff --git a/plugins/TorrentSearch/plugin.py b/plugins/TorrentSearch/plugin.py new file mode 100644 index 000000000..53c76c78d --- /dev/null +++ b/plugins/TorrentSearch/plugin.py @@ -0,0 +1,166 @@ +#!/usr/bin/python + +class plugin_Search: + def __init__(self, path, deluge_core, deluge_interface): + import dcommon, gtk, gtk.glade, dgtk + self.core = deluge_core + self.interface = deluge_interface + self.conf_file = dcommon.CONFIG_DIR + "/search.conf" + if not os.path.isfile(self.conf_file): + f = open(self.conf_file, mode='w') + f.flush() + f.close() + glade = gtk.glade.XML(path + "/searchdlg.glade") + self.dlg = glade.get_widget("search_dialog") + self.dlg.set_icon_from_file(dcommon.get_pixmap("deluge32.png")) + self.view = glade.get_widget("search_view") + model = gtk.ListStore(str, str) + self.view.set_model(model) + dgtk.add_text_column(self.view, "Name", 0) + dgtk.add_text_column(self.view, "Search String", 1) + self.field_name = glade.get_widget("field_name") + self.field_search = glade.get_widget("field_search") + self.button_add = glade.get_widget("button_addsearch") + self.button_del = glade.get_widget("button_delsearch") + dic = { "add_clicked" : self.add_clicked, + "del_clicked" : self.del_clicked, + "row_clicked" : self.row_clicked, + "text_changed" : self.text_changed } + glade.signal_autoconnect(dic) + self.view.get_selection().set_select_function(self.row_clicked) + + + ### Note: All other plugins should use self.interface.toolbar + ### when adding items to the toolbar + self.se = '' + self.toolbar = self.interface.wtree.get_widget("tb_right") + self.engines = dcommon.DelugePreferences() + self.engines.load_from_file(self.conf_file) + self.search_entry = gtk.Entry() + self.search_item = gtk.ToolItem() + self.search_item.add(self.search_entry) + self.search_icon = gtk.Image() + self.search_icon.set_from_stock(gtk.STOCK_FIND, gtk.ICON_SIZE_MENU) + self.menu_button = gtk.MenuToolButton(self.search_icon, "Choose an Engine") + self.menu_button.set_is_important(True) + self.menu_button.connect("clicked", self.torrent_search) + self.menu = gtk.Menu() + self.manage_item = gtk.ImageMenuItem("Manage Engines") + self.image = gtk.Image() + self.image.set_from_stock(gtk.STOCK_PREFERENCES, gtk.ICON_SIZE_MENU) + self.manage_item.set_image(self.image) + self.manage_item.connect("activate", self.configure) + self.menu.add(self.manage_item) + self.menu_button.set_menu(self.menu) + self.toolbar.insert(self.search_item, -1) + self.toolbar.insert(self.menu_button, -1) + self.populate_search_menu() + self.toolbar.show_all() + self.search_item.show_all() + self.menu_button.show_all() + self.menu.show_all() + print "Torrent Search Initialized" + + def unload(self): + self.engines.save_to_file(self.conf_file) + self.toolbar.remove(self.search_item) + self.toolbar.remove(self.menu_button) + + def text_changed(self, args): + a = (self.field_name.get_text() != "") + b = (self.field_search.get_text() != "") + if(a and b): + self.button_add.set_sensitive(1) + else: + self.button_add.set_sensitive(0) + + def add_clicked(self, args): + self.view.get_model().append([self.field_name.get_text(), + self.field_search.get_text()]) + self.field_name.set_text("") + self.field_search.set_text("") + + def del_clicked(self, args): + (model, selection) = self.view.get_selection().get_selected() + model.remove(selection) + self.button_del.set_sensitive(0) + + def row_clicked(self, args): + self.button_del.set_sensitive(1) + return True + + def configure(self, widget=None): + import dcommon, gtk, gtk.glade + + self.dlg.show_all() + model = self.view.get_model() + model.clear + for name in self.engines.keys(): + self.view.get_model().append( (name, self.engines.get(name)) ) + self.button_add.set_sensitive(0) + self.button_del.set_sensitive(0) + result = self.dlg.run() + self.dlg.hide_all() + if result == 1: + self.engines.clear() + the_iter = model.get_iter_first() + while the_iter is not None: + self.engines.set(model.get_value(the_iter, 0), model.get_value(the_iter, 1)) + the_iter = model.iter_next(the_iter) + else: + pass + + + + def update(self): + pass + + def torrent_search(self, widget=None): + print "Searching with engine", self.se + url = self.engines.get(self.se) + entry = self.search_entry.get_text() + print 'URL =', url + print 'Entry =', entry + entry = entry.replace(' ', '+') + print 'URL =', url + print 'Entry =', entry + url = url.replace('${query}', entry) + print 'URL =', url + print 'Entry =', entry + + def populate_search_menu(self): + import gtk + self.menu_button.set_label("Choose an Engine") + for child in self.menu.get_children(): + self.menu.remove(child) + group = None + i = 0 + for engine in self.engines.keys(): + rmi = gtk.RadioMenuItem(None, engine) + rmi.eng_name = engine + rmi.connect("activate", self.select_search, rmi.eng_name) + if (group != None): + rmi.set_group(group) + else: + group = rmi + rmi.set_active(1) + self.menu.insert(rmi, i) + i = i + 1 + rmi.show() + self.menu.insert(self.manage_item, i) + self.menu.show() + + def select_search(self, menuitem, engine_string): + self.menu_button.set_label("Search " + engine_string) + self.se = engine_string + + +register_plugin("Torrent Search", + plugin_Search, + "0.5", + "A searchbar for torrent search engines", + config=True, + default=False, + requires="0.5.0", + interface="gtk", + required_plugins=None) diff --git a/plugins/TorrentSearch/searchdlg.glade b/plugins/TorrentSearch/searchdlg.glade new file mode 100644 index 000000000..9d12ff8e4 --- /dev/null +++ b/plugins/TorrentSearch/searchdlg.glade @@ -0,0 +1,183 @@ + + + + + + 5 + Manage Search Plugins + False + + + True + GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK | GDK_ENTER_NOTIFY_MASK + 2 + + + True + 4 + 4 + + + True + True + + + True + Add a new search engine by entering a Name and a URL. For Name, enter the name of the search engine to be used. For URL, enter the url of the seach page. The user's search query will replace any instance of ${query} in the URL. +For example, a Google search would be: +Name: Google +URL: http://www.google.com/search?q=${query} + True + + + + + True + Help + + + label_item + + + + + 4 + 3 + 4 + + + + + True + gtk-remove + True + + + + 3 + 4 + 1 + 2 + GTK_FILL + GTK_FILL + + + + + True + URL: + + + 2 + 3 + GTK_FILL + GTK_FILL + + + + + True + Name: + + + 1 + 2 + GTK_FILL + GTK_FILL + + + + + True + + + + 1 + 4 + 2 + 3 + GTK_FILL + + + + + True + + + + 1 + 2 + 1 + 2 + GTK_FILL + + + + + True + GTK_POLICY_AUTOMATIC + + + True + + + + + 4 + + + + + True + gtk-add + True + + + + + 2 + 3 + 1 + 2 + GTK_FILL + GTK_FILL + + + + + 1 + + + + + True + GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK | GDK_ENTER_NOTIFY_MASK + GTK_BUTTONBOX_END + + + True + gtk-cancel + True + + + + + True + gtk-ok + True + 1 + + + 1 + + + + + False + GTK_PACK_END + + + + + + diff --git a/src/dcommon.py b/src/dcommon.py index 8bbb78d10..dde02228c 100644 --- a/src/dcommon.py +++ b/src/dcommon.py @@ -65,11 +65,14 @@ class DelugePreferences: def keys(self): return self.pref.keys() + def clear(self): + self.pref.clear() + def load_from_file(self, filename): f = open(filename, mode='r') for line in f: try: - (key, value) = line.split("=") + (key, value) = line.split("=", 1) key = key.strip(" \n") value = value.strip(" \n") self.pref[key] = value diff --git a/src/delugegtk.py b/src/delugegtk.py index fe6a734dc..0f78ed77f 100755 --- a/src/delugegtk.py +++ b/src/delugegtk.py @@ -189,7 +189,23 @@ class DelugeGTK(dbus.service.Object): self.plugin_view.set_model(self.plugin_store) dgtk.add_text_column(self.plugin_view, "Name", 0) dgtk.add_toggle_column(self.plugin_view, "Enabled", 1, toggled_signal=self.plugin_toggled) - + self.prf_glade.signal_autoconnect({'plugin_pref': self.plugin_pref}) + + def plugin_toggled(self, renderer, path): + plugin_iter = self.plugin_store.get_iter_from_string(path) + plugin_name = self.plugin_store.get_value(plugin_iter, 0) + plugin_value = not self.plugin_store.get_value(plugin_iter, 1) + self.plugin_store.set_value(plugin_iter, 1, plugin_value) + if plugin_value: + self.plugins.enable_plugin(plugin_name) + else: + self.plugins.disable_plugin(plugin_name) + + def plugin_pref(self, widget=None): + print "foobar" + (model, plugin_iter) = self.plugin_view.get_selection().get_selected() + plugin_name = self.plugin_store.get_value(plugin_iter, 0) + self.plugins.configure_plugin(plugin_name) def build_torrent_table(self): ## Create the torrent listview @@ -337,21 +353,15 @@ class DelugeGTK(dbus.service.Object): def show_plugin_dialog(self, arg=None): self.plugin_store.clear() for plugin in self.plugins.get_available_plugins(): - self.plugin_store.append( (plugin, False) ) + if plugin in self.plugins.get_enabled_plugins(): + self.plugin_store.append( (plugin, True) ) + else: + self.plugin_store.append( (plugin, False) ) self.plugin_dlg.show() self.plugin_dlg.run() self.plugin_dlg.hide() - def plugin_toggled(self, renderer, path): - plugin_iter = self.plugin_store.get_iter_from_string(path) - plugin_name = self.plugin_store.get_value(plugin_iter, 0) - plugin_value = not self.plugin_store.get_value(plugin_iter, 1) - self.plugin_store.set_value(plugin_iter, 1, plugin_value) - print "Plugin:", plugin_name, renderer.get_active() - if plugin_value: - self.plugins.enable_plugin(plugin_name) - else: - self.plugins.disable_plugin(plugin_name) + diff --git a/src/delugeplugins.py b/src/delugeplugins.py index 911659ec8..0362921c2 100644 --- a/src/delugeplugins.py +++ b/src/delugeplugins.py @@ -39,6 +39,7 @@ class PluginManager: plugin_folders = os.listdir(folder) for plugin in plugin_folders: if os.path.isfile(folder + "/" + plugin + "/plugin.py"): + self.path = folder + "/" + plugin execfile(folder + "/" + plugin + "/plugin.py") def get_available_plugins(self): @@ -48,7 +49,8 @@ class PluginManager: return self.available_plugins[name] def enable_plugin(self, name): - self.enabled_plugins[name] = self.available_plugins[name]['class'](self.core, self.interface) + self.enabled_plugins[name] = self.available_plugins[name]['class']( + self.available_plugins[name]['path'], self.core, self.interface) def get_enabled_plugins(self): return self.enabled_plugins.keys() @@ -56,6 +58,10 @@ class PluginManager: def disable_plugin(self, name): self.enabled_plugins[name].unload() self.enabled_plugins.pop(name) + + def configure_plugin(self, name): + print "configuring", name + self.enabled_plugins[name].configure() def update_active_plugins(self): for name in self.enabled_plugins.keys(): @@ -78,8 +84,8 @@ class PluginManager: 'default': default, 'requires': requires, 'interface': interface, - 'req plugins': required_plugins - } + 'req plugins': required_plugins, + 'path': self.path} ## Few lines of code to test functionality if __name__ == "__main__":