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 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 get_iphone(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 ## removed semi-colon?? return response notes = sort_user_notes(request_user) numNotes = len(notes) startIndex = int(request.GET.get("START_INDEX", 0)) endIndex = int(request.GET.get("END_INDEX", None)) if not endIndex: endIndex = numNotes notesLeft = numNotes - endIndex ndicts = [ extract_zen_notes_data(note) for note in notes[startIndex:endIndex] ] deltaIndex = endIndex - startIndex htmlblob = "\n".join(["<li><div name='note' style='overflow:hidden;' id='%(jid)s' edited='%(edited)s' created='%(created)s' version='%(version)s' deleted='%(deleted)s' pk='%(pk)s' onClick='gid(\"%(jid)s\").blur(); zenNoteView.noteClicked(\"%(jid)s\")'><pre>%(noteText)s</pre></div></li>" % n for n in ndicts ]) # onBlur='zenNoteView.noteBlur(\"%(jid)s\")' if notesLeft > 0: ## height:25px was in style for new notes (=2 lines visible without pre tags) htmlblob += "<li><div id='reqMore'><button id='requestMore' onClick='zenAjax.requestMore()'>Get %s of %s more notes</button></div></li>" % (min(deltaIndex, notesLeft), notesLeft) response = HttpResponse(htmlblob, 'text/html') response.status_code = 200 return response
def get_redact_notes(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 ## Filter out notes that have already been redacted notes = Note.objects.filter( owner=request_user).order_by("-created").exclude(jid=-1).exclude( contents="") numNotes = len(notes) userRedactedNotes = RedactedNote.objects.filter(owner=request_user) for redactedNote in userRedactedNotes: notes = notes.exclude(version=redactedNote.version, jid=redactedNote.jid) pass numNotesLeft = len(notes) ndicts = [extract_zen_notes_data(note) for note in notes] allNotes = [] for note in ndicts: allNotes.append({ "jid": note['jid'], "version": note['version'], "contents": note['noteText'], "deleted": note['deleted'], "created": str(note['created']), "edited": str(note['edited']) }) resultMap = { 'markAsRemoved': {}, 'markAsName': {}, 'markAsPassword': {}, 'markAsPhone': {} } redactedWordArray = WordMap.objects.filter(owner=request_user) for wMap in redactedWordArray: if wMap.wordType in resultMap: resultMap[wMap.wordType][wMap.privWord] = True pass userMeta = { 'userPoints': "0", 'totalNotes': str(numNotes), 'numNotesLeft': str(numNotesLeft) } response = HttpResponse( JSONEncoder().encode({ 'notes': allNotes, 'wordMapIndices': resultMap, 'userMeta': userMeta }), "text/json") response.status_code = 200 return response
def get_json_notes(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 ## Filter out notes that have already been redacted notes = _filter_dupes(request_user.note_owner.filter(deleted=0).order_by("-created")) ndicts = [ extract_zen_notes_data(note) for note in notes ] allNotes = [] for note in ndicts: allNotes.append( {"jid":note['jid'],"version":note['version'], "contents":note['noteText'], "deleted":note['deleted'], "created":str(note['created']), "edited":str(note['edited']) }) allNotes.sort(lambda x,y:cmp(x['created'], y['created']) ) response = HttpResponse(JSONEncoder().encode({"notes":allNotes}), "text/json") response.status_code = 200 return response
def read(self, request): """ Returns a representation of the queryset. The format depends on which responder (e.g. JSONResponder) is assigned to this ModelResource instance. Usually called by a HTTP request to the factory URI with method GET. """ request_user = basicauth_get_user_by_emailaddr(request) if not request_user: logevent(request, 'Note.read', 401, {"requesting user:"******"autherror": "Incorrect user/password combination"})) qs_user = None if request.GET.has_key("jid"): ## user has asked for only one note, yo. qs_user = Note.objects.filter(owner=request_user, jid=int(request.GET["jid"])) else: qs_user = Note.objects.filter(owner=request_user) logevent(request, 'Note.read', 200) return self.responder.list(request, qs_user)
def get_json_notes(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 ## Filter out notes that have already been redacted notes = _filter_dupes( request_user.note_owner.filter(deleted=0).order_by("-created")) ndicts = [extract_zen_notes_data(note) for note in notes] allNotes = [] for note in ndicts: allNotes.append({ "jid": note['jid'], "version": note['version'], "contents": note['noteText'], "deleted": note['deleted'], "created": str(note['created']), "edited": str(note['edited']) }) allNotes.sort(lambda x, y: cmp(x['created'], y['created'])) response = HttpResponse(JSONEncoder().encode({"notes": allNotes}), "text/json") response.status_code = 200 return response
def get_iphone(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 ## removed semi-colon?? return response notes = sort_user_notes(request_user) numNotes = len(notes) startIndex = int(request.GET.get("START_INDEX", 0)) endIndex = int(request.GET.get("END_INDEX", None)) if not endIndex: endIndex = numNotes notesLeft = numNotes - endIndex ndicts = [ extract_zen_notes_data(note) for note in notes[startIndex:endIndex] ] deltaIndex = endIndex - startIndex htmlblob = "\n".join([ "<li><div name='note' style='overflow:hidden;' id='%(jid)s' edited='%(edited)s' created='%(created)s' version='%(version)s' deleted='%(deleted)s' pk='%(pk)s' onClick='gid(\"%(jid)s\").blur(); zenNoteView.noteClicked(\"%(jid)s\")'><pre>%(noteText)s</pre></div></li>" % n for n in ndicts ]) # onBlur='zenNoteView.noteBlur(\"%(jid)s\")' if notesLeft > 0: ## height:25px was in style for new notes (=2 lines visible without pre tags) htmlblob += "<li><div id='reqMore'><button id='requestMore' onClick='zenAjax.requestMore()'>Get %s of %s more notes</button></div></li>" % ( min(deltaIndex, notesLeft), notesLeft) response = HttpResponse(htmlblob, 'text/html') response.status_code = 200 return response
def get_pure(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 ## removed semi-colon?? return response notes = get_sorted_notes(request_user) def puredict(note): return {"noteText":note.contents, "edited":note.edited, "pk":note.id, "jid":note.jid, "col":80, "row":1, "version":note.version, "deleted":"false", "created":note.created} ndicts = [ puredict(note) for note in notes ] #htmlblob = "\n".join([ "<div class='note' nid='%(jid)s' id='%(jid)s' style='display:%(startVisibility)s'><img class='deleteX' src='arrow-left.png' alt='Delete' onMouseOver='zenNoteView.dispNoteOptions(\"%(jid)s\", true)' onmouseout=\"zenNoteView.noteOptions.startTimer();\"/> <textarea name='note' edited='%(edited)s' created='%(created)s' version='%(version)s' deleted='%(deleted)s' pk='%(pk)s' onFocus='zenNoteView.noteClicked(\"%(jid)s\")' cols='%(col)s' rows='%(row)s' hasFocus='false' hasSelect='false' onBlur='zenNoteView.noteBlur(\"%(jid)s\")' style='overflow:hidden'>%(noteText)s</textarea></div>" % n for n in ndicts ]) htmlblob = "\n".join(["<div class='note' id='%(jid)s' %(noteText)s</div>" % n for n in ndicts ]) response = HttpResponse(htmlblob, 'text/html'); response.status_code = 200 return response
def authenticate_user(request): # this authentication mechanism works for BOTH listit-style and eyebrowse-style authentication ba_user = basicauth_get_user_by_emailaddr(request) if ba_user is not None: return ba_user if request.user and request.user.username: return request.user return None
def get_zen(request): iphone = True 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 ## removed semi-colon?? return response notes = sort_user_notes(request_user) startIndex = int(request.GET.get("START_INDEX", 0)) noteLength = len(notes) endIndex = int(request.GET.get("END_INDEX", -1)) if endIndex == -1: iphone = False endIndex = noteLength additionalNotesWaiting = True if iphone and (endIndex >= noteLength): additionalNotesWaiting = False ## make magic happen ndicts = [ extract_zen_notes_data_extras(note) for note in notes[startIndex:endIndex] ] deltaIndex = endIndex - startIndex iconType = request.GET.get("ICON", 'none') if iconType == 'X': ## For zen site ##print "Called from /zen/ site" htmlblob = "\n".join([ "<div class='note' name='%(archiveState)s' style='display:%(startVisibility)s'><img class='deleteX' src='x.png' alt='Delete' onClick='zenNoteAjax.saveEditedNote(\"%(jid)s\", true)'/> <textarea name='note' id='%(jid)s' edited='%(edited)s' created='%(created)s' version='%(version)s' deleted='%(deleted)s' pk='%(pk)s' onFocus='zenNoteView.noteClicked(\"%(jid)s\")' cols='%(col)s' rows='%(row)s' hasFocus='false' hasSelect='false' onBlur='zenNoteView.noteBlur(\"%(jid)s\")' style='overflow:hidden'>%(noteText)s</textarea></div>" % n for n in ndicts ]) else: ## For tags site ##print "Called from /tags/ site" htmlblob = "\n".join([ "<div class='note' name='%(archiveState)s' style='display:%(startVisibility)s'><img class='deleteX' src='arrow-left.png' alt='Delete' onMouseOver='zenNoteView.dispNoteOptions(\"%(jid)s\", true)' onmouseout=\"zenNoteView.noteOptions.startTimer();\"/> <textarea name='note' id='%(jid)s' edited='%(edited)s' created='%(created)s' version='%(version)s' deleted='%(deleted)s' pk='%(pk)s' onFocus='zenNoteView.noteClicked(\"%(jid)s\")' cols='%(col)s' rows='%(row)s' hasFocus='false' hasSelect='false' onBlur='zenNoteView.noteBlur(\"%(jid)s\")' style='overflow:hidden'>%(noteText)s</textarea></div>" % n for n in ndicts ]) if iphone and additionalNotesWaiting: htmlblob += "\n <button id='requestMore' onClick='zeniPhone.requestMore()'>Get %s more notes</div>" % ( deltaIndex) elif iphone: htmlblob += "\n <button id='requestMore' style='display:none' onClick='zeniPhone.requestMore()'>Get %s more notes</div>" % ( deltaIndex) response = HttpResponse(htmlblob, 'text/html') response.status_code = 200 return response
def login(request): request_user = basicauth_get_user_by_emailaddr(request); if not request_user: resp = json_response({"code":401,'autherror':"Incorrect user/password combination"}) resp.status_code = 401; return resp resp = json_response({"code":200,"study1":is_consenting_study1(request_user),"study2":is_consenting_study2(request_user)}) resp.status_code = 200; print "returning resp %s // %s " % (repr(is_consenting_study1(request_user)),repr(is_consenting_study2(request_user))) return resp
def set_consenting_view(request): request_user = basicauth_get_user_by_emailaddr(request) if not request_user: resp = json_response({"code":401,'autherror':"Incorrect user/password combination"}) resp.status_code = 401; return resp value = JSONDecoder().decode(request.raw_post_data)['consenting'] print "set_consenting %s " % repr(value) set_consenting(request_user,value) resp = json_response({"code":200}) resp.status_code = 200; return resp
def create(self, request): """ lets the user post new activity in a giant single array of activity log elements """ request_user = basicauth_get_user_by_emailaddr(request) if not request_user: logevent(request, 'ActivityLog.create POST', 401, jv3.utils.decode_emailaddr(request)) return self.responder.error( request, 401, ErrorDict({"autherror": "Incorrect user/password combination"})) # clientid = self._get_client(request) # this doesn't work, emax clientid = None maxdate, count = self._get_max_helper(request_user, clientid) # overcount committed = [] incoming = JSONDecoder().decode(request.raw_post_data) print "activity log", request_user, " received ", len(incoming) dupes = 0 for item in incoming: #print "item is %s " % repr(item) try: if ActivityLog.objects.filter(owner=request_user, when=item['id'], action=item['type']).count() > 0: # print "actlog skipping ~ " dupes = dupes + 1 continue entry = ActivityLog() entry.owner = request_user entry.when = item['id'] entry.action = item['type'] entry.noteid = item.get("noteid", None) entry.noteText = item.get("noteText", None) entry.search = item.get("search", None) entry.client = item.get("client", None) ## added in new rev clientid = item.get("client") entry.save() committed.append(long(item['id'])) maxdate = max(maxdate, long(item['id'])) except StandardError, error: print "Error with entry %s item %s " % (repr(error), repr(item))
def set_consenting_view(request): request_user = basicauth_get_user_by_emailaddr(request) if not request_user: resp = json_response({ "code": 401, 'autherror': "Incorrect user/password combination" }) resp.status_code = 401 return resp value = JSONDecoder().decode(request.raw_post_data)['consenting'] print "set_consenting %s " % repr(value) set_consenting(request_user, value) resp = json_response({"code": 200}) resp.status_code = 200 return resp
def read(self,request): request_user = basicauth_get_user_by_emailaddr(request); if not request_user: logevent(request,'ActivityLog.read',401,{"requesting user:"******"autherror":"Incorrect user/password combintion"})) clientid = self._get_client(request) if (request.GET['type'] == 'get_max_log_id'): ## "what is the last thing i sent?" try: return self._handle_max_log_request(request_user,clientid); except: print sys.exc_info() logging.error(str(sys.exc_info())) return HttpResponse(JSONEncoder().encode({'value':0, 'num_logs':0})) return HttpResponse(JSONEncoder().encode([]), self.responder.mimetype)
def login(request): request_user = basicauth_get_user_by_emailaddr(request) if not request_user: resp = json_response({ "code": 401, 'autherror': "Incorrect user/password combination" }) resp.status_code = 401 return resp resp = json_response({ "code": 200, "study1": is_consenting_study1(request_user), "study2": is_consenting_study2(request_user) }) resp.status_code = 200 print "returning resp %s // %s " % (repr(is_consenting_study1( request_user)), repr(is_consenting_study2(request_user))) return resp
def get_redact_notes(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 ## Filter out notes that have already been redacted notes = Note.objects.filter(owner=request_user).order_by("-created").exclude(jid=-1).exclude(contents="") numNotes = len(notes) userRedactedNotes = RedactedNote.objects.filter(owner=request_user) for redactedNote in userRedactedNotes: notes = notes.exclude(version=redactedNote.version, jid=redactedNote.jid) pass numNotesLeft = len(notes) ndicts = [ extract_zen_notes_data(note) for note in notes ] allNotes = [] for note in ndicts: allNotes.append( {"jid":note['jid'],"version":note['version'], "contents":note['noteText'], "deleted":note['deleted'], "created":str(note['created']), "edited":str(note['edited']) }) resultMap = { 'markAsRemoved' : {}, 'markAsName' : {}, 'markAsPassword': {}, 'markAsPhone' : {}} redactedWordArray = WordMap.objects.filter(owner=request_user) for wMap in redactedWordArray: if wMap.wordType in resultMap: resultMap[wMap.wordType][wMap.privWord] = True pass userMeta = { 'userPoints': "0", 'totalNotes': str(numNotes), 'numNotesLeft': str(numNotesLeft)} response = HttpResponse(JSONEncoder().encode({'notes':allNotes, 'wordMapIndices':resultMap, 'userMeta':userMeta}), "text/json") response.status_code = 200 return response
def get_zen(request): iphone = True 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 ## removed semi-colon?? return response notes = sort_user_notes(request_user) startIndex = int(request.GET.get("START_INDEX", 0)) noteLength = len(notes) endIndex = int(request.GET.get("END_INDEX", -1)) if endIndex == -1: iphone = False endIndex = noteLength additionalNotesWaiting = True if iphone and (endIndex >= noteLength): additionalNotesWaiting = False; ## make magic happen ndicts = [ extract_zen_notes_data_extras(note) for note in notes[startIndex:endIndex] ] deltaIndex = endIndex - startIndex iconType = request.GET.get("ICON", 'none') if iconType == 'X': ## For zen site ##print "Called from /zen/ site" htmlblob = "\n".join([ "<div class='note' name='%(archiveState)s' style='display:%(startVisibility)s'><img class='deleteX' src='x.png' alt='Delete' onClick='zenNoteAjax.saveEditedNote(\"%(jid)s\", true)'/> <textarea name='note' id='%(jid)s' edited='%(edited)s' created='%(created)s' version='%(version)s' deleted='%(deleted)s' pk='%(pk)s' onFocus='zenNoteView.noteClicked(\"%(jid)s\")' cols='%(col)s' rows='%(row)s' hasFocus='false' hasSelect='false' onBlur='zenNoteView.noteBlur(\"%(jid)s\")' style='overflow:hidden'>%(noteText)s</textarea></div>" % n for n in ndicts ]) else: ## For tags site ##print "Called from /tags/ site" htmlblob = "\n".join([ "<div class='note' name='%(archiveState)s' style='display:%(startVisibility)s'><img class='deleteX' src='arrow-left.png' alt='Delete' onMouseOver='zenNoteView.dispNoteOptions(\"%(jid)s\", true)' onmouseout=\"zenNoteView.noteOptions.startTimer();\"/> <textarea name='note' id='%(jid)s' edited='%(edited)s' created='%(created)s' version='%(version)s' deleted='%(deleted)s' pk='%(pk)s' onFocus='zenNoteView.noteClicked(\"%(jid)s\")' cols='%(col)s' rows='%(row)s' hasFocus='false' hasSelect='false' onBlur='zenNoteView.noteBlur(\"%(jid)s\")' style='overflow:hidden'>%(noteText)s</textarea></div>" % n for n in ndicts ]) if iphone and additionalNotesWaiting: htmlblob += "\n <button id='requestMore' onClick='zeniPhone.requestMore()'>Get %s more notes</div>" % (deltaIndex) elif iphone: htmlblob += "\n <button id='requestMore' style='display:none' onClick='zeniPhone.requestMore()'>Get %s more notes</div>" % (deltaIndex) response = HttpResponse(htmlblob, 'text/html'); response.status_code = 200 return response
def post_json_chrome_logs(request): """ Record Chrome usage logs, return timestamp of last log recorded. """ request_user = basicauth_get_user_by_emailaddr(request) if not request_user: logevent(request, 'post_json_chrome_logs POST', 401, jv3.utils.decode_emailaddr(request)) response = HttpResponse( JSONEncoder().encode( {'autherror': "Incorrect user/password combination"}), "text/json") response.status_code = 401 return response payload = JSONDecoder().decode(request.raw_post_data) logs = payload timestamp = 0 for log in logs: # Save each log, keep track of latest log's timestamp. # keys: time, action, noteid (>0 or -10), info (JSON string) # ext only: tabid (chrome ext tab), url (of focused tab) entry = ChromeLog() entry.owner = request_user entry.when = log['time'] timestamp = max(entry.when, timestamp) entry.action = log['action'] entry.noteid = log.get("noteid", None) entry.info = log.get("info", None) entry.url = log.get("url", None) entry.tabid = log.get("tabid", None) ## added in new rev entry.save() ## Return Response! response = HttpResponse( JSONEncoder().encode({ "lastTimeRecorded": timestamp, }), "text/json") response.status_code = 200 return response
def create(self,request): """ lets the user post new activity in a giant single array of activity log elements """ request_user = basicauth_get_user_by_emailaddr(request); if not request_user: logevent(request,'ActivityLog.create POST',401,jv3.utils.decode_emailaddr(request)) return self.responder.error(request, 401, ErrorDict({"autherror":"Incorrect user/password combination"})) # clientid = self._get_client(request) # this doesn't work, emax clientid = None maxdate,count = self._get_max_helper(request_user,clientid) # overcount committed = []; incoming = JSONDecoder().decode(request.raw_post_data) print "activity log",request_user," received ",len(incoming) dupes = 0 for item in incoming: #print "item is %s " % repr(item) try: if ActivityLog.objects.filter(owner=request_user,when=item['id'],action=item['type']).count() > 0: # print "actlog skipping ~ " dupes = dupes + 1 continue entry = ActivityLog(); entry.owner = request_user; entry.when = item['id']; entry.action = item['type']; entry.noteid = item.get("noteid",None); entry.noteText = item.get("noteText",None); entry.search = item.get("search",None); entry.client = item.get("client",None); ## added in new rev clientid = item.get("client") entry.save(); committed.append(long(item['id'])); maxdate = max(maxdate,long(item['id'])) except StandardError, error: print "Error with entry %s item %s " % (repr(error),repr(item))
def post_usage_statistics(request): print "usage stats" print request.raw_post_data try: slog = ServerLog() request_user = basicauth_get_user_by_emailaddr(request) if request_user: slog.user = request_user slog.when = current_time_decimal() slog.action = "usage_statistics" slog.info = request.raw_post_data slog.host = "" slog.url = "post_diagnostics" slog.request = "" slog.save() return json_response("[]", 200) except: excinfo = sys.exc_info() response = HttpResponse(repr(excinfo), 'text/html') response.status_code = 500 return response
def post_usage_statistics(request): print "usage stats" print request.raw_post_data try: slog = ServerLog() request_user = basicauth_get_user_by_emailaddr(request); if request_user: slog.user = request_user slog.when = current_time_decimal() slog.action = "usage_statistics" slog.info = request.raw_post_data slog.host = "" slog.url="post_diagnostics" slog.request="" slog.save() return json_response("[]", 200); except: excinfo = sys.exc_info() response = HttpResponse(repr(excinfo), 'text/html'); response.status_code = 500 return response
def read(self, request): """ Returns a representation of the queryset. The format depends on which responder (e.g. JSONResponder) is assigned to this ModelResource instance. Usually called by a HTTP request to the factory URI with method GET. """ request_user = basicauth_get_user_by_emailaddr(request); if not request_user: logevent(request,'Note.read',401,{"requesting user:"******"autherror":"Incorrect user/password combination"})) qs_user = None if request.GET.has_key("jid"): ## user has asked for only one note, yo. qs_user = Note.objects.filter(owner=request_user,jid=int(request.GET["jid"])) else: qs_user = Note.objects.filter(owner=request_user) logevent(request,'Note.read',200) return self.responder.list(request, qs_user)
def post_json_chrome_logs(request): """ Record Chrome usage logs, return timestamp of last log recorded. """ request_user = basicauth_get_user_by_emailaddr(request) if not request_user: logevent(request,'post_json_chrome_logs POST', 401, jv3.utils.decode_emailaddr(request)) response = HttpResponse(JSONEncoder().encode({ 'autherror':"Incorrect user/password combination"}), "text/json") response.status_code = 401 return response payload = JSONDecoder().decode(request.raw_post_data) logs = payload timestamp = 0 for log in logs: # Save each log, keep track of latest log's timestamp. # keys: time, action, noteid (>0 or -10), info (JSON string) # ext only: tabid (chrome ext tab), url (of focused tab) entry = ChromeLog(); entry.owner = request_user; entry.when = log['time']; timestamp = max(entry.when, timestamp) entry.action = log['action']; entry.noteid = log.get("noteid",None); entry.info = log.get("info",None); entry.url = log.get("url",None); entry.tabid = log.get("tabid",None); ## added in new rev entry.save(); ## Return Response! response = HttpResponse( JSONEncoder().encode({ "lastTimeRecorded": timestamp, }), "text/json") response.status_code = 200; return response
def read(self, request): request_user = basicauth_get_user_by_emailaddr(request) if not request_user: logevent(request, 'ActivityLog.read', 401, {"requesting user:"******"autherror": "Incorrect user/password combintion"})) clientid = self._get_client(request) if (request.GET['type'] == 'get_max_log_id'): ## "what is the last thing i sent?" try: return self._handle_max_log_request(request_user, clientid) except: print sys.exc_info() logging.error(str(sys.exc_info())) return HttpResponse(JSONEncoder().encode({ 'value': 0, 'num_logs': 0 })) return HttpResponse(JSONEncoder().encode([]), self.responder.mimetype)
def get_pure(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 ## removed semi-colon?? return response notes = get_sorted_notes(request_user) def puredict(note): return { "noteText": note.contents, "edited": note.edited, "pk": note.id, "jid": note.jid, "col": 80, "row": 1, "version": note.version, "deleted": "false", "created": note.created } ndicts = [puredict(note) for note in notes] #htmlblob = "\n".join([ "<div class='note' nid='%(jid)s' id='%(jid)s' style='display:%(startVisibility)s'><img class='deleteX' src='arrow-left.png' alt='Delete' onMouseOver='zenNoteView.dispNoteOptions(\"%(jid)s\", true)' onmouseout=\"zenNoteView.noteOptions.startTimer();\"/> <textarea name='note' edited='%(edited)s' created='%(created)s' version='%(version)s' deleted='%(deleted)s' pk='%(pk)s' onFocus='zenNoteView.noteClicked(\"%(jid)s\")' cols='%(col)s' rows='%(row)s' hasFocus='false' hasSelect='false' onBlur='zenNoteView.noteBlur(\"%(jid)s\")' style='overflow:hidden'>%(noteText)s</textarea></div>" % n for n in ndicts ]) htmlblob = "\n".join([ "<div class='note' id='%(jid)s' %(noteText)s</div>" % n for n in ndicts ]) response = HttpResponse(htmlblob, 'text/html') 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 post_redacted_note(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 for datum in JSONDecoder().decode(request.raw_post_data): ver = datum['version'] noteID = datum['id'] matchingNotes = RedactedNote.objects.filter(jid=noteID, version=ver) for mNote in matchingNotes: del_wordmeta_for_note(mNote) mNote.delete() pass rNote = RedactedNote() rNote.owner = request_user rNote.nCreated = datum['origCreated'] rNote.nEdited = datum['origEdited'] rNote.nDeleted = datum['origDeleted'] rNote.created = datum['created'] rNote.jid = datum['id'] rNote.version = datum['version'] rNote.noteType = datum['noteType'] sCharIndices = datum['sCharIndices'] ## Tuples: (char index, word length) noteText = datum['text'] noteCharList = list(noteText) wordMapIndicesStore = [] ## [word index, WordMap(instance)] to make WordMeta sCharIndices.sort(lambda x,y:cmp(y[2],x[2])) ## Sort redacted indices in reverse order ## Walk thru note text, changing redacted text for public xX9* version for rIndex, rLen, sIndex, sLen in sCharIndices: ## Ex: chinese symbol Z from server seen on client as 3 utf-8 chars: abc ## String "ZZ", with 2nd one redacted ## rIndex = 4 = start index of redacted text in string ## rLen = 3 = length of word as seen by redact site (utf-8) ## sIndex = 1 = start index of redacted text in original encoding (utf-16?) ## sLen = 1 = length of redacted string as sent from server rType = "markAsRemoved" privWord = ''.join(noteCharList[rIndex:rIndex+rLen]) matchWordMap = getWordMap(request_user, rType, privWord) if matchWordMap is False: ## Create a new WordMap if rLen != sLen: ## Word server sent out and word recieved are encoded to different lengths wordMapIDRep, repWord = createSpecialWordMap(request_user, rType, privWord, sLen) else: ## Create WordMap that stores original wordMapIDRep, repWord = createWordMap(request_user, rType, privWord) wordMapIndicesStore.append([sIndex, sLen, wordMapIDRep]) noteCharList[rIndex:rIndex+rLen] = list(repWord) else: ## Found a WordMap already describing this word wordMapIndicesStore.append([sIndex, sLen, matchWordMap[0]]) noteCharList[rIndex:rIndex+rLen] = list(matchWordMap[1]) pass rNote.contents = ''.join(noteCharList) rNote.save() ## Create all the WordMeta using pairs from wordMapIndicesStore for data in wordMapIndicesStore: wMeta = WordMeta(owner=request_user, rNote=rNote, index=data[0], length=data[1], wordMap=data[2]) wMeta.save() pass pass response = HttpResponse("No Errors?", "text/json") response.status_code = 200 return response
def post_redacted_note(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 for datum in JSONDecoder().decode(request.raw_post_data): ver = datum['version'] noteID = datum['id'] matchingNotes = RedactedNote.objects.filter(jid=noteID, version=ver) for mNote in matchingNotes: del_wordmeta_for_note(mNote) mNote.delete() pass rNote = RedactedNote() rNote.owner = request_user rNote.nCreated = datum['origCreated'] rNote.nEdited = datum['origEdited'] rNote.nDeleted = datum['origDeleted'] rNote.created = datum['created'] rNote.jid = datum['id'] rNote.version = datum['version'] rNote.noteType = datum['noteType'] sCharIndices = datum[ 'sCharIndices'] ## Tuples: (char index, word length) noteText = datum['text'] noteCharList = list(noteText) wordMapIndicesStore = [ ] ## [word index, WordMap(instance)] to make WordMeta sCharIndices.sort(lambda x, y: cmp(y[2], x[2]) ) ## Sort redacted indices in reverse order ## Walk thru note text, changing redacted text for public xX9* version for rIndex, rLen, sIndex, sLen in sCharIndices: ## Ex: chinese symbol Z from server seen on client as 3 utf-8 chars: abc ## String "ZZ", with 2nd one redacted ## rIndex = 4 = start index of redacted text in string ## rLen = 3 = length of word as seen by redact site (utf-8) ## sIndex = 1 = start index of redacted text in original encoding (utf-16?) ## sLen = 1 = length of redacted string as sent from server rType = "markAsRemoved" privWord = ''.join(noteCharList[rIndex:rIndex + rLen]) matchWordMap = getWordMap(request_user, rType, privWord) if matchWordMap is False: ## Create a new WordMap if rLen != sLen: ## Word server sent out and word recieved are encoded to different lengths wordMapIDRep, repWord = createSpecialWordMap( request_user, rType, privWord, sLen) else: ## Create WordMap that stores original wordMapIDRep, repWord = createWordMap( request_user, rType, privWord) wordMapIndicesStore.append([sIndex, sLen, wordMapIDRep]) noteCharList[rIndex:rIndex + rLen] = list(repWord) else: ## Found a WordMap already describing this word wordMapIndicesStore.append([sIndex, sLen, matchWordMap[0]]) noteCharList[rIndex:rIndex + rLen] = list(matchWordMap[1]) pass rNote.contents = ''.join(noteCharList) rNote.save() ## Create all the WordMeta using pairs from wordMapIndicesStore for data in wordMapIndicesStore: wMeta = WordMeta(owner=request_user, rNote=rNote, index=data[0], length=data[1], wordMap=data[2]) wMeta.save() pass pass response = HttpResponse("No Errors?", "text/json") response.status_code = 200 return response
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 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 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 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 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 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