[maemo-users] crontab (alpha version)
From: Olivier Ricou maemo1 at altribe.orgDate: Thu Apr 3 18:40:00 EEST 2008
- Previous message: where is crontab ?
- Next message: crontab (alpha version)
- Messages sorted by: [ date ] [ thread ] [ subject ] [ author ]
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.pgp
- Previous message: where is crontab ?
- Next message: crontab (alpha version)
- Messages sorted by: [ date ] [ thread ] [ subject ] [ author ]
