mirror of
https://github.com/samsonjs/vdirsyncer.git
synced 2026-03-25 08:55:50 +00:00
Simplify sync code
Before deletion, vdirsyncer will now check if the item changed on the other side, and induce a re-upload if the item did change. Because of this behavior it is now possible to remove the special-casing if no status is available. Fix #128
This commit is contained in:
parent
f22548000b
commit
6bd5bf7422
2 changed files with 50 additions and 19 deletions
|
|
@ -148,6 +148,21 @@ def test_conflict_resolution_both_etags_new(winning_storage):
|
|||
assert u'item {}'.format(winning_storage) in n
|
||||
|
||||
|
||||
def test_updated_and_deleted():
|
||||
a = MemoryStorage()
|
||||
b = MemoryStorage()
|
||||
href_a, etag_a = a.upload(Item(u'UID:1'))
|
||||
status = {}
|
||||
sync(a, b, status, force_delete=True)
|
||||
|
||||
(href_b, etag_b), = b.list()
|
||||
b.delete(href_b, etag_b)
|
||||
a.update(href_a, Item(u'UID:1\nupdated'), etag_a)
|
||||
sync(a, b, status, force_delete=True)
|
||||
|
||||
assert len(list(a.list())) == len(list(b.list())) == 1
|
||||
|
||||
|
||||
def test_conflict_resolution_invalid_mode():
|
||||
a = MemoryStorage()
|
||||
b = MemoryStorage()
|
||||
|
|
|
|||
|
|
@ -273,25 +273,41 @@ def _get_actions(storages, status):
|
|||
|
||||
a = a_idents.get(ident, None)
|
||||
b = b_idents.get(ident, None)
|
||||
if ident not in status:
|
||||
if a and b: # missing status
|
||||
yield _action_conflict_resolve(ident)
|
||||
elif a and not b: # new item was created in a
|
||||
yield _action_upload(ident, 'b')
|
||||
elif not a and b: # new item was created in b
|
||||
yield _action_upload(ident, 'a')
|
||||
else:
|
||||
assert not a or a['etag'] is not None
|
||||
assert not b or b['etag'] is not None
|
||||
|
||||
try:
|
||||
_, status_etag_a, _, status_etag_b = status[ident]
|
||||
if a and b:
|
||||
if a['etag'] != status_etag_a and b['etag'] != status_etag_b:
|
||||
yield _action_conflict_resolve(ident)
|
||||
elif a['etag'] != status_etag_a: # item was updated in a
|
||||
yield _action_update(ident, 'b')
|
||||
elif b['etag'] != status_etag_b: # item was updated in b
|
||||
yield _action_update(ident, 'a')
|
||||
elif a and not b: # was deleted from b
|
||||
except KeyError:
|
||||
status_etag_a = status_etag_b = None
|
||||
|
||||
if a and b:
|
||||
if a['etag'] != status_etag_a and b['etag'] != status_etag_b:
|
||||
# item was modified on both sides
|
||||
# OR: missing status
|
||||
yield _action_conflict_resolve(ident)
|
||||
elif a['etag'] != status_etag_a:
|
||||
# item was only modified in a
|
||||
yield _action_update(ident, 'b')
|
||||
elif b['etag'] != status_etag_b:
|
||||
# item was only modified in b
|
||||
yield _action_update(ident, 'a')
|
||||
elif a and not b:
|
||||
if a['etag'] != status_etag_a:
|
||||
# was deleted from b but modified on a
|
||||
# OR: new item was created in a
|
||||
yield _action_upload(ident, 'b')
|
||||
else:
|
||||
# was deleted from b and not modified on a
|
||||
yield _action_delete(ident, 'a')
|
||||
elif not a and b: # was deleted from a
|
||||
elif not a and b:
|
||||
if b['etag'] != status_etag_b:
|
||||
# was deleted from a but modified on b
|
||||
# OR: new item was created in b
|
||||
yield _action_upload(ident, 'a')
|
||||
else:
|
||||
# was deleted from a and not changed on b
|
||||
yield _action_delete(ident, 'b')
|
||||
elif not a and not b: # was deleted from a and b
|
||||
yield _action_delete(ident, None)
|
||||
elif not a and not b:
|
||||
# was deleted from a and b, clean up status
|
||||
yield _action_delete(ident, None)
|
||||
|
|
|
|||
Loading…
Reference in a new issue