|
|
|
import os
|
|
|
|
import importlib
|
|
|
|
import inspect
|
|
|
|
from pathlib import PurePath
|
|
|
|
import subprocess
|
|
|
|
from typing import TypedDict
|
|
|
|
|
|
|
|
|
|
|
|
def get_defined_functions_and_classes(module):
|
|
|
|
functions = []
|
|
|
|
classes = []
|
|
|
|
|
|
|
|
for name, obj in inspect.getmembers(module):
|
|
|
|
if inspect.isfunction(obj) and obj.__module__ == module.__name__:
|
|
|
|
functions.append(name)
|
|
|
|
elif inspect.isclass(obj) and obj.__module__ == module.__name__:
|
|
|
|
classes.append(name)
|
|
|
|
|
|
|
|
return functions, classes
|
|
|
|
|
|
|
|
|
|
|
|
class IGenerateSphinx(TypedDict):
|
|
|
|
module_path: PurePath
|
|
|
|
module_name: str
|
|
|
|
functions: list[str]
|
|
|
|
classes: list[str]
|
|
|
|
|
|
|
|
|
|
|
|
def generate_sphinx_output(data: list[IGenerateSphinx]):
|
|
|
|
output = []
|
|
|
|
output.append("API Reference\n===============\n")
|
|
|
|
tmp = {}
|
|
|
|
for i in hierarchy.values():
|
|
|
|
tmp[i] = []
|
|
|
|
# tmp[i].append(f"{i}\n{'-'*len(i)}")
|
|
|
|
|
|
|
|
tmp["__OTHER"] = []
|
|
|
|
|
|
|
|
def add_data(_data: IGenerateSphinx, add_to: list):
|
|
|
|
if _data["functions"]:
|
|
|
|
for function in _data["functions"]:
|
|
|
|
add_to.append(f"\n{function}\n" + "~" * len(function))
|
|
|
|
add_to.append(f".. autofunction:: {_data['module_name']}.{function}")
|
|
|
|
|
|
|
|
if _data["classes"]:
|
|
|
|
for class_name in _data["classes"]:
|
|
|
|
add_to.append(f"\n{class_name}\n" + "~" * len(class_name))
|
|
|
|
full_class_name = f"{_data['module_name']}.{class_name}"
|
|
|
|
add_to.append(f".. attributetable:: {full_class_name}")
|
|
|
|
add_to.append(f".. autoclass:: {full_class_name}\n :members:")
|
|
|
|
|
|
|
|
for i in data:
|
|
|
|
add_to = "__OTHER"
|
|
|
|
for category in hierarchy.keys():
|
|
|
|
if PurePath(category).as_posix() in i["module_path"].as_posix():
|
|
|
|
add_to = hierarchy[category]
|
|
|
|
add_data(i, tmp[add_to])
|
|
|
|
|
|
|
|
for k, v in tmp.items():
|
|
|
|
output.append(f"{k}\n{'-'*len(k)}")
|
|
|
|
output.append("\n\n".join(v))
|
|
|
|
return "\n".join(output)
|
|
|
|
|
|
|
|
|
|
|
|
def generate_documentation(base_path, output_file, hierarchy, exclude_files=[]):
|
|
|
|
documentation = []
|
|
|
|
items: list[IGenerateSphinx] = []
|
|
|
|
|
|
|
|
for file in [
|
|
|
|
{"filename": file, "root": root}
|
|
|
|
for root, dirs, files in os.walk(base_path)
|
|
|
|
if root != "__pycache__"
|
|
|
|
for file in files
|
|
|
|
]:
|
|
|
|
if file["filename"].endswith(".py") and file["filename"] not in exclude_files:
|
|
|
|
module_path = os.path.join(file["root"], file["filename"])
|
|
|
|
module_import_path = module_path.replace(os.path.sep, ".").replace(".py", "")
|
|
|
|
|
|
|
|
module = importlib.import_module(module_import_path)
|
|
|
|
functions, classes = get_defined_functions_and_classes(module)
|
|
|
|
if functions or classes:
|
|
|
|
items.append(
|
|
|
|
{
|
|
|
|
"module_path": PurePath(module_path),
|
|
|
|
"module_name": module_import_path,
|
|
|
|
"functions": functions,
|
|
|
|
"classes": classes,
|
|
|
|
}
|
|
|
|
)
|
|
|
|
doc_content = generate_sphinx_output(items)
|
|
|
|
documentation.append(doc_content)
|
|
|
|
with open(output_file, "w", encoding="utf-8") as doc_file:
|
|
|
|
doc_file.write("\n\n".join(documentation))
|
|
|
|
|
|
|
|
|
|
|
|
if __name__ == "__main__":
|
|
|
|
hierarchy = {
|
|
|
|
"mipac/models": "Misskey Models",
|
|
|
|
"mipac/manager": "Managers",
|
|
|
|
"mipac/actions": "Actions",
|
|
|
|
"mipac/types": "Type class",
|
|
|
|
"mipac/errors": "Errors",
|
|
|
|
}
|
|
|
|
source_path = "mipac"
|
|
|
|
output_path = "docs/index.rst"
|
|
|
|
excluded_files = ["__init__.py", "_version.py"] # Add files to exclude here
|
|
|
|
generate_documentation(source_path, output_path, hierarchy, exclude_files=excluded_files)
|
|
|
|
os.chdir("./docs")
|
|
|
|
subprocess.run(
|
|
|
|
"make gettext && sphinx-intl update -p _build/gettext && ./doc_builder.sh", shell=True
|
|
|
|
)
|