| #!/usr/bin/env python3 |
| |
| import yaml |
| import os |
| import sys |
| import re |
| |
| license = """#!/usr/bin/env python3 |
| # -*- coding: utf-8 -*- |
| # Licensed to the Apache Software Foundation (ASF) under one or more |
| # contributor license agreements. See the NOTICE file distributed with |
| # this work for additional information regarding copyright ownership. |
| # The ASF licenses this file to You under the Apache License, Version 2.0 |
| # (the "License"); you may not use this file except in compliance with |
| # the License. You may obtain a copy of the License at |
| # |
| # http://www.apache.org/licenses/LICENSE-2.0 |
| # |
| # Unless required by applicable law or agreed to in writing, software |
| # distributed under the License is distributed on an "AS IS" BASIS, |
| # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| # See the License for the specific language governing permissions and |
| # limitations under the License. |
| """ |
| |
| baseyaml = """ |
| # THIS IS PULLED FROM SCRIPTS AND AUTOGENERATED! |
| # Please use openapi/combine.py to regenerate! |
| openapi: 3.0.0 |
| info: |
| version: 1.0.0 |
| description: This is the API specifications for interacting with the Blocky/2 UI. |
| title: Blocky/2 |
| license: |
| name: Apache 2.0 |
| url: 'http://www.apache.org/licenses/LICENSE-2.0.html' |
| """ |
| |
| bpath = os.path.dirname(os.path.abspath(__file__)) |
| |
| |
| def deconstruct(): |
| yml = yaml.load(open(bpath + "/../openapi.yaml")) |
| noDefs = 0 |
| print("Dumping paths into pages...") |
| for endpoint, defs in yml['paths'].items(): |
| noDefs += 1 |
| xendpoint = endpoint.replace("/api/", "") |
| ypath = os.path.abspath("%s/../../pages/%s.py" % (bpath, xendpoint)) |
| print(ypath) |
| if os.path.isfile(ypath): |
| print("Editing %s" % ypath) |
| contents = open(ypath, "r").read() |
| contents = re.sub(r"^([#\n](?!\s*\"\"\")[^\r\n]*\n?)+", "", contents, re.MULTILINE) |
| odefs = yaml.dump(defs, default_flow_style=False) |
| odefs = "\n".join(["# %s" % line for line in odefs.split("\n")]) |
| with open(ypath, "w") as f: |
| f.write(license) |
| f.write("########################################################################\n") |
| f.write("# OPENAPI-URI: %s\n" % endpoint) |
| f.write("########################################################################\n") |
| f.write(odefs) |
| f.write("\n########################################################################\n") |
| f.write("\n\n") |
| f.write(contents) |
| f.close() |
| |
| print("Dumping security components...") |
| for basetype, bdefs in yml['components'].items(): |
| for schema, defs in bdefs.items(): |
| noDefs += 1 |
| ypath = "%s/components/%s/%s.yaml" % (bpath, basetype, schema) |
| ydir = os.path.dirname(ypath) |
| if not os.path.isdir(ydir): |
| print("Making directory %s" % ydir) |
| os.makedirs(ydir, exist_ok = True) |
| with open(ypath, "w") as f: |
| f.write("########################################################################\n") |
| f.write("# %-68s #\n" % defs.get('summary', schema)) |
| f.write("########################################################################\n") |
| f.write(yaml.dump(defs, default_flow_style=False)) |
| f.close() |
| print("Dumped %u definitions." % noDefs) |
| |
| def construct(): |
| yml = {} |
| yml['paths'] = {} |
| yml['components'] = {} |
| apidir = os.path.abspath("%s/../../pages/" % bpath) |
| print("Scanning %s" % apidir) |
| for d in os.listdir(apidir): |
| cdir = os.path.abspath("%s/%s" % (apidir, d)) |
| if os.path.isdir(cdir): |
| print("Scanning %s" % cdir) |
| for fname in os.listdir(cdir): |
| if fname.endswith(".py"): |
| fpath = "%s/%s" % (cdir, fname) |
| print("Scanning %s" % fpath) |
| contents = open(fpath, "r").read() |
| m = re.search(r"OPENAPI-URI: (\S+)\n##+\n([\s\S]+?)##+", contents) |
| if m: |
| apath = m.group(1) |
| cyml = m.group(2) |
| print("Weaving in API path %s" % apath) |
| cyml = "\n".join([line[2:] for line in cyml.split("\n")]) |
| defs = yaml.load(cyml) |
| yml['paths'][apath] = defs |
| else: |
| fname = d |
| if fname.endswith(".py"): |
| fpath = "%s/%s" % (apidir, fname) |
| print("Scanning %s" % fpath) |
| contents = open(fpath, "r").read() |
| m = re.search(r"OPENAPI-URI: (\S+)\n##+\n([\s\S]+?)##+", contents) |
| if m: |
| apath = m.group(1) |
| cyml = m.group(2) |
| print("Weaving in API path %s" % apath) |
| cyml = "\n".join([line[2:] for line in cyml.split("\n")]) |
| defs = yaml.load(cyml) |
| yml['paths'][apath] = defs |
| apidir = os.path.abspath("%s/components" % bpath) |
| print("Scanning %s" % apidir) |
| for d in os.listdir(apidir): |
| cdir = os.path.abspath("%s/%s" % (apidir, d)) |
| if os.path.isdir(cdir): |
| print("Scanning %s" % cdir) |
| for fname in os.listdir(cdir): |
| if fname.endswith(".yaml"): |
| yml['components'][d] = yml['components'].get(d, {}) |
| fpath = "%s/%s" % (cdir, fname) |
| print("Scanning %s" % fpath) |
| defs = yaml.load(open(fpath)) |
| yml['components'][d][fname.replace(".yaml", "")] = defs |
| ypath = os.path.abspath("%s/../openapi.yaml" % bpath) |
| with open(ypath, "w") as f: |
| f.write(baseyaml) |
| f.write(yaml.dump(yml, default_flow_style=False)) |
| f.close() |
| print("All done!") |
| |
| if len(sys.argv) > 1 and sys.argv[1] == 'deconstruct': |
| deconstruct() |
| else: |
| construct() |