Esempio n. 1
0
def list_badges(request):
    badge_list = Badge.objects.all()
    for b in badge_list:
        try: b.check = True if b.held_by( Student.from_request(request) ) else False
        except exceptions.ObjectDoesNotExist: b.check = False
    
    return render( request, "badge_list.html", {"badge_list":badge_list} )
Esempio n. 2
0
def view_feedback(request, name):
    me = Student.from_request(request)
    
    # First, try to get the challenge.
    try: challenge = Challenge.objects.get(slug=name)
    except exceptions.ObjectDoesNotExist: raise Http404()
    
    # Now get all of the SOSses related to this user and challenge.
    feedback = SOS.objects.filter(challenge=challenge, student=me)
    
    # Mark feedback as helpful or not.
    if "helpful" in request.GET or "unhelpful" in request.GET:
        helpful = True
        if "unhelpful" in request.GET: helpful = False
        f_id = request.GET["helpful" if helpful else "unhelpful"]
        if f_id.isdigit():
            try:
                f = Feedback.objects.get(id=int(f_id))
                if f.sos in feedback and f.helpful is None:
                    f.helpful = helpful
                    f.save()
                    LogEntry.log(request, "Marked as %shelpful"%("" if helpful else "un"))
            except exceptions.ObjectDoesNotExist:
                LogEntry.log(request, "Feedback voting naughtiness.")
    
    return render(request, "feedback.html", {'challenge': challenge,
                                             'feedback': feedback})
Esempio n. 3
0
def view_feedback(request, name):
    me = Student.from_request(request)
    if "alerts" not in request.session: request.session["alerts"] = []
    if not me:
        request.session["alerts"].append(("alert-error","Please sign in first."))
        return redirect("sign-in")   
    
    # First, try to get the challenge.
    try: challenge = Challenge.objects.get(slug=name)
    except exceptions.ObjectDoesNotExist: raise Http404()
    
    # Now get all of the SOSses related to this user and challenge.
    feedback = SOS.objects.filter(challenge=challenge, student=me)
    
    # Mark feedback as helpful or not.
    if "helpful" in request.GET or "unhelpful" in request.GET:
        helpful = True
        if "unhelpful" in request.GET: helpful = False
        f_id = request.GET["helpful" if helpful else "unhelpful"]
        if f_id.isdigit():
            f = Feedback.objects.get(id=int(f_id))
            if f.sos in feedback and f.helpful is None:
                f.helpful = helpful
                f.save()
                if helpful:
                    f.author.award_xp(50)
                me.award_xp(5)
                LogEntry.log(request, "Marked as %shelpful"%("" if helpful else "un"))

    
    return render(request, "feedback.html", {'challenge': challenge,
                                             'feedback': feedback})
Esempio n. 4
0
def user_profile(request, username):
    me = Student.from_request(request)
    if "alerts" not in request.session: request.session["alerts"] = []
    if not me:
        request.session["alerts"].append(("alert-error","Please sign in first."))
        return redirect("sign-in")
    try: student = Student.objects.get( user=User.objects.get(username=username) )
    except: return redirect("user_list")
    
    # If we are doing a POST, then let's affect the output a bit.
    form = ProfileEditForm( {"bio": me.bio, "twitter": me.twitter, "email": me.public_email} )
    if request.method == "POST":
        form = ProfileEditForm(request.POST)
        if form.is_valid():
            data = form.cleaned_data
            me.bio = data["bio"]
            me.public_email = data["email"]
            me.twitter = data["twitter"]
            me.save()
            return redirect( "profile", username=me.username )
        else:
            request.session["alerts"].append(("alert-error",
                                              "There were some issues with your profile update."))
            for e in form.non_field_errors():
                alerts.append( ("alert-error", e ) )
    
    # Render the magic.
    projects = list(me.owns.all())+list(me.works_on.all())
    return render(request, "user_profile.html", {"student": student,
                                                 "collaborators": student.collaborators(),
                                                 "projects": projects,
                                                 "form": form,
                                                 'alerts': request.session.pop('alerts', []) } )
Esempio n. 5
0
def view_board(request, category):
    me = Student.from_request(request)
    
    # First, try to get the board.
    try: board = DiscussionBoard.objects.get(slug=category)
    except exceptions.ObjectDoesNotExist: raise Http404()
    if not board.can_read(me): raise Http404()
    
    # Get the page number!
    page = 0
    pagination = 50
    if "page" in request.GET and request.GET["page"].isdigit():
        page = max(0,int(request.GET["page"])-1)
    
    # If this is a POST, we are creating a new topic. Redirect when finished.
    if request.method == "POST":
        if board.can_write(me):
            content = str(request.POST.get("content"))
            title = content[:100]+"..."
            if "title" in request.POST:
                title = request.POST["title"]
            
            t = DiscussionTopic()
            t.author = me
            t.board = board
            t.title = title
            t.save()
            
            p = DiscussionPost()
            p.topic = t
            p.author = me
            p.content = content
            p.save()
        
            return redirect( "thread", category=board.slug, thread=t.id )
        else:
            return redirect( "board", category=board.slug )
    
    # Get all of the topics, along with the last person who commented on them
    # and when that was.
    topic_tuples = []
    topics = DiscussionTopic.objects.filter(board=board)
    if not me.ta:
        topics = topics.filter(hidden=False)
    for t in topics[pagination*page:pagination*(page+1)]:
        posts = DiscussionPost.objects.filter(topic=t, hidden=False).order_by("-timestamp")
        count = len(posts)
        new = False
        if count == 0: posts = [None]
        else: new = ( posts[0].timestamp > me.unread_since )
        topic_tuples.append( (t,count,posts[0],new) )
    
    return render( request, "forum_topics.html", {'board': board,
                                                  'topics': topic_tuples,
                                                  'alerts': request.session.pop('alerts', []),
                                                  'page': page+1,
                                                  'pages': (len(topic_tuples)/pagination)+1,
                                                  'can_write': board.can_write(me) } )
Esempio n. 6
0
def view_board(request, name):
    me = Student.from_request(request)
    if "alerts" not in request.session: request.session["alerts"] = []
    if not me:
        request.session["alerts"].append(("alert-error","Please sign in first."))
        return redirect("sign-in")   
    
    # First, try to get the board.
    try: board = DiscussionBoard.objects.get(slug=name)
    except exceptions.ObjectDoesNotExist: raise Http404()
    if board.restricted > me.level: raise Http404()
    
    # Get the page number!
    page = 0
    pagination = 200
    if "page" in request.GET and request.GET["page"].isdigit():
        page = max(0,int(request.GET["page"])-1)
    
    # If this is a POST, we are creating a new topic. Redirect when finished.
    if request.method == "POST" and (me.level >= board.wrestricted or me.ta):
        content = str(request.POST.get("content"))
        title = content[:100]+"..."
        if "title" in request.POST:
            title = request.POST["title"]
        
        t = DiscussionTopic()
        t.author = me
        t.board = board
        t.title = title
        t.save()
        
        p = DiscussionPost()
        p.topic = t
        p.author = me
        p.content = content
        p.save()
        
        return redirect( "thread", name=board.slug, thread=t.id )
    
    # Get all of the topics, along with the last person who commented on them
    # and when that was.
    topic_tuples = []
    for t in DiscussionTopic.objects.filter(hidden=False, board=board)[pagination*page:pagination*(page+1)]:
        posts = DiscussionPost.objects.filter(topic=t, hidden=False).order_by("-timestamp")
        count = len(posts)
        new = False
        if count == 0: posts = [None]
        else: new = ( posts[0].timestamp > me.last_login )
        topic_tuples.append( (t,count,posts[0],new) )
    
    return render( request, "forum_topics.html", {'board': board,
                                                  'topics': topic_tuples,
                                                  'student': me,
                                                  'alerts': request.session.pop('alerts', []),
                                                  'page': page+1,
                                                  'pages': (len(topic_tuples)/pagination)+1 } )
Esempio n. 7
0
def handle_login(request):
    me = Student.from_request(request)
    
    if me:
        request.session["alerts"].append(("alert-error","You are already logged in!"))
        return redirect("index")
    request.session["secret_state"] = str(random.randint(100000000,999999999))
    
    return redirect("https://github.com/login/oauth/authorize?client_id=%s&state=%s&scope=user:email"%
                    (settings.GITHUB_ID, request.session["secret_state"]))
Esempio n. 8
0
def view_thread(request, name, thread):
    me = Student.from_request(request)
    if "alerts" not in request.session: request.session["alerts"] = []
    if not me:
        request.session["alerts"].append(("alert-error","Please sign in first."))
        return redirect("sign-in")   
    
    # First, try to get the challenge, then thread.
    try:
        board = DiscussionBoard.objects.get(slug=name)
        topic = DiscussionTopic.objects.get(id=thread, board=board)
    except exceptions.ObjectDoesNotExist: raise Http404()
    if not me.ta and (topic.hidden or board.restricted > me.level): raise Http404()
    
    # If this is a POST, we are either replying to someone or we are voting.
    # Manage permissions respectively and redirect.
    if request.method == "POST":
        if "thread" in request.POST and (me.level >= board.wrestricted or me.ta):
            p = DiscussionPost()
            p.topic = topic
            p.author = me
            p.content = str(request.POST.get("content"))
            p.save()
            topic.save()
        elif "upvote" in request.POST or "downvote" in request.POST:
            upvote = True
            if "downvote" in request.POST: upvote = False
            p_id = request.POST["upvote" if upvote else "downvote"]
            if p_id.isdigit() and (me.modpoints > 0 or me.ta):
                p = DiscussionPost.objects.get(id=int(p_id))
                if upvote: p.upvotes += 1
                else:      p.downvotes += 1
                request.session["alerts"].append(("alert-success","Post %s."%("upvoted" if upvote else "downvoted")))
                LogEntry.log(request, "Thread %s"%("upvoted" if upvote else "downvoted"))
                p.save()
                me.modpoints -= 1
                me.award_xp(1)
                me.save()
        return redirect( "thread", name=board.slug, thread=topic.id )
    
    # Get all of the posts. Start on the last page by default.
    pagination = 20
    posts = DiscussionPost.objects.filter(hidden=False, topic=topic)
    pages = (len(posts)/pagination)+1
    page = pages-1
    if "page" in request.GET and request.GET["page"].isdigit():
        page = max(0,int(request.GET["page"])-1)
    
    return render( request, "forum_thread.html", {'board': board,
                                                  'topic': topic,
                                                  'student': me,
                                                  'posts': posts[pagination*page:pagination*(page+1)],
                                                  'alerts': request.session.pop('alerts', []),
                                                  'page': page+1,
                                                  'pages': pages })
Esempio n. 9
0
def handle_logout(request):
    me = Student.from_request(request)

    if me:
        logout(request)
        if "alerts" not in request.session: request.session["alerts"] = []
        request.session["alerts"].append(("alert-success","Successfully logged out - come back soon!"))
        return redirect("index") 
    else:
        request.session["alerts"].append(("alert-error","You're already logged out!"))
        return redirect("index") 
Esempio n. 10
0
def view_stage(request, world, stage):
    try: student = Student.from_request(request)
    except exceptions.ObjectDoesNotExist: return HttpResponse("Redirect to login")
    
    here = get_stage(world, stage)
    go = "lesson"
    # if in challenge-first group: go = "challenge"
    
    # If there is only one choice, then go to that one.
    if not here.lesson and here.challenge: go = "challenge"
    if not here.challenge and here.lesson: go = "lesson"
    return redirect( go, world = world, stage = stage )
Esempio n. 11
0
def view_lesson(request, world, stage):
    try: student = Student.from_request(request)
    except exceptions.ObjectDoesNotExist: return HttpResponse("Redirect to login")
    
    here = get_stage(world, stage)
    if not here.lesson:
        if here.challenge: return redirect( "challenge", world = world, stage = stage )
        else: raise Http404()
        
    #TODO log this as read.
    return render( request, "lessons_lesson.html", {'world': here.world,
                                                    'stage': here } )
Esempio n. 12
0
def view_thread(request, category, thread):
    me = Student.from_request(request)
    
    # First, try to get the challenge, then thread.
    try:
        board = DiscussionBoard.objects.get(slug=category)
        topic = DiscussionTopic.objects.get(id=thread, board=board)
    except exceptions.ObjectDoesNotExist: raise Http404()
    if not board.can_read(me): raise Http404()
    
    
    # If this is a POST, we are either replying to someone or we are voting.
    # Manage permissions respectively and redirect.
    if request.method == "POST":
        if "hide" in request.POST and me.ta:
            try:
                p = DiscussionPost.objects.get(id=int(request.POST["hide"]))
                p.hidden = not p.hidden
                p.save()
            except: pass
        elif "topic" in request.POST and me.ta:
            if "lock" == request.POST.get("topic"):
                topic.locked = not topic.locked
            if "hide" == request.POST.get("topic"):
                topic.hidden = not topic.hidden
            topic.save()
        elif "content" in request.POST and board.can_write(me) and (not topic.locked):
            p = DiscussionPost()
            p.topic = topic
            p.author = me
            p.content = str(request.POST.get("content"))
            p.save()
            topic.save()
        return redirect( "thread", category=board.slug, thread=topic.id )
    
    # Get all of the posts. Start on the last page by default.
    pagination = 20
    posts = DiscussionPost.objects.filter(topic=topic)
    if not me.ta:
        post = posts.filter(hidden=False)
    pages = (len(posts)/pagination)+1
    page = pages-1
    if "page" in request.GET and request.GET["page"].isdigit():
        page = max(0,int(request.GET["page"])-1)
    
    return render( request, "forum_thread.html", {'board': board,
                                                  'topic': topic,
                                                  'posts': posts[pagination*page:pagination*(page+1)],
                                                  'alerts': request.session.pop('alerts', []),
                                                  'page': page+1,
                                                  'pages': pages,
                                                  'can_write': board.can_write(me) })
Esempio n. 13
0
def create_demo_user(request):
    me = Student.from_request(request)
    if not settings.DEMO_MODE:
        request.session["alerts"].append(("alert-error","Demo users are not enabled at this time."))
        return redirect("index")
    
    username = "******"%len(Student.objects.all())
    user = User.objects.create_user(username, username+"@example.com", str(random.randint(100000000,999999999)))
    user.save()
    student = Student(user=user)
    student.save()
    user.backend = 'django.contrib.auth.backends.ModelBackend'
    login(request, user)
    return redirect("index")
Esempio n. 14
0
def sign_out(request):
    me = Student.from_request(request)
    if "alerts" not in request.session: request.session["alerts"] = []
    
    if me:
        logout(request)
        if "alerts" not in request.session: request.session["alerts"] = []
        request.session["alerts"].append( ("alert-success",
                                           "You have successfully signed out.") )
        return redirect("index")
    else:
        request.session["alerts"].append( ("alert-success",
                                           "You are already signed out.") )
        return redirect("sign-in")
Esempio n. 15
0
def project_list(request):
    me = Student.from_request(request)
    if "alerts" not in request.session: request.session["alerts"] = []
    if not me:
        request.session["alerts"].append(
            ("alert-error", "Please sign in first."))
        return redirect("sign-in")

    # Retrieve GET parameters.
    filt = request.GET.get("filter")
    page = request.GET.get("page")
    if page and page.isdigit(): page = max(0, int(page) - 1)
    else: page = 0
    pagination = 50

    # If we get a POST request, we create a new project.
    if request.method == "POST":
        name = str(request.POST.get("name"))
        if len(Project.objects.filter(name="name")) > 0:
            request.session["alerts"].append(
                ("alert-error", """A project with that name already
                                              exists. Please choose a different
                                              name."""))
            return redirect("project_list")
        else:
            p = Project()
            p.name = name
            p.owner = me
            p.save()
            return redirect("project", id=p.id)

    # Filter the project list based on the GET filter parameter.
    project_list = []
    if filt == "watch": project_list = list(me.watches.all())
    elif filt == "all": project_list = list(Project.objects.all())
    else:
        project_list = list(me.owns.all()) + list(me.works_on.all())
        filt = "mine"
    project_list = project_list[page * pagination:(page + 1) * pagination]

    # TODO: Create the spotlight.

    return render(
        request, "project_list.html", {
            'projects': project_list,
            'alerts': request.session.pop('alerts', []),
            'page': page + 1,
            'pages': (len(project_list) / pagination) + 1,
            'filter': filt
        })
Esempio n. 16
0
def project_list(request):
    me = Student.from_request(request)
    if "alerts" not in request.session: request.session["alerts"] = []
    if not me:
        request.session["alerts"].append(("alert-error","Please sign in first."))
        return redirect("sign-in")   
    
    # Retrieve GET parameters.
    filt = request.GET.get("filter")
    page = request.GET.get("page")
    if page and page.isdigit(): page = max(0, int(page)-1)
    else: page = 0
    pagination = 50
    
    # If we get a POST request, we create a new project.
    if request.method == "POST":
        name = str(request.POST.get("name"))
        if len(Project.objects.filter(name="name")) > 0:
            request.session["alerts"].append(("alert-error",
                                              """A project with that name already
                                              exists. Please choose a different
                                              name."""))
            return redirect("project_list")
        else:
            p = Project()
            p.name = name
            p.owner = me
            p.save()
            return redirect("project", id=p.id)
    
    # Filter the project list based on the GET filter parameter.
    project_list = []
    if filt == "watch": project_list = list(me.watches.all())
    elif filt == "all": project_list = list(Project.objects.all())
    else:
        project_list = list(me.owns.all()) + list(me.works_on.all())
        filt = "mine"
    project_list = project_list[page*pagination:(page+1)*pagination]
    
    # TODO: Create the spotlight.
    
    
    return render( request, "project_list.html", {'projects':project_list,
                                                  'alerts': request.session.pop('alerts', []),
                                                  'page': page+1,
                                                  'pages': (len(project_list)/pagination)+1,
                                                  'filter': filt } )
Esempio n. 17
0
def view_index(request):
    me = Student.from_request(request)
    
    if me and me.banned:
        logout(request)
        if "alerts" not in request.session: request.session["alerts"] = []
        request.session["alerts"].append(("alert-error","""This account has
                                          been suspended. If you believe this
                                          is in error, please contact the site
                                          administrator."""))
        return redirect("index")
    elif me and not me.agreed: return redirect("terms")
    elif me: return view_dashboard(request, me)
    
    return render(request,
                  "index.html",
                  {'alerts': request.session.pop('alerts', []) })
Esempio n. 18
0
def view_challenge(request, world, stage):
    try: student = Student.from_request(request)
    except exceptions.ObjectDoesNotExist: return HttpResponse("Redirect to login")
    
    here = get_stage(world, stage)
    if not here.challenge:
        if here.lesson: return redirect( "lesson", world = world, stage = stage )
        else: raise Http404()
    
    # TODO log the view
    
    # These are all of the types of challenges.
    c = here.challenge
    if hasattr(c, "quizchallenge"): return view_quizchallenge(request,
                                                              world,
                                                              stage,
                                                              c.quizchallenge)
    raise Http404()
Esempio n. 19
0
def board_list(request):
    me = Student.from_request(request)
    
    # Get all of the boards that this student can read. Store them in the
    # board_pairs where they are paired with the number of new posts since their
    # last visit.
    board_triplets = []
    boards = DiscussionBoard.objects.all()
    for b in boards:
        if b.can_read(me):
            last_posts = b.discussiontopic_set.exclude(hidden=True)
            new_posts = len( last_posts.filter(last_active__gte=me.unread_since) )
            if len(last_posts) == 0: last_posts = [None]
            visible = False
            board_triplets.append( (b, last_posts[0], new_posts) )
    
    return render( request, "forums.html", {'boards': board_triplets,
                                            'alerts': request.session.pop('alerts', []) })
Esempio n. 20
0
def terms_of_use(request):
    me = Student.from_request(request)
    
    # A POST request means that the user has agreed to the terms of use.
    if request.method == "POST" and me:
        me.agreed = True
        me.save()
        request.session["alerts"].append(("alert-success","Thanks! Welcome to #8bitmooc!"))
        return redirect("index")
    
    # If they've already agreed, let them know.
    if me and me.agreed:
        request.session["alerts"].append(("alert-success","You have already agreed to the terms of use."))
    
    # Render the page.
    return render(request,
                  "terms_of_use.html",
                  {'alerts': request.session.pop('alerts', []) })
Esempio n. 21
0
def sign_up(request):
    me = Student.from_request(request)
    if "alerts" not in request.session: request.session["alerts"] = []
    if me: return redirect("index")
    
    form = RegistrationForm()
    if request.method == 'POST':
        form = RegistrationForm(request.POST)
        if form.is_valid():
            data = form.cleaned_data
            u = User.objects.create_user(data['username'], data['email'], data['password1'])
            u.is_active = False
            u.is_admin = False
            u.save()
            request.session["alerts"].append(("alert-success",
                                              "Please check your e-mail for your verification link."))
            
            #TODO move this email to a file so that it's not so darn ugly.
            email = """
Howdy, %s!

You're almost all set for #8bitmooc - all that's left is to verify your
e-mail address. Please click on the following link to activate your
account!

http://%s/sign-up?username=%s&key=%s
            """%(u.username, settings.SITE_URL, u.username,
                 hashlib.sha256(u.username+settings.REGISTER_SALT).hexdigest())
            
            # Send an alert email to this individual.
            send_mail('[8bitmooc] Account Registration', email, '*****@*****.**',
                      [u.email], fail_silently=True)
            return redirect("sign-in")
        else:
            request.session["alerts"].append(("alert-failure",
                                              "There was an issue registering your account."))
            for e in form.non_field_errors():
                alerts.append( ("alert-error", e ) )
            return render( request, "sign-up.html", { "form":form,
                                                      'alerts': request.session.pop('alerts', []) } )
    else:
        return render(request, 'sign-up.html', {"form":form,
                                                'alerts': request.session.pop('alerts', []) })
Esempio n. 22
0
def do_playground(request):
    code = request.POST["code"]
    a = Assembler()
    rom, errors = a.assemble(code)

    # Save this in the database.
    ACR = AssemblyChallengeResponse()
    try:
        ACR.student = Student.from_request(request)
    except exceptions.ObjectDoesNotExist:
        pass
    ACR.code = code
    ACR.save()

    # Either run the game in the browser or download it.
    request.session["rom"] = rom
    if "run" in request.POST or len(errors) > 0:
        return render(request, "assembler_playground.html", {"source_code": request.POST["code"], "errors": errors})
    else:
        return get_rom(request)
Esempio n. 23
0
def view_badge(request, badge):
    
    # If the badge doesn't exist, take the user to the list.
    try: badge = Badge.objects.get(shortname=badge)
    except exceptions.ObjectDoesNotExist: return redirect( "badge_list" )
    
    # Determine if the User has the badge.
    try: awarded = True if badge.held_by(Student.from_request(request)) else False
    except exceptions.ObjectDoesNotExist: awarded = False
    
    # To embed the add-to-backpack button in your model, use the following
    # script: be sure you check to see if the user is authenticated.
    #   <script src="http://beta.openbadges.org/issuer.js"></script>
    #   <script type="text/javascript">
    #   OpenBadges.issue(["{{ domain }}{% url badge_assert user=user.username badge=badge.shortname %}"],function(errors, successes) {});
    #   </script>
    
    return render( request, "badge_details.html", {"badge":badge,
                                                   "awarded":awarded,
                                                   "domain":ISSUER_DOMAIN} )
Esempio n. 24
0
def search(request):
    me = Student.from_request(request)
    LogEntry.log(request, "search for %s"%request)
    if "query" not in request.GET:
        return redirect("index")
    query = request.GET["query"]
    
    # Filter!
    pages = Page.objects.filter(content__icontains=query)
    results = []
    for p in pages:
        i = p.content.lower().index(query.lower())
        results.append( (p.name,"..."+p.content[max(0,i-50):min(len(p.content),i+50)]+"...") )
    
    # TODO search through forum posts
    return render(request,
                  "search.html",
                  {'results': results,
                   'query': query,
                   'alerts': request.session.pop('alerts', []) })
Esempio n. 25
0
def user_profile(request, username):
    try: student = User.objects.get(username=username).student
    except exceptions.ObjectDoesNotExist:
        request.session["alerts"].append(("alert-error","That user does not exist."))
        return redirect("index")
    me = Student.from_request(request)
    
    if request.method == "POST":
        if me.ta and "ban" in request.POST:
            student.banned = not student.banned
            student.agreed = False
            student.save()
        return redirect("profile", username=username)
    
    return render(request,
                  "profile.html",
                  {'student': student,
                   'challenges': Challenge.show_for(student),
                   'published': CodeSubmission.objects.filter(published__gt=0, student=student).order_by('-timestamp'),
                   'alerts': request.session.pop('alerts', []) })
Esempio n. 26
0
def world_map(request, world):
    try: student = Student.from_request(request)
    except exceptions.ObjectDoesNotExist: return HttpResponse("Redirect to login")
    
    try: world = World.objects.get(shortname=world)
    except exceptions.ObjectDoesNotExist: raise Http404()
    
    # Here, we go through all of the stages and find out which ones we can see,
    # which one we can load, and which ones we've completed.
    stages = [] 
    completed = student.stage_set.all()
    for s in world.stage_set.all():
        available = True
        for p in s.prereqs.all():
            if p not in completed:
                available = False
        if available or (not s.hidden):
            stages.append( ( s, available, s in completed ) )
    
    return render( request, 'lessons_map.html', {'world': world,
                                                 'stage_list': stages} )
Esempio n. 27
0
def board_list(request):
    me = Student.from_request(request)
    if "alerts" not in request.session: request.session["alerts"] = []
    if not me:
        request.session["alerts"].append(("alert-error","Please sign in first."))
        return redirect("sign-in")   
    
    # Get all of the boards that this student can read. Store them in the
    # board_pairs where they are paired with the number of new posts since their
    # last visit.
    board_triplets = []
    boards = DiscussionBoard.objects.all()
    if not me.ta: boards = boards.filter(restricted__lte=me.level)
    for b in boards:
        last_posts = b.discussiontopic_set.exclude(hidden=True)
        new_posts = len( last_posts.filter(last_active__gte=me.last_login) )
        if len(last_posts) == 0: last_posts = [None]
        board_triplets.append( (b, last_posts[0], new_posts) )
    
    return render( request, "forums.html", {'boards': board_triplets,
                                            'alerts': request.session.pop('alerts', []) })
Esempio n. 28
0
def user_list(request):
    me = Student.from_request(request)
    if "alerts" not in request.session: request.session["alerts"] = []
    if not me:
        request.session["alerts"].append(("alert-error","Please sign in first."))
        return redirect("sign-in")
    
    # Get all of the GET parameters.
    filt = request.GET.get("filter")
    page = request.GET.get("page")
    if page and page.isdigit(): page = max(0, int(page)-1)
    else: page = 0
    pagination = 99
    
    # Get the students
    student_list = []
    if filt == "teachers":
        student_list += list(Student.objects.filter(ta=True).order_by("-level","-xp"))
    elif filt == "collab":
        student_list += list(me.collaborators()) 
    elif filt == "blocked":
        student_list += list(me.student_set.all()) 
    else:
        student_list += list(Student.objects.all().order_by("-level","-xp"))
        filt = "all"
    
    # Break the students into three columns
    l1,l2,l3 = [],[],[]
    for s in student_list[pagination*page:pagination*(page+1)]:
        if len(l2) > len(l3): l3.append(s)
        elif len(l1) > len(l2): l2.append(s)
        else: l1.append(s)
    
    return render(request, "user_list.html", {"user_columns": (l1,l2,l3),
                                              "page": page+1,
                                              'pages': (len(student_list)/pagination)+1,
                                              "filter": filt } )
Esempio n. 29
0
def view_feedback(request, name):
    me = Student.from_request(request)
    if "alerts" not in request.session: request.session["alerts"] = []
    if not me:
        request.session["alerts"].append(
            ("alert-error", "Please sign in first."))
        return redirect("sign-in")

    # First, try to get the challenge.
    try:
        challenge = Challenge.objects.get(slug=name)
    except exceptions.ObjectDoesNotExist:
        raise Http404()

    # Now get all of the SOSses related to this user and challenge.
    feedback = SOS.objects.filter(challenge=challenge, student=me)

    # Mark feedback as helpful or not.
    if "helpful" in request.GET or "unhelpful" in request.GET:
        helpful = True
        if "unhelpful" in request.GET: helpful = False
        f_id = request.GET["helpful" if helpful else "unhelpful"]
        if f_id.isdigit():
            f = Feedback.objects.get(id=int(f_id))
            if f.sos in feedback and f.helpful is None:
                f.helpful = helpful
                f.save()
                if helpful:
                    f.author.award_xp(50)
                me.award_xp(5)
                LogEntry.log(request,
                             "Marked as %shelpful" % ("" if helpful else "un"))

    return render(request, "feedback.html", {
        'challenge': challenge,
        'feedback': feedback
    })
Esempio n. 30
0
def view_playground(request):
    me = Student.from_request(request)
    if "alerts" not in request.session: request.session["alerts"] = []

    # Compile the code and save it in the database.
    good = False
    if request.method == "POST":
        code = request.POST.get("code") if "code" in request.POST else ""

        # Save this in the database whether it compiles or not.
        CR = ChallengeResponse()
        CR.student = me
        CR.code = code
        CR.save()

        good = assembler.assemble_and_store(request, "playground", code)
        if "download" in request.POST and good:
            return redirect("rom")
        else:
            return redirect("playground")

    # Render the page.
    code = "; put default code here one day"
    if 'code' in request.POST: code = request.POST['code']
    elif 'source' in request.GET:
        try:
            code = Game.objects.get(id=int(request.GET['source'])).code
        except:
            pass
    elif me:
        subs = ChallengeResponse.objects.filter(
            student=me).order_by('-timestamp')
        if len(subs) > 0: code = subs[0].code
    return render(request, "playground.html", {
        'alerts': request.session.pop('alerts', []),
        'code': code
    })
Esempio n. 31
0
def board_list(request):
    me = Student.from_request(request)
    if "alerts" not in request.session: request.session["alerts"] = []
    if not me:
        request.session["alerts"].append(
            ("alert-error", "Please sign in first."))
        return redirect("sign-in")

    # Get all of the boards that this student can read. Store them in the
    # board_pairs where they are paired with the number of new posts since their
    # last visit.
    board_triplets = []
    boards = DiscussionBoard.objects.all()
    if not me.ta: boards = boards.filter(restricted__lte=me.level)
    for b in boards:
        last_posts = b.discussiontopic_set.exclude(hidden=True)
        new_posts = len(last_posts.filter(last_active__gte=me.last_login))
        if len(last_posts) == 0: last_posts = [None]
        board_triplets.append((b, last_posts[0], new_posts))

    return render(request, "forums.html", {
        'boards': board_triplets,
        'alerts': request.session.pop('alerts', [])
    })
Esempio n. 32
0
def challenge_list(request):
    me = Student.from_request(request)
    if "alerts" not in request.session: request.session["alerts"] = []
    if not me:
        request.session["alerts"].append(
            ("alert-error", "Please sign in first."))
        return redirect("sign-in")

    # Get GET parameters, pagination and filters
    filt = request.GET.get("filter")
    page = request.GET.get("page")
    if page and page.isdigit(): page = max(0, int(page) - 1)
    else: page = 0
    pagination = 20  #not used

    # First get all of the challenges that match the user's level. Then create
    # a challenge list tuple that contains the challenge, whether the challenge
    # has been successfully completed, the records for size and speed, and the
    # number of SOSses.
    challenge_list = []
    complete_set = me.challenge_set.all()
    for c in Challenge.objects.filter(difficulty__lte=me.level):
        if c in complete_set or (not c.expired and
                                 (not c.prereq or c.prereq in complete_set)):
            complete = c in complete_set
            size = 0
            speed = 0
            size_complete = False
            speed_complete = False
            best_size, best_speed = None, None
            my_size, my_speed = None, None
            if complete:
                records = ChallengeResponse.objects.filter(
                    challenge=c, is_correct=True).order_by('-rom_size')
                if len(records) > 0:
                    best_size = records[0].rom_size
                    records = records.order_by('-runtime')
                    best_speed = records[0].runtime
                records = records.filter(student=me).order_by('-rom_size')
                if len(records) > 0:
                    my_size = records[0].rom_size
                    records = records.order_by('-runtime')
                    my_speed = records[0].runtime
            sos = len(
                SOS.objects.filter(active=True,
                                   challenge=c).exclude(student=me))
            challenge_list.append((c, complete, my_size, my_size == best_size,
                                   my_speed, my_speed == best_speed, sos))

    # Filter challenges.
    filtered_list = []
    if filt == "all":
        filtered_list = challenge_list
    elif filt == "size":
        filtered_list = [c for c in challenge_list if not c[3]]
    elif filt == "speed":
        filtered_list = [c for c in challenge_list if not c[5]]
    elif filt == "sos":
        filtered_list = [c for c in challenge_list if c[6]]
    else:
        filtered_list = [c for c in challenge_list if not c[1]]
        filt = "incomplete"

    # Break the challenges into two columns. If we decide to do pagination, do it
    # here.
    l1, l2 = [], []
    for c in filtered_list:
        if len(l1) > len(l2): l2.append(c)
        else: l1.append(c)
    return render(
        request, "challenge_list.html", {
            'challenge_columns': (l1, l2),
            'alerts': request.session.pop('alerts', []),
            'filter': filt
        })
Esempio n. 33
0
def view_project(request, id):
    me = Student.from_request(request)
    if "alerts" not in request.session: request.session["alerts"] = []
    if not me:
        request.session["alerts"].append(
            ("alert-error", "Please sign in first."))
        return redirect("sign-in")

    # Make sure the game exists and we are allowed to see it.
    try:
        project = Project.objects.get(id=id)
    except exceptions.ObjectDoesNotExist:
        return redirect("project_list")

    # If we have a POST request, then we need to save the changes we make.
    # We need to come up with a way to improve working together on projects.
    is_owner = (me == project.owner)
    can_edit = (is_owner or me in project.team.all())
    if request.method == "POST":
        if can_edit:
            old_code = project.code
            project.code = str(request.POST.get("code"))
            commit = ProjectCommit()
            commit.author = me
            commit.project = project
            commit.diff = ""
            for d in difflib.unified_diff(old_code.splitlines(),
                                          project.code.splitlines()):
                commit.diff += d + "\n"
            commit.save()
            try:
                project.pattern = Pattern.objects.get(
                    name=request.POST.get("pattern"))
            except exceptions.ObjectDoesNotExist:
                project.pattern = None
            project.save()
        if "watch" in request.POST:
            if request.POST[
                    "watch"] == "true" and me not in project.watched_by.all():
                project.watched_by.add(me)
            elif request.POST[
                    "watch"] == "false" and me in project.watched_by.all():
                project.watched_by.remove(me)
            project.save()
        if "adduser" in request.POST and is_owner:
            try:
                newguy = Student.objects.get(user=User.objects.get(
                    username=request.POST.get("username")))
                project.team.add(newguy)
                project.save()
            except exceptions.ObjectDoesNotExist:
                request.session["alerts"].append((
                    "alert-error",
                    "Could not find the specifed user. Did you type it in wrong?"
                ))
        if "removeuser" in request.POST and is_owner:
            try:
                newguy = Student.objects.get(user=User.objects.get(
                    username=request.POST.get("username")))
                if newguy in project.team.all(): project.team.remove(newguy)
                project.save()
            except exceptions.ObjectDoesNotExist:
                request.session["alerts"].append((
                    "alert-error",
                    "Could not find the specifed user. Did you type it in wrong?"
                ))

        # Now compile, publish, and download, as specified.
        good = assembler.assemble_and_store(request, slugify(project.name),
                                            project.code, project.pattern)
        if "download" in request.POST:
            return redirect("rom")
        elif "publish" in request.POST:
            project.version += 1
            project.save()
            g = Game()
            g.title = project.name + (" (version %d)" % project.version
                                      if project.version > 1 else "")
            g.code = project.code
            g.pattern = project.pattern
            g.description = str(request.POST.get("description"))
            g.save()
            g.authors.add(project.owner)
            for t in project.team.all():
                g.authors.add(t)
            g.save()
            return redirect("play", id=g.id)
        else:
            return redirect("project", id=project.id)

    # If we decided we wanted to download the code then we download it.
    return render(
        request, "project.html", {
            'alerts': request.session.pop('alerts', []),
            'project': project,
            'patterns': Pattern.objects.all(),
            'can_edit': can_edit
        })
Esempio n. 34
0
def sign_in(request):
    me = Student.from_request(request)
    if "alerts" not in request.session: request.session["alerts"] = []
    if me: return redirect("index")
    
    if request.method == "POST":
        if request.POST.get("sign-up") == "sign-up": return redirect("sign-up")
        elif "username" in request.POST and "password" in request.POST:
            username = request.POST.get("username")
            password = request.POST.get("password")
            user = authenticate(username=username, password=password)
            if user is not None:
                if Student.objects.filter(user=user).exists():
                    login(request, user)
                    s = user.student
                    s.last_login = s.this_login
                    s.this_login = timezone.now()
                    if s.last_login is None:
                        s.last_login = s.this_login
                    if s.last_login.day != s.this_login.day:
                        s.modpoints = s.level
                    s.save()
                    return redirect("index")
                else:
                    request.session["alerts"].append(("alert-error",
                                                      """This account has not yet
                                                      been activated. Please check
                                                      your e-mail for the activation
                                                      link."""))
                    return redirect("sign-in")
            else:
                request.session["alerts"].append(("alert-error",
                                                  """Incorrect username or
                                                  password."""))
                return redirect("sign-in")
        else: return redirect("sign-in")
    elif "key" in request.GET and "username" in request.GET:
        key = request.GET["key"]
        username = request.GET["username"]
        
        # Redirect to login if the user account does not exist or has already
        # been activated.
        try: user = User.objects.get(username=username)
        except exceptions.ObjectDoesNotExist: return redirect("sign-in")
        if Student.objects.filter(user=user).exists(): return redirect("sign-in")
        
        # Verify the hash and redirect if it doesn't match.
        if hashlib.sha256(username+settings.REGISTER_SALT).hexdigest() != key:
            return redirect("sign-in")
        
        # Assuming everything went well...
        S = Student( user=user )
        S.save()
        user.is_active = True
        user.save()
        request.session["alerts"].append(("alert-success",
                                          """Verification successful! You may
                                          now sign in!."""))
        return render(request, "sign-in.html", {'alerts': request.session.pop('alerts', []) })
    else:
        return render(request, "sign-in.html", {'alerts': request.session.pop('alerts', []) })
Esempio n. 35
0
def view_playground(request):
    me = Student.from_request(request)

    # Compile the code and save it in the database.
    good = False
    pattern = None
    name = ""
    if request.method == "POST":
        try:
            old = CodeSubmission.objects.filter(student=me, challenge=None).order_by("-timestamp")[0]
        except:
            old = None

        # Get code from the POST request.
        name = slugify(request.POST.get("name") if request.POST.get("name") else "untitled")[:32]
        code = request.POST.get("code") if request.POST.get("code") else ""
        try:
            pattern = Pattern.objects.get(name=str(request.POST.get("pattern")))
        except:
            pattern = None

        # Save this in the database whether it compiles or not.
        CR = CodeSubmission()
        CR.name = name
        CR.student = me
        CR.code = code
        CR.pattern = pattern
        CR.save()

        good = assembler.assemble_and_store(request, name, code, pattern)
        publish = False
        if "publish" in request.POST and me and not me.banned and good:
            publish = True

        # Convert the last code submission into a diff image, but only save it
        # if the diff is actually smaller than the full code.
        if old and old.published == 0:
            old.parent = CR
            old_code = old.code
            old.code = ""
            for d in difflib.unified_diff(CR.code.splitlines(True), old_code.splitlines(True)):
                old.code += d
            if len(old.code) < len(old_code):
                old.save()

        # Redirect based on which button was clicked.
        if publish:
            CR.published = len(CodeSubmission.objects.filter(published__gt=0)) + 1
            CR.save()
            return redirect("playground")
        elif "download" in request.POST and good:
            return redirect("rom")
        else:
            return redirect("playground")

    # Render the page.
    code = ""
    if "rom_code" in request.session:
        code = request.session["rom_code"]
        pattern = request.session.get("rom_pattern")
        name = str(request.session.get("rom_name"))
    elif me:
        subs = CodeSubmission.objects.filter(student=me, challenge=None).order_by("-timestamp")
        if len(subs) > 0:
            code = subs[0].code
            name = subs[0].name

    # Get recently published games.
    recent = CodeSubmission.objects.filter(published__gt=0).order_by("-timestamp")
    return render(
        request,
        "playground.html",
        {
            "name": name,
            "pattern": pattern,
            "patterns": Pattern.objects.all(),
            "code": code,
            "recently_published": recent[:25],
            "alerts": request.session.pop("alerts", []),
        },
    )
Esempio n. 36
0
def view_board(request, name):
    me = Student.from_request(request)
    if "alerts" not in request.session: request.session["alerts"] = []
    if not me:
        request.session["alerts"].append(
            ("alert-error", "Please sign in first."))
        return redirect("sign-in")

    # First, try to get the board.
    try:
        board = DiscussionBoard.objects.get(slug=name)
    except exceptions.ObjectDoesNotExist:
        raise Http404()
    if board.restricted > me.level: raise Http404()

    # Get the page number!
    page = 0
    pagination = 200
    if "page" in request.GET and request.GET["page"].isdigit():
        page = max(0, int(request.GET["page"]) - 1)

    # If this is a POST, we are creating a new topic. Redirect when finished.
    if request.method == "POST" and (me.level >= board.wrestricted or me.ta):
        content = str(request.POST.get("content"))
        title = content[:100] + "..."
        if "title" in request.POST:
            title = request.POST["title"]

        t = DiscussionTopic()
        t.author = me
        t.board = board
        t.title = title
        t.save()

        p = DiscussionPost()
        p.topic = t
        p.author = me
        p.content = content
        p.save()

        return redirect("thread", name=board.slug, thread=t.id)

    # Get all of the topics, along with the last person who commented on them
    # and when that was.
    topic_tuples = []
    for t in DiscussionTopic.objects.filter(
            hidden=False,
            board=board)[pagination * page:pagination * (page + 1)]:
        posts = DiscussionPost.objects.filter(
            topic=t, hidden=False).order_by("-timestamp")
        count = len(posts)
        new = False
        if count == 0: posts = [None]
        else: new = (posts[0].timestamp > me.last_login)
        topic_tuples.append((t, count, posts[0], new))

    return render(
        request, "forum_topics.html", {
            'board': board,
            'topics': topic_tuples,
            'student': me,
            'alerts': request.session.pop('alerts', []),
            'page': page + 1,
            'pages': (len(topic_tuples) / pagination) + 1
        })
Esempio n. 37
0
def view_thread(request, name, thread):
    me = Student.from_request(request)
    if "alerts" not in request.session: request.session["alerts"] = []
    if not me:
        request.session["alerts"].append(
            ("alert-error", "Please sign in first."))
        return redirect("sign-in")

    # First, try to get the challenge, then thread.
    try:
        board = DiscussionBoard.objects.get(slug=name)
        topic = DiscussionTopic.objects.get(id=thread, board=board)
    except exceptions.ObjectDoesNotExist:
        raise Http404()
    if not me.ta and (topic.hidden or board.restricted > me.level):
        raise Http404()

    # If this is a POST, we are either replying to someone or we are voting.
    # Manage permissions respectively and redirect.
    if request.method == "POST":
        if "thread" in request.POST and (me.level >= board.wrestricted
                                         or me.ta):
            p = DiscussionPost()
            p.topic = topic
            p.author = me
            p.content = str(request.POST.get("content"))
            p.save()
            topic.save()
        elif "upvote" in request.POST or "downvote" in request.POST:
            upvote = True
            if "downvote" in request.POST: upvote = False
            p_id = request.POST["upvote" if upvote else "downvote"]
            if p_id.isdigit() and (me.modpoints > 0 or me.ta):
                p = DiscussionPost.objects.get(id=int(p_id))
                if upvote: p.upvotes += 1
                else: p.downvotes += 1
                request.session["alerts"].append(
                    ("alert-success",
                     "Post %s." % ("upvoted" if upvote else "downvoted")))
                LogEntry.log(
                    request,
                    "Thread %s" % ("upvoted" if upvote else "downvoted"))
                p.save()
                me.modpoints -= 1
                me.award_xp(1)
                me.save()
        return redirect("thread", name=board.slug, thread=topic.id)

    # Get all of the posts. Start on the last page by default.
    pagination = 20
    posts = DiscussionPost.objects.filter(hidden=False, topic=topic)
    pages = (len(posts) / pagination) + 1
    page = pages - 1
    if "page" in request.GET and request.GET["page"].isdigit():
        page = max(0, int(request.GET["page"]) - 1)

    return render(
        request, "forum_thread.html", {
            'board': board,
            'topic': topic,
            'student': me,
            'posts': posts[pagination * page:pagination * (page + 1)],
            'alerts': request.session.pop('alerts', []),
            'page': page + 1,
            'pages': pages
        })
Esempio n. 38
0
def view_challenge(request, name):
    me = Student.from_request(request)
    if "alerts" not in request.session: request.session["alerts"] = []
    if not me:
        request.session["alerts"].append(
            ("alert-error", "Please sign in first."))
        return redirect("sign-in")

    # First, try to get the challenge.
    try:
        challenge = Challenge.objects.get(slug=name)
    except exceptions.ObjectDoesNotExist:
        raise Http404()
    feedback = len(SOS.objects.filter(challenge=challenge, student=me))

    # Now make sure that the student can actually see the challenge before
    # letting them look at it. They can see expired challenges, but can't
    # submit to them.
    if challenge.difficulty > me.level:
        request.session["alerts"].append(
            ("alert-error", """You need to reach level %d before
                                          you can attempt this challenge.""" %
             challenge.difficulty))
        return redirect("challenge_list")
    if challenge.prereq and challenge.prereq not in me.challenge_set.all():
        request.session["alerts"].append(
            ("alert-error", """You have not unlocked this challenge yet."""))
        return redirect("challenge_list")

    # If it was a POST request, then we'll take care of that now. This takes
    # care of the side-effects and creates the challenge responses that will be
    # handled below.
    if request.method == "POST":
        if challenge.autograde: do_asm_challenge(request, me, challenge)
        elif challenge.is_jam: do_jam_challenge(request, me, challenge)
        if "download" in request.POST:
            good = True
            for e in request.session['alerts']:
                if e[0] == 'alert-error': good = False
            if good: return redirect("rom")
        else:
            return redirect("challenge", name=challenge.slug)

    # Display the correct challenge page depending on whether it's autograded
    # or a URL.
    if challenge.autograde:
        code = ""
        subs = ChallengeResponse.objects.filter(
            student=me, challenge=challenge).order_by('-timestamp')
        if len(subs) > 0: code = subs[0].code

        # Get the record speeds and sizes for everything.
        my_size, my_speed = None, None
        best_size, best_speed = None, None
        completed = False

        records = ChallengeResponse.objects.filter(
            challenge=challenge, is_correct=True).order_by('-rom_size')
        if len(records) > 0:
            best_size = records[0].rom_size
            records = records.order_by('-runtime')
            best_speed = records[0].runtime
        records = records.filter(student=me).order_by('-rom_size')
        if len(records) > 0:
            my_size = records[0].rom_size
            records = records.order_by('-runtime')
            my_speed = records[0].runtime
            completed = True

        # Try to load up the best submissions by everyone.
        return render(
            request, "challenge_asm.html", {
                'challenge': challenge,
                'alerts': request.session.pop('alerts', []),
                'code': code,
                'my_size': my_size,
                'my_speed': my_speed,
                'best_size': best_size,
                'best_speed': best_speed,
                'completed': completed,
                'badge_domain': settings.ISSUER_DOMAIN,
                'feedback': feedback
            })

    elif challenge.is_jam:
        # Grey out the submission if the student has already submitted a link for
        # this challenge or if it's expired.
        records = ChallengeResponse.objects.filter(challenge=challenge,
                                                   student=me)
        url = ""
        submit_ok = True
        completed = me in challenge.completed_by.all()
        if len(records) > 0:
            url = records[0].code
            if records[0].is_correct is not None: submit_ok = False
        if challenge.expired: submit_ok = False
        return render(
            request, "challenge_jam.html", {
                'challenge': challenge,
                'alerts': request.session.pop('alerts', []),
                'url': url,
                'submit_ok': submit_ok,
                'completed': completed,
                'badge_domain': settings.ISSUER_DOMAIN,
                'feedback': feedback
            })
    else:
        completed = me in challenge.completed_by.all()
        return render(
            request, "challenge_other.html", {
                'challenge': challenge,
                'alerts': request.session.pop('alerts', []),
                'completed': completed,
                'badge_domain': settings.ISSUER_DOMAIN,
                'feedback': feedback
            })
Esempio n. 39
0
def view_sos(request, name):
    me = Student.from_request(request)
    if "alerts" not in request.session: request.session["alerts"] = []
    if not me:
        request.session["alerts"].append(
            ("alert-error", "Please sign in first."))
        return redirect("sign-in")

    # First, try to get the challenge.
    try:
        challenge = Challenge.objects.get(slug=name)
    except exceptions.ObjectDoesNotExist:
        raise Http404()
    if challenge not in me.challenge_set.all():
        request.session["alerts"].append((
            "alert-error",
            "You must complete this challenge before you can respond to an SOS."
        ))
        return redirect("challenge_list")

    # If this is a POST request, we are responding.
    if request.method == "POST":
        if "id" in request.POST and request.POST["id"] == request.session.get(
                "sos-id"):
            target = SOS.objects.get(id=int(request.session.pop("sos-id")))
            fb = Feedback()
            fb.author = me
            fb.sos = target
            fb.content = str(request.POST.get("response"))
            fb.confidence = True if request.POST.get("confident") else False
            fb.good = True if request.POST.get("good") else False
            fb.save()

            if (len(target.feedback_set.all()) >= 3):
                target.active = False
                target.save()

            request.session["alerts"].append(
                ("alert-success", """Thank you for helping your classmates
                                              by participating in the SOS system!
                                              (+10 XP)"""))
            me.award_xp(10)
            LogEntry.log(request, "SOS for %s" % (challenge.slug))
        else:
            request.session["alerts"].append(
                ("alert-error", """There was an error with your
                                              SOS submission."""))
            LogEntry.log(request, "Botched SOS job.")
        return redirect("challenge_list")

    # Now find out if there are any SOS requests.
    all_sos = list(
        SOS.objects.filter(active=True,
                           challenge=challenge).exclude(student=me))
    if len(all_sos) == 0:
        request.session["alerts"].append(
            ("alert-error",
             "There are no active SOS requests for this challenge."))
        return redirect("challenge_list")

    # Now find an SOS to respond to. Make sure that we haven't already responded
    # to it.
    random.shuffle(all_sos)
    target = None
    while len(all_sos) > 0 and target is None:
        x = all_sos.pop()
        feedbacks = Feedback.objects.filter(sos=x, author=me)
        if len(feedbacks) == 0:
            target = x
    if target is None:
        request.session["alerts"].append((
            "alert-error",
            "You have already responded to all active SOS requests for this challenge!"
        ))
        return redirect("challenge_list")

    # Filtering is now over. Time to render.
    request.session["sos-id"] = str(target.id)
    if challenge.autograde:
        assembler.assemble_and_store(request, "challenge",
                                     target.submission.code, challenge.pattern,
                                     challenge.preamble, challenge.postamble)
        return render(
            request, "sos_asm.html", {
                'challenge': challenge,
                'alerts': request.session.pop('alerts', []),
                'sos': target
            })
    elif challenge.is_jam:
        return redirect("challenge_list")
    else:
        return redirect("challenge_list")
Esempio n. 40
0
def webchat(request):
    me = Student.from_request(request)
    LogEntry.log(request, "chat")
    return render(request, "chat.html")