#!/usr/bin/env python "calbum.py - A program for making simple PDF calendar albums." __author__ = 'Dinu Gherman ' __version__ = '0.3.0' import sys, glob, getopt, locale, datetime, calendar from os.path import join, dirname from reportlab import rl_config from reportlab.lib import colors from reportlab.lib.units import cm from reportlab.lib.styles import getSampleStyleSheet from reportlab.lib.enums import TA_CENTER, TA_LEFT, TA_RIGHT from reportlab.platypus.paragraph import Paragraph from reportlab.platypus.flowables import Spacer, Image, PageBreak from reportlab.platypus.frames import Frame from reportlab.platypus.tables import TableStyle, Table from reportlab.platypus.doctemplate \     import PageTemplate, BaseDocTemplate WIDTH = (21-4)*cm styleSheet = getSampleStyleSheet() h1 = styleSheet['Heading1'] h1.alignment = TA_CENTER h1.fontSize = 24 h2 = styleSheet['Heading2'] bt = styleSheet['BodyText'] bt.leading = bt.fontSize*1 class MyTemplate(BaseDocTemplate):     "The document template used for all PDF documents."     def __init__(self, filename, **kw):         m = (21*cm - WIDTH)/2.0         frame1 = Frame(m, m, WIDTH, (29.5-3)*cm, id='F1')         apply(BaseDocTemplate.__init__, (self, filename), kw)         self.addPageTemplates(PageTemplate('normal', [frame1])) def getLtext(lcode):     "Get localised text for some locale code."     ltext = locale.nl_langinfo(lcode).capitalize()     if sys.platform == "darwin":         if rl_config.defaultEncoding == "MacRomanEncoding":             return ltext.decode("latin1").encode("macroman")     return ltext def rotate(seq, steps=1):     "Rotate a sequence by some steps, left/right if pos./neg."     return seq[steps:] + seq[:steps] def makeTable(year, month, day2text={}):     "Create a Platypus table for a given month."     # just to be sure...     firstday = calendar.MONDAY     restdays = [calendar.SATURDAY, calendar.SUNDAY]     restdays = [(d - firstday) % 7 for d in restdays]     calendar.setfirstweekday(firstday)     # make table header line     redFormat = '%s'     nums = range(locale.ABDAY_1, locale.ABDAY_7 + 1)     weekdays = [getLtext(n) for n in rotate(nums)]     weekdays = rotate(weekdays, firstday)     weekdays = ["%s" % d for d in weekdays]     for d in restdays: weekdays[d] = redFormat % weekdays[d]     weekdays = [Paragraph(d, h1) for d in weekdays]     # make numbers, remove zeros     weeks = calendar.monthcalendar(year, month)     for i in range(len(weeks)):         weeks[i] = [str(d or '') for d in weeks[i]]     # add text for special days     day2xy = {}     for i in range(len(weeks)):         week = weeks[i]         for j in range(len(week)):             d = week[j]             day2xy[d] = (j, i+1)             t = day2text.get(d, '')             format = "%s"             if j in restdays: format = redFormat % format             if t:                 p0 = Paragraph(format % d, bt)                 p1 = Paragraph(format % t, bt)                 week[j] = [p0, p1]     # set table attributes     red, black, pale = colors.red, colors.black, colors.lemonchiffon     tableStyleAttributes = []     app = tableStyleAttributes.append     app(('ALIGN', (0, 0), (-1, -1), 'CENTER'))     app(('VALIGN', (0, 0), (-1, -1), 'TOP'))     app(('FONTSIZE', (0, 0), (-1, -1), 20))     app(('GRID', (0, 0), (-1, -1), 1, black))     for i in restdays:         app(('TEXTCOLOR', (i, 0), (i, -1), red))     for i in range(0, 7, 2):         app(('BACKGROUND', (i, 0), (i, -1), pale))     # for i in range(12, 21):     #     app(('BACKGROUND', day2xy[str(i)], day2xy[str(i)], red))     tableStyle = TableStyle(tableStyleAttributes)     # make table     rows = [weekdays] + weeks     table = Table(rows, (WIDTH / 7.0,)*7, (1.5*cm,)*len(rows))     table.setStyle(tableStyle)     return table def writePDF(year, imgDir, outPath, specialDays):     "Create a PDF file with a 12 month calendar."     nums = range(locale.MON_1, locale.MON_12+1)     months = [getLtext(n) for n in nums]     images = glob.glob(join("%s", "*.[jJ][pP][gG]") % imgDir)     while len(images) < 12: images += images     images = images[:12]     specialDays = [sd.split(':') for sd in specialDays]     story = []     sp, pb = Spacer(0*cm, 1*cm), PageBreak()     for i in range(12):         img = Image(images[i], width=WIDTH, height=WIDTH*2/3.)         p = Paragraph("%s %d" % (months[i], year), h1)         s = [(m,d,tx) for (m,d,tx) in specialDays if int(m) == i + 1]         dict = {}         for m, d, tx in s: dict[str(eval(d))] = tx         t = makeTable(year, i+1, day2text=dict)         story += [img, sp, p, sp, t, pb]     MyTemplate(outPath).build(story) if __name__ == "__main__":     year = datetime.datetime.now().year     imgDir = "images"     locName = 'de_de'     outPath = None     specialDays = []     opts, args = getopt.getopt(sys.argv[1:], "y:i:l:o:s:")     for k, v in opts:         if k == '-y': year = int(v)         if k == '-i': imgDir = v         if k == '-l': locName = v         if k == '-o': outPath = v         if k == '-s': specialDays.append(v)     loc = locale.locale_alias.get(locName)     locale.setlocale(locale.LC_ALL, loc)     if outPath is None: outPath = "calbum-%d.pdf" % year     writePDF(year, imgDir, outPath, specialDays)