def post(self): fallback_page = self.url("contests", "add") try: attrs = dict() self.get_string(attrs, "name", empty=None) assert attrs.get("name") is not None, "No contest name specified." attrs["description"] = attrs["name"] # Create the contest. contest = Contest(**attrs) # Add the default group group = Group(name="default") contest.groups.append(group) contest.main_group = group self.sql_session.add(contest) except Exception as error: self.service.add_notification(make_datetime(), "Invalid field(s)", repr(error)) self.redirect(fallback_page) return if self.try_commit(): # Create the contest on RWS. self.service.proxy_service.reinitialize() self.redirect(self.url("contest", contest.id)) else: self.redirect(fallback_page)
def choose_contest(self): """Fill self.contest using contest passed as argument or path. If a contest was specified as argument to CWS, fill self.contest with that; otherwise extract it from the URL path. """ if self.is_multi_contest(): # Choose the contest found in the path argument # see: https://github.com/tornadoweb/tornado/issues/1673 contest_name = self.path_args[0] # Select the correct contest or return an error self.contest = self.sql_session.query(Contest)\ .filter(Contest.name == contest_name).first() if self.contest is None: self.contest = Contest(name=contest_name, description=contest_name) # render_params in this class assumes the contest is loaded, # so we cannot call it without a fully defined contest. Luckily # the one from the base class is enough to display a 404 page. super().prepare() self.r_params = super().render_params() raise tornado.web.HTTPError(404) else: # Select the contest specified on the command line self.contest = Contest.get_from_id(self.service.contest_id, self.sql_session)
def post(self): fallback_page = "/contests/add" try: attrs = dict() self.get_string(attrs, "name", empty=None) assert attrs.get("name") is not None, "No contest name specified." attrs["description"] = attrs["name"] # Create the contest. contest = Contest(**attrs) self.sql_session.add(contest) except Exception as error: self.application.service.add_notification( make_datetime(), "Invalid field(s)", repr(error)) self.redirect(fallback_page) return if self.try_commit(): # Create the contest on RWS. self.application.service.proxy_service.reinitialize() self.redirect("/contest/%s" % contest.id) else: self.redirect(fallback_page)
def get_contest(self): # Check for required files if not (self.__require_file("contest.json") and self.__require_file("problem-list.txt")): return None # Load name and description contest = self.__load_contest(self.path) args = {} args['name'] = contest['name'] args['description'] = contest['description'] logger.info("Loading parameters for contest %s.", args['name']) args['token_mode'] = 'infinite' # Load datetime time_info = contest['time'] start_time_local = datetime.datetime.strptime(time_info['start'], '%Y-%m-%d %H:%M') local_tz = get_localzone() start_time = local_tz.localize(start_time_local, is_dst=None).astimezone( pytz.utc).replace(tzinfo=None) contest_len = datetime.timedelta(minutes=time_info['length']) args['start'] = start_time args['stop'] = start_time + contest_len # Tasks tasks = list( map((lambda x: x[:-1]), open(os.path.join(self.path, 'problem-list.txt'), 'r'))) # Import was successful logger.info("Contest parameters loaded.") return Contest(**args), tasks, []
def _makecontest(self): """ Return a Contest object which can be saved to the database. return (Contest): database object for the contest """ if self.defaultgroup is None: raise Exception("You have to specify a default group") cdb = Contest(name=self.contestname, description=self._description) cdb.timezone = self._timezone cdb.allowed_localizations = self._allowed_localizations cdb.languages = self._languages cdb.allow_registration = self._allow_registration self._set_tokens(cdb) cdb.max_submission_number = self.max_submission_number cdb.min_submission_interval = self.min_submission_interval cdb.max_user_test_number = self.max_user_test_number cdb.min_user_test_interval = self.min_user_test_interval self.usersdb = {} self.participationsdb = {} self.cdb = cdb gdbs = {} for g in self.groups: gdbs[g] = self._makegroup(g, cdb) cdb.main_group = gdbs[self.defaultgroup.name] return cdb
def get_contest(cls, **kwargs): """Create a contest""" args = { "name": unique_unicode_id(), "description": unique_unicode_id(), } args.update(kwargs) contest = Contest(**args) return contest
def add_contest(self, **kwargs): """Add a contest.""" args = { "name": unique_unicode_id(), "description": unique_unicode_id(), } args.update(kwargs) contest = Contest(**args) self.session.add(contest) return contest
def get_contest(cls, **kwargs): """Create a contest""" grpargs = {} for a in ["start", "stop", "per_user_time"]: if a in kwargs: grpargs[a] = kwargs[a] del kwargs[a] args = { "name": unique_unicode_id(), "description": unique_unicode_id(), "main_group": cls.get_group(**grpargs), } args["groups"] = [args["main_group"]] args.update(kwargs) contest = Contest(**args) return contest
def get_contest(self): """See docstring in class Loader. """ name = os.path.split(self.path)[1] conf = yaml.safe_load( io.open(os.path.join(self.path, "contest.yaml"), "rt", encoding="utf-8")) logger.info("Loading parameters for contest %s." % name) args = {} load(conf, args, ["name", "nome_breve"]) load(conf, args, ["description", "nome"]) assert name == args["name"] load(conf, args, "token_initial") load(conf, args, "token_max") load(conf, args, "token_total") load(conf, args, "token_min_interval", conv=make_timedelta) load(conf, args, "token_gen_time", conv=make_timedelta) load(conf, args, "token_gen_number") load(conf, args, ["start", "inizio"], conv=make_datetime) load(conf, args, ["stop", "fine"], conv=make_datetime) load(conf, args, "max_submission_number") load(conf, args, "max_user_test_number") load(conf, args, "min_submission_interval", conv=make_timedelta) load(conf, args, "min_user_test_interval", conv=make_timedelta) logger.info("Contest parameters loaded.") tasks = load(conf, None, ["tasks", "problemi"]) self.tasks_order = dict((name, num) for num, name in enumerate(tasks)) self.users_conf = dict((user['username'], user) for user in load(conf, None, ["users", "utenti"])) users = self.users_conf.keys() return Contest(**args), tasks, users
def get_contest_object(self): """ Return the Contest database object. """ args = {} # Names. args["name"] = self.params["short_name"] args["description"] = self.params["long_name"] # Languages. args["languages"] = self.params["languages"] # Communication args["allow_questions"] = self.params.get("allow_questions", False) # Times. start_time = time_from_str(self.params["start_time"]) stop_time = time_from_str(self.params["end_time"]) args["start"] = make_datetime(time.mktime(start_time.timetuple())) args["stop"] = make_datetime(time.mktime(stop_time.timetuple())) # Limits. args["max_submission_number"] = self.params["max_submission_number"] args["max_user_test_number"] = self.params["max_user_test_number"] interval_seconds = self.params["min_submission_interval"] if interval_seconds is not None: delta = timedelta(seconds=interval_seconds) args["min_submission_interval"] = delta interval_seconds = self.params["min_user_test_interval"] if interval_seconds is not None: delta = timedelta(seconds=interval_seconds) args["min_user_test_interval"] = delta return Contest(**args)
def choose_contest(self): """Fill self.contest using contest passed as argument or path. If a contest was specified as argument to CWS, fill self.contest with that; otherwise extract it from the URL path. """ if self.is_multi_contest(): # Choose the contest found in the path argument # see: https://github.com/tornadoweb/tornado/issues/1673 contest_name = self.path_args[0] # Select the correct contest or return an error try: self.contest = self.contest_list[contest_name] except KeyError: self.contest = Contest( name=contest_name, description=contest_name) self.r_params = self.render_params() raise tornado.web.HTTPError(404) else: # Select the contest specified on the command line self.contest = Contest.get_from_id( self.application.service.contest_id, self.sql_session)
def get_contest(self): """See docstring in class ContestLoader.""" if not os.path.exists(os.path.join(self.path, "contest.yaml")): logger.critical("File missing: \"contest.yaml\"") return None conf = load_yaml_from_path(os.path.join(self.path, "contest.yaml")) # Here we update the time of the last import touch(os.path.join(self.path, ".itime_contest")) # If this file is not deleted, then the import failed touch(os.path.join(self.path, ".import_error_contest")) args = {} load(conf, args, ["name", "nome_breve"]) load(conf, args, ["description", "nome"]) logger.info("Loading parameters for contest %s.", args["name"]) # Use the new token settings format if detected. if "token_mode" in conf: load(conf, args, "token_mode") load(conf, args, "token_max_number") load(conf, args, "token_min_interval", conv=make_timedelta) load(conf, args, "token_gen_initial") load(conf, args, "token_gen_number") load(conf, args, "token_gen_interval", conv=make_timedelta) load(conf, args, "token_gen_max") # Otherwise fall back on the old one. else: logger.warning( "contest.yaml uses a deprecated format for token settings " "which will soon stop being supported, you're advised to " "update it.") # Determine the mode. if conf.get("token_initial", None) is None: args["token_mode"] = TOKEN_MODE_DISABLED elif conf.get("token_gen_number", 0) > 0 and \ conf.get("token_gen_time", 0) == 0: args["token_mode"] = TOKEN_MODE_INFINITE else: args["token_mode"] = TOKEN_MODE_FINITE # Set the old default values. args["token_gen_initial"] = 0 args["token_gen_number"] = 0 args["token_gen_interval"] = timedelta() # Copy the parameters to their new names. load(conf, args, "token_total", "token_max_number") load(conf, args, "token_min_interval", conv=make_timedelta) load(conf, args, "token_initial", "token_gen_initial") load(conf, args, "token_gen_number") load(conf, args, "token_gen_time", "token_gen_interval", conv=make_timedelta) load(conf, args, "token_max", "token_gen_max") # Remove some corner cases. if args["token_gen_initial"] is None: args["token_gen_initial"] = 0 if args["token_gen_interval"].total_seconds() == 0: args["token_gen_interval"] = timedelta(minutes=1) load(conf, args, ["start", "inizio"], conv=make_datetime) load(conf, args, ["stop", "fine"], conv=make_datetime) load(conf, args, ["per_user_time"], conv=make_timedelta) load(conf, args, ["timezone"]) load(conf, args, "max_submission_number") load(conf, args, "max_user_test_number") load(conf, args, "min_submission_interval", conv=make_timedelta) load(conf, args, "min_user_test_interval", conv=make_timedelta) tasks = load(conf, None, ["tasks", "problemi"]) participations = load(conf, None, ["users", "utenti"]) for p in participations: p["password"] = build_password(p["password"]) # Import was successful os.remove(os.path.join(self.path, ".import_error_contest")) logger.info("Contest parameters loaded.") return Contest(**args), tasks, participations
def get_contest(self): """See docstring in class ContestLoader.""" if not os.path.exists(os.path.join(self.path, "contest.yaml")): logger.critical("File missing: \"contest.yaml\"") return None conf = load_yaml_from_path(os.path.join(self.path, "contest.yaml")) # Here we update the time of the last import touch(os.path.join(self.path, ".itime_contest")) # If this file is not deleted, then the import failed touch(os.path.join(self.path, ".import_error_contest")) args = {} # Contest Information load(conf, args, ["name", "nome_breve"]) logger.info("Loading parameters for contest %s.", args["name"]) load(conf, args, ["description", "nome"]) load(conf, args, "allowed_localizations") load(conf, args, ["languages", "allowed_programming_languages"]) load(conf, args, "submissions_download_allowed") load(conf, args, "allow_questions") load(conf, args, "allow_user_tests") load(conf, args, ["score_precision", "score_decimal_places"]) # Logging in load(conf, args, "block_hidden_participations") load(conf, args, "allow_password_authentication") load(conf, args, "allow_registration") load(conf, args, ["ip_restriction","ip_based_login_restriction"]) load(conf, args, ["ip_autologin","ip_based_autologin"]) # Tokens parameters # Use the new token settings format if detected. if "token_mode" in conf: load(conf, args, "token_mode") load(conf, args, ["token_max_number","maximum_number_of_tokens"]) load(conf, args, ["token_min_interval","minimum_interval_between_tokens"], conv=make_timedelta) load(conf, args, ["token_gen_initial","initial_number_of_tokens"]) load(conf, args, ["token_gen_number","token_generation_number"]) load(conf, args, ["token_gen_interval","token_generation_period"], conv=make_timedelta) load(conf, args, ["token_gen_max","maximum_accumulated_tokens"]) # Otherwise fall back on the old one. else: logger.warning( "contest.yaml uses a deprecated format for token settings " "which will soon stop being supported, you're advised to " "update it.") # Determine the mode. if conf.get("token_initial", None) is None: args["token_mode"] = TOKEN_MODE_DISABLED elif conf.get("token_gen_number", 0) > 0 and \ conf.get("token_gen_time", 0) == 0: args["token_mode"] = TOKEN_MODE_INFINITE else: args["token_mode"] = TOKEN_MODE_FINITE # Set the old default values. args["token_gen_initial"] = 0 args["token_gen_number"] = 0 args["token_gen_interval"] = timedelta() # Copy the parameters to their new names. load(conf, args, "token_total", "token_max_number") load(conf, args, "token_min_interval", conv=make_timedelta) load(conf, args, "token_initial", "token_gen_initial") load(conf, args, "token_gen_number") load(conf, args, "token_gen_time", "token_gen_interval", conv=make_timedelta) load(conf, args, "token_max", "token_gen_max") # Remove some corner cases. if args["token_gen_initial"] is None: args["token_gen_initial"] = 0 if args["token_gen_interval"].total_seconds() == 0: args["token_gen_interval"] = timedelta(minutes=1) # Times load(conf, args, ["start", "start_time", "start_time_in_utc", "inizio"], conv=make_utc_datetime) load(conf, args, ["stop", "end_time", "end_time_in_utc", "fine"], conv=make_utc_datetime) load(conf, args, ["per_user_time","length_of_the_contest"], conv=make_timedelta) load(conf, args, ["timezone"]) # Limits load(conf, args, ["max_submission_number","maximum_number_of_submissions"]) load(conf, args, ["max_user_test_number","maximum_number_of_user_tests"]) load(conf, args, ["min_submission_interval","minimum_interval_between_submissions"], conv=make_timedelta) load(conf, args, ["min_user_test_interval","minimum_interval_between_user_tests"], conv=make_timedelta) # Analysis load(conf, args, ["analysis_enabled", "enabled"]) load(conf, args, ["analysis_start", "analysis_mode_start_time_in_utc"], conv=make_utc_datetime) load(conf, args, ["analysis_stop", "analysis_mode_end_time_in_utc"], conv=make_utc_datetime) taskpaths = load(conf, None, ["tasks", "problemi"]) # read true name of tasks tasks = [] self.task_path_map = {} for taskpath in taskpaths: name = taskpath try: conf = load_yaml_from_path(os.path.join(self.path, taskpath, "task.yaml")) name = conf.get("name", taskpath) except: try: conf = load_yaml_from_path(os.path.join(self.path, taskpath + ".yaml")) name = conf.get("name", taskpath) except: pass tasks.append(name) self.task_path_map[name] = os.path.join(self.path, taskpath) participations = load(conf, None, ["users", "participations"]) if participations: for p in participations: p["password"] = build_password(p["password"]) # Import was successful os.remove(os.path.join(self.path, ".import_error_contest")) logger.info("Contest parameters loaded.") return Contest(**args), tasks, participations
def get_contest(self): conf_path = self.path base_path = os.path.dirname(self.path) if not exists(conf_path): logger.critical("cannot find contest config file") return None, None, None conf = load_yaml(conf_path) name = conf['name'] logger.info("loading parameters for contest \"%s\"", name) # default values conf.setdefault('allow_user_tests', False) conf.setdefault('allow_questions', False) conf.setdefault('timezone', 'Asia/Tokyo') # override conf['token_mode'] = TOKEN_MODE_DISABLED # validity check cms_langs = [lang.name for lang in LANGUAGES] for lang in conf['languages']: if lang not in cms_langs: logger.critical("language \"%s\" is not supported", lang) return None, None, None contest = {} assign(contest, conf, 'name') assign(contest, conf, 'description') assign(contest, conf, 'languages') assign(contest, conf, 'allow_user_tests') assign(contest, conf, 'allow_questions') assign(contest, conf, 'timezone') assign(contest, conf, 'token_mode') try_assign(contest, conf, 'ip_restriction') try_assign(contest, conf, 'ip_autologin') try_assign(contest, conf, 'score_precision') try_assign(contest, conf, 'max_submission_number') try_assign(contest, conf, 'max_user_test_number') try_assign(contest, conf, 'analysis_enabled') try_assign(contest, conf, 'min_submission_interval', make_timedelta) try_assign(contest, conf, 'min_user_test_interval', make_timedelta) try_assign(contest, conf, 'start', make_datetime) try_assign(contest, conf, 'stop', make_datetime) try_assign(contest, conf, 'analysis_start', make_datetime) try_assign(contest, conf, 'analysis_stop', make_datetime) participations = [] conf.setdefault('users', []) conf.setdefault('tasks', []) conf.setdefault('task_names', []) for u in conf['users']: p = {} assign(p, u, 'username') try_assign(p, u, 'team') try_assign(p, u, 'hidden') try_assign(p, u, 'ip') try_assign(p, u, 'password', build_password) participations.append(p) tasks = conf['task_names'].copy() for t in conf['tasks']: task_path = os.path.join(base_path, t) task_name = ImprovedImojLoader.find_task_name(task_path) if task_name is not None: tasks.append(task_name) else: logger.warning("cannot detect task name (path: \"%s\")", task_path) logger.info("contest parameters loaded") return Contest(**contest), tasks, participations
def get_contest(self): """See docstring in class Loader. """ name = os.path.split(self.path)[1] conf = yaml.safe_load( io.open(os.path.join(self.path, "contest.yaml"), "rt", encoding="utf-8")) logger.info("Loading parameters for contest %s." % name) args = {} load(conf, args, ["name", "nome_breve"]) load(conf, args, ["description", "nome"]) assert name == args["name"] # Use the new token settings format if detected. if "token_mode" in conf: load(conf, args, "token_mode") load(conf, args, "token_max_number") load(conf, args, "token_min_interval", conv=make_timedelta) load(conf, args, "token_gen_initial") load(conf, args, "token_gen_number") load(conf, args, "token_gen_interval", conv=make_timedelta) load(conf, args, "token_gen_max") # Otherwise fall back on the old one. else: logger.warning( "contest.yaml uses a deprecated format for token settings " "which will soon stop being supported, you're advised to " "update it.") # Determine the mode. if conf.get("token_initial", None) is None: args["token_mode"] = "disabled" elif conf.get("token_gen_number", 0) > 0 and \ conf.get("token_gen_time", 0) == 0: args["token_mode"] = "infinite" else: args["token_mode"] = "finite" # Set the old default values. args["token_gen_initial"] = 0 args["token_gen_number"] = 0 args["token_gen_interval"] = timedelta() # Copy the parameters to their new names. load(conf, args, "token_total", "token_max_number") load(conf, args, "token_min_interval", conv=make_timedelta) load(conf, args, "token_initial", "token_gen_initial") load(conf, args, "token_gen_number") load(conf, args, "token_gen_time", "token_gen_interval", conv=make_timedelta) load(conf, args, "token_max", "token_gen_max") # Remove some corner cases. if args["token_gen_initial"] is None: args["token_gen_initial"] = 0 if args["token_gen_interval"].total_seconds() == 0: args["token_gen_interval"] = timedelta(minutes=1) load(conf, args, ["start", "inizio"], conv=make_datetime) load(conf, args, ["stop", "fine"], conv=make_datetime) load(conf, args, ["per_user_time"], conv=make_timedelta) load(conf, args, "max_submission_number") load(conf, args, "max_user_test_number") load(conf, args, "min_submission_interval", conv=make_timedelta) load(conf, args, "min_user_test_interval", conv=make_timedelta) logger.info("Contest parameters loaded.") tasks = load(conf, None, ["tasks", "problemi"]) self.tasks_order = dict((name, num) for num, name in enumerate(tasks)) self.users_conf = dict((user['username'], user) for user in load(conf, None, ["users", "utenti"])) users = self.users_conf.keys() return Contest(**args), tasks, users
def get_contest(self): """See docstring in class ContestLoader.""" if not os.path.exists(os.path.join(self.path, "contest.yaml")): logger.critical("File missing: \"contest.yaml\"") return None conf = yaml.safe_load( io.open(os.path.join(self.path, "contest.yaml"), "rt", encoding="utf-8")) # Here we update the time of the last import touch(os.path.join(self.path, ".itime_contest")) # If this file is not deleted, then the import failed touch(os.path.join(self.path, ".import_error_contest")) args = {} load(conf, args, ["name", "nome_breve"]) load(conf, args, ["description", "nome"]) load(conf, args, "presentation") load(conf, args, "path_to_logo") load(conf, args, "timezone") pr_temp = load(conf, None, "presentation_translations") if pr_temp: presentation_translations = { language: Presentation(language, pr_temp[language]) for language in pr_temp } else: presentation_translations = {} args["presentation_translations"] = presentation_translations # Authentication methods oic_info = load(conf, None, "oic_info") if oic_info: args["auth_type"] = "OpenIDConnect" with open(os.path.join(self.path, oic_info), "r") as f: args["openidconnect_info"] = f.read() # To limit the interface to a few languages load(conf, args, "allowed_localizations") # Allowed programming languages plang = load(conf, None, "allowed_languages") if plang: args["languages"] = plang logger.info("Loading parameters for contest %s.", args["name"]) # Use the new token settings format if detected. if "token_mode" in conf: load(conf, args, "token_mode") load(conf, args, "token_max_number") load(conf, args, "token_min_interval", conv=make_timedelta) load(conf, args, "token_gen_initial") load(conf, args, "token_gen_number") load(conf, args, "token_gen_interval", conv=make_timedelta) load(conf, args, "token_gen_max") # Otherwise fall back on the old one. else: logger.warning( "contest.yaml uses a deprecated format for token settings " "which will soon stop being supported, you're advised to " "update it.") # Determine the mode. if conf.get("token_initial", None) is None: args["token_mode"] = TOKEN_MODE_DISABLED elif conf.get("token_gen_number", 0) > 0 and \ conf.get("token_gen_time", 0) == 0: args["token_mode"] = TOKEN_MODE_INFINITE else: args["token_mode"] = TOKEN_MODE_FINITE # Set the old default values. args["token_gen_initial"] = 0 args["token_gen_number"] = 0 args["token_gen_interval"] = timedelta() # Copy the parameters to their new names. load(conf, args, "token_total", "token_max_number") load(conf, args, "token_min_interval", conv=make_timedelta) load(conf, args, "token_initial", "token_gen_initial") load(conf, args, "token_gen_number") load(conf, args, "token_gen_time", "token_gen_interval", conv=make_timedelta) load(conf, args, "token_max", "token_gen_max") # Remove some corner cases. if args["token_gen_initial"] is None: args["token_gen_initial"] = 0 if args["token_gen_interval"].total_seconds() == 0: args["token_gen_interval"] = timedelta(minutes=1) load(conf, args, ["start", "inizio"], conv=make_datetime) load(conf, args, ["stop", "fine"], conv=make_datetime) load(conf, args, ["per_user_time"], conv=make_timedelta) load(conf, args, "max_submission_number") load(conf, args, "max_user_test_number") load(conf, args, "min_submission_interval", conv=make_timedelta) load(conf, args, "min_user_test_interval", conv=make_timedelta) tasks = load(conf, None, ["tasks", "problemi"]) participations = load(conf, None, ["users", "utenti"]) if participations is not None: for p in participations: p["password"] = build_password(p["password"]) # Import was successful os.remove(os.path.join(self.path, ".import_error_contest")) logger.info("Contest parameters loaded.") return Contest(**args), tasks, participations
def get_contest(self): """See docstring in class Loader. """ name = os.path.split(self.path)[1] logger.info("Loading parameters for contest %s.", name) args = {} tree = ET.parse(os.path.join(self.path, "contest.xml")) root = tree.getroot() args['name'] = name # TODO: find proper way to choose contest primary language. self.primary_language = root.find('names') \ .find('name').attrib['language'] # All available contest languages are allowed to be used. self.languages = [] for alternative_name in root.find('names'): self.languages.append(alternative_name.attrib['language']) logger.info("Contest languages are %s %s", self.primary_language, str(self.languages)) args['description'] = root.find('names') \ .find("name[@language='%s']" % self.primary_language) \ .attrib['value'] logger.info("Contest description is %s", args['description']) # For now Polygon doesn't support custom contest-wide files, # so we need to hardcode some contest settings. args['start'] = datetime(1970, 1, 1) args['stop'] = datetime(1970, 1, 1) # Uncomment the following to set specific values for these # options. # args['max_submission_number'] = 100 # args['max_user_test_number'] = 100 # args['min_submission_interval'] = make_timedelta(60) # args['min_user_test_interval'] = make_timedelta(60) # args['max_user_test_number'] = 10 # args['min_user_test_interval'] = make_timedelta(60) # args['token_mode'] = 'infinite' # args['token_max_number'] = 100 # args['token_min_interval'] = make_timedelta(60) # args['token_gen_initial'] = 1 # args['token_gen_number'] = 1 # args['token_gen_interval'] = make_timedelta(1800) # args['token_gen_max'] = 2 logger.info("Contest parameters loaded.") tasks = [] for problem in root.find('problems'): tasks.append(os.path.basename(problem.attrib['url'])) participations = [] # This is not standard Polygon feature, but useful for CMS users # we assume contestants.txt contains one line for each user: # # username;password;first_name;last_name;hidden # # For example: # # contestant1;123;Cont;Estant;0 # jury;1234;Ju;Ry;1 users_path = os.path.join(self.path, 'contestants.txt') if os.path.exists(users_path): with io.open(users_path, "rt", encoding="utf-8") as users_file: for user in users_file.readlines(): user = user.strip() user = user.split(';') participations.append({ "username": user[0].strip(), "password": build_password(user[1].strip()), "hidden": user[4].strip() # "ip" is not passed }) return Contest(**args), tasks, participations
def post(self): fallback_page = "/contests/add" try: attrs = dict() self.get_string(attrs, "name", empty=None) self.get_string(attrs, "description") assert attrs.get("name") is not None, "No contest name specified." allowed_localizations = \ self.get_argument("allowed_localizations", "") if allowed_localizations: attrs["allowed_localizations"] = \ [x.strip() for x in allowed_localizations.split(",") if len(x) > 0 and not x.isspace()] else: attrs["allowed_localizations"] = [] attrs["languages"] = self.get_arguments("languages") self.get_bool(attrs, "submissions_download_allowed") self.get_bool(attrs, "block_hidden_participations") self.get_bool(attrs, "ip_restriction") self.get_bool(attrs, "ip_autologin") self.get_string(attrs, "token_mode") self.get_int(attrs, "token_max_number") self.get_timedelta_sec(attrs, "token_min_interval") self.get_int(attrs, "token_gen_initial") self.get_int(attrs, "token_gen_number") self.get_timedelta_min(attrs, "token_gen_interval") self.get_int(attrs, "token_gen_max") self.get_int(attrs, "max_submission_number") self.get_int(attrs, "max_user_test_number") self.get_timedelta_sec(attrs, "min_submission_interval") self.get_timedelta_sec(attrs, "min_user_test_interval") self.get_datetime(attrs, "start") self.get_datetime(attrs, "stop") self.get_string(attrs, "timezone", empty=None) self.get_timedelta_sec(attrs, "per_user_time") self.get_int(attrs, "score_precision") # Create the contest. contest = Contest(**attrs) self.sql_session.add(contest) except Exception as error: self.application.service.add_notification(make_datetime(), "Invalid field(s)", repr(error)) self.redirect(fallback_page) return if self.try_commit(): # Create the contest on RWS. self.application.service.proxy_service.reinitialize() self.redirect("/contest/%s" % contest.id) else: self.redirect(fallback_page)