def delete(self, request): """ Deletes the Note in the model with the particular jid of the note passed in. Only the jid matters; all other fields are ignored. If a note with such a JID does not exist, return 404. Called with HTTP DELETE """ #ResourceForm = forms.form_for_model(Note, form=self.form_class) data = self.receiver.get_put_data(request) #form = ResourceForm(data) form = NoteForm(data) request_user = basicauth_get_user_by_emailaddr(request) if not request_user: logevent(request, 'Note.delete', 401, jv3.utils.decode_emailaddr(request)) return self.responder.error( request, 401, ErrorDict({"autherror": "Incorrect user/password combination"})) matching_notes = Note.objects.filter(jid=form.data['jid'], owner=request_user) if len(matching_notes) == 0: return self.responder.error( request, 404, ErrorDict( {"jid": "Note with jid %d not found" % form.data["jid"]})) for to_die in matching_notes: to_die.delete() return HttpResponse(_("Object successfully deleted."), self.responder.mimetype)
def put_zen(request): ## copied from notes_post_multi, altered for better edit posting ## Purpose: allow notes to be posted, if server has newer version, join texts and return new note ## ## mirrored from NoteCollections.create upstairs but updated to handle ## new batch sync protocol from listit 0.4.0 and newer. ## changes to protocol: ## call it with a list of notes { [ {id: 123981231, text:"i love you"..} ... ] ) ## returns a success with a list { committed: [{ success: <code>, jid: <id> }] ... } unless something really bad happened request_user = basicauth_get_user_by_emailaddr(request) if not request_user: logevent(request, 'ActivityLog.create POST', 401, jv3.utils.decode_emailaddr(request)) response = HttpResponse( JSONEncoder().encode( {'autherror': "Incorrect user/password combination"}), "text/json") response.status_code = 401 return response responses = [] updateResponses = [] if not request.raw_post_data: response = HttpResponse(JSONEncoder().encode({'committed': []}), "text/json") response.status_code = 200 return response for datum in JSONDecoder().decode(request.raw_post_data): form = NoteForm(datum) form.data['owner'] = request_user.id ## clobber this whole-sale from authenticating user matching_notes = Note.objects.filter(jid=int(form.data['jid']), owner=request_user) if len(matching_notes) == 0: ## Save new note if form.is_valid(): new_model = form.save() responses.append({"jid": form.data['jid'], "status": 201}) logevent(request, 'Note.create', 200, form.data['jid']) continue logevent(request, 'Note.create', 400, form.errors) responses.append({"jid": form.data['jid'], "status": 400}) continue else: ## UPDATE an existing note: check if the client version needs updating if (matching_notes[0].version > form.data['version']): if form.is_valid(): for key in Note.update_fields: ## key={contents,created,deleted,edited} if key == "contents": newContent = "Two versions of this note:\nSubmitted Copy:\n%s\n\nServer Copy:\n%s" % ( form.data[key], matching_notes[0].contents) ##print "Key: %s, Data: %s" % (key, newContent) matching_notes[0].__setattr__(key, newContent) else: ##print "Key: %s, Data: %s" % (key, form.data[key]) matching_notes[0].__setattr__(key, form.data[key]) newVersion = max(matching_notes[0].version, form.data['version']) + 1 ##print newVersion matching_notes[ 0].version = newVersion ## Saved note is MOST-up-to-date, ie:(max(both versions)+1) matching_notes[0].save() updateResponses.append({ "jid": form.data['jid'], "content": newContent, "version": newVersion, "status": 201 }) continue continue # If the data contains no errors, migrate the changes over to the version of the note in the db, # increment the version number and announce success if form.is_valid(): ##print "6a: update server note" for key in Note.update_fields: matching_notes[0].__setattr__(key, form.data[key]) newVersion = form.data['version'] + 1 matching_notes[0].version = newVersion matching_notes[0].save() responses.append({ "jid": form.data['jid'], "version": newVersion, "status": 201 }) else: responses.append({"jid": form.data['jid'], "status": 400}) logevent(request, 'Note.create', 400, form.errors) response = HttpResponse( JSONEncoder().encode({ 'committed': responses, 'update': updateResponses }), "text/json") response.status_code = 200 return response
def create(self, request): ## THIS CODE IS DEPRECATED // the SLOW method. IF YOU MAKE ANY CHANGES HERE ## MAKE SURE THE CHANGES ARE REFLECTED in note_update_batch below # MERGED create and update method for server, so that we don't have to do a PUT # forms.form_for_model(self.queryset.model, form=self.form_class) data = self.receiver.get_post_data(request) form = NoteForm(data) # get user being authenticated request_user = basicauth_get_user_by_emailaddr(request) if not request_user: logevent(request, 'Note.create POST', 401, jv3.utils.decode_emailaddr(request)) return self.responder.error( request, 401, ErrorDict({"autherror": "Incorrect user/password combination"})) form.data['owner'] = request_user.id ## clobber this whole-sale from authenticating user matching_notes = Note.objects.filter(jid=form.data['jid'], owner=request_user) if len(matching_notes) == 0: ## CREATE a new note # If the data contains no errors, save the model, if form.is_valid(): new_model = form.save() model_entry = self.entry_class(self, new_model) response = model_entry.read(request) response.status_code = 201 ## response['Location'] ## = model_entry.get_url() logevent(request, 'Note.create', 200, form.data['jid']) return response ## something didn't pass form validation logevent(request, 'Note.create', 400, form.errors) ##print "CREATE form errors %s " % repr(form.errors) return self.responder.error(request, 400, form.errors) else: ## UPDATE an existing note ## check if the client version needs updating if len(matching_notes) > 1: print "# of Matching Notes : %d " % len(matching_notes) if (matching_notes[0].version > form.data['version']): errormsg = "Versions for jid %d not compatible (local:%d, received: %d). Do you need to update? " % ( form.data["jid"], matching_notes[0].version, form.data["version"]) print "NOT UPDATED error -- server: %d, YOU %d " % ( matching_notes[0].version, form.data['version']) return self.responder.error(request, 400, ErrorDict({"jid": errormsg})) # If the data contains no errors, migrate the changes over to # the version of the note in the db, increment the version number # and announce success if form.is_valid(): for key in Note.update_fields: matching_notes[0].__setattr__(key, form.data[key]) # increment version number matching_notes[0].version = form.data[ 'version'] + 1 ## matching_notes[0].version + 1; # save! # print "SAVING %s, is it deleted? %s " % (repr(matching_notes[0]),repr(matching_notes[0].deleted)) matching_notes[0].save() response = self.read(request) response.status_code = 200 ## this BREAKS with 1.0 ## response['Location'] = self.get_url() # announce success logevent(request, 'Note.update', 200, form.data['jid']) return response # Otherwise return a 400 Bad Request error. logevent(request, 'Note.create', 400, form.errors) ## debug formerrors = form.errors print "UPDATE form errors %s " % repr(form.errors) ## end debug return self.responder.error(request, 400, form.errors) pass
def notes_post_multi(request): ## mirrored from NoteCollections.create upstairs but updated to handle ## new batch sync protocol from listit 0.4.0 and newer. ## changes to protocol: ## call it with a list of notes { [ {id: 123981231, text:"i love you"..} ... ] ) ## returns a success with a list { committed: [{ success: <code>, jid: <id> }] ... } unless something really bad happened request_user = basicauth_get_user_by_emailaddr(request) if not request_user: logevent(request, 'ActivityLog.create POST', 401, jv3.utils.decode_emailaddr(request)) response = HttpResponse( JSONEncoder().encode( {'autherror': "Incorrect user/password combination"}), "text/json") response.status_code = 401 return response responses = [] ## print "raw post data: %s " % repr(request.raw_post_data) if not request.raw_post_data: response = HttpResponse(JSONEncoder().encode({'committed': []}), "text/json") response.status_code = 200 return response for datum in JSONDecoder().decode(request.raw_post_data): ## print "datum : %s "% repr(datum) ## print datum form = NoteForm(datum) form.data['owner'] = request_user.id ## clobber this whole-sale from authenticating user matching_notes = request_user.note_owner.filter( jid=int(form.data['jid'])) if len(matching_notes) == 0: ## CREATE a new note # If the data contains no errors, save the model, print "CREATE a new note ", form.data['jid'] if form.is_valid(): new_model = form.save() responses.append({"jid": form.data['jid'], "status": 201}) logevent(request, 'Note.create', 200, form.data['jid']) continue ## something didn't pass form validation logevent(request, 'Note.create', 400, form.errors) responses.append({"jid": form.data['jid'], "status": 400}) continue else: print "UPDATE an existing note", form.data['jid'] ## check if the client version needs updating if len(matching_notes) > 1: print "# of Matching Notes : %d " % len(matching_notes) if (matching_notes[0].version > form.data['version']): responses.append({"jid": form.data['jid'], "status": 400}) continue # If the data contains no errors, migrate the changes over to # the version of the note in the db, increment the version number # and announce success if form.is_valid(): for key in Note.update_fields: matching_notes[0].__setattr__(key, form.data[key]) # increment version number matching_notes[0].version = form.data[ 'version'] + 1 ## matching_notes[0].version + 1; # save! # print "SAVING %s, is it deleted? %s " % (repr(matching_notes[0]),repr(matching_notes[0].deleted)) matching_notes[0].save() responses.append({"jid": form.data['jid'], "status": 201}) else: # Otherwise return a 400 Bad Request error. responses.append({"jid": form.data['jid'], "status": 400}) logevent(request, 'Note.create', 400, form.errors) pass pass ##print responses response = HttpResponse(JSONEncoder().encode({'committed': responses}), "text/json") response.status_code = 200 return response
def post_json_get_updates(request): request_user = basicauth_get_user_by_emailaddr(request); if not request_user: logevent(request,'ActivityLog.create POST',401,jv3.utils.decode_emailaddr(request)) response = HttpResponse(JSONEncoder().encode({'autherror':"Incorrect user/password combination"}), "text/json") response.status_code = 401; return response if not request.raw_post_data: response = HttpResponse(JSONEncoder().encode({'committed':[]}), "text/json") response.status_code = 200; return response ## 1) put_zen method of updating client's "Modified Notes" responses = [] # Successful commit of note. updateResponses = [] # Conflicting notes with new content! payload = JSONDecoder().decode(request.raw_post_data) userNotes = _filter_dupes(request_user.note_owner.all()) #print 'Process modified notes' for datum in payload['modifiedNotes']: form = NoteForm(datum) form.data['owner'] = request_user.id; matching_notes = [u for u in userNotes if u.jid==form.data['jid']] assert len(matching_notes) in [0,1], "Got two, which is fail %d " % form.data['jid'] #print '# matching notes:', len(matching_notes) if len(matching_notes) == 0: ## Save new note if form.is_valid() : #print "No conflict! Save note!" new_model = form.save() responses.append({ "jid": form.data['jid'], "version": form.data['version'], "status": 201}) logevent(request, 'Note.create', 200, form.data['jid']) else: logevent(request,'Note.create', 400, form.errors) responses.append({"jid": form.data['jid'], "status": 400}) else: ## UPDATE an existing note: check if the client version needs updating conflictNote = matching_notes[0] #print "conflictNote/form Ver: ", conflictNote.version, form.data['version'] if (conflictNote.version > form.data['version']): # Server's version of note is conflicting with client's version, merge! if form.is_valid(): #print "Server is more up to date:", conflictNote.jid for key in Note.update_fields: ## key={contents,created,deleted,edited} if key == "contents": newContent = ("Two versions of this note:" + "\nSubmitted Copy:\n%s\n\nServer Copy:\n%s" % (form.data[key],conflictNote.contents)) conflictNote.__setattr__(key, newContent) else: conflictNote.__setattr__(key, form.data[key]) newVersion = max(conflictNote.version, form.data['version']) + 1 conflictNote.version = newVersion newEdited = max(conflictNote.edited, form.data['edited']) conflictNote.edited = newEdited ## Saved note will be MOST-up-to-date, ie:(max(both versions)+1) conflictNote.save() updateResponses.append({"jid": form.data['jid'], "version": newVersion, "edited": newEdited, "contents": newContent, "status": 201}) continue continue # If the data contains no errors, elif form.is_valid(): # No version conflict, update server version. #print "Updating server's copy" for key in Note.update_fields: if key in ['contents', 'created', 'deleted', 'edited']: conflictNote.__setattr__(key, form.data[key]) pass pass newVersion = form.data['version'] + 1 conflictNote.version = newVersion conflictNote.save() responses.append({"jid": form.data['jid'], "version": newVersion, "status": 201}) else: responses.append({"jid": form.data['jid'], "status": 400}) logevent(request, 'Note.create', 400, form.errors) pass pass pass ##2) Figure out which of Client's unmodified notes has been updated on server updateFinal = getUpdatedNotes(payload['unmodifiedNotes'].items(), userNotes) #print 'process notes only known to server' ## 3) Return notes only server knows about! clientJIDs = map(lambda x:int(x['jid']), payload['modifiedNotes']) clientJIDs.extend(map(lambda x:int(x), payload['unmodifiedNotes'].keys())) serverNotes = [u for u in userNotes if u.deleted==0 and not u.jid in clientJIDs] serverNotes = sort_user_for_notes(request_user, serverNotes) ndicts = [ extract_zen_notes_data(note) for note in serverNotes ] ndicts.reverse() servNotes = [] # New notes server has & client doesn't. for note in ndicts: servNotes.append({ "jid": note['jid'], "version": note['version'], "contents": note['noteText'], "deleted": note['deleted'], "created": str(note['created']), "edited": str(note['edited']), "modified": 0}) ## Add meta field here! pass #print 'Add magical note!' magicNote = {} ## JID is a number field... magicalNote = [u for u in userNotes if u.jid == -1] #print 'magical note:', magicalNote if len(magicalNote) > 0: # magical note found #print 'magical note found!' magicalNote = magicalNote[0] magicNote = { 'jid': int(magicalNote.jid), 'version': magicalNote.version, 'created': int(magicalNote.created), 'edited': int(magicalNote.edited), 'deleted': magicalNote.deleted, 'contents': magicalNote.contents, 'modified': 0 } pass #magicNote = checkMagicUpdate(clientMagic, serverMagic) ## Return Response! response = HttpResponse( JSONEncoder().encode({ "committed": responses, "update": updateResponses, "updateFinal": updateFinal, "unknownNotes": servNotes, "magicNote": magicNote}), "text/json") response.status_code = 200; return response
def put_zen(request): ## copied from notes_post_multi, altered for better edit posting ## Purpose: allow notes to be posted, if server has newer version, join texts and return new note ## ## mirrored from NoteCollections.create upstairs but updated to handle ## new batch sync protocol from listit 0.4.0 and newer. ## changes to protocol: ## call it with a list of notes { [ {id: 123981231, text:"i love you"..} ... ] ) ## returns a success with a list { committed: [{ success: <code>, jid: <id> }] ... } unless something really bad happened request_user = basicauth_get_user_by_emailaddr(request); if not request_user: logevent(request,'ActivityLog.create POST',401,jv3.utils.decode_emailaddr(request)) response = HttpResponse(JSONEncoder().encode({'autherror':"Incorrect user/password combination"}), "text/json") response.status_code = 401; return response responses = [] updateResponses = [] if not request.raw_post_data: response = HttpResponse(JSONEncoder().encode({'committed':[]}), "text/json") response.status_code = 200; return response for datum in JSONDecoder().decode(request.raw_post_data): form = NoteForm(datum) form.data['owner'] = request_user.id; ## clobber this whole-sale from authenticating user matching_notes = Note.objects.filter(jid=int(form.data['jid']),owner=request_user) if len(matching_notes) == 0: ## Save new note if form.is_valid() : new_model = form.save() responses.append({"jid":form.data['jid'],"status":201}) logevent(request,'Note.create',200,form.data['jid']) continue logevent(request,'Note.create',400,form.errors) responses.append({"jid":form.data['jid'],"status":400}) continue else: ## UPDATE an existing note: check if the client version needs updating if (matching_notes[0].version > form.data['version']): if form.is_valid(): for key in Note.update_fields: ## key={contents,created,deleted,edited} if key == "contents": newContent = "Two versions of this note:\nSubmitted Copy:\n%s\n\nServer Copy:\n%s" % (form.data[key], matching_notes[0].contents) ##print "Key: %s, Data: %s" % (key, newContent) matching_notes[0].__setattr__(key, newContent) else: ##print "Key: %s, Data: %s" % (key, form.data[key]) matching_notes[0].__setattr__(key, form.data[key]) newVersion = max(matching_notes[0].version, form.data['version']) + 1 ##print newVersion matching_notes[0].version = newVersion ## Saved note is MOST-up-to-date, ie:(max(both versions)+1) matching_notes[0].save() updateResponses.append({"jid": form.data['jid'], "content": newContent, "version": newVersion, "status":201}) continue continue # If the data contains no errors, migrate the changes over to the version of the note in the db, # increment the version number and announce success if form.is_valid() : ##print "6a: update server note" for key in Note.update_fields: matching_notes[0].__setattr__(key,form.data[key]) newVersion = form.data['version'] + 1 matching_notes[0].version = newVersion matching_notes[0].save() responses.append({ "jid": form.data['jid'], "version": newVersion, "status": 201}) else: responses.append({"jid":form.data['jid'],"status":400}) logevent(request,'Note.create',400,form.errors) response = HttpResponse(JSONEncoder().encode({'committed':responses, 'update':updateResponses}), "text/json") response.status_code = 200; return response
def create(self,request): ## THIS CODE IS DEPRECATED // the SLOW method. IF YOU MAKE ANY CHANGES HERE ## MAKE SURE THE CHANGES ARE REFLECTED in note_update_batch below # MERGED create and update method for server, so that we don't have to do a PUT # forms.form_for_model(self.queryset.model, form=self.form_class) data = self.receiver.get_post_data(request) form = NoteForm(data) # get user being authenticated request_user = basicauth_get_user_by_emailaddr(request); if not request_user: logevent(request,'Note.create POST',401, jv3.utils.decode_emailaddr(request)) return self.responder.error(request, 401, ErrorDict({"autherror":"Incorrect user/password combination"})) form.data['owner'] = request_user.id; ## clobber this whole-sale from authenticating user matching_notes = Note.objects.filter(jid=form.data['jid'],owner=request_user) if len(matching_notes) == 0: ## CREATE a new note # If the data contains no errors, save the model, if form.is_valid() : new_model = form.save() model_entry = self.entry_class(self, new_model) response = model_entry.read(request) response.status_code = 201 ## response['Location'] ## = model_entry.get_url() logevent(request,'Note.create',200,form.data['jid']) return response ## something didn't pass form validation logevent(request,'Note.create',400,form.errors) ##print "CREATE form errors %s " % repr(form.errors) return self.responder.error(request, 400, form.errors); else: ## UPDATE an existing note ## check if the client version needs updating if len(matching_notes) > 1: print "# of Matching Notes : %d " % len(matching_notes) if (matching_notes[0].version > form.data['version']): errormsg = "Versions for jid %d not compatible (local:%d, received: %d). Do you need to update? " % (form.data["jid"],matching_notes[0].version,form.data["version"]) print "NOT UPDATED error -- server: %d, YOU %d " % (matching_notes[0].version,form.data['version']) return self.responder.error(request, 400, ErrorDict({"jid":errormsg})) # If the data contains no errors, migrate the changes over to # the version of the note in the db, increment the version number # and announce success if form.is_valid() : for key in Note.update_fields: matching_notes[0].__setattr__(key,form.data[key]) # increment version number matching_notes[0].version = form.data['version'] + 1 ## matching_notes[0].version + 1; # save! # print "SAVING %s, is it deleted? %s " % (repr(matching_notes[0]),repr(matching_notes[0].deleted)) matching_notes[0].save() response = self.read(request) response.status_code = 200 ## this BREAKS with 1.0 ## response['Location'] = self.get_url() # announce success logevent(request,'Note.update',200,form.data['jid']) return response # Otherwise return a 400 Bad Request error. logevent(request,'Note.create',400,form.errors) ## debug formerrors = form.errors print "UPDATE form errors %s " % repr(form.errors) ## end debug return self.responder.error(request, 400, form.errors); pass
def notes_post_multi(request): ## mirrored from NoteCollections.create upstairs but updated to handle ## new batch sync protocol from listit 0.4.0 and newer. ## changes to protocol: ## call it with a list of notes { [ {id: 123981231, text:"i love you"..} ... ] ) ## returns a success with a list { committed: [{ success: <code>, jid: <id> }] ... } unless something really bad happened request_user = basicauth_get_user_by_emailaddr(request); if not request_user: logevent(request,'ActivityLog.create POST',401,jv3.utils.decode_emailaddr(request)) response = HttpResponse(JSONEncoder().encode({'autherror':"Incorrect user/password combination"}), "text/json") response.status_code = 401; return response responses = [] ## print "raw post data: %s " % repr(request.raw_post_data) if not request.raw_post_data: response = HttpResponse(JSONEncoder().encode({'committed':[]}), "text/json") response.status_code = 200; return response for datum in JSONDecoder().decode(request.raw_post_data): ## print "datum : %s "% repr(datum) ## print datum form = NoteForm(datum) form.data['owner'] = request_user.id; ## clobber this whole-sale from authenticating user matching_notes = request_user.note_owner.filter(jid=int(form.data['jid'])) if len(matching_notes) == 0: ## CREATE a new note # If the data contains no errors, save the model, print "CREATE a new note ", form.data['jid'] if form.is_valid() : new_model = form.save() responses.append({"jid":form.data['jid'],"status":201}) logevent(request,'Note.create',200,form.data['jid']) continue ## something didn't pass form validation logevent(request,'Note.create',400,form.errors) responses.append({"jid":form.data['jid'],"status":400}) continue else: print "UPDATE an existing note", form.data['jid'] ## check if the client version needs updating if len(matching_notes) > 1: print "# of Matching Notes : %d " % len(matching_notes) if (matching_notes[0].version > form.data['version']): responses.append({"jid":form.data['jid'],"status":400}) continue # If the data contains no errors, migrate the changes over to # the version of the note in the db, increment the version number # and announce success if form.is_valid() : for key in Note.update_fields: matching_notes[0].__setattr__(key,form.data[key]) # increment version number matching_notes[0].version = form.data['version'] + 1 ## matching_notes[0].version + 1; # save! # print "SAVING %s, is it deleted? %s " % (repr(matching_notes[0]),repr(matching_notes[0].deleted)) matching_notes[0].save() responses.append({"jid":form.data['jid'],"status":201}) else: # Otherwise return a 400 Bad Request error. responses.append({"jid":form.data['jid'],"status":400}) logevent(request,'Note.create',400,form.errors) pass pass ##print responses response = HttpResponse(JSONEncoder().encode({'committed':responses}), "text/json") response.status_code = 200; return response
def post_json_get_updates(request): request_user = basicauth_get_user_by_emailaddr(request) if not request_user: logevent(request, 'ActivityLog.create POST', 401, jv3.utils.decode_emailaddr(request)) response = HttpResponse( JSONEncoder().encode( {'autherror': "Incorrect user/password combination"}), "text/json") response.status_code = 401 return response if not request.raw_post_data: response = HttpResponse(JSONEncoder().encode({'committed': []}), "text/json") response.status_code = 200 return response ## 1) put_zen method of updating client's "Modified Notes" responses = [] # Successful commit of note. updateResponses = [] # Conflicting notes with new content! payload = JSONDecoder().decode(request.raw_post_data) userNotes = _filter_dupes(request_user.note_owner.all()) #print 'Process modified notes' for datum in payload['modifiedNotes']: form = NoteForm(datum) form.data['owner'] = request_user.id matching_notes = [u for u in userNotes if u.jid == form.data['jid']] assert len(matching_notes) in [ 0, 1 ], "Got two, which is fail %d " % form.data['jid'] #print '# matching notes:', len(matching_notes) if len(matching_notes) == 0: ## Save new note if form.is_valid(): #print "No conflict! Save note!" new_model = form.save() responses.append({ "jid": form.data['jid'], "version": form.data['version'], "status": 201 }) logevent(request, 'Note.create', 200, form.data['jid']) else: logevent(request, 'Note.create', 400, form.errors) responses.append({"jid": form.data['jid'], "status": 400}) else: ## UPDATE an existing note: check if the client version needs updating conflictNote = matching_notes[0] #print "conflictNote/form Ver: ", conflictNote.version, form.data['version'] if (conflictNote.version > form.data['version']): # Server's version of note is conflicting with client's version, merge! if form.is_valid(): #print "Server is more up to date:", conflictNote.jid for key in Note.update_fields: ## key={contents,created,deleted,edited} if key == "contents": newContent = ( "Two versions of this note:" + "\nSubmitted Copy:\n%s\n\nServer Copy:\n%s" % (form.data[key], conflictNote.contents)) conflictNote.__setattr__(key, newContent) else: conflictNote.__setattr__(key, form.data[key]) newVersion = max(conflictNote.version, form.data['version']) + 1 conflictNote.version = newVersion newEdited = max(conflictNote.edited, form.data['edited']) conflictNote.edited = newEdited ## Saved note will be MOST-up-to-date, ie:(max(both versions)+1) conflictNote.save() updateResponses.append({ "jid": form.data['jid'], "version": newVersion, "edited": newEdited, "contents": newContent, "status": 201 }) continue continue # If the data contains no errors, elif form.is_valid( ): # No version conflict, update server version. #print "Updating server's copy" for key in Note.update_fields: if key in ['contents', 'created', 'deleted', 'edited']: conflictNote.__setattr__(key, form.data[key]) pass pass newVersion = form.data['version'] + 1 conflictNote.version = newVersion conflictNote.save() responses.append({ "jid": form.data['jid'], "version": newVersion, "status": 201 }) else: responses.append({"jid": form.data['jid'], "status": 400}) logevent(request, 'Note.create', 400, form.errors) pass pass pass ##2) Figure out which of Client's unmodified notes has been updated on server updateFinal = getUpdatedNotes(payload['unmodifiedNotes'].items(), userNotes) #print 'process notes only known to server' ## 3) Return notes only server knows about! clientJIDs = map(lambda x: int(x['jid']), payload['modifiedNotes']) clientJIDs.extend(map(lambda x: int(x), payload['unmodifiedNotes'].keys())) serverNotes = [ u for u in userNotes if u.deleted == 0 and not u.jid in clientJIDs ] serverNotes = sort_user_for_notes(request_user, serverNotes) ndicts = [extract_zen_notes_data(note) for note in serverNotes] ndicts.reverse() servNotes = [] # New notes server has & client doesn't. for note in ndicts: servNotes.append({ "jid": note['jid'], "version": note['version'], "contents": note['noteText'], "deleted": note['deleted'], "created": str(note['created']), "edited": str(note['edited']), "modified": 0 }) ## Add meta field here! pass #print 'Add magical note!' magicNote = {} ## JID is a number field... magicalNote = [u for u in userNotes if u.jid == -1] #print 'magical note:', magicalNote if len(magicalNote) > 0: # magical note found #print 'magical note found!' magicalNote = magicalNote[0] magicNote = { 'jid': int(magicalNote.jid), 'version': magicalNote.version, 'created': int(magicalNote.created), 'edited': int(magicalNote.edited), 'deleted': magicalNote.deleted, 'contents': magicalNote.contents, 'modified': 0 } pass #magicNote = checkMagicUpdate(clientMagic, serverMagic) ## Return Response! response = HttpResponse( JSONEncoder().encode({ "committed": responses, "update": updateResponses, "updateFinal": updateFinal, "unknownNotes": servNotes, "magicNote": magicNote }), "text/json") response.status_code = 200 return response