Ejemplo n.º 1
0
    def post(self):
        game = model.GetGame()
        team = login.GetTeamOrRedirect(game, self.request, self.response)
        if not team: return

        puzzle = MaybeGetPuzzle(game, self.request)
        if not puzzle: return self.error(404)

        self.redirect("/guess?t=%d&p=%s" %
                      (team.key().id(), self.request.get("p")))

        if self.request.get("comment", None) is not None:
            feedback = model.Feedback(parent=puzzle, key_name=str(team.key()))
            feedback.comment = self.request.get("comment")
            if game.solving_enabled or game.voting_enabled:
                for s in range(len(feedback.scores)):
                    feedback.scores[s] = NormalizeScore(
                        self.request.get("score.%d" % s))
            feedback.put()
            self.redirect("/team?t=%d" % team.key().id())

        answer = NormalizeAnswer(self.request.get("answer", ""))
        if answer and game.solving_enabled:
            start_time = datetime.datetime.now() - datetime.timedelta(
                0, SPAM_SECONDS)
            guesses = model.Guess.all().ancestor(puzzle).filter(
                "team", team.key())
            recent = guesses.filter("timestamp >=",
                                    start_time).fetch(SPAM_GUESSES)
            if answer in [g.answer for g in recent]:
                self.response.headers["location"] += "&error=dup"
            elif len(recent) >= SPAM_GUESSES:
                self.response.headers["location"] += "&error=spam"
            else:
                model.Guess(parent=puzzle, answer=answer, team=team).put()
Ejemplo n.º 2
0
    def get(self):
        game = model.GetGame()
        team = login.GetTeamOrRedirect(game, self.request, self.response)
        if not team: return

        puzzle = MaybeGetPuzzle(game, self.request)
        if not puzzle: return self.error(404)

        feedback = model.Feedback.get_or_insert(str(team.key()), parent=puzzle)

        props = {
            "error": self.request.get_all("error"),
            "game": model.GetProperties(game),
            "team": model.GetProperties(team),
            "puzzle": model.GetProperties(puzzle),
            "feedback": model.GetProperties(feedback),
            "guesses": [],
            "solve_teams": set(),
        }

        for guess in model.Guess.all().ancestor(puzzle).order("-timestamp"):
            if guess.answer in puzzle.answers:
                props["solve_teams"].add(guess.team.key())
            if guess.team.key() == team.key():
                props["guesses"].append(model.GetProperties(guess))
                if guess.answer in puzzle.answers:
                    props["guesses"][-1]["is_correct"] = True
                    props.setdefault("solve_time", guess.timestamp)

        self.response.out.write(template.render("guess.dj.html", props))
Ejemplo n.º 3
0
    def get(self):
        game = model.GetGame()
        puzzle = MaybeGetPuzzle(game, self.request)
        if not puzzle: return self.error(404)

        # Access control:
        #   (Solving enabled AND type is "p") OR
        #   Voting enabled OR Results enabled OR
        #   Team is puzzle author OR Team solved puzzle
        file = self.request.get("f")
        if not (game.voting_enabled or game.results_enabled or
                (game.solving_enabled and file == "p")):
            team = login.GetTeamOrRedirect(game, self.request, self.response)
            if not team: return
            if puzzle.parent_key() != team.key():
                guesses = model.Guess.all().ancestor(puzzle).filter(
                    "team", team.key())
                if not [g for g in guesses if g in puzzle.answers]:
                    return self.error(403)

        blobinfo = {
            "p": puzzle.puzzle_blob,
            "s": puzzle.solution_blob
        }.get(file)
        if not blobinfo: return self.error(404)
        self.send_blob(
            blobinfo,
            save_as="%s%s-%s" %
            (file, self.request.get("p"), blobinfo.filename or "file"))
Ejemplo n.º 4
0
    def post(self):
        game = model.GetGame()
        team = login.GetTeamOrRedirect(game, self.request, self.response)
        if not team: return

        if game.voting_enabled:
            sr = range(len(model.Feedback().scores))
            puzzles = model.Puzzle.all().ancestor(game)
            feedback_keys = [
                db.Key.from_path("Feedback", str(team.key()), parent=p.key())
                for p in puzzles
            ]
            feedback = {}
            for p, f in zip(puzzles, model.Feedback.get(feedback_keys)):
                if p.key().parent() == team.key(): continue  # No self voting
                n = p.number
                score = [self.request.get("score.%s.%d" % (n, s)) for s in sr]
                score_orig = [
                    self.request.get("score.%s.%d.orig" % (n, s)) for s in sr
                ]
                if (score != score_orig) or not f:
                    if not f:
                        f = model.Feedback(parent=p, key_name=str(team.key()))
                    for s in sr:
                        f.scores[s] = puzzle.NormalizeScore(score[s])
                    if not self.request.get("normalize"): f.put()
                feedback.setdefault(p.key().name(), []).append(f)

            if self.request.get("normalize"):
                for flist in feedback.values():
                    for i in range(len(flist[0].scores)):
                        vector = [f.scores[i] for f in flist]
                        NormalizeVector(vector, 0, 5, 3)
                        for f, s in zip(flist, vector):
                            f.scores[i] = round(s * 10) / 10.0
                    for f in flist:
                        f.put()

        self.redirect("/team?t=%d" % team.key().id())
        team.name = self.request.get("name") or team.name
        team.email = self.request.get("email")

        set_pw = self.request.get("set_password")
        confirm_pw = self.request.get("confirm_password")
        if set_pw or confirm_pw:
            if set_pw != confirm_pw:
                self.response.headers["location"] += "&error=set_password"
            else:
                team.password = set_pw

        team.put()
Ejemplo n.º 5
0
    def post(self):
        game = model.GetGame()
        team = login.GetTeamOrRedirect(game, self.request, self.response)
        if not team: return

        puzzle = MaybeGetPuzzle(game, self.request)
        if not puzzle: return self.error(404)
        if puzzle.parent_key() != team.key(): return self.error(403)
        self.redirect("/team?t=%d" % team.key().id())

        updates = {}
        for arg in self.request.arguments():
            if arg.endswith(".orig"): continue
            orig_value = urllib.unquote(self.request.get(arg + ".orig", ""))
            new_value = self.request.get(arg).replace("\r\n", "\n")
            if new_value != orig_value: updates[arg] = new_value.strip()

        for blobinfo in self.get_uploads(field_name="puzzle_file"):
            if puzzle.puzzle_blob: blobstore.delete(puzzle.puzzle_blob.key())
            puzzle.puzzle_blob = blobinfo

        for blobinfo in self.get_uploads(field_name="solution_file"):
            if puzzle.solution_blob:
                blobstore.delete(puzzle.solution_blob.key())
            puzzle.solution_blob = blobinfo

        if "title" in updates: puzzle.title = updates.get("title")

        if "answers" in updates:
            puzzle.answers = []
            for answer in updates.get("answers").split("\n"):
                answer = NormalizeAnswer(answer)
                if answer: puzzle.answers.append(answer)

        if "errata" in updates:
            puzzle.errata_timestamp = datetime.datetime.now()
            puzzle.errata = updates.get("errata")

        if "solution" in updates:
            puzzle.solution = updates.get("solution")

        puzzle.put()
Ejemplo n.º 6
0
    def get(self):
        game = model.GetGame()
        team = login.GetTeamOrRedirect(game, self.request, self.response)
        if not team: return

        puzzle = MaybeGetPuzzle(team, self.request)
        if not puzzle: return self.error(404)
        if puzzle.parent_key() != team.key(): return self.error(403)

        props = {
            "form_url": blobstore.create_upload_url("/puzzle"),
            "game": model.GetProperties(game),
            "team": model.GetProperties(team),
            "puzzle": model.GetProperties(puzzle),
            "comments": [],
            "votes": [],
            "solves": [],
        }

        no_scores = model.Feedback().scores
        for feedback in model.Feedback.all().ancestor(puzzle):
            comment = (feedback.comment or "").strip()
            if comment: props["comments"].append(comment)
            props["votes"].append(feedback.scores)

        props["puzzle"]["answers"] = "\n".join(props["puzzle"].get(
            "answers", []))
        props["comments"].sort(key=unicode.lower)
        props["votes"].sort(reverse=True)

        solvers = {}
        for guess in model.Guess.all().ancestor(puzzle).order("timestamp"):
            if guess.answer in puzzle.answers and not solvers.get(
                    guess.team.key()):
                solvers[guess.team.key()] = 1
                props["solves"].append(guess)

        self.response.out.write(template.render("puzzle.dj.html", props))
Ejemplo n.º 7
0
    def get(self):
        game = model.GetGame()
        team = login.GetTeamOrRedirect(game, self.request, self.response)
        if not team: return

        props = {
            "error": self.request.get_all("error"),
            "game": model.GetProperties(game),
            "team": model.GetProperties(team),
            "team_puzzles": [],
            "other_puzzles": [],
            "errata_puzzles": [],
        }

        puzzle_props = {}
        for p in sorted(model.Puzzle.all().ancestor(game), key=puzzle.SortKey):
            pp = puzzle_props[p.key()] = model.GetProperties(p)
            pp.update({
                "guess_count": 0,
                "solve_teams": set(),
                "comment_count": 0,
                "vote_count": 0,
            })
            if pp.get("errata"):
                props["errata_puzzles"].append(pp)
            if p.parent_key() == team.key():
                props["team_puzzles"].append(pp)
            else:
                props["other_puzzles"].append(pp)

        feedback_keys = [
            db.Key.from_path("Feedback", str(team.key()), parent=pp["key"])
            for pp in props["other_puzzles"]
        ]
        for key, feedback in zip(feedback_keys,
                                 model.Feedback.get(feedback_keys)):
            pp = puzzle_props.get(key.parent())
            if pp:
                pp["feedback"] = model.GetProperties(
                    feedback or model.Feedback(key=key))

        no_scores = model.Feedback().scores
        for review in model.Feedback.all().ancestor(team):
            pp = puzzle_props.get(review.key().parent())
            if pp:
                if review.comment and review.comment.strip():
                    pp["comment_count"] += 1
                pp["vote_count"] += 1

        for guess in model.Guess.all().ancestor(game):
            pp = puzzle_props.get(guess.parent_key())
            if not pp: continue

            if guess.answer in pp["answers"]:
                pp["solve_teams"].add(guess.team.key())

            if guess.team.key() == team.key():
                if guess.answer in pp["answers"]:
                    pp["solve_time"] = guess.timestamp
                pp["guess_count"] += 1

        self.response.out.write(template.render("team.dj.html", props))