diff --git a/plugins/Scheduler/plugin.py b/plugins/Scheduler/plugin.py index 53e76032d..4660b21b9 100644 --- a/plugins/Scheduler/plugin.py +++ b/plugins/Scheduler/plugin.py @@ -1,255 +1,273 @@ -import deluge.common, deluge.pref, gtk, copy, pickle, time +import deluge.common +import deluge.pref +import gtk +import copy +import time class plugin_Scheduler: - def __init__(self, path, deluge_core, deluge_interface): - self.path = path - self.core = deluge_core - self.interface = deluge_interface + def __init__(self, path, deluge_core, deluge_interface): + self.path = path + self.core = deluge_core + self.interface = deluge_interface + self.config = deluge.pref.Preferences() - self.days = [_("Mon"), _("Tue"), _("Wed"), _("Thu"), _("Fri"), _("Sat"), _("Sun")] - self.conf_file = deluge.common.CONFIG_DIR + "/scheduler.conf" - self.config = deluge.pref.Preferences() - self.button_state_temp = [[0] * 7 for dummy in xrange(24)] - self.status = -1 - - self.toolbutton_image = gtk.Image() - filename = self.path + "/scheduler.png" - self.toolbutton_image.set_from_file(filename) - - self.toolbutton = gtk.ToolButton(self.toolbutton_image, _("Scheduler")) - self.toolbutton_tip = gtk.Tooltips() - self.toolbutton.set_tooltip(self.toolbutton_tip, _("Scheduler")) - self.toolbutton.connect("clicked", self.configure) - self.interface.toolbar.insert(self.toolbutton, -1) - self.toolbutton.show_all() + self.days = [_("Mon"), _("Tue"), _("Wed"), _("Thu"), _("Fri"), _("Sat"), _("Sun")] + self.config_file = deluge.common.CONFIG_DIR + "/scheduler.conf" + self.status = -1 - #Load config - try: - reader = open(self.conf_file, "rb") - data = pickle.load(reader) - self.button_state = data[0] - self.dllimit = float(data[1][0]) - self.ullimit = float(data[1][1]) - reader.close() - except: - self.button_state = [[0] * 7 for dummy in xrange(24)] - self.dllimit = float(-1) - self.ullimit = float(-1) + #Load config + try: + self.config.load(self.config_file) - def unload(self): - self.interface.toolbar.remove(self.toolbutton) - self.resume() - self.unlimit() + self.status_table = self.config.get("scheduler_table") + self.dllimit = self.config.get("scheduler_dl_limit") + self.ullimit = self.config.get("scheduler_ul_limit") + except: + self.status_table = [[0] * 7 for dummy in xrange(24)] + self.dllimit = self.ullimit = -1 - def update(self): - time_now = time.localtime(time.time()) - - if self.status is not self.button_state[time_now[3]][time_now[6]]: - self.status = self.button_state[time_now[3]][time_now[6]] + #remove speed limitations und unpause all torrents that were running before + def unload(self): + pass - if self.status == 0: - self.resume() - self.unlimit() - elif self.status == 1: - self.resume() - elif self.status == 2: - self.pause() + def update(self): + time_now = time.localtime(time.time()) - if self.status == 1: - self.limit() + if self.status != self.status_table[time_now[3]][time_now[6]]: + self.status = self.status_table[time_now[3]][time_now[6]] + if self.status == 0: + print "[Scheduler] Normal" + elif self.status == 1: + print "[Scheduler] Limited (Down: " + str(self.dllimit/1024) + " Up: " + str(self.ullimit/1024) + ")" + elif self.status == 2: + print "[Scheduler] Paused" + #gets called one time after statuschange - def pause(self): - self.config.set("max_active_torrents", 0) - self.core.apply_queue() + #call stuff here every sec - def resume(self): - self.config.set("max_active_torrents", -1) - self.core.apply_queue() + #Configuration dialog + def configure(self): + global scheduler_select - def limit(self): - self.config.set("max_download_speed", float(self.dllimit)) - self.config.set("max_upload_speed", float(self.ullimit)) + #dialog + dialog = gtk.Dialog(_("Scheduler Settings"),self.interface.window) + dialog.set_default_size(600, 271) + dialog.set_icon_from_file(self.path + "/scheduler.png") - def unlimit(self): - self.interface.apply_prefs() + #buttons + cancel_button = dialog.add_button(gtk.STOCK_CANCEL, gtk.RESPONSE_CANCEL) + ok_button = dialog.add_button(gtk.STOCK_OK, gtk.RESPONSE_OK) + + #text + hover_text = gtk.Label() - #Configuration dialog - def configure(self, widget=None, data=None): - global scheduler_select + dllimit_label = gtk.Label(_("Limited Download Speed (KiB/s):")) + ullimit_label = gtk.Label(_("Limited Upload Speed (KiB/s):")) - self.button_state_temp = copy.deepcopy(self.button_state) + #Select Widget + drawing = scheduler_select(self.status_table, hover_text, self.days) - #dialog - dialog = gtk.Dialog(_("Scheduler Settings")) - dialog.set_default_size(600, 270) + #boxes + vbox_main = gtk.VBox() + hbox_main = gtk.HBox() + vbox_sub = gtk.VBox() + hbox_limit = gtk.HBox() - #buttons - cancel_button = dialog.add_button(gtk.STOCK_CANCEL, gtk.RESPONSE_CANCEL) - ok_button = dialog.add_button(gtk.STOCK_OK, gtk.RESPONSE_OK) - - #text - hover_text = gtk.Label() + #seperator + sep = gtk.HSeparator() - dllimit_label = gtk.Label(_("Limit download to:")) - ullimit_label = gtk.Label(_("Limit upload to:")) + #spinbuttons - #Select Widget - drawing = scheduler_select(self.button_state_temp, hover_text, self.days) + dlinput = gtk.SpinButton() + dlinput.set_numeric(True) + dlinput.set_range(-1, 2048) + dlinput.set_increments(1, 10) + if self.dllimit != -1: + dlinput.set_value(self.dllimit/1024) + else: + dlinput.set_value(self.dllimit) - #boxes - vbox_main = gtk.VBox() - hbox_main = gtk.HBox() - vbox_sub = gtk.VBox() - hbox_limit = gtk.HBox() + ulinput = gtk.SpinButton() + ulinput.set_numeric(True) + ulinput.set_range(-1, 1024) + ulinput.set_increments(1, 10) + if self.ullimit != -1: + ulinput.set_value(self.ullimit/1024) + else: + ulinput.set_value(self.ullimit) - #seperator - sep = gtk.HSeparator() + #pack + dialog.vbox.pack_start(vbox_main) - #spinbuttons + vbox_main.pack_start(hbox_main) + vbox_main.pack_start(hover_text, False, True, 5) + vbox_main.pack_start(sep, False, True) + vbox_main.pack_start(hbox_limit, False, True, 5) - dlinput = gtk.SpinButton() - dlinput.set_numeric(True) - dlinput.set_range(-1, 2048) - dlinput.set_increments(1, 10) - dlinput.set_value(float(self.dllimit)) + hbox_main.pack_start(vbox_sub, False, True, 5) + hbox_main.pack_start(drawing) - ulinput = gtk.SpinButton() - ulinput.set_numeric(True) - ulinput.set_range(-1, 1024) - ulinput.set_increments(1, 10) - ulinput.set_value(float(self.ullimit)) + hbox_limit.pack_start(dllimit_label, True, False) + hbox_limit.pack_start(dlinput, True, False) + hbox_limit.pack_start(ullimit_label, True, False) + hbox_limit.pack_start(ulinput, True, False) - #pack - dialog.vbox.pack_start(vbox_main) + #write weekdays + for index in xrange(len(self.days)): + vbox_sub.pack_start(gtk.Label(self.days[index])) - vbox_main.pack_start(hbox_main) - vbox_main.pack_start(hover_text, False, True, 5) - vbox_main.pack_start(sep, False, True) - vbox_main.pack_start(hbox_limit, False, True, 5) + #show + dialog.show_all() - hbox_main.pack_start(vbox_sub, False, True, 5) - hbox_main.pack_start(drawing) + #Save config + if dialog.run() == -5: + self.status_table = copy.deepcopy(drawing.status_table) + self.status = -1 - hbox_limit.pack_start(dllimit_label, True, False) - hbox_limit.pack_start(dlinput, True, False) - hbox_limit.pack_start(ullimit_label, True, False) - hbox_limit.pack_start(ulinput, True, False) + self.dllimit = int(dlinput.get_value()) + if self.dllimit != -1: + self.dllimit *= 1024 - for index in xrange(len(self.days)): - vbox_sub.pack_start(gtk.Label(self.days[index])) + self.ullimit = int(ulinput.get_value()) + if self.ullimit != -1: + self.ullimit *= 1024 - #show - dialog.show_all() + self.config.set("scheduler_table", drawing.status_table) + self.config.set("scheduler_dl_limit", self.dllimit) + self.config.set("scheduler_ul_limit", self.ullimit) + self.config.save(self.config_file) - #Save config - if dialog.run() == -5: - self.status = -1 - self.button_state = copy.deepcopy(drawing.button_state) - self.dllimit = float(dlinput.get_value()) - self.ullimit = float(ulinput.get_value()) - self.interface.apply_prefs() - - writer = open(self.conf_file, "wb") - pickle.dump([drawing.button_state,[self.dllimit,self.ullimit]], writer) - writer.close() - - dialog.destroy() + dialog.destroy() class scheduler_select(gtk.DrawingArea): - #connect signals - varaibles - def __init__(self, data, label, days): - 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) + #connect signals - varaibles + def __init__(self, data, label, days): + 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.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 = data - self.button_state_temp = [[0] * 7 for dummy in xrange(24)] - self.start_point = [0,0] - self.hover_point = [-1,-1] - self.hover_label = label - self.hover_days = days - self.mouse_press = False + 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.modes = [_("normal"), _("limited"), _("paused")] + self.status_table = data + self.status_table_temp = copy.deepcopy(self.status_table) + self.start_point = [0, 0] + self.hover_point = [-1, -1] + self.hover_label = label + self.hover_days = days + self.mouse_is_down = False - #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() + #redraw the whole thing + def expose(self, widget, event): + self.context = self.window.cairo_create() + self.context.set_line_width(1) + 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] + 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() + for y in xrange(7): + for x in xrange(24): + self.context.set_source_rgba( + self.colors[self.status_table_temp[x][y]][0], + self.colors[self.status_table_temp[x][y]][1], + self.colors[self.status_table_temp[x][y]][2], 0.65 + ) + 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.4, 0.4, 0.4, 0.65) + 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)) + #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 + if x > 23: x = 23 + elif x < 0: x = 0 + if y > 6: y = 6 + elif y < 0: y = 0 - return [x,y] + return [x,y] - #mouse down - def mouse_down(self, widget, event): - self.mouse_press = True - self.start_point = self.get_point(event) - self.button_state_temp = copy.deepcopy(self.button_state) + #mouse down + def mouse_down(self, widget, event): + self.mouse_is_down = 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) + #if the same box -> change it + def mouse_up(self, widget, event): + self.mouse_is_down = 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) + #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.status_table_temp[end_point[0]][end_point[1]] += 1 + if self.status_table_temp[end_point[0]][end_point[1]] > 2: + self.status_table_temp[end_point[0]][end_point[1]] = 0 + elif event.button == 3: + self.status_table_temp[end_point[0]][end_point[1]] -= 1 + if self.status_table_temp[end_point[0]][end_point[1]] < 0: + self.status_table_temp[end_point[0]][end_point[1]] = 2 + self.queue_draw() - self.hover_label.set_text(self.hover_days[self.hover_point[1]] + " " + str(self.hover_point[0]) + ":00 - " + str(self.hover_point[0]) + ":59") + self.status_table = copy.deepcopy(self.status_table_temp) - if self.mouse_press == True: - self.button_state = copy.deepcopy(self.button_state_temp) + self.set_infotext(end_point[0],end_point[1]) - points = [[self.hover_point[0], self.start_point[0]], [self.hover_point[1], self.start_point[1]]] + def set_infotext(self, x, y): + self.hover_label.set_text(self.hover_days[y] + " " + str(x) + ":00 - " + + str(x) + ":59" + " (" + self.modes[self.status_table_temp[x][y]] + ")") - 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]] + def clear_infotext(self): + self.hover_label.set_text("") + + #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.queue_draw() + if self.mouse_is_down: + self.status_table_temp = copy.deepcopy(self.status_table) - #clear hover text on mouse leave - def mouse_leave(self, widget, event): - self.hover_label.set_text("") - self.hover_point = [-1,-1] + 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.status_table_temp[x][y] = self.status_table_temp[ + self.start_point[0]][self.start_point[1]] + + self.queue_draw() + + self.set_infotext(self.hover_point[0], self.hover_point[1]) + + #clear hover text on mouse leave + def mouse_leave(self, widget, event): + self.clear_infotext() + self.hover_point = [-1,-1]