Linux: Preferentially use desktop specific notification daemons

This commit is contained in:
Kovid Goyal 2009-12-16 13:07:37 -07:00
parent c70adff6bf
commit 225eaab491
4 changed files with 116 additions and 3 deletions

BIN
resources/images/notify.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.8 KiB

View File

@ -108,7 +108,7 @@ class LinuxFreeze(Command):
'glib', 'gobject']
packages = ['calibre', 'encodings', 'cherrypy', 'cssutils', 'xdg',
'dateutil', 'dns', 'email']
'dateutil', 'dns', 'email', 'dbus']
includes += ['calibre.gui2.convert.'+x.split('/')[-1].rpartition('.')[0] for x in \
glob.glob('src/calibre/gui2/convert/*.py')]

111
src/calibre/gui2/notify.py Normal file
View File

@ -0,0 +1,111 @@
#!/usr/bin/env python
# vim:fileencoding=UTF-8:ts=4:sw=4:sta:et:sts=4:ai
from __future__ import with_statement
__license__ = 'GPL v3'
__copyright__ = '2009, Kovid Goyal <kovid@kovidgoyal.net>'
__docformat__ = 'restructuredtext en'
from calibre.constants import islinux
class Notifier(object):
DEFAULT_TIMEOUT = 5000
def get_msg_parms(self, timeout, body, summary):
if summary is None:
summary = 'calibre'
if timeout == 0:
timeout = self.DEFAULT_TIMEOUT
return timeout, body, summary
def __call__(self, body, summary=None, replaces_id=None, timeout=0):
raise NotImplementedError
class DBUSNotifier(Notifier):
ICON = I('notify.png')
def __init__(self, server, path):
self.ok, self.err = True, None
try:
import dbus
self.dbus = dbus
self._notify = dbus.SessionBus().get_object(server, path)
except Exception, err:
self.ok = False
self.err = str(err)
class KDENotifier(DBUSNotifier):
def __init__(self):
DBUSNotifier.__init__(self, 'org.kde.VisualNotifications',
'/VisualNotifications')
def __call__(self, body, summary=None, replaces_id=None, timeout=0):
if replaces_id is None:
replaces_id = self.dbus.UInt32()
event_id = ''
timeout, body, summary = self.get_msg_parms(timeout, body, summary)
self._notify.Notify('calibre', replaces_id, event_id, self.ICON, summary, body,
self.dbus.Array(signature='s'), self.dbus.Dictionary(signature='sv'),
timeout)
class FDONotifier(DBUSNotifier):
def __init__(self):
DBUSNotifier.__init__(self, 'org.freedesktop.Notifications',
'/org/freedesktop/Notifications')
def __call__(self, body, summary=None, replaces_id=None, timeout=0):
if replaces_id is None:
replaces_id = self.dbus.UInt32()
timeout, body, summary = self.get_msg_parms(timeout, body, summary)
self._notify.Notify('calibre', replaces_id, self.ICON, summary, body,
self.dbus.Array(signature='s'), self.dbus.Dictionary(signature='sv'),
timeout)
class QtNotifier(Notifier):
def __init__(self, systray=None):
self.systray = systray
self.ok = self.systray is not None and self.systray.supportsMessages()
def __call__(self, body, summary=None, replaces_id=None, timeout=0):
timeout, body, summary = self.get_msg_parms(timeout, body, summary)
if self.systray is not None:
self.systray.showMessage(summary, body, self.systray.Information,
timeout)
def get_notifier(systray=None):
ans = None
if islinux:
ans = KDENotifier()
if not ans.ok:
ans = FDONotifier()
if not ans.ok:
ans = None
if ans is None:
ans = QtNotifier(systray)
if not ans.ok:
ans = None
return ans
if __name__ == '__main__':
n = KDENotifier()
n('hello')
n = FDONotifier()
n('hello')
'''
from PyQt4.Qt import QApplication, QSystemTrayIcon, QIcon
app = QApplication([])
ic = QIcon(I('notify.png'))
tray = QSystemTrayIcon(ic)
tray.setVisible(True)
n = QtNotifier(tray)
n('hello')
'''

View File

@ -9,6 +9,7 @@ from calibre import fit_image, preferred_encoding, isosx
from calibre.gui2 import qstring_to_unicode, config
from calibre.gui2.widgets import IMAGE_EXTENSIONS
from calibre.gui2.progress_indicator import ProgressIndicator
from calibre.gui2.notify import get_notifier
from calibre.ebooks import BOOK_EXTENSIONS
class BookInfoDisplay(QWidget):
@ -218,6 +219,7 @@ class StatusBar(QStatusBar):
def __init__(self, jobs_dialog, systray=None):
QStatusBar.__init__(self)
self.systray = systray
self.notifier = get_notifier(systray)
self.movie_button = MovieButton(jobs_dialog)
self.cover_flow_button = CoverFlowButton()
self.tag_view_button = TagViewButton()
@ -247,13 +249,13 @@ class StatusBar(QStatusBar):
def showMessage(self, msg, timeout=0):
ret = QStatusBar.showMessage(self, msg, timeout)
if self.systray is not None and not config['disable_tray_notification']:
if self.notifier is not None and not config['disable_tray_notification']:
if isosx and isinstance(msg, unicode):
try:
msg = msg.encode(preferred_encoding)
except UnicodeEncodeError:
msg = msg.encode('utf-8')
self.systray.showMessage('calibre', msg, self.systray.Information, 10000)
self.notifier(msg)
return ret
def jobs(self):