Fin de refactorización
This commit is contained in:
parent
9db7d96a06
commit
fdd44d72ff
263
yasd.py
263
yasd.py
|
@ -16,7 +16,14 @@ class YASD:
|
|||
YASD actions performer.
|
||||
"""
|
||||
|
||||
def do(action="check", indata=None, outfile=None, quiet=False, log=False):
|
||||
def do(
|
||||
action="check",
|
||||
indata=None,
|
||||
outfile=None,
|
||||
quiet=False,
|
||||
log=False,
|
||||
stdout=False,
|
||||
):
|
||||
"""
|
||||
Performs YASD actions directly.
|
||||
|
||||
|
@ -31,17 +38,27 @@ class YASD:
|
|||
:type quiet: True or False
|
||||
:param log: If messages are write in a file or not; 'False' by default
|
||||
:type log: True or False
|
||||
:param stdout: if conversion goes to stdout or not; 'False' by default
|
||||
:type stdout: True or False
|
||||
:return: Output data; str on 'document'; bs4.element.Tag on 'convert'
|
||||
or 'sample'; YAML dict on 'check'
|
||||
:rtype: str or bs4.element.Tag or dict
|
||||
"""
|
||||
yasd = YASD(indata, outfile, quiet, log)
|
||||
yasd = YASD(indata, outfile, quiet, log, stdout)
|
||||
yasd.msgr.run(f"action_{action}")
|
||||
if action == "convert":
|
||||
yasd.convert(stdout=True)
|
||||
elif action == "sample":
|
||||
yasd.sample(stdout=True)
|
||||
elif action == "document":
|
||||
yasd.document(stdout=True)
|
||||
match action:
|
||||
case "document":
|
||||
return yasd.document()
|
||||
case "convert":
|
||||
return yasd.convert()
|
||||
case "sample":
|
||||
return yasd.sample()
|
||||
case "check":
|
||||
return yasd.yaml
|
||||
|
||||
def __init__(self, indata=None, outfile=None, quiet=False, log=False):
|
||||
def __init__(
|
||||
self, indata=None, outfile=None, quiet=False, log=False, stdout=False
|
||||
):
|
||||
"""
|
||||
Inits YASD object.
|
||||
|
||||
|
@ -55,56 +72,83 @@ class YASD:
|
|||
:type log: True or False
|
||||
"""
|
||||
self.msgr = YASDMessenger(quiet=quiet, log=log)
|
||||
self.outfile = YASDCheck.file(outfile, self.msgr)
|
||||
self.yaml = YASDCheck(indata, self.msgr).yaml
|
||||
self.formatter = XMLFormatter(indent=2)
|
||||
self.outfile = outfile
|
||||
self.xsd = None
|
||||
self.out = ""
|
||||
self.stdout = stdout
|
||||
|
||||
def convert(self, stdout=False):
|
||||
def convert(self):
|
||||
"""
|
||||
Converts YASD to XSD.
|
||||
|
||||
:param stdout: if conversion goes to stdout or not; 'False' by default
|
||||
:type stdout: True or False
|
||||
:return: XSD element
|
||||
:rtype: bs4.element.Tag
|
||||
"""
|
||||
self.xsd = YASDXSD(self.yaml, self.msgr).xsd
|
||||
return self.__output(self.xsd)
|
||||
|
||||
def sample(self):
|
||||
"""
|
||||
Generates XML sample from YASD.
|
||||
|
||||
:return: XML element
|
||||
:rtype: bs4.element.Tag
|
||||
"""
|
||||
self.xml = YASDXML(self.yaml, self.msgr).xml
|
||||
return self.__output(self.xml, extname=".xml")
|
||||
|
||||
def document(self):
|
||||
"""
|
||||
Generates RST documentation.
|
||||
|
||||
:return: RST document
|
||||
:rtype: str
|
||||
"""
|
||||
self.rst = YASDRST(self.yaml, self.msgr).rst
|
||||
return self.__output(self.rst, extname=".rst")
|
||||
|
||||
def __output(self, outdata, extname=".xsd"):
|
||||
"""
|
||||
Prints in the terminal or writes into a file.
|
||||
|
||||
:return: Output data; str if outdata comes from YASDRST; otherwise
|
||||
bs4.element.Tag
|
||||
:rtype: str or bs4.element.Tag
|
||||
"""
|
||||
if self.stdout:
|
||||
if type(outdata) is not str:
|
||||
outdata = outdata.prettify(formatter=self.formatter)
|
||||
if self.outfile is None:
|
||||
print(outdata)
|
||||
else:
|
||||
suffix = self.outfile.suffix
|
||||
if len(suffix) > 0 and suffix == suffix.replace(" ", ""):
|
||||
extname = suffix
|
||||
filename = f"{self.outfile.stem}{extname}"
|
||||
filename = Path(self.outfile.parent / filename)
|
||||
filename.write_text(outdata)
|
||||
return outdata
|
||||
|
||||
|
||||
class YASDXSD:
|
||||
"""
|
||||
YASD convertor to XSD.
|
||||
"""
|
||||
|
||||
# TODO refactor so it fits XSD grammar, cfr. reference:
|
||||
# https://www.w3schools.com/xml/schema_elements_ref.asp
|
||||
|
||||
def __init__(self, yml=None, messenger=None):
|
||||
"""
|
||||
Inits YASD convertor.
|
||||
"""
|
||||
self.msgr = YASDCheck.messenger(messenger)
|
||||
self.yaml = YASDCheck.yaml(yml, self.msgr)
|
||||
self.xsd = BeautifulSoup(parser="xml")
|
||||
self.__build_schema()
|
||||
self.__build_elements()
|
||||
self.__build_attributes()
|
||||
self.__build_groups()
|
||||
self.__stringify_xsd()
|
||||
if stdout:
|
||||
self.__output()
|
||||
else:
|
||||
return self.out
|
||||
|
||||
def sample(self, stdout=False):
|
||||
"""
|
||||
Generates XML sample from YASD.
|
||||
|
||||
:param stdout: if sample goes to stdout or not; 'False' by default
|
||||
:type stdout: True or False
|
||||
"""
|
||||
# TODO XML sample
|
||||
self.out = "XML sample"
|
||||
if stdout:
|
||||
self.__output()
|
||||
else:
|
||||
return self.out
|
||||
|
||||
def document(self, stdout=False):
|
||||
"""
|
||||
Generates RST documentation.
|
||||
|
||||
:param stdout: if document goes to stdout or not; 'False' by default
|
||||
:type stdout: True or False
|
||||
"""
|
||||
# TODO RST document
|
||||
self.out = f"RST document from :{self.__dict__}"
|
||||
if stdout:
|
||||
self.__output()
|
||||
else:
|
||||
return self.out
|
||||
|
||||
def __build_schema(self):
|
||||
"""
|
||||
|
@ -112,7 +156,6 @@ class YASD:
|
|||
"""
|
||||
for key in ["version", "schemaLocation"]:
|
||||
del self.yaml["schema"][key]
|
||||
self.xsd = BeautifulSoup(parser="xml")
|
||||
schema = self.xsd.new_tag("schema", nsprefix="xs")
|
||||
schema["xmlns:xs"] = "http://www.w3.org/2001/XMLSchema"
|
||||
for key, val in self.yaml["schema"].items():
|
||||
|
@ -152,8 +195,6 @@ class YASD:
|
|||
:param dict el: YASD element
|
||||
:param str tag: tag name for XSD node
|
||||
"""
|
||||
# TODO fix according to 'attribute', 'element' and 'simpleType' refs
|
||||
# https://www.w3schools.com/xml/schema_elements_ref.asp
|
||||
element = self.xsd.new_tag(tag, nsprefix="xs")
|
||||
if "default" in el.keys() and "fixed" in el.keys():
|
||||
del el["fixed"]
|
||||
|
@ -172,8 +213,6 @@ class YASD:
|
|||
|
||||
:param dict el: YASD element
|
||||
"""
|
||||
# TODO fix according to 'element' and 'complexType' refs
|
||||
# https://www.w3schools.com/xml/schema_elements_ref.asp
|
||||
element = self.__build_complex_root(el)
|
||||
complex_type = self.__build_complex_type(el)
|
||||
self.__add_references(complex_type, el, is_attr=True)
|
||||
|
@ -313,32 +352,86 @@ class YASD:
|
|||
del el["description"]
|
||||
return el
|
||||
|
||||
def __stringify_xsd(self):
|
||||
"""
|
||||
Converts BeautifulSoups to pretty text format.
|
||||
"""
|
||||
self.out = self.xsd.prettify(formatter=self.formatter)
|
||||
|
||||
def __output(self, extname=".xsd"):
|
||||
class YASDXML:
|
||||
"""
|
||||
YASD sampler to XML.
|
||||
"""
|
||||
|
||||
# TODO XML Sample
|
||||
|
||||
def __init__(self, yml=None, messenger=None):
|
||||
"""
|
||||
Prints in the terminal or writes into a file.
|
||||
Inits YASD sampler.
|
||||
"""
|
||||
if self.outfile is None:
|
||||
print(self.out)
|
||||
else:
|
||||
suffix = self.outfile.suffix
|
||||
if len(suffix) > 0 and suffix == suffix.replace(" ", ""):
|
||||
extname = suffix
|
||||
filename = f"{self.outfile.stem}{extname}"
|
||||
filename = Path(self.outfile.parent / filename)
|
||||
filename.write_text(self.out)
|
||||
self.msgr = YASDCheck.messenger(messenger)
|
||||
self.yaml = YASDCheck.yaml(yml, self.msgr)
|
||||
self.xml = "XML sample"
|
||||
|
||||
|
||||
class YASDRST:
|
||||
"""
|
||||
YASD document generator to RST.
|
||||
"""
|
||||
|
||||
# TODO RST document
|
||||
|
||||
def __init__(self, yml=None, messenger=None):
|
||||
"""
|
||||
Inits YASD document generator.
|
||||
"""
|
||||
self.msgr = YASDCheck.messenger(messenger)
|
||||
self.yaml = YASDCheck.yaml(yml, self.msgr)
|
||||
self.rst = "RST document"
|
||||
|
||||
|
||||
class YASDCheck:
|
||||
"""
|
||||
YASD input validator.
|
||||
YASD validator.
|
||||
|
||||
Validates everything related to YASD classes.
|
||||
"""
|
||||
|
||||
def messenger(msgr=None):
|
||||
"""
|
||||
Verifies if messenger was initialize.
|
||||
|
||||
:param messenger: Messenger object
|
||||
:type messenger: None or YASDMessenger
|
||||
"""
|
||||
if msgr is None:
|
||||
return YASDMessenger()
|
||||
else:
|
||||
return msgr
|
||||
|
||||
def yaml(yml=None, msgr=None):
|
||||
"""
|
||||
Verifies if yaml exists.
|
||||
|
||||
:param dict yml: YAML object
|
||||
:param msgr: Messenger object
|
||||
:type msgr: None or YASDMessenger
|
||||
"""
|
||||
msgr = YASDCheck.messenger(msgr)
|
||||
if yml is None or type(yml) is not dict:
|
||||
msgr.run("no_yaml", level="error")
|
||||
else:
|
||||
return yml
|
||||
|
||||
def file(filepath=None, msgr=None):
|
||||
"""
|
||||
Verififes if file exists.
|
||||
|
||||
:param filepath: File path
|
||||
:type filepath: None or Path
|
||||
"""
|
||||
msgr = YASDCheck.messenger(msgr)
|
||||
if type(filepath).__module__ != "pathlib":
|
||||
msgr.run("no_input", level="error")
|
||||
elif not filepath.exists() or not filepath.is_file():
|
||||
msgr.run("invalid_input", level="error", file=filepath)
|
||||
return filepath.resolve()
|
||||
|
||||
def __init__(self, indata=None, messenger=None):
|
||||
"""
|
||||
Inits YASD validator.
|
||||
|
@ -348,29 +441,13 @@ class YASDCheck:
|
|||
:param messenger: Object for print or save messages
|
||||
:type messenger: None or YASDMessenger
|
||||
"""
|
||||
if messenger is None:
|
||||
self.msgr = YASDMessenger()
|
||||
else:
|
||||
self.msgr = messenger
|
||||
self.msgr = YASDCheck.messenger(messenger)
|
||||
if type(indata) is dict:
|
||||
self.yaml = indata
|
||||
else:
|
||||
self.yaml = self.parse_file(self.check_file(indata))
|
||||
self.yaml = self.parse_file(YASDCheck.file(indata, self.msgr))
|
||||
self.check_structure()
|
||||
|
||||
def check_file(self, filepath):
|
||||
"""
|
||||
Verifies YASD file.
|
||||
|
||||
:param filepath: YASD file path
|
||||
:type filepath: None or Path
|
||||
"""
|
||||
if type(filepath).__module__ != "pathlib":
|
||||
self.msgr.run("no_input", level="error")
|
||||
elif not filepath.exists() or not filepath.is_file():
|
||||
self.msgr.run("invalid_input", level="error", file=filepath)
|
||||
return filepath.resolve()
|
||||
|
||||
def parse_file(self, filepath):
|
||||
"""
|
||||
Attempts YASD file parsing.
|
||||
|
@ -429,6 +506,7 @@ class YASDMessenger:
|
|||
"invalid_level": "Invalid log level '@lvl'",
|
||||
"invalid_input": "Invalid file '@file'",
|
||||
"invalid_yaml": "Invalid YAML structure",
|
||||
"no_yaml": "YAML dict needed",
|
||||
"no_input": "Input file needed.",
|
||||
}
|
||||
|
||||
|
@ -501,7 +579,14 @@ class YASDCLI:
|
|||
# TODO print man from README
|
||||
print("Manual")
|
||||
else:
|
||||
YASD.do(args.action, args.input, args.output, args.quiet, args.log)
|
||||
YASD.do(
|
||||
args.action,
|
||||
args.input,
|
||||
args.output,
|
||||
args.quiet,
|
||||
args.log,
|
||||
True,
|
||||
)
|
||||
|
||||
def __init_parser(self):
|
||||
"""
|
||||
|
|
Loading…
Reference in New Issue