mirror of
https://github.com/codex-storage/deluge.git
synced 2025-02-23 00:28:21 +00:00
Add Scheduler plugin
This commit is contained in:
parent
c4782e91f0
commit
54af19f249
57
deluge/plugins/scheduler/scheduler/__init__.py
Normal file
57
deluge/plugins/scheduler/scheduler/__init__.py
Normal file
@ -0,0 +1,57 @@
|
||||
#
|
||||
# __init__.py
|
||||
#
|
||||
# Copyright (C) 2009 Andrew Resch <andrewresch@gmail.com>
|
||||
#
|
||||
# Basic plugin template created by:
|
||||
# Copyright (C) 2008 Martijn Voncken <mvoncken@gmail.com>
|
||||
# Copyright (C) 2007-2009 Andrew Resch <andrewresch@gmail.com>
|
||||
#
|
||||
# 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)
|
41
deluge/plugins/scheduler/scheduler/common.py
Normal file
41
deluge/plugins/scheduler/scheduler/common.py
Normal file
@ -0,0 +1,41 @@
|
||||
#
|
||||
# common.py
|
||||
#
|
||||
# Copyright (C) 2009 Andrew Resch <andrewresch@gmail.com>
|
||||
#
|
||||
# Basic plugin template created by:
|
||||
# Copyright (C) 2008 Martijn Voncken <mvoncken@gmail.com>
|
||||
# Copyright (C) 2007-2009 Andrew Resch <andrewresch@gmail.com>
|
||||
#
|
||||
# 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))
|
159
deluge/plugins/scheduler/scheduler/core.py
Normal file
159
deluge/plugins/scheduler/scheduler/core.py
Normal file
@ -0,0 +1,159 @@
|
||||
#
|
||||
# core.py
|
||||
#
|
||||
# Copyright (C) 2009 Andrew Resch <andrewresch@gmail.com>
|
||||
#
|
||||
# Basic plugin template created by:
|
||||
# Copyright (C) 2008 Martijn Voncken <mvoncken@gmail.com>
|
||||
# Copyright (C) 2007-2009 Andrew Resch <andrewresch@gmail.com>
|
||||
#
|
||||
# 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]
|
BIN
deluge/plugins/scheduler/scheduler/data/green.png
Normal file
BIN
deluge/plugins/scheduler/scheduler/data/green.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 792 B |
BIN
deluge/plugins/scheduler/scheduler/data/red.png
Normal file
BIN
deluge/plugins/scheduler/scheduler/data/red.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 759 B |
BIN
deluge/plugins/scheduler/scheduler/data/yellow.png
Normal file
BIN
deluge/plugins/scheduler/scheduler/data/yellow.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 770 B |
270
deluge/plugins/scheduler/scheduler/gtkui.py
Normal file
270
deluge/plugins/scheduler/scheduler/gtkui.py
Normal file
@ -0,0 +1,270 @@
|
||||
#
|
||||
# gtkui.py
|
||||
#
|
||||
# Copyright (C) 2009 Andrew Resch <andrewresch@gmail.com>
|
||||
#
|
||||
# Basic plugin template created by:
|
||||
# Copyright (C) 2008 Martijn Voncken <mvoncken@gmail.com>
|
||||
# Copyright (C) 2007-2009 Andrew Resch <andrewresch@gmail.com>
|
||||
#
|
||||
# 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)
|
49
deluge/plugins/scheduler/scheduler/webui.py
Normal file
49
deluge/plugins/scheduler/scheduler/webui.py
Normal file
@ -0,0 +1,49 @@
|
||||
#
|
||||
# webui.py
|
||||
#
|
||||
# Copyright (C) 2009 Andrew Resch <andrewresch@gmail.com>
|
||||
#
|
||||
# Basic plugin template created by:
|
||||
# Copyright (C) 2008 Martijn Voncken <mvoncken@gmail.com>
|
||||
# Copyright (C) 2007-2009 Andrew Resch <andrewresch@gmail.com>
|
||||
#
|
||||
# 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
|
72
deluge/plugins/scheduler/setup.py
Normal file
72
deluge/plugins/scheduler/setup.py
Normal file
@ -0,0 +1,72 @@
|
||||
#
|
||||
# setup.py
|
||||
#
|
||||
# Copyright (C) 2009 Andrew Resch <andrewresch@gmail.com>
|
||||
#
|
||||
# Basic plugin template created by:
|
||||
# Copyright (C) 2008 Martijn Voncken <mvoncken@gmail.com>
|
||||
# Copyright (C) 2007-2009 Andrew Resch <andrewresch@gmail.com>
|
||||
#
|
||||
# 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__ = "andrewresch@gmail.com"
|
||||
__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)
|
||||
)
|
Loading…
x
Reference in New Issue
Block a user