Skip to content

Commit da71e87

Browse files
author
emax
committed
refactored moving things about
1 parent 25fe5a5 commit da71e87

File tree

4 files changed

+609
-547
lines changed

4 files changed

+609
-547
lines changed

jv3/chrome_views.py

Lines changed: 251 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,251 @@
1+
2+
from django import forms
3+
from django.http import HttpResponseRedirect, HttpResponse
4+
from django.shortcuts import render_to_response
5+
from django_restapi.model_resource import Collection
6+
from django.forms.util import ErrorDict
7+
from django.utils.translation.trans_null import _
8+
from django.core import serializers
9+
from django.core.mail import send_mail
10+
from django.conf import settings
11+
from django.utils.simplejson import JSONEncoder, JSONDecoder
12+
import django.contrib.auth.models as authmodels
13+
from django_restapi.resource import Resource
14+
from django_restapi.model_resource import InvalidModelData
15+
from jv3.models import Note, NoteForm
16+
from jv3.models import RedactedNote ##, RedactedSkip
17+
from jv3.models import WordMap, WordMeta
18+
import jv3.utils
19+
from jv3.models import ActivityLog, UserRegistration, CouhesConsent, ChangePasswordRequest, BugReport, ServerLog, CachedActivityLogStats
20+
from jv3.utils import gen_cookie, makeChangePasswordRequest, nonblank, get_most_recent, gen_confirm_newuser_email_body, gen_confirm_change_password_email, logevent, current_time_decimal, basicauth_get_user_by_emailaddr, make_username, get_user_by_email, is_consenting_study1, is_consenting_study2, json_response, set_consenting
21+
from django.template.loader import get_template
22+
import sys,string,time,logging
23+
import tempfile,os
24+
from decimal import Decimal
25+
from jv3.views import *
26+
27+
def _filter_dupes(note_queryset):
28+
distinct_jids = set([x[0] for x in note_queryset.values_list('jid')])
29+
notes = {}
30+
for n in note_queryset:
31+
if n.jid in notes and notes[n.jid].id < n.id : continue
32+
notes[n.jid] = n
33+
return [notes[n.jid] for n in note_queryset]
34+
35+
## Chrome Extension Get/Post Methods
36+
def get_json_notes(request):
37+
request_user = basicauth_get_user_by_emailaddr(request)
38+
if not request_user:
39+
logevent(request,'ActivityLog.create POST',401,jv3.utils.decode_emailaddr(request))
40+
response = HttpResponse(JSONEncoder().encode({'autherror':"Incorrect user/password combination"}), "text/json")
41+
response.status_code = 401
42+
return response
43+
44+
## Filter out notes that have already been redacted
45+
notes = _filter_dupes(request_user.note_owner.filter(deleted=0).order_by("-created"))
46+
47+
ndicts = [ extract_zen_notes_data(note) for note in notes ]
48+
allNotes = []
49+
for note in ndicts:
50+
allNotes.append(
51+
{"jid":note['jid'],"version":note['version'], "contents":note['noteText'],
52+
"deleted":note['deleted'], "created":str(note['created']),
53+
"edited":str(note['edited']) })
54+
55+
allNotes.sort(lambda x,y:cmp(x['created'], y['created']) )
56+
57+
58+
response = HttpResponse(JSONEncoder().encode({"notes":allNotes}), "text/json")
59+
response.status_code = 200
60+
return response
61+
62+
def post_json_notes(request):
63+
return put_zen(request)
64+
65+
def sort_user_for_notes(request_user, note_list):
66+
## Sort and return user's notes
67+
if request_user.note_owner.filter(jid="-1").count() > 0:
68+
## we want to determine order using magic note
69+
magic_note = request_user.note_owner.filter(jid="-1")[0]
70+
note_order = JSONDecoder().decode(magic_note.contents)['noteorder']
71+
notes = filter(lambda x: x.jid != -1,note_list)
72+
def sort_order(nx,ny):
73+
if nx.jid in note_order and ny.jid in note_order:
74+
result = note_order.index(nx.jid) - note_order.index(ny.jid)
75+
else:
76+
result = int((ny.created - nx.created)/1000)
77+
return result
78+
## sort 'em
79+
notes.sort(sort_order)
80+
else:
81+
# sort by creation date ?
82+
notes = filter(lambda x : x.jid != -1, django_notes)
83+
notes.sort(key=lambda x:-x.created)
84+
return notes
85+
86+
87+
def carefully(fn):
88+
import sys, traceback
89+
def boo(*args,**kwargs):
90+
try:
91+
return fn(*args,**kwargs)
92+
except Exception as exc:
93+
print "Unexpected error:", sys.exc_info()[0]
94+
print str(exc)
95+
traceback.print_exc(file=sys.stdout)
96+
raise
97+
return boo
98+
99+
# @carefully
100+
def post_json_get_updates(request):
101+
request_user = basicauth_get_user_by_emailaddr(request);
102+
if not request_user:
103+
logevent(request,'ActivityLog.create POST',401,jv3.utils.decode_emailaddr(request))
104+
response = HttpResponse(JSONEncoder().encode({'autherror':"Incorrect user/password combination"}), "text/json")
105+
response.status_code = 401;
106+
return response
107+
if not request.raw_post_data:
108+
response = HttpResponse(JSONEncoder().encode({'committed':[]}), "text/json")
109+
response.status_code = 200;
110+
return response
111+
112+
## 1) put_zen method of updating client's "Modified Notes"
113+
responses = [] # Successful commit of note.
114+
updateResponses = [] # Conflicting notes with new content!
115+
payload = JSONDecoder().decode(request.raw_post_data)
116+
userNotes = _filter_dupes(request_user.note_owner.all())
117+
118+
#print 'Process modified notes'
119+
for datum in payload['modifiedNotes']:
120+
form = NoteForm(datum)
121+
form.data['owner'] = request_user.id;
122+
matching_notes = [u for u in userNotes if u.jid==form.data['jid']]
123+
assert len(matching_notes) in [0,1], "Got two, which is fail %d " % form.data['jid']
124+
#print '# matching notes:', len(matching_notes)
125+
if len(matching_notes) == 0: ## Save new note
126+
if form.is_valid() :
127+
new_model = form.save()
128+
responses.append({
129+
"jid": form.data['jid'],
130+
"version": form.data['version'],
131+
"status": 201})
132+
logevent(request, 'Note.create', 200, form.data['jid'])
133+
else:
134+
logevent(request,'Note.create',400,form.errors)
135+
responses.append({"jid": form.data['jid'], "status": 400})
136+
else:
137+
## UPDATE an existing note: check if the client version needs updating
138+
conflictNote = matching_notes[0]
139+
##print "conflictNote/form Ver: ", conflictNote.version, form.data['version']
140+
if (conflictNote.version > form.data['version']):
141+
# Server's version of note is conflicting with client's version, merge!
142+
if form.is_valid():
143+
for key in Note.update_fields: ## key={contents,created,deleted,edited}
144+
if key == "contents":
145+
newContent = ("Two versions of this note:" +
146+
"\nSubmitted Copy:\n%s\n\nServer Copy:\n%s"
147+
% (form.data[key],conflictNote.contents))
148+
conflictNote.__setattr__(key, newContent)
149+
else:
150+
conflictNote.__setattr__(key, form.data[key])
151+
newVersion = max(conflictNote.version,
152+
form.data['version']) + 1
153+
conflictNote.version = newVersion
154+
newEdited = max(conflictNote.edited,
155+
form.data['edited'])
156+
conflictNote.edited = newEdited
157+
## Saved note will be MOST-up-to-date, ie:(max(both versions)+1)
158+
conflictNote.save()
159+
updateResponses.append({"jid": form.data['jid'],
160+
"version": newVersion,
161+
"edited": newEdited,
162+
"contents": newContent,
163+
"status": 201})
164+
continue
165+
continue
166+
# If the data contains no errors,
167+
elif form.is_valid(): # No version conflict, update server version.
168+
#print "update server's note"
169+
for key in Note.update_fields:
170+
conflictNote.__setattr__(key, form.data[key])
171+
newVersion = form.data['version'] + 1
172+
conflictNote.version = newVersion
173+
conflictNote.save()
174+
responses.append({"jid": form.data['jid'],
175+
"version": newVersion,
176+
"status": 201})
177+
else:
178+
responses.append({"jid": form.data['jid'], "status": 400})
179+
logevent(request, 'Note.create', 400, form.errors)
180+
pass
181+
pass
182+
pass
183+
184+
#print 'process unmodified notes'
185+
## 2) Figure out which of Client's unmodified notes has been updated on server
186+
updateFinal = [] # Server has newer version of these notes.
187+
for jid, ver in payload['unmodifiedNotes'].items():
188+
notes = [u for u in userNotes if u.jid==jid]
189+
if notes and notes[0].version > ver:
190+
note = extract_zen_notes_data(notes[0])
191+
updateFinal.append({"jid": note['jid'],
192+
"version": note['version'],
193+
"created":str(note['created']),
194+
"edited": str(note['edited']),
195+
"deleted": note['deleted'],
196+
"contents": note['noteText'],
197+
"modified": 0})
198+
pass
199+
200+
#print 'process notes only known to server'
201+
## 3) Return notes only server knows about!
202+
clientJIDs = map(lambda x:int(x['jid']), payload['modifiedNotes'])
203+
clientJIDs.extend(map(lambda x:int(x), payload['unmodifiedNotes'].keys()))
204+
serverNotes = [u for u in userNotes if u.deleted==0 and not u.jid in clientJIDs]
205+
206+
serverNotes = sort_user_for_notes(request_user, serverNotes)
207+
208+
ndicts = [ extract_zen_notes_data(note) for note in serverNotes ]
209+
210+
ndicts.reverse()
211+
212+
servNotes = [] # New notes server has & client doesn't.
213+
for note in ndicts:
214+
servNotes.append({
215+
"jid": note['jid'],
216+
"version": note['version'],
217+
"contents": note['noteText'],
218+
"deleted": note['deleted'],
219+
"created": str(note['created']),
220+
"edited": str(note['edited']),
221+
"modified": 0})
222+
pass
223+
224+
225+
#print 'Add magical note!'
226+
magicNote = {}
227+
magicalNote = [u for u in userNotes if u.jid=='-1']
228+
if magicalNote: # magical note found
229+
for key, value in magicalNote.values()[0].items():
230+
if key == 'owner_id':
231+
pass
232+
elif type(value) == Decimal:
233+
magicNote[key] = int(value)
234+
else:
235+
magicNote[key] = value
236+
pass
237+
pass
238+
239+
response = HttpResponse(
240+
JSONEncoder().encode({
241+
"committed": responses,
242+
"update": updateResponses,
243+
"updateFinal": updateFinal,
244+
"unknownNotes": servNotes,
245+
"magicNote": magicNote}),
246+
"text/json")
247+
248+
response.status_code = 200;
249+
return response
250+
251+

0 commit comments

Comments
 (0)