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
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
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
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=''))