1 # -*- coding: iso-8859-1 -*- 2 """ 3 MoinMoin - Conversion of iCalendar resources to event pages 4 5 @copyright: 2011 by Paul Boddie <paul@boddie.org.uk> 6 7 @license: GNU GPL (v2 or later), see COPYING.txt for details. 8 """ 9 10 from collections import defaultdict 11 from EventAggregatorSupport import Date 12 import vCalendar 13 import codecs 14 import re 15 16 date_regexp_str = ur'(?P<year>[0-9]{4})(?P<month>[0-9]{2})(?P<day>[0-9]{2})' 17 time_regexp_str = ur'(?P<hour>[0-2][0-9])(?P<minute>[0-5][0-9])(?:(?P<second>[0-6][0-9]))?' 18 19 date_regexp = re.compile(date_regexp_str, re.UNICODE) 20 time_regexp = re.compile(time_regexp_str, re.UNICODE) 21 22 def convert(value, pattern): 23 match = pattern.match(value) 24 if match: 25 return match.groups() 26 else: 27 return [value] 28 29 def convert_date(value, end=0): 30 fields = convert(value, date_regexp) 31 if len(fields) == 1: 32 return value 33 else: 34 date = Date(map(int, fields)) 35 if end: 36 date = date.day_update(-1) 37 return str(date) 38 39 def convert_time(value): 40 fields = convert(value, time_regexp) 41 if len(fields) == 1: 42 return value 43 else: 44 return ":".join(fields) 45 46 def convert_to_time_and_zone(value): 47 for sign in ("-", "+", " "): 48 parts = value.split(sign) 49 if len(parts) > 1: 50 return parts[0], (sign + parts[1]).lstrip() 51 return value, "" 52 53 def convert_datetime(value, end=0): 54 parts = value.split("T") 55 if len(parts) == 1: 56 return convert_date(value, end) 57 else: 58 date, time = parts[:2] 59 if value.endswith("Z"): 60 time, zone = time[:-1], "UTC" 61 else: 62 time, zone = convert_to_time_and_zone(time) 63 return "%s %s %s" % (convert_date(date), convert_time(time), zone) 64 65 def parse_event(it): 66 event = defaultdict(unicode) 67 68 for name, parameters, value in it: 69 if name == "END" and value == "VEVENT": 70 break 71 if name.startswith("DT"): 72 value = convert_datetime(value, name == "DTEND") 73 event[name] = value 74 75 return event 76 77 if __name__ == "__main__": 78 import os, sys 79 progname = os.path.split(sys.argv[0])[-1] 80 81 try: 82 it = vCalendar.iterparse(sys.argv[1]) 83 except IndexError: 84 print >>sys.stderr, "Usage: %s <iCalendar filename>" % progname 85 sys.exit(1) 86 87 events = [] 88 89 for name, parameters, value in it: 90 if name == "BEGIN" and value == "VEVENT": 91 event = parse_event(it) 92 event["DTEND"] = event["DTEND"] or event["DTSTART"] 93 events.append(event) 94 95 out = codecs.getwriter("utf-8")(sys.stdout) 96 97 for event in events: 98 out.write(u""" 99 == %(SUMMARY)s == 100 101 Start:: %(DTSTART)s 102 End:: %(DTEND)s 103 Summary:: %(SUMMARY)s 104 Topics:: %(CATEGORIES)s 105 Location:: %(LOCATION)s 106 URL:: %(URL)s 107 """ % event) 108 109 out.write(""" 110 ---- 111 CategoryEvents 112 """) 113 114 # vim: tabstop=4 expandtab shiftwidth=4