MyCoServer/mycoserver/group.py

297 lines
9.9 KiB
Python
Raw Normal View History

#!/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]
for uuid in self.groups:
if uuid not in ret.groups:
ret.groups[uuid]=self.groups[uuid]
return ret
class Group(object):
def __init__(self):
self.uuid=None
self.name=None
self.contributors={}
2014-01-31 01:58:00 +01:00
self.deletedContributors={}
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])
2014-01-31 01:58:00 +01:00
if 'deletedContributors' in data:
for email in data['deletedContributors']:
self.deletedContributors[email]=Contributor()
self.deletedContributors[email].load(data['deletedContributors'][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()
2014-01-31 01:58:00 +01:00
deletedContributors={}
for email in self.deletedContributors:
deletedContributors[email]=self.deletedContributors[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,
2014-01-31 01:58:00 +01:00
'deletedContributors': deletedContributors,
'contributions': contributions,
'deletedContributions': deletedContributions
}
2014-01-31 01:58:00 +01:00
def restoreContributor(self, email):
contributor=Contributor()
contributor.load(self.deletedContributors[email])
for uuid in self.deletedContributions:
if self.deletedContributions[uuid].contributor==contributor.email and self.deletedContributions[uuid].lastChange==contributor.deletionTime:
self.contributions[uuid]=Contribution()
self.contributions[uuid].load(self.deletedContributions[uuid].export())
# Restored contribution must not be more up to date than other
self.contributions[uuid].lastChange=0
del self.deletedContributions[uuid]
contributor.deletionTime=None
self.contributors[email]=contributor
del self.deletedContributors[email]
def deleteContributor(self, email, time):
contributor=Contributor()
contributor.load(self.contributors[email])
contributor.deletionTime=time
for uuid in self.contributions:
if self.contributions[uuid].contributor==email:
self.deletedContributions[uuid]=Contribution()
self.deletedContributions[uuid].load(self.contributions[uuid].export())
self.deletedContributions[uuid].lastChange=time
del self.contributions[uuid]
self.deletedContributors[email]=contributor
del self.contributors[email]
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
2014-01-31 01:58:00 +01:00
## Deleted Contributors
for email in self.deletedContributors:
if email not in group.deletedContributors:
logging.debug('Contributor %s not deleted on the other' % email)
lastChange=0
for uuid in group.contributions:
if group.contributions[uuid].contributor==email and group.contributions[uuid].lastChange>lastChange:
lastChange=group.contributions[uuid].lastChange
if self.deletedContributors[email].deletionTime<lastChange:
logging.debug('Some modifications are more recent than my deletion, retoring contributors and his contributions')
# Restore contributor and his contributions
self.restoreContributor(email)
continue
elif email in group.contributors:
logging.debug('My deletion are more recent than other modification, deleting contributors and his contributions in the other group')
# Delete contributor and his contributions
group.deleteContributor(email,self.deletedContributors[email].deletionTime)
ret.deletedContributors[email]=self.deletedContributors[email]
for email in group.deletedContributors:
if email not in ret.deletedContributors:
logging.debug('Contributor %s not deleted on me' % email)
lastChange=0
for uuid in ret.contributions:
if ret.contributions[uuid].contributor==email and ret.contributions[uuid].lastChange>lastChange:
lastChange=ret.contributions[uuid].lastChange
if group.deletedContributors[email].deletionTime<lastChange:
logging.debug('Some of my modifications are more recent than the other deletion, retoring contributors and his contributions in the other group')
# Restore contributor and his contributions
group.restoreContributor(email)
continue
elif email in group.contributors:
# Delete contributor and his contributions
logging.debug('The other group deletion are more recent than my modifications, deleting my contributor and his contributions')
ret.deleteContributor(email,group.deletedContributors[email].deletionTime)
ret.deletedContributors[email]=group.deletedContributors[email]
## 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]
elif ret.deletedContributions[uuid].lastChange<group.deletedContributions[uuid].lastChange:
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]
del ret.deletedContributions[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]
del ret.deletedContributions[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
2014-01-31 01:58:00 +01:00
self.deletionTime=None
def load(self,data):
self.name=data['name']
self.email=data['email']
2014-01-31 01:58:00 +01:00
if 'deletionTime' in data:
self.deletionTime=data['deletionTime']
def export(self):
2014-01-31 01:58:00 +01:00
ret={
'name': self.name,
'email': self.email
}
2014-01-31 01:58:00 +01:00
if self.deletionTime is not None:
ret['deletionTime']=self.deletionTime
return ret
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)