Ejemplo n.º 1
0
def view_published(request, id):
    if id > 0:
        try:
            c = CodeSubmission.objects.get(published=id)
            assembler.assemble_and_store(request, c.name, c.code, c.pattern)
        except:
            pass
    return redirect("playground")
Ejemplo n.º 2
0
def do_asm_challenge(request, student, challenge):
    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 = student
    CR.challenge = challenge
    CR.code = code
    CR.is_correct = False
    CR.save()

    # Only try to autograde if the program compiles.
    if assembler.assemble_and_store(request, "challenge", code,
                                    challenge.pattern, challenge.preamble,
                                    challenge.postamble):

        completed = student in challenge.completed_by.all()
        results = autograde.grade(challenge, student, code, completed)

        # Save its correctness in the database.
        CR.is_correct = True if results else False
        if results: CR.rom_size, CR.runtime = results
        CR.save()

        # Award XP if the program is correct.
        if results and not completed:
            challenge.completed_by.add(student)
            challenge.save()
            student.award_xp(challenge.xp)
            student.save()
            request.session['alerts'].append(
                ('alert-success', '''Congratulations! You completed
                                              this challenge and earned %d
                                              XP.''' % challenge.xp))
            LogEntry.log(request, "Completed %s" % challenge.slug)
        elif results:
            request.session['alerts'].append(
                ('alert-success', '''This solution was %d bytes in
                                              size and executed %d lines of
                                              code.''' % results))
            LogEntry.log(
                request,
                "%s: %d, %d" % (challenge.slug, results[0], results[1]))

    # Is there an SOS involved?
    if "sos" in request.POST and "help" in request.POST:
        for s in SOS.objects.filter(challenge=challenge, student=student):
            s.active = False
            s.save()

        s = SOS()
        s.challenge = challenge
        s.submission = CR
        s.content = request.POST["help"]
        s.student = student
        s.save()
Ejemplo n.º 3
0
def do_asm_challenge(request, student, challenge):
    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 = student
    CR.challenge = challenge
    CR.code = code
    CR.is_correct = False
    CR.save()
    
    # Only try to autograde if the program compiles.
    if assembler.assemble_and_store(request, "challenge", code, challenge.pattern,
                                    challenge.preamble, challenge.postamble):
        
        completed = student in challenge.completed_by.all()
        results = autograde.grade( challenge, student, code, completed )
        
        # Save its correctness in the database.
        CR.is_correct = True if results else False
        if results: CR.rom_size, CR.runtime = results
        CR.save()
        
        # Award XP if the program is correct.
        if results and not completed:
            challenge.completed_by.add(student)
            challenge.save()
            student.award_xp(challenge.xp)
            student.save()
            request.session['alerts'].append(('alert-success',
                                              '''Congratulations! You completed
                                              this challenge and earned %d
                                              XP.'''%challenge.xp))
            LogEntry.log(request, "Completed %s"%challenge.slug)
        elif results:
            request.session['alerts'].append(('alert-success',
                                              '''This solution was %d bytes in
                                              size and executed %d lines of
                                              code.'''%results))
            LogEntry.log(request, "%s: %d, %d"%(challenge.slug,results[0],results[1]))
    
    # Is there an SOS involved?
    if "sos" in request.POST and "help" in request.POST:
        for s in SOS.objects.filter(challenge=challenge, student=student):
            s.active = False
            s.save()
    
        s = SOS()
        s.challenge = challenge
        s.submission = CR
        s.content = request.POST["help"]
        s.student = student
        s.save()
Ejemplo n.º 4
0
def play_game(request, id):
    try:
        game = Game.objects.get(id=id)
    except exceptions.ObjectDoesNotExist:
        return redirect("arcade")

    good = assembler.assemble_and_store(request, slugify(game.title),
                                        game.code, game.pattern)
    request.session.pop('alerts', [])

    game.hits += 1
    game.save()

    # Now we can display the code to the user.
    if not good:
        return redirect("arcade")
    elif "download" in request.GET:
        return redirect("rom")
    else:
        return render(request, "arcade.html", {'game': game})
Ejemplo n.º 5
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
    })
Ejemplo n.º 6
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", []),
        },
    )
Ejemplo n.º 7
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")
Ejemplo n.º 8
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")
Ejemplo n.º 9
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
        })
Ejemplo n.º 10
0
def view_challenge(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()
        
    # Find the records for this submission. We need them whether we are viewing
    # or processing.
    my_size, my_speed = 0x10000, 0x10000
    best_size, best_speed = 0x1000000, 0x1000000
    completed = False
    records = CodeSubmission.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
        
    # 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.
    code = ""
    if request.method == "POST":
        try: old = CodeSubmission.objects.filter(student=me, challenge=challenge).order_by('-timestamp')[0]
        except: old = None
        
        code = request.POST.get("code") if "code" in request.POST else ""
        CR = CodeSubmission()
        CR.student = me
        CR.challenge = challenge
        CR.code = code
        CR.is_correct = False if challenge.autograde else None
        CR.save()
        
        # 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 len(SOS.objects.filter(submission=old)) == 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()
        
        # Only try to autograde if the program compiles.
        compiles = assembler.assemble_and_store(request, "challenge%s"%challenge.slug,
                   code, challenge.pattern, challenge.preamble, challenge.postamble)
        if compiles and challenge.autograde:
            completed = me in challenge.completed_by.all()
            results = autograde.grade( challenge, me, code, completed )
            
            # Save its correctness in the database.
            CR.is_correct = True if results else False
            if results: CR.rom_size, CR.runtime = results
            CR.save()
            
            # Award victory if the program is correct.
            if results and not completed:
                challenge.completed_by.add(me)
                challenge.save()
                request.session['alerts'].append(('alert-success',
                                                  '''Congratulations! You completed
                                                  this challenge! Can you make it
                                                  more efficient?'''))
                LogEntry.log(request, "Completed %s"%challenge.slug)
            elif results:
                request.session['alerts'].append(('alert-success',
                                                  '''This solution was %d bytes in
                                                  size and executed %d instructions.'''%results))
                LogEntry.log(request, "%s: %d, %d"%(challenge.slug,results[0],results[1]))
        
        # Is there an SOS involved?
        if "sos" in request.POST and "help" in request.POST:
            for s in SOS.objects.filter(challenge=challenge, student=me):
                s.active = False
                s.save()
        
            s = SOS()
            s.challenge = challenge
            s.submission = CR
            s.content = request.POST["help"]
            s.student = me
            s.save()
        
        # Handle the redirect.
        if "download" in request.POST and compiles:
            return redirect("rom")
        return redirect("challenge", challenge.slug)
    
    # Load the latest submission code to display it on the screen.
    subs = CodeSubmission.objects.filter(student=me, challenge=challenge).order_by('-timestamp')
    if len(subs) > 0: code = subs[0].code
    
    # Try to load up the best submissions by everyone.
    return render(request, "challenge.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,
                                              'feedback': SOS.objects.filter(challenge=challenge, student=me) } )
Ejemplo n.º 11
0
def view_sos(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()
    
    # Make sure the student has completed it.
    if challenge not in me.challenge_set.all() and not me.ta:
        request.session['alerts'].append(('alert-error',
                                          '''You can't respond to SOS requests
                                          until you complete the challenge!'''))
        return redirect("index")
    if not challenge.autograde and not me.ta:
        request.session['alerts'].append(('alert-error',
                                          '''Only instructors and TAs can grade
                                          code submission projects.'''))
        return redirect("index")
    
    
    # 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.confident = True if request.POST.get("confident") else False
            fb.good = True if request.POST.get("good") else False
            fb.save()
            
            if request.POST.get("pass") and me.ta:
                target.active = False
                target.save()
                target.submission.correct = True
                challenge.completed_by.add( target.student )
                target.submission.save()
                challenge.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!"""))
        else:
            request.session["alerts"].append(("alert-error",
                                              """There was an error with your
                                              SOS submission."""))
            LogEntry.log(request, "Botched SOS job.")
        return redirect("index")
    
    
    # Find all of the SOS requests for this challenge.
    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("index")
    
    # Get a random challenge if you are not the TA. If you're the TA, get the
    # oldest one.
    if not me.ta: random.shuffle( all_sos )
    target = None
    while len(all_sos) > 0 and target is None:
        x = all_sos.pop(0)
        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("index")
    
    # Now try to assemble the game and then load the page so that we can try to
    # help!
    request.session["sos-id"] = str(target.id)
    assembler.assemble_and_store(request, "challenge", target.submission.code, challenge.pattern,
                                 challenge.preamble, challenge.postamble)
    return render(request, "sos.html", {'challenge': challenge,
                                        'alerts': request.session.pop('alerts', []),
                                        'sos': target } )
Ejemplo n.º 12
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} )