kopia lustrzana https://github.com/collective/icalendar
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
rodzic
4d0cc5fae7
commit
33ab1b01ff
|
@ -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', )
|
||||
|
|
|
@ -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))
|
||||
|
|
Ładowanie…
Reference in New Issue