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:
parent
0723a77214
commit
535940e2e6
|
@ -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")
|
||||||
|
|
|
@ -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")
|
||||||
|
|
||||||
|
|
|
@ -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')
|
|
||||||
|
|
Loading…
Reference in New Issue