mirror of
https://github.com/samsonjs/vdirsyncer.git
synced 2026-04-27 14:57:41 +00:00
More fixes
This commit is contained in:
parent
b878c1dba2
commit
9851282e47
2 changed files with 43 additions and 23 deletions
|
|
@ -55,15 +55,13 @@ def sync(storage_a, storage_b, status):
|
||||||
list_b = dict(prepare_list(storage_b, b_href_to_uid))
|
list_b = dict(prepare_list(storage_b, b_href_to_uid))
|
||||||
a_uid_to_href = dict((x['uid'], href) for href, x in list_a.iteritems())
|
a_uid_to_href = dict((x['uid'], href) for href, x in list_a.iteritems())
|
||||||
b_uid_to_href = dict((x['uid'], href) for href, x in list_b.iteritems())
|
b_uid_to_href = dict((x['uid'], href) for href, x in list_b.iteritems())
|
||||||
etags_a = dict((x['uid'], x['etag']) for href, x in list_a.iteritems())
|
|
||||||
etags_b = dict((x['uid'], x['etag']) for href, x in list_b.iteritems())
|
|
||||||
del a_href_to_uid, b_href_to_uid
|
del a_href_to_uid, b_href_to_uid
|
||||||
|
|
||||||
actions, prefetch_from_a, prefetch_from_b = \
|
actions, prefetch_from_a, prefetch_from_b = \
|
||||||
get_actions(etags_a, etags_b, status)
|
get_actions(list_a, list_b, status, a_uid_to_href, b_uid_to_href)
|
||||||
|
|
||||||
prefetch(storage_a, list_a, (a_uid_to_href[x] for x in prefetch_from_a))
|
prefetch(storage_a, list_a, prefetch_from_a)
|
||||||
prefetch(storage_b, list_b, (b_uid_to_href[x] for x in prefetch_from_b))
|
prefetch(storage_b, list_b, prefetch_from_b)
|
||||||
|
|
||||||
storages = {
|
storages = {
|
||||||
'a': (storage_a, list_a, a_uid_to_href),
|
'a': (storage_a, list_a, a_uid_to_href),
|
||||||
|
|
@ -96,38 +94,47 @@ def sync(storage_a, storage_b, status):
|
||||||
dest_storage.delete(dest_href, dest_etag)
|
dest_storage.delete(dest_href, dest_etag)
|
||||||
del status[uid]
|
del status[uid]
|
||||||
|
|
||||||
def get_actions(list_a, list_b, status):
|
def get_actions(list_a, list_b, status, a_uid_to_href, b_uid_to_href):
|
||||||
prefetch_from_a = []
|
prefetch_from_a = []
|
||||||
prefetch_from_b = []
|
prefetch_from_b = []
|
||||||
actions = []
|
actions = []
|
||||||
for uid in set(list_a).union(set(list_b)).union(set(status)):
|
uids_a = set(x['uid'] for x in list_a.values())
|
||||||
|
uids_b = set(x['uid'] for x in list_b.values())
|
||||||
|
uids_status = set(status)
|
||||||
|
for uid in uids_a.union(uids_b).union(uids_status):
|
||||||
|
href_a = a_uid_to_href.get(uid, None)
|
||||||
|
href_b = b_uid_to_href.get(uid, None)
|
||||||
|
a = list_a.get(href_a, None)
|
||||||
|
b = list_b.get(href_b, None)
|
||||||
if uid not in status:
|
if uid not in status:
|
||||||
if uid in list_a and uid in list_b: # missing status
|
if uid in uids_a and uid in uids_b: # missing status
|
||||||
# TODO: might need some kind of diffing too?
|
# TODO: might need some kind of diffing too?
|
||||||
status[uid] = (list_a[uid], list_b[uid])
|
if a['obj'].raw != b['obj'].raw:
|
||||||
elif uid in list_a and uid not in list_b: # new item was created in a
|
1/0
|
||||||
prefetch_from_a.append(uid)
|
status[uid] = (href_a, a['etag'], href_b, b['etag'])
|
||||||
|
elif uid in uids_a and uid not in uids_b: # new item was created in a
|
||||||
|
prefetch_from_a.append(href_a)
|
||||||
actions.append(('upload', uid, 'a', 'b'))
|
actions.append(('upload', uid, 'a', 'b'))
|
||||||
elif uid not in list_a and uid in list_b: # new item was created in b
|
elif uid not in uids_a and uid in uids_b: # new item was created in b
|
||||||
prefetch_from_b.append(uid)
|
prefetch_from_b.append(href_b)
|
||||||
actions.append(('upload', uid, 'b', 'a'))
|
actions.append(('upload', uid, 'b', 'a'))
|
||||||
else:
|
else:
|
||||||
href_a, etag_a, href_b, etag_b = status[uid]
|
_, status_etag_a, _, status_etag_b = status[uid]
|
||||||
if uid in list_a and uid in list_b:
|
if uid in uids_a and uid in uids_b:
|
||||||
if list_a[uid] != etag_a and list_b[uid] != etag_b:
|
if a['etag'] != status_etag_a and b['etag'] != status_etag_b:
|
||||||
1/0 # conflict resolution TODO
|
1/0 # conflict resolution TODO
|
||||||
elif list_a[uid] != etag_a: # item was updated in a
|
elif a['etag'] != status_etag_a: # item was updated in a
|
||||||
prefetch_from_a.append(uid)
|
prefetch_from_a.append(href_a)
|
||||||
actions.append(('update', uid, 'a', 'b'))
|
actions.append(('update', uid, 'a', 'b'))
|
||||||
elif list_b[uid] != etag_b: # item was updated in b
|
elif b['etag'] != status_etag_b: # item was updated in b
|
||||||
prefetch_from_b.append(uid)
|
prefetch_from_b.append(href_b)
|
||||||
actions.append(('update', uid, 'b', 'a'))
|
actions.append(('update', uid, 'b', 'a'))
|
||||||
else: # completely in sync!
|
else: # completely in sync!
|
||||||
pass
|
pass
|
||||||
elif uid in list_a and uid not in list_b: # was deleted from b
|
elif uid in uids_a and uid not in uids_b: # was deleted from b
|
||||||
actions.append(('delete', uid, None, 'a'))
|
actions.append(('delete', uid, None, 'a'))
|
||||||
elif uid not in list_a and uid in list_b: # was deleted from a
|
elif uid not in uids_a and uid in uids_b: # was deleted from a
|
||||||
actions.append(('delete', uid, None, 'b'))
|
actions.append(('delete', uid, None, 'b'))
|
||||||
elif uid not in list_a and uid not in list_b: # was deleted from a and b
|
elif uid not in uids_a and uid not in uids_b: # was deleted from a and b
|
||||||
actions.append(('delete', uid, None, None))
|
actions.append(('delete', uid, None, None))
|
||||||
return actions, prefetch_from_a, prefetch_from_b
|
return actions, prefetch_from_a, prefetch_from_b
|
||||||
|
|
|
||||||
|
|
@ -38,6 +38,19 @@ class SyncTests(TestCase):
|
||||||
assert a.has('1.txt')
|
assert a.has('1.txt')
|
||||||
assert b.has('1.asd')
|
assert b.has('1.asd')
|
||||||
|
|
||||||
|
def test_missing_status_and_different_items(self):
|
||||||
|
return # TODO
|
||||||
|
a = MemoryStorage(fileext='.txt')
|
||||||
|
b = MemoryStorage(fileext='.asd')
|
||||||
|
status = {}
|
||||||
|
item1 = Item('UID:1\nhaha')
|
||||||
|
item2 = Item('UID:1\nhoho')
|
||||||
|
a.upload(item1)
|
||||||
|
b.upload(item2)
|
||||||
|
sync(a, b, status)
|
||||||
|
assert status
|
||||||
|
assert a.get('1.txt')[0].raw == b.get('1.asd')[0].raw
|
||||||
|
|
||||||
def test_upload_and_update(self):
|
def test_upload_and_update(self):
|
||||||
a = MemoryStorage(fileext='.txt')
|
a = MemoryStorage(fileext='.txt')
|
||||||
b = MemoryStorage(fileext='.asd')
|
b = MemoryStorage(fileext='.asd')
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue