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__":