def reranked_notes(): reranks = rerank_result() notes = {} decoder = JSONDecoder() nranked = [] for r in reranks: rankings = decoder.decode(r.noteText)["rank"] for n in rankings.iterkeys(): notes[n] = notes.get(n, 0) + 1 nranked.append(len(rankings)) return notes, nranked
def reranked_notes(): reranks = rerank_result() notes = {} decoder = JSONDecoder() nranked = [] for r in reranks: rankings = decoder.decode(r.noteText)["rank"] for n in rankings.iterkeys(): notes[n] = notes.get(n, 0) + 1 nranked.append(len(rankings)) return notes, nranked
def add_delete_from_whitelist(request): user = authenticate_user(request) if user is None: return json_response({ "code": 404, "error": "Username or password incorrect" }) privacysettings = user.privacysettings_set.all()[0] json = request.raw_post_data if len(json.strip()) == 0: return json_response({"code": 200}) add_dels = JSONDecoder().decode(json) assert type(add_dels) == dict, "Received thing not a dict, erroring" adds = add_dels['add'] dels = add_dels['delete'] # delete urls if privacysettings.whitelist is None: privacysettings.whitelist = '' wl = privacysettings.whitelist.split(' ') wl = filter(lambda x: x not in dels, wl) wl = wl + [x for x in adds if not x in wl] privacysettings.whitelist = ' '.join(wl) # Save privacysettings.save() return json_response({"code": 200})
def sort_user_notes(request_user): ## Sort and return user's notes if Note.objects.filter(owner=request_user, jid="-1").count() > 0: ## we want to determine order using magic note magic_note = Note.objects.filter(owner=request_user, jid="-1")[0] note_order = JSONDecoder().decode(magic_note.contents)['noteorder'] notes = [ n for n in Note.objects.filter(owner=request_user, deleted=False).exclude(jid=-1) ] def sort_order(nx, ny): if nx.jid in note_order and ny.jid in note_order: result = note_order.index(nx.jid) - note_order.index(ny.jid) else: result = int((ny.created - nx.created) / 1000) return result ## sort 'em notes.sort(sort_order) else: # sort by creation date ? notes = Note.objects.filter( owner=request_user, deleted=False).order_by("-created").exclude(jid=-1) return notes
def reaccess_urls(): decoder = JSONDecoder() def get_url(logobject): try: return decoder.decode(logobject.search)["viewing_url"] except TypeError, v: pass return None
def user_search(user, days_ago=None, nosmoothing=False): from jv3.study.content_analysis import activity_logs_for_user global search_cache global search_query_cache alogs = wuw.reduceRepeatLogsValues( activity_logs_for_user(user, None, days_ago)) searches = [] queries = [] last_time = 0 for al_i in range(len(alogs)): al = alogs[al_i] if al["action"] == 'search': try: query = JSONDecoder().decode(al["search"]) except: continue if type(query) == dict: key = None if 'search' in query: key = 'search' if 'query' in query: key = 'query' if key is not None: # no empty searches pls if len(query[key].strip()) > 0 and nosmoothing or long( al['when']) - long(last_time) > ( 10 * 1000): # 10 second smoothing queries.append(query[key]) al['query'] = query[key] al['hits'] = query.get('hits', []) searches.append(al) last_time = al['when'] elif al["action"] == 'clear-search' and ( nosmoothing or long(al['when']) - long(last_time) > (10 * 1000)): al['query'] = '' searches.append(al) last_time = al["when"] search_cache[user.id] = searches search_query_cache[user.id] = queries return searches, nltk.FreqDist(queries)
def get_title_from_evt(evt): if evt.entitydata: foo = JSONDecoder().decode(evt.entitydata) if foo: foo = foo[0] if foo: foo = foo['data'] if foo: foo = JSONDecoder().decode(foo) if foo.has_key('title'): return foo['title'] if foo.has_key('data'): foo = JSONDecoder().decode(foo['data']) if foo.has_key('title'): return foo['title'] return
def calendar_update_event_dates(request): id = request.POST.get('id', None) start = request.POST.get('start', None) end = request.POST.get('end', None) id = request.REQUEST.get('id', None) try: all_day = JSONDecoder().decode(request.POST.get('allDay', 'null')) except ValueError: all_day = None start = datetime.datetime.fromtimestamp(float(start) / 1000) end = datetime.datetime.fromtimestamp(float(end) / 1000) if id: kwargs = decode_occurrence(id) event_id = kwargs.pop('event_id') instance_event, occurrence = get_occurrence(event_id, **kwargs) calendars = get_user_calendars(request.user, ['manager', 'creator']) if instance_event.calendar.pk not in [ c.calendar_id for c in calendars ]: return HttpResponse("error", mimetype="text/javascript", status=403) if all_day: ostart = start.strftime('%Y-%m-%d 00:00:00') oend = end.strftime('%Y-%m-%d 23:59:59') else: ostart = start.strftime('%Y-%m-%d %H:%M:%S') oend = end.strftime('%Y-%m-%d %H:%M:%S') if occurrence.pk: occurrence.start = ostart occurrence.end = oend occurrence.save() else: occurrence.title = instance_event.title occurrence.description = instance_event.description occurrence.start = ostart occurrence.end = oend occurrence.save() ied = EventDetails.objects.get_eventdetails_for_object( instance_event) EventDetails.objects.create_details( occurrence, location=ied.location, free_busy=ied.free_busy, privacy=ied.privacy, bgcolor=ied.bgcolor, category=ied.category, ) return HttpResponse("success", mimetype="text/javascript") else: return HttpResponse("error", mimetype="text/javascript", status=400)
def post_intention(request): rpd = request.raw_post_data print "rpd ", rpd, type(rpd) newsintentions = JSONDecoder().decode(rpd)['results'] # json.loads(request.raw_post_data) d = read() for ni in newsintentions: print ni r = [] for c in columns: r.append(ni.get(c,None)) d.append(r) _write(d) return HttpResponse("{}","text/json")
def user_search(user,days_ago=None,nosmoothing=False): from jv3.study.content_analysis import activity_logs_for_user global search_cache global search_query_cache alogs = wuw.reduceRepeatLogsValues(activity_logs_for_user(user,None,days_ago)) searches = [] queries = [] last_time = 0 for al_i in range(len(alogs)): al = alogs[al_i] if al["action"] == 'search': try: query = JSONDecoder().decode(al["search"]) except: continue if type(query) == dict: key = None if 'search' in query: key = 'search' if 'query' in query: key = 'query' if key is not None: # no empty searches pls if len(query[key].strip()) > 0 and nosmoothing or long(al['when'])-long(last_time) > (10*1000): # 10 second smoothing queries.append(query[key]) al['query'] = query[key] al['hits'] = query.get('hits',[]) searches.append(al) last_time = al['when'] elif al["action"] == 'clear-search' and (nosmoothing or long(al['when'])-long(last_time) > (10*1000)): al['query'] = '' searches.append(al) last_time = al["when"] search_cache[user.id] = searches search_query_cache[user.id] = queries return searches,nltk.FreqDist(queries)
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 post_events(request): ## lets the user post new activity in a giant single array of activity log elements request_user = authenticate_user(request) if not request_user: return json_response({"error": "Incorrect user/password combination"}, 401) logs = JSONDecoder().decode(request.raw_post_data) committed = [save_entry(entry, request_user) for entry in logs] hosts = uniq([log['entity']['host'] for log in logs], lambda x: x, None) notifications = get_notifications_for_user(request_user, hosts) return json_response( { "committed": len(committed), "notifications": notifications }, 200)
def call_router(app, action, **kwargs): """ TODO: docs """ post = kwargs if len(kwargs) else None (status, content_type, body) = request("%s/%s" % (app, action), post=post) # if the response was encoded json, decode it before returning if content_type == "application/json": return JSONDecoder().decode(body) # return plain text as-is elif content_type == "text/plain": return body # other content types must be dealt with by 'request' raise exceptions.MalformedRouterResponse( "The call_router helper can only return decoded JSON or plain" +\ "text responses. The content_type was: %s" % content_type)
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 event in a giant single array of event log elements """ request_user = authenticate_user(request); if not request_user: return self.responder.error(request, 401, ErrorDict({"autherror":"Incorrect user/password combination"})) #clientid = self._get_client(request) ## note to emax: this does not work! clientid = None maxwhen,count = self._get_max_helper(request_user,clientid) dupes = 0 committed = []; decoded = JSONDecoder().decode(request.raw_post_data) print "event received ",request_user,len(decoded) for item in decoded: try: matches = Event.objects.filter(owner=request_user, start=item['start'], entityid=item["entityid"]) if matches.count() > 0: dupes = dupes + 1 entry = matches[0] else: entry = Event() entry.owner = request_user entry.start = item['start'] entry.end = item['end'] entry.type = item['type'] entry.entityid = item['entityid'] entry.entitytype = item['entitytype'] entry.entitydata = item.get('entitydata',"").encode('ascii','ignore') clientid = item['client'] entry.client = item['client'] entry.save() committed.append(item['start']) maxwhen = max(maxwhen,entry.start) except StandardError, error: print "Error with entry %s item %s " % (repr(error),repr(item)) pass
def sigscroll_reads(note, aggregation=sigscroll_count): print note.jid if sigscroll_count_cache.has_key(note.owner.id): return sigscroll_count_cache[note.owner.id].get(note.jid, 0) print "computing sigscroll reads for user %s " % repr(note.owner) new_cache = {} for al in ActivityLog.objects.filter(action="significant-scroll", owner=note.owner): if al.search is None: continue for nv in JSONDecoder().decode(al.search)["note_visibilities"]: nvid = int(nv["id"]) new_cache[nvid] = aggregation(new_cache.get(nvid, 0), nv) global sigscroll_count_cache sigscroll_count_cache[note.owner.id] = new_cache return sigscroll_count_cache[note.owner.id].get(note.jid, 0)
def get_title_from_evt(evt): if evt.entitydata: foo = JSONDecoder().decode(evt.entitydata) if foo: foo = foo[0] if foo: foo = foo['data'] if foo: foo = JSONDecoder().decode(foo) if foo.has_key('title'): return foo['title'] if foo.has_key('data'): foo = JSONDecoder().decode(foo['data']) if foo.has_key('title'): return foo['title'] return
def sort_user_for_notes(request_user, note_list): ## Sort and return user's notes if request_user.note_owner.filter(jid="-1").count() > 0: ## we want to determine order using magic note magic_note = request_user.note_owner.filter(jid="-1")[0] note_order = JSONDecoder().decode(magic_note.contents)['noteorder'] notes = filter(lambda x: x.jid != -1, note_list) def sort_order(nx, ny): if nx.jid in note_order and ny.jid in note_order: result = note_order.index(nx.jid) - note_order.index(ny.jid) else: result = int((ny.created - nx.created) / 1000) return result ## sort 'em notes.sort(sort_order) else: # sort by creation date ? ##notes = filter(lambda x : x.jid != -1, django_notes) notes = filter(lambda x: x.jid != -1, note_list) notes.sort(key=lambda x: -x.created) return notes
def post_survey(request): (user, registration) = get_user_and_registration_from_cookie( request.POST['cookie'], request) if (not user): print "no such user registration for cookie %s " % repr(cookie) response = render_to_response('/500.html') response.status_code = 500 return response ## save result for q in JSONDecoder().decode(request.POST['questions']): question_model = jv3.models.SurveyQuestion.objects.filter(user=user, qid=q["qid"]) assert len(question_model ) == 1, "Survey questions matching qid %s %d " % (repr( q["qid"]), len(question_model)) question_model[0].response = q["response"] question_model[0].save() response = HttpResponse('Successful', 'text/html') response.status_code = 200 return response
def load_json(json): decoder = JSONDecoder() return decoder.decode(json.read())
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 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_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 load_json(json): decoder = JSONDecoder() return decoder.decode(json.read())
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