class BaseHandler(CommonRequestHandler): """Base RequestHandler for this application. All the RequestHandler classes in this application should be a child of this class. """ # Whether the login cookie duration has to be refreshed when # this handler is called. Useful to filter asynchronous # requests. refresh_cookie = True @catch_exceptions def prepare(self): """This method is executed at the beginning of each request. """ self.set_header("Cache-Control", "no-cache, must-revalidate") self.sql_session = Session() self.contest = Contest.get_from_id(self.application.service.contest, self.sql_session) localization_dir = os.path.join(os.path.dirname(__file__), "mo") if os.path.exists(localization_dir): tornado.locale.load_gettext_translations(localization_dir, "cms") self._ = self.get_browser_locale().translate self.r_params = self.render_params() def get_current_user(self): """Gets the current user logged in from the cookies If a valid cookie is retrieved, return a User object with the username specified in the cookie. Otherwise, return None. """ timestamp = time.time() if self.get_secure_cookie("login") is None: return None try: cookie = pickle.loads(self.get_secure_cookie("login")) username = str(cookie[0]) last_update = int(cookie[1]) except: self.clear_cookie("login") return None # Check if the cookie is expired. if timestamp - last_update > config.cookie_duration: self.clear_cookie("login") return None user = self.sql_session.query(User).filter_by(contest=self.contest).filter_by(username=username).first() if user is None: self.clear_cookie("login") return None if self.refresh_cookie: self.set_secure_cookie("login", pickle.dumps((user.username, int(time.time()))), expires_days=None) # If this is the first time we see user during the active # phase of the contest, we note that his/her time starts from # now. if self.contest.phase(timestamp) == 0 and user.starting_time is None: logger.info("Starting now for user %s" % user.username) user.starting_time = timestamp self.sql_session.commit() return user def render_params(self): """Return the default render params used by almost all handlers. return (dict): default render params """ ret = {} ret["timestamp"] = int(time.time()) ret["contest"] = self.contest ret["url_root"] = get_url_root(self.request.path) ret["valid_phase_end"] = self.contest.stop if self.contest is not None: ret["phase"] = self.contest.phase(ret["timestamp"]) # If we have a user logged in, the contest may be ended # before contest.stop if the user has finished the time # allocated for him/her. if ret["phase"] == 0 and self.current_user is not None and self.contest.per_user_time is not None: delta = ret["timestamp"] - self.current_user.starting_time if delta >= self.contest.per_user_time: ret["phase"] = 1 user_end_time = self.current_user.starting_time + self.contest.per_user_time if user_end_time < self.contest.stop: ret["valid_phase_end"] = user_end_time ret["contest_list"] = self.sql_session.query(Contest).all() ret["cookie"] = str(self.cookies) return ret def finish(self, *args, **kwds): """ Finishes this response, ending the HTTP request. We override this method in order to properly close the database. """ if hasattr(self, "sql_session"): logger.debug("Closing SQL connection.") try: self.sql_session.close() except Exception as error: logger.warning("Couldn't close SQL connection: %r" % error) tornado.web.RequestHandler.finish(self, *args, **kwds)
class BaseHandler(CommonRequestHandler): """Base RequestHandler for this application. All the RequestHandler classes in this application should be a child of this class. """ def safe_get_item(self, cls, ident, session=None): """Get item from database of class cls and id ident, using session if given, or self.sql_session if not given. If id is not found, raise a 404. cls (class): class of object to retrieve. ident (string): id of object. session (session/None): session to use. return (object/404): the object with the given id, or 404. """ if session is None: session = self.sql_session entity = cls.get_from_id(ident, session) if entity is None: raise tornado.web.HTTPError(404) return entity def prepare(self): """This method is executed at the beginning of each request. """ # Attempt to update the contest and all its references # If this fails, the request terminates. self.set_header("Cache-Control", "no-cache, must-revalidate") self.sql_session = Session() self.sql_session.expire_all() self.contest = None localization_dir = os.path.join(os.path.dirname(__file__), "mo") if os.path.exists(localization_dir): tornado.locale.load_gettext_translations(localization_dir, "cms") def render_params(self): """Return the default render params used by almost all handlers. return (dict): default render params """ params = {} params["timestamp"] = int(time.time()) params["contest"] = self.contest params["url_root"] = get_url_root(self.request.path) if self.contest is not None: params["phase"] = self.contest.phase(params["timestamp"]) # Keep "== None" in filter arguments params["unanswered"] = self.sql_session.query(Question)\ .join(User)\ .filter(User.contest_id == self.contest.id)\ .filter(Question.reply_timestamp == None)\ .filter(Question.ignored == False)\ .count() params["contest_list"] = self.sql_session.query(Contest).all() params["cookie"] = str(self.cookies) return params def finish(self, *args, **kwds): """ Finish this response, ending the HTTP request. We override this method in order to properly close the database. """ logger.debug("Closing SQL connection.") self.sql_session.close() tornado.web.RequestHandler.finish(self, *args, **kwds) def get_non_negative_int(self, argument_name, default, allow_empty=True): """ Get a non-negative integer from the arguments. Use default if the argument is missing; If allow_empty=False, Empty values such as "" and None are not permitted. Raise ValueError if the argument can't be converted into a non-negative integer. """ argument = self.get_argument(argument_name, repr(default)) if allow_empty and \ (argument is None or argument == "" or argument == "None"): return None try: argument = int(argument) except: raise ValueError("%s: can't cast %s to int." % (argument_name, argument)) if argument < 0: raise ValueError("%s is negative." % argument_name) return argument