Implementation of groups objects and use it to synchronize groups with an advanced method

This commit is contained in:
Benjamin Renard 2014-01-28 02:07:19 +01:00
parent e8a355c06e
commit 32f0f2a03d
3 changed files with 236 additions and 18 deletions

View file

@ -5,6 +5,7 @@ import json
import logging import logging
log = logging.getLogger(__name__) log = logging.getLogger(__name__)
import MySQLdb import MySQLdb
from mycoserver import group
class DB(object): class DB(object):
@ -72,26 +73,17 @@ class DB(object):
def sync_group(self,email,groups): def sync_group(self,email,groups):
db_groups=self.get_group(email) db_groups=self.get_group(email)
json_group=json.dumps(groups)
if db_groups!=False: if db_groups!=False:
log.debug('Database groups : %s' % db_groups) db_grouplist=group.GroupList()
log.debug('Provided groups : %s' % groups) db_grouplist.load(db_groups)
if 'groups' not in db_groups or db_groups['groups']=={}: grouplist=group.GroupList()
log.debug('Database group is empty') grouplist.load(groups)
if 'groups' not in groups or groups['groups']=={}: synced_grouplist=db_grouplist.sync(grouplist)
log.debug('Database and provided group are empty. Return empty') if self.set_group(email,synced_grouplist.export()):
return {'groups': {'groups': {}}} log.debug('Groups successfuly synchronized, return result')
else: return {'groups': synced_grouplist.export()}
log.debug('Insert provided groups in database and return it')
if self.do_sql("INSERT INTO groups (email,groups) VALUES ('%s','%s')" % (email,json_group)):
return {'groups': groups}
elif 'groups' not in groups or groups['groups']=={}:
log.debug('Provide group is empty. Return database groups')
return {'groups': db_groups}
else: else:
log.debug('Update database with provided group and return it') return {'syncerror': 'Erreur en modifiant les informations de la base de donnees'}
if self.do_sql("UPDATE groups SET groups='%s' WHERE email='%s'" % (json_group,email)):
return {'groups': groups}
return {'syncerror': 'Erreur inconnu'} return {'syncerror': 'Erreur inconnu'}
def get_group(self,email): def get_group(self,email):
@ -103,3 +95,14 @@ class DB(object):
return {'groups': {}} return {'groups': {}}
else: else:
return False return False
def set_group(self,email,groups):
ret=self.select("SELECT groups FROM groups WHERE email='%s'" % email)
if ret!=False:
json_groups=json.dumps(groups)
if len(ret)==1:
return self.do_sql("UPDATE groups SET groups='%s' WHERE email='%s'" % (json_groups,email))
else:
return self.do_sql("INSERT INTO groups (email,groups) VALUES ('%s','%s')" % (email,json_groups))
else:
return False

210
mycoserver/group.py Normal file
View file

@ -0,0 +1,210 @@
#!/usr/bin/python
# -*- coding: utf-8 -*-
import logging
import urllib
log = logging.getLogger(__name__)
class GroupList(object):
def __init__(self):
self.groups={}
self.lastChange=False
def load(self,data):
if 'lastChange' in data:
self.lastChange=data['lastChange']
if 'groups' in data:
for g in data['groups']:
self.groups[g]=Group()
self.groups[g].load(data['groups'][g])
def export(self):
groups={}
for uuid in self.groups:
groups[uuid]=self.groups[uuid].export()
return {
'lastChange': self.lastChange,
'groups': groups
}
def toJSON(self,pretty=False):
if pretty:
return json.dumps(self.export(),indent=4, separators=(',', ': '))
else:
return json.dumps(self.export())
def sync(self,groups):
ret=GroupList()
if groups.lastChange<self.lastChange:
ret.lastChange=self.lastChange
else:
ret.lastChange=groups.lastChange
for uuid in groups.groups:
if uuid in self.groups:
ret.groups[uuid]=self.groups[uuid].sync(groups.groups[uuid])
else:
ret.groups[uuid]=groups.groups[uuid]
return ret
class Group(object):
def __init__(self):
self.uuid=None
self.name=None
self.contributors={}
self.contributions={}
self.deletedContributions={}
def load(self,data):
try:
self.uuid=data['uuid']
self.name=data['name']
for email in data['contributors']:
self.contributors[email]=Contributor()
self.contributors[email].load(data['contributors'][email])
for uuid in data['contributions']:
self.contributions[uuid]=Contribution()
self.contributions[uuid].load(data['contributions'][uuid])
if 'deletedContributions' in data:
for uuid in data['deletedContributions']:
self.deletedContributions[uuid]=Contribution()
self.deletedContributions[uuid].load(data['deletedContributions'][uuid])
return True
except Exception,e:
logging.error('Error loading JSON data : %s',e)
return False
def export(self):
contributors={}
for email in self.contributors:
contributors[email]=self.contributors[email].export()
contributions={}
for uuid in self.contributions:
contributions[uuid]=self.contributions[uuid].export()
deletedContributions={}
for uuid in self.deletedContributions:
deletedContributions[uuid]=self.deletedContributions[uuid].export()
return {
'uuid': self.uuid,
'name': self.name,
'contributors': contributors,
'contributions': contributions,
'deletedContributions': deletedContributions
}
def sync(self, group):
ret=Group()
ret.uuid=self.uuid
# FIXME : Add lastChange on group to permit name choice between to object
ret.name=group.name
## Contributors
ret.contributors=self.contributors
for email in group.contributors:
if email not in ret.contributors:
ret.contributors[email]=group.contributors[email]
## Deleted Contributions
for uuid in self.deletedContributions:
if uuid in group.deletedContributions:
ret.deletedContributions[uuid]=self.deletedContributions[uuid].sync(group.deletedContributions[uuid])
else:
ret.deletedContributions[uuid]=self.deletedContributions[uuid]
for uuid in group.deletedContributions:
if uuid not in ret.deletedContributions:
ret.deletedContributions[uuid]=group.deletedContributions[uuid]
## Contributions
for uuid in self.contributions:
if uuid in group.contributions:
ret.contributions[uuid]=self.contributions[uuid].sync(group.contributions[uuid])
elif uuid not in ret.deletedContributions:
ret.contributions[uuid]=self.contributions[uuid]
elif self.contributions[uuid].lastChange>ret.deletedContributions[uuid].lastChange:
ret.contributions[uuid]=self.contributions[uuid]
for uuid in group.contributions:
if uuid not in ret.contributions:
if uuid not in ret.deletedContributions:
ret.contributions[uuid]=group.contributions[uuid]
elif group.contributions[uuid].lastChange>ret.deletedContributions[uuid].lastChange:
ret.contributions[uuid]=group.contributions[uuid]
return ret
class Contribution(object):
def __init__(self):
self.uuid=None
self.contributor=None
self.title=None
self.cost=None
self.date=None
self.lastChange=None
def load(self,data):
self.uuid=data['uuid']
self.contributor=data['contributor']
self.title=data['title']
self.cost=data['cost']
self.date=data['date']
self.lastChange=data['lastChange']
def export(self):
return {
'uuid': self.uuid,
'contributor': self.contributor,
'cost': self.cost,
'title': self.title,
'date': self.date,
'lastChange': self.lastChange
}
def sync(self, c):
if c.lastChange>self.lastChange:
return c
else:
return self
class Contributor(object):
def __init__(self):
self.name=None
self.email=None
def load(self,data):
self.name=data['name']
self.email=data['email']
def export(self):
return {
'name': self.name,
'email': self.email
}
if __name__ == '__main__':
import testdata
import json
data=json.loads(testdata.group_as_json)
data2=json.loads(testdata.group_as_json2)
gl=GroupList()
gl.load(data2)
print gl.toJSON(True)
print 'Try sync groups'
gl2=GroupList()
gl2.load(data)
gl_sync=gl.sync(gl2)
print 'Sync group : %s' % gl_sync
print gl_sync.toJSON(True)

5
mycoserver/testdata.py Normal file
View file

@ -0,0 +1,5 @@
#!/usr/bin/python
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"}}}}}"""
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":{}}}}"""