-
Notifications
You must be signed in to change notification settings - Fork 0
/
dbus_notify.py
176 lines (145 loc) · 4.04 KB
/
dbus_notify.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
# Copyright (C) 2006, Thomas Leonard
import sys
import rox
from Memo import Memo
from rox import options
from os import path
memo_soundfile = options.Option('memo_sound', "")
timer_soundfile = options.Option('timer_sound', "")
# See http://www.galago-project.org/specs/notification/
_avail = None # Unknown
notification_service = None
_nid_to_memo = {}
LOW = 0
NORMAL = 1
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)
now = time.time()
delay = memo.time - now
earlyAlert = delay > 0
parts = memo.message.split('\n', 1)
summary = escape(parts[0])
body = '<i>' + (_('Alarm set for %s') % time.ctime(memo.time)) + '</i>'
if len(parts) == 2:
body += '\n' + escape(parts[1])
hints = {}
if earlyAlert:
okText = "Later"
hints['urgency'] = dbus.types.Byte(NORMAL)
else:
okText = "Ok"
hints['urgency'] = dbus.types.Byte(CRITICAL)
if memo.nosound:
hints['suppress-sound'] = dbus.types.Boolean(True)
elif memo.soundfile is not None and memo.soundfile != "":
hints['suppress-sound'] = dbus.types.Boolean(False)
hints['sound-file'] = dbus.types.String(memo.soundfile)
elif memo_soundfile.value != "":
hints['suppress-sound'] = dbus.types.Boolean(False)
hints['sound-file'] = dbus.types.String(memo_soundfile.value)
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', okText,
],
hints,
0) # timeout
_nid_to_memo[id] = memo
if earlyAlert:
memo.state = Memo.EARLY
else:
memo.state = Memo.DONE
from main import memo_list
memo_list.notify_changed()
def timer():
import time
import dbus.types
assert _avail
hints = {}
hints['urgency'] = dbus.types.Byte(CRITICAL)
if timer_soundfile.value != "":
hints['sound-file'] = timer_soundfile.value
notification_service.Notify('Memo',
0, # replaces_id,
path.join(rox.app_dir, ".DirIcon"), # icon
'Time is up!',
'The Memo timer you set has expired.',
[],
hints,
0) # timeout
if __name__ == '__main__':
__builtins__._ = lambda x: x
from Memo import Memo
assert is_available()
notify(Memo(0, 'This is a <message>.\nMore <details> go <here>.', True))
from rox import g
g.main()