#!/usr/bin/env python # author: Dave Bayer # typical use: calendar.py calendar.txt calendar import datetime import re import sys # usage message usage = """in out Generates calendar html from input description input file format (empty lines ok, year optional, $ ends input, b,r,g are colors): 12/18,21-23 b 1:00-2:00 1/10,12/2010 b 2:00-3:00 1/14 b 1:00-2:00 $ 2/16 g """ # get command line arguments def get_args(count, usage): argv = sys.argv if len(argv) == count + 1: return argv[1:] else: print '\nusage: %s %s' % (argv[0], usage) exit(0) # parse a days descriptor 9-12,14,22-24 into individual days def dates(ranges): out = [] for field in ranges.split(','): day = map(int, field.split('-')) if len(day) == 2: out.extend(range(day[0], day[1]+1)) else: out.append(day[0]) return out # regular expressions for parsing input events eof = re.compile(r'[$]') event = re.compile(r'(\d+)/([-,0-9]+)(?:/(\d+))?\s*([a-z])?\s+(.+)?') # read_events processes input events def read_events(file): year = datetime.datetime.today().year events = dict() for line in file.readlines(): if eof.match(line): break data = event.match(line) if data: (mo, da, ye, co, tx) = data.groups() month = int(mo) if ye: year = int(ye) for day in dates(da): date = datetime.date(year,month,day) events[date] = co, tx return events # html strings, data header = """ """ footer = "
Monday Tuesday Wednesday Thursday Friday
" # show_date prepares table cell for date colors = { 'b':'99ffff', 'r':'ff9999', 'g':'dddddd' } month = ['', 'Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec'] def show_day(date, events): html = "%s
%s" color = 'ffffff' msg = '' if date in events.keys(): co, tx = events[date] if co in colors.keys(): color = colors[co] if tx: msg = "%s" % tx if date.weekday() == 0 or date.day == 1: day = "%s %s" % (date.day, month[date.month]) else: day = "%d" % date.day return html % (color, day, msg) # change date to specified day of same week (Monday is 0 and Sunday is 6) def set_day (date, day): return date + datetime.timedelta(day - date.weekday()) # mon_fri is a generator giving dates needed for calendar def mon_fri(dates): date = set_day(min(dates),0) end = set_day(max(dates),4) while date <= end: day = date.weekday() if day <= 4: yield date, day date += datetime.timedelta(1) # write_html outputs events calendar def write_html(events, file): dates = events.keys() print >>file, header for date, day in mon_fri(dates): if day == 0: print >>file, '' print >>file, show_day(date, events) if day == 4: print >>file, '\n' print >>file, footer # open input, output files fin, fon = get_args(2, usage) fi = open(fin) fo = open(fon, mode='w') # read events and write calendar html events = read_events(fi) write_html(events, fo) # close input, output files fi.close() fo.close()