EventAggregator

Changeset

216:65a2a2bd4ea4
2011-07-18 Paul Boddie raw files shortlog changelog graph Added a script that converts iCalendar resources to event pages, writing such pages (containing multiple events) to standard output.
scripts/ics2page.py (file)
     1.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     1.2 +++ b/scripts/ics2page.py	Mon Jul 18 00:28:55 2011 +0200
     1.3 @@ -0,0 +1,114 @@
     1.4 +# -*- coding: iso-8859-1 -*-
     1.5 +"""
     1.6 +    MoinMoin - Conversion of iCalendar resources to event pages
     1.7 +
     1.8 +    @copyright: 2011 by Paul Boddie <paul@boddie.org.uk>
     1.9 +
    1.10 +    @license: GNU GPL (v2 or later), see COPYING.txt for details.
    1.11 +"""
    1.12 +
    1.13 +from collections import defaultdict
    1.14 +from EventAggregatorSupport import Date
    1.15 +import vCalendar
    1.16 +import codecs
    1.17 +import re
    1.18 +
    1.19 +date_regexp_str = ur'(?P<year>[0-9]{4})(?P<month>[0-9]{2})(?P<day>[0-9]{2})'
    1.20 +time_regexp_str = ur'(?P<hour>[0-2][0-9])(?P<minute>[0-5][0-9])(?:(?P<second>[0-6][0-9]))?'
    1.21 +
    1.22 +date_regexp = re.compile(date_regexp_str, re.UNICODE)
    1.23 +time_regexp = re.compile(time_regexp_str, re.UNICODE)
    1.24 +
    1.25 +def convert(value, pattern):
    1.26 +    match = pattern.match(value)
    1.27 +    if match:
    1.28 +        return match.groups()
    1.29 +    else:
    1.30 +        return [value]
    1.31 +
    1.32 +def convert_date(value, end=0):
    1.33 +    fields = convert(value, date_regexp)
    1.34 +    if len(fields) == 1:
    1.35 +        return value
    1.36 +    else:
    1.37 +        date = Date(map(int, fields))
    1.38 +        if end:
    1.39 +            date = date.day_update(-1)
    1.40 +        return str(date)
    1.41 +
    1.42 +def convert_time(value):
    1.43 +    fields = convert(value, time_regexp)
    1.44 +    if len(fields) == 1:
    1.45 +        return value
    1.46 +    else:
    1.47 +        return ":".join(fields)
    1.48 +
    1.49 +def convert_to_time_and_zone(value):
    1.50 +    for sign in ("-", "+", " "):
    1.51 +        parts = value.split(sign)
    1.52 +        if len(parts) > 1:
    1.53 +            return parts[0], (sign + parts[1]).lstrip()
    1.54 +    return value, ""
    1.55 +
    1.56 +def convert_datetime(value, end=0):
    1.57 +    parts = value.split("T")
    1.58 +    if len(parts) == 1:
    1.59 +        return convert_date(value, end)
    1.60 +    else:
    1.61 +        date, time = parts[:2]
    1.62 +        if value.endswith("Z"):
    1.63 +            time, zone = time[:-1], "UTC"
    1.64 +        else:
    1.65 +            time, zone = convert_to_time_and_zone(time)
    1.66 +        return "%s %s %s" % (convert_date(date), convert_time(time), zone)
    1.67 +
    1.68 +def parse_event(it):
    1.69 +    event = defaultdict(unicode)
    1.70 +
    1.71 +    for name, parameters, value in it:
    1.72 +        if name == "END" and value == "VEVENT":
    1.73 +            break
    1.74 +        if name.startswith("DT"):
    1.75 +            value = convert_datetime(value, name == "DTEND")
    1.76 +        event[name] = value
    1.77 +
    1.78 +    return event
    1.79 +
    1.80 +if __name__ == "__main__":
    1.81 +    import os, sys
    1.82 +    progname = os.path.split(sys.argv[0])[-1]
    1.83 +
    1.84 +    try:
    1.85 +        it = vCalendar.iterparse(sys.argv[1])
    1.86 +    except IndexError:
    1.87 +        print >>sys.stderr, "Usage: %s <iCalendar filename>" % progname
    1.88 +        sys.exit(1)
    1.89 +
    1.90 +    events = []
    1.91 +
    1.92 +    for name, parameters, value in it:
    1.93 +        if name == "BEGIN" and value == "VEVENT":
    1.94 +            event = parse_event(it)
    1.95 +            event["DTEND"] = event["DTEND"] or event["DTSTART"]
    1.96 +            events.append(event)
    1.97 +
    1.98 +    out = codecs.getwriter("utf-8")(sys.stdout)
    1.99 +
   1.100 +    for event in events:
   1.101 +        out.write(u"""
   1.102 +== %(SUMMARY)s ==
   1.103 +
   1.104 + Start:: %(DTSTART)s
   1.105 + End:: %(DTEND)s
   1.106 + Summary:: %(SUMMARY)s
   1.107 + Topics:: %(CATEGORIES)s
   1.108 + Location:: %(LOCATION)s
   1.109 + URL:: %(URL)s
   1.110 +""" % event)
   1.111 +
   1.112 +    out.write("""
   1.113 +----
   1.114 +CategoryEvents
   1.115 +""")
   1.116 +
   1.117 +# vim: tabstop=4 expandtab shiftwidth=4