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)
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)
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)
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()
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()
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(
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):
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)