Author: andar

Revision: 5338

Log:
        Add Scheduler plugin

Diff:
Added: trunk/deluge/plugins/scheduler/scheduler/__init__.py
===================================================================
--- trunk/deluge/plugins/scheduler/scheduler/__init__.py                        
        (rev 0)
+++ trunk/deluge/plugins/scheduler/scheduler/__init__.py        2009-06-02 
00:57:52 UTC (rev 5338)
@@ -0,0 +1,57 @@
+#
+# __init__.py
+#
+# Copyright (C) 2009 Andrew Resch <[email protected]>
+#
+# Basic plugin template created by:
+# Copyright (C) 2008 Martijn Voncken <[email protected]>
+# Copyright (C) 2007-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.
+#
+#    In addition, as a special exception, the copyright holders give
+#    permission to link the code of portions of this program with the OpenSSL
+#    library.
+#    You must obey the GNU General Public License in all respects for all of
+#    the code used other than OpenSSL. If you modify file(s) with this
+#    exception, you may extend this exception to your version of the file(s),
+#    but you are not obligated to do so. If you do not wish to do so, delete
+#    this exception statement from your version. If you delete this exception
+#    statement from all source files in the program, then also delete it here.
+#
+
+from deluge.plugins.init import PluginInitBase
+
+class CorePlugin(PluginInitBase):
+    def __init__(self, plugin_name):
+        from core import Core as _plugin_cls
+        self._plugin_cls = _plugin_cls
+        super(CorePlugin, self).__init__(plugin_name)
+
+class GtkUIPlugin(PluginInitBase):
+    def __init__(self, plugin_name):
+        from gtkui import GtkUI as _plugin_cls
+        self._plugin_cls = _plugin_cls
+        super(GtkUIPlugin, self).__init__(plugin_name)
+
+class WebUIPlugin(PluginInitBase):
+    def __init__(self, plugin_name):
+        from webui import WebUI as _plugin_cls
+        self._plugin_cls = _plugin_cls
+        super(WebUIPlugin, self).__init__(plugin_name)

Added: trunk/deluge/plugins/scheduler/scheduler/common.py
===================================================================
--- trunk/deluge/plugins/scheduler/scheduler/common.py                          
(rev 0)
+++ trunk/deluge/plugins/scheduler/scheduler/common.py  2009-06-02 00:57:52 UTC 
(rev 5338)
@@ -0,0 +1,41 @@
+#
+# common.py
+#
+# Copyright (C) 2009 Andrew Resch <[email protected]>
+#
+# Basic plugin template created by:
+# Copyright (C) 2008 Martijn Voncken <[email protected]>
+# Copyright (C) 2007-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.
+#
+#    In addition, as a special exception, the copyright holders give
+#    permission to link the code of portions of this program with the OpenSSL
+#    library.
+#    You must obey the GNU General Public License in all respects for all of
+#    the code used other than OpenSSL. If you modify file(s) with this
+#    exception, you may extend this exception to your version of the file(s),
+#    but you are not obligated to do so. If you do not wish to do so, delete
+#    this exception statement from your version. If you delete this exception
+#    statement from all source files in the program, then also delete it here.
+#
+
+def get_resource(filename):
+    import pkg_resources, os
+    return pkg_resources.resource_filename("scheduler", os.path.join("data", 
filename))

Added: trunk/deluge/plugins/scheduler/scheduler/core.py
===================================================================
--- trunk/deluge/plugins/scheduler/scheduler/core.py                            
(rev 0)
+++ trunk/deluge/plugins/scheduler/scheduler/core.py    2009-06-02 00:57:52 UTC 
(rev 5338)
@@ -0,0 +1,159 @@
+#
+# core.py
+#
+# Copyright (C) 2009 Andrew Resch <[email protected]>
+#
+# Basic plugin template created by:
+# Copyright (C) 2008 Martijn Voncken <[email protected]>
+# Copyright (C) 2007-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.
+#
+#    In addition, as a special exception, the copyright holders give
+#    permission to link the code of portions of this program with the OpenSSL
+#    library.
+#    You must obey the GNU General Public License in all respects for all of
+#    the code used other than OpenSSL. If you modify file(s) with this
+#    exception, you may extend this exception to your version of the file(s),
+#    but you are not obligated to do so. If you do not wish to do so, delete
+#    this exception statement from your version. If you delete this exception
+#    statement from all source files in the program, then also delete it here.
+#
+
+import time
+
+from deluge.log import LOG as log
+from deluge.plugins.pluginbase import CorePluginBase
+import deluge.component as component
+import deluge.configmanager
+from deluge.core.rpcserver import export
+from deluge.event import DelugeEvent
+
+from twisted.internet import reactor
+
+DEFAULT_PREFS = {
+    "low_down": -1.0,
+    "low_up": -1.0,
+    "low_active": -1,
+    "button_state": [[1] * 7 for dummy in xrange(24)]
+}
+
+STATES = {
+    0: "Green",
+    1: "Yellow",
+    2: "Red"
+}
+
+class SchedulerEvent(DelugeEvent):
+    """
+    Emitted when a schedule state changes.
+    """
+    def __init__(self, colour):
+        """
+        :param colour: str, the current scheduler state
+        """
+        self._args = [colour]
+
+class Core(CorePluginBase):
+    def enable(self):
+        # Create the defaults with the core config
+        core_config = component.get("Core").config
+        DEFAULT_PREFS["low_down"] = core_config["max_download_speed"]
+        DEFAULT_PREFS["low_up"] = core_config["max_upload_speed"]
+        DEFAULT_PREFS["low_active"] = core_config["max_active_limit"]
+
+        self.config = deluge.configmanager.ConfigManager("scheduler.conf", 
DEFAULT_PREFS)
+
+        self.state = self.get_state()
+
+        # Apply the scheduling rules
+        self.do_schedule(False)
+
+        # Schedule the next do_schedule() call for on the next hour
+        now = time.localtime(time.time())
+        secs_to_next_hour = ((60 - now[4]) * 60) + (60 - now[5])
+        self.timer = reactor.callLater(secs_to_next_hour, self.do_schedule)
+
+    def disable(self):
+        try:
+            self.timer.cancel()
+        except:
+            pass
+
+    def update(self):
+        pass
+
+
+    def do_schedule(self, timer=True):
+        """
+        This is where we apply schedule rules.
+        """
+
+        state = self.get_state()
+
+        if state == "Green":
+            # This is Green (Normal) so we just make sure we've applied the
+            # global defaults
+            core_config = deluge.configmanager.ConfigManager("core.conf")
+            core_config.apply_set_functions("max_download_speed")
+            core_config.apply_set_functions("max_upload_speed")
+            core_config.apply_set_functions("max_active_limit")
+            # Resume the session if necessary
+            component.get("Core").session.resume()
+        elif state == "Yellow":
+            # This is Yellow (Slow), so use the settings provided from the user
+            session = component.get("Core").session
+            session.set_download_rate_limit(int(self.config["low_down"] * 
1024))
+            session.set_upload_rate_limit(int(self.config["low_up"] * 1024))
+            settings = session.settings()
+            settings.active_limit = self.config["low_active"]
+            session.set_settings(settings)
+            # Resume the session if necessary
+            component.get("Core").session.resume()
+        elif state == "Red":
+            # This is Red (Stop), so pause the libtorrent session
+            component.get("Core").session.pause()
+
+        if state != self.state:
+            # The state has changed since last update so we need to emit an 
event
+            self.state = state
+            component.get("EventManager").emit(SchedulerEvent(self.state))
+
+        if timer:
+            # Call this again in 1 hour
+            self.timer = reactor.callLater(3600, self.do_schedule)
+
+    @export()
+    def set_config(self, config):
+        "sets the config dictionary"
+        for key in config.keys():
+            self.config[key] = config[key]
+        self.config.save()
+        self.do_schedule(False)
+
+    @export()
+    def get_config(self):
+        "returns the config dictionary"
+        return self.config.config
+
+    @export()
+    def get_state(self):
+        now = time.localtime(time.time())
+        level = self.config["button_state"][now[3]][now[6]]
+        return STATES[level]

Added: trunk/deluge/plugins/scheduler/scheduler/data/green.png
===================================================================
(Binary files differ)


Property changes on: trunk/deluge/plugins/scheduler/scheduler/data/green.png
___________________________________________________________________
Added: svn:mime-type
   + application/octet-stream

Added: trunk/deluge/plugins/scheduler/scheduler/data/red.png
===================================================================
(Binary files differ)


Property changes on: trunk/deluge/plugins/scheduler/scheduler/data/red.png
___________________________________________________________________
Added: svn:mime-type
   + application/octet-stream

Added: trunk/deluge/plugins/scheduler/scheduler/data/yellow.png
===================================================================
(Binary files differ)


Property changes on: trunk/deluge/plugins/scheduler/scheduler/data/yellow.png
___________________________________________________________________
Added: svn:mime-type
   + application/octet-stream

Added: trunk/deluge/plugins/scheduler/scheduler/gtkui.py
===================================================================
--- trunk/deluge/plugins/scheduler/scheduler/gtkui.py                           
(rev 0)
+++ trunk/deluge/plugins/scheduler/scheduler/gtkui.py   2009-06-02 00:57:52 UTC 
(rev 5338)
@@ -0,0 +1,270 @@
+#
+# gtkui.py
+#
+# Copyright (C) 2009 Andrew Resch <[email protected]>
+#
+# Basic plugin template created by:
+# Copyright (C) 2008 Martijn Voncken <[email protected]>
+# Copyright (C) 2007-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.
+#
+#    In addition, as a special exception, the copyright holders give
+#    permission to link the code of portions of this program with the OpenSSL
+#    library.
+#    You must obey the GNU General Public License in all respects for all of
+#    the code used other than OpenSSL. If you modify file(s) with this
+#    exception, you may extend this exception to your version of the file(s),
+#    but you are not obligated to do so. If you do not wish to do so, delete
+#    this exception statement from your version. If you delete this exception
+#    statement from all source files in the program, then also delete it here.
+#
+
+import gtk
+
+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
+
+from common import get_resource
+
+DAYS = ["Mon", "Tue", "Wed", "Thu", "Fri", "Sat", "Sun"]
+
+class SchedulerSelectWidget(gtk.DrawingArea):
+    def __init__(self, hover):
+        gtk.DrawingArea.__init__(self)
+        self.set_events(gtk.gdk.BUTTON_PRESS_MASK | 
gtk.gdk.BUTTON_RELEASE_MASK | gtk.gdk.POINTER_MOTION_MASK | 
gtk.gdk.LEAVE_NOTIFY_MASK)
+
+        self.connect("expose_event", self.expose)
+        self.connect("button_press_event", self.mouse_down)
+        self.connect("button_release_event", self.mouse_up)
+        self.connect("motion_notify_event", self.mouse_hover)
+        self.connect("leave_notify_event", self.mouse_leave)
+
+        self.colors = [[115.0/255, 210.0/255, 22.0/255], [237.0/255, 
212.0/255, 0.0/255], [204.0/255, 0.0/255, 0.0/255]]
+        self.button_state = [[0] * 7 for dummy in xrange(24)]
+
+        self.start_point = [0,0]
+        self.hover_point = [-1,-1]
+        self.hover_label = hover
+        self.hover_days = DAYS
+        self.mouse_press = False
+        self.set_size_request(350,150)
+
+    def set_button_state(self, state):
+        self.button_state = []
+        for s in state:
+            self.button_state.append(list(s))
+        log.debug(self.button_state)
+
+    #redraw the whole thing
+    def expose(self, widget, event):
+        self.context = self.window.cairo_create()
+        self.context.rectangle(event.area.x, event.area.y, event.area.width, 
event.area.height)
+        self.context.clip()
+
+        width = self.window.get_size()[0]
+        height = self.window.get_size()[1]
+
+        for y in xrange(7):
+            for x in xrange(24):
+                
self.context.set_source_rgba(self.colors[self.button_state[x][y]][0], 
self.colors[self.button_state[x][y]][1], 
self.colors[self.button_state[x][y]][2], 0.7)
+                self.context.rectangle(width*(6*x/145.0+1/145.0), 
height*(6*y/43.0+1/43.0), 5*width/145.0, 5*height/43.0)
+                self.context.fill_preserve()
+                self.context.set_source_rgba(0.5, 0.5, 0.5, 0.5)
+                self.context.stroke()
+
+    #coordinates --> which box
+    def get_point(self, event):
+        size = self.window.get_size()
+        x = int((event.x-size[0]*0.5/145.0)/(6*size[0]/145.0))
+        y = int((event.y-size[1]*0.5/43.0)/(6*size[1]/43.0))
+
+        if x > 23: x = 23
+        elif x < 0: x = 0
+        if y > 6: y = 6
+        elif y < 0: y = 0
+
+        return [x,y]
+
+    #mouse down
+    def mouse_down(self, widget, event):
+        self.mouse_press = True
+        self.start_point = self.get_point(event)
+
+    #if the same box -> change it
+    def mouse_up(self, widget, event):
+        self.mouse_press = False
+        end_point = self.get_point(event)
+
+        #change color on mouseclick depending on the button
+        if end_point[0] is self.start_point[0] and end_point[1] is 
self.start_point[1]:
+            if event.button == 1:
+                self.button_state[end_point[0]][end_point[1]] += 1
+                if self.button_state[end_point[0]][end_point[1]] > 2:
+                    self.button_state[end_point[0]][end_point[1]] = 0
+            elif event.button == 3:
+                self.button_state[end_point[0]][end_point[1]] -= 1
+                if self.button_state[end_point[0]][end_point[1]] < 0:
+                    self.button_state[end_point[0]][end_point[1]] = 2
+            self.queue_draw()
+
+    #if box changed and mouse is pressed draw all boxes from start point to 
end point
+    #set hover text etc..
+    def mouse_hover(self, widget, event):
+        if self.get_point(event) != self.hover_point:
+            self.hover_point = self.get_point(event)
+
+            self.hover_label.set_text(self.hover_days[self.hover_point[1]] + " 
" + str(self.hover_point[0]) + ":00 - " + str(self.hover_point[0]) + ":59")
+
+            if self.mouse_press == True:
+                points = [[self.hover_point[0], self.start_point[0]], 
[self.hover_point[1], self.start_point[1]]]
+
+                for x in xrange(min(points[0]), max(points[0])+1):
+                    for y in xrange(min(points[1]), max(points[1])+1):
+                        self.button_state[x][y] = 
self.button_state[self.start_point[0]][self.start_point[1]]
+
+                self.queue_draw()
+
+    #clear hover text on mouse leave
+    def mouse_leave(self, widget, event):
+        self.hover_label.set_text("")
+        self.hover_point = [-1,-1]
+
+class GtkUI(GtkPluginBase):
+    def enable(self):
+        self.create_prefs_page()
+
+        component.get("PluginManager").register_hook("on_apply_prefs", 
self.on_apply_prefs)
+        component.get("PluginManager").register_hook("on_show_prefs", 
self.on_show_prefs)
+
+        self.status_item = component.get("StatusBar").add_item(
+            image=get_resource("green.png"),
+            text="",
+            callback=self.on_status_item_clicked,
+            tooltip="Scheduler")
+
+        def on_get_state(state):
+            self.status_item.set_image_from_file(get_resource(state.lower() + 
".png"))
+
+        self.state_deferred = 
client.scheduler.get_state().addCallback(on_get_state)
+        client.register_event_handler("SchedulerEvent", 
self.on_scheduler_event)
+
+    def disable(self):
+        component.get("Preferences").remove_page("Scheduler")
+        component.get("PluginManager").deregister_hook("on_apply_prefs", 
self.on_apply_prefs)
+        component.get("PluginManager").deregister_hook("on_show_prefs", 
self.on_show_prefs)
+
+    def on_apply_prefs(self):
+        log.debug("applying prefs for Scheduler")
+        config = {}
+        config["low_down"] = self.spin_download.get_value()
+        config["low_up"] = self.spin_upload.get_value()
+        config["low_active"] = self.spin_active.get_value_as_int()
+        config["button_state"] = self.scheduler_select.button_state
+        client.scheduler.set_config(config)
+
+    def on_show_prefs(self):
+        def on_get_config(config):
+            log.debug("config: %s", config)
+            self.scheduler_select.set_button_state(config["button_state"])
+            self.spin_download.set_value(config["low_down"])
+            self.spin_upload.set_value(config["low_up"])
+            self.spin_active.set_value(config["low_active"])
+
+
+        client.scheduler.get_config().addCallback(on_get_config)
+
+    def on_scheduler_event(self, state):
+        def on_state_deferred(s):
+           self.status_item.set_image_from_file(get_resource(state.lower() + 
".png"))
+
+        self.state_deferred.addCallback(on_state_deferred)
+
+    def on_status_item_clicked(self, widget, event):
+        component.get("Preferences").show("Scheduler")
+
+    #Configuration dialog
+    def create_prefs_page(self):
+        #Select Widget
+        hover = gtk.Label()
+        self.scheduler_select = SchedulerSelectWidget(hover)
+
+        vbox = gtk.VBox(False, 5)
+        hbox = gtk.HBox(False, 5)
+        vbox_days = gtk.VBox()
+        for day in DAYS:
+            vbox_days.pack_start(gtk.Label(day))
+        hbox.pack_start(vbox_days, False, False)
+        hbox.pack_start(self.scheduler_select, True, True)
+        frame = gtk.Frame()
+        label = gtk.Label()
+        label.set_markup("<b>Schedule</b>")
+        frame.set_label_widget(label)
+        frame.set_shadow_type(gtk.SHADOW_NONE)
+        frame.add(hbox)
+
+        vbox.pack_start(frame, True, True)
+        vbox.pack_start(hover)
+
+        table = gtk.Table(3, 2)
+
+        label = gtk.Label(_("Download Limit:"))
+        label.set_alignment(0.0, 0.6)
+        table.attach(label, 0, 1, 0, 1, gtk.FILL)
+        self.spin_download = gtk.SpinButton()
+        self.spin_download.set_numeric(True)
+        self.spin_download.set_range(-1.0, 99999.0)
+        self.spin_download.set_increments(1, 10)
+        table.attach(self.spin_download, 1, 2, 0, 1, gtk.FILL)
+
+        label = gtk.Label(_("Upload Limit:"))
+        label.set_alignment(0.0, 0.6)
+        table.attach(label, 0, 1, 1, 2, gtk.FILL)
+        self.spin_upload = gtk.SpinButton()
+        self.spin_upload.set_numeric(True)
+        self.spin_upload.set_range(-1.0, 99999.0)
+        self.spin_upload.set_increments(1, 10)
+        table.attach(self.spin_upload, 1, 2, 1, 2, gtk.FILL)
+
+        label = gtk.Label(_("Active Torrents:"))
+        label.set_alignment(0.0, 0.6)
+        table.attach(label, 0, 1, 2, 3, gtk.FILL)
+        self.spin_active = gtk.SpinButton()
+        self.spin_active.set_numeric(True)
+        self.spin_active.set_range(-1, 9999)
+        self.spin_active.set_increments(1, 10)
+        table.attach(self.spin_active, 1, 2, 2, 3, gtk.FILL)
+
+        eventbox = gtk.EventBox()
+        eventbox.modify_bg(gtk.STATE_NORMAL, gtk.gdk.color_parse("#EDD400"))
+        eventbox.add(table)
+        frame = gtk.Frame()
+        label = gtk.Label()
+        label.set_markup(_("<b>Slow Settings</b>"))
+        frame.set_label_widget(label)
+        frame.modify_bg(gtk.STATE_NORMAL, gtk.gdk.color_parse("#CDB400"))
+        frame.set_border_width(2)
+        frame.add(eventbox)
+        vbox.pack_start(frame, False, False)
+
+        vbox.show_all()
+        component.get("Preferences").add_page("Scheduler", vbox)

Added: trunk/deluge/plugins/scheduler/scheduler/webui.py
===================================================================
--- trunk/deluge/plugins/scheduler/scheduler/webui.py                           
(rev 0)
+++ trunk/deluge/plugins/scheduler/scheduler/webui.py   2009-06-02 00:57:52 UTC 
(rev 5338)
@@ -0,0 +1,49 @@
+#
+# webui.py
+#
+# Copyright (C) 2009 Andrew Resch <[email protected]>
+#
+# Basic plugin template created by:
+# Copyright (C) 2008 Martijn Voncken <[email protected]>
+# Copyright (C) 2007-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.
+#
+#    In addition, as a special exception, the copyright holders give
+#    permission to link the code of portions of this program with the OpenSSL
+#    library.
+#    You must obey the GNU General Public License in all respects for all of
+#    the code used other than OpenSSL. If you modify file(s) with this
+#    exception, you may extend this exception to your version of the file(s),
+#    but you are not obligated to do so. If you do not wish to do so, delete
+#    this exception statement from your version. If you delete this exception
+#    statement from all source files in the program, then also delete it here.
+#
+
+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):
+        pass
+
+    def disable(self):
+        pass

Added: trunk/deluge/plugins/scheduler/setup.py
===================================================================
--- trunk/deluge/plugins/scheduler/setup.py                             (rev 0)
+++ trunk/deluge/plugins/scheduler/setup.py     2009-06-02 00:57:52 UTC (rev 
5338)
@@ -0,0 +1,72 @@
+#
+# setup.py
+#
+# Copyright (C) 2009 Andrew Resch <[email protected]>
+#
+# Basic plugin template created by:
+# Copyright (C) 2008 Martijn Voncken <[email protected]>
+# Copyright (C) 2007-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.
+#
+#    In addition, as a special exception, the copyright holders give
+#    permission to link the code of portions of this program with the OpenSSL
+#    library.
+#    You must obey the GNU General Public License in all respects for all of
+#    the code used other than OpenSSL. If you modify file(s) with this
+#    exception, you may extend this exception to your version of the file(s),
+#    but you are not obligated to do so. If you do not wish to do so, delete
+#    this exception statement from your version. If you delete this exception
+#    statement from all source files in the program, then also delete it here.
+#
+
+from setuptools import setup
+
+__plugin_name__ = "Scheduler"
+__author__ = "Andrew Resch"
+__author_email__ = "[email protected]"
+__version__ = "0.1"
+__url__ = "http://deluge-torrent.org";
+__license__ = "GPLv3"
+__description__ = "Schedule limits on a per-hour per-day basis."
+__long_description__ = """"""
+__pkg_data__ = {__plugin_name__.lower(): ["template/*", "data/*"]}
+
+setup(
+    name=__plugin_name__,
+    version=__version__,
+    description=__description__,
+    author=__author__,
+    author_email=__author_email__,
+    url=__url__,
+    license=__license__,
+    long_description=__long_description__ if __long_description__ else 
__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