- Notifications
You must be signed in to change notification settings - Fork 3
Expand file tree
/
Copy pathclient.py
More file actions
Latest commit
109 lines (100 loc) · 4.1 KB
/
Copy pathclient.py
File metadata and controls
109 lines (100 loc) · 4.1 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
importcopy
importtime
importstorage
classClient:
''' acts locally, when sync method is called it will sync with server.
dirty - locally modified flag
server_key - key on the server
deleted - object is locally deleted
'''
def__init__(self, local_storage):
self.storage=storage.Storage(local_storage)
defcreate(self, obj):
obj['dirty'] =True
obj['server_key'] =None
obj['deleted'] =False
obj['ts'] =0
key=self.storage.create(obj)
returnkey
defread(self, key):
returnself.storage.read(key=key)
defupdate(self, key, obj):
old_obj=self.read(key)
obj['dirty'] =True
obj['ts'] =old_obj['ts']
obj['deleted'] =old_obj['deleted']
obj['server_key'] =old_obj['server_key']
self.storage.update(key, obj)
defdelete(self, key):
obj=self.storage.read(key=key)
ifobj['server_key']: # originated from server
obj['dirty'] =True
obj['deleted'] =True
self.storage.update(key, obj)
else:
delself.storage.objects[obj['key']]
def_get_max_ts(self):
max_ts=0
forobjinself.storage.read_all():
ifobj['ts'] >max_ts: max_ts=obj['ts']
returnmax_ts
defsync(self, server):
# download part
max_ts=self._get_max_ts()
newer_objects=server.get(timestamp=max_ts)
forserver_objinnewer_objects:
local_obj=None
try:
local_obj=self.storage.read(server_key=server_obj['key'])
exceptKeyError:
pass
iflocal_obj: # we have same object locally.
server_obj['dirty'] =False
server_obj['server_key'] =server_obj['key']
if'deleted'inserver_objandserver_obj['deleted']:
obj=self.storage.read(server_key=server_obj['key'])
delself.storage.objects[obj['key']]
elif'dirty'inlocal_objandlocal_obj['dirty']:
ifserver_obj['ts'] >local_obj['ts']: # conflict resolution. based on timestamp
self.storage.update(server_obj['key'], server_obj)
else:
self.storage.update(local_obj['key'], server_obj)
else: # we do not have the object.
ifnotserver_obj['deleted']:
temp_obj=server_obj
temp_obj['server_key'] =server_obj['key']
temp_obj['dirty'] =False
self.storage.create(temp_obj)
# upload part, send dirty objects to server. assume client cannot delete.
objects_to_send= [ ]
objects_to_update= [ ]
objects_to_delete= [ ]
forlocal_objinself.storage.read_all():
iflocal_obj['dirty']:
iflocal_obj['server_key']: # object is originated from server
iflocal_obj['deleted']:
objects_to_delete.append(local_obj)
else:
objects_to_update.append(local_obj)
else:
ifnotlocal_obj['deleted']:
objects_to_send.append(local_obj)
forobjinobjects_to_send:
temp_obj=copy.deepcopy(obj)
delobj['dirty']
delobj['server_key']
server_obj=server.post(obj)
server_obj['dirty'] =False
server_obj['server_key'] =server_obj['key']
self.storage.update(temp_obj['key'], server_obj)
forobjinobjects_to_update:
temp_obj=copy.deepcopy(obj)
delobj['dirty']
delobj['server_key']
server_obj=server.put(temp_obj['server_key'], obj)
server_obj['dirty'] =False
server_obj['server_key'] =temp_obj['server_key']
self.storage.update(temp_obj['key'], server_obj)
forobjinobjects_to_delete:
server.delete(obj['server_key'])
delself.storage.objects[obj['key']]