Files
auto_news_upload/modules/package.py
T
2026-10-31 16:15:04 +08:00

64 lines
3.1 KiB
Python
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
#!/usr/bin/env python3
"""Build a portable v1 article package for the DWW11 userscript (standard library only)."""
from __future__ import annotations
import argparse
import base64
import json
import mimetypes
from pathlib import Path
def make_package(directory: str | Path, markdown: str | None = None) -> dict:
"""Return JSON-serializable data; no network access or publishing side effects."""
root = Path(directory).expanduser().resolve(strict=True)
if not root.is_dir():
raise ValueError("文章目录不存在")
choices = sorted(path for path in root.rglob("*") if path.is_file() and path.suffix.lower() == ".md")
if markdown:
selected = (root / markdown).resolve(strict=True)
elif len(choices) == 1:
selected = choices[0].resolve()
else:
raise ValueError("目录必须包含一个 Markdown 文件,或通过 --markdown 指定目录内相对路径")
if not selected.is_relative_to(root) or selected.suffix.lower() != ".md" or not selected.is_file():
raise ValueError("Markdown 必须位于所选文章目录内")
images = []
# Package local supported images. The importer uploads only those referenced by Markdown.
for path in sorted(root.rglob("*")):
if not path.is_file() or path.suffix.lower() not in {".jpg", ".jpeg", ".png", ".gif"}:
continue
if not path.resolve().is_relative_to(root):
raise ValueError(f"图片符号链接指向目录外:{path.name}")
if not 0 < path.stat().st_size < 20 * 1024 * 1024:
raise ValueError(f"图片为空或达到 20 MB:{path.name}")
images.append({"path": path.relative_to(root).as_posix(),
"mime": mimetypes.guess_type(path.name)[0] or "application/octet-stream",
"base64": base64.b64encode(path.read_bytes()).decode("ascii")})
return {"schemaVersion": 1, "markdownPath": selected.relative_to(root).as_posix(),
"markdown": selected.read_text(encoding="utf-8-sig"), "images": images}
def main() -> None:
parser = argparse.ArgumentParser(description="把文章目录打包为油猴脚本可导入的 JSON;不上传或发布")
parser.add_argument("directory", help="包含 Markdown 和图片的目录")
parser.add_argument("--markdown", help="多个 Markdown 时指定目录内的相对路径")
parser.add_argument("-o", "--output", help="输出文件路径;未指定时输出到标准输出")
args = parser.parse_args()
try:
content = json.dumps(make_package(args.directory, args.markdown), ensure_ascii=False, indent=2)
if args.output:
output = Path(args.output).expanduser()
# Never silently overwrite an article or an existing package.
with output.open("x", encoding="utf-8") as handle:
handle.write(content + "\n")
print(json.dumps({"ok": True, "package": str(output.resolve())}, ensure_ascii=False))
else:
print(content)
except (OSError, ValueError) as error:
parser.exit(1, f"打包失败:{error}\n")
if __name__ == "__main__":
main()