Example Plugin

This commit is contained in:
Zach Tibbitts 2007-02-15 21:30:17 +00:00
parent 98b3b4e7cc
commit f2d2ac6c8e
7 changed files with 210 additions and 35 deletions

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.4 KiB

View File

@ -0,0 +1,94 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!DOCTYPE glade-interface SYSTEM "glade-2.0.dtd">
<!--Generated with glade3 3.1.4 on Thu Feb 15 15:34:54 2007 by zach@notapowerbook-->
<glade-interface>
<widget class="GtkDialog" id="dialog">
<property name="border_width">5</property>
<property name="title" translatable="yes">Example Plugin</property>
<property name="default_width">313</property>
<property name="default_height">167</property>
<property name="has_separator">False</property>
<child internal-child="vbox">
<widget class="GtkVBox" id="dialog-vbox1">
<property name="visible">True</property>
<property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK | GDK_ENTER_NOTIFY_MASK</property>
<property name="spacing">2</property>
<child>
<widget class="GtkTable" id="table1">
<property name="visible">True</property>
<property name="n_rows">2</property>
<property name="n_columns">2</property>
<child>
<widget class="GtkEntry" id="entry1">
<property name="visible">True</property>
</widget>
<packing>
<property name="left_attach">1</property>
<property name="right_attach">2</property>
</packing>
</child>
<child>
<widget class="GtkEntry" id="entry2">
<property name="visible">True</property>
</widget>
<packing>
<property name="left_attach">1</property>
<property name="right_attach">2</property>
<property name="top_attach">1</property>
<property name="bottom_attach">2</property>
</packing>
</child>
<child>
<widget class="GtkLabel" id="label1">
<property name="visible">True</property>
<property name="label" translatable="yes">First Value</property>
</widget>
</child>
<child>
<widget class="GtkLabel" id="label2">
<property name="visible">True</property>
<property name="label" translatable="yes">Second Value</property>
</widget>
<packing>
<property name="top_attach">1</property>
<property name="bottom_attach">2</property>
</packing>
</child>
</widget>
<packing>
<property name="position">1</property>
</packing>
</child>
<child internal-child="action_area">
<widget class="GtkHButtonBox" id="dialog-action_area1">
<property name="visible">True</property>
<property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK | GDK_ENTER_NOTIFY_MASK</property>
<property name="layout_style">GTK_BUTTONBOX_END</property>
<child>
<widget class="GtkButton" id="button_cancel">
<property name="visible">True</property>
<property name="label" translatable="yes">gtk-cancel</property>
<property name="use_stock">True</property>
</widget>
</child>
<child>
<widget class="GtkButton" id="button_ok">
<property name="visible">True</property>
<property name="label" translatable="yes">gtk-ok</property>
<property name="use_stock">True</property>
<property name="response_id">1</property>
</widget>
<packing>
<property name="position">1</property>
</packing>
</child>
</widget>
<packing>
<property name="expand">False</property>
<property name="pack_type">GTK_PACK_END</property>
</packing>
</child>
</widget>
</child>
</widget>
</glade-interface>

View File

@ -1,27 +1,106 @@
#!/usr/bin/python
# An example plugin for use with Deluge
class plugin_Example:
# 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
## path = A string containing the path to the plugin
## deluge_core = The active instance of the Deluge Manager
## deluge_interface = The active instance of the Deluge Interface
def __init__(self, path, deluge_core, deluge_interface):
# Save the path, interface, and core so they can be used later
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 dcommon, gtk, gtk.glade, dgtk
# Create an options file and try to load existing Values
self.config_file = dcommon.CONFIG_DIR + "/example.conf"
self.config = dcommon.DelugePreferences()
try:
self.config.load_from_file(self.config_file)
except IOError:
# File does not exist
pass
# Extract the configuration dialog from the gladefile
self.glade = gtk.glade.XML(path + "/example.glade")
self.dialog = self.glade.get_widget("dialog")
self.dialog.set_icon_from_file(self.path + "/example-plugin.png")
# Access the interface's toolbar
self.toolbar = self.interface.toolbar
# Make a toolbar button
icon = gtk.Image()
icon.set_from_file(self.path + "/example-plugin.png") # Toolbar items should be 22x22 pixel images
self.button = gtk.ToolButton(icon_widget=icon, label="Example Plugin")
self.button.connect("clicked", self.clicked) # Connect the signal handler for the button
self.toolbar.add(self.button) # Add button to toolbar
self.button.show_all() # Show the button
print "Example Plugin loaded"
## 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)
print "Example Plugin unloaded"
## update will be called every UPDATE_INTERVAL (usually about 1 second)
def update(self):
print "Hello World, from Example Plugin"
print "Example Plugin has been updated"
## This will be only called if your plugin is configurable
def configure(self):
entry1 = self.glade.get_widget("entry1")
entry2 = self.glade.get_widget("entry2")
try:
entry1.set_text(self.config.get("option1"))
entry2.set_text(self.config.get("option2"))
except KeyError:
entry1.set_text("")
entry2.set_text("")
self.dialog.show()
response = self.dialog.run()
self.dialog.hide()
if response:
self.config.set("option1", entry1.get_text())
self.config.set("option2", entry2.get_text())
## 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")
try:
text = "This is a popup notification from Example Plugin\n" + \
"Your value for option1 is %s\n"%self.config.get("option1") + \
"and option2 is %s"%self.config.get("option2")
except KeyError:
text = "This is a popup notification from Example Plugin\n" + \
"If you had set options by configuring this plugin,\n" + \
"they would appear here"
label = gtk.Label(text)
dialog.vbox.pack_start(label)
dialog.show_all()
dialog.run()
dialog.hide()
dialog.destroy()
register_plugin("Example Plugin",
plugin_Example,
"0.2",
"An example plugin",
config=False,
default=False,
requires="0.5.0",
interface="gtk",
required_plugins=None)
register_plugin("Example Plugin", # The name of the plugin
plugin_Example, # The plugin's class
"0.5.0", # The plugin's version number
"An example plugin", # A description of the plugin
config=True, # If the plugin can be configured
default=False, # If the plugin should be loaded by default
requires="0.5.0", # Required version of Deluge
interface="gtk", # Required Deluge interface
required_plugins=None # Any plugins that must be loaded before this
)

View File

@ -1,25 +1,19 @@
# 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
print "Hello World loaded"
def unload(self):
print "Hello World unloaded"
pass
def update(self):
print "Hello, World!"
register_plugin("Hello World",
plugin_Hello,
"1.0",
'Displays "Hello, World"',
config=False,
default=False,
requires="0.5.0",
interface=None,
required_plugins=None)
requires="0.5.0")

View File

@ -1,4 +1,4 @@
#!/usr/bin/python
class plugin_Search:
def __init__(self, path, deluge_core, deluge_interface):

View File

@ -202,7 +202,10 @@ class DelugeGTK(dbus.service.Object):
version = plugin['version']
config = plugin['config']
description = plugin['description']
self.prf_glade.get_widget("plugin_conf").set_sensitive(config)
if name in self.plugins.get_enabled_plugins():
self.prf_glade.get_widget("plugin_conf").set_sensitive(config)
else:
self.prf_glade.get_widget("plugin_conf").set_sensitive(False)
self.prf_glade.get_widget("plugin_text").get_buffer(
).set_text("%s\nVersion: %s\n\n%s"%
(name, version, description))
@ -215,6 +218,8 @@ class DelugeGTK(dbus.service.Object):
self.plugin_store.set_value(plugin_iter, 1, plugin_value)
if plugin_value:
self.plugins.enable_plugin(plugin_name)
self.prf_glade.get_widget("plugin_conf").set_sensitive(
self.plugins.get_plugin(plugin_name)['config'])
else:
self.plugins.disable_plugin(plugin_name)
@ -373,6 +378,8 @@ class DelugeGTK(dbus.service.Object):
self.plugin_store.append( (plugin, True) )
else:
self.plugin_store.append( (plugin, False) )
self.prf_glade.get_widget("plugin_text").get_buffer().set_text("")
self.prf_glade.get_widget("plugin_conf").set_sensitive(False)
self.plugin_dlg.show()
self.plugin_dlg.run()
self.plugin_dlg.hide()
@ -686,6 +693,10 @@ class DelugeGTK(dbus.service.Object):
self.share_column.set_visible(obj.get_active())
def quit(self, obj=None):
self.shutdown()
def shutdown(self):
self.plugins.shutdown_all_plugins()
self.manager.quit()
gtk.main_quit()

View File

@ -67,16 +67,13 @@ class PluginManager:
for name in self.enabled_plugins.keys():
self.enabled_plugins[name].update()
def register_plugin(self,
name,
plugin_class,
version,
description,
config=False,
default=False,
requires=None,
interface=None,
required_plugins=None):
def shutdown_all_plugins(self):
for name in self.enabled_plugins.keys():
self.enabled_plugins[name].unload()
self.enabled_plugins.clear()
def register_plugin(self, name, plugin_class, version, description, config=False,
default=False, requires=None, interface=None, required_plugins=None):
self.available_plugins[name] = {'class': plugin_class,
'version': version,
'description': description,