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*()`.
This commit is contained in:
Pedro Algarvio 2009-11-22 02:34:35 +00:00
parent 0723a77214
commit 535940e2e6
3 changed files with 128 additions and 102 deletions

View File

@ -122,27 +122,31 @@ class Core(CorePluginBase, Notifications):
def notify_flash(self, title='', message=''): def notify_flash(self, title='', message=''):
if not self.config["flash_enabled"]: if not self.config["flash_enabled"]:
return defer.succeed("Flash notification not enabled") return defer.succeed("Flash notification not enabled")
return defer.maybeDeferred( d = defer.maybeDeferred(component.get("EventManager").emit,
component.get("EventManager").emit, events.NotificationFlashEvent(title, message))
events.NotificationFlashEvent(title, message) d.addCallback(self._on_notify_event_sucess, 'flash')
) d.addErrback(self._on_notify_event_failure, 'flash')
return d
@export @export
def notify_popup(self, title='', message=''): def notify_popup(self, title='', message=''):
if not self.config["popup_enabled"]: if not self.config["popup_enabled"]:
return defer.succeed("Popup notification not enabled") return defer.succeed("Popup notification not enabled")
return defer.maybeDeferred( d = defer.maybeDeferred(component.get("EventManager").emit,
component.get("EventManager").emit, events.NotificationPopupEvent(title, message))
events.NotificationPopupEvent(title, message) d.addCallback(self._on_notify_event_sucess, 'popup')
) d.addErrback(self._on_notify_event_failure, 'popup')
return d
@export @export
def notify_sound(self, sound_path=''): def notify_sound(self, sound_path=''):
if not self.config["sound_enabled"]: if not self.config["sound_enabled"]:
return defer.succeed("Sound notification not enabled") return defer.succeed("Sound notification not enabled")
return defer.maybeDeferred( d = defer.maybeDeferred(component.get("EventManager").emit,
component.get("EventManager").emit,
events.NotificationSoundEvent(sound_path)) 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=[]): def _notify_email(self, title='', message='', smtp_from='', recipients=[]):
config = self.config config = self.config
@ -162,8 +166,10 @@ Subject: %(title)s
try: try:
server = smtplib.SMTP(config["smtp_host"], config["smtp_port"]) server = smtplib.SMTP(config["smtp_host"], config["smtp_port"])
except Exception, err: except Exception, err:
log.error("There was an error sending the notification email: %s", err_msg = _("There was an error sending the notification email:"
err) " %s") % err
log.error(err_msg)
raise err
security_enabled = config['smtp_tls'] security_enabled = config['smtp_tls']
@ -178,19 +184,25 @@ Subject: %(title)s
if config['smtp_user'] and config['smtp_pass']: if config['smtp_user'] and config['smtp_pass']:
try: try:
server.login(config['smtp_user'], config['smtp_pass']) server.login(config['smtp_user'], config['smtp_pass'])
except smtplib.SMTPHeloError: except smtplib.SMTPHeloError, err:
log.warning("The server didn't reply properly to the helo " err_msg = _("The server didn't reply properly to the helo "
"greeting") "greeting: %s") % err
except smtplib.SMTPAuthenticationError: log.error(err_msg)
log.warning("The server didn't accept the username/password " raise err
"combination") 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:
try: try:
server.sendmail(config['smtp_from'], to_addrs, message) server.sendmail(config['smtp_from'], to_addrs, message)
except smtplib.SMTPException, err: except smtplib.SMTPException, err:
log.error("There was an error sending the notification email: " err_msg = _("There was an error sending the notification email:"
"%s", err) " %s") % err
log.error(err_msg)
raise err
finally: finally:
if security_enabled: if security_enabled:
# avoid false failure detection when the server closes # avoid false failure detection when the server closes
@ -202,4 +214,23 @@ Subject: %(title)s
pass pass
else: else:
server.quit() 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")

View File

@ -54,9 +54,9 @@ except ImportError:
try: try:
import pynotify import pynotify
POPUP_ENABLED = True POPUP_AVAILABLE = True
except ImportError: except ImportError:
POPUP_ENABLED = False POPUP_AVAILABLE = False
# Relative imports # Relative imports
from common import get_resource from common import get_resource
@ -103,7 +103,7 @@ class GtkUI(GtkPluginBase, Notifications):
component.get("PluginManager").register_hook("on_show_prefs", component.get("PluginManager").register_hook("on_show_prefs",
self.on_show_prefs) self.on_show_prefs)
if not POPUP_ENABLED: if not POPUP_AVAILABLE:
self.glade.get_widget("popup_enabled").set_property('sensitive', self.glade.get_widget("popup_enabled").set_property('sensitive',
False) False)
else: else:
@ -121,6 +121,9 @@ class GtkUI(GtkPluginBase, Notifications):
else: else:
client.register_event_handler("NotificationSoundEvent", client.register_event_handler("NotificationSoundEvent",
self.notify_sound) self.notify_sound)
client.register_event_handler("TorrentFinishedEvent",
self._on_torrent_finished_event)
# Force config populate # Force config populate
client.notifications.get_config().addCallback(self.cb_get_config) 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) self.glade.get_widget('sound_path').set_property('sensitive', False)
def notify_blink(self): 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=[]): 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=''): 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=''): def notify_popup(self, title='', message=''):
if not self.config['popup_enabled']: if not self.config['popup_enabled']:
return defer.succeed("Popup notification is not enabled.") return defer.succeed(_("Popup notification is not enabled."))
if not POPUP_ENABLED: if not POPUP_AVAILABLE:
return defer.fail("pynotify is not installed") return defer.fail(_("pynotify is not installed"))
if pynotify.init("Deluge"): if pynotify.init("Deluge"):
icon = gtk.gdk.pixbuf_new_from_file_at_size( 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 = pynotify.Notification(title, message)
self.note.set_icon_from_pixbuf(icon) self.note.set_icon_from_pixbuf(icon)
if not self.note.show(): if not self.note.show():
log.warning("pynotify failed to show notification") err_msg = _("pynotify failed to show notification")
return defer.fail("pynotify failed to show notification") log.warning(err_msg)
return defer.succeed("Notification popup shown") return defer.fail(err_msg)
return defer.succeed(_("Notification popup shown"))
def notify_sound(self, sound_path=''): def notify_sound(self, sound_path=''):
if not self.config['sound_enabled']: if not self.config['sound_enabled']:
return defer.succeed("Sound notification not enabled") return defer.succeed(_("Sound notification not enabled"))
if not SOUND_AVAILABLE: if not SOUND_AVAILABLE:
log.warning("pygame is not installed") err_msg = _("pygame is not installed")
return defer.fail("pygame is not installed") log.warning(err_msg)
return defer.fail(err_msg)
pygame.init() pygame.init()
try: try:
@ -274,9 +287,41 @@ class GtkUI(GtkPluginBase, Notifications):
alert_sound.load(sound_path) alert_sound.load(sound_path)
alert_sound.play() alert_sound.play()
except pygame.error, message: except pygame.error, message:
log.warning("pygame failed to play because %s" % (message)) err_msg = _("Sound notification failed %s") % (message)
return defer.fail("Sound notification failed %s" % (message)) log.warning(err_msg)
return defer.fail(err_msg)
else: else:
log.info("sound notification played successfully") msg = _("Sound notification Success")
return defer.succeed("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")

View File

@ -34,12 +34,8 @@
# #
from twisted.internet import defer, threads
from deluge import component from deluge import component
from deluge.core.rpcserver import export
from deluge.log import LOG as log from deluge.log import LOG as log
from deluge.ui.client import client
class Notifications(component.Component): class Notifications(component.Component):
def __init__(self, name): def __init__(self, name):
@ -87,63 +83,17 @@ class Notifications(component.Component):
self.notify_sound(sound_path) self.notify_sound(sound_path)
def _on_notify_sucess(self, result, kind): 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): 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): def _on_notify_event_sucess(self, result, kind):
# log.debug("\n\nhandler for TorrentFinishedEvent called") log.debug("\n\nNotification event success using %s: %s", kind, result)
# torrent = component.get("TorrentManager")[torrent_id] return result
# torrent_status = torrent.get_status({})
# # Email def _on_notify_event_failure(self, failure, kind):
# title = _("Finished Torrent %(name)s") % torrent_status log.debug("\n\nNotification event failure using %s: %s", kind, failure)
# message = _( return failure
# "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')