diff options
Diffstat (limited to 'vobject/hcalendar.py')
-rw-r--r-- | vobject/hcalendar.py | 125 |
1 files changed, 125 insertions, 0 deletions
diff --git a/vobject/hcalendar.py b/vobject/hcalendar.py new file mode 100644 index 0000000..93614ab --- /dev/null +++ b/vobject/hcalendar.py @@ -0,0 +1,125 @@ +""" +hCalendar: A microformat for serializing iCalendar data + (http://microformats.org/wiki/hcalendar) + +Here is a sample event in an iCalendar: + +BEGIN:VCALENDAR +PRODID:-//XYZproduct//EN +VERSION:2.0 +BEGIN:VEVENT +URL:http://www.web2con.com/ +DTSTART:20051005 +DTEND:20051008 +SUMMARY:Web 2.0 Conference +LOCATION:Argent Hotel\, San Francisco\, CA +END:VEVENT +END:VCALENDAR + +and an equivalent event in hCalendar format with various elements optimized appropriately. + +<span class="vevent"> + <a class="url" href="http://www.web2con.com/"> + <span class="summary">Web 2.0 Conference</span>: + <abbr class="dtstart" title="2005-10-05">October 5</abbr>- + <abbr class="dtend" title="2005-10-08">7</abbr>, + at the <span class="location">Argent Hotel, San Francisco, CA</span> + </a> +</span> +""" + +from base import foldOneLine, CRLF, registerBehavior +from icalendar import VCalendar2_0 +from datetime import date, datetime, timedelta +import StringIO + +class HCalendar(VCalendar2_0): + name = 'HCALENDAR' + + @classmethod + def serialize(cls, obj, buf=None, lineLength=None, validate=True): + """ + Serialize iCalendar to HTML using the hCalendar microformat (http://microformats.org/wiki/hcalendar) + """ + + outbuf = buf or StringIO.StringIO() + level = 0 # holds current indentation level + tabwidth = 3 + + def indent(): + return ' ' * level * tabwidth + + def out(s): + outbuf.write(indent()) + outbuf.write(s) + + # not serializing optional vcalendar wrapper + + vevents = obj.vevent_list + + for event in vevents: + out('<span class="vevent">' + CRLF) + level += 1 + + # URL + url = event.getChildValue("url") + if url: + out('<a class="url" href="' + url + '">' + CRLF) + level += 1 + # SUMMARY + summary = event.getChildValue("summary") + if summary: + out('<span class="summary">' + summary + '</span>:' + CRLF) + + # DTSTART + dtstart = event.getChildValue("dtstart") + if dtstart: + if type(dtstart) == date: + timeformat = "%A, %B %e" + machine = "%Y%m%d" + elif type(dtstart) == datetime: + timeformat = "%A, %B %e, %H:%M" + machine = "%Y%m%dT%H%M%S%z" + + #TODO: Handle non-datetime formats? + #TODO: Spec says we should handle when dtstart isn't included + + out('<abbr class="dtstart", title="%s">%s</abbr>\r\n' % + (dtstart.strftime(machine), dtstart.strftime(timeformat))) + + # DTEND + dtend = event.getChildValue("dtend") + if not dtend: + duration = event.getChildValue("duration") + if duration: + dtend = duration + dtstart + # TODO: If lacking dtend & duration? + + if dtend: + human = dtend + # TODO: Human readable part could be smarter, excluding repeated data + if type(dtend) == date: + human = dtend - timedelta(days=1) + + out('- <abbr class="dtend", title="%s">%s</abbr>\r\n' % + (dtend.strftime(machine), human.strftime(timeformat))) + + # LOCATION + location = event.getChildValue("location") + if location: + out('at <span class="location">' + location + '</span>' + CRLF) + + description = event.getChildValue("description") + if description: + out('<div class="description">' + description + '</div>' + CRLF) + + if url: + level -= 1 + out('</a>' + CRLF) + + level -= 1 + out('</span>' + CRLF) # close vevent + + return buf or outbuf.getvalue() + +registerBehavior(HCalendar)
\ No newline at end of file |