Esempio n. 1
0
    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)
Esempio n. 2
0
    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)
Esempio n. 3
0
    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)
Esempio n. 4
0
 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, []
Esempio n. 5
0
    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
Esempio n. 6
0
 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
Esempio n. 7
0
 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
Esempio n. 8
0
 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
Esempio n. 9
0
    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
Esempio n. 10
0
    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)
Esempio n. 11
0
    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)
Esempio n. 12
0
    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
Esempio n. 13
0
    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
Esempio n. 14
0
    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
Esempio n. 15
0
    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
Esempio n. 16
0
    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
Esempio n. 17
0
    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
Esempio n. 18
0
    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)