def getHTML5Info(payload, req): if "url" not in payload: return UR.prepare_response({}, 1, "missing url !") url = payload["url"].partition("#")[0].rstrip("/") # remove hash part of the URL by default, as well as trailing slash. #TODO: use optional argument id_ensemble to disambiguate if provided. sources_info = M.HTML5Info.objects.filter(url=url) ownerships = M.Ownership.objects.select_related("source", "ensemble", "folder").filter(source__html5info__in=sources_info, deleted=False) #TODO: with django 1.9, you can use Q objects to OR two conditions #so instead of iterating to test below, just add .filter(Q(ensemble__memberships__user=UR.getUserId(req)) | Q(ensemble.allow_guest)) #then use UR.qs2dict as was done previously if not ownerships.exists(): return UR.prepare_response({}, 1, "this URL is not recognized: ") output = { "files": {}, "ensembles": {}, "folders": {} } for r in ownerships: if (r.ensemble.allow_guest or auth.isMember(UR.getUserId(req),r.ensemble_id)): output["ensembles"][r.ensemble_id]=UR.model2dict(r,annotations.__NAMES["ensembles2"]) output["files"][r.source_id]=UR.model2dict(r,annotations.__NAMES["files2"]) output["folders"][r.folder_id]=UR.model2dict(r,annotations.__NAMES["folders2"]) if (output["ensembles"]): return UR.prepare_response(output) else: return UR.prepare_response({}, 1, "not allowed: guest access isn't allowed for this file.")
def getHTML5Info(payload, req): if "url" not in payload: return UR.prepare_response({}, 1, "missing url !") url = payload["url"].partition("#")[0].rstrip( "/" ) # remove hash part of the URL by default, as well as trailing slash. #TODO: use optional argument id_ensemble to disambiguate if provided. sources_info = M.HTML5Info.objects.filter(url=url) ownerships = M.Ownership.objects.select_related( "source", "ensemble", "folder").filter(source__html5info__in=sources_info, deleted=False) #TODO: with django 1.9, you can use Q objects to OR two conditions #so instead of iterating to test below, just add .filter(Q(ensemble__memberships__user=UR.getUserId(req)) | Q(ensemble.allow_guest)) #then use UR.qs2dict as was done previously if not ownerships.exists(): return UR.prepare_response({}, 1, "this URL is not recognized: ") output = {"files": {}, "ensembles": {}, "folders": {}} for r in ownerships: if (r.ensemble.allow_guest or auth.isMember(UR.getUserId(req), r.ensemble_id)): output["ensembles"][r.ensemble_id] = UR.model2dict( r, annotations.__NAMES["ensembles2"]) output["files"][r.source_id] = UR.model2dict( r, annotations.__NAMES["files2"]) output["folders"][r.folder_id] = UR.model2dict( r, annotations.__NAMES["folders2"]) if (output["ensembles"]): return UR.prepare_response(output) else: return UR.prepare_response( {}, 1, "not allowed: guest access isn't allowed for this file.")
def subscribe_with_key(req): key = req.GET.get("key", "") if not key: return HttpResponse(UR.prepare_response({}, 1, "NOT ALLOWED")) e = M.Ensemble.objects.get(invitekey=key) if not e.use_invitekey: return HttpResponse(UR.prepare_response({}, 1, "NOT ALLOWED")) auth_user = UR.getUserInfo(req) if req.method == 'GET': if auth_user is None: # Guest retrieving the subscribe page remote_form = RemoteForm(forms.UserForm()) return HttpResponse(UR.prepare_response({"new_user": True, "class_settings": UR.model2dict(e), "form": remote_form.as_dict()})) else: # Logged in user retrieving the subscribe page user = auth_user remote_form = RemoteForm(forms.UserForm(instance=user)) m = M.Membership.objects.filter(user=user, ensemble=e) if m.count() ==0: m = M.Membership(user=user, ensemble=e) m.save() return HttpResponse(UR.prepare_response({"new_user": False, "user": UR.model2dict(user), "class_settings": UR.model2dict(e), "form": remote_form.as_dict()})) else: # POST requests if auth_user is None: # Guest subscribing to a class user = M.User(confkey="".join([choice(string.ascii_letters+string.digits) for i in xrange(0,32)])) req.POST = dict(req.POST.iteritems()) # Convert immutable object to mutable object user_form = forms.UserForm(req.POST, instance=user) if user_form.is_valid(): user_form.save() m = M.Membership(user=user, ensemble=e) m.save() # membership exists but user is still invalid until has confirmed their email p = { "tutorial_url": settings.GUEST_TUTORIAL_URL, "conf_url": "%s://%s/?ckey=%s" %(settings.PROTOCOL, settings.NB_SERVERNAME, user.confkey), "firstname": user.firstname, "email": user.email } email = EmailMessage( "Welcome to NB, %s" % (user.firstname,), render_to_string("email/confirm_subscribe", p), settings.EMAIL_FROM, (user.email, ), (settings.EMAIL_BCC, )) email.send() return HttpResponse(UR.prepare_response({"new_user": True, "class_settings": UR.model2dict(e), "next": "/subscribe_thanks"})) else: # Invalid form - return form with error messages __clean_form(user_form) # Ensure user-generated data gets cleaned before sending back the form remote_form = RemoteForm(user_form) return HttpResponse(UR.prepare_response({"new_user": True, "user": UR.model2dict(user), "class_settings": UR.model2dict(e), "form": remote_form.as_dict()})) else: # Logged in user subscribing to a class user = auth_user m = M.Membership.objects.filter(user=user, ensemble=e) if m.count() ==0: m = M.Membership(user=user, ensemble=e) m.save() return HttpResponse(UR.prepare_response({"new_user": False, "class_settings": UR.model2dict(e), "next": "/"}))
def set_comment_label(P, req): uid = UR.getUserId(req) cid = P["comment_id"] if not auth.canLabelComment(uid, cid): return UR.prepare_response({}, 1, "NOT ALLOWED") record = None try: record = M.CommentLabel.objects.get(grader__id=uid, comment__id=cid, category_id=P["category_id"]) rh = M.CommentLabelHistory() rh.grader = record.grader rh.ctime = record.ctime rh.grade = record.grade rh.category = record.category rh.comment = record.comment rh.save() record.ctime = datetime.datetime.now() except M.CommentLabel.DoesNotExist: record = M.CommentLabel() record.category_id = P["category_id"] record.comment_id = cid record.grade = P["grade"] record.grader_id = uid record.save() retval = {"commentlabels":{record.id: UR.model2dict(record)}} return UR.prepare_response(retval)
def __serve_page_with_vars(req, tpl, o, allow_guest=False, nologin_url=None, content_type=None): """Serve the template 'tpl' if user is in DB or allow_guest is True. If not, serve the welcome/login screen""" user = UR.getUserInfo(req, allow_guest, __extra_confkey_getter) if user is None: redirect_url = nologin_url if nologin_url is not None else ( "/login?next=%s" % (req.META.get("PATH_INFO", "/"), )) return HttpResponseRedirect(redirect_url) if user.guest is False and (user.firstname is None or user.lastname is None): return HttpResponseRedirect("/enteryourname?ckey=%s" % (user.confkey, )) user = UR.model2dict( user, { "ckey": "confkey", "email": None, "firstname": None, "guest": None, "id": None, "lastname": None, "password": None, "valid": None }) signals.page_served.send("page", req=req, uid=user["id"]) r = render_to_response( tpl, o, content_type=('application/xhtml+xml' if content_type is None else content_type)) r.set_cookie("userinfo", urllib.quote(json.dumps(user)), 1e6) return r
def saveNote(payload, req): uid = UR.getUserId(req) if not auth.canAnnotate(uid, payload["id_ensemble"]): return UR.prepare_response({}, 1, "NOT ALLOWED") payload["id_author"] = uid retval = {} a = annotations.addNote(payload) if len(a) == 0: return UR.prepare_response({}, 2, "DUPLICATE") tms = {} for mark in payload["marks"]: tm = M.ThreadMark() m_types = [c[0] for c in tm.TYPES if c[1] == mark] if len( m_types ): #old clients may return types we don't have in DB so ignore them tm.type = m_types[0] tm.user_id = uid tm.comment = a[0] tm.location_id = tm.comment.location_id tm.save() tms[tm.id] = UR.model2dict(tm) retval["locations"], html5 = annotations.getLocation(a[0].location_id) if (html5 is not None): retval["html5locations"] = html5 retval["comments"] = {} retval["tags"] = {} for annotation in a: retval["comments"].update(annotations.getComment(annotation.id, uid)) retval["tags"].update(annotations.getTagsByComment(annotation.id)) retval["threadmarks"] = tms return UR.prepare_response(retval)
def saveNote(payload, req): uid = UR.getUserId(req) if not auth.canAnnotate(uid, payload["id_ensemble"]): return UR.prepare_response({}, 1, "NOT ALLOWED") payload["id_author"] = uid retval = {} a = annotations.addNote(payload) if len(a) == 0: return UR.prepare_response({}, 2, "DUPLICATE") tms = {} for mark in payload["marks"]: tm = M.ThreadMark() m_types = [c[0] for c in tm.TYPES if c[1]==mark] if len(m_types): #old clients may return types we don't have in DB so ignore them tm.type = m_types[0] tm.user_id = uid tm.comment=a[0] tm.location_id=tm.comment.location_id tm.save() tms[tm.id] = UR.model2dict(tm) retval["locations"], html5 = annotations.getLocation(a[0].location_id) if (html5 is not None): retval["html5locations"]=html5 retval["comments"] = {} retval["tags"] = {} for annotation in a: retval["comments"].update(annotations.getComment(annotation.id, uid)) retval["tags"].update(annotations.getTagsByComment(annotation.id)) retval["threadmarks"] = tms return UR.prepare_response(retval)
def __serve_page_with_vars(req, tpl, o, allow_guest=False, nologin_url=None, content_type=None): """Serve the template 'tpl' if user is in DB or allow_guest is True. If not, serve the welcome/login screen""" user = UR.getUserInfo(req, allow_guest, __extra_confkey_getter) if user is None: redirect_url = ( nologin_url if nologin_url is not None else ("/login?next=%s" % (req.META.get("PATH_INFO", "/"),)) ) return HttpResponseRedirect(redirect_url) if user.guest is False and (user.firstname is None or user.lastname is None): return HttpResponseRedirect("/enteryourname?ckey=%s" % (user.confkey,)) user = UR.model2dict( user, { "ckey": "confkey", "email": None, "firstname": None, "guest": None, "id": None, "lastname": None, "password": None, "valid": None, }, ) signals.page_served.send("page", req=req, uid=user["id"]) r = render_to_response(tpl, o, content_type=("application/xhtml+xml" if content_type is None else content_type)) r.set_cookie("userinfo", urllib.quote(json.dumps(user)), 1e6) return r
def rate_reply(P,req): uid = UR.getUserId(req); status = P["status"] tm = M.ThreadMark.objects.get(pk=P["threadmark_id"]) previous_accepted_ratings = M.ReplyRating.objects.filter(threadmark=tm, status__gt=M.ReplyRating.TYPE_UNRESOLVED) if tm.user_id == uid: rr = M.ReplyRating() rr.status = status rr.threadmark = tm rr.comment_id = P["comment_id"] rr.save() if status: tm.active = status==M.ReplyRating.TYPE_UNRESOLVED and previous_accepted_ratings.count()==0 tm.save() return UR.prepare_response({"replyrating": {rr.id: UR.model2dict(rr)}}) return UR.prepare_response({}, 1, "NOT ALLOWED")
def source_analytics(req, n): pages, chart_stats = doc_analytics.get_page_stats(n) highlights = doc_analytics.get_highlights(n) source = M.Source.objects.get(pk=n) var_dict = { 'source': source, 'pages': pages, 'chart_stats': chart_stats, 'highlights': highlights, 'numpages': source.numpages } return HttpResponse(UR.prepare_response({"source": UR.model2dict(source), "pages": pages, "chart_stats": chart_stats, "highlights": highlights, "numpages": source.numpages}))
def source_analytics(req, n): pages, chart_stats = doc_analytics.get_page_stats(n) highlights = doc_analytics.get_highlights(n) source = M.Source.objects.get(pk=n) var_dict = { 'source': source, 'pages': pages, 'chart_stats': chart_stats, 'highlights': highlights, 'numpages': source.numpages } return HttpResponse( UR.prepare_response({ "source": UR.model2dict(source), "pages": pages, "chart_stats": chart_stats, "highlights": highlights, "numpages": source.numpages }))
def saveNote(payload, req): uid = UR.getUserId(req) if not auth.canAnnotate(uid, payload["id_ensemble"]): return UR.prepare_response({}, 1, "NOT ALLOWED") payload["id_author"] = uid retval = {} a = annotations.addNote(payload) tms = {} for mark in payload["marks"]: tm = M.ThreadMark() m_types = [c[0] for c in tm.TYPES if c[1]==mark] if len(m_types): #old clients may return types we don't have in DB so ignore them tm.type = m_types[0] tm.user_id = uid tm.comment=a tm.location_id=a.location_id tm.save() tms[tm.id] = UR.model2dict(tm) retval["locations"] = annotations.getLocation(a.location_id) retval["comments"] = annotations.getComment(a.id, uid) retval["threadmarks"] = tms return UR.prepare_response(retval)
def subscribe_with_key(req): key = req.GET.get("key", "") if not key: return HttpResponse(UR.prepare_response({}, 1, "NOT ALLOWED")) try: e = M.Ensemble.objects.get(invitekey=key) except ObjectDoesNotExist: return HttpResponse(UR.prepare_response({}, 1, "NOT ALLOWED")) if not e.use_invitekey: return HttpResponse(UR.prepare_response({}, 1, "NOT ALLOWED")) auth_user = UR.getUserInfo(req) if req.method == 'GET': if auth_user is None: # Guest retrieving the subscribe page remote_form = RemoteForm(forms.UserForm()) return HttpResponse( UR.prepare_response({ "new_user": True, "class_settings": UR.model2dict(e), "form": remote_form.as_dict() })) else: # Logged in user retrieving the subscribe page user = auth_user remote_form = RemoteForm(forms.UserForm(instance=user)) m = M.Membership.objects.filter(user=user, ensemble=e) if m.count() == 0: m = M.Membership(user=user, ensemble=e) m.save() return HttpResponse( UR.prepare_response({ "new_user": False, "user": UR.model2dict(user), "class_settings": UR.model2dict(e), "form": remote_form.as_dict() })) else: # POST requests if auth_user is None: # Guest subscribing to a class user = M.User(confkey="".join([ choice(string.ascii_letters + string.digits) for i in xrange(0, 32) ])) req.POST = dict(req.POST.iteritems() ) # Convert immutable object to mutable object user_form = forms.UserForm(req.POST, instance=user) if user_form.is_valid(): user_form.save() m = M.Membership(user=user, ensemble=e) m.save( ) # membership exists but user is still invalid until has confirmed their email p = { "tutorial_url": settings.GUEST_TUTORIAL_URL, "conf_url": "%s://%s/?ckey=%s" % (settings.PROTOCOL, settings.NB_SERVERNAME, user.confkey), "firstname": user.firstname, "email": user.email } email = EmailMessage( "Welcome to NB, %s" % (user.firstname, ), render_to_string("email/confirm_subscribe", p), settings.EMAIL_FROM, (user.email, ), (settings.EMAIL_BCC, )) email.send() return HttpResponse( UR.prepare_response({ "new_user": True, "class_settings": UR.model2dict(e), "next": "/subscribe_thanks" })) else: # Invalid form - return form with error messages __clean_form( user_form ) # Ensure user-generated data gets cleaned before sending back the form remote_form = RemoteForm(user_form) return HttpResponse( UR.prepare_response({ "new_user": True, "user": UR.model2dict(user), "class_settings": UR.model2dict(e), "form": remote_form.as_dict() })) else: # Logged in user subscribing to a class user = auth_user m = M.Membership.objects.filter(user=user, ensemble=e) if m.count() == 0: m = M.Membership(user=user, ensemble=e) m.save() return HttpResponse( UR.prepare_response({ "new_user": False, "class_settings": UR.model2dict(e), "next": "/" }))