this repo has no description
1from . import yaml
2from . import spec
3from . import helpers
4
5from flask import Flask, request, jsonify
6from glob import glob
7from datetime import timedelta
8
9import re
10
11app = Flask(__name__)
12
13
14@app.route("/")
15def root():
16 return app.send_static_file("index.html")
17
18
19@app.route("/files.json")
20def files():
21 files = [x[5:].replace("\\", "/") for x in glob("spec/**/*.mzn", recursive=True)]
22 return jsonify({"files": files})
23
24
25@app.route("/file.json")
26def file():
27 path = "./spec/" + request.args["f"]
28 with open(path, encoding="utf-8") as file:
29 contents = file.read()
30 yaml_comment = re.match(r"\/\*\*\*\n(.*?)\n\*\*\*\/", contents, flags=re.S)
31 if yaml_comment is None:
32 return jsonify({"cases": []})
33
34 tests = [x for x in yaml.load_all(yaml_comment.group(1))]
35
36 cases = [
37 {
38 k: v
39 for k, v in test.__dict__.items()
40 if v is not yaml.Undefined
41 and k in ["name", "solvers", "check_against", "markers", "type",]
42 }
43 for test in tests
44 ]
45
46 for case, test in zip(cases, tests):
47 case["extra_files"] = "\n".join(test.extra_files)
48 case["expected"] = (
49 [{"value": yaml.dump(expected)} for expected in test.expected]
50 if isinstance(test.expected, list)
51 else [{"value": yaml.dump(test.expected)}]
52 )
53
54 case["options"] = [
55 {"key": k, "value": (v if isinstance(v, str) else "")}
56 for k, v in test.options.items()
57 if k not in ["all_solutions", "timeout"]
58 ]
59 case["all_solutions"] = (
60 "all_solutions" in test.options and test.options["all_solutions"]
61 )
62 case["timeout"] = (
63 test.options["timeout"].total_seconds()
64 if "timeout" in test.options
65 else 0
66 )
67 return jsonify({"cases": cases})
68
69
70def load_spec(data):
71 items = {
72 k: v
73 for k, v in data.items()
74 if k in ["name", "solvers", "check_against", "markers", "type"]
75 }
76 items["extra_files"] = data["extra_files"].splitlines(keepends=False)
77 items["expected"] = [yaml.load(x["value"]) for x in data["expected"]]
78 items["options"] = {
79 x["key"]: (x["value"] if len(x["value"]) > 0 else True) for x in data["options"]
80 }
81 items["options"]["all_solutions"] = data["all_solutions"]
82 if not data["timeout"] == "" and float(data["timeout"]) > 0:
83 items["options"]["timeout"] = timedelta(seconds=float(data["timeout"]))
84 print(items)
85 return spec.Test(**items)
86
87
88@app.route("/generate.json", methods=["POST"])
89def generate():
90 path = "./spec/" + request.args["f"]
91 variables = request.args["vars"].splitlines(keepends=False)
92 mode = request.args["mode"]
93 data = request.json
94
95 def filter_args(solution, mode, variables):
96 if mode == "exclude":
97 for x in variables:
98 delattr(solution, x)
99 else:
100 all_vars = [x for x in solution.__dict__.keys()]
101 for x in all_vars:
102 if x not in variables:
103 delattr(solution, x)
104 return solution
105
106 test = load_spec(data)
107
108 generated = []
109 for solver in test.solvers:
110 model, result, required, obtained = test.run(path, solver)
111 if not test.passed(result):
112 if isinstance(obtained, spec.Result):
113 if isinstance(obtained.solution, list):
114 obtained.solution = [
115 filter_args(s, mode, variables) for s in obtained.solution
116 ]
117 else:
118 filter_args(obtained.solution, mode, variables)
119 test.expected.append(obtained)
120 generated.append({"value": yaml.dump(obtained)})
121
122 return jsonify({"obtained": generated})
123
124
125@app.route("/save.json", methods=["POST"])
126def save():
127 path = "./spec/" + request.args["f"]
128 data = request.json
129 dumped = yaml.dump_all(load_spec(x) for x in data)
130
131 with open(path, encoding="utf-8", mode="r+") as file:
132 contents = file.read()
133 yaml_comment = re.match(
134 r"^(.*\/\*\*\*\n)(.*?)(\n\*\*\*\/.*)$", contents, flags=re.S
135 )
136 output = ""
137 if yaml_comment is None:
138 output = "/***\n" + dumped + "***/\n\n" + contents
139 else:
140 output = yaml_comment.group(1) + dumped + yaml_comment.group(3)
141
142 file.seek(0)
143 file.truncate()
144 file.write(output)
145
146 return jsonify({"status": "success"})
147
148
149if __name__ == "__main__":
150 app.run(debug=True)