3 import hildon, hildondesktop
8 import atexit, os, datetime
9 from dbus.mainloop.glib import DBusGMainLoop
12 class CallNotify(hildondesktop.StatusMenuItem):
14 hildondesktop.StatusMenuItem.__init__(self)
17 self.configDir = "/home/user/.config/CallNotify/"
18 self.configFile = "conf.txt"
19 self.readConfigurationFile()
23 self.path = "/home/user/.rtcom-eventlogger/el.db"
24 self.missed = self.getMissedCallsCount(False)
25 self.missedSMS = self.getMissedCallsCount(True)
26 self.missedLastCall = self.missed
27 self.missedLastSMS = self.missedSMS
29 self.soundFile = "/usr/share/CallNotify/missed.wav"
30 self.dbg('constructor')
35 # Register to handle screen off/on events
36 osso_c = osso.Context("osso_test_device_on", "0.0.1", False)
37 device = osso.DeviceState(osso_c)
38 #device.set_display_event_cb(self.state_cb)
40 # Check missed calls notification
41 self.tmr_main = gobject.timeout_add(5000, self.handleMissedCall)
43 # add d-bus listener for removing notification after viewing missed call
44 # Doing timeout_add with return False instead of explicitly raising a thread
45 gobject.timeout_add(500, self.startDbusListeners)
46 #atexit.register(self.cleanup)
50 self.dbg('constructor end')
54 label = gtk.Label("Call Notify")
57 button.connect("clicked", self.openSettingsDialog)
60 self.dbg('addGUI end')
62 def checkForConfigFile(self):
63 self.dbg('checkForConfigFile started')
64 if not os.path.exists(self.configDir):
65 os.mkdir(self.configDir)
66 if not os.path.exists(self.configDir+self.configFile):
67 a = open(self.configDir+self.configFile,'w')
72 def readConfigurationFile(self):
73 self.dbg('readConfigurationFile started')
74 self.checkForConfigFile()
75 f = open(self.configDir+self.configFile, 'r')
76 raw_set = f.readline().rsplit(';')
77 self.visual = raw_set[0] in ('y')
78 self.sound = raw_set[1] in ('y')
79 self.vibration = raw_set[2] in ('y')
80 self.interval = float(raw_set[3])
83 def saveConfigurationFile(self):
84 self.dbg('saveConfigurationFile started')
85 f = open(self.configDir+self.configFile, "w")
102 conf += str(self.interval)
107 def openSettingsDialog(self, widget, data=None):
108 self.dbg('openSettingsDialog started')
109 self.dialog = gtk.Dialog(title="Call Notify Settings")
110 self.dialog.set_size_request(800,300)
111 #self.dialog.connect("response", self.dialogClosed)
112 self.readConfigurationFile()
115 b2 = gtk.CheckButton(label="Visual Notification On")
116 b2.connect("clicked", self.notificationActivate)
117 b2.set_active(self.visual)
118 self.dialog.vbox.add(b2)
122 b3 = gtk.CheckButton(label="Sound Notification On")
123 b3.connect("clicked", self.soundActivate)
124 b3.set_active(self.sound)
125 self.dialog.vbox.add(b3)
129 b4 = gtk.CheckButton(label="Vibrate Notification On")
130 b4.connect("clicked", self.vibrateActivate)
131 b4.set_active(self.vibration)
132 self.dialog.vbox.add(b4)
136 Adj = gtk.Adjustment(self.interval, lower=0, upper=60, step_incr=5, page_incr=5)
137 Adj.connect("value_changed", self.intervalChanged)
138 Adj.set_value(self.interval)
140 Slider = gtk.HScale(adjustment=Adj)
141 self.dialog.vbox.add(Slider)
145 b5 = gtk.Button(label="Manually reset notification")
146 b5.connect("clicked", self.resetNotification)
147 self.dialog.vbox.add(b5)
151 bSave = gtk.Button(label="Save")
152 bSave.connect("clicked", self.saveSettings)
153 self.dialog.action_area.add(bSave)
157 bCancel = gtk.Button(label="Cancel")
158 bCancel.connect("clicked", self.cancelDialog)
159 self.dialog.vbox.add(bCancel)
161 self.dialog.show_all()
163 def intervalChanged(self, adj):
164 self.dbg('intervalChanged started')
165 self.interval = adj.value
167 def saveSettings(self, widget, data=None):
168 self.dbg('saveSettings started')
169 self.saveConfigurationFile()
171 def dialogClosed(self, dialog, response_id):
172 self.dbg('dialogClosed started')
174 def cancelDialog(self, widget, data=None):
175 self.dbg('cancelDialog started')
176 self.dialog.destroy()
178 def resetNotification(self, widget, data=None):
179 self.dbg('resetNotification started')
180 self.stop_notification(self)
182 def soundActivate(self, widget, data=None):
183 self.dbg('soundActivate started')
184 self.sound = widget.get_active() #not(self.sound)
186 def notificationActivate(self,widget, data=None):
187 self.dbg('notificationActivate started')
188 self.visual = widget.get_active() #not(self.visual)
190 def vibrateActivate(self, widget, data=None):
191 self.dbg('vibrateActivate started')
192 self.vibration = widget.get_active() #not(self.vibrate)
196 self.dbg('playSound started')
198 hildon.hildon_play_system_sound(self.soundFile)
199 #pygame.time.delay(1000)
201 bb = 'run-standalone.sh dbus-send --print-reply --system --dest=com.nokia.mce /com/nokia/mce/request com.nokia.mce.request.req_vibrator_pattern_activate string:' + "\'PatternIncomingCall\'"
205 bb = 'run-standalone.sh dbus-send --print-reply --system --dest=com.nokia.mce /com/nokia/mce/request com.nokia.mce.request.req_vibrator_pattern_deactivate string:' + "\'PatternIncomingCall\'"
212 self.dbg('cleanup started')
213 gobject.source_remove(self.tmr_main)
214 gobject.source_remove(self.tmr_ptr)
215 gobject.source_remove(self.tmr_ptr2)
219 def loadImages(self):
220 self.dbg('loadImages started')
222 #self.pixbuf = gtk.gdk.pixbuf_new_from_file_at_size("/home/user/phone.png",18,18)
223 icon_theme = gtk.icon_theme_get_default()
224 self.callPicture = gtk.gdk.pixbuf_new_from_file_at_size("/usr/share/CallNotify/call.png",18,18)
225 #icon_theme.load_icon("general_call", 18, gtk.ICON_LOOKUP_NO_SVG)
226 self.smsPicture = gtk.gdk.pixbuf_new_from_file_at_size("/usr/share/CallNotify/sms.png",18,18)
228 # Load 5 numbers and the "+5"
230 #self.imgList.append(gtk.gdk.pixbuf_new_from_file_at_size("/home/user/1.png",18,18))
231 self.imgList.append(gtk.gdk.pixbuf_new_from_file_at_size("/usr/share/CallNotify/1.png",18,18))
232 self.imgList.append(gtk.gdk.pixbuf_new_from_file_at_size("/usr/share/CallNotify/2.png",18,18))
233 self.imgList.append(gtk.gdk.pixbuf_new_from_file_at_size("/usr/share/CallNotify/3.png",18,18))
234 self.imgList.append(gtk.gdk.pixbuf_new_from_file_at_size("/usr/share/CallNotify/4.png",18,18))
235 self.imgList.append(gtk.gdk.pixbuf_new_from_file_at_size("/usr/share/CallNotify/5.png",18,18))
236 self.imgList.append(gtk.gdk.pixbuf_new_from_file_at_size("/usr/share/CallNotify/more.png",18,18))
238 # Screen off event-handler
239 def state_cb(self, state, a):
240 self.dbg('state_cb started')
241 if state == osso.device_state.OSSO_DISPLAY_OFF:
243 #gobject.source_remove(self.tmr_main)
245 #gobject.source_remove(self.tmr_ptr)
247 #gobject.source_remove(self.tmr_ptr2)
250 elif state == osso.device_state.OSSO_DISPLAY_ON:
253 #self.tmr_main = gobject.timeout_add(5000, self.handleMissedCall)
254 #self.handleMissedCall()
257 # Method to define the way to add dbus signal receiver
259 def smsRead2(self, a):
260 self.dbg('smsrec started')
261 self.stop_notification(self)
263 def startDbusListeners(self):
264 self.dbg('startDbusListeners started')
265 DBusGMainLoop(set_as_default=True)
266 bus = dbus.SessionBus()
267 #bus.add_signal_receiver(self.stop_notification, "NotificationClosed", "org.freedesktop.Notifications", "org.freedesktop.Notifications", "/org/freedesktop/Notifications")
268 #bus.add_signal_receiver(self.handleMissedCall, "Notify", None, None, None)
269 #bus.add_signal_receiver(self.handleMissedCall, "MembersChanged", None, None, None)
270 bus.add_signal_receiver(self.smsReceived, "MessageReceived", None, None, None)
271 bus.add_signal_receiver(self.smsRead, "NotificationClosed", "org.freedesktop.Notifications", None, "/org/freedesktop/Notifications")
272 bus.add_signal_receiver(self.smsRead2, "PendingMessagesRemoved", None, None, None)
274 self.mainLoop = gobject.MainLoop()
278 def smsReceived(self, a):
279 self.dbg('snsReceived started')
280 if a[0].has_key('message-type'):
281 if self.missedLastSMS == self.getMissedCallsCount(True):
282 if self.msgType == "Call":
283 self.msgType = "Both"
287 self.missedLastSMS = self.getMissedCallsCount(True)
289 def smsRead(self, a):
290 self.dbg('smsRead started')
291 self.stop_notification(a)
293 def handleMissedCall(self):
294 self.dbg('handleMissedCall started')
295 if self.missedLastCall != self.getMissedCallsCount(False):
296 if self.msgType == "SMS":
297 self.msgType = "Both"
299 self.msgType = "Call"
301 self.missedLastCall = self.getMissedCallsCount(False)
304 def stop_notification(self, a):
305 self.dbg('stop_notification started')
307 self.set_status_area_icon(None)
308 # Reset the notification (get recent missed call count)
309 self.missed = self.getMissedCallsCount(False)
310 self.missedSMS = self.getMissedCallsCount(True)
311 self.missedLastCall = self.missed
312 self.missedLastSMS = self.missedSMS
315 gobject.source_remove(self.tmr_ptr)
316 gobject.source_remove(self.tmr_ptr2)
322 self.dbg('theLoop started')
323 missedCalls = self.getMissedCallsCount(False)
324 if self.missedLastCall != missedCalls:
326 self.missedLastCall = missedCalls
329 def getMissedCallsCount(self, isSms):
330 self.dbg('getMissedCallsCount started. agrs: ' + str(isSms))
334 conn = sqlite3.connect(self.path)
336 cur.execute("select count(id) from Events where event_type_id = " + str(eType))
337 return cur.fetchone()[0]
340 self.dbg('show started')
341 # blink the icon every 1 second
343 self.readConfigurationFile()
346 self.tmr_ptr = gobject.timeout_add(1000, self.blinkIcon)
347 self.tmr_ptr2 = gobject.timeout_add(int(self.interval*1000*60), self.playSound)
350 self.dbg('blinkIcon started')
353 img = self.callPicture
354 if self.msgType == "SMS":
355 img = self.smsPicture
356 self.set_status_area_icon(img)
359 img = self.smsPicture
361 counter = self.missed
362 if self.msgType == "SMS":
363 counter = self.missedSMS
365 index = self.getMissedCallsCount(isSMS) - counter - 1
370 if self.msgType != "Both":
371 img = self.imgList[index]
373 self.set_status_area_icon(img)
378 f = open(self.configDir+'log.txt', 'a')
379 f.write(str(datetime.datetime.now()) + ': '+ txt)
384 hd_plugin_type = CallNotify