Files
holy-python/rule_service.py
2026-08-04 14:02:45 +08:00

104 lines
3.2 KiB
Python
Raw Permalink 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.
from pathlib import Path
from typing import Any
from flask import Request
from config import Config
from database import json_dumps, json_loads, now_iso
from task_service import TaskError
RULE_DIR = Config.FILE_STORAGE_PATH / "rules"
RULE_HTML_PATH = RULE_DIR / "current.html"
RULE_META_PATH = RULE_DIR / "current.json"
def _ensure_rule_dir() -> None:
RULE_DIR.mkdir(parents=True, exist_ok=True)
def _read_text(path: Path) -> str:
return path.read_text(encoding="utf-8")
def get_rule_document() -> dict[str, Any]:
"""读取当前规则 HTML 的公开元数据。"""
if not RULE_HTML_PATH.exists():
return {
"exists": False,
"title": "",
"filename": "",
"updated_at": None,
"size_bytes": 0,
"html_url": "/api/v1/rules/current.html",
}
metadata = json_loads(_read_text(RULE_META_PATH)) if RULE_META_PATH.exists() else {}
stat = RULE_HTML_PATH.stat()
return {
"exists": True,
"title": metadata.get("title") or "小红书问一问收录规则探索",
"filename": metadata.get("filename") or RULE_HTML_PATH.name,
"updated_at": metadata.get("updated_at"),
"size_bytes": stat.st_size,
"html_url": "/api/v1/rules/current.html",
}
def get_rule_html_path() -> Path:
if not RULE_HTML_PATH.exists():
raise TaskError("RULE_NOT_FOUND", "当前没有已上传的规则 HTML", 404)
return RULE_HTML_PATH
def save_rule_document(request: Request) -> dict[str, Any]:
"""保存当前规则 HTML支持 multipart 文件、JSON html 字段和 text/html 原文。"""
filename = "current.html"
title = "小红书问一问收录规则探索"
html = ""
uploaded = request.files.get("file")
if uploaded:
filename = uploaded.filename or filename
html = uploaded.read().decode("utf-8")
title = request.form.get("title") or title
else:
payload = request.get_json(silent=True)
if isinstance(payload, dict):
html = str(payload.get("html") or "")
filename = str(payload.get("filename") or filename)
title = str(payload.get("title") or title)
else:
html = request.get_data(as_text=True) or ""
title = request.args.get("title") or title
filename = request.args.get("filename") or filename
if not html.strip():
raise TaskError("RULE_HTML_REQUIRED", "html 内容不能为空", 400)
if "<html" not in html.lower() and "<!doctype html" not in html.lower():
raise TaskError("RULE_HTML_INVALID", "请上传完整 HTML 文档", 400)
_ensure_rule_dir()
updated_at = now_iso()
RULE_HTML_PATH.write_text(html, encoding="utf-8")
RULE_META_PATH.write_text(
json_dumps({
"title": title,
"filename": filename,
"updated_at": updated_at,
}),
encoding="utf-8",
)
return get_rule_document()
def delete_rule_document() -> dict[str, Any]:
"""删除当前规则 HTML 和元数据。"""
deleted = False
for path in (RULE_HTML_PATH, RULE_META_PATH):
if path.exists():
path.unlink()
deleted = True
return {"deleted": deleted, **get_rule_document()}