rebuild changelog and redownload from peers.

This commit is contained in:
j 2016-01-23 22:19:34 +05:30
commit ff5917ade0
9 changed files with 129 additions and 58 deletions

View file

@ -77,10 +77,48 @@ class Changelog(db.Model):
logger.debug('record change: %s', c.json())
@classmethod
def apply_changes(cls, user, changes):
def apply_changes(cls, user, changes, first=False):
trigger = changes
if trigger:
trigger_event('change', {});
trigger_event('change', {})
if first:
logger.debug('remove left over items')
items = set()
lists = {}
peers = set()
for change in changes:
if change[2][0] == 'additem':
items.add(change[2][1])
if change[2][0] == 'addlist':
lists[change[2][1]] = set()
if change[2][0] == 'addlistitems':
if not change[2][1] in lists:
lists[change[2][1]] = set()
for i in change[2][2]:
lists[change[2][1]].add(i)
if change[2][0] == 'addpeer':
peers.add(change[2][1])
for i in user.library.items:
if i.id not in items and user in i.users:
i.users.remove(user)
if i.users:
i.update()
else:
i.delete()
for name in lists:
qs = user.lists.filter_by(name=name)
if qs.count():
l = qs[0]
remove = []
for i in l.get_items():
if i.id not in lists[name]:
remove.append(i.id)
l.items.remove(i.id)
for peer in user.models.Users.query:
if user.id in peer.info.get('users', {}) and peer.id not in peers:
del peer.info['users'][user.id]
peer.save()
for change in changes:
if user.id in state.removepeer:
del state.removepeer[user.id]
@ -105,10 +143,9 @@ class Changelog(db.Model):
c.timestamp = timestamp
c.user_id = user.id
c.revision = revision
c.data = data
args = json.loads(data)
logger.debug('apply change from %s: %s(%s)', user.name, args[0], args[1:])
if getattr(c, 'action_' + args[0])(user, timestamp, *args[1:]):
c.data = json.dumps(data)
logger.debug('apply change from %s: %s(%s)', user.name, data[0], data[1:])
if getattr(c, 'action_' + data[0])(user, timestamp, *data[1:]):
logger.debug('change applied')
state.db.session.add(c)
state.db.session.commit()
@ -126,26 +163,8 @@ class Changelog(db.Model):
def json(self):
timestamp = self.timestamp or datetime2ts(self.created)
return [self.revision, timestamp, self.data]
return [self.revision, timestamp, json.loads(self.data)]
@classmethod
def restore(cls, user_id, path=None):
from user.models import User
user = User.get_or_create(user_id)
if not path:
path = '/tmp/oml_changelog_%s.json' % user_id
with open(path, 'r') as fd:
for change in fd:
change = json.loads(change)
cls.apply_change(user, change, user_id == settings.USER_ID)
@classmethod
def export(cls, user_id, path=None):
if not path:
path = '/tmp/oml_changelog_%s.json' % user_id
with open(path, 'w') as fd:
for c in cls.query.filter_by(user_id=user_id).order_by('revision'):
fd.write(json.dumps(c.json(), ensure_ascii=False) + '\n')
def action_additem(self, user, timestamp, itemid, info):
from item.models import Item
@ -435,17 +454,17 @@ class Changelog(db.Model):
rv = data[0]
ts = data[1]
data = [op, id] + data[2:]
_changes.append([rv, ts, json.dumps(data)])
_changes.append([rv, ts, data])
_changes.sort(key=lambda change: (change[0], change[1]))
if orderlists:
ids = [l.name for l in List.query.filter_by(user_id=user_id,type='static').order_by('index_') if l.name]
if len(ids) > 1:
_changes.append([-1, timestamp, json.dumps(['orderlists', ids])])
_changes.append([-1, timestamp, ['orderlists', ids]])
userinfo = state.user().json()
if editusername:
_changes.append([-1, timestamp, json.dumps(['editusername', userinfo['username']])])
_changes.append([-1, timestamp, ['editusername', userinfo['username']]])
if editcontact:
_changes.append([-1, timestamp, json.dumps(['editcontact', userinfo['contact']])])
_changes.append([-1, timestamp, ['editcontact', userinfo['contact']]])
if _changes:
r = revision
for c in reversed(_changes):