diff --git a/deluge/event.py b/deluge/event.py index 9a9017762..5f1e1ea51 100644 --- a/deluge/event.py +++ b/deluge/event.py @@ -49,7 +49,8 @@ class DelugeEventMetaClass(type): """ def __init__(cls, name, bases, dct): super(DelugeEventMetaClass, cls).__init__(name, bases, dct) - known_events[name] = cls + if name != "DelugeEvent": + known_events[name] = cls class DelugeEvent(object): """ diff --git a/deluge/plugins/freespace/create_dev_link.sh b/deluge/plugins/freespace/create_dev_link.sh new file mode 100755 index 000000000..be73dcaeb --- /dev/null +++ b/deluge/plugins/freespace/create_dev_link.sh @@ -0,0 +1,7 @@ +#!/bin/bash +cd /home/vampas/projects/DelugeNotify/deluge/plugins/freespace +mkdir temp +export PYTHONPATH=./temp +python setup.py build develop --install-dir ./temp +cp ./temp/FreeSpace.egg-link .config/plugins +rm -fr ./temp diff --git a/deluge/plugins/freespace/freespace/__init__.py b/deluge/plugins/freespace/freespace/__init__.py new file mode 100644 index 000000000..7f5b5704c --- /dev/null +++ b/deluge/plugins/freespace/freespace/__init__.py @@ -0,0 +1,58 @@ +# +# __init__.py +# +# Copyright (C) 2009 Pedro Algarvio +# +# Basic plugin template created by: +# Copyright (C) 2008 Martijn Voncken +# Copyright (C) 2007-2009 Andrew Resch +# Copyright (C) 2009 Damien Churchill +# +# 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) diff --git a/deluge/plugins/freespace/freespace/common.py b/deluge/plugins/freespace/freespace/common.py new file mode 100644 index 000000000..ef27e0af8 --- /dev/null +++ b/deluge/plugins/freespace/freespace/common.py @@ -0,0 +1,42 @@ +# +# common.py +# +# Copyright (C) 2009 Pedro Algarvio +# +# Basic plugin template created by: +# Copyright (C) 2008 Martijn Voncken +# Copyright (C) 2007-2009 Andrew Resch +# Copyright (C) 2009 Damien Churchill +# +# 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("freespace", os.path.join("data", filename)) diff --git a/deluge/plugins/freespace/freespace/core.py b/deluge/plugins/freespace/freespace/core.py new file mode 100644 index 000000000..4ef054d90 --- /dev/null +++ b/deluge/plugins/freespace/freespace/core.py @@ -0,0 +1,201 @@ +# +# core.py +# +# Copyright (C) 2009 Pedro Algarvio +# +# Basic plugin template created by: +# Copyright (C) 2008 Martijn Voncken +# Copyright (C) 2007-2009 Andrew Resch +# Copyright (C) 2009 Damien Churchill +# +# 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 os, statvfs +from datetime import datetime, timedelta +from twisted.internet import task +from deluge.log import LOG as log +from deluge.plugins.pluginbase import CorePluginBase +from deluge.event import DelugeEvent +import deluge.component as component +import deluge.configmanager +from deluge.core.rpcserver import export + + +class LowDiskSpaceEvent(DelugeEvent): + """Triggered when the available space for a specific path is getting + too low. + """ + def __init__(self, percents_dict): + """ + :param percents: dictionary of path keys with their respecive + occupation percentages. + """ + self._args = [percents_dict] + +DEFAULT_PREFS = { + "enabled": False, + "percent": 90 +} + +class Core(CorePluginBase): + CLEANUP_TIMEOUT_SECS = 3600 # One hour + + def enable(self): + self.config = deluge.configmanager.ConfigManager("freespace.conf", + DEFAULT_PREFS) + self.notifications_sent = {} + + if not self._timer: + self._timer = task.LoopingCall(self.update) + else: + self._timer.stop() + self._interval = 15 #60 + if self.config['enabled']: + self._timer.start(self._interval, False) + + self._cleanup = task.LoopingCall(self.__cleanup_notifications) + self._cleanup.start(self._interval, False) + + try: + component.get("CorePlugin.Notifications"). \ + register_custom_email_notification( + "LowDiskSpaceEvent", self.__custom_email_notification + ) + except KeyError: + pass + component.get("EventManager").register_event_handler( + "PluginEnabledEvent", self.__on_plugin_enabled + ) + component.get("EventManager").register_event_handler( + "PluginDisabledEvent", self.__on_plugin_disabled + ) + + def disable(self): + try: + component.get("CorePlugin.Notifications"). \ + deregister_custom_email_notification("LowDiskSpaceEvent") + except KeyError: + pass + component.get("EventManager").deregister_event_handler( + "PluginEnabledEvent", self.__on_plugin_enabled + ) + component.get("EventManager").deregister_event_handler( + "PluginDisabledEvent", self.__on_plugin_disabled + ) + self._cleanup.stop() + + def update(self): + log.debug('\n\nUpdating %s FreeSpace', self.__class__.__name__) + nots = {} + for path in self.__gather_paths_to_check(): + log.debug("Checking path %s", path) + free_percent = self.__get_free_space(path) + if (100 - free_percent) > self.config['percent']: + if path not in self.notifications_sent: + self.notifications_sent[path] = datetime.utcnow() + nots[path] = (100 - free_percent) + else: + log.warning("Running low on disk space on %s but " + "notifications were already triggered.", path) + if nots: + component.get("EventManager").emit(LowDiskSpaceEvent(nots)) + + + @export + def set_config(self, config): + "sets the config dictionary" + if not self.config['enabled'] and config['enabled']: + self._timer.start(self._interval, False) + elif self.config['enabled'] and not config['enabled']: + self._timer.stop() + + for key in config.keys(): + self.config[key] = config[key] + self.config.save() + + @export + def get_config(self): + "returns the config dictionary" + return self.config.config + + def __gather_paths_to_check(self): + self.over_percentage = {} + torrent_manager = component.get('TorrentManager') + paths = set() + for torrent_id in torrent_manager.get_torrent_list(): + status = torrent_manager[torrent_id].get_status([ + 'is_finished', + 'move_on_completed_path', + 'save_path' + ]) + if not status['is_finished']: + paths.add(status['move_on_completed_path']) + paths.add(status['save_path']) + return paths + + def __get_free_space(self, path): + log.debug("Calculating free space on %s", path) + stat = os.statvfs(path) + free_blocks = stat[statvfs.F_BAVAIL] + total_blocks = stat[statvfs.F_BLOCKS] + free_percent = free_blocks * 100 / total_blocks + return free_percent + + def __custom_email_notification(self, ocupied_percents): + + subject = _("Low Disk Space Warning") + message = _("You're running low on disk space:\n") + + for path, ocupied_percent in ocupied_percents.iteritems(): + message += _(' %s%% ocupation in %s\n') % (ocupied_percent, path) +# "\"%s\"%% space occupation on %s") % (ocupied_percent, path) + return subject, message + + def __on_plugin_enabled(self, plugin_name): + if plugin_name == 'Notifications': + component.get("CorePlugin.Notifications"). \ + register_custom_email_notification( + "LowDiskSpaceEvent", self.__custom_email_notification + ) + + def __on_plugin_disabled(self, plugin_name): + if plugin_name == 'Notifications': + component.get("CorePlugin.Notifications"). \ + deregister_custom_email_notification("LowDiskSpaceEvent") + + def __cleanup_notifications(self): + now = datetime.now() + for path, when in self.notifications_sent.copy().iteritems(): + if when <= (now -timedelta(seconds=self.CLEANUP_TIMEOUT_SECS)): + log.debug("Removing old(%s) path from notified paths: %s", + when, path) + self.notifications_sent.pop(path) + diff --git a/deluge/plugins/freespace/freespace/data/config.glade b/deluge/plugins/freespace/freespace/data/config.glade new file mode 100644 index 000000000..15d771f5c --- /dev/null +++ b/deluge/plugins/freespace/freespace/data/config.glade @@ -0,0 +1,100 @@ + + + + + + + + True + + + True + 0 + none + + + True + 12 + + + True + vertical + + + True + + + Consider low when + True + True + False + True + + + False + 0 + + + + + True + True + 2 + + 90 0 99 1 10 0 + + + False + 5 + 1 + + + + + True + % + + + False + 2 + + + + + True + of the disk is occupied. + + + False + 5 + 3 + + + + + 0 + + + + + + + + + True + <b>Free Space Checking</b> + True + + + label_item + + + + + 0 + + + + + + diff --git a/deluge/plugins/freespace/freespace/data/freespace.js b/deluge/plugins/freespace/freespace/data/freespace.js new file mode 100644 index 000000000..745e09820 --- /dev/null +++ b/deluge/plugins/freespace/freespace/data/freespace.js @@ -0,0 +1,50 @@ +/* +Script: freespace.js + The client-side javascript code for the FreeSpace plugin. + +Copyright: + (C) Pedro Algarvio 2009 + 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. + + 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. +*/ + +FreeSpacePlugin = Ext.extend(Deluge.Plugin, { + constructor: function(config) { + config = Ext.apply({ + name: "FreeSpace" + }, config); + FreeSpacePlugin.superclass.constructor.call(this, config); + }, + + onDisable: function() { + + }, + + onEnable: function() { + + } +}); +new FreeSpacePlugin(); diff --git a/deluge/plugins/freespace/freespace/gtkui.py b/deluge/plugins/freespace/freespace/gtkui.py new file mode 100644 index 000000000..ddabf3933 --- /dev/null +++ b/deluge/plugins/freespace/freespace/gtkui.py @@ -0,0 +1,174 @@ +# +# gtkui.py +# +# Copyright (C) 2009 Pedro Algarvio +# +# Basic plugin template created by: +# Copyright (C) 2008 Martijn Voncken +# Copyright (C) 2007-2009 Andrew Resch +# Copyright (C) 2009 Damien Churchill +# +# 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 + +class GtkUI(GtkPluginBase): + + def enable(self): + log.debug('\n\nEnabling %s FreeSpace', self.__class__.__name__) + self.glade = gtk.glade.XML(get_resource("config.glade")) + self.prefs = self.glade.get_widget('prefs_box') + parent = self.prefs.get_parent() + if parent: + parent.remove(self.prefs) + +# chk_ap = component.get("Preferences").glade.get_widget('chk_add_paused') +# downloads_vbox = chk_ap.get_parent().get_parent().get_parent().get_parent() + + downloads_vbox = component.get("Preferences").glade.get_widget('vbox1') + downloads_vbox.pack_start(self.prefs, False, True, 0) +# self.prefs.set_parent(frame) + +# component.get("Preferences").add_page("FreeSpace", self.glade.get_widget("prefs_box")) + component.get("PluginManager").register_hook("on_apply_prefs", + self.on_apply_prefs) + component.get("PluginManager").register_hook("on_show_prefs", + self.on_show_prefs) + + try: + notifications = component.get("GtkPlugin.Notifications") + notifications.register_custom_popup_notification( + "LowDiskSpaceEvent", self.__custom_popup_notification + ) + notifications.register_custom_blink_notification( + "LowDiskSpaceEvent", self.__custom_blink_notification + ) + notifications.register_custom_sound_notification( + "LowDiskSpaceEvent", self.__custom_sound_notification + ) + except KeyError: + pass + + client.register_event_handler("PluginEnabledEvent", + self.__on_plugin_enabled) + + client.register_event_handler("PluginDisabledEvent", + self.__on_plugin_disabled) + + def disable(self): + component.get("Preferences").remove_page("FreeSpace") + component.get("PluginManager").deregister_hook("on_apply_prefs", + self.on_apply_prefs) + component.get("PluginManager").deregister_hook("on_show_prefs", + self.on_show_prefs) + try: + notifications = component.get("GtkPlugin.Notifications") + notifications.deregister_custom_popup_notification( + "LowDiskSpaceEvent" + ) + notifications.deregister_custom_blink_notification( + "LowDiskSpaceEvent" + ) + notifications.deregister_custom_sound_notification( + "LowDiskSpaceEvent" + ) + except KeyError: + pass + + client.deregister_event_handler("PluginEnabledEvent", + self.__on_plugin_enabled) + + client.deregister_event_handler("PluginDisabledEvent", + self.__on_plugin_disabled) + + def on_apply_prefs(self): + log.debug("applying prefs for FreeSpace") + config = { + "enabled": self.glade.get_widget('enabled').get_active(), + "percent": self.glade.get_widget('percent').get_value() + } + client.freespace.set_config(config) + + def on_show_prefs(self): + client.freespace.get_config().addCallback(self.cb_get_config) + + def cb_get_config(self, config): + "callback for on show_prefs" + self.glade.get_widget('enabled').set_active(config['enabled']) + self.glade.get_widget('percent').set_value(config['percent']) + + def __custom_popup_notification(self, ocupied_percents): + title = _("Low Free Space") + message = '' + for path, percent in ocupied_percents.iteritems(): + message += '%s%% %s\n' % (percent, path) + message += '\n' + return title, message + + def __custom_blink_notification(self, ocupied_percents): + return True # Yes, do blink + + def __custom_sound_notification(self, ocupied_percents): + return '' # Use default sound + + def __on_plugin_enabled(self, plugin_name): + if plugin_name == 'Notifications': + notifications = component.get("GtkPlugin.Notifications") + notifications.register_custom_popup_notification( + "LowDiskSpaceEvent", self.__custom_popup_notification + ) + notifications.register_custom_blink_notification( + "LowDiskSpaceEvent", self.__custom_blink_notification + ) + notifications.register_custom_sound_notification( + "LowDiskSpaceEvent", self.__custom_sound_notification + ) + + def __on_plugin_disabled(self, plugin_name): + pass +# if plugin_name == 'Notifications': +# notifications = component.get("GtkPlugin.Notifications") +# notifications.deregister_custom_popup_notification( +# "LowDiskSpaceEvent" +# ) +# notifications.deregister_custom_blink_notification( +# "LowDiskSpaceEvent" +# ) +# notifications.deregister_custom_sound_notification( +# "LowDiskSpaceEvent" +# ) diff --git a/deluge/plugins/freespace/freespace/webui.py b/deluge/plugins/freespace/freespace/webui.py new file mode 100644 index 000000000..9bee15849 --- /dev/null +++ b/deluge/plugins/freespace/freespace/webui.py @@ -0,0 +1,55 @@ +# +# webui.py +# +# Copyright (C) 2009 Pedro Algarvio +# +# Basic plugin template created by: +# Copyright (C) 2008 Martijn Voncken +# Copyright (C) 2007-2009 Andrew Resch +# Copyright (C) 2009 Damien Churchill +# +# 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 + +from common import get_resource + +class WebUI(WebPluginBase): + + scripts = [get_resource("freespace.js")] + + def enable(self): + pass + + def disable(self): + pass diff --git a/deluge/plugins/freespace/setup.py b/deluge/plugins/freespace/setup.py new file mode 100755 index 000000000..2e1843074 --- /dev/null +++ b/deluge/plugins/freespace/setup.py @@ -0,0 +1,73 @@ +# +# setup.py +# +# Copyright (C) 2009 Pedro Algarvio +# +# Basic plugin template created by: +# Copyright (C) 2008 Martijn Voncken +# Copyright (C) 2007-2009 Andrew Resch +# Copyright (C) 2009 Damien Churchill +# +# 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__ = "FreeSpace" +__author__ = "Pedro Algarvio" +__author_email__ = "ufs@ufsoft.org" +__version__ = "0.1" +__url__ = "http://deluge.ufsoft.org/hg/Notification/" +__license__ = "GPLv3" +__description__ = "" +__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) +) diff --git a/deluge/plugins/notifications/notifications/common.py b/deluge/plugins/notifications/notifications/common.py index 39735b7da..12bb27436 100644 --- a/deluge/plugins/notifications/notifications/common.py +++ b/deluge/plugins/notifications/notifications/common.py @@ -55,6 +55,8 @@ except ImportError: try: import pynotify POPUP_AVAILABLE = True + if deluge.common.windows_check(): + POPUP_AVAILABLE = False except ImportError: POPUP_AVAILABLE = False @@ -65,11 +67,10 @@ def get_resource(filename): os.path.join("data", filename)) -class CustomNotifications(component.Component): +class CustomNotifications(object): config = None # shut-up pylint def __init__(self, plugin_name=None): - component.Component.__init__(self, "Notifications") self.custom_notifications = { "email": {}, "popup": {}, @@ -133,14 +134,6 @@ class CustomNotifications(component.Component): if eventtype not in known_events: log.error("The event \"%s\" is not known" % eventtype) return False - log.debug('\n\nKLASSS %s: %s: %s', - handler.__class__, - isinstance(handler.__class__, self.__class__), - handler in dir(self)) - log.debug(dir(handler)) - log.debug(handler.im_self) - log.debug(self) - log.debug("IM SELF: %s", handler.im_self is self) if known_events[eventtype].__module__.startswith('deluge.event'): if handler.im_self is self: return True @@ -220,8 +213,15 @@ Subject: %(subject)s message = '\r\n'.join((headers + message).splitlines()) try: - server = smtplib.SMTP(self.config["smtp_host"], - self.config["smtp_port"]) + try: + # Python 2.6 + server = smtplib.SMTP(self.config["smtp_host"], + self.config["smtp_port"], + timeout=60) + except: + # Python 2.6 + server = smtplib.SMTP(self.config["smtp_host"], + self.config["smtp_port"]) except Exception, err: err_msg = _("There was an error sending the notification email:" " %s") % err diff --git a/deluge/plugins/notifications/notifications/gtkui.py b/deluge/plugins/notifications/notifications/gtkui.py index 8aa66ab75..164fe0958 100644 --- a/deluge/plugins/notifications/notifications/gtkui.py +++ b/deluge/plugins/notifications/notifications/gtkui.py @@ -202,8 +202,6 @@ class GtkUI(GtkPluginBase, GtkUiNotifications): column.set_property('visible', False) self.sounds_treeview.append_column(column) - self.sounds_treeview.connect("button-press-event", - self.on_sounds_treeview_clicked) self.sounds_treeview.set_model(self.sounds_model) def build_notifications_model_populate_treeview(self): diff --git a/deluge/ui/gtkui/glade/preferences_dialog.glade b/deluge/ui/gtkui/glade/preferences_dialog.glade index f2d3052a9..ab9e1257a 100644 --- a/deluge/ui/gtkui/glade/preferences_dialog.glade +++ b/deluge/ui/gtkui/glade/preferences_dialog.glade @@ -3922,390 +3922,6 @@ HTTP W/ Auth tab - - - True - True - automatic - automatic - - - True - queue - none - - - True - - - True - GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK - 0 - 10 - 10 - <b><i><big>Notification</big></i></b> - True - - - False - 0 - - - - - True - - - False - 1 - - - - - True - 12 - - - True - 6 - - - True - 0 - none - - - True - 5 - 12 - - - True - 3 - 2 - 5 - - - Sound: - True - True - False - Only OGG and WAV files are supported - True - True - - - 2 - 3 - GTK_FILL - - - - - Popup - True - True - False - Not available on Windows - True - True - - - 2 - 1 - 2 - GTK_FILL - - - - - Blinking tray icon - True - True - False - True - True - - - 2 - GTK_FILL - - - - - True - - - 1 - 2 - 2 - 3 - - - - - - - - - True - <b>General</b> - True - - - label_item - - - - - False - False - 5 - 0 - - - - - True - 0 - none - - - True - 5 - 12 - - - True - 6 - 2 - 5 - - - True - 0 - Security: - - - 5 - 6 - GTK_FILL - - - - - True - 5 - - - None - True - True - False - True - True - - - False - False - 0 - - - - - SSL - True - True - False - True - rad_ntf_none - - - False - False - 1 - - - - - TLS - True - True - False - True - rad_ntf_none - - - False - False - 2 - - - - - 1 - 2 - 5 - 6 - GTK_FILL - - - - - True - 0 - Password: - - - 4 - 5 - GTK_FILL - - - - - True - True - False - - - 1 - 2 - 4 - 5 - - - - - True - 0 - Username: - - - 3 - 4 - GTK_FILL - - - - - True - True - - - 1 - 2 - 3 - 4 - - - - - True - 0 - Server: - - - 2 - 3 - GTK_FILL - GTK_FILL - - - - - True - True - - - 1 - 2 - 2 - 3 - - - - - True - 0 - Address: - - - 1 - 2 - GTK_FILL - GTK_FILL - - - - - True - True - - - 1 - 2 - 1 - 2 - - - - - Enable - True - True - False - True - - - 2 - GTK_FILL - GTK_FILL - - - - - - - - - True - <b>Email</b> - True - - - label_item - - - - - False - False - 1 - - - - - - - 2 - - - - - - - - - 8 - - - - - - tab - - True @@ -4842,7 +4458,7 @@ HTTP W/ Auth - 9 + 8 @@ -4851,6 +4467,15 @@ HTTP W/ Auth tab + + + + + + + tab + + True diff --git a/deluge/ui/gtkui/preferences.py b/deluge/ui/gtkui/preferences.py index 207716916..a9c6b7a4d 100644 --- a/deluge/ui/gtkui/preferences.py +++ b/deluge/ui/gtkui/preferences.py @@ -17,9 +17,9 @@ # # 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. +# 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 @@ -464,35 +464,6 @@ class Preferences(component.Component): self.glade.get_widget("chk_show_new_releases").set_active( self.gtkui_config["show_new_releases"]) - ## Notification tab ## - self.glade.get_widget("chk_ntf_tray_blink").set_active( - self.gtkui_config["ntf_tray_blink"]) - if deluge.common.windows_check(): - self.glade.get_widget("chk_ntf_popup").set_sensitive(False) - else: - self.glade.get_widget("chk_ntf_popup").set_active( - self.gtkui_config["ntf_popup"]) - self.glade.get_widget("chk_ntf_email").set_active( - self.gtkui_config["ntf_email"]) - self.glade.get_widget("chk_ntf_sound").set_active( - self.gtkui_config["ntf_sound"]) - if self.gtkui_config["ntf_sound_path"]: - self.glade.get_widget("combo_ntf_sound_path").set_filename(self.gtkui_config["ntf_sound_path"]) - self.glade.get_widget("txt_ntf_email").set_text( - self.gtkui_config["ntf_email_add"]) - self.glade.get_widget("txt_ntf_server").set_text( - self.gtkui_config["ntf_server"]) - self.glade.get_widget("txt_ntf_username").set_text( - self.gtkui_config["ntf_username"]) - self.glade.get_widget("txt_ntf_pass").set_text( - self.gtkui_config["ntf_pass"]) - if not self.gtkui_config["ntf_security"]: - self.glade.get_widget("rad_ntf_none").set_active(True) - elif self.gtkui_config["ntf_security"] == 'SSL': - self.glade.get_widget("rad_ntf_none").set_active(True) - elif self.gtkui_config["ntf_security"] == 'TLS': - self.glade.get_widget("rad_ntf_tls").set_active(True) - ## Cache tab ## if client.connected(): self.__update_cache_status() @@ -658,32 +629,6 @@ class Preferences(component.Component): new_gtkui_config["show_rate_in_title"] = \ self.glade.get_widget("chk_show_rate_in_title").get_active() - ## Notification tab ## - new_gtkui_config["ntf_tray_blink"] = \ - self.glade.get_widget("chk_ntf_tray_blink").get_active() - new_gtkui_config["ntf_popup"] = \ - self.glade.get_widget("chk_ntf_popup").get_active() - new_gtkui_config["ntf_sound"] = \ - self.glade.get_widget("chk_ntf_sound").get_active() - new_gtkui_config["ntf_email"] = \ - self.glade.get_widget("chk_ntf_email").get_active() - new_gtkui_config["ntf_email_add"] = \ - self.glade.get_widget("txt_ntf_email").get_text() - new_gtkui_config["ntf_username"] = \ - self.glade.get_widget("txt_ntf_username").get_text() - new_gtkui_config["ntf_pass"] = \ - self.glade.get_widget("txt_ntf_pass").get_text() - new_gtkui_config["ntf_server"] = \ - self.glade.get_widget("txt_ntf_server").get_text() - new_gtkui_config["ntf_sound_path"] = \ - self.glade.get_widget("combo_ntf_sound_path").get_filename() - if self.glade.get_widget("rad_ntf_none").get_active(): - new_gtkui_config["ntf_security"] = None - elif self.glade.get_widget("rad_ntf_ssl").get_active(): - new_gtkui_config["ntf_security"] = 'SSL' - elif self.glade.get_widget("rad_ntf_tls").get_active(): - new_gtkui_config["ntf_security"] = 'TLS' - ## Other tab ## new_gtkui_config["show_new_releases"] = \ self.glade.get_widget("chk_show_new_releases").get_active()