def log_history(payload, req): uid = UR.getUserInfo(req, True).id if uid is None: #SACHA TODO: LOG this. return UR.prepare_response({}, 1, "NOT ALLOWED") cid = UR.CID if cid == 0: return UR.prepare_response({}, 1, "CID MOST BE NONZERO") session, previous_activity = annotations.markActivity(cid) if session is None: return UR.prepare_response({}, 1, "SESSION NOT FOUND") id_session = session.id output={} if "seen" in payload and cid != 0: annotations.markCommentSeen(uid, id_session, payload["seen"]) if "page" in payload and cid != 0: annotations.markPageSeen(uid, id_session, payload["page"]) if "idle" in payload and cid != 0: annotations.markIdle(uid, id_session, payload["idle"]) if "__return" in payload and cid != 0: R = payload["__return"] if R["type"] == "newNotesOnFile": id_source = R["a"]["id_source"] if auth.canReadFile(uid, id_source): output["locations"], output["comments"] = annotations.getCommentsByFile(id_source, uid, previous_activity) return UR.prepare_response(output)
def add_youtube_doc(req, ensemble_id): import base.models as M from apiclient.discovery import build from urlparse import urlparse, parse_qs import re re_iso8601 = re.compile("PT(?:(?P<hours>\d+)H)?(?:(?P<minutes>\d+)M)?(?:(?P<seconds>\d+)S)?") youtube = build("youtube", "v3", developerKey=settings.GOOGLE_DEVELOPER_KEY) user = UR.getUserInfo(req, False) if user is None: redirect_url = "/login?next=%s" % (req.META.get("PATH_INFO","/"),) return HttpResponseRedirect(redirect_url) if not auth.canEditEnsemble(user.id, ensemble_id): return HttpResponseRedirect("/notallowed") addform = forms.YoutubeForm() if req.method == 'POST': addform = forms.YoutubeForm(req.POST) if addform.is_valid(): source = M.Source() source.numpages = 1 source.w = 0 source.h = 0 source.rotation = 0 source.version = 0 source.type = 2 source.submittedby=user source.save() ownership = M.Ownership() ownership.source = source ownership.ensemble_id = ensemble_id ownership.save() info = M.YoutubeInfo() info.source = source url = addform.cleaned_data['url'] result = urlparse(url) key = None try: # old format ,e.g. http://www.youtube.com/watch?v=Z3EAE9F2Qpo key = parse_qs(result.query)["v"][0] except KeyError: # new format, e.g. http://youtu.be/Z3EAE9F2Qpo key = result.path[1:] key = key.strip() info.key = key info.save(); ginfo = youtube.videos().list(part="id,contentDetails,snippet", id=key).execute() source.title = ginfo["items"][0]["snippet"]["title"] matches_dict = re_iso8601.match(ginfo["items"][0]["contentDetails"]["duration"]).groupdict() numsecs = 0 if matches_dict["hours"] is not None: numsecs += int(matches_dict["hours"])*3600 if matches_dict["minutes"] is not None: numsecs += int(matches_dict["minutes"])*60 if matches_dict["seconds"] is not None: numsecs += int(matches_dict["seconds"]) source.numpages = numsecs #we use 1/100 sec precision. source.save(); #addform.cleaned_data['title'] return HttpResponseRedirect("/") return render_to_response("web/add_youtube_doc.html", {"form": addform})
def add_html_doc(req, ensemble_id): import base.models as M user = UR.getUserInfo(req, False) if user is None: redirect_url = "/login?next=%s" % (req.META.get("PATH_INFO", "/"), ) return HttpResponseRedirect(redirect_url) if not auth.canEditEnsemble(user.id, ensemble_id): return HttpResponseRedirect("/notallowed") addform = forms.Html5Form() if req.method == 'POST': addform = forms.Html5Form(req.POST) if addform.is_valid(): source = M.Source() source.numpages = 1 source.w = 0 source.h = 0 source.rotation = 0 source.version = 0 source.type = 4 source.submittedby = user source.title = addform.cleaned_data['title'] source.save() ownership = M.Ownership() ownership.source = source ownership.ensemble_id = ensemble_id ownership.save() info = M.HTML5Info() info.source = source info.url = addform.cleaned_data['url'] info.save() return HttpResponseRedirect("/") return render_to_response("web/add_html_doc.html", {"form": addform})
def log_history(payload, req): uid = UR.getUserInfo(req, True).id if uid is None: #SACHA TODO: LOG this. return UR.prepare_response({}, 1, "NOT ALLOWED") cid = UR.CID if cid == 0: return UR.prepare_response({}, 1, "CID MOST BE NONZERO") session, previous_activity = annotations.markActivity(cid) if session is None: return UR.prepare_response({}, 1, "SESSION NOT FOUND") id_session = session.id output={} if "seen" in payload and cid != 0: annotations.markCommentSeen(uid, id_session, payload["seen"]) if "page" in payload and cid != 0: annotations.markPageSeen(uid, id_session, payload["page"]) if "idle" in payload and cid != 0: annotations.markIdle(uid, id_session, payload["idle"]) if "scrolling" in payload and cid != 0: logger = logging.getLogger("scrolling") logger.info("%s|%s"%(id_session, payload["scrolling"])); if "__return" in payload and cid != 0: R = payload["__return"] if R["type"] == "newNotesOnFile": id_source = R["a"]["id_source"] if auth.canReadFile(uid, id_source): output["locations"], output["html5locations"], output["comments"], output["threadmarks"] = annotations.getCommentsByFile(id_source, uid, previous_activity) elif R["type"] == "newPending": #for now, we retrieve all the pending stuff. output = annotations.getPending(uid, payload) return UR.prepare_response(output)
def add_html5video_doc(req, ensemble_id): import base.models as M user = UR.getUserInfo(req, False) if user is None: redirect_url = "/login?next=%s" % (req.META.get("PATH_INFO","/"),) return HttpResponseRedirect(redirect_url) if not auth.canEditEnsemble(user.id, ensemble_id): return HttpResponseRedirect("/notallowed") addform = forms.Html5Form() if req.method == 'POST': addform = forms.Html5Form(req.POST) if addform.is_valid(): source = M.Source() source.numpages = 1 source.w = 0 source.h = 0 source.rotation = 0 source.version = 0 source.type = 3 source.submittedby=user source.title = addform.cleaned_data['title'] source.save() ownership = M.Ownership() ownership.source = source ownership.ensemble_id = ensemble_id ownership.save() info = M.HTML5Info() info.source = source # trailing slash is sometimes added by server redirects # but person specifying upload url may not realize this # so remove trailing slash as well as hash part of the URL info.url = addform.cleaned_data['url'].partition("#")[0].rstrip("/") info.save(); return HttpResponseRedirect("/") return render_to_response("web/add_html5video_doc.html", {"form": addform})
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 __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 add_html_doc(req, ensemble_id): import base.models as M user = UR.getUserInfo(req, False) if user is None: redirect_url = "/login?next=%s" % (req.META.get("PATH_INFO","/"),) return HttpResponseRedirect(redirect_url) if not auth.canEditEnsemble(user.id, ensemble_id): return HttpResponseRedirect("/notallowed") addform = forms.Html5Form() if req.method == 'POST': addform = forms.Html5Form(req.POST) if addform.is_valid(): source = M.Source() source.numpages = 1 source.w = 0 source.h = 0 source.rotation = 0 source.version = 0 source.type = 4 source.submittedby=user source.title = addform.cleaned_data['title'] source.save() ownership = M.Ownership() ownership.source = source ownership.ensemble_id = ensemble_id ownership.save() info = M.HTML5Info() info.source = source info.url = addform.cleaned_data['url'] info.save(); return HttpResponseRedirect("/") return render_to_response("web/add_html_doc.html", {"form": addform})
def newsite(req): import base.models as M, random, string form = None auth_user = UR.getUserInfo(req) ensemble_form = None user_form = None if auth_user is not None: return HttpResponseRedirect("/admin") if req.method == 'POST': user = M.User(confkey="".join([choice(string.ascii_letters+string.digits) for i in xrange(0,32)])) ensemble = M.Ensemble() user_form = forms.UserForm(req.POST, instance=user) ensemble_form = forms.EnsembleForm(req.POST, instance=ensemble) if user_form.is_valid() and ensemble_form.is_valid(): user_form.save() ensemble.invitekey = "".join([ random.choice(string.ascii_letters+string.digits) for i in xrange(0,50)]) ensemble_form.save() m = M.Membership(user=user, ensemble=ensemble, admin=True) m.save() p = {"tutorial_url": settings.GUEST_TUTORIAL_URL, "conf_url": "http://%s?ckey=%s" %(settings.NB_SERVERNAME, user.confkey), "firstname": user.firstname, "email": user.email, "password": user.password } email = EmailMessage( "Welcome to NB, %s" % (user.firstname), render_to_string("email/confirm_newsite", p), settings.EMAIL_FROM, (user.email, ), (settings.EMAIL_BCC, )) email.send() return HttpResponseRedirect('/newsite_thanks') else: user_form = forms.UserForm() ensemble_form = forms.EnsembleForm() return render_to_response("web/newsite.html", {"user_form": user_form, "ensemble_form": ensemble_form})
def newsite(req): import base.models as M, random, string form = None auth_user = UR.getUserInfo(req) ensemble_form = None user_form = None if auth_user is not None: return HttpResponseRedirect("/") if req.method == 'POST': user = M.User(confkey="".join([choice(string.ascii_letters+string.digits) for i in xrange(0,32)])) ensemble = M.Ensemble() user_form = forms.UserForm(req.POST, instance=user) ensemble_form = forms.EnsembleForm(req.POST, instance=ensemble) if user_form.is_valid() and ensemble_form.is_valid(): user_form.save() ensemble.invitekey = "".join([ random.choice(string.ascii_letters+string.digits) for i in xrange(0,50)]) ensemble_form.save() m = M.Membership(user=user, ensemble=ensemble, admin=True) m.save() p = {"tutorial_url": settings.GUEST_TUTORIAL_URL, "conf_url": "http://%s?ckey=%s" %(settings.NB_SERVERNAME, user.confkey), "firstname": user.firstname, "email": user.email, "password": user.password } email = EmailMessage( "Welcome to NB, %s" % (user.firstname), render_to_string("email/confirm_newsite", p), settings.EMAIL_FROM, (user.email, ), (settings.EMAIL_BCC, )) email.send() return HttpResponseRedirect('/newsite_thanks') else: user_form = forms.UserForm() ensemble_form = forms.EnsembleForm() return render_to_response("web/newsite.html", {"user_form": user_form, "ensemble_form": ensemble_form})
def log_history(payload, req): uid = UR.getUserInfo(req, True).id if uid is None: #SACHA TODO: LOG this. return UR.prepare_response({}, 1, "NOT ALLOWED") cid = UR.CID if cid == 0: return UR.prepare_response({}, 1, "CID MOST BE NONZERO") session, previous_activity = annotations.markActivity(cid) if session is None: return UR.prepare_response({}, 1, "SESSION NOT FOUND") id_session = session.id output = {} if "seen" in payload and cid != 0: annotations.markCommentSeen(uid, id_session, payload["seen"]) if "page" in payload and cid != 0: annotations.markPageSeen(uid, id_session, payload["page"]) if "idle" in payload and cid != 0: annotations.markIdle(uid, id_session, payload["idle"]) if "__return" in payload and cid != 0: R = payload["__return"] if R["type"] == "newNotesOnFile": id_source = R["a"]["id_source"] if auth.canReadFile(uid, id_source): output["locations"], output[ "comments"] = annotations.getCommentsByFile( id_source, uid, previous_activity) return UR.prepare_response(output)
def on_register_session(sender, **payload): req = payload["req"] #print req.META uid = UR.getUserInfo(req, True).id p={} p["ctime"] = payload["cid"] p["ip"] = req.META["REMOTE_ADDR"] if "REMOTE_ADDR" in req.META else None annotations.register_session(uid, p)
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 subscribe(req): key = req.GET.get("key", "") e = M.Ensemble.objects.get(invitekey=key) if not e.use_invitekey: return HttpResponseRedirect("/notallowed") auth_user = UR.getUserInfo(req) user = None P = {"ensemble": e, "key": key} if req.method == 'POST': if auth_user is None: user = M.User(confkey="".join([ choice(string.ascii_letters + string.digits) for i in xrange(0, 32) ])) 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 HttpResponseRedirect('/subscribe_thanks') else: P["form"] = forms.UserForm(req.POST, instance=user) return render_to_response("web/subscribe_newuser.html", P) else: 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 HttpResponseRedirect('/') #user_form = forms.EnterYourNameUserForm(req.POST, instance=user) else: if auth_user is not None: P["user"] = auth_user P["form"] = forms.UserForm(instance=user) return render_to_response("web/subscribe_existinguser.html", P) else: P["form"] = forms.UserForm() return render_to_response("web/subscribe_newuser.html", P)
def properties_ensemble_users(req, id): user = UR.getUserInfo(req) if user is None: return HttpResponseRedirect("/login?next=%s" % (req.META.get("PATH_INFO", "/"), )) if not auth.canEditEnsemble(user.id, id): return HttpResponseRedirect("/notallowed") ensemble = M.Ensemble.objects.get(pk=id) memberships = M.Membership.objects.filter(ensemble=ensemble) real_memberships = memberships.filter( user__in=M.User.objects.filter(valid=True), deleted=False) if "action" in req.GET and "membership_id" in req.GET: if req.GET["action"] == "delete": m = real_memberships.filter(id=req.GET["membership_id"]) if len(m): m = m[0] m.deleted = True m.save() return HttpResponseRedirect(req.path) elif req.GET["action"] == "undelete": deleted_memberships = memberships.filter( user__in=M.User.objects.filter(valid=True), deleted=True) m = deleted_memberships.filter(id=req.GET["membership_id"]) if len(m): m = m[0] m.deleted = False m.save() return HttpResponseRedirect(req.path) elif req.GET["action"] == "admin": m = real_memberships.filter(id=req.GET["membership_id"]) if len(m): m = m[0] m.admin = True m.save() return HttpResponseRedirect(req.path) elif req.GET["action"] == "unadmin": m = real_memberships.filter(id=req.GET["membership_id"]) if len(m): m = m[0] m.admin = False m.save() return HttpResponseRedirect(req.path) elif req.GET["action"] == "setsection": m = real_memberships.filter(id=req.GET["membership_id"]) if req.POST["section_id"] == "None": s = None else: sections = M.Section.objects.filter(ensemble=ensemble) s = sections.filter(id=req.POST["section_id"])[0] if len(m): m = m[0] m.section = s m.save() return HttpResponseRedirect(req.path) return render_to_response("web/properties_ensemble_users.html")
def properties_ensemble_users(req, id): user = UR.getUserInfo(req) if user is None: return HttpResponseRedirect("/login?next=%s" % (req.META.get("PATH_INFO","/"),)) if not auth.canEditEnsemble(user.id, id): return HttpResponseRedirect("/notallowed") ensemble = M.Ensemble.objects.get(pk=id) sections = M.Section.objects.filter(ensemble=ensemble) memberships = M.Membership.objects.filter(ensemble=ensemble) pendingconfirmations = memberships.filter(user__in=M.User.objects.filter(valid=False), deleted=False) real_memberships = memberships.filter(user__in=M.User.objects.filter(valid=True), deleted=False) deleted_memberships = memberships.filter(user__in=M.User.objects.filter(valid=True), deleted=True) pendinginvites = M.Invite.objects.filter(ensemble=ensemble).exclude(user__id__in=real_memberships.values("user_id")) if "action" in req.GET and "membership_id" in req.GET: if req.GET["action"] == "delete": m = real_memberships.filter(id=req.GET["membership_id"]) if len(m): m = m[0] m.deleted = True m.save() return HttpResponseRedirect(req.path) elif req.GET["action"] == "undelete": m = deleted_memberships.filter(id=req.GET["membership_id"]) if len(m): m = m[0] m.deleted = False m.save() return HttpResponseRedirect(req.path) elif req.GET["action"] == "admin": m = real_memberships.filter(id=req.GET["membership_id"]) if len(m): m = m[0] m.admin = True m.save() return HttpResponseRedirect(req.path) elif req.GET["action"] == "unadmin": m = real_memberships.filter(id=req.GET["membership_id"]) if len(m): m = m[0] m.admin = False m.save() return HttpResponseRedirect(req.path) elif req.GET["action"] == "setsection": m = real_memberships.filter(id=req.GET["membership_id"]) if req.POST["section_id"] == "None": s = None else: s = sections.filter(id=req.POST["section_id"])[0] if len(m): m = m[0] m.section = s m.save() return HttpResponseRedirect(req.path) return render_to_response("web/properties_ensemble_users.html", {"ensemble": ensemble, "memberships": real_memberships, "pendinginvites": pendinginvites, "pendingconfirmations": pendingconfirmations, "deleted_memberships": deleted_memberships, "sections": sections})
def logout(req): o = {} r = __serve_page(req, 'web/static_page.html', content_type="text/html", allow_guest=True) user = UR.getUserInfo(req, False) if user is not None and user.guest: r.set_cookie("pgid", user.id, 1e9) r.delete_cookie("userinfo") r.delete_cookie("ckey") from django.contrib.auth import logout as djangologout djangologout(req) return r
def properties_ensemble_sections(req, id): user = UR.getUserInfo(req) if user is None: return HttpResponseRedirect("/login?next=%s" % (req.META.get("PATH_INFO", "/"), )) if not auth.canEditEnsemble(user.id, id): return HttpResponseRedirect("/notallowed") ensemble = M.Ensemble.objects.get(pk=id) sections = M.Section.objects.filter(ensemble=ensemble) err = "" if "action" in req.GET: if req.GET["action"] == "create" and "name" in req.POST: if M.Section.objects.filter(ensemble=ensemble, name=req.POST["name"]).exists(): err = "Could not create section: a section with the same name already exists." else: s = M.Section(name=req.POST["name"], ensemble=ensemble) s.save() return HttpResponseRedirect(req.path) elif req.GET["action"] == "delete" and "section_id" in req.GET: s = sections.filter(id=req.GET["section_id"]) if len(s): s = s[0] if (len(M.Membership.objects.filter(section=s)) > 0): err = "The section you are trying to delete is not empty." else: s.delete() return HttpResponseRedirect(req.path) else: err = "Cannot find section" elif req.GET[ "action"] == "reassign" and "membership_id" in req.POST and "section_id" in req.POST: if req.POST["section_id"] == "None": s = [None] else: s = sections.filter(id=req.POST["section_id"]) if len(s): s = s[0] m = M.Membership.objects.filter(id=req.POST["membership_id"]) if len(m): m = m[0] m.section = s m.save() else: err = "Cannot find member" else: err = "Cannot find section" else: err = "Unrecognized Command" if err or "json" in req.GET: return HttpResponse(json.dumps({"error_message": err}), content_type="application/json") else: return render_to_response("web/properties_ensemble_sections.html")
def logout(req): o = {} r = render_to_response("web/logout.html", {"o": o}) user = UR.getUserInfo(req, False) if user is not None and user.guest: r.set_cookie("pgid", user.id, 1e9) r.delete_cookie("userinfo") r.delete_cookie("ckey") from django.contrib.auth import logout as djangologout djangologout(req) return r
def properties_ensemble_users(req, id): user = UR.getUserInfo(req) if user is None: return HttpResponseRedirect("/login?next=%s" % (req.META.get("PATH_INFO","/"),)) if not auth.canEditEnsemble(user.id, id): return HttpResponseRedirect("/notallowed") ensemble = M.Ensemble.objects.get(pk=id) memberships = M.Membership.objects.filter(ensemble=ensemble) pendingconfirmations = memberships.filter(user__in=M.User.objects.filter(valid=False), deleted=False) real_memberships = memberships.filter(user__in=M.User.objects.filter(valid=True), deleted=False) pendinginvites = M.Invite.objects.filter(ensemble=ensemble).exclude(user__id__in=real_memberships.values("user_id")) return render_to_response("web/properties_ensemble_users.html", {"ensemble": ensemble, "memberships": real_memberships, "pendinginvites": pendinginvites, "pendingconfirmations": pendingconfirmations})
def properties_ensemble_sections(req, id): user = UR.getUserInfo(req) if user is None: return HttpResponseRedirect("/login?next=%s" % (req.META.get("PATH_INFO","/"),)) if not auth.canEditEnsemble(user.id, id): return HttpResponseRedirect("/notallowed") ensemble = M.Ensemble.objects.get(pk=id) sections = M.Section.objects.filter(ensemble=ensemble) all_students = M.Membership.objects.filter(ensemble=ensemble).filter(guest=False) students = {} for s in sections: students[s] = all_students.filter(section=s) no_section = all_students.filter(section=None) err = "" if "action" in req.GET: if req.GET["action"] == "create" and "name" in req.POST: if M.Section.objects.filter(ensemble=ensemble, name=req.POST["name"]).exists(): err = "Could not create section: a section with the same name already exists." else: s = M.Section(name=req.POST["name"], ensemble=ensemble) s.save() elif req.GET["action"] == "delete" and "section_id" in req.GET: s = sections.filter(id=req.GET["section_id"]) if len(s): s = s[0] if ( len(M.Membership.objects.filter(section=s)) > 0): err = "The section you are trying to delete is not empty." else: s.delete() return HttpResponseRedirect(req.path) else: err = "Cannot find section" elif req.GET["action"] == "reassign" and "membership_id" in req.POST and "section_id" in req.POST: if req.POST["section_id"] == "None": s = [None] else: s = sections.filter(id=req.POST["section_id"]); if len(s): s = s[0]; m = M.Membership.objects.filter(id=req.POST["membership_id"]) if len(m): m = m[0] m.section = s m.save() else: err = "Cannot find member" else: err = "Cannot find section" else: err = "Unrecognized Command" if "json" in req.GET: return HttpResponse(json.dumps({"error_message": err}), content_type="application/json") return render_to_response("web/properties_ensemble_sections.html", {"ensemble": ensemble, "sections": sections, "students": students, "no_section": no_section, "error_message": err })
def add_youtube_doc(req, ensemble_id): import base.models as M from apiclient.discovery import build from urlparse import urlparse, parse_qs import re re_iso8601 = re.compile("PT(?:(?P<hours>\d+)H)?(?:(?P<minutes>\d+)M)?(?:(?P<seconds>\d+)S)?") youtube = build("youtube", "v3", developerKey=settings.GOOGLE_DEVELOPER_KEY) user = UR.getUserInfo(req, False) if user is None: redirect_url = "/login?next=%s" % (req.META.get("PATH_INFO","/"),) return HttpResponseRedirect(redirect_url) if not auth.canEditEnsemble(user.id, ensemble_id): return HttpResponseRedirect("/notallowed") addform = forms.YoutubeForm() if req.method == 'POST': addform = forms.YoutubeForm(req.POST) if addform.is_valid(): source = M.Source() source.numpages = 1 source.w = 0 source.h = 0 source.rotation = 0 source.version = 0 source.type = 2 source.submittedby=user source.save() ownership = M.Ownership() ownership.source = source ownership.ensemble_id = ensemble_id ownership.save() info = M.YoutubeInfo() info.source = source url = addform.cleaned_data['url'] result = urlparse(url) key = parse_qs(result.query)["v"][0] info.key = key info.save(); ginfo = youtube.videos().list(part="id,contentDetails,snippet", id=key).execute() source.title = ginfo["items"][0]["snippet"]["title"] matches_dict = re_iso8601.match(ginfo["items"][0]["contentDetails"]["duration"]).groupdict() numsecs = 0 if matches_dict["hours"] is not None: numsecs += int(matches_dict["hours"])*3600 if matches_dict["minutes"] is not None: numsecs += int(matches_dict["minutes"])*60 if matches_dict["seconds"] is not None: numsecs += int(matches_dict["seconds"]) source.numpages = numsecs #we use 1/100 sec precision. source.save(); #addform.cleaned_data['title'] return HttpResponseRedirect("/") return render_to_response("web/add_youtube_doc.html", {"form": addform})
def enter_your_name(req): import base.models as M user = UR.getUserInfo(req, False) if user is None: redirect_url = "/login?next=%s" % (req.META.get("PATH_INFO","/"),) return HttpResponseRedirect(redirect_url) user_form = forms.EnterYourNameUserForm(instance=user) if req.method == 'POST': user_form = forms.EnterYourNameUserForm(req.POST, instance=user) if user_form.is_valid(): user_form.save() return HttpResponseRedirect("/?ckey=%s" % (user.confkey,)) return render_to_response("web/enteryourname.html", {"user_form": user_form})
def subscribe(req): key = req.GET.get("key", "") e = M.Ensemble.objects.get(invitekey=key) if not e.use_invitekey: return HttpResponseRedirect("/notallowed") auth_user = UR.getUserInfo(req) user = None P = {"ensemble": e, "key": key} if req.method == "POST": if auth_user is None: user = M.User(confkey="".join([choice(string.ascii_letters + string.digits) for i in xrange(0, 32)])) 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 HttpResponseRedirect("/subscribe_thanks") else: P["form"] = forms.UserForm(req.POST, instance=user) return render_to_response("web/subscribe_newuser.html", P) else: 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 HttpResponseRedirect("/") # user_form = forms.EnterYourNameUserForm(req.POST, instance=user) else: if auth_user is not None: P["user"] = auth_user P["form"] = forms.UserForm(instance=user) return render_to_response("web/subscribe_existinguser.html", P) else: P["form"] = forms.UserForm() return render_to_response("web/subscribe_newuser.html", P)
def properties_ensemble(req, id): user = UR.getUserInfo(req) if user is None: return HttpResponseRedirect("/login?next=%s" % (req.META.get("PATH_INFO","/"),)) if not auth.canEditEnsemble(user.id, id): return HttpResponseRedirect("/notallowed") ensemble = M.Ensemble.objects.get(pk=id) ensemble_form = None if req.method=="POST": ensemble_form = forms.EnsembleForm(req.POST, instance=ensemble) if ensemble_form.is_valid(): ensemble_form.save() return HttpResponseRedirect('/') else: return render_to_response("web/properties_ensemble.html")
def properties_ensemble(req, id): user = UR.getUserInfo(req) if user is None: return HttpResponseRedirect("/login?next=%s" % (req.META.get("PATH_INFO","/"),)) if not auth.canEditEnsemble(user.id, id): return HttpResponseRedirect("/notallowed") ensemble = M.Ensemble.objects.get(pk=id) ensemble_form = None if req.method=="POST": ensemble_form = forms.EnsembleForm(req.POST, instance=ensemble) if ensemble_form.is_valid(): ensemble_form.save() return HttpResponseRedirect('/admin') else: ensemble_form = forms.EnsembleForm(instance=ensemble) return render_to_response("web/properties_ensemble.html", {"form": ensemble_form, "conf_url": "%s://%s/subscribe?key=%s" %(settings.PROTOCOL, settings.NB_SERVERNAME, ensemble.invitekey)})
def properties_ensemble(req, id): user = UR.getUserInfo(req) if user is None: return HttpResponseRedirect("/login?next=%s" % (req.META.get("PATH_INFO","/"),)) if not auth.canEditEnsemble(user.id, id): return HttpResponseRedirect("/notallowed") ensemble = M.Ensemble.objects.get(pk=id) ensemble_form = None if req.method=="POST": ensemble_form = forms.EnsembleForm(req.POST, instance=ensemble) if ensemble_form.is_valid(): ensemble_form.save() return HttpResponseRedirect('/') else: ensemble_form = forms.EnsembleForm(instance=ensemble) return render_to_response("web/properties_ensemble.html", {"form": ensemble_form, "conf_url": "%s://%s/subscribe?key=%s" %(settings.PROTOCOL, settings.NB_SERVERNAME, ensemble.invitekey)})
def properties_ensemble(req, id): user = UR.getUserInfo(req) if user is None: return HttpResponseRedirect("/login?next=%s" % (req.META.get("PATH_INFO", "/"), )) if not auth.canEditEnsemble(user.id, id): return HttpResponseRedirect("/notallowed") ensemble = M.Ensemble.objects.get(pk=id) ensemble_form = None if req.method == "POST": ensemble_form = forms.EnsembleForm(req.POST, instance=ensemble) if ensemble_form.is_valid(): ensemble_form.save() return HttpResponseRedirect('/') else: return render_to_response("web/properties_ensemble.html")
def user_name_form(req): user = UR.getUserInfo(req, False) if user is None: redirect_url = "/login?next=%s" % (req.META.get("PATH_INFO","/"),) return HttpResponse(UR.prepare_response({"redirect": redirect_url})) remote_form = RemoteForm(forms.UserForm(instance=user)) if req.method == 'POST': user_form = forms.EnterYourNameUserForm(req.POST, instance=user) if user_form.is_valid(): user_form.save() return HttpResponse(UR.prepare_response({"redirect": "/?ckey=%s" % user.confkey})) 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({"form": remote_form.as_dict()})) else: return HttpResponse(UR.prepare_response({"form": remote_form.as_dict()}))
def newsite_form(req): import base.models as M, random, string auth_user = UR.getUserInfo(req) if auth_user is not None: return HttpResponse(UR.prepare_response({"redirect": "/"})) if req.method == 'GET': remote_user_form = RemoteForm(forms.UserForm()) remote_class_form = RemoteForm(forms.EnsembleForm()) return HttpResponse(UR.prepare_response({"user_form": remote_user_form.as_dict(), "class_form": remote_class_form.as_dict()})) else: user = M.User(confkey="".join([choice(string.ascii_letters+string.digits) for i in xrange(0,32)])) ensemble = M.Ensemble() req.POST = dict(req.POST.iteritems()) # Convert immutable object to mutable object user_form = forms.UserForm(req.POST, instance=user) ensemble_form = forms.EnsembleForm(req.POST, instance=ensemble) if user_form.is_valid() and ensemble_form.is_valid(): user_form.save() ensemble.invitekey = "".join([ random.choice(string.ascii_letters+string.digits) for i in xrange(0,50)]) ensemble_form.save() m = M.Membership(user=user, ensemble=ensemble, admin=True) m.save() p = { "tutorial_url": settings.GUEST_TUTORIAL_URL, "conf_url": "http://%s?ckey=%s" %(settings.NB_SERVERNAME, user.confkey), "firstname": user.firstname, "email": user.email } email = EmailMessage( "Welcome to NB, %s" % (user.firstname), render_to_string("email/confirm_newsite", p), settings.EMAIL_FROM, (user.email, ), (settings.EMAIL_BCC, )) email.send() return HttpResponse(UR.prepare_response({"redirect": "/newsite_thanks"})) else: # Invalid form - return form with error messages __clean_form(user_form) # Ensure user-generated data gets cleaned before sending back the form __clean_form(ensemble_form) # Ensure user-generated data gets cleaned before sending back the form remote_user_form = RemoteForm(user_form) remote_class_form = RemoteForm(ensemble_form) return HttpResponse(UR.prepare_response({"user_form": remote_user_form.as_dict(), "class_form": remote_class_form.as_dict()}))
def user_name_form(req): user = UR.getUserInfo(req, False) if user is None: redirect_url = "/login?next=%s" % (req.META.get("PATH_INFO", "/"), ) return HttpResponse(UR.prepare_response({"redirect": redirect_url})) remote_form = RemoteForm(forms.UserForm(instance=user)) if req.method == 'POST': user_form = forms.EnterYourNameUserForm(req.POST, instance=user) if user_form.is_valid(): user_form.save() return HttpResponse( UR.prepare_response({"redirect": "/?ckey=%s" % user.confkey})) 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({"form": remote_form.as_dict()})) else: return HttpResponse( UR.prepare_response({"form": remote_form.as_dict()}))
def add_html_doc(req, ensemble_id): import base.models as M user = UR.getUserInfo(req, False) if user is None: redirect_url = "/login?next=%s" % (req.META.get("PATH_INFO", "/"), ) return HttpResponseRedirect(redirect_url) if not auth.canEditEnsemble(user.id, ensemble_id): return HttpResponseRedirect("/notallowed") addform = forms.Html5Form() if req.method == 'POST': addform = forms.Html5Form(req.POST) if addform.is_valid(): source = M.Source() source.numpages = 1 source.w = 0 source.h = 0 source.rotation = 0 source.version = 0 source.type = 4 source.submittedby = user source.title = addform.cleaned_data['title'] source.save() ownership = M.Ownership() ownership.source = source ownership.ensemble_id = ensemble_id ownership.save() info = M.HTML5Info() info.source = source # trailing slash is sometimes added by server redirects # but person specifying upload url may not realize this # so remove trailing slash as well as hash part of the URL info.url = addform.cleaned_data['url'].partition("#")[0].rstrip( "/") info.save() return HttpResponseRedirect("/") return render_to_response("web/add_html_doc.html", {"form": addform})
def properties_ensemble_sections(req, id): user = UR.getUserInfo(req) if user is None: return HttpResponseRedirect("/login?next=%s" % (req.META.get("PATH_INFO", "/"), )) if not auth.canEditEnsemble(user.id, id): return HttpResponseRedirect("/notallowed") ensemble = M.Ensemble.objects.get(pk=id) sections = M.Section.objects.filter(ensemble=ensemble) err = "" if "action" in req.GET: if req.GET["action"] == "create" and "name" in req.POST: if M.Section.objects.filter(ensemble=ensemble, name=req.POST["name"]).exists(): err = "Could not create section \"%s\" because it already exists." % req.POST[ "name"] else: s = M.Section(name=req.POST["name"], ensemble=ensemble) s.save() return HttpResponseRedirect(req.path) elif req.GET["action"] == "delete" and "section_id" in req.GET: s = sections.filter(id=req.GET["section_id"]) if len(s): s = s[0] if (len(M.Membership.objects.filter(section=s)) > 0): err = "The section you are trying to delete is not empty." else: s.delete() return HttpResponseRedirect(req.path) else: err = "Cannot find section" elif req.GET[ "action"] == "reassign" and "membership_id" in req.POST and "section_id" in req.POST: if req.POST["section_id"] == "None": s = [None] else: s = sections.filter(id=req.POST["section_id"]) if len(s): s = s[0] m = M.Membership.objects.filter(id=req.POST["membership_id"]) if len(m): m = m[0] m.section = s m.save() else: err = "Cannot find member" else: err = "Cannot find section" elif req.GET["action"] == "reassign_many": json_data = json.loads(req.body) new_sections = set(json_data["new_sections"]) # Check that none of the new_sections already exist old_sections = set([ s.name for s in M.Section.objects.filter(ensemble=ensemble).all() ]) sections_intersection = old_sections.intersection(new_sections) if sections_intersection: err = "Could not create the following sections because they already exists: " + \ ", ".join(sections_intersection) return HttpResponse(json.dumps({"error_message": err}), content_type="application/json") # Check that all section names in updated_sections are valid i.e. either an existing section # or one of the new_sections. all_sections = old_sections.union(new_sections) updated_sections = json_data["updated_sections"] updated_sections_names = set( [r["section"] for r in updated_sections]) invalid_section_names = updated_sections_names.difference( all_sections) if invalid_section_names: # Under normal circumstances the code should not get here because the UI should have ensured that all # new sections are part of the new_sections field in the json data sent to the server. err = "Could not update records because students cannot be added to these sections which do not exist: " + \ ", ".join(invalid_section_names) return HttpResponse(json.dumps({"error_message": err}), content_type="application/json") # Check that all user IDs in updated_sections are valid invalid_user_id = [] for r in updated_sections: if not len(M.Membership.objects.filter(id=r["user_id"])): invalid_user_id.append(r["user_id"]) if invalid_user_id: err = "Could not update records because the following user IDs are invalid: " + \ ", ".join(invalid_user_id) return HttpResponse(json.dumps({"error_message": err}), content_type="application/json") # Create new sections for section_name in new_sections: section_object = M.Section(name=section_name, ensemble=ensemble) section_object.save() # Update students' sections for r in updated_sections: m = M.Membership.objects.filter(id=r["user_id"])[0] s = sections.filter(name=r["section"], ensemble=ensemble)[0] m.section = s m.save() else: err = "Unrecognized Command" if err or "json" in req.GET: return HttpResponse(json.dumps({"error_message": err}), content_type="application/json") else: return render_to_response("web/properties_ensemble_sections.html")
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": "/" }))
def properties_ensemble_sections(req, id): user = UR.getUserInfo(req) if user is None: return HttpResponseRedirect("/login?next=%s" % (req.META.get("PATH_INFO","/"),)) if not auth.canEditEnsemble(user.id, id): return HttpResponseRedirect("/notallowed") ensemble = M.Ensemble.objects.get(pk=id) sections = M.Section.objects.filter(ensemble=ensemble) err = "" if "action" in req.GET: if req.GET["action"] == "create" and "name" in req.POST: if M.Section.objects.filter(ensemble=ensemble, name=req.POST["name"]).exists(): err = "Could not create section \"%s\" because it already exists." % req.POST["name"] else: s = M.Section(name=req.POST["name"], ensemble=ensemble) s.save() return HttpResponseRedirect(req.path) elif req.GET["action"] == "delete" and "section_id" in req.GET: s = sections.filter(id=req.GET["section_id"]) if len(s): s = s[0] if ( len(M.Membership.objects.filter(section=s)) > 0): err = "The section you are trying to delete is not empty." else: s.delete() return HttpResponseRedirect(req.path) else: err = "Cannot find section" elif req.GET["action"] == "reassign" and "membership_id" in req.POST and "section_id" in req.POST: if req.POST["section_id"] == "None": s = [None] else: s = sections.filter(id=req.POST["section_id"]); if len(s): s = s[0]; m = M.Membership.objects.filter(id=req.POST["membership_id"]) if len(m): m = m[0] m.section = s m.save() else: err = "Cannot find member" else: err = "Cannot find section" elif req.GET["action"] == "reassign_many": json_data = json.loads(req.body) new_sections = set(json_data["new_sections"]) # Check that none of the new_sections already exist old_sections = set([s.name for s in M.Section.objects.filter(ensemble=ensemble).all()]) sections_intersection = old_sections.intersection(new_sections) if sections_intersection: err = "Could not create the following sections because they already exists: " + \ ", ".join(sections_intersection) return HttpResponse(json.dumps({"error_message": err}), content_type="application/json") # Check that all section names in updated_sections are valid i.e. either an existing section # or one of the new_sections. all_sections = old_sections.union(new_sections) updated_sections = json_data["updated_sections"] updated_sections_names = set([r["section"] for r in updated_sections]) invalid_section_names = updated_sections_names.difference(all_sections) if invalid_section_names: # Under normal circumstances the code should not get here because the UI should have ensured that all # new sections are part of the new_sections field in the json data sent to the server. err = "Could not update records because students cannot be added to these sections which do not exist: " + \ ", ".join(invalid_section_names) return HttpResponse(json.dumps({"error_message": err}), content_type="application/json") # Check that all user IDs in updated_sections are valid invalid_user_id = [] for r in updated_sections: if not len(M.Membership.objects.filter(id=r["user_id"])): invalid_user_id.append(r["user_id"]) if invalid_user_id: err = "Could not update records because the following user IDs are invalid: " + \ ", ".join(invalid_user_id) return HttpResponse(json.dumps({"error_message": err}), content_type="application/json") # Create new sections for section_name in new_sections: section_object = M.Section(name=section_name, ensemble=ensemble) section_object.save() # Update students' sections for r in updated_sections: m = M.Membership.objects.filter(id=r["user_id"])[0] s = sections.filter(name=r["section"], ensemble=ensemble)[0]; m.section = s m.save() else: err = "Unrecognized Command" if err or "json" in req.GET: return HttpResponse(json.dumps({"error_message": err}), content_type="application/json") else: return render_to_response("web/properties_ensemble_sections.html")
def newsite_form(req): import base.models as M, random, string auth_user = UR.getUserInfo(req) if auth_user is not None: return HttpResponse(UR.prepare_response({"redirect": "/"})) if req.method == 'GET': remote_user_form = RemoteForm(forms.UserForm()) remote_class_form = RemoteForm(forms.EnsembleForm()) return HttpResponse( UR.prepare_response({ "user_form": remote_user_form.as_dict(), "class_form": remote_class_form.as_dict() })) else: user = M.User(confkey="".join([ choice(string.ascii_letters + string.digits) for i in xrange(0, 32) ])) ensemble = M.Ensemble() req.POST = dict( req.POST.iteritems()) # Convert immutable object to mutable object user_form = forms.UserForm(req.POST, instance=user) ensemble_form = forms.EnsembleForm(req.POST, instance=ensemble) if user_form.is_valid() and ensemble_form.is_valid(): user_form.save() ensemble.invitekey = "".join([ random.choice(string.ascii_letters + string.digits) for i in xrange(0, 50) ]) ensemble_form.save() m = M.Membership(user=user, ensemble=ensemble, admin=True) m.save() p = { "tutorial_url": settings.GUEST_TUTORIAL_URL, "conf_url": "http://%s?ckey=%s" % (settings.NB_SERVERNAME, user.confkey), "firstname": user.firstname, "email": user.email } email = EmailMessage("Welcome to NB, %s" % (user.firstname), render_to_string("email/confirm_newsite", p), settings.EMAIL_FROM, (user.email, ), (settings.EMAIL_BCC, )) email.send() return HttpResponse( UR.prepare_response({"redirect": "/newsite_thanks"})) else: # Invalid form - return form with error messages __clean_form( user_form ) # Ensure user-generated data gets cleaned before sending back the form __clean_form( ensemble_form ) # Ensure user-generated data gets cleaned before sending back the form remote_user_form = RemoteForm(user_form) remote_class_form = RemoteForm(ensemble_form) return HttpResponse( UR.prepare_response({ "user_form": remote_user_form.as_dict(), "class_form": remote_class_form.as_dict() }))