vRecur.ical()'s parts are in canonical order.

Mac iCal ignores RRULEs where FREQ is not the first rule part. vRecur.ical() now sorts those parts according to the order listed in RFC 5545, section 3.3.10.

Signed-off-by: Rok Garbas <rok@garbas.si>
pull/6/head
George V. Reilly 2011-05-26 15:09:27 -07:00 zatwierdzone przez Rok Garbas
rodzic 04ae7637e7
commit f0117b7898
1 zmienionych plików z 17 dodań i 8 usunięć

Wyświetl plik

@ -929,7 +929,7 @@ class vRecur(CaselessDict):
>>> r['byminute'] = 30
>>> r = vRecur(r)
>>> r.ical()
'BYHOUR=8,9;BYDAY=SU;BYMINUTE=30;BYMONTH=1;FREQ=YEARLY;INTERVAL=2'
'FREQ=YEARLY;INTERVAL=2;BYMINUTE=30;BYHOUR=8,9;BYDAY=SU;BYMONTH=1'
>>> r = vRecur(FREQ='yearly', INTERVAL=2)
>>> r['BYMONTH'] = 1
@ -937,12 +937,12 @@ class vRecur(CaselessDict):
>>> r['BYHOUR'] = [8,9]
>>> r['BYMINUTE'] = 30
>>> r.ical()
'BYDAY=SU;BYMINUTE=30;BYMONTH=1;INTERVAL=2;FREQ=YEARLY;BYHOUR=8,9'
'FREQ=YEARLY;INTERVAL=2;BYMINUTE=30;BYHOUR=8,9;BYDAY=SU;BYMONTH=1'
>>> r = vRecur(freq='DAILY', count=10)
>>> r['bysecond'] = [0, 15, 30, 45]
>>> r.ical()
'COUNT=10;FREQ=DAILY;BYSECOND=0,15,30,45'
'FREQ=DAILY;COUNT=10;BYSECOND=0,15,30,45'
>>> r = vRecur(freq='DAILY', until=datetime(2005,1,1,12,0,0))
>>> r.ical()
@ -953,23 +953,23 @@ class vRecur(CaselessDict):
>>> r
{'COUNT': [10], 'FREQ': ['DAILY'], 'INTERVAL': [2]}
>>> vRecur(r).ical()
'COUNT=10;FREQ=DAILY;INTERVAL=2'
'FREQ=DAILY;COUNT=10;INTERVAL=2'
>>> r = vRecur.from_ical('FREQ=YEARLY;INTERVAL=2;BYMONTH=1;BYDAY=-SU;BYHOUR=8,9;BYMINUTE=30')
>>> r
{'BYHOUR': [8, 9], 'BYDAY': ['-SU'], 'BYMINUTE': [30], 'BYMONTH': [1], 'FREQ': ['YEARLY'], 'INTERVAL': [2]}
>>> vRecur(r).ical()
'BYDAY=-SU;BYMINUTE=30;INTERVAL=2;BYMONTH=1;FREQ=YEARLY;BYHOUR=8,9'
'FREQ=YEARLY;INTERVAL=2;BYMINUTE=30;BYHOUR=8,9;BYDAY=-SU;BYMONTH=1'
Some examples from the spec
>>> r = vRecur.from_ical('FREQ=MONTHLY;BYDAY=MO,TU,WE,TH,FR;BYSETPOS=-1')
>>> vRecur(r).ical()
'BYSETPOS=-1;FREQ=MONTHLY;BYDAY=MO,TU,WE,TH,FR'
'FREQ=MONTHLY;BYDAY=MO,TU,WE,TH,FR;BYSETPOS=-1'
>>> r = vRecur.from_ical('FREQ=YEARLY;INTERVAL=2;BYMONTH=1;BYDAY=SU;BYHOUR=8,9;BYMINUTE=30')
>>> vRecur(r).ical()
'BYDAY=SU;BYMINUTE=30;INTERVAL=2;BYMONTH=1;FREQ=YEARLY;BYHOUR=8,9'
'FREQ=YEARLY;INTERVAL=2;BYMINUTE=30;BYHOUR=8,9;BYDAY=SU;BYMONTH=1'
and some errors
>>> r = vRecur.from_ical('BYDAY=12')
@ -982,6 +982,10 @@ class vRecur(CaselessDict):
frequencies = ["SECONDLY", "MINUTELY", "HOURLY", "DAILY", "WEEKLY",
"MONTHLY", "YEARLY"]
canonical_order = [ "FREQ", "UNTIL", "COUNT", "INTERVAL",
"BYSECOND", "BYMINUTE", "BYHOUR", "BYDAY", "BYMONTHDAY", "BYYEARDAY",
"BYWEEKNO", "BYMONTH", "BYSETPOS", "WKST" ]
types = CaselessDict({
'COUNT':vInt,
'INTERVAL':vInt,
@ -1005,7 +1009,7 @@ class vRecur(CaselessDict):
def ical(self):
# SequenceTypes
result = []
for key, vals in self.items():
for key, vals in self.sorted_items():
typ = self.types[key]
if not type(vals) in SequenceTypes:
vals = [vals]
@ -1013,6 +1017,11 @@ class vRecur(CaselessDict):
result.append('%s=%s' % (key, vals))
return ';'.join(result)
def sorted_items(self):
"""Mac iCal ignores RRULEs where FREQ is not the first rule part.
Sorts parts according to the order listed in RFC 5545, section 3.3.10."""
return [(k, self[k]) for k in self.canonical_order if self.get(k)]
def parse_type(key, values):
# integers
parser = vRecur.types.get(key, vText)