diff --git a/plugins/BlocklistImport/__init__.py b/plugins/BlocklistImport/__init__.py
new file mode 100644
index 000000000..d754fbaf6
--- /dev/null
+++ b/plugins/BlocklistImport/__init__.py
@@ -0,0 +1,95 @@
+
+
+plugin_name = "Blocklist Importer"
+plugin_author = "Steve 'Tarka' Smith"
+plugin_version = "0.1"
+plugin_description = "Downloads and import PeerGuardian blocklists"
+
+def deluge_init(deluge_path):
+ global path
+ path = deluge_path
+
+def enable(core, interface):
+ global path
+ return BlocklistImport(path, core, interface)
+
+#################### The plugin itself ####################
+
+import urllib, deluge.common, deluge.pref
+from peerguardian import PGReader, PGException
+from ui import GTKConfig, GTKProgress
+
+class BlocklistImport:
+
+ def __init__(self, path, core, interface):
+ print "Loading blocklist plugin ..."
+ # Save the path, interface, and core so they can be used later
+ self.path = path
+ self.core = core
+ self.interface = interface
+ self.gtkconf = GTKConfig(self)
+ self.gtkprog = GTKProgress(self)
+
+ self.blockfile = deluge.common.CONFIG_DIR + "/blocklist.p2b.gzip"
+
+ conffile = deluge.common.CONFIG_DIR + "/blocklist.conf"
+ self.config = deluge.pref.Preferences(filename=conffile,
+ global_defaults=False)
+ self.config.load()
+
+ if not self.config.has_key('url'):
+ self.configure()
+ else:
+ self.loadlist(fetch=self.config.get('load_on_start'))
+
+
+ def _download_update(self, curr, chunksize, size):
+ incs = float(size) / float(chunksize)
+ self.gtkprog.download_prog(curr/incs)
+
+ def loadlist(self, fetch=False):
+ # FIXME
+ #self.gtkprog.start()
+
+ # Attempt initial import
+ # FIXME: Make async
+ if fetch:
+ print "Downloading blocklist..."
+ filename, headers = urllib.urlretrieve(self.config.get('url'),
+ filename=self.blockfile,
+ reporthook=self._download_update)
+ print "Done"
+
+ self.core.reset_ip_filter()
+ reader = PGReader(self.blockfile)
+
+ ips = reader.next()
+ while ips:
+ print "Blocking",ips
+ self.core.add_range_to_ip_filter(*ips)
+ ips = reader.next()
+
+ reader.close()
+
+ # FIXME
+ #self.gtkprog.stop()
+
+ def configure(self):
+ self.gtkconf.start()
+
+ def setconfig(self, url, load_on_start):
+ self.config.set('url', url)
+ self.config.set('load_on_start', load_on_start)
+ self.config.save()
+
+ self.loadlist(fetch=True)
+
+ def disable(self):
+ self.core.reset_ip_filter()
+
+ def unload(self):
+ #self.config.save_to_file(self.config_file)
+ self.core.reset_ip_filter()
+
+ def update(self):
+ pass
diff --git a/plugins/BlocklistImport/peerguardian.py b/plugins/BlocklistImport/peerguardian.py
new file mode 100644
index 000000000..98d2c70d1
--- /dev/null
+++ b/plugins/BlocklistImport/peerguardian.py
@@ -0,0 +1,55 @@
+
+from exceptions import Exception
+from struct import unpack
+import gzip, socket
+
+class PGException(Exception):
+ pass
+
+# Incrementally reads PeerGuardian blocklists v1 and v2.
+# See http://wiki.phoenixlabs.org/wiki/P2B_Format
+class PGReader:
+
+ def __init__(self, filename):
+ print "PGReader loading",filename
+
+ # FIXME: Catch and convert exception?
+ self.fd = gzip.open(filename, "rb")
+
+ # 4 bytes, should be 0xffffffff
+ buf = self.fd.read(4)
+ hdr = unpack("l", buf)[0]
+ if hdr != -1:
+ print "LEADER IS",hdr
+ raise PGException("Invalid leader %d"%hdr)
+
+ magic = self.fd.read(3)
+ if magic != "P2B":
+ raise PGException("Invalid magic code")
+
+ buf = self.fd.read(1)
+ ver = ord(buf)
+ if ver != 1 and ver != 2:
+ raise PGException("Invalid version %d" % ver)
+
+ def next(self):
+
+ # Skip over the string
+ buf = -1
+ while buf != 0:
+ buf = self.fd.read(1)
+ if buf == "": # EOF
+ return False
+ buf = ord(buf)
+
+ buf = self.fd.read(4)
+ start = socket.inet_ntoa(buf)
+
+ buf = self.fd.read(4)
+ end = socket.inet_ntoa(buf)
+
+ return (start, end)
+
+ def close(self):
+ self.fd.close()
+
diff --git a/plugins/BlocklistImport/ui.py b/plugins/BlocklistImport/ui.py
new file mode 100644
index 000000000..e9aecab49
--- /dev/null
+++ b/plugins/BlocklistImport/ui.py
@@ -0,0 +1,92 @@
+
+import gtk
+
+class GTKConfig(gtk.Dialog):
+ def __init__(self, plugin):
+ gtk.Dialog.__init__(self, title="Blocklist Config",
+ flags=gtk.DIALOG_MODAL,
+ buttons=(gtk.STOCK_CANCEL, gtk.RESPONSE_REJECT,
+ gtk.STOCK_OK, gtk.RESPONSE_ACCEPT))
+
+ # Setup
+ self.set_border_width(12)
+ self.vbox.set_spacing(6)
+
+ # List source
+ label = gtk.Label()
+ label.set_markup('Blocklist URL')
+ self.url = gtk.Entry()
+ self.listtype = gtk.combo_box_new_text()
+ self.listtype.append_text("PeerGuardian (GZip)")
+ self.listtype.set_active(0)
+
+ hbox = gtk.HBox(False, 6)
+ hbox.pack_start(label)
+ hbox.pack_start(self.url)
+ hbox.pack_start(self.listtype)
+
+ self.vbox.pack_start(hbox)
+
+ # Load on start
+ self.load_on_start = gtk.CheckButton("Load on start")
+ self.vbox.pack_start(self.load_on_start)
+
+ self.connect('response', self.ok)
+ self.connect('close', self.cancel)
+
+ self.hide_all()
+
+ self.plugin = plugin
+
+
+ def ok(self, dialog, response):
+ self.hide_all()
+
+ if response != gtk.RESPONSE_ACCEPT:
+ self.cancel(dialog)
+ return
+
+ self.plugin.setconfig(self.url.get_text(),
+ self.load_on_start.get_active())
+
+ def cancel(self, dialog, response):
+ self.hide_all()
+
+ def start(self):
+ self.show_all()
+
+
+class GTKProgress(gtk.Dialog):
+ def __init__(self, plugin):
+ gtk.Dialog.__init__(self, title="Setting-Up Blocklist",
+ flags=gtk.DIALOG_MODAL,
+ buttons=(gtk.STOCK_CANCEL, gtk.RESPONSE_REJECT))
+ # Setup
+ self.set_border_width(12)
+ self.vbox.set_spacing(6)
+
+ label = gtk.Label()
+ label.set_markup('Loading and installing blocklist')
+ self.vbox.pack_start(label)
+
+ self.progress = gtk.ProgressBar()
+ self.vbox.pack_start(self.progress)
+
+ self.connect('close', self.cancel)
+
+ self.hide_all()
+
+ def download_prog(self, fract):
+ if fract > 1.0:
+ fract = 1.0
+ self.progress.set_fraction(fract)
+
+ def cancel(self, dialog, response):
+ self.hide_all()
+
+ def start(self):
+ print "showing all"
+ self.show_all()
+
+ def stop(self):
+ self.hide_all()
diff --git a/plugins/ExamplePlugin/__init__.py b/plugins/ExamplePlugin/__init__.py
new file mode 100644
index 000000000..58f0e59eb
--- /dev/null
+++ b/plugins/ExamplePlugin/__init__.py
@@ -0,0 +1,17 @@
+# An example plugin for use with Deluge
+
+plugin_name = "Example Plugin" # The name of the plugin
+plugin_author = "Zach Tibbitts" # The author's Name
+plugin_version = "0.5.0" # The plugin's version number
+plugin_description = "An example plugin" # A description of the plugin
+
+def deluge_init(deluge_path):
+ global path
+ path = deluge_path
+
+
+from ExamplePlugin.plugin import plugin_Example
+
+def enable(core, interface):
+ global path
+ return plugin_Example(path, core, interface)
diff --git a/plugins/ExamplePlugin/plugin.py b/plugins/ExamplePlugin/plugin.py
index 2651f54c7..c2f6ad2b2 100644
--- a/plugins/ExamplePlugin/plugin.py
+++ b/plugins/ExamplePlugin/plugin.py
@@ -1,5 +1,7 @@
# An example plugin for use with Deluge
+import deluge.common, deluge.pref, gtk, gtk.glade
+
# This plugin is intended to be used with Deluge's default GTK interface
class plugin_Example: # The plugin's class
## Your plugin's contructor should follow this format
@@ -11,14 +13,12 @@ class plugin_Example: # The plugin's class
self.path = path
self.core = deluge_core
self.interface = deluge_interface
- # Classes must be imported as they are needed from within
- # the plugin's functions
- import common, gtk, gtk.glade, dgtk, pref
+
# Create an options file and try to load existing Values
- self.config_file = common.CONFIG_DIR + "/example.conf"
- self.config = pref.Preferences()
+ self.config_file = deluge.common.CONFIG_DIR + "/example.conf"
+ self.config = deluge.pref.Preferences()
try:
- self.config.load_from_file(self.config_file)
+ self.config.load(self.config_file)
except IOError:
# File does not exist
pass
@@ -41,7 +41,7 @@ class plugin_Example: # The plugin's class
## unload is called when the plugin is removed or Deluge is shut down
def unload(self):
self.toolbar.remove(self.button) # Remove the button from the toolbar
- self.config.save_to_file(self.config_file)
+ self.config.save(self.config_file)
## update will be called every UPDATE_INTERVAL (usually about 1 second)
def update(self):
@@ -71,7 +71,6 @@ class plugin_Example: # The plugin's class
## This will be called whenever self.button is clicked
def clicked(self, button):
# Build a dialog from scratch rather than from a glade file
- import gtk
dialog = gtk.Dialog(title="Example Plugin", parent=self.interface.window,
buttons=(gtk.STOCK_OK, 0))
dialog.set_icon_from_file(self.path + "/example-plugin.png")
@@ -91,11 +90,3 @@ class plugin_Example: # The plugin's class
dialog.hide()
dialog.destroy()
-
-register_plugin("Example Plugin", # The name of the plugin
- plugin_Example, # The plugin's class
- "Zach Tibbitts", # The author's Name
- "0.5.0", # The plugin's version number
- "An example plugin", # A description of the plugin
- config=True, # If the plugin can be configured
- )
diff --git a/plugins/HelloWorld/__init__.py b/plugins/HelloWorld/__init__.py
new file mode 100644
index 000000000..86d75ac4b
--- /dev/null
+++ b/plugins/HelloWorld/__init__.py
@@ -0,0 +1,29 @@
+# A simple plugin to display Hello, World
+
+plugin_name = "Hello World"
+plugin_author = "Zach Tibbitts"
+plugin_version = "1.0"
+plugin_description = 'Displays "Hello, World"'
+
+def deluge_init(deluge_path):
+ global path
+ path = deluge_path
+
+def enable(core, interface):
+ global path
+ return plugin_Hello(path, core, interface)
+
+
+class plugin_Hello:
+ def __init__(self, path, deluge_core, deluge_interface):
+ self.path = path
+ self.core = deluge_core
+ self.interface = deluge_interface
+
+ def unload(self):
+ pass
+
+ def update(self):
+ print "Hello, World!"
+
+
diff --git a/plugins/HelloWorld/plugin.py b/plugins/HelloWorld/plugin.py
deleted file mode 100644
index f112d326a..000000000
--- a/plugins/HelloWorld/plugin.py
+++ /dev/null
@@ -1,19 +0,0 @@
-# A simple plugin to display Hello, World
-
-class plugin_Hello:
- def __init__(self, path, deluge_core, deluge_interface):
- self.path = path
- self.core = deluge_core
- self.interface = deluge_interface
-
- def unload(self):
- pass
-
- def update(self):
- print "Hello, World!"
-
-register_plugin("Hello World",
- plugin_Hello,
- "Zach Tibbitts",
- "1.0",
- 'Displays "Hello, World"')
diff --git a/plugins/NetworkGraph/__init__.py b/plugins/NetworkGraph/__init__.py
new file mode 100644
index 000000000..717fd9057
--- /dev/null
+++ b/plugins/NetworkGraph/__init__.py
@@ -0,0 +1,16 @@
+
+plugin_name = "Network Activity Graph"
+plugin_author = "Alon Zakai, Zach Tibbitts"
+plugin_version = "0.2"
+plugin_description = "Network Activity Graph plugin\n\nWritten by Kripkenstein"
+
+
+def deluge_init(deluge_path):
+ global path
+ path = deluge_path
+
+from NetworkGraph.plugin import plugin_NetGraph
+
+def enable(core, interface):
+ global path
+ return plugin_NetGraph(path, core, interface)
diff --git a/plugins/NetworkGraph/plugin.py b/plugins/NetworkGraph/plugin.py
index 29a3ba52b..2a96f05d6 100644
--- a/plugins/NetworkGraph/plugin.py
+++ b/plugins/NetworkGraph/plugin.py
@@ -50,9 +50,6 @@ class plugin_NetGraph:
self.parentNotebook.remove_page(page)
break
- def configure(self):
- pass
-
def update(self):
import gtk
session_info = self.core.get_state()
@@ -158,12 +155,3 @@ class plugin_NetGraph:
self.ctx.stroke()
-### Register plugin with Deluge
-
-register_plugin("Network Activity Graph", # The name of the plugin
- plugin_NetGraph, # The plugin's class
- "Alon Zakai, Zach Tibbitts", # Authors
- "0.2", # The plugin's version number
- "Network Activity Graph plugin\n\nWritten by Kripkenstein", # A description of the plugin
- config=False, # If the plugin can be configured
- )
diff --git a/plugins/NetworkHealth/__init__.py b/plugins/NetworkHealth/__init__.py
new file mode 100644
index 000000000..8e177cf35
--- /dev/null
+++ b/plugins/NetworkHealth/__init__.py
@@ -0,0 +1,18 @@
+
+
+plugin_name = "Network Health Monitor"
+plugin_author = "Alon Zakai, Zach Tibbitts"
+plugin_version = "0.2"
+plugin_description = "Network Health Monitor plugin\n\nWritten by Kripkenstein"
+
+
+def deluge_init(deluge_path):
+ global path
+ path = deluge_path
+
+
+from NetworkHealth.plugin import plugin_NetworkHealth
+
+def enable(core, interface):
+ global path
+ return plugin_NetworkHealth(path, core, interface)
diff --git a/plugins/NetworkHealth/plugin.py b/plugins/NetworkHealth/plugin.py
index a1094ebe9..cfb5d286f 100644
--- a/plugins/NetworkHealth/plugin.py
+++ b/plugins/NetworkHealth/plugin.py
@@ -7,12 +7,6 @@ class plugin_NetworkHealth:
self.counter = 30
self.maxCount = self.counter
- def config(self):
- pass
-
- def unload(self):
- pass
-
def update(self):
session_info = self.core.get_state()
if not session_info['has_incoming_connections'] and \
@@ -28,12 +22,3 @@ class plugin_NetworkHealth:
self.counter = self.maxCount
self.parent.statusbar_temp_msg = self.parent.statusbar_temp_msg + ' ' + message
-
-### Register plugin with Deluge
-register_plugin("Network Health Monitor", # The name of the plugin
- plugin_NetworkHealth, # The plugin's class
- "Alon Zakai, Zach Tibbitts", # Authors
- "0.2", # The plugin's version number
- "Network Health Monitor plugin\n\nWritten by Kripkenstein", # A description of the plugin
- config=False # If the plugin can be configured\
- )
diff --git a/plugins/TorrentCreator/__init__.py b/plugins/TorrentCreator/__init__.py
new file mode 100644
index 000000000..0f5a9bd0b
--- /dev/null
+++ b/plugins/TorrentCreator/__init__.py
@@ -0,0 +1,17 @@
+
+
+plugin_name = "Deluge Torrent Creator"
+plugin_author = "regulate"
+plugin_version = "0.1"
+plugin_description = "A torrent creator plugin"
+
+def deluge_init(deluge_path):
+ global path
+ path = deluge_path
+
+
+from TorrentCreator.plugin import plugin_tcreator
+
+def enable(core, interface):
+ global path
+ return plugin_tcreator(path, core, interface)
diff --git a/plugins/TorrentCreator/plugin.py b/plugins/TorrentCreator/plugin.py
index 9722055a4..549948f3c 100644
--- a/plugins/TorrentCreator/plugin.py
+++ b/plugins/TorrentCreator/plugin.py
@@ -91,5 +91,3 @@ class plugin_tcreator:
ret = self.core.create_torrent(self.dest, src_dir, trackers, comments, size, author)
return ret
-register_plugin("Deluge Torrent Creator", plugin_tcreator, "regulate", "0.1", "A torrent creator plugin", config=False)
-
diff --git a/plugins/TorrentSearch/__init__.py b/plugins/TorrentSearch/__init__.py
new file mode 100644
index 000000000..ec5f0193a
--- /dev/null
+++ b/plugins/TorrentSearch/__init__.py
@@ -0,0 +1,17 @@
+
+plugin_name = "Torrent Search"
+plugin_author = "Zach Tibbitts"
+plugin_version = "0.5"
+plugin_description = "A searchbar for torrent search engines"
+
+
+def deluge_init(deluge_path):
+ global path
+ path = deluge_path
+
+
+from TorrentSearch.plugin import plugin_Search
+
+def enable(core, interface):
+ global path
+ return plugin_Search(path, core, interface)
diff --git a/plugins/TorrentSearch/plugin.py b/plugins/TorrentSearch/plugin.py
index 489f405a6..5e8fbfda0 100644
--- a/plugins/TorrentSearch/plugin.py
+++ b/plugins/TorrentSearch/plugin.py
@@ -151,11 +151,3 @@ class plugin_Search:
self.menu_button.set_label("Search " + engine_string)
self.se = engine_string
-
-register_plugin("Torrent Search",
- plugin_Search,
- "Zach Tibbitts",
- "0.5",
- "A searchbar for torrent search engines",
- config=True
- )
diff --git a/src/core.py b/src/core.py
index 46f828980..1dfe14ca0 100644
--- a/src/core.py
+++ b/src/core.py
@@ -742,3 +742,11 @@ class Manager:
def pe_settings(self, out_enc_policy, in_enc_policy, allowed_enc_level, prefer_rc4):
return deluge_core.pe_settings(out_enc_policy, in_enc_policy, allowed_enc_level, prefer_rc4)
+
+ # Creates/resets the IP filter list
+ def reset_ip_filter(self):
+ return deluge_core.reset_IP_filter()
+
+ # Adds an IP range (as two dotted quad strings) to the filter
+ def add_range_to_ip_filter(self, start, end):
+ return deluge_core.add_range_to_IP_filter(start, end)
diff --git a/src/deluge_core.cpp b/src/deluge_core.cpp
index fa54a49c8..6523fb429 100644
--- a/src/deluge_core.cpp
+++ b/src/deluge_core.cpp
@@ -1191,43 +1191,33 @@ static PyObject *torrent_create_torrent(PyObject *self, PyObject *args)
}
-static PyObject *torrent_apply_IP_filter(PyObject *self, PyObject *args)
+static PyObject *torrent_reset_IP_filter(PyObject *self, PyObject *args)
{
- PyObject *ranges;
- if (!PyArg_ParseTuple(args, "O", &ranges))
- return NULL;
-
- long num_ranges = PyList_Size(ranges);
-
- // printf("Number of ranges: %ld\r\n", num_ranges);
- // Py_INCREF(Py_None); return Py_None;
-
// Remove existing filter, if there is one
if (M_the_filter != NULL)
delete M_the_filter;
M_the_filter = new ip_filter();
- address_v4 from, to;
- PyObject *curr;
-
- // printf("Can I 10.10.10.10? %d\r\n", the_filter->access(address_v4::from_string("10.10.10.10")));
-
- for (long i = 0; i < num_ranges; i++)
- {
- curr = PyList_GetItem(ranges, i);
- // PyObject_Print(curr, stdout, 0);
- from = address_v4::from_string(PyString_AsString(PyList_GetItem(curr, 0)));
- to = address_v4::from_string(PyString_AsString(PyList_GetItem(curr, 1)));
- // printf("Filtering: %s - %s\r\n", from.to_string().c_str(), to.to_string().c_str());
- M_the_filter->add_rule(from, to, ip_filter::blocked);
- };
-
- // printf("Can I 10.10.10.10? %d\r\n", the_filter->access(address_v4::from_string("10.10.10.10")));
-
M_ses->set_ip_filter(*M_the_filter);
- // printf("Can I 10.10.10.10? %d\r\n", the_filter->access(address_v4::from_string("10.10.10.10")));
+ Py_INCREF(Py_None); return Py_None;
+}
+
+
+static PyObject *torrent_add_range_to_IP_filter(PyObject *self, PyObject *args)
+{
+ if (M_the_filter == NULL) {
+ RAISE_PTR(DelugeError, "No filter defined, use reset_IP_filter");
+ }
+
+ char *start, *end;
+ if (!PyArg_ParseTuple(args, "ss", &start, &end))
+ return NULL;
+
+ address_v4 inet_start = address_v4::from_string(start);
+ address_v4 inet_end = address_v4::from_string(end);
+ M_the_filter->add_rule(inet_start, inet_end, ip_filter::blocked);
Py_INCREF(Py_None); return Py_None;
}
@@ -1286,7 +1276,8 @@ static PyMethodDef deluge_core_methods[] =
{"stop_DHT", torrent_stop_DHT, METH_VARARGS, "."},
{"get_DHT_info", torrent_get_DHT_info, METH_VARARGS, "."},
{"create_torrent", torrent_create_torrent, METH_VARARGS, "."},
- {"apply_IP_filter", torrent_apply_IP_filter, METH_VARARGS, "."},
+ {"reset_IP_filter", torrent_reset_IP_filter, METH_VARARGS, "."},
+ {"add_range_to_IP_filter", torrent_add_range_to_IP_filter, METH_VARARGS, "."},
{NULL}
};
diff --git a/src/dialogs.py b/src/dialogs.py
index b2664678c..fdbc873dd 100644
--- a/src/dialogs.py
+++ b/src/dialogs.py
@@ -154,11 +154,11 @@ class PluginDlg:
return True
name = model.get_value(model.get_iter(path), 0)
plugin = self.plugins.get_plugin(name)
- author = plugin['author']
- version = plugin['version']
- config = plugin['config']
- description = plugin['description']
+ author = plugin.plugin_author
+ version = plugin.plugin_version
+ description = plugin.plugin_description
if name in self.plugins.get_enabled_plugins():
+ config = self.plugins.configurable_plugin(name)
self.glade.get_widget("plugin_conf").set_sensitive(config)
else:
self.glade.get_widget("plugin_conf").set_sensitive(False)
@@ -174,8 +174,8 @@ class PluginDlg:
self.store.set_value(plugin_iter, 1, plugin_value)
if plugin_value:
self.plugins.enable_plugin(plugin_name)
- self.glade.get_widget("plugin_conf").set_sensitive(
- self.plugins.get_plugin(plugin_name)['config'])
+ config = self.plugins.configurable_plugin(plugin_name)
+ self.glade.get_widget("plugin_conf").set_sensitive(config)
else:
self.plugins.disable_plugin(plugin_name)
self.glade.get_widget("plugin_conf").set_sensitive(False)
diff --git a/src/plugins.py b/src/plugins.py
index 912f2cc8c..ee5a20f4b 100644
--- a/src/plugins.py
+++ b/src/plugins.py
@@ -20,7 +20,7 @@
# 51 Franklin Street, Fifth Floor
# Boston, MA 02110-1301, USA.
-import os
+import os, sys, imp
class PluginManager:
def __init__(self, deluge_core, deluge_interface):
@@ -32,15 +32,26 @@ class PluginManager:
def add_plugin_dir(self, directory):
self.plugin_dirs.append(directory)
+ sys.path.append(directory)
+ # Scans all defined plugin dirs for Deluge plugins. The resulting
+ # module object is store with the defined name.
def scan_for_plugins(self):
- register_plugin = self.register_plugin
for folder in self.plugin_dirs:
- plugin_folders = os.listdir(folder)
- for plugin in plugin_folders:
- if os.path.isfile(os.path.join(folder, plugin, "plugin.py")):
- self.path = os.path.join(folder, plugin)
- execfile(os.path.join(folder, plugin, "plugin.py"))
+ print "Scanning plugin dir",folder
+ for modname in os.listdir(folder):
+ path = folder+'/'+modname
+ if '__init__.py' in os.listdir(path):
+ # Import the found module. Note that the last
+ # parameter is important otherwise only the base
+ # modules (ie. 'plugins') is imported. This appears
+ # to be by design.
+ print "Loading module",modname
+ mod = __import__(modname, globals(), locals(), [''])
+ if 'deluge_init' in dir(mod):
+ print "Initialising plugin",modname
+ mod.deluge_init(path)
+ self.available_plugins[mod.plugin_name] = mod
def get_available_plugins(self):
return self.available_plugins.keys()
@@ -49,35 +60,38 @@ class PluginManager:
return self.available_plugins[name]
def enable_plugin(self, name):
- self.enabled_plugins[name] = self.available_plugins[name]['class'](
- self.available_plugins[name]['path'], self.core, self.interface)
+ plugin = self.available_plugins[name]
+ self.enabled_plugins[name] = plugin.enable(self.core, self.interface)
def get_enabled_plugins(self):
return self.enabled_plugins.keys()
def disable_plugin(self, name):
- self.enabled_plugins[name].unload()
+ plugin = self.enabled_plugins[name]
+ if 'unload' in dir(plugin):
+ plugin.unload()
self.enabled_plugins.pop(name)
+ def configurable_plugin(self, name):
+ if name in self.enabled_plugins:
+ return 'configure' in dir(self.enabled_plugins[name])
+ else:
+ return False
+
def configure_plugin(self, name):
self.enabled_plugins[name].configure()
def update_active_plugins(self):
for name in self.enabled_plugins.keys():
- self.enabled_plugins[name].update()
+ plugin = self.enabled_plugins[name]
+ if 'update' in dir(plugin):
+ plugin.update()
def shutdown_all_plugins(self):
for name in self.enabled_plugins.keys():
- self.enabled_plugins[name].unload()
+ self.disable_plugin(name)
self.enabled_plugins.clear()
- def register_plugin(self, name, plugin_class, author, version, description, config=False):
- self.available_plugins[name] = {'class': plugin_class,
- 'author': author,
- 'version': version,
- 'description': description,
- 'config': config,
- 'path': self.path}
## Few lines of code to test functionality
if __name__ == "__main__":