mirror of
https://github.com/samsonjs/vdirsyncer.git
synced 2026-04-27 14:57:41 +00:00
Merge pull request #79 from untitaker/multi-vcalendar
split_collection: Allow multiple wrappers
This commit is contained in:
commit
7eedb170a2
3 changed files with 61 additions and 30 deletions
|
|
@ -12,25 +12,42 @@ import vdirsyncer.utils.vobject as vobject
|
||||||
from .. import normalize_item, VCARD_TEMPLATE, BARE_EVENT_TEMPLATE, \
|
from .. import normalize_item, VCARD_TEMPLATE, BARE_EVENT_TEMPLATE, \
|
||||||
EVENT_TEMPLATE
|
EVENT_TEMPLATE
|
||||||
|
|
||||||
_simple_joined = u'\r\n'.join((
|
|
||||||
u'BEGIN:VADDRESSBOOK',
|
|
||||||
VCARD_TEMPLATE.format(r=123),
|
|
||||||
VCARD_TEMPLATE.format(r=345),
|
|
||||||
VCARD_TEMPLATE.format(r=678),
|
|
||||||
u'END:VADDRESSBOOK\r\n'
|
|
||||||
))
|
|
||||||
|
|
||||||
_simple_split = [
|
_simple_split = [
|
||||||
VCARD_TEMPLATE.format(r=123),
|
VCARD_TEMPLATE.format(r=123),
|
||||||
VCARD_TEMPLATE.format(r=345),
|
VCARD_TEMPLATE.format(r=345),
|
||||||
VCARD_TEMPLATE.format(r=678)
|
VCARD_TEMPLATE.format(r=678)
|
||||||
]
|
]
|
||||||
|
|
||||||
|
_simple_joined = u'\r\n'.join(
|
||||||
|
[u'BEGIN:VADDRESSBOOK'] +
|
||||||
|
_simple_split +
|
||||||
|
[u'END:VADDRESSBOOK\r\n']
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
def test_split_collection_simple():
|
def test_split_collection_simple():
|
||||||
given = list(vobject.split_collection(_simple_joined))
|
given = list(vobject.split_collection(_simple_joined))
|
||||||
|
|
||||||
assert [normalize_item(item) for item in given] == \
|
assert [normalize_item(item) for item in given] == \
|
||||||
[normalize_item(item) for item in _simple_split]
|
[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_split_collection_multiple_wrappers():
|
||||||
|
joined = u'\r\n'.join(
|
||||||
|
u'BEGIN:VADDRESSBOOK\r\n' +
|
||||||
|
x +
|
||||||
|
u'\r\nEND:VADDRESSBOOK\r\n'
|
||||||
|
for x in _simple_split
|
||||||
|
)
|
||||||
|
given = list(vobject.split_collection(joined))
|
||||||
|
|
||||||
|
assert [normalize_item(item) for item in given] == \
|
||||||
|
[normalize_item(item) for item in _simple_split]
|
||||||
|
|
||||||
if vobject.ICALENDAR_ORIGINAL_ORDER_SUPPORT:
|
if vobject.ICALENDAR_ORIGINAL_ORDER_SUPPORT:
|
||||||
assert [x.splitlines() for x in given] == \
|
assert [x.splitlines() for x in given] == \
|
||||||
[x.splitlines() for x in _simple_split]
|
[x.splitlines() for x in _simple_split]
|
||||||
|
|
|
||||||
|
|
@ -11,7 +11,7 @@ import os
|
||||||
import requests
|
import requests
|
||||||
|
|
||||||
from .. import log, exceptions
|
from .. import log, exceptions
|
||||||
from .compat import urlparse, get_raw_input
|
from .compat import urlparse, get_raw_input, iteritems
|
||||||
|
|
||||||
|
|
||||||
logger = log.get(__name__)
|
logger = log.get(__name__)
|
||||||
|
|
@ -35,13 +35,19 @@ def expand_path(p):
|
||||||
|
|
||||||
def split_dict(d, f):
|
def split_dict(d, f):
|
||||||
'''Puts key into first dict if f(key), otherwise in second dict'''
|
'''Puts key into first dict if f(key), otherwise in second dict'''
|
||||||
a = {}
|
a, b = split_sequence(iteritems(d), lambda item: f(item[0]))
|
||||||
b = {}
|
return dict(a), dict(b)
|
||||||
for k, v in d.items():
|
|
||||||
if f(k):
|
|
||||||
a[k] = v
|
def split_sequence(s, f):
|
||||||
|
'''Puts item into first list if f(item), else in second list'''
|
||||||
|
a = []
|
||||||
|
b = []
|
||||||
|
for item in s:
|
||||||
|
if f(item):
|
||||||
|
a.append(item)
|
||||||
else:
|
else:
|
||||||
b[k] = v
|
b.append(item)
|
||||||
|
|
||||||
return a, b
|
return a, b
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -12,7 +12,7 @@ import icalendar.cal
|
||||||
import icalendar.parser
|
import icalendar.parser
|
||||||
import icalendar.caselessdict
|
import icalendar.caselessdict
|
||||||
|
|
||||||
from . import cached_property
|
from . import cached_property, split_sequence
|
||||||
from .compat import text_type, itervalues
|
from .compat import text_type, itervalues
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -128,25 +128,33 @@ def split_collection(text, inline=(u'VTIMEZONE',),
|
||||||
wrap_items_with=(u'VCALENDAR',)):
|
wrap_items_with=(u'VCALENDAR',)):
|
||||||
'''Emits items in the order they occur in the text.'''
|
'''Emits items in the order they occur in the text.'''
|
||||||
assert isinstance(text, text_type)
|
assert isinstance(text, text_type)
|
||||||
collection = icalendar.cal.Component.from_ical(text)
|
collections = icalendar.cal.Component.from_ical(text, multiple=True)
|
||||||
items = collection.subcomponents
|
assert collections
|
||||||
|
collection_name = None
|
||||||
|
|
||||||
if collection.name in wrap_items_with:
|
for collection in collections:
|
||||||
start = u'BEGIN:{}'.format(collection.name)
|
items = collection.subcomponents
|
||||||
end = u'END:{}'.format(collection.name)
|
if collection_name is None:
|
||||||
else:
|
collection_name = collection.name
|
||||||
start = end = u''
|
|
||||||
|
|
||||||
inlined_items = {}
|
if collection_name in wrap_items_with:
|
||||||
for item in items:
|
start = u'BEGIN:{}'.format(collection_name)
|
||||||
if item.name in inline:
|
end = u'END:{}'.format(collection_name)
|
||||||
inlined_items[item.name] = item
|
else:
|
||||||
|
start = end = u''
|
||||||
|
|
||||||
for item in items:
|
if collection.name != collection.name:
|
||||||
if item.name not in inline:
|
raise ValueError('Different types of components at top-level. '
|
||||||
|
'Expected {}, got {}.'
|
||||||
|
.format(collection_name, collection.name))
|
||||||
|
|
||||||
|
inlined_items, normal_items = \
|
||||||
|
split_sequence(items, lambda item: item.name in inline)
|
||||||
|
|
||||||
|
for item in normal_items:
|
||||||
lines = []
|
lines = []
|
||||||
lines.append(start)
|
lines.append(start)
|
||||||
for inlined_item in itervalues(inlined_items):
|
for inlined_item in inlined_items:
|
||||||
lines.extend(to_unicode_lines(inlined_item))
|
lines.extend(to_unicode_lines(inlined_item))
|
||||||
|
|
||||||
lines.extend(to_unicode_lines(item))
|
lines.extend(to_unicode_lines(item))
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue