Fix Gitea wiki filenames: use percent-encoded Cyrillic slugs.
Unicode names caused HTTP 500 in the wiki UI; match Gitea storage format.
This commit is contained in:
+20
-21
@@ -10,7 +10,8 @@ from export1c_help.discover import HelpPage
|
||||
|
||||
_INVALID = re.compile(r'[\\/:*?"<>|#\[\]]+')
|
||||
_SPACES = re.compile(r"\s+")
|
||||
_MAX_NAME_BYTES = 180
|
||||
# Keep slug short so percent-encoded form fits in 255-byte FS names
|
||||
_MAX_SLUG_BYTES = 72
|
||||
|
||||
|
||||
def sanitize_title(title: str) -> str:
|
||||
@@ -38,17 +39,21 @@ def _short_hash(s: str) -> str:
|
||||
|
||||
|
||||
def wiki_filename(title: str, *, meta_key: str | None = None) -> str:
|
||||
"""Unicode wiki slug (spaces → «-»)."""
|
||||
slug = sanitize_title(title).replace(" ", "-")
|
||||
# reserve room for optional -xxxxxxxx suffix
|
||||
slug = _truncate_utf8(slug, _MAX_NAME_BYTES)
|
||||
return f"{slug}.md"
|
||||
"""
|
||||
Gitea wiki stores non-ASCII page names as percent-encoded «Slug.md».
|
||||
|
||||
|
||||
def wiki_filename_gitea_legacy(title: str) -> str:
|
||||
Slug = title with spaces → «-», truncated so encoded length ≤ 255.
|
||||
"""
|
||||
slug = sanitize_title(title).replace(" ", "-")
|
||||
slug = _truncate_utf8(slug, 80)
|
||||
return quote(slug, safe="-_.") + ".md"
|
||||
slug = _truncate_utf8(slug, _MAX_SLUG_BYTES)
|
||||
if meta_key:
|
||||
# stable disambiguator when truncated
|
||||
pass
|
||||
encoded = quote(slug, safe="-_.") + ".md"
|
||||
if len(encoded) > 255 and meta_key:
|
||||
slug = _truncate_utf8(slug, 50) + "-" + _short_hash(meta_key)
|
||||
encoded = quote(slug, safe="-_.") + ".md"
|
||||
return encoded
|
||||
|
||||
|
||||
def decode_wiki_filename(name: str) -> str:
|
||||
@@ -60,11 +65,7 @@ def assign_titles(
|
||||
pages: list[HelpPage],
|
||||
h1_by_meta: dict[str, str | None],
|
||||
) -> tuple[dict[str, str], dict[str, str]]:
|
||||
"""
|
||||
Returns (meta_key → title, meta_key → filename).
|
||||
|
||||
Filenames are unique even after UTF-8 truncation.
|
||||
"""
|
||||
"""Returns (meta_key → title, meta_key → filename)."""
|
||||
used_title: set[str] = set()
|
||||
used_file: set[str] = set()
|
||||
titles: dict[str, str] = {}
|
||||
@@ -87,15 +88,13 @@ def assign_titles(
|
||||
title = sanitize_title(p.meta_key)
|
||||
break
|
||||
|
||||
fname = wiki_filename(title)
|
||||
fname = wiki_filename(title, meta_key=p.meta_key)
|
||||
if fname.casefold() in used_file:
|
||||
stem = fname[:-3]
|
||||
stem = _truncate_utf8(stem, _MAX_NAME_BYTES - 9)
|
||||
fname = f"{stem}-{_short_hash(p.meta_key)}.md"
|
||||
# last-resort unique
|
||||
slug = _truncate_utf8(sanitize_title(title).replace(" ", "-"), 50)
|
||||
fname = quote(f"{slug}-{_short_hash(p.meta_key)}", safe="-_.") + ".md"
|
||||
guard = 0
|
||||
while fname.casefold() in used_file:
|
||||
fname = f"page-{_short_hash(p.meta_key + str(guard))}.md"
|
||||
fname = quote(f"page-{_short_hash(p.meta_key + str(guard))}", safe="-_.") + ".md"
|
||||
guard += 1
|
||||
|
||||
used_title.add(title.casefold())
|
||||
|
||||
Reference in New Issue
Block a user