Benjamin Renard commited on 2014-01-28 01:07:19
Showing 3 changed files, with 236 additions and 18 deletions.
... | ... |
@@ -5,6 +5,7 @@ import json |
5 | 5 |
import logging |
6 | 6 |
log = logging.getLogger(__name__) |
7 | 7 |
import MySQLdb |
8 |
+from mycoserver import group |
|
8 | 9 |
|
9 | 10 |
class DB(object): |
10 | 11 |
|
... | ... |
@@ -72,26 +73,17 @@ class DB(object): |
72 | 73 |
|
73 | 74 |
def sync_group(self,email,groups): |
74 | 75 |
db_groups=self.get_group(email) |
75 |
- json_group=json.dumps(groups) |
|
76 | 76 |
if db_groups!=False: |
77 |
- log.debug('Database groups : %s' % db_groups) |
|
78 |
- log.debug('Provided groups : %s' % groups) |
|
79 |
- if 'groups' not in db_groups or db_groups['groups']=={}: |
|
80 |
- log.debug('Database group is empty') |
|
81 |
- if 'groups' not in groups or groups['groups']=={}: |
|
82 |
- log.debug('Database and provided group are empty. Return empty') |
|
83 |
- return {'groups': {'groups': {}}} |
|
77 |
+ db_grouplist=group.GroupList() |
|
78 |
+ db_grouplist.load(db_groups) |
|
79 |
+ grouplist=group.GroupList() |
|
80 |
+ grouplist.load(groups) |
|
81 |
+ synced_grouplist=db_grouplist.sync(grouplist) |
|
82 |
+ if self.set_group(email,synced_grouplist.export()): |
|
83 |
+ log.debug('Groups successfuly synchronized, return result') |
|
84 |
+ return {'groups': synced_grouplist.export()} |
|
84 | 85 |
else: |
85 |
- log.debug('Insert provided groups in database and return it') |
|
86 |
- if self.do_sql("INSERT INTO groups (email,groups) VALUES ('%s','%s')" % (email,json_group)): |
|
87 |
- return {'groups': groups} |
|
88 |
- elif 'groups' not in groups or groups['groups']=={}: |
|
89 |
- log.debug('Provide group is empty. Return database groups') |
|
90 |
- return {'groups': db_groups} |
|
91 |
- else: |
|
92 |
- log.debug('Update database with provided group and return it') |
|
93 |
- if self.do_sql("UPDATE groups SET groups='%s' WHERE email='%s'" % (json_group,email)): |
|
94 |
- return {'groups': groups} |
|
86 |
+ return {'syncerror': 'Erreur en modifiant les informations de la base de donnees'} |
|
95 | 87 |
return {'syncerror': 'Erreur inconnu'} |
96 | 88 |
|
97 | 89 |
def get_group(self,email): |
... | ... |
@@ -103,3 +95,14 @@ class DB(object): |
103 | 95 |
return {'groups': {}} |
104 | 96 |
else: |
105 | 97 |
return False |
98 |
+ |
|
99 |
+ def set_group(self,email,groups): |
|
100 |
+ ret=self.select("SELECT groups FROM groups WHERE email='%s'" % email) |
|
101 |
+ if ret!=False: |
|
102 |
+ json_groups=json.dumps(groups) |
|
103 |
+ if len(ret)==1: |
|
104 |
+ return self.do_sql("UPDATE groups SET groups='%s' WHERE email='%s'" % (json_groups,email)) |
|
105 |
+ else: |
|
106 |
+ return self.do_sql("INSERT INTO groups (email,groups) VALUES ('%s','%s')" % (email,json_groups)) |
|
107 |
+ else: |
|
108 |
+ return False |
... | ... |
@@ -0,0 +1,210 @@ |
1 |
+#!/usr/bin/python |
|
2 |
+# -*- coding: utf-8 -*- |
|
3 |
+ |
|
4 |
+import logging |
|
5 |
+import urllib |
|
6 |
+log = logging.getLogger(__name__) |
|
7 |
+ |
|
8 |
+class GroupList(object): |
|
9 |
+ |
|
10 |
+ def __init__(self): |
|
11 |
+ self.groups={} |
|
12 |
+ self.lastChange=False |
|
13 |
+ |
|
14 |
+ def load(self,data): |
|
15 |
+ if 'lastChange' in data: |
|
16 |
+ self.lastChange=data['lastChange'] |
|
17 |
+ if 'groups' in data: |
|
18 |
+ for g in data['groups']: |
|
19 |
+ self.groups[g]=Group() |
|
20 |
+ self.groups[g].load(data['groups'][g]) |
|
21 |
+ |
|
22 |
+ def export(self): |
|
23 |
+ groups={} |
|
24 |
+ for uuid in self.groups: |
|
25 |
+ groups[uuid]=self.groups[uuid].export() |
|
26 |
+ |
|
27 |
+ return { |
|
28 |
+ 'lastChange': self.lastChange, |
|
29 |
+ 'groups': groups |
|
30 |
+ } |
|
31 |
+ |
|
32 |
+ def toJSON(self,pretty=False): |
|
33 |
+ if pretty: |
|
34 |
+ return json.dumps(self.export(),indent=4, separators=(',', ': ')) |
|
35 |
+ else: |
|
36 |
+ return json.dumps(self.export()) |
|
37 |
+ |
|
38 |
+ def sync(self,groups): |
|
39 |
+ ret=GroupList() |
|
40 |
+ if groups.lastChange<self.lastChange: |
|
41 |
+ ret.lastChange=self.lastChange |
|
42 |
+ else: |
|
43 |
+ ret.lastChange=groups.lastChange |
|
44 |
+ for uuid in groups.groups: |
|
45 |
+ if uuid in self.groups: |
|
46 |
+ ret.groups[uuid]=self.groups[uuid].sync(groups.groups[uuid]) |
|
47 |
+ else: |
|
48 |
+ ret.groups[uuid]=groups.groups[uuid] |
|
49 |
+ return ret |
|
50 |
+ |
|
51 |
+ |
|
52 |
+class Group(object): |
|
53 |
+ |
|
54 |
+ def __init__(self): |
|
55 |
+ self.uuid=None |
|
56 |
+ self.name=None |
|
57 |
+ self.contributors={} |
|
58 |
+ self.contributions={} |
|
59 |
+ self.deletedContributions={} |
|
60 |
+ |
|
61 |
+ def load(self,data): |
|
62 |
+ try: |
|
63 |
+ self.uuid=data['uuid'] |
|
64 |
+ self.name=data['name'] |
|
65 |
+ for email in data['contributors']: |
|
66 |
+ self.contributors[email]=Contributor() |
|
67 |
+ self.contributors[email].load(data['contributors'][email]) |
|
68 |
+ for uuid in data['contributions']: |
|
69 |
+ self.contributions[uuid]=Contribution() |
|
70 |
+ self.contributions[uuid].load(data['contributions'][uuid]) |
|
71 |
+ if 'deletedContributions' in data: |
|
72 |
+ for uuid in data['deletedContributions']: |
|
73 |
+ self.deletedContributions[uuid]=Contribution() |
|
74 |
+ self.deletedContributions[uuid].load(data['deletedContributions'][uuid]) |
|
75 |
+ return True |
|
76 |
+ except Exception,e: |
|
77 |
+ logging.error('Error loading JSON data : %s',e) |
|
78 |
+ return False |
|
79 |
+ |
|
80 |
+ def export(self): |
|
81 |
+ contributors={} |
|
82 |
+ for email in self.contributors: |
|
83 |
+ contributors[email]=self.contributors[email].export() |
|
84 |
+ |
|
85 |
+ contributions={} |
|
86 |
+ for uuid in self.contributions: |
|
87 |
+ contributions[uuid]=self.contributions[uuid].export() |
|
88 |
+ |
|
89 |
+ deletedContributions={} |
|
90 |
+ for uuid in self.deletedContributions: |
|
91 |
+ deletedContributions[uuid]=self.deletedContributions[uuid].export() |
|
92 |
+ |
|
93 |
+ return { |
|
94 |
+ 'uuid': self.uuid, |
|
95 |
+ 'name': self.name, |
|
96 |
+ 'contributors': contributors, |
|
97 |
+ 'contributions': contributions, |
|
98 |
+ 'deletedContributions': deletedContributions |
|
99 |
+ } |
|
100 |
+ |
|
101 |
+ def sync(self, group): |
|
102 |
+ ret=Group() |
|
103 |
+ ret.uuid=self.uuid |
|
104 |
+ |
|
105 |
+ # FIXME : Add lastChange on group to permit name choice between to object |
|
106 |
+ ret.name=group.name |
|
107 |
+ |
|
108 |
+ ## Contributors |
|
109 |
+ ret.contributors=self.contributors |
|
110 |
+ for email in group.contributors: |
|
111 |
+ if email not in ret.contributors: |
|
112 |
+ ret.contributors[email]=group.contributors[email] |
|
113 |
+ |
|
114 |
+ ## Deleted Contributions |
|
115 |
+ for uuid in self.deletedContributions: |
|
116 |
+ if uuid in group.deletedContributions: |
|
117 |
+ ret.deletedContributions[uuid]=self.deletedContributions[uuid].sync(group.deletedContributions[uuid]) |
|
118 |
+ else: |
|
119 |
+ ret.deletedContributions[uuid]=self.deletedContributions[uuid] |
|
120 |
+ for uuid in group.deletedContributions: |
|
121 |
+ if uuid not in ret.deletedContributions: |
|
122 |
+ ret.deletedContributions[uuid]=group.deletedContributions[uuid] |
|
123 |
+ |
|
124 |
+ ## Contributions |
|
125 |
+ for uuid in self.contributions: |
|
126 |
+ if uuid in group.contributions: |
|
127 |
+ ret.contributions[uuid]=self.contributions[uuid].sync(group.contributions[uuid]) |
|
128 |
+ elif uuid not in ret.deletedContributions: |
|
129 |
+ ret.contributions[uuid]=self.contributions[uuid] |
|
130 |
+ elif self.contributions[uuid].lastChange>ret.deletedContributions[uuid].lastChange: |
|
131 |
+ ret.contributions[uuid]=self.contributions[uuid] |
|
132 |
+ for uuid in group.contributions: |
|
133 |
+ if uuid not in ret.contributions: |
|
134 |
+ if uuid not in ret.deletedContributions: |
|
135 |
+ ret.contributions[uuid]=group.contributions[uuid] |
|
136 |
+ elif group.contributions[uuid].lastChange>ret.deletedContributions[uuid].lastChange: |
|
137 |
+ ret.contributions[uuid]=group.contributions[uuid] |
|
138 |
+ |
|
139 |
+ return ret |
|
140 |
+ |
|
141 |
+ |
|
142 |
+class Contribution(object): |
|
143 |
+ |
|
144 |
+ def __init__(self): |
|
145 |
+ self.uuid=None |
|
146 |
+ self.contributor=None |
|
147 |
+ self.title=None |
|
148 |
+ self.cost=None |
|
149 |
+ self.date=None |
|
150 |
+ self.lastChange=None |
|
151 |
+ |
|
152 |
+ def load(self,data): |
|
153 |
+ self.uuid=data['uuid'] |
|
154 |
+ self.contributor=data['contributor'] |
|
155 |
+ self.title=data['title'] |
|
156 |
+ self.cost=data['cost'] |
|
157 |
+ self.date=data['date'] |
|
158 |
+ self.lastChange=data['lastChange'] |
|
159 |
+ |
|
160 |
+ def export(self): |
|
161 |
+ return { |
|
162 |
+ 'uuid': self.uuid, |
|
163 |
+ 'contributor': self.contributor, |
|
164 |
+ 'cost': self.cost, |
|
165 |
+ 'title': self.title, |
|
166 |
+ 'date': self.date, |
|
167 |
+ 'lastChange': self.lastChange |
|
168 |
+ } |
|
169 |
+ |
|
170 |
+ def sync(self, c): |
|
171 |
+ if c.lastChange>self.lastChange: |
|
172 |
+ return c |
|
173 |
+ else: |
|
174 |
+ return self |
|
175 |
+ |
|
176 |
+class Contributor(object): |
|
177 |
+ |
|
178 |
+ def __init__(self): |
|
179 |
+ self.name=None |
|
180 |
+ self.email=None |
|
181 |
+ |
|
182 |
+ def load(self,data): |
|
183 |
+ self.name=data['name'] |
|
184 |
+ self.email=data['email'] |
|
185 |
+ |
|
186 |
+ def export(self): |
|
187 |
+ return { |
|
188 |
+ 'name': self.name, |
|
189 |
+ 'email': self.email |
|
190 |
+ } |
|
191 |
+ |
|
192 |
+ |
|
193 |
+if __name__ == '__main__': |
|
194 |
+ import testdata |
|
195 |
+ import json |
|
196 |
+ |
|
197 |
+ data=json.loads(testdata.group_as_json) |
|
198 |
+ data2=json.loads(testdata.group_as_json2) |
|
199 |
+ |
|
200 |
+ gl=GroupList() |
|
201 |
+ gl.load(data2) |
|
202 |
+ |
|
203 |
+ print gl.toJSON(True) |
|
204 |
+ |
|
205 |
+ print 'Try sync groups' |
|
206 |
+ gl2=GroupList() |
|
207 |
+ gl2.load(data) |
|
208 |
+ gl_sync=gl.sync(gl2) |
|
209 |
+ print 'Sync group : %s' % gl_sync |
|
210 |
+ print gl_sync.toJSON(True) |
... | ... |
@@ -0,0 +1,5 @@ |
1 |
+#!/usr/bin/python |
|
2 |
+ |
|
3 |
+group_as_json="""{"groups":{"7547b547-a3df-40f6-a728-e990ef35c67d":{"uuid":"7547b547-a3df-40f6-a728-e990ef35c67d","name":"test","contributors":{"ben@ben.com":{"name":"Benjamin","email":"ben@ben.com"},"ludo@myco.com":{"name":"Ludovic","email":"ludo@myco.com"}},"contributions":{"4467c88a-f99d-416f-9055-6241441579ed":{"contributor":"ben@ben.com","uuid":"4467c88a-f99d-416f-9055-6241441579ed","cost":14,"title":"test2","date":1390867172110,"lastChange":1390867172117},"78171e1b-8bcf-4614-ac9b-363fd23e3745":{"contributor":"ben@ben.com","uuid":"78171e1b-8bcf-4614-ac9b-363fd23e3745","cost":13,"title":"test","date":1390086000000,"lastChange":1390137335475}},"deletedContributions":{"a370e8a9-ec54-44e8-b6df-22d60d8e6214":{"contributor":"ben@ben.com","cost":12,"date":1390863713090,"lastChange":1390863716422,"title":"test2","uuid":"a370e8a9-ec54-44e8-b6df-22d60d8e6214"}}}}}""" |
|
4 |
+ |
|
5 |
+group_as_json2="""{"groups":{"7547b547-a3df-40f6-a728-e990ef35c67d":{"uuid":"7547b547-a3df-40f6-a728-e990ef35c67d","name":"test","contributors":{"ben@ben.com":{"name":"Benjamin","email":"ben@ben.com"},"ludo@myco.com":{"name":"Ludovic","email":"ludo@myco.com"}},"contributions":{"78171e1b-8bcf-4614-ac9b-363fd23e3745":{"contributor":"ben@ben.com","uuid":"78171e1b-8bcf-4614-ac9b-363fd23e3745","cost":13,"title":"test","date":1390086000000,"lastChange":1390137335475}},"deletedContributions":{}}}}""" |
|
0 | 6 |