docs read fix
This commit is contained in:
+43
-13
@@ -32,6 +32,13 @@ MAX_DOC_FILES = 100
|
||||
MAX_DOC_BYTES = 300_000
|
||||
REQUEST_TIMEOUT = 8
|
||||
|
||||
# Gitea si u stromu repozitáře vynucuje vlastní stránkování (api.DEFAULT_PAGING_NUM, ve
|
||||
# výchozím nastavení 30 položek) a náš per_page si klidně sníží. Strom vrací VŠECHNY soubory,
|
||||
# ne jen *.md, takže bez dotažení dalších stránek by se dokumentace ve větším repu vůbec
|
||||
# nenašla. Proto čteme stránku po stránce, dokud Gitea hlásí truncated.
|
||||
TREE_PAGE_SIZE = 100
|
||||
MAX_TREE_PAGES = 50
|
||||
|
||||
|
||||
class RepoDocsError(RuntimeError):
|
||||
"""Dokumentaci se nepodařilo načíst (chybí token, Gitea je nedostupná, repo neexistuje)."""
|
||||
@@ -65,16 +72,31 @@ def list_markdown_files(repo: str, branch: str = "") -> list[dict]:
|
||||
raise RepoDocsError("Služba nemá evidovaný název repozitáře.")
|
||||
|
||||
ref = (branch or "").strip() or _default_branch(repo)
|
||||
payload = _request_json(f"/api/v1/repos/{quote(gitea_org())}/{quote(repo)}/git/trees/{quote(ref, safe='')}?recursive=true&per_page=1000")
|
||||
tree_url = f"/api/v1/repos/{quote(gitea_org())}/{quote(repo)}/git/trees/{quote(ref, safe='')}"
|
||||
|
||||
files = []
|
||||
for entry in payload.get("tree") or []:
|
||||
if entry.get("type") != "blob":
|
||||
continue
|
||||
path = entry.get("path") or ""
|
||||
if not is_markdown_path(path):
|
||||
continue
|
||||
files.append({"path": path, "size": int(entry.get("size") or 0)})
|
||||
seen_entries = 0
|
||||
for page in range(1, MAX_TREE_PAGES + 1):
|
||||
payload = _request_json(f"{tree_url}?recursive=true&per_page={TREE_PAGE_SIZE}&page={page}")
|
||||
entries = payload.get("tree") or []
|
||||
if not entries:
|
||||
break
|
||||
|
||||
seen_entries += len(entries)
|
||||
for entry in entries:
|
||||
if entry.get("type") != "blob":
|
||||
continue
|
||||
path = entry.get("path") or ""
|
||||
if not is_markdown_path(path):
|
||||
continue
|
||||
files.append({"path": path, "size": int(entry.get("size") or 0)})
|
||||
|
||||
total_count = int(payload.get("total_count") or 0)
|
||||
if not payload.get("truncated") or (total_count and seen_entries >= total_count):
|
||||
break
|
||||
if len(files) >= MAX_DOC_FILES:
|
||||
logger.info("Repozitář %s má více než %s souborů *.md, seznam je zkrácený.", repo, MAX_DOC_FILES)
|
||||
break
|
||||
|
||||
files.sort(key=lambda item: (item["path"].count("/"), item["path"].lower()))
|
||||
return files[:MAX_DOC_FILES]
|
||||
@@ -105,19 +127,23 @@ def read_markdown(repo: str, path: str, branch: str = "") -> str:
|
||||
def render_markdown(text: str, repo: str) -> str:
|
||||
"""Vyrenderuje markdown do HTML přes Gitea API.
|
||||
|
||||
Portál nemá markdown knihovnu a Gitea render umí a zároveň si výstupní HTML sanitizuje.
|
||||
Když render selže, vrátíme obsah jako neformátovaný (escapovaný) text - náhled tak
|
||||
funguje i při výpadku render endpointu.
|
||||
Portál nemá markdown knihovnu, Gitea render umí a zároveň si výstupní HTML sanitizuje.
|
||||
Náhled ale nesmí skončit prázdný: když render selže NEBO vrátí prázdné tělo (Gitea to
|
||||
dělá i bez chybové hlášky, např. když si nepřečte pole text), zobrazíme obsah souboru
|
||||
jako neformátovaný escapovaný text.
|
||||
"""
|
||||
if not text.strip():
|
||||
return '<p class="muted">Soubor je prázdný.</p>'
|
||||
|
||||
payload = json.dumps(
|
||||
{
|
||||
"text": text,
|
||||
"mode": "gfm",
|
||||
"context": f"/{gitea_org()}/{repo}",
|
||||
"wiki": False,
|
||||
}
|
||||
).encode("utf-8")
|
||||
|
||||
rendered = ""
|
||||
try:
|
||||
rendered = _request_bytes(
|
||||
"/api/v1/markdown",
|
||||
@@ -126,11 +152,15 @@ def render_markdown(text: str, repo: str) -> str:
|
||||
accept="text/html",
|
||||
content_type="application/json",
|
||||
).decode("utf-8", errors="replace")
|
||||
return f'<div class="md-body">{rendered}</div>'
|
||||
except RepoDocsError as exc:
|
||||
logger.warning("Gitea markdown render selhal (%s), zobrazuji neformátovaný text: %s", repo, exc)
|
||||
|
||||
if not rendered.strip():
|
||||
logger.warning("Gitea markdown render vrátil prázdný výstup (%s), zobrazuji neformátovaný text.", repo)
|
||||
return f'<pre class="md-raw">{html.escape(text)}</pre>'
|
||||
|
||||
return f'<div class="md-body">{rendered}</div>'
|
||||
|
||||
|
||||
def _default_branch(repo: str) -> str:
|
||||
"""Výchozí větev repozitáře podle Gitea (služby zakládané portálem mají main)."""
|
||||
|
||||
Reference in New Issue
Block a user