Generate VEVENTs in canonical order.

The default sorted order was extremely irritating:
DTEND before DTSTART, etc.
Now the important properties are listed first:
        'SUMMARY', 'DTSTART', 'DTEND', 'DURATION', 'DTSTAMP',
        'UID', 'RECURRENCE-ID', 'SEQUENCE',
        'RRULE' 'EXRULE', 'RDATE', 'EXDATE',

Also, fixed spelling of RECURRENCE-ID and LAST-MODIFIED.
pull/14/head
George V. Reilly 2011-12-21 19:38:40 -08:00
rodzic 4d0cc5fae7
commit 33ab1b01ff
2 zmienionych plików z 27 dodań i 10 usunięć

Wyświetl plik

@ -325,8 +325,7 @@ class Component(CaselessDict):
"""
vText = types_factory['text']
properties = [('BEGIN', vText(self.name).ical())]
property_names = self.keys()
property_names.sort()
property_names = self.sorted_keys()
for name in property_names:
values = self[name]
if type(values) == ListType:
@ -436,11 +435,17 @@ class Event(Component):
name = 'VEVENT'
canonical_order = (
'SUMMARY', 'DTSTART', 'DTEND', 'DURATION', 'DTSTAMP',
'UID', 'RECURRENCE-ID', 'SEQUENCE',
'RRULE' 'EXRULE', 'RDATE', 'EXDATE',
)
required = ('UID',)
singletons = (
'CLASS', 'CREATED', 'DESCRIPTION', 'DTSTART', 'GEO',
'LAST-MOD', 'LOCATION', 'ORGANIZER', 'PRIORITY', 'DTSTAMP', 'SEQUENCE',
'STATUS', 'SUMMARY', 'TRANSP', 'URL', 'RECURID', 'DTEND', 'DURATION',
'LAST-MODIFIED', 'LOCATION', 'ORGANIZER', 'PRIORITY', 'DTSTAMP', 'SEQUENCE',
'STATUS', 'SUMMARY', 'TRANSP', 'URL', 'RECURRENCE-ID', 'DTEND', 'DURATION',
'DTSTART',
)
exclusive = ('DTEND', 'DURATION', )
@ -458,8 +463,8 @@ class Todo(Component):
required = ('UID',)
singletons = (
'CLASS', 'COMPLETED', 'CREATED', 'DESCRIPTION', 'DTSTAMP', 'DTSTART',
'GEO', 'LAST-MOD', 'LOCATION', 'ORGANIZER', 'PERCENT', 'PRIORITY',
'RECURID', 'SEQUENCE', 'STATUS', 'SUMMARY', 'UID', 'URL', 'DUE', 'DURATION',
'GEO', 'LAST-MODIFIED', 'LOCATION', 'ORGANIZER', 'PERCENT', 'PRIORITY',
'RECURRENCE-ID', 'SEQUENCE', 'STATUS', 'SUMMARY', 'UID', 'URL', 'DUE', 'DURATION',
)
exclusive = ('DUE', 'DURATION',)
multiple = (
@ -475,8 +480,8 @@ class Journal(Component):
required = ('UID',)
singletons = (
'CLASS', 'CREATED', 'DESCRIPTION', 'DTSTART', 'DTSTAMP', 'LAST-MOD',
'ORGANIZER', 'RECURID', 'SEQUENCE', 'STATUS', 'SUMMARY', 'UID', 'URL',
'CLASS', 'CREATED', 'DESCRIPTION', 'DTSTART', 'DTSTAMP', 'LAST-MODIFIED',
'ORGANIZER', 'RECURRENCE-ID', 'SEQUENCE', 'STATUS', 'SUMMARY', 'UID', 'URL',
)
multiple = (
'ATTACH', 'ATTENDEE', 'CATEGORIES', 'COMMENT', 'CONTACT', 'EXDATE',
@ -499,12 +504,13 @@ class FreeBusy(Component):
class Timezone(Component):
name = 'VTIMEZONE'
canonical_order = ('TZID', 'STANDARDC', 'DAYLIGHTC',)
required = (
'TZID', 'STANDARDC', 'DAYLIGHTC', 'DTSTART', 'TZOFFSETTO',
'TZOFFSETFROM'
)
singletons = ('LAST-MOD', 'TZURL', 'TZID',)
singletons = ('LAST-MODIFIED', 'TZURL', 'TZID',)
multiple = ('COMMENT', 'RDATE', 'RRULE', 'TZNAME',)
@ -537,7 +543,7 @@ class Calendar(Component):
>>> event.set('dtstart', datetime(2005,4,4,8,0,0))
>>> cal.add_component(event)
>>> cal.subcomponents[0].as_string()
'BEGIN:VEVENT\\r\\nDTSTART;VALUE=DATE-TIME:20050404T080000\\r\\nSUMMARY:Python meeting about calendaring\\r\\nUID:42\\r\\nEND:VEVENT\\r\\n'
'BEGIN:VEVENT\\r\\nSUMMARY:Python meeting about calendaring\\r\\nDTSTART;VALUE=DATE-TIME:20050404T080000\\r\\nUID:42\\r\\nEND:VEVENT\\r\\n'
Write to disc
>>> import tempfile, os
@ -572,6 +578,7 @@ class Calendar(Component):
"""
name = 'VCALENDAR'
canonical_order = ('PRODID', 'VERSION', 'CALSCALE', 'METHOD',)
required = ('prodid', 'version', )
singletons = ('prodid', 'version', )
multiple = ('calscale', 'method', )

Wyświetl plik

@ -91,3 +91,13 @@ class CaselessDict(dict):
def __repr__(self):
return 'CaselessDict(' + dict.__repr__(self) + ')'
canonical_order = None
def sorted_keys(self):
"""
Sorts keys according to the canonical_order for the derived class.
Keys not specified in canonical_order will appear at the end.
"""
canonical_map = dict((k, i) for i, k in enumerate(self.canonical_order or []))
return sorted(self.keys(), key=lambda k: canonical_map.get(k, 999))