Merge lp:~jconti/gm-notify/messaging-menu into lp:gm-notify
- messaging-menu
- Merge into trunk
Proposed by
Dimitri John Ledkov
Status: | Merged |
---|---|
Approved by: | Mateusz Balbus |
Approved revision: | 96 |
Merged at revision: | 80 |
Proposed branch: | lp:~jconti/gm-notify/messaging-menu |
Merge into: | lp:gm-notify |
Diff against target: |
1304 lines (+762/-216) 10 files modified
MANIFEST (+2/-0) data/gm-notify.convert (+6/-0) data/gm-notify.desktop (+2/-2) data/net.launchpad.gm-notify.gschema.xml (+25/-0) gm-config.ui (+439/-0) gm-notify (+150/-106) gm-notify-config (+84/-75) gm_notify_keyring.py (+40/-24) gtalk.py (+11/-5) setup.py (+3/-4) |
To merge this branch: | bzr merge lp:~jconti/gm-notify/messaging-menu |
Related bugs: |
Reviewer | Review Type | Date Requested | Status |
---|---|---|---|
Mateusz Balbus | Approve | ||
Review via email: mp+155163@code.launchpad.net |
Commit message
Description of the change
To post a comment you must log in.
Revision history for this message
Dimitri John Ledkov (xnox) wrote : | # |
Preview Diff
[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1 | === modified file 'MANIFEST' | |||
2 | --- MANIFEST 2010-09-18 13:06:25 +0000 | |||
3 | +++ MANIFEST 2013-03-25 04:23:21 +0000 | |||
4 | @@ -4,12 +4,14 @@ | |||
5 | 4 | keyring.py | 4 | keyring.py |
6 | 5 | setup.py | 5 | setup.py |
7 | 6 | gm-config.glade | 6 | gm-config.glade |
8 | 7 | gm-config.ui | ||
9 | 7 | gtalk.py | 8 | gtalk.py |
10 | 8 | data/checking.gif | 9 | data/checking.gif |
11 | 9 | data/gm-notify | 10 | data/gm-notify |
12 | 10 | data/gm-notify-config.desktop | 11 | data/gm-notify-config.desktop |
13 | 11 | data/gm-notify.desktop | 12 | data/gm-notify.desktop |
14 | 12 | data/gm-notify.schemas | 13 | data/gm-notify.schemas |
15 | 14 | data/net.launchpad.gm-notify.gschema.xml | ||
16 | 13 | po/gm-notify.pot | 15 | po/gm-notify.pot |
17 | 14 | po/bg/gm-notify.mo | 16 | po/bg/gm-notify.mo |
18 | 15 | po/bg/gm-notify.po | 17 | po/bg/gm-notify.po |
19 | 16 | 18 | ||
20 | === added file 'data/gm-notify.convert' | |||
21 | --- data/gm-notify.convert 1970-01-01 00:00:00 +0000 | |||
22 | +++ data/gm-notify.convert 2013-03-25 04:23:21 +0000 | |||
23 | @@ -0,0 +1,6 @@ | |||
24 | 1 | [net.launchpad.gm-notify] | ||
25 | 2 | play-sound = /apps/gm-notify/play_sound | ||
26 | 3 | ignore-inbox = /apps/gm-notify/ignore_inbox | ||
27 | 4 | soundfile = /apps/gm-notify/soundfile | ||
28 | 5 | mailboxes = /apps/gm-notify/mailboxes | ||
29 | 6 | openclient = /apps/gm-notify/openclient | ||
30 | 0 | 7 | ||
31 | === modified file 'data/gm-notify.desktop' | |||
32 | --- data/gm-notify.desktop 2010-06-22 19:46:39 +0000 | |||
33 | +++ data/gm-notify.desktop 2013-03-25 04:23:21 +0000 | |||
34 | @@ -1,8 +1,8 @@ | |||
35 | 1 | [Desktop Entry] | 1 | [Desktop Entry] |
36 | 2 | Encoding=UTF-8 | 2 | Encoding=UTF-8 |
38 | 3 | Name=Google Mail | 3 | Name=GMail Notifier |
39 | 4 | Comment=An E-Mail Notifier for Google Mail | 4 | Comment=An E-Mail Notifier for Google Mail |
41 | 5 | Icon=applications-email-panel | 5 | Icon=evolution |
42 | 6 | Type=Application | 6 | Type=Application |
43 | 7 | Exec=gm-notify | 7 | Exec=gm-notify |
44 | 8 | StartupNotify=False | 8 | StartupNotify=False |
45 | 9 | 9 | ||
46 | === added file 'data/net.launchpad.gm-notify.gschema.xml' | |||
47 | --- data/net.launchpad.gm-notify.gschema.xml 1970-01-01 00:00:00 +0000 | |||
48 | +++ data/net.launchpad.gm-notify.gschema.xml 2013-03-25 04:23:21 +0000 | |||
49 | @@ -0,0 +1,25 @@ | |||
50 | 1 | <?xml version="1.0" encoding="UTF-8"?> | ||
51 | 2 | <schemalist> | ||
52 | 3 | <schema path="/net/launchpad/gm-notify/" id="net.launchpad.gm-notify" gettext-domain="gm-notify"> | ||
53 | 4 | <key type="b" name="play-sound"> | ||
54 | 5 | <default>false</default> | ||
55 | 6 | <summary>Shall we play a sound on new mail?</summary> | ||
56 | 7 | </key> | ||
57 | 8 | <key type="b" name="ignore-inbox"> | ||
58 | 9 | <default>false</default> | ||
59 | 10 | <summary>If true, there won't be notifications regarding just your inbox.</summary> | ||
60 | 11 | </key> | ||
61 | 12 | <key type="s" name="soundfile"> | ||
62 | 13 | <default>''</default> | ||
63 | 14 | <summary>Path to the soundfile which should be played when a new mail arrives</summary> | ||
64 | 15 | </key> | ||
65 | 16 | <key type="as" name="mailboxes"> | ||
66 | 17 | <default>[]</default> | ||
67 | 18 | <summary>List containing mailboxes to check</summary> | ||
68 | 19 | </key> | ||
69 | 20 | <key type="b" name="openclient"> | ||
70 | 21 | <default>false</default> | ||
71 | 22 | <summary>Shall we open the default mail client or webinterface?</summary> | ||
72 | 23 | </key> | ||
73 | 24 | </schema> | ||
74 | 25 | </schemalist> | ||
75 | 0 | 26 | ||
76 | === added file 'gm-config.ui' | |||
77 | --- gm-config.ui 1970-01-01 00:00:00 +0000 | |||
78 | +++ gm-config.ui 2013-03-25 04:23:21 +0000 | |||
79 | @@ -0,0 +1,439 @@ | |||
80 | 1 | <?xml version="1.0" encoding="UTF-8"?> | ||
81 | 2 | <interface> | ||
82 | 3 | <!-- interface-requires gtk+ 3.0 --> | ||
83 | 4 | <object class="GtkWindow" id="gmnotify_config_main"> | ||
84 | 5 | <property name="can_focus">False</property> | ||
85 | 6 | <property name="border_width">10</property> | ||
86 | 7 | <property name="title" translatable="yes">GMail Notifier</property> | ||
87 | 8 | <property name="window_position">center</property> | ||
88 | 9 | <property name="icon_name">evolution</property> | ||
89 | 10 | <child> | ||
90 | 11 | <object class="GtkBox" id="vbox_main"> | ||
91 | 12 | <property name="visible">True</property> | ||
92 | 13 | <property name="can_focus">False</property> | ||
93 | 14 | <property name="orientation">vertical</property> | ||
94 | 15 | <property name="spacing">10</property> | ||
95 | 16 | <child> | ||
96 | 17 | <object class="GtkNotebook" id="notebook_main"> | ||
97 | 18 | <property name="visible">True</property> | ||
98 | 19 | <property name="can_focus">True</property> | ||
99 | 20 | <child> | ||
100 | 21 | <object class="GtkBox" id="vbox1"> | ||
101 | 22 | <property name="can_focus">False</property> | ||
102 | 23 | <property name="orientation">vertical</property> | ||
103 | 24 | <child> | ||
104 | 25 | <object class="GtkGrid" id="grid1"> | ||
105 | 26 | <property name="visible">True</property> | ||
106 | 27 | <property name="can_focus">False</property> | ||
107 | 28 | <property name="row_homogeneous">True</property> | ||
108 | 29 | <property name="column_homogeneous">True</property> | ||
109 | 30 | <child> | ||
110 | 31 | <object class="GtkLabel" id="label_user"> | ||
111 | 32 | <property name="visible">True</property> | ||
112 | 33 | <property name="can_focus">False</property> | ||
113 | 34 | <property name="label" translatable="yes">E-Mail:</property> | ||
114 | 35 | </object> | ||
115 | 36 | <packing> | ||
116 | 37 | <property name="left_attach">0</property> | ||
117 | 38 | <property name="top_attach">0</property> | ||
118 | 39 | <property name="width">1</property> | ||
119 | 40 | <property name="height">1</property> | ||
120 | 41 | </packing> | ||
121 | 42 | </child> | ||
122 | 43 | <child> | ||
123 | 44 | <object class="GtkLabel" id="label_password"> | ||
124 | 45 | <property name="visible">True</property> | ||
125 | 46 | <property name="can_focus">False</property> | ||
126 | 47 | <property name="label" translatable="yes">Password:</property> | ||
127 | 48 | </object> | ||
128 | 49 | <packing> | ||
129 | 50 | <property name="left_attach">0</property> | ||
130 | 51 | <property name="top_attach">1</property> | ||
131 | 52 | <property name="width">1</property> | ||
132 | 53 | <property name="height">1</property> | ||
133 | 54 | </packing> | ||
134 | 55 | </child> | ||
135 | 56 | <child> | ||
136 | 57 | <object class="GtkEntry" id="input_user"> | ||
137 | 58 | <property name="visible">True</property> | ||
138 | 59 | <property name="can_focus">True</property> | ||
139 | 60 | <property name="invisible_char">●</property> | ||
140 | 61 | <property name="invisible_char_set">True</property> | ||
141 | 62 | </object> | ||
142 | 63 | <packing> | ||
143 | 64 | <property name="left_attach">1</property> | ||
144 | 65 | <property name="top_attach">0</property> | ||
145 | 66 | <property name="width">1</property> | ||
146 | 67 | <property name="height">1</property> | ||
147 | 68 | </packing> | ||
148 | 69 | </child> | ||
149 | 70 | <child> | ||
150 | 71 | <object class="GtkEntry" id="input_password"> | ||
151 | 72 | <property name="visible">True</property> | ||
152 | 73 | <property name="can_focus">True</property> | ||
153 | 74 | <property name="visibility">False</property> | ||
154 | 75 | <property name="invisible_char">●</property> | ||
155 | 76 | <property name="invisible_char_set">True</property> | ||
156 | 77 | <signal name="focus-out-event" handler="on_input_password_focus_out_event" swapped="no"/> | ||
157 | 78 | </object> | ||
158 | 79 | <packing> | ||
159 | 80 | <property name="left_attach">1</property> | ||
160 | 81 | <property name="top_attach">1</property> | ||
161 | 82 | <property name="width">1</property> | ||
162 | 83 | <property name="height">1</property> | ||
163 | 84 | </packing> | ||
164 | 85 | </child> | ||
165 | 86 | <child> | ||
166 | 87 | <object class="GtkImage" id="image_credentials"> | ||
167 | 88 | <property name="visible">True</property> | ||
168 | 89 | <property name="can_focus">False</property> | ||
169 | 90 | <property name="stock">gtk-stop</property> | ||
170 | 91 | </object> | ||
171 | 92 | <packing> | ||
172 | 93 | <property name="left_attach">0</property> | ||
173 | 94 | <property name="top_attach">2</property> | ||
174 | 95 | <property name="width">1</property> | ||
175 | 96 | <property name="height">1</property> | ||
176 | 97 | </packing> | ||
177 | 98 | </child> | ||
178 | 99 | <child> | ||
179 | 100 | <object class="GtkLabel" id="label_credentials"> | ||
180 | 101 | <property name="visible">True</property> | ||
181 | 102 | <property name="can_focus">False</property> | ||
182 | 103 | <property name="label" translatable="yes">Please enter credentials</property> | ||
183 | 104 | </object> | ||
184 | 105 | <packing> | ||
185 | 106 | <property name="left_attach">1</property> | ||
186 | 107 | <property name="top_attach">2</property> | ||
187 | 108 | <property name="width">1</property> | ||
188 | 109 | <property name="height">1</property> | ||
189 | 110 | </packing> | ||
190 | 111 | </child> | ||
191 | 112 | </object> | ||
192 | 113 | <packing> | ||
193 | 114 | <property name="expand">True</property> | ||
194 | 115 | <property name="fill">True</property> | ||
195 | 116 | <property name="position">0</property> | ||
196 | 117 | </packing> | ||
197 | 118 | </child> | ||
198 | 119 | <child> | ||
199 | 120 | <object class="GtkHSeparator" id="seperator_account"> | ||
200 | 121 | <property name="visible">True</property> | ||
201 | 122 | <property name="can_focus">False</property> | ||
202 | 123 | </object> | ||
203 | 124 | <packing> | ||
204 | 125 | <property name="expand">False</property> | ||
205 | 126 | <property name="fill">True</property> | ||
206 | 127 | <property name="position">2</property> | ||
207 | 128 | </packing> | ||
208 | 129 | </child> | ||
209 | 130 | <child> | ||
210 | 131 | <object class="GtkBox" id="vbox2"> | ||
211 | 132 | <property name="visible">True</property> | ||
212 | 133 | <property name="can_focus">False</property> | ||
213 | 134 | <property name="border_width">10</property> | ||
214 | 135 | <property name="orientation">vertical</property> | ||
215 | 136 | <property name="spacing">5</property> | ||
216 | 137 | <child> | ||
217 | 138 | <object class="GtkLabel" id="label_click"> | ||
218 | 139 | <property name="visible">True</property> | ||
219 | 140 | <property name="can_focus">False</property> | ||
220 | 141 | <property name="xalign">0</property> | ||
221 | 142 | <property name="label" translatable="yes">Click on applet opens:</property> | ||
222 | 143 | </object> | ||
223 | 144 | <packing> | ||
224 | 145 | <property name="expand">False</property> | ||
225 | 146 | <property name="fill">True</property> | ||
226 | 147 | <property name="position">0</property> | ||
227 | 148 | </packing> | ||
228 | 149 | </child> | ||
229 | 150 | <child> | ||
230 | 151 | <object class="GtkAlignment" id="alignment1"> | ||
231 | 152 | <property name="visible">True</property> | ||
232 | 153 | <property name="can_focus">False</property> | ||
233 | 154 | <property name="left_padding">20</property> | ||
234 | 155 | <child> | ||
235 | 156 | <object class="GtkRadioButton" id="radiobutton_openweb"> | ||
236 | 157 | <property name="label" translatable="yes">GMail webinterface</property> | ||
237 | 158 | <property name="visible">True</property> | ||
238 | 159 | <property name="can_focus">True</property> | ||
239 | 160 | <property name="receives_default">False</property> | ||
240 | 161 | <property name="relief">none</property> | ||
241 | 162 | <property name="xalign">0.5</property> | ||
242 | 163 | <property name="active">True</property> | ||
243 | 164 | <property name="draw_indicator">True</property> | ||
244 | 165 | </object> | ||
245 | 166 | </child> | ||
246 | 167 | </object> | ||
247 | 168 | <packing> | ||
248 | 169 | <property name="expand">False</property> | ||
249 | 170 | <property name="fill">True</property> | ||
250 | 171 | <property name="position">1</property> | ||
251 | 172 | </packing> | ||
252 | 173 | </child> | ||
253 | 174 | <child> | ||
254 | 175 | <object class="GtkAlignment" id="alignment2"> | ||
255 | 176 | <property name="visible">True</property> | ||
256 | 177 | <property name="can_focus">False</property> | ||
257 | 178 | <property name="left_padding">20</property> | ||
258 | 179 | <child> | ||
259 | 180 | <object class="GtkRadioButton" id="radiobutton_openclient"> | ||
260 | 181 | <property name="label" translatable="yes">Current default mail client</property> | ||
261 | 182 | <property name="visible">True</property> | ||
262 | 183 | <property name="can_focus">True</property> | ||
263 | 184 | <property name="receives_default">False</property> | ||
264 | 185 | <property name="xalign">0.5</property> | ||
265 | 186 | <property name="yalign">0.50999999046325684</property> | ||
266 | 187 | <property name="active">True</property> | ||
267 | 188 | <property name="draw_indicator">True</property> | ||
268 | 189 | <property name="group">radiobutton_openweb</property> | ||
269 | 190 | </object> | ||
270 | 191 | </child> | ||
271 | 192 | </object> | ||
272 | 193 | <packing> | ||
273 | 194 | <property name="expand">False</property> | ||
274 | 195 | <property name="fill">True</property> | ||
275 | 196 | <property name="position">2</property> | ||
276 | 197 | </packing> | ||
277 | 198 | </child> | ||
278 | 199 | </object> | ||
279 | 200 | <packing> | ||
280 | 201 | <property name="expand">False</property> | ||
281 | 202 | <property name="fill">True</property> | ||
282 | 203 | <property name="position">3</property> | ||
283 | 204 | </packing> | ||
284 | 205 | </child> | ||
285 | 206 | </object> | ||
286 | 207 | </child> | ||
287 | 208 | <child type="tab"> | ||
288 | 209 | <object class="GtkLabel" id="label_account"> | ||
289 | 210 | <property name="visible">True</property> | ||
290 | 211 | <property name="can_focus">False</property> | ||
291 | 212 | <property name="label" translatable="yes">Account</property> | ||
292 | 213 | </object> | ||
293 | 214 | <packing> | ||
294 | 215 | <property name="tab_fill">False</property> | ||
295 | 216 | </packing> | ||
296 | 217 | </child> | ||
297 | 218 | <child> | ||
298 | 219 | <object class="GtkBox" id="vbox_enhanced"> | ||
299 | 220 | <property name="visible">True</property> | ||
300 | 221 | <property name="can_focus">False</property> | ||
301 | 222 | <property name="border_width">10</property> | ||
302 | 223 | <property name="orientation">vertical</property> | ||
303 | 224 | <property name="spacing">5</property> | ||
304 | 225 | <child> | ||
305 | 226 | <object class="GtkCheckButton" id="checkbutton_sound"> | ||
306 | 227 | <property name="label" translatable="yes">Play sound when new message arrives</property> | ||
307 | 228 | <property name="visible">True</property> | ||
308 | 229 | <property name="can_focus">True</property> | ||
309 | 230 | <property name="receives_default">False</property> | ||
310 | 231 | <property name="relief">half</property> | ||
311 | 232 | <property name="xalign">0.5</property> | ||
312 | 233 | <property name="draw_indicator">True</property> | ||
313 | 234 | <signal name="toggled" handler="on_checkbutton_sound_toggled" swapped="no"/> | ||
314 | 235 | </object> | ||
315 | 236 | <packing> | ||
316 | 237 | <property name="expand">False</property> | ||
317 | 238 | <property name="fill">True</property> | ||
318 | 239 | <property name="position">0</property> | ||
319 | 240 | </packing> | ||
320 | 241 | </child> | ||
321 | 242 | <child> | ||
322 | 243 | <object class="GtkFileChooserButton" id="fcbutton_sound"> | ||
323 | 244 | <property name="visible">True</property> | ||
324 | 245 | <property name="can_focus">False</property> | ||
325 | 246 | <property name="create_folders">False</property> | ||
326 | 247 | </object> | ||
327 | 248 | <packing> | ||
328 | 249 | <property name="expand">False</property> | ||
329 | 250 | <property name="fill">True</property> | ||
330 | 251 | <property name="position">1</property> | ||
331 | 252 | </packing> | ||
332 | 253 | </child> | ||
333 | 254 | <child> | ||
334 | 255 | <object class="GtkFrame" id="frame_labels"> | ||
335 | 256 | <property name="visible">True</property> | ||
336 | 257 | <property name="can_focus">False</property> | ||
337 | 258 | <property name="label_xalign">0</property> | ||
338 | 259 | <property name="shadow_type">none</property> | ||
339 | 260 | <child> | ||
340 | 261 | <object class="GtkAlignment" id="alignment3"> | ||
341 | 262 | <property name="visible">True</property> | ||
342 | 263 | <property name="can_focus">False</property> | ||
343 | 264 | <property name="left_padding">12</property> | ||
344 | 265 | <child> | ||
345 | 266 | <object class="GtkBox" id="vbox3"> | ||
346 | 267 | <property name="visible">True</property> | ||
347 | 268 | <property name="can_focus">False</property> | ||
348 | 269 | <property name="orientation">vertical</property> | ||
349 | 270 | <child> | ||
350 | 271 | <object class="GtkLabel" id="label_labeldesc"> | ||
351 | 272 | <property name="visible">True</property> | ||
352 | 273 | <property name="can_focus">False</property> | ||
353 | 274 | <property name="xalign">0</property> | ||
354 | 275 | <property name="label" translatable="yes">Please enter the Labels you want to have | ||
355 | 276 | checked seperated by commas</property> | ||
356 | 277 | </object> | ||
357 | 278 | <packing> | ||
358 | 279 | <property name="expand">False</property> | ||
359 | 280 | <property name="fill">True</property> | ||
360 | 281 | <property name="padding">5</property> | ||
361 | 282 | <property name="position">0</property> | ||
362 | 283 | </packing> | ||
363 | 284 | </child> | ||
364 | 285 | <child> | ||
365 | 286 | <object class="GtkEntry" id="entry_labels"> | ||
366 | 287 | <property name="visible">True</property> | ||
367 | 288 | <property name="can_focus">True</property> | ||
368 | 289 | <property name="invisible_char">●</property> | ||
369 | 290 | </object> | ||
370 | 291 | <packing> | ||
371 | 292 | <property name="expand">False</property> | ||
372 | 293 | <property name="fill">True</property> | ||
373 | 294 | <property name="position">1</property> | ||
374 | 295 | </packing> | ||
375 | 296 | </child> | ||
376 | 297 | <child> | ||
377 | 298 | <object class="GtkCheckButton" id="checkbutton_inbox"> | ||
378 | 299 | <property name="label" translatable="yes">Ignore inbox</property> | ||
379 | 300 | <property name="visible">True</property> | ||
380 | 301 | <property name="can_focus">True</property> | ||
381 | 302 | <property name="receives_default">False</property> | ||
382 | 303 | <property name="xalign">0.5</property> | ||
383 | 304 | <property name="yalign">0.46000000834465027</property> | ||
384 | 305 | <property name="draw_indicator">True</property> | ||
385 | 306 | </object> | ||
386 | 307 | <packing> | ||
387 | 308 | <property name="expand">True</property> | ||
388 | 309 | <property name="fill">True</property> | ||
389 | 310 | <property name="position">2</property> | ||
390 | 311 | </packing> | ||
391 | 312 | </child> | ||
392 | 313 | </object> | ||
393 | 314 | </child> | ||
394 | 315 | </object> | ||
395 | 316 | </child> | ||
396 | 317 | <child type="label"> | ||
397 | 318 | <object class="GtkLabel" id="label_labels"> | ||
398 | 319 | <property name="visible">True</property> | ||
399 | 320 | <property name="can_focus">False</property> | ||
400 | 321 | <property name="label" translatable="yes"><b>Labels:</b></property> | ||
401 | 322 | <property name="use_markup">True</property> | ||
402 | 323 | </object> | ||
403 | 324 | </child> | ||
404 | 325 | </object> | ||
405 | 326 | <packing> | ||
406 | 327 | <property name="expand">False</property> | ||
407 | 328 | <property name="fill">True</property> | ||
408 | 329 | <property name="position">2</property> | ||
409 | 330 | </packing> | ||
410 | 331 | </child> | ||
411 | 332 | <child> | ||
412 | 333 | <object class="GtkFrame" id="frame_autostart"> | ||
413 | 334 | <property name="visible">True</property> | ||
414 | 335 | <property name="can_focus">False</property> | ||
415 | 336 | <property name="label_xalign">0</property> | ||
416 | 337 | <property name="shadow_type">none</property> | ||
417 | 338 | <child> | ||
418 | 339 | <object class="GtkAlignment" id="alignment4"> | ||
419 | 340 | <property name="visible">True</property> | ||
420 | 341 | <property name="can_focus">False</property> | ||
421 | 342 | <property name="left_padding">12</property> | ||
422 | 343 | <child> | ||
423 | 344 | <object class="GtkCheckButton" id="checkbutton_autostart"> | ||
424 | 345 | <property name="label" translatable="yes">Start automatically on logon</property> | ||
425 | 346 | <property name="visible">True</property> | ||
426 | 347 | <property name="can_focus">True</property> | ||
427 | 348 | <property name="receives_default">False</property> | ||
428 | 349 | <property name="xalign">0.5</property> | ||
429 | 350 | <property name="draw_indicator">True</property> | ||
430 | 351 | </object> | ||
431 | 352 | </child> | ||
432 | 353 | </object> | ||
433 | 354 | </child> | ||
434 | 355 | <child type="label"> | ||
435 | 356 | <object class="GtkLabel" id="label1"> | ||
436 | 357 | <property name="visible">True</property> | ||
437 | 358 | <property name="can_focus">False</property> | ||
438 | 359 | <property name="label" translatable="yes"><b>Autostart:</b></property> | ||
439 | 360 | <property name="use_markup">True</property> | ||
440 | 361 | </object> | ||
441 | 362 | </child> | ||
442 | 363 | </object> | ||
443 | 364 | <packing> | ||
444 | 365 | <property name="expand">False</property> | ||
445 | 366 | <property name="fill">True</property> | ||
446 | 367 | <property name="position">3</property> | ||
447 | 368 | </packing> | ||
448 | 369 | </child> | ||
449 | 370 | </object> | ||
450 | 371 | <packing> | ||
451 | 372 | <property name="position">1</property> | ||
452 | 373 | <property name="tab_fill">False</property> | ||
453 | 374 | </packing> | ||
454 | 375 | </child> | ||
455 | 376 | <child type="tab"> | ||
456 | 377 | <object class="GtkLabel" id="label_enhanced"> | ||
457 | 378 | <property name="visible">True</property> | ||
458 | 379 | <property name="can_focus">False</property> | ||
459 | 380 | <property name="label" translatable="yes">Enhanced</property> | ||
460 | 381 | </object> | ||
461 | 382 | <packing> | ||
462 | 383 | <property name="position">1</property> | ||
463 | 384 | <property name="tab_fill">False</property> | ||
464 | 385 | </packing> | ||
465 | 386 | </child> | ||
466 | 387 | </object> | ||
467 | 388 | <packing> | ||
468 | 389 | <property name="expand">True</property> | ||
469 | 390 | <property name="fill">True</property> | ||
470 | 391 | <property name="position">0</property> | ||
471 | 392 | </packing> | ||
472 | 393 | </child> | ||
473 | 394 | <child> | ||
474 | 395 | <object class="GtkBox" id="hbox_mainbuttons"> | ||
475 | 396 | <property name="visible">True</property> | ||
476 | 397 | <property name="can_focus">False</property> | ||
477 | 398 | <property name="spacing">10</property> | ||
478 | 399 | <child> | ||
479 | 400 | <object class="GtkButton" id="button_apply"> | ||
480 | 401 | <property name="label">gtk-apply</property> | ||
481 | 402 | <property name="visible">True</property> | ||
482 | 403 | <property name="can_focus">True</property> | ||
483 | 404 | <property name="receives_default">True</property> | ||
484 | 405 | <property name="use_stock">True</property> | ||
485 | 406 | <signal name="clicked" handler="on_button_apply_clicked" swapped="no"/> | ||
486 | 407 | </object> | ||
487 | 408 | <packing> | ||
488 | 409 | <property name="expand">True</property> | ||
489 | 410 | <property name="fill">True</property> | ||
490 | 411 | <property name="position">0</property> | ||
491 | 412 | </packing> | ||
492 | 413 | </child> | ||
493 | 414 | <child> | ||
494 | 415 | <object class="GtkButton" id="button_close"> | ||
495 | 416 | <property name="label">gtk-close</property> | ||
496 | 417 | <property name="visible">True</property> | ||
497 | 418 | <property name="can_focus">True</property> | ||
498 | 419 | <property name="receives_default">True</property> | ||
499 | 420 | <property name="use_stock">True</property> | ||
500 | 421 | <signal name="clicked" handler="gtk_main_quit" swapped="no"/> | ||
501 | 422 | </object> | ||
502 | 423 | <packing> | ||
503 | 424 | <property name="expand">True</property> | ||
504 | 425 | <property name="fill">True</property> | ||
505 | 426 | <property name="position">1</property> | ||
506 | 427 | </packing> | ||
507 | 428 | </child> | ||
508 | 429 | </object> | ||
509 | 430 | <packing> | ||
510 | 431 | <property name="expand">False</property> | ||
511 | 432 | <property name="fill">True</property> | ||
512 | 433 | <property name="position">1</property> | ||
513 | 434 | </packing> | ||
514 | 435 | </child> | ||
515 | 436 | </object> | ||
516 | 437 | </child> | ||
517 | 438 | </object> | ||
518 | 439 | </interface> | ||
519 | 0 | 440 | ||
520 | === modified file 'gm-notify' | |||
521 | --- gm-notify 2010-09-18 13:06:25 +0000 | |||
522 | +++ gm-notify 2013-03-25 04:23:21 +0000 | |||
523 | @@ -1,4 +1,4 @@ | |||
525 | 1 | #!/usr/bin/env python | 1 | #!/usr/bin/python |
526 | 2 | # -*- coding: utf-8 -*- | 2 | # -*- coding: utf-8 -*- |
527 | 3 | 3 | ||
528 | 4 | # gm-notify v0.10.3 | 4 | # gm-notify v0.10.3 |
529 | @@ -19,21 +19,18 @@ | |||
530 | 19 | # You should have received a copy of the GNU General Public License | 19 | # You should have received a copy of the GNU General Public License |
531 | 20 | # along with this program. If not, see <http://www.gnu.org/licenses/>. | 20 | # along with this program. If not, see <http://www.gnu.org/licenses/>. |
532 | 21 | # | 21 | # |
533 | 22 | from __future__ import print_function | ||
534 | 23 | |||
535 | 22 | import os | 24 | import os |
536 | 23 | import sys | 25 | import sys |
537 | 24 | import subprocess | 26 | import subprocess |
538 | 25 | import gettext | 27 | import gettext |
539 | 26 | import webbrowser | 28 | import webbrowser |
540 | 27 | 29 | ||
550 | 28 | import pynotify | 30 | from gi.repository import Gio, GLib, MessagingMenu, Notify |
551 | 29 | import indicate | 31 | |
552 | 30 | import gobject | 32 | from twisted.internet import gireactor |
553 | 31 | import pygst | 33 | gireactor.install() |
545 | 32 | pygst.require("0.10") | ||
546 | 33 | import gst | ||
547 | 34 | import gconf | ||
548 | 35 | from twisted.internet import glib2reactor | ||
549 | 36 | glib2reactor.install() | ||
554 | 37 | from twisted.internet import reactor | 34 | from twisted.internet import reactor |
555 | 38 | from twisted.words.protocols.jabber import jid | 35 | from twisted.words.protocols.jabber import jid |
556 | 39 | 36 | ||
557 | @@ -57,22 +54,69 @@ | |||
558 | 57 | if os.path.exists(path) and os.access(path, os.X_OK): return path | 54 | if os.path.exists(path) and os.access(path, os.X_OK): return path |
559 | 58 | raise PathNotFound("%s not found" % name) | 55 | raise PathNotFound("%s not found" % name) |
560 | 59 | 56 | ||
562 | 60 | class CheckMail(): | 57 | def play_sound(name): |
563 | 58 | '''Spawns a canberra-gtk-play process to play the sound''' | ||
564 | 59 | if name is None: | ||
565 | 60 | return | ||
566 | 61 | player_path = "/usr/bin/canberra-gtk-play" | ||
567 | 62 | # Not installed? | ||
568 | 63 | if not os.path.exists(player_path): | ||
569 | 64 | return | ||
570 | 65 | command = [player_path] | ||
571 | 66 | # File exists, so use the file flag | ||
572 | 67 | if os.path.exists(name): | ||
573 | 68 | command.extend(["-f", name]) | ||
574 | 69 | # Assume it is a sound id | ||
575 | 70 | else: | ||
576 | 71 | command.extend(["-i", name]) | ||
577 | 72 | try: | ||
578 | 73 | result = GLib.spawn_async(command) | ||
579 | 74 | except: | ||
580 | 75 | return | ||
581 | 76 | # Does nothing but the documentation says to do it anyway | ||
582 | 77 | if len(result) > 0: | ||
583 | 78 | GLib.spawn_close_pid(result[0]) | ||
584 | 79 | |||
585 | 80 | class CheckMail(Gio.Application): | ||
586 | 61 | def __init__(self): | 81 | def __init__(self): |
587 | 62 | '''initiates DBUS-Messaging interface, creates the MailChecker and registers with indicator-applet. | 82 | '''initiates DBUS-Messaging interface, creates the MailChecker and registers with indicator-applet. |
588 | 63 | In the end it starts the periodic check timer and a gtk main-loop''' | 83 | In the end it starts the periodic check timer and a gtk main-loop''' |
595 | 64 | 84 | super(CheckMail, self).__init__(application_id="net.launchpad.gm-notify", | |
596 | 65 | # Kill running gm-notify processes (UGLY!) | 85 | flags=Gio.ApplicationFlags.FLAGS_NONE) |
597 | 66 | subprocess.call("kill `pgrep -f gm-notify | grep -v %s`" % os.getpid(), stdout=open("/dev/null", "w"), shell=True) | 86 | |
598 | 67 | 87 | self._has_activated = False | |
599 | 68 | # Initiate pynotify and Gnome Keyring | 88 | self._counts = {} |
600 | 69 | if not pynotify.init(_("GMail Notifier")): | 89 | self.connect("activate", self.on_activate) |
601 | 90 | |||
602 | 91 | def on_remote_quit(self, action, args): | ||
603 | 92 | '''Stops the application when the "remote-quit" action is activated''' | ||
604 | 93 | reactor.stop() | ||
605 | 94 | |||
606 | 95 | def on_activate(self, app): | ||
607 | 96 | '''When first receiving the activate signal, initialize the primary | ||
608 | 97 | instance. On subsequent activate signals, we are being activated from a | ||
609 | 98 | secondary instance, so treat it as if our name was clicked in the | ||
610 | 99 | messaging menu.''' | ||
611 | 100 | if self._has_activated: | ||
612 | 101 | self.indicator_clicked() | ||
613 | 102 | return | ||
614 | 103 | |||
615 | 104 | self._has_activated = True | ||
616 | 105 | |||
617 | 106 | # Add an action to quit | ||
618 | 107 | quit_action = Gio.SimpleAction.new("remote-quit", None) | ||
619 | 108 | quit_action.connect("activate", self.on_remote_quit) | ||
620 | 109 | self.add_action(quit_action) | ||
621 | 110 | |||
622 | 111 | # Initialize the desktop notifications | ||
623 | 112 | if not Notify.init(_("GMail Notifier")): | ||
624 | 70 | sys.exit(-1) | 113 | sys.exit(-1) |
626 | 71 | 114 | ||
627 | 72 | keys = keyring.Keyring("GMail", "mail.google.com", "http") | 115 | keys = keyring.Keyring("GMail", "mail.google.com", "http") |
628 | 73 | if keys.has_credentials(): | 116 | if keys.has_credentials(): |
629 | 74 | self.creds = keys.get_credentials() | 117 | self.creds = keys.get_credentials() |
630 | 75 | else: | 118 | else: |
631 | 119 | print("Failed to get credentials") | ||
632 | 76 | # Start gm-notify-config if no credentials are found | 120 | # Start gm-notify-config if no credentials are found |
633 | 77 | try: | 121 | try: |
634 | 78 | subprocess.call(get_executable_path("gm-notify-config")) | 122 | subprocess.call(get_executable_path("gm-notify-config")) |
635 | @@ -88,67 +132,86 @@ | |||
636 | 88 | else: | 132 | else: |
637 | 89 | self.domain = self.jid.host | 133 | self.domain = self.jid.host |
638 | 90 | 134 | ||
664 | 91 | # init gconf to read config values | 135 | self.client = Gio.Settings("net.launchpad.gm-notify") |
665 | 92 | self.client = gconf.client_get_default() | 136 | |
666 | 93 | 137 | # Set up the sound file | |
667 | 94 | # init sound | 138 | self._soundfile = self.client.get_string("soundfile") |
668 | 95 | soundfile = self.client.get_string("/apps/gm-notify/soundfile") | 139 | if self._soundfile == '': |
669 | 96 | if self.client.get_bool("/apps/gm-notify/play_sound") and soundfile: | 140 | self._soundfile = "message-new-instant" |
670 | 97 | self.player = gst.element_factory_make("playbin", "player") | 141 | if not self.client.get_boolean("play-sound"): |
671 | 98 | self.player.set_property("video-sink", gst.element_factory_make("fakesink", "fakesink")) | 142 | self._soundfile = None |
672 | 99 | self.player.set_property("uri", "file://" + soundfile) | 143 | |
673 | 100 | bus = self.player.get_bus() | 144 | # Messaging Menu integration |
674 | 101 | bus.add_signal_watch() | 145 | self._m_menu = MessagingMenu.App.new("gm-notify.desktop") |
675 | 102 | bus.connect("message", self.gst_message) | 146 | self._m_menu.register() |
676 | 103 | else: | 147 | self._m_menu.connect("activate-source", self.source_clicked) |
677 | 104 | self.player = None | 148 | |
678 | 105 | 149 | # Read ignore-inbox value. If true you will only receive notifications | |
679 | 106 | # Register with Indicator-Applet | 150 | # about configured labels |
680 | 107 | self.server = indicate.indicate_server_ref_default() | 151 | self.ignore_inbox = self.client.get_boolean("ignore-inbox") |
656 | 108 | self.server.set_type("message.mail") | ||
657 | 109 | self.server.set_desktop_file("/usr/share/gm-notify/gm-notify.desktop") | ||
658 | 110 | self.server.connect("server-display", self.serverClick) | ||
659 | 111 | self.indicators = {} | ||
660 | 112 | |||
661 | 113 | # Read /apps/gm-notify/ignore_inbox value. If true you will only receive | ||
662 | 114 | # notifications about configured labels | ||
663 | 115 | self.ignore_inbox = self.client.get_bool("/apps/gm-notify/ignore_inbox") | ||
681 | 116 | 152 | ||
682 | 117 | # Retrieve the mailbox we're gonna check | 153 | # Retrieve the mailbox we're gonna check |
684 | 118 | self.mailboxes = self.client.get_list("/apps/gm-notify/mailboxes", gconf.VALUE_STRING) | 154 | self.mailboxes = self.client.get_strv("mailboxes") |
685 | 119 | self.mailboxes.insert(0, "inbox") | 155 | self.mailboxes.insert(0, "inbox") |
686 | 120 | self.addMailboxIndicators() | ||
687 | 121 | self.checker = MailChecker(self.jid, self.creds[1], self.mailboxes[1:], self.new_mail, self.update_count) | 156 | self.checker = MailChecker(self.jid, self.creds[1], self.mailboxes[1:], self.new_mail, self.update_count) |
688 | 122 | self.checker.connect() | 157 | self.checker.connect() |
705 | 123 | 158 | ||
706 | 124 | reactor.run() | 159 | def indicator_clicked(self): |
707 | 125 | 160 | '''called when "Google Mail" is clicked in indicator-messages and | |
708 | 126 | def gst_message(self, bus, message): | 161 | performs a Mail Check''' |
709 | 127 | if message.type == gst.MESSAGE_EOS: | 162 | for label in self.mailboxes: |
710 | 128 | self.player.set_state(gst.STATE_NULL) | 163 | self.remove_attention(label) |
711 | 129 | elif message.type == gst.MESSAGE_ERROR: | 164 | |
696 | 130 | self.player.set_state(gst.STATE_NULL) | ||
697 | 131 | print "Error: %s - %s" % message.parse_error() | ||
698 | 132 | |||
699 | 133 | def serverClick(self, server, timestamp=None): | ||
700 | 134 | '''called when the server is clicked in the indicator-applet and performs a Mail Check''' | ||
701 | 135 | for indicator in self.indicators: | ||
702 | 136 | self.indicators[indicator].set_property("draw-attention", "false") | ||
703 | 137 | |||
704 | 138 | if self.player: self.player.set_state(gst.STATE_NULL) | ||
712 | 139 | self.checker.queryInbox() | 165 | self.checker.queryInbox() |
713 | 166 | |||
714 | 167 | def remove_attention(self, label): | ||
715 | 168 | '''Removes attention from the label source if it exists''' | ||
716 | 169 | if self._m_menu.has_source(label): | ||
717 | 170 | self._m_menu.remove_attention(label) | ||
718 | 171 | |||
719 | 172 | def has_source(self, label): | ||
720 | 173 | '''Returns true if we have this label, or if we don't and it is in our | ||
721 | 174 | mailboxes list, create it''' | ||
722 | 175 | if label == "inbox" and self.ignore_inbox: | ||
723 | 176 | return False | ||
724 | 177 | elif label in self.mailboxes: | ||
725 | 178 | if not self._m_menu.has_source(label): | ||
726 | 179 | if label in MAILBOXES_NAMES: | ||
727 | 180 | name = MAILBOXES_NAMES[label] | ||
728 | 181 | else: | ||
729 | 182 | name = label | ||
730 | 183 | if label == "inbox": | ||
731 | 184 | self._m_menu.insert_source_with_string(0, label, None, name, _("empty")) | ||
732 | 185 | else: | ||
733 | 186 | self._m_menu.append_source_with_string(label, None, name, _("empty")) | ||
734 | 187 | if label in self._counts: | ||
735 | 188 | self._m_menu.set_source_count(label, self._counts[label]) | ||
736 | 189 | return True | ||
737 | 190 | else: | ||
738 | 191 | return False | ||
739 | 140 | 192 | ||
740 | 141 | def update_count(self, count): | 193 | def update_count(self, count): |
741 | 194 | '''Updates the count for all the mailboxes''' | ||
742 | 142 | for mailbox in count.iteritems(): | 195 | for mailbox in count.iteritems(): |
743 | 143 | if mailbox[0] == "inbox" and self.ignore_inbox: | 196 | if mailbox[0] == "inbox" and self.ignore_inbox: |
744 | 144 | continue | 197 | continue |
745 | 145 | 198 | ||
752 | 146 | i = self.indicators[mailbox[0]] | 199 | if self.has_source(mailbox[0]): |
753 | 147 | if int(i.get_property("count")) > int(mailbox[1]): | 200 | # Get the last count |
754 | 148 | i.set_property("draw-attention", "false") | 201 | last_count = 0 |
755 | 149 | i.set_property("count", unicode(mailbox[1])) | 202 | if mailbox[0] in self._counts: |
756 | 150 | if int(mailbox[1]) or mailbox[0] == "inbox": i.show() | 203 | last_count = self._counts[mailbox[0]] |
757 | 151 | else: i.hide() | 204 | current_count = int(mailbox[1]) |
758 | 205 | |||
759 | 206 | # Remove attention if the count has decreased | ||
760 | 207 | if last_count > current_count: | ||
761 | 208 | self._m_menu.remove_attention(mailbox[0]) | ||
762 | 209 | if current_count > 0: | ||
763 | 210 | self._m_menu.set_source_count(mailbox[0], current_count) | ||
764 | 211 | # Remove the source if 0 messages, to save space | ||
765 | 212 | else: | ||
766 | 213 | self._m_menu.remove_source(mailbox[0]) | ||
767 | 214 | self._counts[mailbox[0]] = current_count | ||
768 | 152 | 215 | ||
769 | 153 | def new_mail(self, mails): | 216 | def new_mail(self, mails): |
770 | 154 | '''Takes mailbox name and titles of mails, to display notification and add indicators''' | 217 | '''Takes mailbox name and titles of mails, to display notification and add indicators''' |
771 | @@ -158,11 +221,12 @@ | |||
772 | 158 | got_label = False | 221 | got_label = False |
773 | 159 | for label in mail['labels']: | 222 | for label in mail['labels']: |
774 | 160 | if label == u"^i": label = "inbox" | 223 | if label == u"^i": label = "inbox" |
780 | 161 | if label in self.indicators: | 224 | if label == "inbox" and self.ignore_inbox: |
781 | 162 | if not label == "inbox" or not self.ignore_inbox: | 225 | continue |
782 | 163 | got_label = True | 226 | if self.has_source(label): |
783 | 164 | self.indicators[label].set_property("draw-attention", "true") | 227 | got_label = True |
784 | 165 | if not got_label and self.ignore_inbox: continue | 228 | self._m_menu.draw_attention(label) |
785 | 229 | if not got_label: continue | ||
786 | 166 | 230 | ||
787 | 167 | if "sender_name" in mail: text += mail['sender_name'] + ":\n" | 231 | if "sender_name" in mail: text += mail['sender_name'] + ":\n" |
788 | 168 | elif "sender_address" in mail: text += mail['sender_address'] + ":\n" | 232 | elif "sender_address" in mail: text += mail['sender_address'] + ":\n" |
789 | @@ -179,9 +243,9 @@ | |||
790 | 179 | 243 | ||
791 | 180 | if text: | 244 | if text: |
792 | 181 | self.showNotification(_("Incoming message"), text.strip("\n")) | 245 | self.showNotification(_("Incoming message"), text.strip("\n")) |
794 | 182 | if self.player: self.player.set_state(gst.STATE_PLAYING) | 246 | play_sound(self._soundfile) |
795 | 183 | 247 | ||
797 | 184 | def labelClick(self, indicator, timestamp=None): | 248 | def source_clicked(self, app, source_id): |
798 | 185 | '''called when a label is clicked in the indicator-applet and opens the corresponding gmail page''' | 249 | '''called when a label is clicked in the indicator-applet and opens the corresponding gmail page''' |
799 | 186 | if self.domain: | 250 | if self.domain: |
800 | 187 | url = "https://mail.google.com/a/"+self.domain+"/" | 251 | url = "https://mail.google.com/a/"+self.domain+"/" |
801 | @@ -189,49 +253,29 @@ | |||
802 | 189 | url = "https://mail.google.com/mail/" | 253 | url = "https://mail.google.com/mail/" |
803 | 190 | 254 | ||
804 | 191 | try: | 255 | try: |
806 | 192 | url += "#%s" % MAILBOXES_URLS[indicator.label] | 256 | url += "#%s" % MAILBOXES_URLS[source_id] |
807 | 193 | except KeyError: | 257 | except KeyError: |
811 | 194 | url += "#label/%s" % indicator.label | 258 | url += "#label/%s" % source_id |
809 | 195 | |||
810 | 196 | indicator.set_property("draw-attention", "false") | ||
812 | 197 | 259 | ||
813 | 198 | # Open mail client | 260 | # Open mail client |
825 | 199 | if self.client.get_bool("/apps/gm-notify/openclient"): | 261 | if self.client.get_boolean("openclient"): |
826 | 200 | command = self.client.get_string("/desktop/gnome/url-handlers/mailto/command").split(" ")[0] | 262 | try: |
827 | 201 | if command.find("mutt") != -1: command += " -f =%s" % indicator.label | 263 | info = Gio.AppInfo.get_default_for_type("x-scheme-handler/mailto", False) |
828 | 202 | if self.client.get_bool("/desktop/gnome/url-handlers/mailto/needs_terminal"): | 264 | info.launch(None, None) |
829 | 203 | termCmd = self.client.get_string("/desktop/gnome/applications/terminal/exec") | 265 | except: |
830 | 204 | if termCmd: | 266 | pass |
820 | 205 | termCmd += " " + self.client.get_string("/desktop/gnome/applications/terminal/exec_arg") + " " | ||
821 | 206 | else: | ||
822 | 207 | termCmd = "gnome-terminal -x " | ||
823 | 208 | command = termCmd + command | ||
824 | 209 | subprocess.Popen(command, shell=True) | ||
831 | 210 | else: | 267 | else: |
832 | 211 | webbrowser.open(url) | 268 | webbrowser.open(url) |
834 | 212 | 269 | ||
835 | 213 | def showNotification(self, title, message): | 270 | def showNotification(self, title, message): |
836 | 214 | '''takes a title and a message to display the email notification. Returns the | 271 | '''takes a title and a message to display the email notification. Returns the |
837 | 215 | created notification object''' | 272 | created notification object''' |
838 | 216 | 273 | ||
840 | 217 | n = pynotify.Notification(title, message, "notification-message-email") | 274 | n = Notify.Notification.new(title, message, "notification-message-email") |
841 | 218 | n.show() | 275 | n.show() |
842 | 219 | 276 | ||
843 | 220 | return n | 277 | return n |
844 | 221 | 278 | ||
845 | 222 | def addMailboxIndicators(self): | ||
846 | 223 | for mailbox in reversed(self.mailboxes): | ||
847 | 224 | new_indicator = indicate.Indicator() | ||
848 | 225 | |||
849 | 226 | try: | ||
850 | 227 | new_indicator.set_property("name", MAILBOXES_NAMES[mailbox]) | ||
851 | 228 | except KeyError: | ||
852 | 229 | new_indicator.set_property("name", mailbox) | ||
853 | 230 | new_indicator.set_property("count", "0") | ||
854 | 231 | new_indicator.label = mailbox | ||
855 | 232 | new_indicator.connect("user-display", self.labelClick) | ||
856 | 233 | self.indicators[mailbox] = new_indicator | ||
857 | 234 | self.indicators["inbox"].show() | ||
858 | 235 | if self.ignore_inbox: self.indicators["inbox"].hide() | ||
859 | 236 | |||
860 | 237 | cm = CheckMail() | 279 | cm = CheckMail() |
861 | 280 | reactor.registerGApplication(cm) | ||
862 | 281 | reactor.run() | ||
863 | 238 | 282 | ||
864 | === modified file 'gm-notify-config' | |||
865 | --- gm-notify-config 2010-09-18 13:06:25 +0000 | |||
866 | +++ gm-notify-config 2013-03-25 04:23:21 +0000 | |||
867 | @@ -19,19 +19,18 @@ | |||
868 | 19 | # You should have received a copy of the GNU General Public License | 19 | # You should have received a copy of the GNU General Public License |
869 | 20 | # along with this program. If not, see <http://www.gnu.org/licenses/>. | 20 | # along with this program. If not, see <http://www.gnu.org/licenses/>. |
870 | 21 | # | 21 | # |
871 | 22 | from __future__ import print_function | ||
872 | 23 | |||
873 | 22 | import sys | 24 | import sys |
874 | 23 | import os | 25 | import os |
875 | 24 | import gettext | 26 | import gettext |
876 | 25 | import subprocess | 27 | import subprocess |
877 | 26 | import shutil | 28 | import shutil |
878 | 27 | 29 | ||
886 | 28 | import pynotify | 30 | from gi.repository import Gio, Gtk |
887 | 29 | import pygtk | 31 | |
888 | 30 | pygtk.require("2.0") | 32 | from twisted.internet import gtk3reactor |
889 | 31 | import gtk, gtk.glade | 33 | gtk3reactor.install() |
883 | 32 | import gconf | ||
884 | 33 | from twisted.internet import gtk2reactor | ||
885 | 34 | gtk2reactor.install() | ||
890 | 35 | from twisted.internet import reactor | 34 | from twisted.internet import reactor |
891 | 36 | from twisted.words.protocols.jabber import jid | 35 | from twisted.words.protocols.jabber import jid |
892 | 37 | 36 | ||
893 | @@ -39,8 +38,6 @@ | |||
894 | 39 | from gtalk import MailChecker | 38 | from gtalk import MailChecker |
895 | 40 | 39 | ||
896 | 41 | _ = gettext.translation('gm-notify', fallback=True).ugettext | 40 | _ = gettext.translation('gm-notify', fallback=True).ugettext |
897 | 42 | if not pynotify.init(_("GMail Notifier")): | ||
898 | 43 | sys.exit(-1) | ||
899 | 44 | 41 | ||
900 | 45 | class PathNotFound(Exception): pass | 42 | class PathNotFound(Exception): pass |
901 | 46 | 43 | ||
902 | @@ -53,24 +50,39 @@ | |||
903 | 53 | if os.path.exists(path) and os.access(path, os.X_OK): return path | 50 | if os.path.exists(path) and os.access(path, os.X_OK): return path |
904 | 54 | raise PathNotFound("%s not found" % name) | 51 | raise PathNotFound("%s not found" % name) |
905 | 55 | 52 | ||
907 | 56 | class Window: | 53 | class Window(Gtk.Application): |
908 | 57 | def __init__(self): | 54 | def __init__(self): |
909 | 55 | super(Window, self).__init__(application_id="net.launchpad.gm-notify-config", | ||
910 | 56 | flags=Gio.ApplicationFlags.FLAGS_NONE) | ||
911 | 57 | self.window = None | ||
912 | 58 | self.connect("activate", self.on_activate) | ||
913 | 59 | |||
914 | 60 | def on_activate(self, app): | ||
915 | 61 | '''Setup the application''' | ||
916 | 62 | if self.window is not None: | ||
917 | 63 | return | ||
918 | 64 | |||
919 | 58 | ##### | 65 | ##### |
920 | 59 | # GUI initialization | 66 | # GUI initialization |
921 | 60 | ##### | 67 | ##### |
922 | 61 | self.keys = keyring.Keyring("GMail", "mail.google.com", "http") | 68 | self.keys = keyring.Keyring("GMail", "mail.google.com", "http") |
924 | 62 | self.client = gconf.client_get_default() | 69 | self.client = Gio.Settings("net.launchpad.gm-notify") |
925 | 63 | 70 | ||
932 | 64 | if os.path.exists("gm-config.glade"): | 71 | if os.path.exists("gm-config.ui"): |
933 | 65 | glade_file = "gm-config.glade" | 72 | builder_file = "gm-config.ui" |
934 | 66 | elif os.path.exists("/usr/local/share/gm-notify/gm-config.glade"): | 73 | elif os.path.exists("/usr/local/share/gm-notify/gm-config.ui"): |
935 | 67 | glade_file = "/usr/local/share/gm-notify/gm-config.glade" | 74 | builder_file = "/usr/local/share/gm-notify/gm-config.ui" |
936 | 68 | elif os.path.exists("/usr/share/gm-notify/gm-config.glade"): | 75 | elif os.path.exists("/usr/share/gm-notify/gm-config.ui"): |
937 | 69 | glade_file = "/usr/share/gm-notify/gm-config.glade" | 76 | builder_file = "/usr/share/gm-notify/gm-config.ui" |
938 | 70 | 77 | ||
941 | 71 | self.wTree = gtk.glade.XML(glade_file, "gmnotify_config_main", "gm-notify") | 78 | self.wTree = Gtk.Builder.new() |
942 | 72 | self.window = self.wTree.get_widget("gmnotify_config_main") | 79 | self.wTree.add_from_file(builder_file) |
943 | 80 | self.wTree.set_translation_domain("gm-notify") | ||
944 | 81 | self.window = self.wTree.get_object("gmnotify_config_main") | ||
945 | 73 | self.window.show_all() | 82 | self.window.show_all() |
946 | 83 | self.add_window(self.window) | ||
947 | 84 | |||
948 | 85 | self.wTree.get_object("notebook_main").set_current_page(0) | ||
949 | 74 | 86 | ||
950 | 75 | ##### | 87 | ##### |
951 | 76 | # Init with stored values | 88 | # Init with stored values |
952 | @@ -81,8 +93,8 @@ | |||
953 | 81 | self.creds = self.keys.get_credentials() | 93 | self.creds = self.keys.get_credentials() |
954 | 82 | else: | 94 | else: |
955 | 83 | self.creds = ("", "") | 95 | self.creds = ("", "") |
958 | 84 | self.wTree.get_widget("input_user").set_text(self.creds[0]) | 96 | self.wTree.get_object("input_user").set_text(self.creds[0]) |
959 | 85 | self.wTree.get_widget("input_password").set_text(self.creds[1]) | 97 | self.wTree.get_object("input_password").set_text(self.creds[1]) |
960 | 86 | 98 | ||
961 | 87 | self.api = MailChecker("", "") | 99 | self.api = MailChecker("", "") |
962 | 88 | self.api.cb_auth_successful = self.credentials_valid | 100 | self.api.cb_auth_successful = self.credentials_valid |
963 | @@ -91,68 +103,64 @@ | |||
964 | 91 | self.check_credentials(None, None) | 103 | self.check_credentials(None, None) |
965 | 92 | 104 | ||
966 | 93 | # Sound | 105 | # Sound |
971 | 94 | self.wTree.get_widget("checkbutton_sound").set_active(self.client.get_bool("/apps/gm-notify/play_sound")) | 106 | self.wTree.get_object("checkbutton_sound").set_active(self.client.get_boolean("play-sound")) |
972 | 95 | if self.client.get_string("/apps/gm-notify/soundfile"): | 107 | if self.client.get_string("soundfile"): |
973 | 96 | self.wTree.get_widget("fcbutton_sound").set_filename(self.client.get_string("/apps/gm-notify/soundfile")) | 108 | self.wTree.get_object("fcbutton_sound").set_filename(self.client.get_string("soundfile")) |
974 | 97 | self.on_checkbutton_sound_toggled(self.wTree.get_widget("checkbutton_sound")) | 109 | self.on_checkbutton_sound_toggled(self.wTree.get_object("checkbutton_sound")) |
975 | 98 | 110 | ||
976 | 99 | # ClickAction | 111 | # ClickAction |
979 | 100 | if self.client.get_bool("/apps/gm-notify/openclient"): | 112 | if self.client.get_boolean("openclient"): |
980 | 101 | self.wTree.get_widget("radiobutton_openclient").set_active(True) | 113 | self.wTree.get_object("radiobutton_openclient").set_active(True) |
981 | 102 | else: | 114 | else: |
983 | 103 | self.wTree.get_widget("radiobutton_openweb").set_active(True) | 115 | self.wTree.get_object("radiobutton_openweb").set_active(True) |
984 | 104 | 116 | ||
985 | 105 | # Mailboxes | 117 | # Mailboxes |
989 | 106 | mailboxes = self.client.get_list("/apps/gm-notify/mailboxes", gconf.VALUE_STRING) | 118 | mailboxes = self.client.get_strv("mailboxes") |
990 | 107 | self.wTree.get_widget("checkbutton_inbox").set_active(self.client.get_bool("/apps/gm-notify/ignore_inbox")) | 119 | self.wTree.get_object("checkbutton_inbox").set_active(self.client.get_boolean("ignore-inbox")) |
991 | 108 | self.wTree.get_widget("entry_labels").set_text(", ".join(mailboxes)) | 120 | self.wTree.get_object("entry_labels").set_text(", ".join(mailboxes)) |
992 | 109 | 121 | ||
993 | 110 | # Autorun | 122 | # Autorun |
994 | 111 | if os.path.exists("data/gm-notify.desktop"): | 123 | if os.path.exists("data/gm-notify.desktop"): |
995 | 112 | self.gm_notify_autostart_file = "data/gm-notify.desktop" | 124 | self.gm_notify_autostart_file = "data/gm-notify.desktop" |
1000 | 113 | elif os.path.exists("/usr/local/share/gm-notify/gm-notify.desktop"): | 125 | elif os.path.exists("/usr/local/share/applications/gm-notify.desktop"): |
1001 | 114 | self.gm_notify_autostart_file = "/usr/local/share/gm-notify/gm-notify.desktop" | 126 | self.gm_notify_autostart_file = "/usr/local/share/applications/gm-notify.desktop" |
1002 | 115 | elif os.path.exists("/usr/share/gm-notify/gm-notify.desktop"): | 127 | elif os.path.exists("/usr/share/applications/gm-notify.desktop"): |
1003 | 116 | self.gm_notify_autostart_file = "/usr/share/gm-notify/gm-notify.desktop" | 128 | self.gm_notify_autostart_file = "/usr/share/applications/gm-notify.desktop" |
1004 | 117 | self.autostart_file = os.path.expanduser("~/.config/autostart/gm-notify.desktop") | 129 | self.autostart_file = os.path.expanduser("~/.config/autostart/gm-notify.desktop") |
1006 | 118 | self.wTree.get_widget("checkbutton_autostart").set_active(os.path.exists(self.autostart_file)) | 130 | self.wTree.get_object("checkbutton_autostart").set_active(os.path.exists(self.autostart_file)) |
1007 | 119 | 131 | ||
1014 | 120 | signals = { "gtk_main_quit": self.terminate, | 132 | # Connect signals |
1015 | 121 | "on_button_apply_clicked": self.save, | 133 | self.wTree.get_object("button_close").connect("clicked", self.terminate) |
1016 | 122 | "on_input_password_focus_out_event": self.check_credentials, | 134 | self.wTree.get_object("button_apply").connect("clicked", self.save) |
1017 | 123 | "on_checkbutton_sound_toggled": self.on_checkbutton_sound_toggled, | 135 | self.wTree.get_object("input_password").connect("focus-out-event", self.check_credentials) |
1018 | 124 | } | 136 | self.wTree.get_object("checkbutton_sound").connect("toggled", self.on_checkbutton_sound_toggled) |
1013 | 125 | self.wTree.signal_autoconnect(signals) | ||
1019 | 126 | 137 | ||
1020 | 127 | def save(self, widget, data=None): | 138 | def save(self, widget, data=None): |
1021 | 128 | '''saves the entered data and closes the app''' | 139 | '''saves the entered data and closes the app''' |
1022 | 129 | |||
1023 | 130 | self.client.add_dir("/apps/gm-notify", gconf.CLIENT_PRELOAD_NONE) | ||
1024 | 131 | |||
1025 | 132 | # Credentials | 140 | # Credentials |
1026 | 133 | self.keys.delete_credentials() | 141 | self.keys.delete_credentials() |
1029 | 134 | self.keys.set_credentials(( self.wTree.get_widget("input_user").get_text(), | 142 | self.keys.set_credentials(self.wTree.get_object("input_user").get_text(), |
1030 | 135 | self.wTree.get_widget("input_password").get_text())) | 143 | self.wTree.get_object("input_password").get_text()) |
1031 | 136 | 144 | ||
1032 | 137 | # Mailboxes | 145 | # Mailboxes |
1033 | 138 | mailboxes = [] | 146 | mailboxes = [] |
1035 | 139 | for label in self.wTree.get_widget("entry_labels").get_text().split(","): | 147 | for label in self.wTree.get_object("entry_labels").get_text().split(","): |
1036 | 140 | mailboxes.append(label.strip()) | 148 | mailboxes.append(label.strip()) |
1039 | 141 | self.client.set_list("/apps/gm-notify/mailboxes", gconf.VALUE_STRING, mailboxes) | 149 | self.client.set_strv("mailboxes", mailboxes) |
1040 | 142 | self.client.set_bool("/apps/gm-notify/ignore_inbox", self.wTree.get_widget("checkbutton_inbox").get_active()) | 150 | self.client.set_boolean("ignore-inbox", self.wTree.get_object("checkbutton_inbox").get_active()) |
1041 | 143 | 151 | ||
1042 | 144 | # ClickAction | 152 | # ClickAction |
1044 | 145 | self.client.set_bool("/apps/gm-notify/openclient", self.wTree.get_widget("radiobutton_openclient").get_active()) | 153 | self.client.set_boolean("openclient", self.wTree.get_object("radiobutton_openclient").get_active()) |
1045 | 146 | 154 | ||
1046 | 147 | # Soundfile | 155 | # Soundfile |
1050 | 148 | if self.wTree.get_widget("checkbutton_sound").get_active() and self.wTree.get_widget("fcbutton_sound").get_filename(): | 156 | if self.wTree.get_object("checkbutton_sound").get_active() and self.wTree.get_object("fcbutton_sound").get_filename(): |
1051 | 149 | self.client.set_bool("/apps/gm-notify/play_sound", True) | 157 | self.client.set_boolean("play-sound", True) |
1052 | 150 | self.client.set_string("/apps/gm-notify/soundfile", str(self.wTree.get_widget("fcbutton_sound").get_filename())) | 158 | self.client.set_string("soundfile", str(self.wTree.get_object("fcbutton_sound").get_filename())) |
1053 | 151 | else: | 159 | else: |
1055 | 152 | self.client.set_bool("/apps/gm-notify/play_sound", False) | 160 | self.client.set_boolean("play-sound", False) |
1056 | 153 | 161 | ||
1057 | 154 | # Autorun | 162 | # Autorun |
1059 | 155 | if self.wTree.get_widget("checkbutton_autostart").get_active(): | 163 | if self.wTree.get_object("checkbutton_autostart").get_active(): |
1060 | 156 | if not os.path.exists(self.autostart_file): | 164 | if not os.path.exists(self.autostart_file): |
1061 | 157 | try: | 165 | try: |
1062 | 158 | os.makedirs(os.path.expanduser("~/.config/autostart")) | 166 | os.makedirs(os.path.expanduser("~/.config/autostart")) |
1063 | @@ -163,13 +171,13 @@ | |||
1064 | 163 | shutil.copyfile(self.gm_notify_autostart_file, self.autostart_file) | 171 | shutil.copyfile(self.gm_notify_autostart_file, self.autostart_file) |
1065 | 164 | os.chmod(self.autostart_file, 0700) | 172 | os.chmod(self.autostart_file, 0700) |
1066 | 165 | except IOError: | 173 | except IOError: |
1068 | 166 | print "Warning: cannot write to path", self.autostart_file | 174 | print("Warning: cannot write to path", self.autostart_file) |
1069 | 167 | else: | 175 | else: |
1070 | 168 | if os.path.exists(self.autostart_file): | 176 | if os.path.exists(self.autostart_file): |
1071 | 169 | try: | 177 | try: |
1072 | 170 | os.unlink(self.autostart_file) | 178 | os.unlink(self.autostart_file) |
1073 | 171 | except: | 179 | except: |
1075 | 172 | print "Warning: cannot delete", self.autostart_file | 180 | print("Warning: cannot delete", self.autostart_file) |
1076 | 173 | 181 | ||
1077 | 174 | # Start gm-notify itself | 182 | # Start gm-notify itself |
1078 | 175 | subprocess.Popen(get_executable_path("gm-notify")) | 183 | subprocess.Popen(get_executable_path("gm-notify")) |
1079 | @@ -178,16 +186,16 @@ | |||
1080 | 178 | reactor.stop() | 186 | reactor.stop() |
1081 | 179 | 187 | ||
1082 | 180 | def on_checkbutton_sound_toggled(self, widget): | 188 | def on_checkbutton_sound_toggled(self, widget): |
1084 | 181 | self.wTree.get_widget("fcbutton_sound").set_sensitive(self.wTree.get_widget("checkbutton_sound").get_active()) | 189 | self.wTree.get_object("fcbutton_sound").set_sensitive(self.wTree.get_object("checkbutton_sound").get_active()) |
1085 | 182 | 190 | ||
1086 | 183 | def check_credentials(self, widget, event, data=None): | 191 | def check_credentials(self, widget, event, data=None): |
1087 | 184 | '''check if the given credentials are valid''' | 192 | '''check if the given credentials are valid''' |
1088 | 185 | 193 | ||
1094 | 186 | input_user = self.wTree.get_widget("input_user") | 194 | input_user = self.wTree.get_object("input_user") |
1095 | 187 | input_password = self.wTree.get_widget("input_password") | 195 | input_password = self.wTree.get_object("input_password") |
1096 | 188 | image_credentials = self.wTree.get_widget("image_credentials") | 196 | image_credentials = self.wTree.get_object("image_credentials") |
1097 | 189 | label_credentials = self.wTree.get_widget("label_credentials") | 197 | label_credentials = self.wTree.get_object("label_credentials") |
1098 | 190 | button_apply = self.wTree.get_widget("button_apply") | 198 | button_apply = self.wTree.get_object("button_apply") |
1099 | 191 | button_apply.set_sensitive(False) | 199 | button_apply.set_sensitive(False) |
1100 | 192 | 200 | ||
1101 | 193 | # Change status text and disable input fields | 201 | # Change status text and disable input fields |
1102 | @@ -203,13 +211,13 @@ | |||
1103 | 203 | return False | 211 | return False |
1104 | 204 | 212 | ||
1105 | 205 | def credentials_valid(self): | 213 | def credentials_valid(self): |
1111 | 206 | input_user = self.wTree.get_widget("input_user") | 214 | input_user = self.wTree.get_object("input_user") |
1112 | 207 | input_password = self.wTree.get_widget("input_password") | 215 | input_password = self.wTree.get_object("input_password") |
1113 | 208 | image_credentials = self.wTree.get_widget("image_credentials") | 216 | image_credentials = self.wTree.get_object("image_credentials") |
1114 | 209 | label_credentials = self.wTree.get_widget("label_credentials") | 217 | label_credentials = self.wTree.get_object("label_credentials") |
1115 | 210 | button_apply = self.wTree.get_widget("button_apply") | 218 | button_apply = self.wTree.get_object("button_apply") |
1116 | 211 | 219 | ||
1118 | 212 | image_credentials.set_from_icon_name("gtk-yes", gtk.ICON_SIZE_MENU) | 220 | image_credentials.set_from_icon_name("gtk-yes", Gtk.IconSize.MENU) |
1119 | 213 | label_credentials.set_text(_("Valid credentials")) | 221 | label_credentials.set_text(_("Valid credentials")) |
1120 | 214 | button_apply.set_sensitive(True) | 222 | button_apply.set_sensitive(True) |
1121 | 215 | input_user.set_sensitive(True) | 223 | input_user.set_sensitive(True) |
1122 | @@ -218,12 +226,12 @@ | |||
1123 | 218 | self.api.die() | 226 | self.api.die() |
1124 | 219 | 227 | ||
1125 | 220 | def credentials_invalid(self): | 228 | def credentials_invalid(self): |
1130 | 221 | input_user = self.wTree.get_widget("input_user") | 229 | input_user = self.wTree.get_object("input_user") |
1131 | 222 | input_password = self.wTree.get_widget("input_password") | 230 | input_password = self.wTree.get_object("input_password") |
1132 | 223 | image_credentials = self.wTree.get_widget("image_credentials") | 231 | image_credentials = self.wTree.get_object("image_credentials") |
1133 | 224 | label_credentials = self.wTree.get_widget("label_credentials") | 232 | label_credentials = self.wTree.get_object("label_credentials") |
1134 | 225 | 233 | ||
1136 | 226 | image_credentials.set_from_icon_name("gtk-stop", gtk.ICON_SIZE_MENU) | 234 | image_credentials.set_from_icon_name("gtk-stop", Gtk.IconSize.MENU) |
1137 | 227 | label_credentials.set_text(_("Invalid credentials")) | 235 | label_credentials.set_text(_("Invalid credentials")) |
1138 | 228 | input_user.set_sensitive(True) | 236 | input_user.set_sensitive(True) |
1139 | 229 | input_password.set_sensitive(True) | 237 | input_password.set_sensitive(True) |
1140 | @@ -231,4 +239,5 @@ | |||
1141 | 231 | self.api.die() | 239 | self.api.die() |
1142 | 232 | 240 | ||
1143 | 233 | t = Window() | 241 | t = Window() |
1144 | 242 | reactor.registerGApplication(t) | ||
1145 | 234 | reactor.run() | 243 | reactor.run() |
1146 | 235 | 244 | ||
1147 | === modified file 'gm_notify_keyring.py' | |||
1148 | --- gm_notify_keyring.py 2010-05-05 17:31:35 +0000 | |||
1149 | +++ gm_notify_keyring.py 2013-03-25 04:23:21 +0000 | |||
1150 | @@ -1,43 +1,59 @@ | |||
1151 | 1 | from __future__ import print_function | ||
1152 | 2 | |||
1153 | 1 | __version__ = "$Revision: 14294 $" | 3 | __version__ = "$Revision: 14294 $" |
1154 | 2 | 4 | ||
1158 | 3 | import gtk # ensure that the application name is correctly set | 5 | from gi.repository import GnomeKeyring, Gtk |
1159 | 4 | import gnomekeyring as gkey | 6 | |
1160 | 5 | 7 | def attributes(d): | |
1161 | 8 | '''Converts a dictionary to a GnomeKeyring.Attribute array''' | ||
1162 | 9 | attrs = GnomeKeyring.Attribute.list_new() | ||
1163 | 10 | for key in d: | ||
1164 | 11 | GnomeKeyring.Attribute.list_append_string(attrs, key, str(d[key])) | ||
1165 | 12 | return attrs | ||
1166 | 13 | |||
1167 | 14 | def dict_from_attributes(attrs): | ||
1168 | 15 | '''Converts item results back into a dictionary''' | ||
1169 | 16 | result = {} | ||
1170 | 17 | for attr in GnomeKeyring.Attribute.list_to_glist(attrs): | ||
1171 | 18 | result[attr.name] = attr.get_string() | ||
1172 | 19 | return result | ||
1173 | 20 | |||
1174 | 21 | class KeyringException(Exception): | ||
1175 | 22 | pass | ||
1176 | 6 | 23 | ||
1177 | 7 | class Keyring(object): | 24 | class Keyring(object): |
1178 | 8 | def __init__(self, name, server, protocol): | 25 | def __init__(self, name, server, protocol): |
1179 | 9 | self._name = name | 26 | self._name = name |
1180 | 10 | self._server = server | 27 | self._server = server |
1181 | 11 | self._protocol = protocol | 28 | self._protocol = protocol |
1183 | 12 | self._keyring = gkey.get_default_keyring_sync() | 29 | result, self._keyring = GnomeKeyring.get_default_keyring_sync() |
1184 | 13 | 30 | ||
1185 | 14 | def has_credentials(self): | 31 | def has_credentials(self): |
1191 | 15 | try: | 32 | attrs = attributes({"server": self._server, "protocol": self._protocol}) |
1192 | 16 | attrs = {"server": self._server, "protocol": self._protocol} | 33 | result, items = GnomeKeyring.find_items_sync(GnomeKeyring.ItemType.NETWORK_PASSWORD, attrs) |
1193 | 17 | items = gkey.find_items_sync(gkey.ITEM_NETWORK_PASSWORD, attrs) | 34 | if result in (GnomeKeyring.Result.NO_MATCH, GnomeKeyring.Result.DENIED): |
1189 | 18 | return len(items) > 0 | ||
1190 | 19 | except (gkey.DeniedError, gkey.NoMatchError): | ||
1194 | 20 | return False | 35 | return False |
1195 | 36 | return len(items) > 0 | ||
1196 | 21 | 37 | ||
1197 | 22 | def get_credentials(self): | 38 | def get_credentials(self): |
1201 | 23 | attrs = {"server": self._server, "protocol": self._protocol} | 39 | attrs = attributes({"server": self._server, "protocol": self._protocol}) |
1202 | 24 | items = gkey.find_items_sync(gkey.ITEM_NETWORK_PASSWORD, attrs) | 40 | result, items = GnomeKeyring.find_items_sync(GnomeKeyring.ItemType.NETWORK_PASSWORD, attrs) |
1203 | 25 | return (items[0].attributes["user"], items[0].secret) | 41 | if len(items) == 0: |
1204 | 42 | raise KeyringException("Credentials not found") | ||
1205 | 43 | d = dict_from_attributes(items[0].attributes) | ||
1206 | 44 | return (d["user"], items[0].secret) | ||
1207 | 26 | 45 | ||
1208 | 27 | def delete_credentials(self): | 46 | def delete_credentials(self): |
1216 | 28 | attrs = {"server": self._server, "protocol": self._protocol} | 47 | attrs = attributes({"server": self._server, "protocol": self._protocol}) |
1217 | 29 | try: | 48 | result, items = GnomeKeyring.find_items_sync(GnomeKeyring.ItemType.NETWORK_PASSWORD, attrs) |
1218 | 30 | items = gkey.find_items_sync(gkey.ITEM_NETWORK_PASSWORD, attrs) | 49 | for item in items: |
1219 | 31 | for item in items: | 50 | GnomeKeyring.item_delete_sync(self._keyring, item.item_id) |
1213 | 32 | gkey.item_delete_sync(None, item.item_id) | ||
1214 | 33 | except (gkey.DeniedError, gkey.NoMatchError): | ||
1215 | 34 | pass | ||
1220 | 35 | 51 | ||
1223 | 36 | def set_credentials(self, (user, pw)): | 52 | def set_credentials(self, user, pw): |
1224 | 37 | attrs = { | 53 | attrs = attributes({ |
1225 | 38 | "user": user, | 54 | "user": user, |
1226 | 39 | "server": self._server, | 55 | "server": self._server, |
1227 | 40 | "protocol": self._protocol, | 56 | "protocol": self._protocol, |
1231 | 41 | } | 57 | }) |
1232 | 42 | gkey.item_create_sync(gkey.get_default_keyring_sync(), | 58 | GnomeKeyring.item_create_sync(self._keyring, |
1233 | 43 | gkey.ITEM_NETWORK_PASSWORD, self._name, attrs, pw, True) | 59 | GnomeKeyring.ItemType.NETWORK_PASSWORD, self._name, attrs, pw, True) |
1234 | 44 | 60 | ||
1235 | === modified file 'gtalk.py' | |||
1236 | --- gtalk.py 2010-09-18 13:06:25 +0000 | |||
1237 | +++ gtalk.py 2013-03-25 04:23:21 +0000 | |||
1238 | @@ -19,17 +19,19 @@ | |||
1239 | 19 | # You should have received a copy of the GNU General Public License | 19 | # You should have received a copy of the GNU General Public License |
1240 | 20 | # along with this program. If not, see <http://www.gnu.org/licenses/>. | 20 | # along with this program. If not, see <http://www.gnu.org/licenses/>. |
1241 | 21 | # | 21 | # |
1242 | 22 | from __future__ import print_function | ||
1243 | 23 | |||
1244 | 22 | from threading import Event | 24 | from threading import Event |
1245 | 23 | 25 | ||
1246 | 24 | from twisted.words.protocols.jabber import xmlstream, client, jid | 26 | from twisted.words.protocols.jabber import xmlstream, client, jid |
1247 | 25 | from twisted.words.xish import domish | 27 | from twisted.words.xish import domish |
1249 | 26 | from twisted.internet import reactor, task | 28 | from twisted.internet import reactor, task, error |
1250 | 27 | 29 | ||
1251 | 28 | _DEBUG = False | 30 | _DEBUG = False |
1252 | 29 | COLOR_GREEN = "\033[92m" | 31 | COLOR_GREEN = "\033[92m" |
1253 | 30 | COLOR_END = "\033[0m" | 32 | COLOR_END = "\033[0m" |
1254 | 31 | def DEBUG(msg): | 33 | def DEBUG(msg): |
1256 | 32 | if _DEBUG: print COLOR_GREEN + str(msg) + COLOR_END | 34 | if _DEBUG: print(COLOR_GREEN + str(msg) + COLOR_END) |
1257 | 33 | 35 | ||
1258 | 34 | class GTalkClientFactory(xmlstream.XmlStreamFactory): | 36 | class GTalkClientFactory(xmlstream.XmlStreamFactory): |
1259 | 35 | def __init__(self, jid, password): | 37 | def __init__(self, jid, password): |
1260 | @@ -89,7 +91,11 @@ | |||
1261 | 89 | self.connector.disconnect() # Our reconnecting factory will try the reconnecting | 91 | self.connector.disconnect() # Our reconnecting factory will try the reconnecting |
1262 | 90 | 92 | ||
1263 | 91 | def send_callback_handler(self, data, callback=None, **kargs): | 93 | def send_callback_handler(self, data, callback=None, **kargs): |
1265 | 92 | self.timeout_call_id.cancel() | 94 | try: |
1266 | 95 | self.timeout_call_id.cancel() | ||
1267 | 96 | except error.AlreadyCalled: | ||
1268 | 97 | DEBUG("already called timeout_call_id.cancel()") | ||
1269 | 98 | return | ||
1270 | 93 | if callback: | 99 | if callback: |
1271 | 94 | callback(data, **kargs) | 100 | callback(data, **kargs) |
1272 | 95 | else: | 101 | else: |
1273 | @@ -242,10 +248,10 @@ | |||
1274 | 242 | if iq: self.queryInbox() | 248 | if iq: self.queryInbox() |
1275 | 243 | 249 | ||
1276 | 244 | def rawDataIn(self, buf): | 250 | def rawDataIn(self, buf): |
1278 | 245 | print u"< %s" % unicode(buf, "utf-8") | 251 | print(u"< %s" % unicode(buf, "utf-8")) |
1279 | 246 | 252 | ||
1280 | 247 | def rawDataOut(self, buf): | 253 | def rawDataOut(self, buf): |
1282 | 248 | print u"> %s" % unicode(buf, "utf-8") | 254 | print(u"> %s" % unicode(buf, "utf-8")) |
1283 | 249 | 255 | ||
1284 | 250 | def connectedCB(self, xmlstream): | 256 | def connectedCB(self, xmlstream): |
1285 | 251 | self.xmlstream = xmlstream | 257 | self.xmlstream = xmlstream |
1286 | 252 | 258 | ||
1287 | === modified file 'setup.py' | |||
1288 | --- setup.py 2010-09-18 13:06:25 +0000 | |||
1289 | +++ setup.py 2013-03-25 04:23:21 +0000 | |||
1290 | @@ -10,11 +10,10 @@ | |||
1291 | 10 | py_modules=['gtalk', 'gm_notify_keyring'], | 10 | py_modules=['gtalk', 'gm_notify_keyring'], |
1292 | 11 | scripts=['gm-notify', 'gm-notify-config'], | 11 | scripts=['gm-notify', 'gm-notify-config'], |
1293 | 12 | data_files=[('/usr/share/applications', ['data/gm-notify-config.desktop']), | 12 | data_files=[('/usr/share/applications', ['data/gm-notify-config.desktop']), |
1296 | 13 | ('/usr/share/indicators/messages/applications', ['data/gm-notify']), | 13 | ('/usr/share/applications', ['data/gm-notify.desktop']), |
1295 | 14 | ('/usr/share/gm-notify', ['data/gm-notify.desktop']), | ||
1297 | 15 | ('/usr/share/gm-notify', ['data/checking.gif']), | 14 | ('/usr/share/gm-notify', ['data/checking.gif']), |
1300 | 16 | ('/usr/share/gm-notify', ['gm-config.glade']), | 15 | ('/usr/share/gm-notify', ['gm-config.ui']), |
1301 | 17 | ('/etc/gconf/schemas', ['data/gm-notify.schemas']), | 16 | ('/usr/share/glib-2.0/schemas', ['data/net.launchpad.gm-notify.gschema.xml']), |
1302 | 18 | ('/usr/share/locale/da/LC_MESSAGES', ['po/da/gm-notify.mo']), | 17 | ('/usr/share/locale/da/LC_MESSAGES', ['po/da/gm-notify.mo']), |
1303 | 19 | ('/usr/share/locale/bg/LC_MESSAGES', ['po/bg/gm-notify.mo']), | 18 | ('/usr/share/locale/bg/LC_MESSAGES', ['po/bg/gm-notify.mo']), |
1304 | 20 | ('/usr/share/locale/de/LC_MESSAGES', ['po/de/gm-notify.mo']), | 19 | ('/usr/share/locale/de/LC_MESSAGES', ['po/de/gm-notify.mo']), |
This looks very good, I'm considering to upload this into Ubuntu Archive, as it has MessagingMenu support, among many other improvements.