import json import os import re import shutil import traceback from datetime import datetime from pathlib import Path from textwrap import shorten from typing import Dict, List, TextIO, Union from openbb_terminal.core.session.current_system import set_system_variable from openbb_terminal.core.session.current_user import get_current_user from openbb_terminal.rich_config import console from website.controller_doc_classes import ( ControllerDoc, LoadControllersDoc, sub_names_full as subnames, ) set_system_variable("TEST_MODE", True) set_system_variable("LOG_COLLECT", False) website_path = Path(__file__).parent.absolute() reference_import = """ import ReferenceCard from "@site/src/components/General/ReferenceCard"; \n") def main() -> bool: """Main function to generate markdown files""" console.print( "[bright_yellow]Loading Controllers... Please wait and ignore any errors, this is normal.[/bright_yellow]" ) load_ctrls = LoadControllersDoc() ctrls = load_ctrls.available_controllers() wopen_kwargs = {"encoding": "utf-8", "newline": "\n"} console.print( "[bright_yellow]Generating markdown files... Don't ignore any errors now[/bright_yellow]" ) content_path: Path = website_path / "content/terminal/reference" reference_cards: Dict[Path, List[Dict[str, str]]] = {} for file in content_path.glob("*"): if file.is_file(): file.unlink() else: shutil.rmtree(file) for ctrl_trailmap in ctrls: try: ctrl = load_ctrls.get_controller_doc(ctrl_trailmap) ctrl_cmds = process_cmd_parsers(ctrl) for cmd in ctrl_cmds: examples = existing_markdown_file_examples(ctrl_trailmap, cmd) markdown = generate_markdown(cmd, examples) if cmd["cmd_name"] == "index": cmd["cmd_name"] = "index_cmd" trail = ctrl_trailmap.split(".") filepath = content_path / f"{'/'.join(trail)}/{cmd['cmd_name']}.md" reference_cards.setdefault(filepath.parent, []).append( dict( title=cmd["cmd_name"], description=cmd["description"], url="/".join(trail), ) ) filepath.parent.mkdir(parents=True, exist_ok=True) with open(filepath, "w", **wopen_kwargs) as f: # type: ignore f.write(markdown) except Exception as e: traceback.print_exc() console.print( f"[red]Failed to generate markdown for {ctrl_trailmap}: {e}[/red]" ) return False # Sort reference_cards reference_cards = dict(sorted(reference_cards.items(), key=lambda item: item[0])) # Generate root "_category_.json" file with open(content_path / "_category_.json", "w", **wopen_kwargs) as f: # type: ignore f.write(json.dumps({"label": "Terminal Reference", "position": 4}, indent=2)) # Generate root "index.md" file with open(content_path / "index.mdx", "w", **wopen_kwargs) as f: # type: ignore fname = "OpenBB Terminal Features" rel_path = content_path.relative_to(content_path) write_reference_index(reference_cards, fname, content_path, rel_path, f) def gen_category_json(fname: str, path: Path): """Generate category json""" fname = subnames[fname.lower()] if fname.lower() in subnames else fname.title() with open(path / "_category_.json", "w", **wopen_kwargs) as f: # type: ignore f.write(json.dumps({"label": fname}, indent=2)) with open(path / "index.mdx", "w", **wopen_kwargs) as f: # type: ignore rel_path = path.relative_to(content_path) write_reference_index(reference_cards, fname, path, rel_path, f) def gen_category_recursive(nested_path: Path): """Generate category json recursively""" for folder in nested_path.iterdir(): if folder.is_dir(): gen_category_json(folder.name, folder) gen_category_recursive(folder) # pylint: disable=cell-var-from-loop # Generate modules/sub category json and index files gen_category_recursive(content_path) console.print( "[green]Markdown files generated, check the website/content/terminal/reference/ folder[/green]" ) return True if __name__ == "__main__": main()