Hi, Here is the first version of a crontab for our Nokia N... (I don't know on which model alarmd is). I think it can parse all crontab input however I expect you to let me know if there is a problem. Of course, don't complain if it destroys all you Nokia, job and life, I tried it but you never can be sure with this things! You should first run it as root to init the directory and files : crontab init Then as a user you can do crontab -e or crontab -l as usual. Olivier. -------------- next part -------------- #! /usr/bin/env python # mimicks the *NIX crontab # it uses the alarmd of the Nokia N... to reduce the energy cost # # (c) 2008 Olivier Ricou <olivier at ricou.eu.org> # Licence: BSDlike # # depends: pyalarmd, cf http://home.cfl.rr.com/genecash/nokia/ import sys,os,datetime,time,pyalarmd # The crontab has 6 fields. The 5 first can have int value # # # m h dom mon dow command # # # run five minutes after midnight, every day # 5 0 * * * $HOME/bin/daily.job >> $HOME/tmp/out 2>&1 # # run at 2:15pm on the first of every month # 15 14 1 * * $HOME/bin/monthly # # run at 10 pm on weekdays, annoy Joe # 0 22 * * 1-5 mail -s "It's 10pm" joe%Joe,%%Where are your kids?% # 23 0-23/2 * * * echo "run 23 minutes after midn, 2am, 4am ..., everyday" # 5 4 * * sun echo "run at 5 after 4 every sunday" # the alarmd has only one value for recurrence hence we cannot set an # alarm every first of month since monthes have different length. # Therefore the trick is to run crontab.py every night and reparse the crontabs one_day = 24 * 60 flag =(pyalarmd.ALARM_EVENT_NO_DIALOG | pyalarmd.ALARM_EVENT_NO_SNOOZE | pyalarmd.ALARM_EVENT_ACTDEAD) today = datetime.datetime.now() tomorrow = today + datetime.timedelta(days=1) now = time.mktime(today.timetuple()) # Epoch seconds now24 = time.mktime(tomorrow.timetuple()) # Epoch seconds def parse_crontab_and_set_alarms(dir,user): file = open("%s/%s" % (dir,user),'r') comment = " # crontab of %s" % user for al in pyalarmd.alarm_query(0,sys.maxint): try: if (pyalarmd.get_alarm(al)['exec_name'].find(comment) >= 0): pyalarmd.cancel_alarm(al) except: pass for line in file.readlines(): recurrence = 0 recurrence_count = 1 alarms = [] line = line.strip() if (line == '' or line[0] == '#'): continue t = line.split() # minutes try: minute = int(t[0]) except: try: recurrence = int(t[0].split('/')[1]) t[0] = t[0].split('/')[0] except: # / is optional recurrence = 1 if (t[0] == '*'): minute = 0 recurrence_count = 60 / recurrence else: # then the only possibility is x-y try: minute = int(t[0].split('-')[0]) end = int(t[0].split('-')[1]) recurrence_count = int((end - minute) % 60 / recurrence) + 1 except: print "syntax error in minutes:\n %s" % line sys.exit(1) # hours try: hour = int(t[1]) rec = 0 rec_count = 1 except: try: rec = int(t[1].split('/')[1]) t[1] = t[1].split('/')[0] except: # / is optional rec = 1 if (t[1] == '*'): hour = 0 rec_count = 24 / rec else: # then the only possibility is x-y try: hour = int(t[1].split('-')[0]) end = int(t[1].split('-')[1]) rec_count = int((end - hour) % 24 / rec ) + 1 except: print "syntax error in hours:\n %s" % line sys.exit(1) if (recurrence > 0): # for each hour we set up an alarm for h in range(rec_count): a = [] start = datetime.datetime(today.year, today.month, today.day, hour+h*rec, minute, 0) a.append(start) a.append(recurrence) a.append(recurrence_count) alarms.append(a) start += datetime.timedelta(days=1) a = [] a.append(start) a.append(recurrence) a.append(recurrence_count) alarms.append(a) else: start_time = datetime.datetime(today.year, today.month, today.day, hour, minute, 0) a = [] a.append(start_time) a.append(rec * 60) a.append(rec_count) alarms.append(a) start_time += datetime.timedelta(days=1) a = [] a.append(start_time) a.append(rec * 60) a.append(rec_count) alarms.append(a) # # Now all we do is to remove alarm from alarms # # day of the month if not (t[2] == '*'): try: dom = int(t[2]) for a in alarms: if (a[0].day != dom): alarms.remove(a) except: try: rec = int(t[2].split('/')[1]) t[2] = t[2].split('/')[0] except: # / is optional rec = 1 try: start = int(t[2].split('-')[0]) end = int(t[2].split('-')[1]) for a in alarms: if (today.day > end or tomorrow.day < start or (a[0].day -start) % rec != 0): alarms.remove(a) except: if (t[2] == '*'): for a in alarms: if (a[0].day % rec != 0): alarms.remove(a) else: print "syntax error in day:\n %s" % line sys.exit(1) # month if not (t[3] == '*'): try: month = int(t[3]) for a in alarms: if (a[0].month != month): alarms.remove(a) except: try: rec = int(t[3].split('/')[1]) t[3] = t[3].split('/')[0] except: # / is optional rec = 1 try: start = int(t[3].split('-')[0]) end = int(t[3].split('-')[1]) for a in alarms: if (today.month > end or tomorrow.month < start or (a[0].month -start) % rec != 0): alarms.remove(a) except: if (t[3] == '*'): for a in alarms: if (a[0].month % rec != 0): alarms.remove(a) else: print "syntax error in month:\n %s" % line sys.exit(1) # day of the week if not (t[4] == '*'): try: dow = int(t[4]) for a in alarms: if (a[0].weekday() != dow): alarms.remove(a) except: try: rec = int(t[4].split('/')[1]) t[4] = t[4].split('/')[0] except: # / is optional rec = 1 try: start = int(t[4].split('-')[0]) end = int(t[4].split('-')[1]) for a in alarms: if (today.weekday() > end or tomorrow.weekday() < start or (a[0].weekday() -start) % rec != 0): alarms.remove(a) except: if (t[4] == '*'): for a in alarms: if (a[0].weekday % rec != 0): alarms.remove(a) else: print "syntax error in weekday (use only figure):\n %s" % line sys.exit(1) # command cmd = "" for i in t[5:]: cmd += i+" " cmd += comment # # Let put the alarms in the queue # for a in alarms: pyalarmd.add_alarm(time.mktime(a[0].timetuple()),a[1], a[2],0, None, \ None,None,None,None,None,None,None, cmd, flag) dir = "/var/spool/cron/crontab" user = os.getlogin() if (len(sys.argv) == 1): # we parse all the crontabs for u in os.listdir(dir): parse_crontab_and_set_alarms(dir,u) else: if (sys.argv[1] == "init"): # should be run by root if (user != "root"): print "init should be run by root" sys.exit(1) # first we init the dir and files os.system("/bin/mkdir -p %s" % dir) for u in os.popen("ls -1 /home/").readlines(): u = u.strip() os.system("/bin/touch %s/%s" % (dir,u)) os.system("/bin/chown %s %s/%s" % (u,dir,u)) os.system("/bin/touch %s/root" % dir) # then we put crontab.py in the alarmd queue (it should be run every day) # we cancel the former alarm to put a new one which allows: # - to have a new time to parse the crontabs # - to move this program in another directory for al in pyalarmd.alarm_query(0,sys.maxint): try: if (pyalarmd.get_alarm(al)['exec_name'].find(sys.argv[0].split('/')[-1]) >= 0): pyalarmd.cancel_alarm(al) except: pass pyalarmd.add_alarm(now,one_day,-1,0,0,None,None,None,None,None, \ None,None,None,os.path.abspath(sys.argv[0]),flag) elif (sys.argv[1] == "-e"): # we edit the user crontab and parse it if not os.path.isfile("%s/%s" % (dir,user)): print "your crontab should be created by root, run as root:\n %s init" \ % sys.argv[0] sys.exit(1) editor = os.getenv("EDITOR") if (editor == None): editor = "vi" os.system("%s %s/%s" % (editor,dir,user)) parse_crontab_and_set_alarms(dir,user) elif (sys.argv[1] == "-l"): # we list the user crontab os.system("/bin/cat %s/%s" % (dir,user)) else: print "usage: %s [-e|-l|init]" % sys.argv[0] -------------- next part -------------- A non-text attachment was scrubbed... Name: not available Type: application/pgp-signature Size: 189 bytes Desc: Digital signature Url : http://lists.maemo.org/pipermail/maemo-users/attachments/20080403/90365d8a/attachment-0001.pgp