Ready for mentors
[cgmail.git] / cGmail / lib / notifier.py
blob42691845981a0febeee991c6f6f9b8b6e4996da5
2 # Copyright (C) 2007 Marco Ferragina <marco.ferragina@gmail.com>
4 # This program is free software; you can redistribute it and/or modify
5 # it under the terms of the GNU General Public License as published by
6 # the Free Software Foundation; either version 2 of the License, or
7 # (at your option) any later version.
9 # This program is distributed in the hope that it will be useful,
10 # but WITHOUT ANY WARRANTY; without even the implied warranty of
11 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 # GNU General Public License for more details.
14 # You should have received a copy of the GNU General Public License
15 # along with this program; if not, write to the Free Software
16 # Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
18 try:
19 import dbus
20 from dbus.mainloop.glib import DBusGMainLoop
21 HAVE_DBUS = True
22 except ImportError:
23 HAVE_DBUS = False
25 import gtk
26 import gobject
27 import os
28 import re
30 from common import *
31 #import webbrowser
33 cwd = os.getcwd()
35 ICON = os.path.join(cwd, DEFAULT_NOTIFY_ICON)
36 GLADE_FILE = os.path.join(GLADE_BASE_PATH, "popup_notification_window.glade")
38 notification_instances = 0
39 class NotificationWindow:
40 def __init__(self, title, text, icon = ICON, msec = 3000):
41 global notification_instances
42 notification_instances += 1
44 widgets = gtk.glade.XML(GLADE_FILE, domain="planimo")
45 self.window = widgets.get_widget('popup_notification_window')
46 close_button = widgets.get_widget('close_button')
47 event_type_label = widgets.get_widget('event_type_label')
49 event_description_label = widgets.get_widget('event_description_label')
50 eventbox = widgets.get_widget('eventbox')
51 image = widgets.get_widget('notification_image')
54 event_type_label.set_markup(
55 '<span foreground="black" weight="bold">%s</span>' % title)
57 self.window.modify_bg(gtk.STATE_NORMAL,
58 gtk.gdk.color_parse('#dab255'))
61 bg_color = '#ffffbf'
62 popup_bg_color = gtk.gdk.color_parse(bg_color)
63 close_button.modify_bg(gtk.STATE_NORMAL, popup_bg_color)
64 eventbox.modify_bg(gtk.STATE_NORMAL, popup_bg_color)
65 event_description_label.set_markup(
66 '<span foreground="black">%s</span>' % text)
68 # set the image
69 image.set_from_file(icon)
71 # position the window to bottom-right of screen
72 window_width, window_height = self.window.get_size()
73 pos_x = gtk.gdk.screen_width() - window_width - 1
74 pos_y = gtk.gdk.screen_height() - \
75 notification_instances * (window_height + 2)
76 self.window.move(pos_x, pos_y)
78 widgets.signal_autoconnect(self)
79 self.window.show_all()
80 gobject.timeout_add(msec, self.on_timeout)
82 def on_close_button_clicked(self, widget):
83 global notification_instances
85 self.window.destroy()
86 notification_instances -= 1
88 def on_timeout(self):
89 global notification_instances
91 self.window.destroy()
92 notification_instances -= 1
94 if HAVE_DBUS:
95 dbus_loop = DBusGMainLoop()
96 session_bus = dbus.SessionBus(mainloop = dbus_loop)
97 obj = session_bus.get_object("org.freedesktop.Notifications",
98 "/org/freedesktop/Notifications")
99 notif = dbus.Interface(obj, "org.freedesktop.Notifications")
101 class Notifier:
102 def __init__(self):
103 global notif
104 if HAVE_DBUS:
105 self.notif = notif
106 self.notif.connect_to_signal("ActionInvoked", self.action_cb)
107 self.__actions = {}
108 self.__actions_list = []
110 def action_cb(self, id, act):
111 try:
112 handler = self.__actions[act][0]
113 handler()
114 except Exception:
115 pass
117 def set_actions(self, actions):
118 self.__actions = actions
119 self.__actions_list = []
120 for actname, values in actions.iteritems():
121 self.__actions_list.append(actname)
122 self.__actions_list.append(values[1])
124 def notify(self, title, message, icon = None, msec = 3000):
125 if icon is None:
126 icon = ICON
127 else:
128 cwd = os.getcwd()
129 icon = os.path.join(cwd, icon)
131 iconfile = "file://" + icon
132 # allow bold tag and sub nasty chars
133 message = message.replace("&", "&amp;")
134 message = re.sub(r'<(?!/?b>)', "&lt;", message)
135 message = re.sub(r'(?<!b)>', "&gt;", message)
137 print message
139 if not HAVE_DBUS:
140 # Revert to classic window
141 NotificationWindow(title, message, icon, msec)
142 else:
143 # new api
144 try:
145 self.notif.Notify(
146 "cgmail",
147 dbus.UInt32(0),
148 iconfile,
149 title,
150 message,
151 self.__actions_list,
152 [],
153 dbus.Int32(msec)
155 except Exception, detail:
156 # Nothing to do with dbus:
157 # Revert to classic window
158 print "Warning: Error while trying to use notification-daemon.\n Reverting to classic method.\n Please upgrade your dbus and libnotify version", detail
159 NotificationWindow(title, message, icon, msec)
162 if __name__ == "__main__":
163 n = Notifier()
164 msg = '<span size="larger">Test</span> ok'
165 n.notify("Title", msg, True, msec=10000)
167 import gobject
168 loop = gobject.MainLoop()
169 loop.run()