mirror of
https://github.com/mealie-recipes/mealie.git
synced 2025-07-19 21:29:40 +02:00
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()
|