import thread import time import sys import math class Alarm(object): """alarm instance this beeps every 0.5 seconds """ snooze_interval = 9 * 60 ring_interval = 0.5 _alarm_on = True # make the clock run, but don't ring _alarm_time = False _ring = False _snooze = False _kill = False def set(self, hours, minutes, seconds=0): """set alarm to ::""" print 'setting alarm at %r' % ((hours, minutes, seconds),) self._alarm_time = (hours, minutes, seconds) def switch_alarm_state(self): self._alarm_on = not self._alarm_on def go(self): self._ring = True self._snooze = False def stop(self): self._ring = False self._snooze = False def snooze(self): self._snooze = time.time() def quit(self): self._kill = True def ring(self): sys.stdout.write('ring\n\a') sys.stdout.flush() def run(self): thread.start_new_thread(self.eventloop, ()) self.timeloop() def timeloop(self): print 'entering timeloop' try: while 1: if self._kill: return currtime = time.time() if (self._snooze and self._snooze < (currtime - self.snooze_interval)): self._snooze = False timetuple = time.localtime()[3:6] if self._alarm_time == timetuple: self._ring = True self._snooze = False if self._alarm_on and self._ring and not self._snooze: self.ring() self.print_status() time.sleep(self.ring_interval) except: exc, e, tb = sys.exc_info() print 'Exception:', exc, e def eventloop(self): while 1: print 'going to block a bit here...' char = sys.stdin.read(1) print 'char received:', char if char in ' ': self.snooze() elif char == 'q': self.quit() elif char == 'o': # hmmm... do we spot useless accessors here? :| self.switch_alarm_state() def print_status(self): print time.strftime('%H:%M:%S') print 'self._alarm_on:', self._alarm_on print 'self._ring:', self._ring print 'self._snooze:', self._snooze if self._alarm_on and self._ring and not self._snooze: print 'alarm!' __alarm__ = Alarm() def alarm_in(secs, alarm=__alarm__): """start the alarm in seconds""" print 'alarm in %s seconds' % secs def _switch(self): self.quit() __alarm__.swith_alarm_state = _switch hours = int(math.floor(secs / 3600)) if hours > 24: print 'can\'t set alarms > 24 hours, sorry...' return mins = int(math.floor((secs - (hours * 3600)) / 60)) secs = int(math.floor(secs % 60)) currtime = list(time.localtime()[3:6]) secs = currtime[2] + secs if secs > 60: mins += 1 secs -= 60 mins = currtime[1] + mins if mins > 60: hours += 1 mins -= 60 hours = currtime[0] + hours if hours > 24: hours -= 24 __alarm__.set(hours, mins, secs) alarm.run() def alarm_at(hours, mins, secs=0, alarm=__alarm__): """start the alarm at hours:mins:secs""" print 'alarm at %s:%s:%s' % (hours, mins, secs) __alarm__.set(int(hours), int(mins), int(secs)) __alarm__.run() if __name__ == '__main__': def usage(): print ('usage: %s *or* %s :[:]' % (sys.argv[1], sys.argv[1])) print print ' the first form will start an alarm in seconds, ' print ' the second will make the program function as an alarm clock,' print ' ringing every day at ::.' if len(sys.argv) != 2: usage() sys.exit() arg = sys.argv[1] try: seconds = int(arg) except ValueError: chunks = arg.split(':') if len(chunks) not in [2,3]: usage() sys.exit() hours = chunks[0] mins = chunks[1] secs = 0 if len(chunks) == 3: secs = chunks[2] alarm_at(hours, mins, secs) else: alarm_in(seconds)