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