mirror of
https://github.com/samsonjs/vdirsyncer.git
synced 2026-04-27 14:57:41 +00:00
Some code cleanup for sync
This commit is contained in:
parent
bc954cf3a5
commit
f758e6d6d8
1 changed files with 33 additions and 28 deletions
|
|
@ -15,6 +15,8 @@
|
||||||
:copyright: (c) 2014 Markus Unterwaditzer
|
:copyright: (c) 2014 Markus Unterwaditzer
|
||||||
:license: MIT, see LICENSE for more details.
|
:license: MIT, see LICENSE for more details.
|
||||||
'''
|
'''
|
||||||
|
import itertools
|
||||||
|
|
||||||
import vdirsyncer.exceptions as exceptions
|
import vdirsyncer.exceptions as exceptions
|
||||||
import vdirsyncer.log
|
import vdirsyncer.log
|
||||||
sync_logger = vdirsyncer.log.get('sync')
|
sync_logger = vdirsyncer.log.get('sync')
|
||||||
|
|
@ -74,18 +76,17 @@ def sync(storage_a, storage_b, status, conflict_resolution=None):
|
||||||
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())
|
||||||
del a_href_to_uid, b_href_to_uid
|
del a_href_to_uid, b_href_to_uid
|
||||||
|
|
||||||
|
storages = {
|
||||||
|
'a': (storage_a, list_a, a_uid_to_href),
|
||||||
|
'b': (storage_b, list_b, b_uid_to_href)
|
||||||
|
}
|
||||||
|
|
||||||
actions, prefetch_from_a, prefetch_from_b = \
|
actions, prefetch_from_a, prefetch_from_b = \
|
||||||
get_actions(list_a, list_b, status, a_uid_to_href, b_uid_to_href)
|
get_actions(storages, status)
|
||||||
|
|
||||||
prefetch(storage_a, list_a, prefetch_from_a)
|
prefetch(storage_a, list_a, prefetch_from_a)
|
||||||
prefetch(storage_b, list_b, prefetch_from_b)
|
prefetch(storage_b, list_b, prefetch_from_b)
|
||||||
|
|
||||||
storages = {
|
|
||||||
'a': (storage_a, list_a, a_uid_to_href),
|
|
||||||
'b': (storage_b, list_b, b_uid_to_href),
|
|
||||||
None: (None, None, None)
|
|
||||||
}
|
|
||||||
|
|
||||||
for action in actions:
|
for action in actions:
|
||||||
action(storages, status, conflict_resolution)
|
action(storages, status, conflict_resolution)
|
||||||
|
|
||||||
|
|
@ -133,7 +134,7 @@ def action_update(uid, source, dest):
|
||||||
return inner
|
return inner
|
||||||
|
|
||||||
|
|
||||||
def action_delete(uid, source, dest):
|
def action_delete(uid, dest):
|
||||||
def inner(storages, status, conflict_resolution):
|
def inner(storages, status, conflict_resolution):
|
||||||
if dest is not None:
|
if dest is not None:
|
||||||
dest_storage, dest_list, dest_uid_to_href = storages[dest]
|
dest_storage, dest_list, dest_uid_to_href = storages[dest]
|
||||||
|
|
@ -178,32 +179,38 @@ def action_conflict_resolve(uid):
|
||||||
return inner
|
return inner
|
||||||
|
|
||||||
|
|
||||||
def get_actions(list_a, list_b, status, a_uid_to_href, b_uid_to_href):
|
def get_actions(storages, status):
|
||||||
prefetch_from_a = []
|
prefetch_from_a = []
|
||||||
prefetch_from_b = []
|
prefetch_from_b = []
|
||||||
actions = []
|
actions = []
|
||||||
uids_a = set(x['uid'] for x in list_a.values())
|
|
||||||
uids_b = set(x['uid'] for x in list_b.values())
|
storage_a, list_a, a_uid_to_href = storages['a']
|
||||||
uids_status = set(status)
|
storage_b, list_b, b_uid_to_href = storages['b']
|
||||||
for uid in uids_a.union(uids_b).union(uids_status):
|
|
||||||
|
uids_a = (x['uid'] for x in list_a.itervalues())
|
||||||
|
uids_b = (x['uid'] for x in list_b.itervalues())
|
||||||
|
handled = set()
|
||||||
|
for uid in itertools.chain(uids_a, uids_b, status):
|
||||||
|
if uid in handled:
|
||||||
|
continue
|
||||||
|
handled.add(uid)
|
||||||
|
|
||||||
href_a = a_uid_to_href.get(uid, None)
|
href_a = a_uid_to_href.get(uid, None)
|
||||||
href_b = b_uid_to_href.get(uid, None)
|
href_b = b_uid_to_href.get(uid, None)
|
||||||
a = list_a.get(href_a, None)
|
a = list_a.get(href_a, None)
|
||||||
b = list_b.get(href_b, None)
|
b = list_b.get(href_b, None)
|
||||||
if uid not in status:
|
if uid not in status:
|
||||||
if uid in uids_a and uid in uids_b: # missing status
|
if a and b: # missing status
|
||||||
actions.append(action_conflict_resolve(uid))
|
actions.append(action_conflict_resolve(uid))
|
||||||
# new item was created in a
|
elif a and not b: # new item was created in a
|
||||||
elif uid in uids_a and uid not in uids_b:
|
|
||||||
prefetch_from_a.append(href_a)
|
prefetch_from_a.append(href_a)
|
||||||
actions.append(action_upload(uid, 'a', 'b'))
|
actions.append(action_upload(uid, 'a', 'b'))
|
||||||
# new item was created in b
|
elif not a and b: # new item was created in b
|
||||||
elif uid not in uids_a and uid in uids_b:
|
|
||||||
prefetch_from_b.append(href_b)
|
prefetch_from_b.append(href_b)
|
||||||
actions.append(action_upload(uid, 'b', 'a'))
|
actions.append(action_upload(uid, 'b', 'a'))
|
||||||
else:
|
else:
|
||||||
_, status_etag_a, _, status_etag_b = status[uid]
|
_, status_etag_a, _, status_etag_b = status[uid]
|
||||||
if uid in uids_a and uid in uids_b:
|
if a and b:
|
||||||
if a['etag'] != status_etag_a and b['etag'] != status_etag_b:
|
if a['etag'] != status_etag_a and b['etag'] != status_etag_b:
|
||||||
prefetch_from_a.append(href_a)
|
prefetch_from_a.append(href_a)
|
||||||
prefetch_from_b.append(href_b)
|
prefetch_from_b.append(href_b)
|
||||||
|
|
@ -214,13 +221,11 @@ def get_actions(list_a, list_b, status, a_uid_to_href, b_uid_to_href):
|
||||||
elif b['etag'] != status_etag_b: # item was updated in b
|
elif b['etag'] != status_etag_b: # item was updated in b
|
||||||
prefetch_from_b.append(href_b)
|
prefetch_from_b.append(href_b)
|
||||||
actions.append(action_update(uid, 'b', 'a'))
|
actions.append(action_update(uid, 'b', 'a'))
|
||||||
else: # completely in sync!
|
elif a and not b: # was deleted from b
|
||||||
pass
|
actions.append(action_delete(uid, 'a'))
|
||||||
elif uid in uids_a and uid not in uids_b: # was deleted from b
|
elif not a and b: # was deleted from a
|
||||||
actions.append(action_delete(uid, None, 'a'))
|
actions.append(action_delete(uid, 'b'))
|
||||||
elif uid not in uids_a and uid in uids_b: # was deleted from a
|
elif not a and not b: # was deleted from a and b
|
||||||
actions.append(action_delete(uid, None, 'b'))
|
actions.append(action_delete(uid, None))
|
||||||
# was deleted from a and b
|
|
||||||
elif uid not in uids_a and uid not in uids_b:
|
|
||||||
actions.append(action_delete(uid, None, None))
|
|
||||||
return actions, prefetch_from_a, prefetch_from_b
|
return actions, prefetch_from_a, prefetch_from_b
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue