Added missing import
[memo.git] / dbus_notify.py
blobb7fe6630170d185438eef9fa8ef4e4ecbbe1031c
1 # Copyright (C) 2006, Thomas Leonard
3 import sys
4 import rox
5 from Memo import Memo
6 from rox import options
7 from os import path
9 memo_soundfile = options.Option('memo_sound', "")
10 timer_soundfile = options.Option('timer_sound', "")
12 # See http://www.galago-project.org/specs/notification/
14 _avail = None # Unknown
15 notification_service = None
17 _nid_to_memo = {}
19 LOW = 0
20 NORMAL = 1
21 CRITICAL = 2
23 def _NotificationClosed(nid, *unused):
24 if nid in _nid_to_memo:
25 del _nid_to_memo[nid]
26 #print "Closed"
28 def _ActionInvoked(nid, action):
29 try:
30 memo = _nid_to_memo.get(nid, None)
31 if memo:
32 if action == 'edit':
33 from EditBox import EditBox
34 EditBox(memo).show()
35 elif action == 'delete':
36 from main import memo_list
37 memo_list.delete(memo)
38 elif action == 'hide':
39 from main import memo_list
40 memo_list.set_hidden(memo, 1)
41 elif action in ('ok', 'default'):
42 pass
43 else:
44 raise Exception('Unknown action "%s"' % action)
45 except Exception:
46 rox.report_exception()
48 def is_available():
49 global _avail, notification_service
50 if _avail is not None: return _avail
52 try:
53 import dbus
54 import dbus.glib
56 session_bus = dbus.SessionBus()
58 remote_object = session_bus.get_object('org.freedesktop.Notifications',
59 '/org/freedesktop/Notifications')
61 notification_service = dbus.Interface(remote_object,
62 'org.freedesktop.Notifications')
64 # The Python bindings insist on printing a pointless introspection
65 # warning to stderr if the service is missing. Force it to be done
66 # now so we can skip it
67 old_stderr = sys.stderr
68 sys.stderr = None
69 try:
70 notification_service.GetCapabilities()
71 finally:
72 sys.stderr = old_stderr
74 notification_service.connect_to_signal('NotificationClosed', _NotificationClosed)
75 notification_service.connect_to_signal('ActionInvoked', _ActionInvoked)
77 _avail = True
78 except:
79 _avail = False
80 return _avail
82 def close(memo):
83 # Used when the memo has been deleted (or changed)
84 for nid in _nid_to_memo:
85 if _nid_to_memo[nid] is memo:
86 notification_service.CloseNotification(nid)
88 def close_all():
89 for nid in _nid_to_memo:
90 notification_service.CloseNotification(nid)
92 def escape(s):
93 return s.replace('&', '&amp;').replace('<', '&lt;')
95 def notify(memo):
96 import time
97 import dbus.types
98 assert _avail
100 close(memo)
102 now = time.time()
103 delay = memo.time - now
104 earlyAlert = delay > 0
106 parts = memo.message.split('\n', 1)
107 summary = escape(parts[0])
108 body = '<i>' + (_('Alarm set for %s') % time.ctime(memo.time)) + '</i>'
109 if len(parts) == 2:
110 body += '\n' + escape(parts[1])
112 hints = {}
113 if earlyAlert:
114 okText = "Later"
115 hints['urgency'] = dbus.types.Byte(NORMAL)
116 else:
117 okText = "Ok"
118 hints['urgency'] = dbus.types.Byte(CRITICAL)
120 if memo.nosound:
121 hints['suppress-sound'] = dbus.types.Boolean(True)
122 elif memo.soundfile is not None and memo.soundfile != "":
123 hints['suppress-sound'] = dbus.types.Boolean(False)
124 hints['sound-file'] = dbus.types.String(memo.soundfile)
125 elif memo_soundfile.value != "":
126 hints['suppress-sound'] = dbus.types.Boolean(False)
127 hints['sound-file'] = dbus.types.String(memo_soundfile.value)
128 id = notification_service.Notify('Memo',
129 0, # replaces_id,
130 path.join(rox.app_dir, ".DirIcon"), # icon
131 summary,
132 body,
134 'hide', 'Hide memo',
135 'delete', 'Delete',
136 'edit', 'Edit',
137 'ok', okText,
139 hints,
140 0) # timeout
142 _nid_to_memo[id] = memo
144 if earlyAlert:
145 memo.state = Memo.EARLY
146 else:
147 memo.state = Memo.DONE
148 from main import memo_list
149 memo_list.notify_changed()
151 def timer():
152 import time
153 import dbus.types
154 assert _avail
156 hints = {}
157 hints['urgency'] = dbus.types.Byte(CRITICAL)
158 if timer_soundfile.value != "":
159 hints['sound-file'] = timer_soundfile.value
161 notification_service.Notify('Memo',
162 0, # replaces_id,
163 path.join(rox.app_dir, ".DirIcon"), # icon
164 'Time is up!',
165 'The Memo timer you set has expired.',
167 hints,
168 0) # timeout
170 if __name__ == '__main__':
171 __builtins__._ = lambda x: x
172 from Memo import Memo
173 assert is_available()
174 notify(Memo(0, 'This is a <message>.\nMore <details> go <here>.', True))
175 from rox import g
176 g.main()