#!/usr/bin/env python """ ch18_ical_to_hcal.py Render iCalendar as hCalendar-formatted HTML. """ import os, sys from md5 import md5 from httpcache import HTTPCache from icalendar import Calendar, Event HTML_DIR = "hcal" ICS_URL = "http://icalx.com/public/peterpqa/US-Practical.ics" HEVENT_TMPL = u""" %(dtstart:date:%A, %B %d, %Y)s: %(summary)s
%(dtstart:date:%A, %B %d, %Y)s : %(summary)s
%(description)s
""" def main(): """ Perform iCalendar to hCalendar rendering. """ # Establish the calendar URL and output file. ics_url = len(sys.argv) > 1 and sys.argv[0] or ICS_URL html_dir = len(sys.argv) > 2 and sys.argv[1] or HTML_DIR # Get the calendar via URL and parse the data cal = Calendar.from_string(HTTPCache(ics_url).content()) # Create HTML_DIR if it doesn't already exist if not os.path.exists(html_dir): os.makedirs(html_dir) # Process calendar components. for event in cal.walk(): # Skip this calendar component if it's not an event. if not type(event) is Event: continue # Summarize the event data, make a hash, build a filename. hash_src = ','.join(['%s=%s' % x for x in event.items()]) hash = md5(hash_src).hexdigest() hcal_fn = os.path.join(html_dir, '%s.html' % hash) # Build the hCalendar content and write out to file. hcal_out = HEVENT_TMPL % ICalTmplWrapper(event) open(hcal_fn, 'w').write(hcal_out) class ICalTmplWrapper: """ Formatting helper class for iCalendar objects. """ def __init__(self, obj): """Initialize wrapper with an iCal obj instance.""" self.obj = obj def __getitem__(self, key): """Provides simple formatting options for dates and encoding.""" # Get the name and optional formatting type from format key name, fmt = (':' in key) and key.split(':', 1) or (key, None) # If no such key in obj, return blank. if not self.obj.has_key(name): return '' # No special formatting, return decoded value. if fmt is None: return self.obj.decoded(name) # 'encoded' formatting, return the encoded value. elif fmt == 'encoded': return self.obj[name] # 'date' formatting, so assume this value is a datetime # and return formatted according to supplied option. elif fmt.startswith('date:'): fmt, date_fmt = fmt.encode().split(":",1) data = self.obj.decoded(name) return data.strftime(date_fmt) if __name__=='__main__': main()