from . import yaml from . import spec from . import helpers from flask import Flask, request, jsonify from glob import glob from datetime import timedelta import re app = Flask(__name__) @app.route("/") def root(): return app.send_static_file("index.html") @app.route("/files.json") def files(): files = [x[5:].replace("\\", "/") for x in glob("spec/**/*.mzn", recursive=True)] return jsonify({"files": files}) @app.route("/file.json") def file(): path = "./spec/" + request.args["f"] with open(path, encoding="utf-8") as file: contents = file.read() yaml_comment = re.match(r"\/\*\*\*\n(.*?)\n\*\*\*\/", contents, flags=re.S) if yaml_comment is None: return jsonify({"cases": []}) tests = [x for x in yaml.load_all(yaml_comment.group(1))] cases = [ { k: v for k, v in test.__dict__.items() if v is not yaml.Undefined and k in ["name", "solvers", "check_against", "markers", "type",] } for test in tests ] for case, test in zip(cases, tests): case["extra_files"] = "\n".join(test.extra_files) case["expected"] = ( [{"value": yaml.dump(expected)} for expected in test.expected] if isinstance(test.expected, list) else [{"value": yaml.dump(test.expected)}] ) case["options"] = [ {"key": k, "value": (v if isinstance(v, str) else "")} for k, v in test.options.items() if k not in ["all_solutions", "timeout"] ] case["all_solutions"] = ( "all_solutions" in test.options and test.options["all_solutions"] ) case["timeout"] = ( test.options["timeout"].total_seconds() if "timeout" in test.options else 0 ) return jsonify({"cases": cases}) def load_spec(data): items = { k: v for k, v in data.items() if k in ["name", "solvers", "check_against", "markers", "type"] } items["extra_files"] = data["extra_files"].splitlines(keepends=False) items["expected"] = [yaml.load(x["value"]) for x in data["expected"]] items["options"] = { x["key"]: (x["value"] if len(x["value"]) > 0 else True) for x in data["options"] } items["options"]["all_solutions"] = data["all_solutions"] if not data["timeout"] == "" and float(data["timeout"]) > 0: items["options"]["timeout"] = timedelta(seconds=float(data["timeout"])) print(items) return spec.Test(**items) @app.route("/generate.json", methods=["POST"]) def generate(): path = "./spec/" + request.args["f"] variables = request.args["vars"].splitlines(keepends=False) mode = request.args["mode"] data = request.json def filter_args(solution, mode, variables): if mode == "exclude": for x in variables: delattr(solution, x) else: all_vars = [x for x in solution.__dict__.keys()] for x in all_vars: if x not in variables: delattr(solution, x) return solution test = load_spec(data) generated = [] for solver in test.solvers: model, result, required, obtained = test.run(path, solver) if not test.passed(result): if isinstance(obtained, spec.Result): if isinstance(obtained.solution, list): obtained.solution = [ filter_args(s, mode, variables) for s in obtained.solution ] else: filter_args(obtained.solution, mode, variables) test.expected.append(obtained) generated.append({"value": yaml.dump(obtained)}) return jsonify({"obtained": generated}) @app.route("/save.json", methods=["POST"]) def save(): path = "./spec/" + request.args["f"] data = request.json dumped = yaml.dump_all(load_spec(x) for x in data) with open(path, encoding="utf-8", mode="r+") as file: contents = file.read() yaml_comment = re.match( r"^(.*\/\*\*\*\n)(.*?)(\n\*\*\*\/.*)$", contents, flags=re.S ) output = "" if yaml_comment is None: output = "/***\n" + dumped + "***/\n\n" + contents else: output = yaml_comment.group(1) + dumped + yaml_comment.group(3) file.seek(0) file.truncate() file.write(output) return jsonify({"status": "success"}) if __name__ == "__main__": app.run(debug=True)