Improve handling of malformed items

This commit is contained in:
Markus Unterwaditzer 2018-01-05 18:14:19 +01:00
parent 50604f24f1
commit afa8031eec
4 changed files with 15 additions and 13 deletions

View file

@ -235,7 +235,7 @@ def test_broken_item():
assert 'Parsing error at line 1' in str(excinfo.value)
item = vobject.Item('END:FOO')
assert item.parsed is None
assert not item.is_parseable
def test_multiple_items():

View file

@ -40,7 +40,7 @@ def repair_storage(storage, repair_unsafe_uid):
def repair_item(href, item, seen_uids, repair_unsafe_uid):
if item.parsed is None:
if not item.is_parseable:
raise IrreparableItem()
new_item = item

View file

@ -27,6 +27,7 @@ sync_logger = logging.getLogger(__name__)
class _StorageInfo(object):
'''A wrapper class that holds prefetched items, the status and other
things.'''
def __init__(self, storage, status):
self.storage = storage
self.status = status
@ -57,6 +58,12 @@ class _StorageInfo(object):
# Prefetch items
for href, item, etag in (self.storage.get_multi(prefetch)
if prefetch else ()):
if not item.is_parseable:
sync_logger.warning(
'Storage "{}": item {} is malformed. '
'Please try to repair it.'
.format(self.storage.instance_name, href)
)
_store_props(item.ident, ItemMetadata(
href=href,
hash=item.hash,
@ -122,9 +129,9 @@ def sync(storage_a, storage_b, status, conflict_resolution=None,
raise BothReadOnly()
if conflict_resolution == 'a wins':
conflict_resolution = lambda a, b: a
def conflict_resolution(a, b): return a
elif conflict_resolution == 'b wins':
conflict_resolution = lambda a, b: b
def conflict_resolution(a, b): return b
status_nonempty = bool(next(status.iter_old(), None))

View file

@ -32,6 +32,10 @@ class Item(object):
native.change_uid(new_c, new_uid or '')
return Item(native.write_component(new_c), component=new_c)
@property
def is_parseable(self):
return bool(self._component)
@property
def raw(self):
'''Raw content of the item, as unicode string.
@ -70,15 +74,6 @@ class Item(object):
# 2. The status file would contain really sensitive information.
return self.uid or self.hash
@property
def parsed(self):
'''Don't cache because the rv is mutable.'''
# FIXME: remove
try:
return _Component.parse(self.raw)
except Exception:
return None
@property
def is_valid(self):
return bool(self._component)