Author: damoxc

Revision: 4918

Log:
        begin an execute command upon event plugin

Diff:
Added: trunk/deluge/plugins/execute/execute/__init__.py
===================================================================
--- trunk/deluge/plugins/execute/execute/__init__.py                            
(rev 0)
+++ trunk/deluge/plugins/execute/execute/__init__.py    2009-03-22 23:37:21 UTC 
(rev 4918)
@@ -0,0 +1,34 @@
+#
+# __init__.py
+#
+# Copyright (C) 2009 Damien Churchill <[email protected]>
+#
+# Deluge is free software.
+#
+# You may redistribute it and/or modify it under the terms of the
+# GNU General Public License, as published by the Free Software
+# Foundation; either version 3 of the License, or (at your option)
+# any later version.
+#
+# deluge is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+# See the GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with deluge.    If not, write to:
+#     The Free Software Foundation, Inc.,
+#     51 Franklin Street, Fifth Floor
+#     Boston, MA    02110-1301, USA.
+#
+
+from deluge.plugins.init import PluginInitBase
+
+class CorePlugin(PluginInitBase):
+    from core import Core as _plugin_cls
+
+class GtkUIPlugin(PluginInitBase):
+    from gtkui import GtkUI as _plugin_cls
+
+class WebUIPlugin(PluginInitBase):
+    from webui import WebUI as _plugin_cls

Added: trunk/deluge/plugins/execute/execute/common.py
===================================================================
--- trunk/deluge/plugins/execute/execute/common.py                              
(rev 0)
+++ trunk/deluge/plugins/execute/execute/common.py      2009-03-22 23:37:21 UTC 
(rev 4918)
@@ -0,0 +1,29 @@
+#
+# common.py
+#
+# Copyright (C) 2009 Andrew Resch <[email protected]>
+#
+# Deluge is free software.
+#
+# You may redistribute it and/or modify it under the terms of the
+# GNU General Public License, as published by the Free Software
+# Foundation; either version 3 of the License, or (at your option)
+# any later version.
+#
+# deluge is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+# See the GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with deluge.    If not, write to:
+#      The Free Software Foundation, Inc.,
+#      51 Franklin Street, Fifth Floor
+#      Boston, MA    02110-1301, USA.
+#
+
+import pkg_resources
+import os.path
+
+def get_resource(filename):
+    return pkg_resources.resource_filename("example", os.path.join("data", 
filename))

Added: trunk/deluge/plugins/execute/execute/core.py
===================================================================
--- trunk/deluge/plugins/execute/execute/core.py                                
(rev 0)
+++ trunk/deluge/plugins/execute/execute/core.py        2009-03-22 23:37:21 UTC 
(rev 4918)
@@ -0,0 +1,103 @@
+#
+# core.py
+#
+# Copyright (C) 2009 Andrew Resch <[email protected]>
+#
+# Deluge is free software.
+#
+# You may redistribute it and/or modify it under the terms of the
+# GNU General Public License, as published by the Free Software
+# Foundation; either version 3 of the License, or (at your option)
+# any later version.
+#
+# deluge is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+# See the GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with deluge.    If not, write to:
+#      The Free Software Foundation, Inc.,
+#      51 Franklin Street, Fifth Floor
+#      Boston, MA    02110-1301, USA.
+#
+
+import os
+import time
+import hashlib
+from subprocess import Popen, PIPE
+
+from deluge.log import LOG as log
+from deluge.plugins.pluginbase import CorePluginBase
+import deluge.component as component
+from deluge.configmanager import ConfigManager
+from deluge.core.rpcserver import export
+
+DEFAULT_CONFIG = {
+    "commands": []
+}
+
+EXECUTE_ID = 0
+EXECUTE_EVENT = 1
+EXECUTE_COMMAND = 2
+
+class Core(CorePluginBase):
+    def enable(self):
+        self.config = ConfigManager("execute.conf", DEFAULT_CONFIG)
+        event_manager = component.get("EventManager")
+        event_manager.register_event_handler("TorrentFinishedEvent",
+            self.on_torrent_finished)
+        log.debug("Example core plugin enabled!")
+    
+    def execute_commands(self, torrent_id, event):
+        torrent = component.get("TorrentManager").torrents[torrent_id]
+        info = torrent.get_status(["name", "save_path"])
+        torrent_name = info["name"]
+        path = info["save_path"]
+        for command in self.config["commands"]:
+            if command[EXECUTE_EVENT] == event:
+                command = os.path.expandvars(command[EXECUTE_COMMAND])
+                command = os.path.expanduser(command)
+                p = Popen([command, torrent_id, torrent_name, path],
+                    stdin=PIPE, stdout=PIPE, stderr=PIPE)
+                if p.wait() != 0:
+                    log.warn("Execute command failed with exit code %d",
+                        p.returncode)
+
+    def disable(self):
+        self.config.save()
+        event_manager = component.get("EventManager")
+        event_manager.deregister_event_handler("TorrentFinishedEvent",
+            self.on_torrent_finished)
+        log.debug("Example core plugin disabled!")
+    
+    def on_torrent_finished(self, torrent_id):
+        self.execute_commands(torrent_id, "complete")
+    
+    ### Exported RPC methods ###
+    @export
+    def add_command(self, event, command):
+        command_id = hashlib.sha1(str(time.time())).hexdigest()
+        self.config["commands"].append((command_id, event, command))
+        self.config.save()
+
+    @export
+    def get_commands(self):
+        return self.config["commands"]
+    
+    @export
+    def remove_command(self, command_id):
+        for command in self.config["commands"]:
+            if command[EXECUTE_ID] == command_id:
+                self.config["commands"].remove(command)
+                break
+        self.config.save()
+    
+    @export
+    def save_command(self, command_id, event, command):
+        for command in self.config["commands"]:
+            if command[EXECUTE_ID] == command_id:
+                command[EXECUTE_EVENT] = event
+                command[EXECUTE_COMMAND] = event
+                break
+        self.config.save()
\ No newline at end of file

Added: trunk/deluge/plugins/execute/execute/data/execute_prefs.glade
===================================================================
--- trunk/deluge/plugins/execute/execute/data/execute_prefs.glade               
                (rev 0)
+++ trunk/deluge/plugins/execute/execute/data/execute_prefs.glade       
2009-03-22 23:37:21 UTC (rev 4918)
@@ -0,0 +1,157 @@
+<?xml version="1.0"?>
+<glade-interface>
+  <!-- interface-requires gtk+ 2.16 -->
+  <!-- interface-naming-policy project-wide -->
+  <widget class="GtkWindow" id="execute_window">
+    <child>
+      <widget class="GtkVBox" id="execute_box">
+        <property name="visible">True</property>
+        <child>
+          <widget class="GtkFrame" id="commands_frame">
+            <property name="visible">True</property>
+            <property name="label_xalign">0</property>
+            <property name="shadow_type">none</property>
+            <child>
+              <widget class="GtkAlignment" id="commands_alignment">
+                <property name="visible">True</property>
+                <property name="left_padding">12</property>
+                <child>
+                  <widget class="GtkVBox" id="commands_vbox">
+                    <property name="visible">True</property>
+                    <child>
+                      <placeholder/>
+                    </child>
+                  </widget>
+                </child>
+              </widget>
+            </child>
+            <child>
+              <widget class="GtkLabel" id="commands_label">
+                <property name="visible">True</property>
+                <property name="label" 
translatable="yes">&lt;b&gt;Commands&lt;/b&gt;</property>
+                <property name="use_markup">True</property>
+              </widget>
+              <packing>
+                <property name="type">label_item</property>
+              </packing>
+            </child>
+          </widget>
+          <packing>
+            <property name="position">0</property>
+          </packing>
+        </child>
+        <child>
+          <widget class="GtkFrame" id="add_frame">
+            <property name="visible">True</property>
+            <property name="label_xalign">0</property>
+            <property name="shadow_type">none</property>
+            <child>
+              <widget class="GtkAlignment" id="add_alignment">
+                <property name="visible">True</property>
+                <property name="left_padding">12</property>
+                <child>
+                  <widget class="GtkTable" id="add_table">
+                    <property name="visible">True</property>
+                    <property name="n_rows">3</property>
+                    <property name="n_columns">2</property>
+                    <child>
+                      <widget class="GtkLabel" id="event_label">
+                        <property name="visible">True</property>
+                        <property name="xalign">0</property>
+                        <property name="label" 
translatable="yes">Event</property>
+                      </widget>
+                      <packing>
+                        <property name="x_options">GTK_FILL</property>
+                        <property name="x_padding">5</property>
+                      </packing>
+                    </child>
+                    <child>
+                      <widget class="GtkLabel" id="command_label">
+                        <property name="visible">True</property>
+                        <property name="xalign">0</property>
+                        <property name="label" 
translatable="yes">Command</property>
+                      </widget>
+                      <packing>
+                        <property name="top_attach">1</property>
+                        <property name="bottom_attach">2</property>
+                        <property name="x_options">GTK_FILL</property>
+                        <property name="x_padding">5</property>
+                      </packing>
+                    </child>
+                    <child>
+                      <widget class="GtkEntry" id="command_entry">
+                        <property name="visible">True</property>
+                        <property name="can_focus">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="GtkComboBox" id="event_combobox">
+                        <property name="visible">True</property>
+                        <property name="items" translatable="yes"></property>
+                      </widget>
+                      <packing>
+                        <property name="left_attach">1</property>
+                        <property name="right_attach">2</property>
+                      </packing>
+                    </child>
+                    <child>
+                      <widget class="GtkHBox" id="hbox1">
+                        <property name="visible">True</property>
+                        <child>
+                          <widget class="GtkButton" id="add_button">
+                            <property name="label" 
translatable="yes">Add</property>
+                            <property name="visible">True</property>
+                            <property name="can_focus">True</property>
+                            <property name="receives_default">True</property>
+                            <signal name="clicked" 
handler="on_add_button_clicked"/>
+                          </widget>
+                          <packing>
+                            <property name="expand">False</property>
+                            <property name="padding">5</property>
+                            <property name="position">0</property>
+                          </packing>
+                        </child>
+                        <child>
+                          <placeholder/>
+                        </child>
+                      </widget>
+                      <packing>
+                        <property name="left_attach">1</property>
+                        <property name="right_attach">2</property>
+                        <property name="top_attach">2</property>
+                        <property name="bottom_attach">3</property>
+                      </packing>
+                    </child>
+                    <child>
+                      <placeholder/>
+                    </child>
+                  </widget>
+                </child>
+              </widget>
+            </child>
+            <child>
+              <widget class="GtkLabel" id="add_label">
+                <property name="visible">True</property>
+                <property name="label" translatable="yes">&lt;b&gt;Add 
Command&lt;/b&gt;</property>
+                <property name="use_markup">True</property>
+              </widget>
+              <packing>
+                <property name="type">label_item</property>
+              </packing>
+            </child>
+          </widget>
+          <packing>
+            <property name="expand">False</property>
+            <property name="position">1</property>
+          </packing>
+        </child>
+      </widget>
+    </child>
+  </widget>
+</glade-interface>

Added: trunk/deluge/plugins/execute/execute/gtkui.py
===================================================================
--- trunk/deluge/plugins/execute/execute/gtkui.py                               
(rev 0)
+++ trunk/deluge/plugins/execute/execute/gtkui.py       2009-03-22 23:37:21 UTC 
(rev 4918)
@@ -0,0 +1,109 @@
+#
+# gtkui.py
+#
+# Copyright (C) 2009 Damien Churchill <[email protected]>
+#
+# Deluge is free software.
+#
+# You may redistribute it and/or modify it under the terms of the
+# GNU General Public License, as published by the Free Software
+# Foundation; either version 3 of the License, or (at your option)
+# any later version.
+#
+# deluge is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+# See the GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with deluge.    If not, write to:
+#      The Free Software Foundation, Inc.,
+#      51 Franklin Street, Fifth Floor
+#      Boston, MA    02110-1301, USA.
+#
+
+import os
+import gtk
+import pkg_resources
+
+from deluge.log import LOG as log
+from deluge.ui.client import client
+from deluge.plugins.pluginbase import GtkPluginBase
+import deluge.component as component
+import deluge.common
+
+EXECUTE_ID = 0
+EXECUTE_EVENT = 1
+EXECUTE_COMMAND = 2
+
+EVENT_MAP = {
+    "complete": _("Torrent Complete")
+}
+
+class ExecutePreferences(object):
+    def __init__(self, plugin):
+        self.plugin = plugin
+    
+    def load(self):
+        log.debug("Adding Execute Preferences page")
+        self.glade = gtk.glade.XML(self.get_resource("execute_prefs.glade"))
+        self.glade.signal_autoconnect({
+            "on_add_button_clicked": self.on_add_button_clicked
+        })
+        
+        events = self.glade.get_widget("event_combobox")
+        
+        store = gtk.ListStore(str, str)
+        store.append((_("Torrent Complete"), "complete"))
+        events.set_model(store)
+
+        self.plugin.add_preferences_page(_("Execute"),
+            self.glade.get_widget("execute_box"))
+        self.plugin.register_hook("on_show_prefs", self.load_commands)
+        self.plugin.register_hook("on_apply_prefs", self.on_apply_prefs)
+
+    def unload(self):
+        self.plugin.remove_preferences_page(_("Execute"))
+        self.plugin.deregister_hook("on_apply_prefs", self.on_apply_prefs)
+        self.plugin.deregister_hook("on_show_prefs", self.load_commands)
+
+    def get_resource(self, filename):
+        return pkg_resources.resource_filename("execute", os.path.join("data",
+            filename))
+    
+    def load_commands(self):
+        def on_get_commands(commands):
+            vbox = self.glade.get_widget("commands_vbox")
+            for command in commands:
+                command_id, event, command = command
+                log.debug("Adding command `%s`", command_id)
+                hbox = gtk.HBox(False, 0)
+                label = gtk.Label(EVENT_MAP[event])
+                entry = gtk.Entry()
+                entry.set_text(command)
+                hbox.pack_start(label, padding = 5)
+                hbox.pack_start(entry)
+                vbox.pack_start(hbox)
+                hbox.show_all()
+        client.execute.get_commands().addCallback(on_get_commands)
+    
+    def on_add_button_clicked(self, *args):
+        command = self.glade.get_widget("command_entry").get_text()
+        events = self.glade.get_widget("event_combobox")
+        event = events.get_model()[events.get_active()][1]
+        client.execute.add_command(event, command)
+
+    def on_apply_prefs(self):
+        options = {}
+        #update options dict here.
+        client.label.set_config(options)
+
+class GtkUI(GtkPluginBase):    
+    
+    def enable(self):
+        self.plugin = component.get("PluginManager")
+        self.prefences = ExecutePreferences(self.plugin)
+        self.prefences.load()
+
+    def disable(self):
+        pass

Added: trunk/deluge/plugins/execute/execute/webui.py
===================================================================
--- trunk/deluge/plugins/execute/execute/webui.py                               
(rev 0)
+++ trunk/deluge/plugins/execute/execute/webui.py       2009-03-22 23:37:21 UTC 
(rev 4918)
@@ -0,0 +1,36 @@
+#
+# webui.py
+#
+# Copyright (C) 2009 Damien Churchill <[email protected]>
+#
+# Deluge is free software.
+#
+# You may redistribute it and/or modify it under the terms of the
+# GNU General Public License, as published by the Free Software
+# Foundation; either version 3 of the License, or (at your option)
+# any later version.
+#
+# deluge is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+# See the GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with deluge.    If not, write to:
+#      The Free Software Foundation, Inc.,
+#      51 Franklin Street, Fifth Floor
+#      Boston, MA    02110-1301, USA.
+#
+
+
+from deluge.log import LOG as log
+from deluge.ui.client import client
+from deluge import component
+from deluge.plugins.pluginbase import WebPluginBase
+
+class WebUI(WebPluginBase):
+    def enable(self):
+        log.debug("Example Web plugin enabled!")
+
+    def disable(self):
+        log.debug("Example Web plugin disabled!")

Added: trunk/deluge/plugins/execute/setup.py
===================================================================
--- trunk/deluge/plugins/execute/setup.py                               (rev 0)
+++ trunk/deluge/plugins/execute/setup.py       2009-03-22 23:37:21 UTC (rev 
4918)
@@ -0,0 +1,56 @@
+#
+# setup.py
+#
+# Copyright (C) 2009 Damien Churchill <[email protected]>
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 3, or (at your option)
+# any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.    See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program.    If not, write to:
+#     The Free Software Foundation, Inc.,
+#     51 Franklin Street, Fifth Floor
+#     Boston, MA    02110-1301, USA.
+#
+
+from setuptools import setup
+
+__plugin_name__ = "Execute"
+__author__ = "Damien Churchill"
+__author_email__ = "[email protected]"
+__version__ = "1.2"
+__url__ = "http://deluge-torrent.org";
+__license__ = "GPLv3"
+__description__ = "Plugin to execute a command upon an event"
+__long_description__ = __description__
+__pkg_data__ = {__plugin_name__.lower(): ["data/*"]}
+
+setup(
+    name=__plugin_name__,
+    version=__version__,
+    description=__description__,
+    author=__author__,
+    author_email=__author_email__,
+    url=__url__,
+    license=__license__,
+    long_description=__long_description__,
+
+    packages=[__plugin_name__.lower()],
+    package_data = __pkg_data__,
+
+    entry_points="""
+    [deluge.plugin.core]
+    %s = %s:CorePlugin
+    [deluge.plugin.gtkui]
+    %s = %s:GtkUIPlugin
+    [deluge.plugin.webui]
+    %s = %s:WebUIPlugin
+    """ % ((__plugin_name__, __plugin_name__.lower())*3)
+)



--~--~---------~--~----~------------~-------~--~----~
You received this message because you are subscribed to the Google Groups 
"deluge-commit" group.
To post to this group, send email to [email protected]
To unsubscribe from this group, send email to 
[email protected]
For more options, visit this group at 
http://groups.google.com/group/deluge-commit?hl=en
-~----------~----~----~----~------~----~------~--~---

Reply via email to