def handle(changeset): print ('Received ' + str(changeset)) # Fetch project and pad ids. project_id = changeset['projectId'] pad_id = changeset['padId'] # Fetch project lock or create it, if not exists already. if project_id not in update_locks: update_locks[project_id] = Lock() update_lock = update_locks[project_id] with update_lock: # Fetch next revision number. if project_id not in revisions: revisions[project_id] = {} if pad_id not in revisions[project_id]: revisions[project_id][pad_id] = [Revision('0', None)] # Follow the changeset by all revisions not known by that user. revs = revisions[project_id][pad_id] apply_from = len(revs) for i in range(len(revs), 0, -1): if changeset['baseRev'] == revs[i - 1].id: apply_from = i break for i in range(apply_from, len(revs)): if changeset['baseLen'] == revs[i].changeset['newLen']: apply_from = i + 1 break # Fetch current revision. crtRev, baseRev = changeset['revId'], changeset['baseRev'] for i in range(apply_from, len(revs)): changeset = follow(revs[i].changeset, changeset) # Update base rev. changeset['baseRev'] = baseRev # Create new revision out of this changeset. revisions[project_id][pad_id].append(Revision(crtRev, changeset)) # Update current pad in db. changeset['projectId'], changeset['padId'] = project_id, pad_id changeset['revId'] = crtRev updateDBPad(changeset, crtRev) # Add the new comments to DB. if 'comments' in changeset: for code, comment in changeset['comments'].items(): newComment = Comment(comment['author'], comment['text']) newComment.pad_id = comment['padId'] newComment.code = comment['code'] db.session.add(newComment) db.session.commit() # Include the id of the client that generated the changeset. changeset['clientId'] = request.sid # Broadcast to all clients. emit('server_client_changeset', changeset, room=changeset['projectId']) # Send ACK to the client. emit('server_client_ack', changeset['padId'], room=request.sid)