11 _FREMANTLE_ALARM = "Fremantle"
12 _DIABLO_ALARM = "Diablo"
18 ALARM_TYPE = _FREMANTLE_ALARM
19 except (ImportError, OSError):
21 import osso.alarmd as alarmd
22 ALARM_TYPE = _DIABLO_ALARM
23 except (ImportError, OSError):
24 ALARM_TYPE = _NO_ALARM
27 def _get_start_time(recurrence):
28 now = datetime.datetime.now()
29 startTimeMinute = now.minute + max(recurrence, 5) # being safe
30 startTimeHour = now.hour + int(startTimeMinute / 60)
31 startTimeMinute = startTimeMinute % 59
32 now.replace(minute=startTimeMinute)
33 timestamp = int(time.mktime(now.timetuple()))
37 def _create_recurrence_mask(recurrence, base):
39 >>> bin(_create_recurrence_mask(60, 60))
41 >>> bin(_create_recurrence_mask(30, 60))
42 '0b1000000000000000000000000000001'
43 >>> bin(_create_recurrence_mask(2, 60))
44 '0b10101010101010101010101010101010101010101010101010101010101'
45 >>> bin(_create_recurrence_mask(1, 60))
46 '0b111111111111111111111111111111111111111111111111111111111111'
49 for i in xrange(base / recurrence):
50 mask |= 1 << (recurrence * i)
54 def _unpack_minutes(recurrence):
56 >>> _unpack_minutes(0)
58 >>> _unpack_minutes(1)
60 >>> _unpack_minutes(59)
62 >>> _unpack_minutes(60)
64 >>> _unpack_minutes(129)
66 >>> _unpack_minutes(5 * 60 * 24 + 3 * 60 + 2)
68 >>> _unpack_minutes(12 * 60 * 24 + 3 * 60 + 2)
72 minutesInDay = 24 * minutesInAnHour
73 minutesInAWeek = minutesInDay * 7
75 days = recurrence / minutesInDay
77 recurrence -= days * minutesInDay
78 hours = recurrence / minutesInAnHour
79 recurrence -= hours * minutesInAnHour
80 mins = recurrence % minutesInAnHour
82 assert recurrence == 0, "Recurrence %d" % recurrence
83 return daysOfWeek, hours, mins
86 class _FremantleAlarmHandler(object):
90 _TITLE = "Dialcentral Notifications"
91 _LAUNCHER = os.path.abspath(os.path.join(os.path.dirname(__file__), "alarm_notify.py"))
96 self._alarmCookie = self._INVALID_COOKIE
97 self._launcher = self._LAUNCHER
99 def load_settings(self, config, sectionName):
101 self._recurrence = config.getint(sectionName, "recurrence")
102 self._alarmCookie = config.getint(sectionName, "alarmCookie")
103 launcher = config.get(sectionName, "notifier")
105 self._launcher = launcher
106 except ConfigParser.NoOptionError:
108 except ConfigParser.NoSectionError:
111 def save_settings(self, config, sectionName):
112 config.set(sectionName, "recurrence", str(self._recurrence))
113 config.set(sectionName, "alarmCookie", str(self._alarmCookie))
114 launcher = self._launcher if self._launcher != self._LAUNCHER else ""
115 config.set(sectionName, "notifier", launcher)
117 def apply_settings(self, enabled, recurrence):
118 if recurrence != self._recurrence or enabled != self.isEnabled:
122 self._set_alarm(recurrence)
123 self._recurrence = int(recurrence)
126 def recurrence(self):
127 return self._recurrence
131 return self._alarmCookie != self._INVALID_COOKIE
133 def _set_alarm(self, recurrenceMins):
134 assert 1 <= recurrenceMins, "Notifications set to occur too frequently: %d" % recurrenceMins
135 alarmTime = _get_start_time(recurrenceMins)
137 event = alarm.Event()
138 event.appid = self._TITLE
139 event.alarm_time = alarmTime
140 event.recurrences_left = self._REPEAT_FOREVER
142 action = event.add_actions(1)[0]
143 action.flags |= alarm.ACTION_TYPE_EXEC | alarm.ACTION_WHEN_TRIGGERED
144 action.command = self._launcher
146 recurrence = event.add_recurrences(1)[0]
147 recurrence.mask_min |= _create_recurrence_mask(recurrenceMins, 60)
148 recurrence.mask_hour |= alarm.RECUR_HOUR_DONTCARE
149 recurrence.mask_mday |= alarm.RECUR_MDAY_DONTCARE
150 recurrence.mask_wday |= alarm.RECUR_WDAY_DONTCARE
151 recurrence.mask_mon |= alarm.RECUR_MON_DONTCARE
152 recurrence.special |= alarm.RECUR_SPECIAL_NONE
154 assert event.is_sane()
155 self._alarmCookie = alarm.add_event(event)
157 def _clear_alarm(self):
158 if self._alarmCookie == self._INVALID_COOKIE:
160 alarm.delete_event(self._alarmCookie)
161 self._alarmCookie = self._INVALID_COOKIE
164 class _DiabloAlarmHandler(object):
167 _TITLE = "Dialcentral Notifications"
168 _LAUNCHER = os.path.abspath(os.path.join(os.path.dirname(__file__), "alarm_notify.py"))
174 bus = dbus.SystemBus()
175 self._alarmdDBus = bus.get_object("com.nokia.alarmd", "/com/nokia/alarmd");
176 self._alarmCookie = self._INVALID_COOKIE
177 self._launcher = self._LAUNCHER
179 def load_settings(self, config, sectionName):
181 self._recurrence = config.getint(sectionName, "recurrence")
182 self._alarmCookie = config.getint(sectionName, "alarmCookie")
183 launcher = config.get(sectionName, "notifier")
185 self._launcher = launcher
186 except ConfigParser.NoOptionError:
188 except ConfigParser.NoSectionError:
191 def save_settings(self, config, sectionName):
192 config.set(sectionName, "recurrence", str(self._recurrence))
193 config.set(sectionName, "alarmCookie", str(self._alarmCookie))
194 launcher = self._launcher if self._launcher != self._LAUNCHER else ""
195 config.set(sectionName, "notifier", launcher)
197 def apply_settings(self, enabled, recurrence):
198 if recurrence != self._recurrence or enabled != self.isEnabled:
202 self._set_alarm(recurrence)
203 self._recurrence = int(recurrence)
206 def recurrence(self):
207 return self._recurrence
211 return self._alarmCookie != self._INVALID_COOKIE
213 def _set_alarm(self, recurrence):
214 assert 1 <= recurrence, "Notifications set to occur too frequently: %d" % recurrence
215 alarmTime = _get_start_time(recurrence)
217 #Setup the alarm arguments so that they can be passed to the D-Bus add_event method
219 alarmd.ALARM_EVENT_NO_DIALOG |
220 alarmd.ALARM_EVENT_NO_SNOOZE |
221 alarmd.ALARM_EVENT_CONNECTED
224 action.extend(['flags', _DEFAULT_FLAGS])
225 action.extend(['title', self._TITLE])
226 action.extend(['path', self._launcher])
230 [alarmTime, int(27)],
231 signature=dbus.Signature('v')
233 ]) #int(27) used in place of alarm_index
236 event.extend([dbus.ObjectPath('/AlarmdEventRecurring'), dbus.UInt32(4)])
237 event.extend(['action', dbus.ObjectPath('/AlarmdActionExec')]) #use AlarmdActionExec instead of AlarmdActionDbus
238 event.append(dbus.UInt32(len(action) / 2))
240 event.extend(['time', dbus.Int64(alarmTime)])
241 event.extend(['recurr_interval', dbus.UInt32(recurrence)])
242 event.extend(['recurr_count', dbus.Int32(self._REPEAT_FOREVER)])
244 self._alarmCookie = self._alarmdDBus.add_event(*event);
246 def _clear_alarm(self):
247 if self._alarmCookie == self._INVALID_COOKIE:
249 deleteResult = self._alarmdDBus.del_event(dbus.Int32(self._alarmCookie))
250 self._alarmCookie = self._INVALID_COOKIE
251 assert deleteResult != -1, "Deleting of alarm event failed"
254 class _NoneAlarmHandler(object):
257 self._alarmCookie = 0
259 def load_settings(self, config, sectionName):
262 def save_settings(self, config, sectionName):
265 def apply_settings(self, enabled, recurrence):
269 def recurrence(self):
278 _FREMANTLE_ALARM: _FremantleAlarmHandler,
279 _DIABLO_ALARM: _DiabloAlarmHandler,
280 _NO_ALARM: _NoneAlarmHandler,
291 parser = optparse.OptionParser()
292 parser.add_option("-x", "--display", action="store_true", dest="display", help="Display data")
293 parser.add_option("-e", "--enable", action="store_true", dest="enabled", help="Whether the alarm should be enabled or not", default=False)
294 parser.add_option("-d", "--disable", action="store_false", dest="enabled", help="Whether the alarm should be enabled or not", default=False)
295 parser.add_option("-r", "--recurrence", action="store", type="int", dest="recurrence", help="How often the alarm occurs", default=5)
296 (commandOptions, commandArgs) = parser.parse_args()
298 alarmHandler = AlarmHandler()
299 config = ConfigParser.SafeConfigParser()
300 config.read(constants._user_settings_)
301 alarmHandler.load_settings(config, "alarm")
303 if commandOptions.display:
304 print "Alarm (%s) is %s for every %d minutes" % (
305 alarmHandler._alarmCookie,
306 "enabled" if alarmHandler.isEnabled else "disabled",
307 alarmHandler.recurrence,
310 isEnabled = commandOptions.enabled
311 recurrence = commandOptions.recurrence
312 alarmHandler.apply_settings(isEnabled, recurrence)
314 alarmHandler.save_settings(config, "alarm")
315 configFile = open(constants._user_settings_, "wb")
317 config.write(configFile)
322 if __name__ == "__main__":