12 _FREMANTLE_ALARM = "Fremantle"
13 _DIABLO_ALARM = "Diablo"
19 ALARM_TYPE = _FREMANTLE_ALARM
20 except (ImportError, OSError):
22 import osso.alarmd as alarmd
23 ALARM_TYPE = _DIABLO_ALARM
24 except (ImportError, OSError):
25 ALARM_TYPE = _NO_ALARM
28 _moduleLogger = logging.getLogger(__name__)
31 def _get_start_time(recurrence):
32 now = datetime.datetime.now()
33 startTimeMinute = now.minute + max(recurrence, 5) # being safe
34 startTimeHour = now.hour + int(startTimeMinute / 60)
35 startTimeMinute = startTimeMinute % 59
36 now.replace(minute=startTimeMinute)
37 timestamp = int(time.mktime(now.timetuple()))
41 def _create_recurrence_mask(recurrence, base):
43 >>> bin(_create_recurrence_mask(60, 60))
45 >>> bin(_create_recurrence_mask(30, 60))
46 '0b1000000000000000000000000000001'
47 >>> bin(_create_recurrence_mask(2, 60))
48 '0b10101010101010101010101010101010101010101010101010101010101'
49 >>> bin(_create_recurrence_mask(1, 60))
50 '0b111111111111111111111111111111111111111111111111111111111111'
53 for i in xrange(base / recurrence):
54 mask |= 1 << (recurrence * i)
58 def _unpack_minutes(recurrence):
60 >>> _unpack_minutes(0)
62 >>> _unpack_minutes(1)
64 >>> _unpack_minutes(59)
66 >>> _unpack_minutes(60)
68 >>> _unpack_minutes(129)
70 >>> _unpack_minutes(5 * 60 * 24 + 3 * 60 + 2)
72 >>> _unpack_minutes(12 * 60 * 24 + 3 * 60 + 2)
76 minutesInDay = 24 * minutesInAnHour
77 minutesInAWeek = minutesInDay * 7
79 days = recurrence / minutesInDay
81 recurrence -= days * minutesInDay
82 hours = recurrence / minutesInAnHour
83 recurrence -= hours * minutesInAnHour
84 mins = recurrence % minutesInAnHour
86 assert recurrence == 0, "Recurrence %d" % recurrence
87 return daysOfWeek, hours, mins
90 class _FremantleAlarmHandler(object):
94 _TITLE = "Dialcentral Notifications"
95 _LAUNCHER = os.path.abspath(os.path.join(os.path.dirname(__file__), "alarm_notify.py"))
100 self._alarmCookie = self._INVALID_COOKIE
101 self._launcher = self._LAUNCHER
103 def load_settings(self, config, sectionName):
105 self._recurrence = config.getint(sectionName, "recurrence")
106 self._alarmCookie = config.getint(sectionName, "alarmCookie")
107 launcher = config.get(sectionName, "notifier")
109 self._launcher = launcher
110 except ConfigParser.NoOptionError:
112 except ConfigParser.NoSectionError:
115 def save_settings(self, config, sectionName):
116 config.set(sectionName, "recurrence", str(self._recurrence))
117 config.set(sectionName, "alarmCookie", str(self._alarmCookie))
118 launcher = self._launcher if self._launcher != self._LAUNCHER else ""
119 config.set(sectionName, "notifier", launcher)
121 def apply_settings(self, enabled, recurrence):
122 if recurrence != self._recurrence or enabled != self.isEnabled:
126 self._set_alarm(recurrence)
127 self._recurrence = int(recurrence)
130 def recurrence(self):
131 return self._recurrence
135 return self._alarmCookie != self._INVALID_COOKIE
137 def _set_alarm(self, recurrenceMins):
138 assert 1 <= recurrenceMins, "Notifications set to occur too frequently: %d" % recurrenceMins
139 alarmTime = _get_start_time(recurrenceMins)
141 event = alarm.Event()
142 event.appid = self._TITLE
143 event.alarm_time = alarmTime
144 event.recurrences_left = self._REPEAT_FOREVER
146 action = event.add_actions(1)[0]
147 action.flags |= alarm.ACTION_TYPE_EXEC | alarm.ACTION_WHEN_TRIGGERED
148 action.command = self._launcher
150 recurrence = event.add_recurrences(1)[0]
151 recurrence.mask_min |= _create_recurrence_mask(recurrenceMins, 60)
152 recurrence.mask_hour |= alarm.RECUR_HOUR_DONTCARE
153 recurrence.mask_mday |= alarm.RECUR_MDAY_DONTCARE
154 recurrence.mask_wday |= alarm.RECUR_WDAY_DONTCARE
155 recurrence.mask_mon |= alarm.RECUR_MON_DONTCARE
156 recurrence.special |= alarm.RECUR_SPECIAL_NONE
158 assert event.is_sane()
159 self._alarmCookie = alarm.add_event(event)
161 def _clear_alarm(self):
162 if self._alarmCookie == self._INVALID_COOKIE:
164 alarm.delete_event(self._alarmCookie)
165 self._alarmCookie = self._INVALID_COOKIE
168 class _DiabloAlarmHandler(object):
171 _TITLE = "Dialcentral Notifications"
172 _LAUNCHER = os.path.abspath(os.path.join(os.path.dirname(__file__), "alarm_notify.py"))
178 bus = dbus.SystemBus()
179 self._alarmdDBus = bus.get_object("com.nokia.alarmd", "/com/nokia/alarmd");
180 self._alarmCookie = self._INVALID_COOKIE
181 self._launcher = self._LAUNCHER
183 def load_settings(self, config, sectionName):
185 self._recurrence = config.getint(sectionName, "recurrence")
186 self._alarmCookie = config.getint(sectionName, "alarmCookie")
187 launcher = config.get(sectionName, "notifier")
189 self._launcher = launcher
190 except ConfigParser.NoOptionError:
192 except ConfigParser.NoSectionError:
195 def save_settings(self, config, sectionName):
196 config.set(sectionName, "recurrence", str(self._recurrence))
197 config.set(sectionName, "alarmCookie", str(self._alarmCookie))
198 launcher = self._launcher if self._launcher != self._LAUNCHER else ""
199 config.set(sectionName, "notifier", launcher)
201 def apply_settings(self, enabled, recurrence):
202 if recurrence != self._recurrence or enabled != self.isEnabled:
206 self._set_alarm(recurrence)
207 self._recurrence = int(recurrence)
210 def recurrence(self):
211 return self._recurrence
215 return self._alarmCookie != self._INVALID_COOKIE
217 def _set_alarm(self, recurrence):
218 assert 1 <= recurrence, "Notifications set to occur too frequently: %d" % recurrence
219 alarmTime = _get_start_time(recurrence)
221 #Setup the alarm arguments so that they can be passed to the D-Bus add_event method
223 alarmd.ALARM_EVENT_NO_DIALOG |
224 alarmd.ALARM_EVENT_NO_SNOOZE |
225 alarmd.ALARM_EVENT_CONNECTED
228 action.extend(['flags', _DEFAULT_FLAGS])
229 action.extend(['title', self._TITLE])
230 action.extend(['path', self._launcher])
234 [alarmTime, int(27)],
235 signature=dbus.Signature('v')
237 ]) #int(27) used in place of alarm_index
240 event.extend([dbus.ObjectPath('/AlarmdEventRecurring'), dbus.UInt32(4)])
241 event.extend(['action', dbus.ObjectPath('/AlarmdActionExec')]) #use AlarmdActionExec instead of AlarmdActionDbus
242 event.append(dbus.UInt32(len(action) / 2))
244 event.extend(['time', dbus.Int64(alarmTime)])
245 event.extend(['recurr_interval', dbus.UInt32(recurrence)])
246 event.extend(['recurr_count', dbus.Int32(self._REPEAT_FOREVER)])
248 self._alarmCookie = self._alarmdDBus.add_event(*event);
250 def _clear_alarm(self):
251 if self._alarmCookie == self._INVALID_COOKIE:
253 deleteResult = self._alarmdDBus.del_event(dbus.Int32(self._alarmCookie))
254 self._alarmCookie = self._INVALID_COOKIE
255 assert deleteResult != -1, "Deleting of alarm event failed"
258 class _NoneAlarmHandler(object):
262 _LAUNCHER = os.path.abspath(os.path.join(os.path.dirname(__file__), "alarm_notify.py"))
265 self._alarmCookie = 0
267 self._alarmCookie = self._INVALID_COOKIE
268 self._launcher = self._LAUNCHER
270 def load_settings(self, config, sectionName):
272 self._recurrence = config.getint(sectionName, "recurrence")
273 self._alarmCookie = config.getint(sectionName, "alarmCookie")
274 launcher = config.get(sectionName, "notifier")
276 self._launcher = launcher
277 except ConfigParser.NoOptionError:
279 except ConfigParser.NoSectionError:
282 def save_settings(self, config, sectionName):
283 config.set(sectionName, "recurrence", str(self._recurrence))
284 config.set(sectionName, "alarmCookie", str(self._alarmCookie))
285 launcher = self._launcher if self._launcher != self._LAUNCHER else ""
286 config.set(sectionName, "notifier", launcher)
288 def apply_settings(self, enabled, recurrence):
289 self._alarmCookie = 0 if enabled else self._INVALID_COOKIE
290 self._recurrence = recurrence
293 def recurrence(self):
294 return self._recurrence
298 return self._alarmCookie != self._INVALID_COOKIE
302 _FREMANTLE_ALARM: _FremantleAlarmHandler,
303 _DIABLO_ALARM: _DiabloAlarmHandler,
304 _NO_ALARM: _NoneAlarmHandler,
309 logFormat = '(%(relativeCreated)5d) %(levelname)-5s %(threadName)s.%(name)s.%(funcName)s: %(message)s'
310 logging.basicConfig(level=logging.DEBUG, format=logFormat)
317 parser = optparse.OptionParser()
318 parser.add_option("-x", "--display", action="store_true", dest="display", help="Display data")
319 parser.add_option("-e", "--enable", action="store_true", dest="enabled", help="Whether the alarm should be enabled or not", default=False)
320 parser.add_option("-d", "--disable", action="store_false", dest="enabled", help="Whether the alarm should be enabled or not", default=False)
321 parser.add_option("-r", "--recurrence", action="store", type="int", dest="recurrence", help="How often the alarm occurs", default=5)
322 (commandOptions, commandArgs) = parser.parse_args()
324 alarmHandler = AlarmHandler()
325 config = ConfigParser.SafeConfigParser()
326 config.read(constants._user_settings_)
327 alarmHandler.load_settings(config, "alarm")
329 if commandOptions.display:
330 print "Alarm (%s) is %s for every %d minutes" % (
331 alarmHandler._alarmCookie,
332 "enabled" if alarmHandler.isEnabled else "disabled",
333 alarmHandler.recurrence,
336 isEnabled = commandOptions.enabled
337 recurrence = commandOptions.recurrence
338 alarmHandler.apply_settings(isEnabled, recurrence)
340 alarmHandler.save_settings(config, "alarm")
341 configFile = open(constants._user_settings_, "wb")
343 config.write(configFile)
348 if __name__ == "__main__":