mirror of
https://github.com/samsonjs/vdirsyncer.git
synced 2026-04-27 14:57:41 +00:00
Merge branch 'vcards_split'
This commit is contained in:
commit
8493407c49
3 changed files with 29 additions and 19 deletions
|
|
@ -18,7 +18,8 @@ vdirsyncer.log.set_level(vdirsyncer.log.logging.DEBUG)
|
||||||
def normalize_item(item):
|
def normalize_item(item):
|
||||||
if not isinstance(item, text_type):
|
if not isinstance(item, text_type):
|
||||||
item = item.raw
|
item = item.raw
|
||||||
return tuple(sorted(_normalize_item(item).splitlines()))
|
return tuple(sorted(_normalize_item(
|
||||||
|
item, use_icalendar=False).splitlines()))
|
||||||
|
|
||||||
|
|
||||||
def assert_item_equals(a, b):
|
def assert_item_equals(a, b):
|
||||||
|
|
@ -30,11 +31,11 @@ VERSION:3.0
|
||||||
FN:Cyrus Daboo
|
FN:Cyrus Daboo
|
||||||
N:Daboo;Cyrus
|
N:Daboo;Cyrus
|
||||||
ADR;TYPE=POSTAL:;2822 Email HQ;Suite 2821;RFCVille;PA;15213;USA
|
ADR;TYPE=POSTAL:;2822 Email HQ;Suite 2821;RFCVille;PA;15213;USA
|
||||||
EMAIL;TYPE=INTERNET;TYPE=PREF:cyrus@example.com
|
EMAIL;TYPE=PREF:cyrus@example.com
|
||||||
NICKNAME:me
|
NICKNAME:me
|
||||||
NOTE:Example VCard.
|
NOTE:Example VCard.
|
||||||
ORG:Self Employed
|
ORG:Self Employed
|
||||||
TEL;TYPE=WORK;TYPE=VOICE:412 605 0499
|
TEL;TYPE=VOICE:412 605 0499
|
||||||
TEL;TYPE=FAX:412 605 0705
|
TEL;TYPE=FAX:412 605 0705
|
||||||
URL:http://www.example.com
|
URL:http://www.example.com
|
||||||
X-SOMETHING:{r}
|
X-SOMETHING:{r}
|
||||||
|
|
|
||||||
|
|
@ -10,22 +10,21 @@
|
||||||
from vdirsyncer.utils.vobject import split_collection, join_collection, \
|
from vdirsyncer.utils.vobject import split_collection, join_collection, \
|
||||||
hash_item
|
hash_item
|
||||||
|
|
||||||
from .. import normalize_item, SIMPLE_TEMPLATE, BARE_EVENT_TEMPLATE, \
|
from .. import normalize_item, VCARD_TEMPLATE, BARE_EVENT_TEMPLATE, \
|
||||||
EVENT_TEMPLATE
|
EVENT_TEMPLATE
|
||||||
|
|
||||||
|
|
||||||
_simple_joined = u'\r\n'.join((
|
_simple_joined = u'\r\n'.join((
|
||||||
u'BEGIN:VADDRESSBOOK',
|
u'BEGIN:VADDRESSBOOK',
|
||||||
SIMPLE_TEMPLATE.format(r=123),
|
VCARD_TEMPLATE.format(r=123),
|
||||||
SIMPLE_TEMPLATE.format(r=345),
|
VCARD_TEMPLATE.format(r=345),
|
||||||
SIMPLE_TEMPLATE.format(r=678),
|
VCARD_TEMPLATE.format(r=678),
|
||||||
u'END:VADDRESSBOOK'
|
u'END:VADDRESSBOOK'
|
||||||
))
|
))
|
||||||
|
|
||||||
_simple_split = [
|
_simple_split = [
|
||||||
SIMPLE_TEMPLATE.format(r=123),
|
VCARD_TEMPLATE.format(r=123),
|
||||||
SIMPLE_TEMPLATE.format(r=345),
|
VCARD_TEMPLATE.format(r=345),
|
||||||
SIMPLE_TEMPLATE.format(r=678)
|
VCARD_TEMPLATE.format(r=678)
|
||||||
]
|
]
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -36,10 +35,7 @@ def test_split_collection_simple():
|
||||||
|
|
||||||
|
|
||||||
def test_join_collection_simple():
|
def test_join_collection_simple():
|
||||||
item_type = _simple_split[0].splitlines()[0][len(u'BEGIN:'):]
|
given = join_collection(_simple_split)
|
||||||
given = join_collection(_simple_split, wrappers={
|
|
||||||
item_type: (u'VADDRESSBOOK', ())
|
|
||||||
})
|
|
||||||
print(given)
|
print(given)
|
||||||
print(_simple_joined)
|
print(_simple_joined)
|
||||||
assert normalize_item(given) == normalize_item(_simple_joined)
|
assert normalize_item(given) == normalize_item(_simple_joined)
|
||||||
|
|
|
||||||
|
|
@ -13,7 +13,17 @@ import icalendar.parser
|
||||||
|
|
||||||
from . import text_type, itervalues
|
from . import text_type, itervalues
|
||||||
|
|
||||||
IGNORE_PROPS = frozenset((
|
|
||||||
|
def _process_properties(*s):
|
||||||
|
rv = set()
|
||||||
|
for key in s:
|
||||||
|
rv.add(key + ':')
|
||||||
|
rv.add(key + ';')
|
||||||
|
|
||||||
|
return frozenset(rv)
|
||||||
|
|
||||||
|
|
||||||
|
IGNORE_PROPS = _process_properties(
|
||||||
# PRODID is changed by radicale for some reason after upload
|
# PRODID is changed by radicale for some reason after upload
|
||||||
'PRODID',
|
'PRODID',
|
||||||
# VERSION can get lost in singlefile storage
|
# VERSION can get lost in singlefile storage
|
||||||
|
|
@ -24,11 +34,13 @@ IGNORE_PROPS = frozenset((
|
||||||
# REV is from the VCARD specification and is supposed to change when the
|
# REV is from the VCARD specification and is supposed to change when the
|
||||||
# item does -- however, we can determine that ourselves
|
# item does -- however, we can determine that ourselves
|
||||||
'REV'
|
'REV'
|
||||||
))
|
)
|
||||||
|
|
||||||
|
|
||||||
def normalize_item(text, ignore_props=IGNORE_PROPS):
|
def normalize_item(text, ignore_props=IGNORE_PROPS, use_icalendar=True):
|
||||||
try:
|
try:
|
||||||
|
if not use_icalendar:
|
||||||
|
raise Exception()
|
||||||
lines = to_unicode_lines(icalendar.cal.Component.from_ical(text))
|
lines = to_unicode_lines(icalendar.cal.Component.from_ical(text))
|
||||||
except Exception:
|
except Exception:
|
||||||
lines = sorted(text.splitlines())
|
lines = sorted(text.splitlines())
|
||||||
|
|
@ -36,7 +48,7 @@ def normalize_item(text, ignore_props=IGNORE_PROPS):
|
||||||
return u'\r\n'.join(line.strip()
|
return u'\r\n'.join(line.strip()
|
||||||
for line in lines
|
for line in lines
|
||||||
if line.strip() and
|
if line.strip() and
|
||||||
not any(line.startswith(p + ':')
|
not any(line.startswith(p)
|
||||||
for p in IGNORE_PROPS))
|
for p in IGNORE_PROPS))
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -81,6 +93,7 @@ def to_unicode_lines(item):
|
||||||
|
|
||||||
for content_line in item.content_lines():
|
for content_line in item.content_lines():
|
||||||
if content_line:
|
if content_line:
|
||||||
|
content_line = content_line.replace(u'\\;', u';')
|
||||||
yield icalendar.parser.foldline(content_line)
|
yield icalendar.parser.foldline(content_line)
|
||||||
|
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue