Esempio n. 1
0
 def get_token(cls, submission=None, **kwargs):
     """Create a token."""
     submission = submission if submission is not None \
         else cls.get_submission()
     args = {
         "submission": submission,
         "timestamp": (submission.task.contest.start
                       + timedelta(seconds=unique_long_id())),
     }
     args.update(kwargs)
     token = Token(**args)
     return token
Esempio n. 2
0
 def add_token(self, submission=None, **kwargs):
     """Create a token and add it to the session"""
     if submission is None:
         submission = self.add_submission()
     args = {
         "submission":
         submission,
         "timestamp": (submission.task.contest.start +
                       timedelta(seconds=unique_long_id())),
     }
     args.update(kwargs)
     token = Token(**args)
     self.session.add(token)
     return token
Esempio n. 3
0
def accept_token(sql_session, submission, timestamp):
    """Add a token to the database.

    This function is primarily called by CWS when a contestant sends a
    request to play a token on a submission. It received the arguments
    of such a request, it validates them and, if there are no issues,
    it adds a token to the database, for the given submission at the
    given timestamp.

    sql_session (Session): the SQLAlchemy database session to use.
    submission (Submission): the submission on which the token should
        be applied (the participation, task and contest will be
        extracted from here).
    timestamp (datetime): the moment at which the request occurred.

    return (Token): the Token that was added to the database.

    raise (UnacceptableToken): if some of the requirements that have to
        be met in order for the request to be accepted don't hold.
    raise (TokenAlreadyPlayed): if the request is for adding a token to
        a submission that already has one.

    """
    tokens_available_ = tokens_available(submission.participation,
                                         submission.task, timestamp)

    if tokens_available_[0] == 0 or tokens_available_[2] is not None:
        logger.warning("User %s tried to play a token when they "
                       "shouldn't.", submission.participation.user.username)
        raise UnacceptableToken(
            N_("Token request discarded"),
            N_("Your request has been discarded because you have no "
               "tokens available."))

    if submission.token is not None:
        raise TokenAlreadyPlayed(
            N_("Token request discarded"),
            N_("Your request has been discarded because "
               "you already used a token on that submission."))

    token = Token(timestamp, submission=submission)
    sql_session.add(token)

    return token
Esempio n. 4
0
    def post(self, task_name, submission_num):
        participation = self.current_user

        try:
            task = self.contest.get_task(task_name)
        except KeyError:
            raise tornado.web.HTTPError(404)

        submission = self.sql_session.query(Submission)\
            .filter(Submission.participation == participation)\
            .filter(Submission.task == task)\
            .order_by(Submission.timestamp)\
            .offset(int(submission_num) - 1)\
            .first()
        if submission is None:
            raise tornado.web.HTTPError(404)

        # Don't trust the user, check again if (s)he can really play
        # the token.
        tokens_available = self.contest.tokens_available(
            participation.user.username, task.name, self.timestamp)
        if tokens_available[0] == 0 or tokens_available[2] is not None:
            logger.warning(
                "User %s tried to play a token when they "
                "shouldn't.", participation.user.username)
            # Add "no luck" notification
            self.application.service.add_notification(
                participation.user.username, self.timestamp,
                self._("Token request discarded"),
                self._("Your request has been discarded because you have no "
                       "tokens available."), NOTIFICATION_ERROR)
            self.redirect("/tasks/%s/submissions" % quote(task.name, safe=''))
            return

        if submission.token is None:
            token = Token(self.timestamp, submission=submission)
            self.sql_session.add(token)
            self.sql_session.commit()
        else:
            self.application.service.add_notification(
                participation.user.username, self.timestamp,
                self._("Token request discarded"),
                self._("Your request has been discarded because you already "
                       "used a token on that submission."),
                NOTIFICATION_WARNING)
            self.redirect("/tasks/%s/submissions" % quote(task.name, safe=''))
            return

        # Inform ProxyService and eventually the ranking that the
        # token has been played.
        self.application.service.proxy_service.submission_tokened(
            submission_id=submission.id)

        logger.info("Token played by user %s on task %s.",
                    participation.user.username, task.name)

        # Add "All ok" notification.
        self.application.service.add_notification(
            participation.user.username, self.timestamp,
            self._("Token request received"),
            self._("Your request has been received "
                   "and applied to the submission."), NOTIFICATION_SUCCESS)

        self.redirect("/tasks/%s/submissions" % quote(task.name, safe=''))