icsxml.py 1.92 KB
"""icsxml -- convert iCalendar data to XML

Convert to XHTML, RDF or other XML format using kid templates.
"""

import codecs

import kid

from icslex import unbreak, properties, asDate, recurlex, unesc

def main(args):
    import sys
    tpl = kid.Template(file=args[0])
    tpl.events = events(args[1:])
    tpl.contacts = tpl.events #@@ kludge

    tpl.when = '2006-04-08@@'

    for s in tpl.generate(output='xml', encoding='utf-8'):
	sys.stdout.write(s)

def events(files):
    for fn in files:
	lines = unbreak(codecs.open(fn, encoding='utf-8'))

	while 1:
	    obj = {}
	    try:
		delim, name = properties(lines, obj)
	    except StopIteration:
		break
	    if obj.has_key('dtstart'):
		fixvalues(obj)
		yield obj
	    if (delim, name) == ('end', 'VCARD'): #@@kludge
		fixvalues(obj)
		yield obj

def fixvalues(obj):
    for k in obj.keys():
	params = obj[k]
	val = params['_']
	for p in params.keys():
	    if not (p == '_' or (p == 'charset' and params[p] == 'UTF-8')):
		warn("throwing away: params", k, params)
	if k in ('dtstart', 'dtend'):
	    val = asDate(val)
	elif k == 'rrule':
	    val = recurlex(val)
	elif k == 'n':
	    warn("struct", k, val)
	    structured_text(params,
			    val,
			    ('family-name',
			     'given-name',
			     'additional-name',
			     'honorific-prefix',
			     'honorific-suffix'))
	    val = params
	else:
	    val = unesc(val)
	obj[k] = val

    obj['id'] = id(obj) #@@kludge

    for k in ('dtstamp', 'dtend', 'summary'): #@@kludge
        if not obj.has_key(k):
	    obj[k] = asDate('20050124T205828Z') 

def structured_text(obj, val, keys):
    for comp, key in zip(val.split(";"), keys):
	obj[key] = comp

def warn(*args):
    import sys
    sys.stderr.write(' '.join([unicode(a).encode('utf-8') for a in args]))
    sys.stderr.write("\n")
	
def _test():
    import doctest
    doctest.testmod()

if __name__ == '__main__':
    import sys
    if '--test' in sys.argv:
	_test()
    else:
	main(sys.argv[1:])