mirror of
https://github.com/ZoiteChat/zoitechat.git
synced 2026-06-10 08:50:18 +00:00
Fix offline docs install paths
This commit is contained in:
@@ -1,42 +1,89 @@
|
|||||||
#!/usr/bin/env python3
|
#!/usr/bin/env python3
|
||||||
|
|
||||||
import html
|
import html
|
||||||
import io
|
import io
|
||||||
import pathlib
|
import pathlib
|
||||||
import shutil
|
import shutil
|
||||||
import sys
|
import sys
|
||||||
import tarfile
|
import tarfile
|
||||||
|
import tempfile
|
||||||
import urllib.error
|
import urllib.error
|
||||||
import urllib.request
|
import urllib.request
|
||||||
|
|
||||||
|
|
||||||
url = sys.argv[1]
|
url = sys.argv[1]
|
||||||
out_dir = pathlib.Path(sys.argv[2])
|
out_dir = pathlib.Path(sys.argv[2])
|
||||||
source_dir = pathlib.Path(sys.argv[3]) if len(sys.argv) > 3 else pathlib.Path.cwd()
|
source_dir = pathlib.Path(sys.argv[3]) if len(sys.argv) > 3 else pathlib.Path.cwd()
|
||||||
docs_dir = out_dir / 'offline-docs'
|
docs_dir = out_dir / "offline-docs"
|
||||||
|
|
||||||
if docs_dir.exists():
|
if docs_dir.exists():
|
||||||
shutil.rmtree(docs_dir)
|
shutil.rmtree(docs_dir)
|
||||||
docs_dir.mkdir(parents=True, exist_ok=True)
|
docs_dir.mkdir(parents=True, exist_ok=True)
|
||||||
|
|
||||||
def write_source_docs():
|
|
||||||
parts = ['<!doctype html><html><head><meta charset="utf-8"><title>ZoiteChat Documentation</title></head><body><h1>ZoiteChat Documentation</h1>']
|
def write_source_docs() -> None:
|
||||||
for name in ('readme.md', 'troubleshooting.md', 'changelog.rst'):
|
parts = [
|
||||||
|
'<!doctype html><html><head><meta charset="utf-8">'
|
||||||
|
"<title>ZoiteChat Documentation</title></head><body>"
|
||||||
|
"<h1>ZoiteChat Documentation</h1>"
|
||||||
|
]
|
||||||
|
|
||||||
|
for name in ("readme.md", "troubleshooting.md", "changelog.rst"):
|
||||||
path = source_dir / name
|
path = source_dir / name
|
||||||
if path.exists():
|
if path.exists():
|
||||||
parts.append(f'<h2>{html.escape(name)}</h2><pre>{html.escape(path.read_text(encoding="utf-8", errors="replace"))}</pre>')
|
parts.append(
|
||||||
parts.append('</body></html>')
|
f"<h2>{html.escape(name)}</h2>"
|
||||||
(docs_dir / 'index.html').write_text('\n'.join(parts), encoding='utf-8')
|
f"<pre>{html.escape(path.read_text(encoding='utf-8', errors='replace'))}</pre>"
|
||||||
|
)
|
||||||
|
|
||||||
|
parts.append("</body></html>")
|
||||||
|
(docs_dir / "index.html").write_text("\n".join(parts), encoding="utf-8")
|
||||||
|
|
||||||
|
|
||||||
|
def safe_extract(tar: tarfile.TarFile, target: pathlib.Path) -> None:
|
||||||
|
target = target.resolve()
|
||||||
|
|
||||||
|
for member in tar.getmembers():
|
||||||
|
member_path = (target / member.name).resolve()
|
||||||
|
if not str(member_path).startswith(str(target) + "/"):
|
||||||
|
raise tarfile.TarError(f"unsafe archive path: {member.name}")
|
||||||
|
|
||||||
|
tar.extractall(target)
|
||||||
|
|
||||||
|
|
||||||
|
def copy_index_tree(extracted_dir: pathlib.Path) -> bool:
|
||||||
|
indexes = sorted(extracted_dir.rglob("index.html"))
|
||||||
|
if not indexes:
|
||||||
|
return False
|
||||||
|
|
||||||
|
root = indexes[0].parent
|
||||||
|
for item in root.iterdir():
|
||||||
|
dest = docs_dir / item.name
|
||||||
|
if item.is_dir():
|
||||||
|
shutil.copytree(item, dest, dirs_exist_ok=True)
|
||||||
|
else:
|
||||||
|
shutil.copy2(item, dest)
|
||||||
|
|
||||||
|
return (docs_dir / "index.html").exists()
|
||||||
|
|
||||||
|
|
||||||
if url:
|
if url:
|
||||||
try:
|
try:
|
||||||
with urllib.request.urlopen(url, timeout=30) as r:
|
with urllib.request.urlopen(url, timeout=30) as response:
|
||||||
data = r.read()
|
data = response.read()
|
||||||
with tarfile.open(fileobj=io.BytesIO(data), mode='r:gz') as tar:
|
|
||||||
try:
|
with tempfile.TemporaryDirectory() as tmp:
|
||||||
tar.extractall(docs_dir, filter='data')
|
extract_dir = pathlib.Path(tmp)
|
||||||
except TypeError:
|
with tarfile.open(fileobj=io.BytesIO(data), mode="r:gz") as tar:
|
||||||
tar.extractall(docs_dir)
|
safe_extract(tar, extract_dir)
|
||||||
|
|
||||||
|
if not copy_index_tree(extract_dir):
|
||||||
|
write_source_docs()
|
||||||
|
|
||||||
except (OSError, tarfile.TarError, urllib.error.URLError) as error:
|
except (OSError, tarfile.TarError, urllib.error.URLError) as error:
|
||||||
print(f'offline docs download failed: {error}', file=sys.stderr)
|
print(f"offline docs download failed: {error}", file=sys.stderr)
|
||||||
write_source_docs()
|
write_source_docs()
|
||||||
else:
|
else:
|
||||||
write_source_docs()
|
write_source_docs()
|
||||||
(out_dir / 'offline-docs.stamp').write_text('ok')
|
|
||||||
|
(out_dir / "offline-docs.stamp").write_text("ok", encoding="utf-8")
|
||||||
|
|||||||
@@ -57,7 +57,8 @@
|
|||||||
"-Dwith-perl=perl",
|
"-Dwith-perl=perl",
|
||||||
"-Dwith-python=python3",
|
"-Dwith-python=python3",
|
||||||
"-Dwith-lua=lua",
|
"-Dwith-lua=lua",
|
||||||
"-Doffline-docs-package=net.zoite.Zoitechat"
|
"-Doffline-docs-package=net.zoite.Zoitechat",
|
||||||
|
"-Doffline-docs-dir=share/zoitechat/offline-docs"
|
||||||
],
|
],
|
||||||
"build-options": {
|
"build-options": {
|
||||||
"cflags": "-Wno-error=missing-include-dirs"
|
"cflags": "-Wno-error=missing-include-dirs"
|
||||||
|
|||||||
@@ -63,12 +63,12 @@ option('with-perl-legacy-api', type: 'boolean', value: false,
|
|||||||
description: 'Enables the legacy IRC perl module for compatibility with old scripts'
|
description: 'Enables the legacy IRC perl module for compatibility with old scripts'
|
||||||
)
|
)
|
||||||
|
|
||||||
option('offline-docs-url', type: 'string', value: '',
|
option('offline-docs-url', type: 'string', value: 'https://dl.zoitechat.org/offlinedocs/zoitechat-docs-html-2.18.1.tar.gz',
|
||||||
description: 'URL for offline documentation archive (tar.gz)'
|
description: 'URL for offline documentation archive (tar.gz)'
|
||||||
)
|
)
|
||||||
option('offline-docs-package', type: 'string', value: '',
|
option('offline-docs-package', type: 'string', value: '',
|
||||||
description: 'Package or app id to use under the installed documentation directory'
|
description: 'Package or app id to use under the installed documentation directory'
|
||||||
)
|
)
|
||||||
option('offline-docs-dir', type: 'string', value: 'https://dl.zoitechat.org/offlinedocs/zoitechat-docs-html-2.18.1.tar.gz',
|
option('offline-docs-dir', type: 'string', value: '',
|
||||||
description: 'Installed offline documentation directory relative to prefix'
|
description: 'Installed offline documentation directory relative to prefix'
|
||||||
)
|
)
|
||||||
|
|||||||
Reference in New Issue
Block a user