authoring server 4
All checks were successful
Build Org Website / build (push) Successful in 44s

This commit is contained in:
2026-05-07 13:53:45 +01:00
parent d33e1771af
commit 2fd5a098b1
7 changed files with 75 additions and 11 deletions

View File

@@ -6,7 +6,9 @@ from __future__ import annotations
import json
import mimetypes
import os
import posixpath
import re
import struct
import subprocess
import sys
import threading
@@ -455,7 +457,61 @@ def save_page(data: dict[str, Any]) -> dict[str, Any]:
return page_to_dict(read_page(target))
def save_upload(filename: str, payload: bytes) -> dict[str, str]:
def image_dimensions(payload: bytes, ext: str) -> tuple[int, int] | None:
if ext == ".png" and payload.startswith(b"\x89PNG\r\n\x1a\n") and len(payload) >= 24:
width, height = struct.unpack(">II", payload[16:24])
return width, height
if ext == ".gif" and payload[:6] in {b"GIF87a", b"GIF89a"} and len(payload) >= 10:
width, height = struct.unpack("<HH", payload[6:10])
return width, height
if ext in {".jpg", ".jpeg"} and payload.startswith(b"\xff\xd8"):
i = 2
while i + 9 < len(payload):
if payload[i] != 0xFF:
i += 1
continue
marker = payload[i + 1]
i += 2
if marker in {0xD8, 0xD9}:
continue
if i + 2 > len(payload):
break
size = int.from_bytes(payload[i:i + 2], "big")
if size < 2:
break
if marker in {0xC0, 0xC1, 0xC2, 0xC3, 0xC5, 0xC6, 0xC7, 0xC9, 0xCA, 0xCB, 0xCD, 0xCE, 0xCF}:
if i + 7 <= len(payload):
height = int.from_bytes(payload[i + 3:i + 5], "big")
width = int.from_bytes(payload[i + 5:i + 7], "big")
return width, height
break
i += size
return None
def relative_asset_path(page_path: str, asset_path: str) -> str:
page = safe_relative_path(page_path) if page_path else LIMA_DIR / "index.md"
if page.suffix != ".md" or not page.is_relative_to(LIMA_DIR):
page = LIMA_DIR / "index.md"
page_rel = page.relative_to(ROOT).as_posix()
page_output_dir = posixpath.dirname(page_rel)
return posixpath.relpath(asset_path, page_output_dir or ".")
def gallery_image_html(filename: str, asset_path: str, page_path: str, payload: bytes, ext: str) -> str:
absolute_url = f"https://zainezq.com/{asset_path}"
relative_url = relative_asset_path(page_path, asset_path)
dims = image_dimensions(payload, ext)
width, height = dims if dims else (1920, 1080)
alt = html_escape(filename)
return (
f'<a href="{absolute_url}" data-img="{absolute_url}" data-alt="{alt}" '
f'data-width="{width}" data-height="{height}">'
f'<img src="{relative_url}" alt="{alt}" style="cursor: zoom-in;"></a>'
)
def save_upload(filename: str, payload: bytes, page_path: str = "") -> dict[str, str]:
original = Path(filename or "attachment").name
ext = Path(original).suffix.lower()
if ext not in ALLOWED_UPLOAD_EXTENSIONS:
@@ -471,14 +527,20 @@ def save_upload(filename: str, payload: bytes) -> dict[str, str]:
counter += 1
target.write_bytes(payload)
rel = target.relative_to(ROOT).as_posix()
url = f"/{rel}"
absolute_url = f"https://zainezq.com/{rel}"
relative_url = relative_asset_path(page_path, rel)
mime = mimetypes.guess_type(target.name)[0] or ""
alt = Path(original).stem.replace("-", " ").replace("_", " ").strip() or "attachment"
if mime.startswith("video/") or ext in {".mp4", ".webm", ".mov"}:
markdown = f'<video controls src="{url}"></video>'
markdown = f'<video controls src="{relative_url}"></video>'
else:
markdown = f"![{alt}]({url})"
return {"url": url, "path": rel, "markdown": markdown, "filename": target.name}
markdown = gallery_image_html(target.name, rel, page_path, payload, ext)
return {
"url": absolute_url,
"relativeUrl": relative_url,
"path": rel,
"markdown": markdown,
"filename": target.name,
}
def run_build_commands() -> tuple[bool, str, str]:
@@ -893,6 +955,7 @@ APP_HTML = r"""<!doctype html>
saveMessage.textContent = "Uploading attachment.";
const body = new FormData();
body.append("attachment", file);
body.append("pagePath", state.currentPath || editor.targetPath.value || "lima/index.md");
try {
const res = await fetch("/api/upload", { method: "POST", body });
const data = await res.json();
@@ -974,7 +1037,10 @@ class Handler(BaseHTTPRequestHandler):
payload = field.file.read()
if not payload:
raise ValueError("Attachment is empty.")
self.send_json(save_upload(field.filename, payload))
page_path = ""
if "pagePath" in form:
page_path = str(form["pagePath"].value or "")
self.send_json(save_upload(field.filename, payload, page_path))
except Exception as exc:
self.send_json({"error": str(exc)}, HTTPStatus.BAD_REQUEST)
return