pdf_calendar.py backup

#!/usr/bin/env python
"""Create a PDF calendar.
 
This script requires Python and Reportlab
( http://reportlab.org/rl_toolkit.html ). Tested only with Python 2.4 and
Reportlab 1.2.
 
See bottom of file for an example of usage. No command-line interface has been
added, but it would be trivial to do so. Furthermore, this script is pretty
hacky, and could use some refactoring, but it works for what it's intended
to do.
 
Created by Bill Mill on 11/16/05, this script is in the public domain. There
are no express warranties, so if you mess stuff up with this script, it's not
my fault.
 
If you have questions or comments or bugfixes or flames, please drop me a line 
at bill.mill@gmail.com .
"""
from reportlab.lib import pagesizes
from reportlab.pdfgen.canvas import Canvas
import calendar, time, datetime
from math import floor
 
NOW = datetime.datetime.now()
SIZE = pagesizes.landscape(pagesizes.letter)
 
class NoCanvasError(Exception): pass
 
def nonzero(row):
    return len([x for x in row if x!=0])
 
def createCalendar(month, year=NOW.year, canvas=None, filename=None, \
                   size=SIZE):
    """
    Create a one-month pdf calendar, and return the canvas
 
    month: can be an integer (1=Jan, 12=Dec) or a month abbreviation (Jan, Feb,
            etc.
    year: year in which month falls. Defaults to current year.
    canvas: you may pass in a canvas to add a calendar page to the end.
    filename: String containing the file to write the calendar to
    size: size, in points of the canvas to write on
    """
    if type(month) == type(''):
        month = time.strptime(month, "%b")[1]
    if canvas is None and filename is not None:
        canvas = Canvas(filename, size)
    elif canvas is None and filename is None:
        raise NoCanvasError
    monthname = time.strftime("%B", time.strptime(str(month), "%m"))
    cal = calendar.monthcalendar(year, month)
 
    width, height = size
 
    #draw the month title
    title = monthname + ' ' + str(year)
    canvas.drawCentredString(width / 2, height - 27, title)
    height = height - 40
 
    #margins
    wmar, hmar = width/50, height/50
 
    #set up constants
    width, height = width - (2*wmar), height - (2*hmar)
    rows, cols = len(cal), 7
    lastweek = nonzero(cal[-1])
    firstweek = nonzero(cal[0])
    weeks = len(cal)
    rowheight = floor(height / rows)
    boxwidth = floor(width/7)
 
    #draw the bottom line
    canvas.line(wmar, hmar, wmar+(boxwidth*lastweek), hmar)
    #now, for all complete rows, draw the bottom line
    for row in range(1, len(cal[1:-1]) + 1):
        y = hmar + (row * rowheight)
        canvas.line(wmar, y, wmar + (boxwidth * 7), y)
    #now draw the top line of the first full row
    y = hmar + ((rows-1) * rowheight)
    canvas.line(wmar, y, wmar + (boxwidth * 7), y)
    #and, then the top line of the first row
    startx = wmar + (boxwidth * (7-firstweek))
    endx = startx + (boxwidth * firstweek)
    y = y + rowheight
    canvas.line(startx, y, endx, y)
 
    #now draw the vert lines
    for col in range(8):
        #1 = don't draw line to first or last; 0 = do draw
        last, first = 1, 1
        if col <= lastweek: last = 0
        if col >= 7 - firstweek: first = 0
        x = wmar + (col * boxwidth)
        starty = hmar + (last * rowheight)
        endy = hmar + (rows * rowheight) - (first * rowheight)
        canvas.line(x, starty, x, endy)
 
    #now fill in the day numbers and any data
    x = wmar + 6
    y = hmar + (rows * rowheight) - 15
    for week in cal:
        for day in week:
            if day:
                canvas.drawString(x, y, str(day))
            x = x + boxwidth
        y = y - rowheight
        x = wmar + 6
 
    #finish this page
    canvas.showPage()
 
    return canvas
 
if __name__ == "__main__":
    #create a December, 2005 PDF
    c = createCalendar(12, 2005, filename="blog_calendar.pdf")
    #now add January, 2006 to the end
    createCalendar(1, 2006, canvas=c)
    c.save()

From: https://billmill.org/static/files/pdf_calendar.py