mirror of
https://github.com/mealie-recipes/mealie.git
synced 2024-12-21 19:41:22 -08:00
9e77a9f367
* upgrade sqlalchemy to 2.0 * rewrite all db models to sqla 2.0 mapping api * fix some importing and typing weirdness * fix types of a lot of nullable columns * remove get_ref methods * fix issues found by tests * rewrite all queries in repository_recipe to 2.0 style * rewrite all repository queries to 2.0 api * rewrite all remaining queries to 2.0 api * remove now-unneeded __allow_unmapped__ flag * remove and fix some unneeded cases of "# type: ignore" * fix formatting * bump black version * run black * can this please be the last one. okay. just. okay. * fix repository errors * remove return * drop open API validator --------- Co-authored-by: Sören Busch <fleshgolem@gmx.net>
101 lines
2.5 KiB
Python
101 lines
2.5 KiB
Python
import pathlib
|
|
import re
|
|
from dataclasses import dataclass, field
|
|
|
|
from utils import PROJECT_DIR, log, render_python_template
|
|
|
|
template = """# This file is auto-generated by gen_schema_exports.py
|
|
{% for file in data.module.files %}{{ file.import_str() }}
|
|
{% endfor %}
|
|
|
|
__all__ = [
|
|
{% for file in data.module.files %}
|
|
{%- for class in file.classes -%}
|
|
"{{ class }}",
|
|
{%- endfor -%}
|
|
{%- endfor %}
|
|
]
|
|
|
|
"""
|
|
|
|
SCHEMA_PATH = PROJECT_DIR / "mealie" / "schema"
|
|
|
|
SKIP = {"static", "__pycache__"}
|
|
|
|
|
|
class PyFile:
|
|
import_path: str
|
|
"""The import path of the file"""
|
|
|
|
classes: list[str]
|
|
"""A list of classes in the file"""
|
|
|
|
def __init__(self, path: pathlib.Path):
|
|
self.import_path = path.stem
|
|
self.classes = []
|
|
|
|
self.classes = PyFile.extract_classes(path)
|
|
self.classes.sort()
|
|
|
|
def import_str(self) -> str:
|
|
"""Returns a string that can be used to import the file"""
|
|
return f"from .{self.import_path} import {', '.join(self.classes)}"
|
|
|
|
@staticmethod
|
|
def extract_classes(file_path: pathlib.Path) -> list[str]:
|
|
name = file_path.stem
|
|
|
|
if name == "__init__" or name.startswith("_"):
|
|
return []
|
|
|
|
classes = re.findall(r"(?m)^class\s(\w+)", file_path.read_text())
|
|
return classes
|
|
|
|
|
|
@dataclass
|
|
class Modules:
|
|
directory: pathlib.Path
|
|
"""The directory to search for modules"""
|
|
|
|
files: list[PyFile] = field(default_factory=list)
|
|
"""A list of files in the directory"""
|
|
|
|
def __post_init__(self):
|
|
for file in self.directory.glob("*.py"):
|
|
if file.name.startswith("_"):
|
|
continue
|
|
|
|
pfile = PyFile(file)
|
|
|
|
if len(pfile.classes) > 0:
|
|
self.files.append(pfile)
|
|
|
|
else:
|
|
log.debug(f"Skipping {file.name} as it has no classes")
|
|
|
|
|
|
def find_modules(root: pathlib.Path) -> list[Modules]:
|
|
"""Finds all the top level modules in the provided folder"""
|
|
modules: list[Modules] = []
|
|
for file in root.iterdir():
|
|
if file.is_dir() and file.name not in SKIP:
|
|
modules.append(Modules(directory=file))
|
|
|
|
return modules
|
|
|
|
|
|
def main():
|
|
modules = find_modules(SCHEMA_PATH)
|
|
|
|
for module in modules:
|
|
log.debug(f"Module: {module.directory.name}")
|
|
for file in module.files:
|
|
log.debug(f" File: {file.import_path}")
|
|
log.debug(f" Classes: [{', '.join(file.classes)}]")
|
|
|
|
render_python_template(template, module.directory / "__init__.py", {"module": module})
|
|
|
|
|
|
if __name__ == "__main__":
|
|
main()
|