From 535940e2e6e19c3d9ad2825196e7f03a5da9ca41 Mon Sep 17 00:00:00 2001 From: Pedro Algarvio Date: Sun, 22 Nov 2009 02:34:35 +0000 Subject: [PATCH] Notifications(email, blink, popup, sound) are working both for classic mode and daemon mode. Still need some further tests for using `component.get('Notifications').notify*()`. --- .../notifications/notifications/core.py | 75 ++++++++++++----- .../notifications/notifications/gtkui.py | 83 ++++++++++++++----- .../notifications/notifications/manager.py | 72 +++------------- 3 files changed, 128 insertions(+), 102 deletions(-) diff --git a/deluge/plugins/notifications/notifications/core.py b/deluge/plugins/notifications/notifications/core.py index 5280b7246..9a1e09359 100644 --- a/deluge/plugins/notifications/notifications/core.py +++ b/deluge/plugins/notifications/notifications/core.py @@ -122,27 +122,31 @@ class Core(CorePluginBase, Notifications): def notify_flash(self, title='', message=''): if not self.config["flash_enabled"]: return defer.succeed("Flash notification not enabled") - return defer.maybeDeferred( - component.get("EventManager").emit, - events.NotificationFlashEvent(title, message) - ) + d = defer.maybeDeferred(component.get("EventManager").emit, + events.NotificationFlashEvent(title, message)) + d.addCallback(self._on_notify_event_sucess, 'flash') + d.addErrback(self._on_notify_event_failure, 'flash') + return d @export def notify_popup(self, title='', message=''): if not self.config["popup_enabled"]: return defer.succeed("Popup notification not enabled") - return defer.maybeDeferred( - component.get("EventManager").emit, - events.NotificationPopupEvent(title, message) - ) + d = defer.maybeDeferred(component.get("EventManager").emit, + events.NotificationPopupEvent(title, message)) + d.addCallback(self._on_notify_event_sucess, 'popup') + d.addErrback(self._on_notify_event_failure, 'popup') + return d @export def notify_sound(self, sound_path=''): if not self.config["sound_enabled"]: return defer.succeed("Sound notification not enabled") - return defer.maybeDeferred( - component.get("EventManager").emit, - events.NotificationSoundEvent(sound_path)) + d = defer.maybeDeferred(component.get("EventManager").emit, + events.NotificationSoundEvent(sound_path)) + d.addCallback(self._on_notify_event_sucess, 'sound') + d.addErrback(self._on_notify_event_failure, 'sound') + return d def _notify_email(self, title='', message='', smtp_from='', recipients=[]): config = self.config @@ -162,8 +166,10 @@ Subject: %(title)s try: server = smtplib.SMTP(config["smtp_host"], config["smtp_port"]) except Exception, err: - log.error("There was an error sending the notification email: %s", - err) + err_msg = _("There was an error sending the notification email:" + " %s") % err + log.error(err_msg) + raise err security_enabled = config['smtp_tls'] @@ -178,19 +184,25 @@ Subject: %(title)s if config['smtp_user'] and config['smtp_pass']: try: server.login(config['smtp_user'], config['smtp_pass']) - except smtplib.SMTPHeloError: - log.warning("The server didn't reply properly to the helo " - "greeting") - except smtplib.SMTPAuthenticationError: - log.warning("The server didn't accept the username/password " - "combination") + except smtplib.SMTPHeloError, err: + err_msg = _("The server didn't reply properly to the helo " + "greeting: %s") % err + log.error(err_msg) + raise err + except smtplib.SMTPAuthenticationError, err: + err_msg = _("The server didn't accept the username/password " + "combination: %s") % err + log.error(err_msg) + raise err try: try: server.sendmail(config['smtp_from'], to_addrs, message) except smtplib.SMTPException, err: - log.error("There was an error sending the notification email: " - "%s", err) + err_msg = _("There was an error sending the notification email:" + " %s") % err + log.error(err_msg) + raise err finally: if security_enabled: # avoid false failure detection when the server closes @@ -202,4 +214,23 @@ Subject: %(title)s pass else: server.quit() - return "Notification email sent." + return _("Notification email sent.") + + def _on_torrent_finished_event(self, torrent_id): + log.debug("\n\nhandler for TorrentFinishedEvent called for CORE") + torrent = component.get("TorrentManager")[torrent_id] + torrent_status = torrent.get_status({}) + # Email + title = _("Finished Torrent \"%(name)s\"") % torrent_status + message = _( + "This email is to inform you that Deluge has finished " + "downloading \"%(name)s\", which includes %(num_files)i files." + "\nTo stop receiving these alerts, simply turn off email " + "notification in Deluge's preferences.\n\n" + "Thank you,\nDeluge." + ) % torrent_status + + d = defer.maybeDeferred(self.notify_email, title, message) + d.addCallback(self._on_notify_sucess, 'email') + d.addErrback(self._on_notify_failure, 'email') + log.debug("Email notification callback yielded") diff --git a/deluge/plugins/notifications/notifications/gtkui.py b/deluge/plugins/notifications/notifications/gtkui.py index 9d21b02bf..8fdbdde0f 100644 --- a/deluge/plugins/notifications/notifications/gtkui.py +++ b/deluge/plugins/notifications/notifications/gtkui.py @@ -54,9 +54,9 @@ except ImportError: try: import pynotify - POPUP_ENABLED = True + POPUP_AVAILABLE = True except ImportError: - POPUP_ENABLED = False + POPUP_AVAILABLE = False # Relative imports from common import get_resource @@ -103,7 +103,7 @@ class GtkUI(GtkPluginBase, Notifications): component.get("PluginManager").register_hook("on_show_prefs", self.on_show_prefs) - if not POPUP_ENABLED: + if not POPUP_AVAILABLE: self.glade.get_widget("popup_enabled").set_property('sensitive', False) else: @@ -121,6 +121,9 @@ class GtkUI(GtkPluginBase, Notifications): else: client.register_event_handler("NotificationSoundEvent", self.notify_sound) + + client.register_event_handler("TorrentFinishedEvent", + self._on_torrent_finished_event) # Force config populate client.notifications.get_config().addCallback(self.cb_get_config) @@ -235,19 +238,27 @@ class GtkUI(GtkPluginBase, Notifications): self.glade.get_widget('sound_path').set_property('sensitive', False) def notify_blink(self): - return defer.maybeDeferred(self.tray.blink, True) + defer.maybeDeferred(self.tray.blink, True) + return defer.succeed("blink notification shown.") def notify_email(self, title='', message='', smtp_from='', recipients=[]): - client.notifications.notify_email(title, message, smtp_from, recipients) + d = client.notifications.notify_email(title, message, smtp_from, + recipients) + d.addCallback(self._on_notify_sucess, "email") + d.addCallback(self._on_notify_failure, "email") + return d def notify_flash(self, title='', message=''): - client.notifications.notify_flash(title, message) + d = client.notifications.notify_flash(title, message) + d.addCallback(self._on_notify_sucess, "flash") + d.addCallback(self._on_notify_failure, "flash") + return d def notify_popup(self, title='', message=''): if not self.config['popup_enabled']: - return defer.succeed("Popup notification is not enabled.") - if not POPUP_ENABLED: - return defer.fail("pynotify is not installed") + return defer.succeed(_("Popup notification is not enabled.")) + if not POPUP_AVAILABLE: + return defer.fail(_("pynotify is not installed")) if pynotify.init("Deluge"): icon = gtk.gdk.pixbuf_new_from_file_at_size( @@ -255,16 +266,18 @@ class GtkUI(GtkPluginBase, Notifications): self.note = pynotify.Notification(title, message) self.note.set_icon_from_pixbuf(icon) if not self.note.show(): - log.warning("pynotify failed to show notification") - return defer.fail("pynotify failed to show notification") - return defer.succeed("Notification popup shown") + err_msg = _("pynotify failed to show notification") + log.warning(err_msg) + return defer.fail(err_msg) + return defer.succeed(_("Notification popup shown")) def notify_sound(self, sound_path=''): if not self.config['sound_enabled']: - return defer.succeed("Sound notification not enabled") + return defer.succeed(_("Sound notification not enabled")) if not SOUND_AVAILABLE: - log.warning("pygame is not installed") - return defer.fail("pygame is not installed") + err_msg = _("pygame is not installed") + log.warning(err_msg) + return defer.fail(err_msg) pygame.init() try: @@ -274,9 +287,41 @@ class GtkUI(GtkPluginBase, Notifications): alert_sound.load(sound_path) alert_sound.play() except pygame.error, message: - log.warning("pygame failed to play because %s" % (message)) - return defer.fail("Sound notification failed %s" % (message)) + err_msg = _("Sound notification failed %s") % (message) + log.warning(err_msg) + return defer.fail(err_msg) else: - log.info("sound notification played successfully") - return defer.succeed("Sound notification Success") + msg = _("Sound notification Success") + log.info(msg) + return defer.succeed(msg) + + def _on_torrent_finished_event(self, torrent_id): + log.debug("\n\nhandler for TorrentFinishedEvent GTKUI called") + # Blink + d0 = defer.maybeDeferred(self.notify_blink) + d0.addCallback(self._on_notify_sucess, 'blink') + d0.addErrback(self._on_notify_failure, 'blink') + log.debug("Blink notification callback yielded") + # Sound + d1 = defer.maybeDeferred(self.notify_sound) + d1.addCallback(self._on_notify_sucess, 'sound') + d1.addErrback(self._on_notify_failure, 'sound') + log.debug("Sound notification callback yielded") + # Popup + d2 = client.core.get_torrent_status(torrent_id, ["name", "num_files"]) + d2.addCallback(self._on_torrent_finished_event_got_torrent_status) + d2.addErrback(self._on_torrent_finished_event_torrent_status_failure) + + def _on_torrent_finished_event_torrent_status_failure(self, failure): + log.debug("Failed to get torrent status to be able to show the popup") + + def _on_torrent_finished_event_got_torrent_status(self, torrent_status): + log.debug("\n\nhandler for TorrentFinishedEvent GTKUI called. Torrent Status") + title = _("Finished Torrent") + message = _("The torrent \"%(name)s\" including %(num_files)i " + "has finished downloading.") % torrent_status + d2 = defer.maybeDeferred(self.notify_popup, title, message) + d2.addCallback(self._on_notify_sucess, 'popup') + d2.addErrback(self._on_notify_failure, 'popup') + log.debug("Popup notification callback yielded") diff --git a/deluge/plugins/notifications/notifications/manager.py b/deluge/plugins/notifications/notifications/manager.py index b95658d01..2ea41c966 100644 --- a/deluge/plugins/notifications/notifications/manager.py +++ b/deluge/plugins/notifications/notifications/manager.py @@ -34,12 +34,8 @@ # -from twisted.internet import defer, threads from deluge import component -from deluge.core.rpcserver import export from deluge.log import LOG as log -from deluge.ui.client import client - class Notifications(component.Component): def __init__(self, name): @@ -87,63 +83,17 @@ class Notifications(component.Component): self.notify_sound(sound_path) def _on_notify_sucess(self, result, kind): - log.debug("Notification success using %s: %s", kind, result) + log.debug("\n\nNotification success using %s: %s", kind, result) + return result def _on_notify_failure(self, failure, kind): - log.debug("Notification failure using %s: %s", kind, failure) + log.debug("\n\nNotification failure using %s: %s", kind, failure) + return failure -# def _on_torrent_finished_event(self, torrent_id): -# log.debug("\n\nhandler for TorrentFinishedEvent called") -# torrent = component.get("TorrentManager")[torrent_id] -# torrent_status = torrent.get_status({}) -# # Email -# title = _("Finished Torrent %(name)s") % torrent_status -# message = _( -# "This email is to inform you that Deluge has finished " -# "downloading \"%(name)s\", which includes %(num_files)i files." -# "\nTo stop receiving these alerts, simply turn off email " -# "notification in Deluge's preferences.\n\n" -# "Thank you,\nDeluge." -# ) % torrent_status -# -# d0 = defer.maybeDeferred(self.notify_blink) -# d0.addCallback(self._on_notify_sucess, 'blink') -# d0.addErrback(self._on_notify_failure, 'blink') -# log.debug("Blink notification callback yielded") -# -## self.notify_email(title, message) -# d1 = defer.maybeDeferred(self.notify_email, title, message) -# d1.addCallback(self._on_notify_sucess, 'email') -# d1.addErrback(self._on_notify_failure, 'email') -## d. -## yield d -# log.debug("Email notification callback yielded") -# -# d2 = defer.maybeDeferred(self.notify_flash, title, message) -# d2.addCallback(self._on_notify_sucess, 'flash') -# d2.addErrback(self._on_notify_failure, 'flash') -## d. -## yield d -# log.debug("Flash notification callback yielded") -# # Sound -## self.notify_sound() -# d3 = defer.maybeDeferred(self.notify_sound) -# d3.addCallback(self._on_notify_sucess, 'sound') -# d3.addErrback(self._on_notify_failure, 'sound') -## yield d -# log.debug("Sound notification callback yielded") -# -# # Popup -# title = _("Finished Torrent") -# message = _("The torrent \"%(name)s\" including %(num_files)i " -# "has finished downloading.") % torrent_status -## self.notify_popup(title, message) -# d4 = defer.maybeDeferred(self.notify_popup, title, message) -# d4.addCallback(self._on_notify_sucess, 'popup') -# d4.addErrback(self._on_notify_failure, 'popup') -## yield d -# log.debug("Popup notification callback yielded") -# -# d5 = defer.maybeDeferred(self.notify_sound) -# d5.addCallback(self._on_notify_sucess, 'sound') -# d5.addErrback(self._on_notify_failure, 'sound') + def _on_notify_event_sucess(self, result, kind): + log.debug("\n\nNotification event success using %s: %s", kind, result) + return result + + def _on_notify_event_failure(self, failure, kind): + log.debug("\n\nNotification event failure using %s: %s", kind, failure) + return failure