mirror of
https://github.com/samsonjs/vdirsyncer.git
synced 2026-04-02 10:15:50 +00:00
Clean up mess in sync partially
This commit is contained in:
parent
2d30d1b7f2
commit
cc44b85e25
1 changed files with 56 additions and 49 deletions
|
|
@ -34,55 +34,21 @@ def sync(storage_a, storage_b, status):
|
|||
items_a = {} # items prefetched for copy
|
||||
items_b = {} # {uid: (item, etag)}
|
||||
|
||||
storages = {
|
||||
'a': [storage_a, items_a, list_a],
|
||||
'b': [storage_b, items_b, list_b]
|
||||
}
|
||||
|
||||
def get_actions():
|
||||
already_handled = set()
|
||||
prefetch_from_a = []
|
||||
prefetch_from_b = []
|
||||
actions = [] # list(tuple(action, uid, source, dest))
|
||||
for uid in itertools.chain(list_a, list_b, status):
|
||||
if uid in already_handled:
|
||||
continue
|
||||
already_handled.add(uid)
|
||||
if uid not in status:
|
||||
if uid in list_a and uid in list_b: # missing status
|
||||
# TODO: might need some kind of diffing too?
|
||||
status[uid] = (list_a[uid], list_b[uid])
|
||||
elif uid in list_a and uid not in list_b: # new item in a
|
||||
prefetch_from_a.append(uid)
|
||||
actions.append(('upload', uid, 'a', 'b'))
|
||||
elif uid not in list_a and uid in list_b: # new item in b
|
||||
prefetch_from_b.append(uid)
|
||||
actions.append(('upload', uid, 'b', 'a'))
|
||||
else:
|
||||
if uid in list_a and uid in list_b:
|
||||
if list_a[uid] != status[uid][0] and list_b[uid] != status[uid][1]:
|
||||
1/0 # conflict resolution TODO
|
||||
elif list_a[uid] != status[uid][0]: # item update in a
|
||||
prefetch_from_a.append(uid)
|
||||
actions.append(('update', uid, 'a', 'b'))
|
||||
elif list_b[uid] != status[uid][1]: # item update in b
|
||||
prefetch_from_b.append(uid)
|
||||
actions.append(('update', uid, 'b', 'a'))
|
||||
else: # completely in sync!
|
||||
pass
|
||||
elif uid in list_a and uid not in list_b: # deleted from b
|
||||
actions.append(('delete', uid, 'b', 'a'))
|
||||
elif uid not in list_a and uid in list_b: # deleted from a
|
||||
actions.append(('delete', uid, 'a', 'b'))
|
||||
elif uid not in list_a and uid not in list_b: # deleted from a and b
|
||||
del status[uid]
|
||||
return actions, prefetch_from_a, prefetch_from_b
|
||||
actions, prefetch_from_a, prefetch_from_b = get_actions()
|
||||
actions, prefetch_from_a, prefetch_from_b = \
|
||||
get_actions(list_a, list_b, status)
|
||||
|
||||
for item, uid, etag in storage_a.get_multi(prefetch_from_a):
|
||||
items_a[uid] = (item, etag)
|
||||
for item, uid, etag in storage_b.get_multi(prefetch_from_b):
|
||||
items_b[uid] = (item, etag)
|
||||
def prefetch():
|
||||
for item, uid, etag in storage_a.get_multi(prefetch_from_a):
|
||||
items_a[uid] = (item, etag)
|
||||
for item, uid, etag in storage_b.get_multi(prefetch_from_b):
|
||||
items_b[uid] = (item, etag)
|
||||
prefetch()
|
||||
|
||||
storages = {
|
||||
'a': (storage_a, items_a, list_a),
|
||||
'b': (storage_b, items_b, list_b),
|
||||
None: (None, None, None)
|
||||
}
|
||||
|
||||
for action, uid, source, dest in actions:
|
||||
source_storage, source_items, source_list = storages[source]
|
||||
|
|
@ -96,5 +62,46 @@ def sync(storage_a, storage_b, status):
|
|||
dest_etag = dest_storage.update(item, dest_list[uid])
|
||||
status[uid] = (source_etag, dest_etag) if source == 'a' else (dest_etag, source_etag)
|
||||
elif action == 'delete':
|
||||
dest_storage.delete(uid, dest_list[uid])
|
||||
if dest is not None:
|
||||
dest_storage.delete(uid, dest_list[uid])
|
||||
del status[uid]
|
||||
|
||||
def get_actions(list_a, list_b, status):
|
||||
already_handled = set()
|
||||
prefetch_from_a = []
|
||||
prefetch_from_b = []
|
||||
actions = []
|
||||
for uid in itertools.chain(list_a, list_b, status):
|
||||
if uid in already_handled:
|
||||
continue
|
||||
already_handled.add(uid)
|
||||
if uid not in status:
|
||||
if uid in list_a and uid in list_b: # missing status
|
||||
# TODO: might need some kind of diffing too?
|
||||
status[uid] = (list_a[uid], list_b[uid])
|
||||
elif uid in list_a and uid not in list_b: # new item was created in a
|
||||
prefetch_from_a.append(uid)
|
||||
actions.append(('upload', uid, 'a', 'b'))
|
||||
elif uid not in list_a and uid in list_b: # new item was created in b
|
||||
prefetch_from_b.append(uid)
|
||||
actions.append(('upload', uid, 'b', 'a'))
|
||||
else:
|
||||
if uid in list_a and uid in list_b:
|
||||
if list_a[uid] != status[uid][0] and list_b[uid] != status[uid][1]:
|
||||
1/0 # conflict resolution TODO
|
||||
elif list_a[uid] != status[uid][0]: # item was updated in a
|
||||
prefetch_from_a.append(uid)
|
||||
actions.append(('update', uid, 'a', 'b'))
|
||||
elif list_b[uid] != status[uid][1]: # item was updated in b
|
||||
prefetch_from_b.append(uid)
|
||||
actions.append(('update', uid, 'b', 'a'))
|
||||
else: # completely in sync!
|
||||
pass
|
||||
elif uid in list_a and uid not in list_b: # was deleted from b
|
||||
actions.append(('delete', uid, None, 'a'))
|
||||
elif uid not in list_a and uid in list_b: # was deleted from a
|
||||
actions.append(('delete', uid, None, 'b'))
|
||||
elif uid not in list_a and uid not in list_b: # was deleted from a and b
|
||||
actions.append(('delete', uid, None, None))
|
||||
del status[uid]
|
||||
return actions, prefetch_from_a, prefetch_from_b
|
||||
|
|
|
|||
Loading…
Reference in a new issue