mirror of
https://github.com/samsonjs/vdirsyncer.git
synced 2026-03-25 08:55:50 +00:00
Preserve order of parameters and properties
Since version 3.7, icalendar supports the preserving of the order of the ICS file's parameters and properties. We can use this to avoid unnecessary changes for .ics files managed with singlefilestorage.
This commit is contained in:
parent
2f299504ce
commit
9087b62647
3 changed files with 30 additions and 10 deletions
|
|
@ -5,6 +5,7 @@ python:
|
|||
- "3.4"
|
||||
env:
|
||||
- BUILD=tests DAV_SERVER=radicale RADICALE_BACKEND=filesystem REQUIREMENTS=release
|
||||
- BUILD=tests DAV_SERVER=radicale RADICALE_BACKEND=filesystem REQUIREMENTS=release PKGS='icalendar==3.6'
|
||||
- BUILD=tests DAV_SERVER=radicale RADICALE_BACKEND=filesystem REQUIREMENTS=devel
|
||||
- BUILD=tests DAV_SERVER=radicale RADICALE_BACKEND=database REQUIREMENTS=devel
|
||||
- BUILD=tests DAV_SERVER=owncloud REQUIREMENTS=release
|
||||
|
|
@ -12,5 +13,6 @@ env:
|
|||
|
||||
install:
|
||||
- "./build.sh install"
|
||||
- '[ -z "$PKGS" ] || pip install $PKGS'
|
||||
script:
|
||||
- "./build.sh run"
|
||||
|
|
|
|||
|
|
@ -7,8 +7,7 @@
|
|||
:license: MIT, see LICENSE for more details.
|
||||
'''
|
||||
|
||||
from vdirsyncer.utils.vobject import split_collection, join_collection, \
|
||||
hash_item
|
||||
import vdirsyncer.utils.vobject as vobject
|
||||
|
||||
from .. import normalize_item, VCARD_TEMPLATE, BARE_EVENT_TEMPLATE, \
|
||||
EVENT_TEMPLATE
|
||||
|
|
@ -18,7 +17,7 @@ _simple_joined = u'\r\n'.join((
|
|||
VCARD_TEMPLATE.format(r=123),
|
||||
VCARD_TEMPLATE.format(r=345),
|
||||
VCARD_TEMPLATE.format(r=678),
|
||||
u'END:VADDRESSBOOK'
|
||||
u'END:VADDRESSBOOK\r\n'
|
||||
))
|
||||
|
||||
_simple_split = [
|
||||
|
|
@ -29,16 +28,19 @@ _simple_split = [
|
|||
|
||||
|
||||
def test_split_collection_simple():
|
||||
given = split_collection(_simple_joined)
|
||||
given = list(vobject.split_collection(_simple_joined))
|
||||
assert [normalize_item(item) for item in given] == \
|
||||
[normalize_item(item) for item in _simple_split]
|
||||
if vobject.ICALENDAR_ORIGINAL_ORDER_SUPPORT:
|
||||
assert [x.splitlines() for x in given] == \
|
||||
[x.splitlines() for x in _simple_split]
|
||||
|
||||
|
||||
def test_join_collection_simple():
|
||||
given = join_collection(_simple_split)
|
||||
print(given)
|
||||
print(_simple_joined)
|
||||
given = vobject.join_collection(_simple_split)
|
||||
assert normalize_item(given) == normalize_item(_simple_joined)
|
||||
if vobject.ICALENDAR_ORIGINAL_ORDER_SUPPORT:
|
||||
assert given.splitlines() == _simple_joined.splitlines()
|
||||
|
||||
|
||||
def test_split_collection_timezones():
|
||||
|
|
@ -66,7 +68,8 @@ def test_split_collection_timezones():
|
|||
[timezone, u'END:VCALENDAR']
|
||||
)
|
||||
|
||||
given = set(normalize_item(item) for item in split_collection(full))
|
||||
given = set(normalize_item(item)
|
||||
for item in vobject.split_collection(full))
|
||||
expected = set(
|
||||
normalize_item(u'\r\n'.join((
|
||||
u'BEGIN:VCALENDAR', item, timezone, u'END:VCALENDAR'
|
||||
|
|
@ -81,4 +84,4 @@ def test_hash_item():
|
|||
a = EVENT_TEMPLATE.format(r=1)
|
||||
b = u'\n'.join(line for line in a.splitlines()
|
||||
if u'PRODID' not in line and u'VERSION' not in line)
|
||||
assert hash_item(a) == hash_item(b)
|
||||
assert vobject.hash_item(a) == vobject.hash_item(b)
|
||||
|
|
|
|||
|
|
@ -10,6 +10,7 @@ import hashlib
|
|||
|
||||
import icalendar.cal
|
||||
import icalendar.parser
|
||||
import icalendar.caselessdict
|
||||
|
||||
from . import text_type, itervalues
|
||||
|
||||
|
|
@ -36,6 +37,15 @@ IGNORE_PROPS = _process_properties(
|
|||
'REV'
|
||||
)
|
||||
|
||||
# Whether the installed icalendar version has
|
||||
# https://github.com/collective/icalendar/pull/136
|
||||
# (support for keeping the order of properties and parameters)
|
||||
#
|
||||
# This basically checks whether the superclass of all icalendar classes has a
|
||||
# method from OrderedDict.
|
||||
ICALENDAR_ORIGINAL_ORDER_SUPPORT = \
|
||||
hasattr(icalendar.caselessdict.CaselessDict, '__reversed__')
|
||||
|
||||
|
||||
def normalize_item(text, ignore_props=IGNORE_PROPS, use_icalendar=True):
|
||||
try:
|
||||
|
|
@ -90,7 +100,12 @@ def to_unicode_lines(item):
|
|||
'''icalendar doesn't provide an efficient way of getting the ical data as
|
||||
unicode. So let's do it ourselves.'''
|
||||
|
||||
for content_line in item.content_lines():
|
||||
if ICALENDAR_ORIGINAL_ORDER_SUPPORT:
|
||||
content_lines = item.content_lines(sorted=False)
|
||||
else:
|
||||
content_lines = item.content_lines()
|
||||
|
||||
for content_line in content_lines:
|
||||
if content_line:
|
||||
# https://github.com/untitaker/vdirsyncer/issues/70
|
||||
# icalendar escapes semicolons which are not supposed to get
|
||||
|
|
|
|||
Loading…
Reference in a new issue