#!/usr/bin/env python3 import html import os import sys from collections import defaultdict from contextlib import suppress from typing import Any, Dict, List, Set sys.path.insert(0, os.path.join(os.path.dirname(__file__), "..")) # check for the venv from tools.lib import sanity_check sanity_check.check_venv(__file__) import orjson Call = Dict[str, Any] def clean_up_pattern(s: str) -> str: paren_level = 0 in_braces = False result = "" prior_char = None for c in s: if c == "(": paren_level += 1 if c == "<" and prior_char == "P": in_braces = True if (in_braces or paren_level == 0) and c != "?": result += c if c == ")": paren_level -= 1 if c == ">": in_braces = False prior_char = c return result def fix_test_name(s: str) -> str: return s.replace("zerver.tests.", "") def create_single_page(pattern: str, out_dir: str, href: str, calls: List[Call]) -> None: fn = out_dir + "/" + href with open(fn, "w") as f: f.write( """ """ ) f.write(f"

{html.escape(pattern)}

\n") calls.sort(key=lambda call: call["status_code"]) for call in calls: f.write("
") f.write("\n{}".format(fix_test_name(call["test_name"]))) f.write('
') f.write(call["url"]) f.write("
\n") f.write(call["method"] + "
\n") f.write("status code: {}
\n".format(call["status_code"])) f.write("
") f.write("
") def create_user_docs() -> None: fn = "var/url_coverage.txt" # TODO: make path more robust, maybe use json suffix out_dir = "var/api_docs" with suppress(OSError): os.mkdir(out_dir) main_page = out_dir + "/index.html" with open(main_page, "w") as f: f.write( """ """ ) with open(fn, "rb") as coverage: calls = [orjson.loads(line) for line in coverage] pattern_dict: Dict[str, List[Call]] = defaultdict(list) for call in calls: if "pattern" in call: pattern = clean_up_pattern(call["pattern"]) if pattern: pattern_dict[pattern].append(call) patterns = set(pattern_dict.keys()) tups = [ ("api/v1/external", "webhooks"), ("api/v1", "api"), ("json", "legacy"), ] groups: Dict[str, Set[str]] = {} for prefix, name in tups: groups[name] = {p for p in patterns if p.startswith(prefix)} patterns -= groups[name] groups["other"] = patterns for name in ["api", "legacy", "webhooks", "other"]: f.write(name + " endpoints:\n\n") f.write("") f.write("\n") print(f"open {main_page}") if __name__ == "__main__": create_user_docs()