1 #!/usr/bin/env python 2 3 import libxml2dom 4 import calendar 5 6 # Borrowed from calendar, but with a non-global first weekday variable. 7 8 def monthcalendar(year, month, firstweekday=0): 9 """Return a matrix representing a month's calendar. 10 Each row represents a week; days outside this month are zero.""" 11 day1, ndays = calendar.monthrange(year, month) 12 rows = [] 13 r7 = range(7) 14 day = (firstweekday - day1 + 6) % 7 - 5 # for leading 0's in first week 15 while day <= ndays: 16 row = [0, 0, 0, 0, 0, 0, 0] 17 for i in r7: 18 if 1 <= day <= ndays: row[i] = day 19 day = day + 1 20 rows.append(row) 21 return rows 22 23 # Helper functions. 24 25 def get_previous_year_and_month(year, month): 26 if month - 1 == 0: 27 return year - 1, 12 28 else: 29 return year, month - 1 30 31 def get_next_year_and_month(year, month): 32 if month + 1 == 13: 33 return year + 1, 1 34 else: 35 return year, month + 1 36 37 # XML production functions. 38 39 def write_month_to_document(doc, root, year, month): 40 weeks = monthcalendar(year, month) 41 month_element = root.appendChild(doc.createElement("month")) 42 43 # Add navigational attributes. 44 45 month_element.setAttribute("number", str(month)) 46 month_element.setAttribute("year", str(year)) 47 yp, mp = get_previous_year_and_month(year, month) 48 month_element.setAttribute("number-previous", str(mp)) 49 month_element.setAttribute("year-previous", str(yp)) 50 yn, mn = get_next_year_and_month(year, month) 51 month_element.setAttribute("number-next", str(mn)) 52 month_element.setAttribute("year-next", str(yn)) 53 54 # Add weeks and days. 55 56 for numbers in weeks: 57 week_element = month_element.appendChild(doc.createElement("week")) 58 for number in numbers: 59 day_element = week_element.appendChild(doc.createElement("day")) 60 if number != 0: 61 day_element.setAttribute("date", "%04d%02d%02d" % (year, month, number)) 62 day_element.setAttribute("number", str(number)) 63 64 def get_calendar_for_month(year, month): 65 doc = libxml2dom.createDocument(None, "calendar", None) 66 write_month_to_document(doc, doc.childNodes[-1], year, month) 67 return doc 68 69 if __name__ == "__main__": 70 import sys 71 try: 72 print get_calendar_for_month(int(sys.argv[1]), int(sys.argv[2])).toString() 73 except (IndexError, ValueError): 74 print "Please specify a year and a month (numeric, 1-12)." 75 76 # vim: tabstop=4 expandtab shiftwidth=4