#!/usr/bin/python

# run this once an hour using a cronjob

import datetime
from PIL import Image
import re
import urllib
import xml.dom.minidom

def escapeIcal(ical):
    # TODO(bolinfest): figure out how newlines are escaped
    return ical.replace('\\', '\\\\').replace(';', '\\;').replace(',', '\\,')

fp = urllib.urlopen('http://www.xkcd.com/atom.xml')
# Read local file for testing
# fp = open('xkcd.xml', 'r')
rss = fp.read()
fp.close()

dom = xml.dom.minidom.parseString(rss)
entries = dom.getElementsByTagName('entry')

# cannot have an empty line at the beginning of the .ics file
HEADER = """\
BEGIN:VCALENDAR
X-WR-CALNAME;VALUE=TEXT:xkcd.com
VERSION:2.0
CALSCALE:GREGORIAN"""

FOOTER = """
END:VCALENDAR"""

VEVENT = """
BEGIN:VEVENT
DTSTART;VALUE=DATE:%(startDate)s
DTEND;VALUE=DATE:%(endDate)s
SUMMARY:%(title)s
X-GOOGLE-CALENDAR-CONTENT-TITLE:%(title)s
X-GOOGLE-CALENDAR-CONTENT-ICON:http://xkcd.com/static/favicon.ico
X-GOOGLE-CALENDAR-CONTENT-URL:http://www.google.com/ig/modules/imagelink.xml
X-GOOGLE-CALENDAR-CONTENT-TYPE:application/x-google-gadgets+xml
X-GOOGLE-CALENDAR-CONTENT-WIDTH:%(width)s
X-GOOGLE-CALENDAR-CONTENT-HEIGHT:%(height)s
X-GOOGLE-CALENDAR-CONTENT-GADGET-PREF;NAME=linkUrl:%(linkUrl)s
X-GOOGLE-CALENDAR-CONTENT-GADGET-PREF;NAME=width:%(width)s
X-GOOGLE-CALENDAR-CONTENT-GADGET-PREF;NAME=height:%(height)s
X-GOOGLE-CALENDAR-CONTENT-GADGET-PREF;NAME=imageUrl:%(imageUrl)s
X-GOOGLE-CALENDAR-CONTENT-GADGET-PREF;NAME=tooltip:%(tooltip)s
END:VEVENT"""

delta = datetime.timedelta(1)
src_re = re.compile('src="([^"]+)"')
title_re = re.compile('title="([^"]+)"')
out = [HEADER]
for entry in entries:
    updated = entry.getElementsByTagName('updated')[0].firstChild.nodeValue. \
              replace("-", "")
    d = {}
    d['startDate'] = updated
    startDate = datetime.date(int(updated[0:4], 10),
                              int(updated[4:6], 10),
                              int(updated[6:8], 10))
    endDate = startDate + delta
    d['endDate'] = endDate.strftime("%Y%m%d")

    d['title'] = entry.getElementsByTagName('title')[0].firstChild.nodeValue
    d['title'] = escapeIcal(d['title'])

    description = entry.getElementsByTagName('summary')[0].firstChild.nodeValue
    m = src_re.search(description)
    d['imageUrl'] = m.groups()[0]

    m = title_re.search(description)
    d['tooltip'] = m.groups()[0]
    d['tooltip'] = escapeIcal(d['tooltip'])

    guid = entry.getElementsByTagName('id')[0].firstChild.nodeValue
    d['linkUrl'] = guid

    temp_file = urllib.urlretrieve(d['imageUrl'])[0]
    # Eliminate or at least hide the warning that results from using Image
    dimensions = Image.open(temp_file).size
    d['width'] = dimensions[0]
    d['height'] = dimensions[1]

    out.append(VEVENT % d)

out.append(FOOTER)
out = "".join(out)
out = out.encode('latin-1')
fh = open('/www/bolinfest.com/calendars/xkcd.ics', 'w')
fh.write(out)
fh.close()

