Zionetrix::Git
Repositories
Help
Report an Issue
MyCoServer
Code
Commits
Branches
Tags
Search
Tree:
4e883c3
Branches
Tags
master
MyCoServer
mycoserver
group.py
Fix management of deletedContributors in sync process
Benjamin Renard
commited
4e883c3
at 2014-01-31 01:24:26
group.py
Blame
History
Raw
#!/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={} 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]) 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() 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, 'deletedContributors': deletedContributors, 'contributions': contributions, 'deletedContributions': deletedContributions } def restoreContributor(self, email): contributor=Contributor() contributor.load(self.deletedContributors[email].export()) for uuid in self.deletedContributions.keys(): 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].export()) contributor.deletionTime=time for uuid in self.contributions.keys(): 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 ## Deleted Contributors for email in self.deletedContributors.keys(): 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.keys(): 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 for email in self.contributors: if email not in ret.deletedContributors: ret.contributors[email]=self.contributors[email] for email in group.contributors: if email not in ret.contributors and email not in ret.deletedContributors: 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 self.deletionTime=None def load(self,data): self.name=data['name'] self.email=data['email'] if 'deletionTime' in data: self.deletionTime=data['deletionTime'] def export(self): ret={ 'name': self.name, 'email': self.email } 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)