mirror of
https://github.com/samsonjs/vdirsyncer.git
synced 2026-04-27 14:57:41 +00:00
More refactoring
This commit is contained in:
parent
a949b07233
commit
ba99c599c3
1 changed files with 42 additions and 62 deletions
|
|
@ -7,13 +7,14 @@
|
||||||
:license: MIT, see LICENSE for more details.
|
:license: MIT, see LICENSE for more details.
|
||||||
'''
|
'''
|
||||||
import hashlib
|
import hashlib
|
||||||
|
from itertools import chain, tee
|
||||||
|
|
||||||
import icalendar.cal
|
import icalendar.cal
|
||||||
import icalendar.caselessdict
|
import icalendar.caselessdict
|
||||||
import icalendar.parser
|
import icalendar.parser
|
||||||
|
|
||||||
from . import cached_property, split_sequence
|
from . import cached_property, split_sequence, uniq
|
||||||
from .compat import itervalues, text_type
|
from .compat import text_type
|
||||||
|
|
||||||
|
|
||||||
def _process_properties(*s):
|
def _process_properties(*s):
|
||||||
|
|
@ -140,33 +141,27 @@ def split_collection(text, inline=(u'VTIMEZONE',),
|
||||||
collection_name = None
|
collection_name = None
|
||||||
|
|
||||||
for collection in collections:
|
for collection in collections:
|
||||||
items = collection.subcomponents
|
|
||||||
if collection_name is None:
|
if collection_name is None:
|
||||||
collection_name = collection.name
|
collection_name = collection.name
|
||||||
|
start = end = ()
|
||||||
if collection_name in wrap_items_with:
|
if collection_name in wrap_items_with:
|
||||||
start = u'BEGIN:{}'.format(collection_name)
|
start = (u'BEGIN:{}'.format(collection_name),)
|
||||||
end = u'END:{}'.format(collection_name)
|
end = (u'END:{}'.format(collection_name),)
|
||||||
else:
|
|
||||||
start = end = u''
|
|
||||||
|
|
||||||
if collection.name != collection_name:
|
elif collection.name != collection_name:
|
||||||
raise ValueError('Different types of components at top-level. '
|
raise ValueError('Different types of components at top-level. '
|
||||||
'Expected {}, got {}.'
|
'Expected {}, got {}.'
|
||||||
.format(collection_name, collection.name))
|
.format(collection_name, collection.name))
|
||||||
|
|
||||||
inlined_items, normal_items = \
|
inlined_items, normal_items = split_sequence(
|
||||||
split_sequence(items, lambda item: item.name in inline)
|
collection.subcomponents,
|
||||||
|
lambda item: item.name in inline
|
||||||
|
)
|
||||||
|
inlined_lines = list(chain(*(to_unicode_lines(inlined_item)
|
||||||
|
for inlined_item in inlined_items)))
|
||||||
|
|
||||||
for item in normal_items:
|
for item in normal_items:
|
||||||
lines = []
|
lines = chain(start, inlined_lines, to_unicode_lines(item), end)
|
||||||
lines.append(start)
|
|
||||||
for inlined_item in inlined_items:
|
|
||||||
lines.extend(to_unicode_lines(inlined_item))
|
|
||||||
|
|
||||||
lines.extend(to_unicode_lines(item))
|
|
||||||
lines.append(end)
|
|
||||||
|
|
||||||
yield u''.join(line + u'\r\n' for line in lines if line)
|
yield u''.join(line + u'\r\n' for line in lines if line)
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -189,58 +184,43 @@ def to_unicode_lines(item):
|
||||||
|
|
||||||
|
|
||||||
_default_join_wrappers = {
|
_default_join_wrappers = {
|
||||||
u'VCALENDAR': (u'VCALENDAR', (u'VTIMEZONE',)),
|
u'VCALENDAR': u'VCALENDAR',
|
||||||
u'VEVENT': (u'VCALENDAR', (u'VTIMEZONE',)),
|
u'VEVENT': u'VCALENDAR',
|
||||||
u'VTODO': (u'VCALENDAR', (u'VTIMEZONE',)),
|
u'VTODO': u'VCALENDAR',
|
||||||
u'VCARD': (u'VADDRESSBOOK', ())
|
u'VCARD': u'VADDRESSBOOK'
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
def join_collection(items, wrappers=_default_join_wrappers):
|
def join_collection(items, wrappers=_default_join_wrappers):
|
||||||
'''
|
'''
|
||||||
:param wrappers: {
|
:param wrappers: {
|
||||||
item_type: wrapper_type, common_components
|
item_type: wrapper_type
|
||||||
}
|
}
|
||||||
|
|
||||||
Common components are those who can be moved from the item into the
|
|
||||||
wrapper, with duplicates removed.
|
|
||||||
'''
|
'''
|
||||||
inline = {}
|
|
||||||
components = []
|
|
||||||
wrapper_type = None
|
|
||||||
inline_types = None
|
|
||||||
item_type = None
|
|
||||||
|
|
||||||
def handle_item(item):
|
items1, items2 = tee((icalendar.cal.Component.from_ical(x)
|
||||||
if item.name in inline_types:
|
for x in items), 2)
|
||||||
inline[tuple(to_unicode_lines(item))] = item
|
item_type, wrapper_type = _get_item_type(items1, wrappers)
|
||||||
else:
|
_get_item_components = lambda x: (x.name == wrapper_type
|
||||||
components.append(item)
|
and x.subcomponents
|
||||||
|
or [x])
|
||||||
|
components = chain(*(_get_item_components(x) for x in items2))
|
||||||
|
lines = chain(*uniq(tuple(to_unicode_lines(x)) for x in components))
|
||||||
|
|
||||||
for item in items:
|
|
||||||
component = icalendar.cal.Component.from_ical(item)
|
|
||||||
|
|
||||||
if item_type is None:
|
|
||||||
item_type = component.name
|
|
||||||
wrapper_type, inline_types = wrappers[item_type]
|
|
||||||
|
|
||||||
if component.name == item_type:
|
|
||||||
if item_type == wrapper_type:
|
|
||||||
for subcomponent in component.subcomponents:
|
|
||||||
handle_item(subcomponent)
|
|
||||||
else:
|
|
||||||
handle_item(component)
|
|
||||||
|
|
||||||
start = end = u''
|
|
||||||
if wrapper_type is not None:
|
if wrapper_type is not None:
|
||||||
start = u'BEGIN:{}'.format(wrapper_type)
|
start = [u'BEGIN:{}'.format(wrapper_type)]
|
||||||
end = u'END:{}'.format(wrapper_type)
|
end = [u'END:{}'.format(wrapper_type)]
|
||||||
|
lines = chain(start, lines, end)
|
||||||
lines = [start]
|
|
||||||
for inlined_item in itervalues(inline):
|
|
||||||
lines.extend(to_unicode_lines(inlined_item))
|
|
||||||
for component in components:
|
|
||||||
lines.extend(to_unicode_lines(component))
|
|
||||||
lines.append(end)
|
|
||||||
|
|
||||||
return u''.join(line + u'\r\n' for line in lines)
|
return u''.join(line + u'\r\n' for line in lines)
|
||||||
|
|
||||||
|
|
||||||
|
def _get_item_type(components, wrappers):
|
||||||
|
for component in components:
|
||||||
|
try:
|
||||||
|
item_type = component.name
|
||||||
|
wrapper_type = wrappers[item_type]
|
||||||
|
except KeyError:
|
||||||
|
pass
|
||||||
|
else:
|
||||||
|
return item_type, wrapper_type
|
||||||
|
return None, None
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue