update fps parser

This commit is contained in:
virusdefender 2017-02-19 12:58:36 +08:00
parent a16701a320
commit bb3d4f7f02

View File

@ -1,36 +1,41 @@
#!/usr/bin/env python3
import copy
import base64
import os
import random
import string
import xml.etree.ElementTree as ET
class FPSParser(object):
def __init__(self, path):
self.path = path
self._root = None
self._parse_result = None
def __init__(self, fps_path):
self.fps_path = fps_path
@property
def root(self):
if self._root is None:
self._root = ET.ElementTree(file=self.path).getroot()
if self._root.attrib["version"] != "1.2":
raise ValueError("Unsupported version")
return self._root
def _root(self):
root = ET.ElementTree(file=self.fps_path).getroot()
version = root.attrib.get("version", "No Version")
if version not in ["1.1", "1.2"]:
raise ValueError("Unsupported version '" + version + "'")
return root
def parse(self):
problem = {"title": None, "description": None,
"memory_limit": {"unit": None, "value": None},
"time_limit": {"unit": None, "value": None},
"images": [], "input": None, "output": None, "samples": [],
"append": [], "template": [], "prepend": [],
"test_cases": [], "hint": None, "source": None,
"spj": [], "solution": []}
ret = []
for node in self._root:
if node.tag == "item":
ret.append(self._parse_one_problem(node))
return ret
def _parse_one_problem(self, node):
sample_start = True
test_case_start = True
for node in self.root:
if node.tag == "item":
problem = {"title": "No Title", "description": "No Description",
"input": "No Input Description",
"output": "No Output Description",
"memory_limit": {"unit": None, "value": None},
"time_limit": {"unit": None, "value": None},
"samples": [], "images": [], "append": [],
"template": [], "prepend": [], "test_cases": [],
"hint": None, "source": None, "spj": None, "solution": []}
for item in node:
tag = item.tag
if tag in ["title", "description", "input", "output", "hint", "source"]:
@ -53,11 +58,16 @@ class FPSParser(object):
if value <= 0:
raise ValueError("Invalid memory limit value")
problem["memory_limit"]["value"] = value
elif tag in ["template", "append", "prepend", "solution", "spj"]:
elif tag in ["template", "append", "prepend", "solution"]:
lang = item.attrib.get("language")
if not lang:
raise ValueError("Invalid " + tag + ", language name is missed")
problem[tag].append({"language": lang, "code": item.text})
elif tag == 'spj':
lang = item.attrib.get("language")
if not lang:
raise ValueError("Invalid spj, language name if missed")
problem["spj"] = {"language": lang, "code": item.text}
elif tag == "img":
problem["images"].append({"src": None, "blob": None})
for child in item:
@ -86,34 +96,31 @@ class FPSParser(object):
problem["test_cases"][-1]["output"] = item.text
test_case_start = True
self._parse_result = problem
return problem
raise ValueError("Invalid xml")
def save_image(self, file_base_path, base_url):
if not self._parse_result:
self.parse()
for item in self._parse_result["images"]:
class FPSHelper(object):
def save_image(self, problem, base_dir, base_url):
_problem = copy.deepcopy(problem)
for img in _problem["images"]:
name = "".join(random.choice(string.ascii_lowercase + string.digits) for _ in range(12))
ext = os.path.splitext(item["src"])[1]
ext = os.path.splitext(img["src"])[1]
file_name = name + ext
with open(os.path.join(file_base_path, file_name), "wb") as f:
f.write(item["blob"])
desc = self._parse_result["description"].replace(item["src"], os.path.join(base_url, file_name))
self._parse_result["description"] = desc
return self._parse_result
with open(os.path.join(base_dir, file_name), "wb") as f:
f.write(img["blob"])
for item in ["description", "input", "output"]:
_problem[item] = _problem[item].replace(img["src"], os.path.join(base_url, file_name))
return _problem
def save_test_case(self, file_base_path, input_preprocessor=None, output_preprocessor=None):
if not self._parse_result:
self.parse()
for index, item in enumerate(self._parse_result["test_cases"]):
with open(os.path.join(file_base_path, str(index + 1) + ".in"), "w") as f:
def save_test_case(self, problem, base_dir, input_preprocessor=None, output_preprocessor=None):
for index, item in enumerate(problem["test_cases"]):
with open(os.path.join(base_dir, str(index + 1) + ".in"), "w", encoding="utf-8") as f:
if input_preprocessor:
input_content = input_preprocessor(item["input"])
else:
input_content = item["input"]
f.write(input_content)
with open(os.path.join(file_base_path, str(index + 1) + ".out"), "w") as f:
with open(os.path.join(base_dir, str(index + 1) + ".out"), "w", encoding="utf-8") as f:
if output_preprocessor:
output_content = output_preprocessor(item["output"])
else:
@ -123,7 +130,14 @@ class FPSParser(object):
if __name__ == "__main__":
import pprint
import os
parser = FPSParser("fps.xml")
parser.parse()
pprint.pprint(parser.save_image("/tmp", "/static/img"))
parser.save_test_case("/tmp")
helper = FPSHelper()
problems = parser.parse()
for index, problem in enumerate(problems):
path = os.path.join("/tmp/", str(index + 1))
os.mkdir(path)
helper.save_test_case(problem, path)
pprint.pprint(helper.save_image(problem, "/tmp", "/static/img"))