# Copyright (C) 2006, Thomas Leonard import sys import rox from os import path # See http://www.galago-project.org/specs/notification/ _avail = None # Unknown notification_service = None _nid_to_memo = {} CRITICAL = 2 def _NotificationClosed(nid, *unused): if nid in _nid_to_memo: del _nid_to_memo[nid] #print "Closed" def _ActionInvoked(nid, action): try: memo = _nid_to_memo.get(nid, None) if memo: if action == 'edit': from EditBox import EditBox EditBox(memo).show() elif action == 'delete': from main import memo_list memo_list.delete(memo) elif action == 'hide': from main import memo_list memo_list.set_hidden(memo, 1) elif action in ('ok', 'default'): pass else: raise Exception('Unknown action "%s"' % action) except Exception: rox.report_exception() def is_available(): global _avail, notification_service if _avail is not None: return _avail try: import dbus import dbus.glib session_bus = dbus.SessionBus() remote_object = session_bus.get_object('org.freedesktop.Notifications', '/org/freedesktop/Notifications') notification_service = dbus.Interface(remote_object, 'org.freedesktop.Notifications') # The Python bindings insist on printing a pointless introspection # warning to stderr if the service is missing. Force it to be done # now so we can skip it old_stderr = sys.stderr sys.stderr = None try: notification_service.GetCapabilities() finally: sys.stderr = old_stderr notification_service.connect_to_signal('NotificationClosed', _NotificationClosed) notification_service.connect_to_signal('ActionInvoked', _ActionInvoked) _avail = True except: _avail = False return _avail def close(memo): # Used when the memo has been deleted (or changed) for nid in _nid_to_memo: if _nid_to_memo[nid] is memo: notification_service.CloseNotification(nid) def close_all(): for nid in _nid_to_memo: notification_service.CloseNotification(nid) def escape(s): return s.replace('&', '&').replace('<', '<') def notify(memo): import time import dbus.types assert _avail close(memo) parts = memo.message.split('\n', 1) summary = escape(parts[0]) body = '' + (_('Alarm set for %s') % time.ctime(memo.time)) + '' if len(parts) == 2: body += '\n' + escape(parts[1]) id = notification_service.Notify('Memo', 0, # replaces_id, path.join(rox.app_dir, ".DirIcon"), # icon summary, body, [ 'hide', 'Hide memo', 'delete', 'Delete', 'edit', 'Edit', 'ok', 'OK', ], {'urgency': dbus.types.Byte(CRITICAL)}, 0) # timeout _nid_to_memo[id] = memo memo.silent = 1 from main import memo_list memo_list.notify_changed() def timer(): import time import dbus.types assert _avail notification_service.Notify('Memo', 0, # replaces_id, path.join(rox.app_dir, ".DirIcon"), # icon 'Time is up!', 'The Memo timer you set has expired.', [], {'urgency': dbus.types.Byte(CRITICAL)}, 0) # timeout if __name__ == '__main__': __builtins__._ = lambda x: x from Memo import Memo assert is_available() notify(Memo(0, 'This is a .\nMore
go .', True)) from rox import g g.main()