1 #!/usr/bin/env python 2 3 """ 4 Copyright (C) 2005 Paul Boddie <paul@boddie.org.uk> 5 6 Additional copyrights for the monthcalendar function: 7 8 Copyright (c) 2001, 2002, 2003, 2004, 2005 Python Software Foundation. 9 Copyright (c) 2000 BeOpen.com. 10 Copyright (c) 1995-2001 Corporation for National Research Initiatives. 11 Copyright (c) 1991-1995 Stichting Mathematisch Centrum. 12 13 This library is free software; you can redistribute it and/or 14 modify it under the terms of the GNU Lesser General Public 15 License as published by the Free Software Foundation; either 16 version 2.1 of the License, or (at your option) any later version. 17 18 This library is distributed in the hope that it will be useful, 19 but WITHOUT ANY WARRANTY; without even the implied warranty of 20 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 21 Lesser General Public License for more details. 22 23 You should have received a copy of the GNU Lesser General Public 24 License along with this library; if not, write to the Free Software 25 Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA 26 """ 27 28 import libxml2dom 29 import calendar 30 31 # Borrowed from calendar, but with a non-global first weekday variable. 32 33 def monthcalendar(year, month, firstweekday=0): 34 """Return a matrix representing a month's calendar. 35 Each row represents a week; days outside this month are zero.""" 36 day1, ndays = calendar.monthrange(year, month) 37 rows = [] 38 r7 = range(7) 39 day = (firstweekday - day1 + 6) % 7 - 5 # for leading 0's in first week 40 while day <= ndays: 41 row = [0, 0, 0, 0, 0, 0, 0] 42 for i in r7: 43 if 1 <= day <= ndays: row[i] = day 44 day = day + 1 45 rows.append(row) 46 return rows 47 48 # Helper functions. 49 50 def get_previous_year_and_month(year, month): 51 if month - 1 == 0: 52 return year - 1, 12 53 else: 54 return year, month - 1 55 56 def get_next_year_and_month(year, month): 57 if month + 1 == 13: 58 return year + 1, 1 59 else: 60 return year, month + 1 61 62 # XML production functions. 63 64 def write_month_to_document(doc, root, year, month): 65 weeks = monthcalendar(year, month) 66 month_element = root.appendChild(doc.createElement("month")) 67 68 # Add navigational attributes. 69 70 month_element.setAttribute("number", str(month)) 71 month_element.setAttribute("year", str(year)) 72 yp, mp = get_previous_year_and_month(year, month) 73 month_element.setAttribute("number-previous", str(mp)) 74 month_element.setAttribute("year-previous", str(yp)) 75 yn, mn = get_next_year_and_month(year, month) 76 month_element.setAttribute("number-next", str(mn)) 77 month_element.setAttribute("year-next", str(yn)) 78 79 # Add weeks and days. 80 81 for numbers in weeks: 82 week_element = month_element.appendChild(doc.createElement("week")) 83 for number in numbers: 84 day_element = week_element.appendChild(doc.createElement("day")) 85 if number != 0: 86 day_element.setAttribute("date", "%04d%02d%02d" % (year, month, number)) 87 day_element.setAttribute("number", str(number)) 88 89 def get_calendar_for_month(year, month): 90 doc = libxml2dom.createDocument(None, "calendar", None) 91 write_month_to_document(doc, doc.childNodes[-1], year, month) 92 return doc 93 94 if __name__ == "__main__": 95 import sys 96 try: 97 print get_calendar_for_month(int(sys.argv[1]), int(sys.argv[2])).toString() 98 except (IndexError, ValueError): 99 print "Please specify a year and a month (numeric, 1-12)." 100 101 # vim: tabstop=4 expandtab shiftwidth=4