예제 #1
0
파일: case.py 프로젝트: qinmaye/eoj3
    def form_valid(self, form):
        global_create_time = datetime.now()
        option = form.cleaned_data["option"]
        case_number_start = form.cleaned_data["case_number"]
        cases = []

        if option == "text":
            input_binary = REFORMAT(form.cleaned_data["input_text"].encode(),
                                    self.revision.well_form_policy)
            output_binary = REFORMAT(form.cleaned_data["output_text"].encode(),
                                     self.revision.well_form_policy)
            description = "手动创建."
            case = Case(create_time=global_create_time,
                        in_samples=form.cleaned_data["in_samples"],
                        description=description,
                        activated=form.cleaned_data["activated"])
            case.input_file.save("in", ContentFile(input_binary), save=False)
            case.output_file.save("out",
                                  ContentFile(output_binary),
                                  save=False)
            case.save_fingerprint(self.problem.id)
            cases.append(case)

        elif option == "batch":
            tmp_directory = '/tmp/' + random_string()
            with zipfile.ZipFile(form.cleaned_data["batch_file"]) as myZip:
                myZip.extractall(path=tmp_directory)
            case_config = {}
            if path.exists(path.join(tmp_directory, "data.json")):
                with open(path.join(tmp_directory,
                                    "data.json")) as json_config:
                    case_config = json.loads(json_config.read())
            for inf, ouf in sort_data_list_from_directory(tmp_directory):
                with open(path.join(tmp_directory, inf),
                          'rb') as ins, open(path.join(tmp_directory, ouf),
                                             'rb') as ous:
                    conf = case_config.get(inf, {})
                    case = Case(
                        create_time=global_create_time,
                        description=conf.get(
                            "description", "\"%s\": (%s, %s)." %
                            (form.cleaned_data["batch_file"].name, inf, ouf)),
                        in_samples=conf.get("in_samples", False),
                        activated=conf.get("activated", True),
                        group=conf.get("group", 0),
                        points=conf.get("points", 10))
                    if self.revision.well_form_policy:
                        case.input_file.save("in",
                                             ContentFile(
                                                 REFORMAT(ins.read(), True)),
                                             save=False)
                        case.output_file.save("out",
                                              ContentFile(
                                                  REFORMAT(ous.read(), True)),
                                              save=False)
                    else:
                        case.input_file.save("in", File(ins), save=False)
                        case.output_file.save("out", File(ous), save=False)
                    case.save_fingerprint(self.problem.id)
                    cases.append(case)
예제 #2
0
파일: case.py 프로젝트: ilyg8853/eoj3
    def form_valid(self, form):
        global_create_time = datetime.now()
        option = form.cleaned_data["option"]
        case_number_start = form.cleaned_data["case_number"]
        cases = []
        current_total_size = self.get_current_total_size()

        if option == "text":
            input_binary = REFORMAT(form.cleaned_data["input_text"].encode(),
                                    self.revision.well_form_policy)
            output_binary = REFORMAT(form.cleaned_data["output_text"].encode(),
                                     self.revision.well_form_policy)
            description = "手动创建."
            case = Case(create_time=global_create_time,
                        in_samples=form.cleaned_data["in_samples"],
                        description=description,
                        activated=form.cleaned_data["activated"])
            case.input_file.save("in", ContentFile(input_binary), save=False)
            case.output_file.save("out",
                                  ContentFile(output_binary),
                                  save=False)
            case.save_fingerprint(self.problem.id)
            if current_total_size + case.case_size > CASE_SUM_MAX_TOTAL_LENGTH:
                raise ValueError("测试点总规模已超过限制 (2GB)")
            cases.append(case)
예제 #3
0
파일: case.py 프로젝트: revectores/eoj3
 def naturalize_order(revision, case_set):
     remove_list = []
     add_list = []
     with transaction.atomic():
         for idx, case in enumerate(case_set, start=1):
             if idx != case.case_number:
                 remove_list.append(Case(pk=case.pk))
                 case.case_number = idx
                 case.pk = None
                 case.save()
                 add_list.append(case)
         revision.cases.add(*add_list)
         revision.cases.remove(*remove_list)
예제 #4
0
파일: case.py 프로젝트: Abner9291/eoj3
 def generate_cases(revision, commands):
     """
     report: [
         {
             success: True / False
             error: ...
             case_number: 1
             detail: ...
         }, { ... }, ...
     ]
     """
     generators = {}
     current_task = Task.objects.create(revision=revision, abstract="GENERATE CASES")
     report = []
     for command_string in commands:
         ret = {"command": command_string}
         command = command_string.split()
         program_name, program_args = command[0], command[1:]
         try:
             if program_name not in generators:
                 program = revision.programs.get(name=program_name, tag="generator")
                 generators[program_name] = Runner(program)
             elif isinstance(generators[program_name], CompileError):
                 raise generators[program_name]
             runner = generators[program_name]
             if revision.cases.all().count():
                 case_number = revision.cases.all().aggregate(Max("case_number"))["case_number__max"] + 1
             else: case_number = 1
             new_case = Case(create_time=datetime.now(),
                             description="Gen \"%s\"" % command_string,
                             case_number=case_number)
             new_case.input_file.save("in_" + random_string(), ContentFile(b""), save=False)
             new_case.output_file.save("out_" + random_string(), ContentFile(b""), save=False)
             running_result = runner.run(args=program_args, stdout=new_case.input_file.path,
                                         max_time=revision.time_limit * 5 / 1000,
                                         max_memory=revision.memory_limit * 3)
             CaseManagementTools.reformat_file(new_case.input_file.path, revision.well_form_policy)
             new_case.save_fingerprint(revision.problem_id)
             ret["case_number"] = case_number
             with transaction.atomic():
                 new_case.save()
                 revision.cases.add(new_case)
                 ret.update(case_number=case_number,
                            success=running_result["verdict"] == "OK",
                            detail=running_result,
                            generated=new_case.input_preview)
         except (Program.MultipleObjectsReturned, Program.DoesNotExist):
             ret.update(success=False,
                        error="There should be exactly one program tagged 'generator' that fits the command.")
         except CompileError as e:
             generators[program_name] = e
             ret.update(success=False, error=e.error)
         report.append(ret)
         current_task.status = -2
         current_task.report = json.dumps(report)
     current_task.status = 0 if all(map(lambda r: r["success"], report)) else -1
     current_task.save()
예제 #5
0
파일: case.py 프로젝트: revectores/eoj3
 def run_case_output(revision, case_set, solution):
     """
     report: similar to generating cases, [{ }, { }, ... { }]
     """
     current_task = Task.objects.create(revision=revision,
                                        abstract="RUN OUTPUT, %d cases" %
                                        len(case_set))
     try:
         runner = Runner(solution)
         result = []
         failed = False
         for case in case_set:
             if case.output_lock: continue  # output content protected
             case.output_file.save("out", ContentFile(b''), save=False)
             case.parent_id = case.pk
             case.pk = None
             run_result = runner.run(stdin=case.input_file.path,
                                     stdout=case.output_file.path,
                                     max_time=revision.time_limit * 3 /
                                     1000,
                                     max_memory=revision.memory_limit * 2)
             CaseManagementTools.reformat_file(case.output_file.path,
                                               revision.well_form_policy)
             case.save_fingerprint(revision.problem_id)
             with transaction.atomic():
                 case.save()
                 revision.cases.remove(Case(pk=case.parent_id))
                 revision.cases.add(case)
                 result.append({
                     "case_number": case.case_number,
                     "success": run_result["verdict"] == "OK",
                     "detail": run_result
                 })
                 if run_result["verdict"] != "OK":
                     failed = True
                 current_task.status = -2
                 current_task.report = json.dumps(result)
                 current_task.save()
예제 #6
0
                        case.input_file.save("in", File(ins), save=False)
                        case.output_file.save("out", File(ous), save=False)
                    case.save_fingerprint(self.problem.id)
                    cases.append(case)
            shutil.rmtree(tmp_directory)

        elif option == "batch_input":
            tmp_directory = '/tmp/' + random_string()
            with zipfile.ZipFile(form.cleaned_data["batch_file"]) as myZip:
                myZip.extractall(path=tmp_directory)
            for file in special_sort(os.listdir(tmp_directory)):
                file_abspath = os.path.join(tmp_directory, file)
                if os.path.isdir(file_abspath) or file.startswith("."):
                    continue
                with open(path.join(tmp_directory, file), 'rb') as in_file:
                    case = Case(create_time=global_create_time,
                                description="File \"%s\"" % file)
                    if self.revision.well_form_policy:
                        case.input_file.save(
                            "in",
                            ContentFile(REFORMAT(in_file.read(), True)),
                            save=False)
                    else:
                        case.input_file.save("in", File(in_file), save=False)
                    case.output_file.save("out", ContentFile(""), save=False)
                    case.save_fingerprint(self.problem.id)
                    cases.append(case)
            shutil.rmtree(tmp_directory)

        elif option == "gen":
            commands = list(
                map(
예제 #7
0
파일: case.py 프로젝트: qinmaye/eoj3
                exist.add(idx)
                case.case_number = idx
        else:
            idx = case_number_start
            for case in cases:
                case.case_number = idx
                idx += 1
            for case in self.revision.cases.filter(
                    case_number__gte=case_number_start).order_by(
                        "case_number"):
                # do modifications to modified cases
                if idx != case.case_number:
                    case.case_number = idx
                    idx += 1
                    case.parent_id = case.id
                    remove_list.append(Case(pk=case.id))
                    case.id = None
                    cases.append(case)

        with transaction.atomic():
            for case in cases:
                case.save()
            self.revision.cases.add(*cases)
            self.revision.cases.remove(*remove_list)

        messages.success(self.request, "%d 组数据已成功添加." % len(cases))

        return redirect(self.get_success_url())


class CaseUpdateFileView(RevisionCaseMixin, FormView):
예제 #8
0
파일: case.py 프로젝트: ilyg8853/eoj3
class CaseCreateView(ProblemRevisionMixin, FormView):
    form_class = CaseCreateForm
    template_name = 'polygon/problem2/case/create.jinja2'
    polygon_title = "添加数据"

    def get_success_url(self):
        return reverse('polygon:revision_case',
                       kwargs={
                           'pk': self.problem.id,
                           'rpk': self.revision.id
                       })

    def form_valid(self, form):
        global_create_time = datetime.now()
        option = form.cleaned_data["option"]
        case_number_start = form.cleaned_data["case_number"]
        cases = []
        current_total_size = self.get_current_total_size()

        if option == "text":
            input_binary = REFORMAT(form.cleaned_data["input_text"].encode(),
                                    self.revision.well_form_policy)
            output_binary = REFORMAT(form.cleaned_data["output_text"].encode(),
                                     self.revision.well_form_policy)
            description = "手动创建."
            case = Case(create_time=global_create_time,
                        in_samples=form.cleaned_data["in_samples"],
                        description=description,
                        activated=form.cleaned_data["activated"])
            case.input_file.save("in", ContentFile(input_binary), save=False)
            case.output_file.save("out",
                                  ContentFile(output_binary),
                                  save=False)
            case.save_fingerprint(self.problem.id)
            if current_total_size + case.case_size > CASE_SUM_MAX_TOTAL_LENGTH:
                raise ValueError("测试点总规模已超过限制 (2GB)")
            cases.append(case)

        elif option == "batch":
            tmp_directory = '/tmp/' + random_string()
            with zipfile.ZipFile(form.cleaned_data["batch_file"]) as myZip:
                myZip.extractall(path=tmp_directory)
            case_config = {}
            if path.exists(path.join(tmp_directory, "data.json")):
                with open(path.join(tmp_directory,
                                    "data.json")) as json_config:
                    case_config = json.loads(json_config.read())
            for inf, ouf in sort_data_list_from_directory(tmp_directory):
                with open(path.join(tmp_directory, inf),
                          'rb') as ins, open(path.join(tmp_directory, ouf),
                                             'rb') as ous:
                    conf = case_config.get(inf, {})
                    case = Case(
                        create_time=global_create_time,
                        description=conf.get(
                            "description", "\"%s\": (%s, %s)." %
                            (form.cleaned_data["batch_file"].name, inf, ouf)),
                        in_samples=conf.get("in_samples", False),
                        activated=conf.get("activated", True),
                        group=conf.get("group", 0),
                        points=conf.get("points", 10))
                    if self.revision.well_form_policy:
                        case.input_file.save("in",
                                             ContentFile(
                                                 REFORMAT(ins.read(), True)),
                                             save=False)
                        case.output_file.save("out",
                                              ContentFile(
                                                  REFORMAT(ous.read(), True)),
                                              save=False)
                    else:
                        case.input_file.save("in", File(ins), save=False)
                        case.output_file.save("out", File(ous), save=False)