Files
skill-template/content-manager/content_manager/services/image_service.py
2026-04-04 10:35:02 +08:00

172 lines
5.0 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.
"""图片:业务规则(文件落盘 + 路径写入 images 表)。"""
from __future__ import annotations
import json
import os
import sys
from typing import Any, Dict, Optional
from content_manager.config import get_skill_data_dir, resolve_stored_path
from content_manager.db import images_repository as ir
from content_manager.db.connection import get_conn, init_db
from content_manager.services import file_store
from content_manager.util.timeutil import now_unix, unix_to_iso
def _row_to_public_dict(row: tuple) -> Dict[str, Any]:
rid, file_path, title, status, source, account_id, error_msg, extra_json, cat, uat = row
abs_path = resolve_stored_path(str(file_path))
d: Dict[str, Any] = {
"id": int(rid),
"kind": "image",
"file_path": file_path,
"absolute_path": abs_path,
"title": title,
"status": status or "draft",
"source": source or "manual",
"account_id": account_id,
"error_msg": error_msg,
"created_at": unix_to_iso(cat),
"updated_at": unix_to_iso(uat),
}
if extra_json:
try:
ex = json.loads(extra_json)
if isinstance(ex, dict):
d["extra"] = ex
except json.JSONDecodeError:
pass
return d
def cmd_add(src_file: str, title: Optional[str] = None, source: str = "manual") -> None:
init_db()
src_file = os.path.abspath(src_file.strip())
if not os.path.isfile(src_file):
print(f"❌ 找不到文件:{src_file}")
sys.exit(1)
skill_data = get_skill_data_dir()
ts = now_unix()
conn = get_conn()
try:
new_id = ir.insert_row(
conn,
file_path="",
title=(title or "").strip() or None,
status="draft",
source=source,
account_id=None,
error_msg=None,
extra_json=None,
created_at=ts,
updated_at=ts,
)
rel, _abs = file_store.copy_into_skill_data(skill_data, "images", new_id, src_file)
ir.update_file_path(conn, new_id, rel, now_unix())
conn.commit()
except Exception:
conn.rollback()
raise
finally:
conn.close()
print(f"✅ 已新增图片 id={new_id} | 路径:{rel}")
def cmd_get(image_id: str) -> None:
init_db()
if not str(image_id).strip().isdigit():
print("❌ 图片 id 必须是纯数字。请先 image list 查看。")
sys.exit(1)
iid = int(image_id)
conn = get_conn()
try:
row = ir.fetch_by_id(conn, iid)
finally:
conn.close()
if not row:
print("❌ 没有这条图片记录。")
sys.exit(1)
print(json.dumps(_row_to_public_dict(row), ensure_ascii=False))
def cmd_list(limit: int = 20, max_chars: int = 80) -> None:
init_db()
conn = get_conn()
try:
rows = ir.list_recent(conn, limit)
finally:
conn.close()
if not rows:
print("暂无图片")
return
def trunc(s: str) -> str:
if not s:
return ""
return s if len(s) <= max_chars else s[:max_chars] + "..."
sep = "_" * 39
for idx, r in enumerate(rows):
rid, file_path, title, status, source, account_id, error_msg, extra_json, cat, uat = r
print(f"id{rid}")
print(f"file_path{trunc(str(file_path or ''))}")
print(f"title{title or ''}")
print(f"status{status or ''}")
print(f"source{source or ''}")
print(f"account_id{account_id or ''}")
print(f"error_msg{error_msg or ''}")
print(f"created_at{unix_to_iso(cat) or ''}")
print(f"updated_at{unix_to_iso(uat) or ''}")
if idx != len(rows) - 1:
print(sep)
print()
def cmd_delete(image_id: str) -> None:
init_db()
if not str(image_id).strip().isdigit():
print("❌ 图片 id 必须是纯数字。")
sys.exit(1)
iid = int(image_id)
skill_data = get_skill_data_dir()
conn = get_conn()
try:
row = ir.fetch_by_id(conn, iid)
if not row:
print("❌ 没有 id 为 {} 的图片记录。".format(iid))
sys.exit(1)
rel = row[1]
n = ir.delete_by_id(conn, iid)
if n == 0:
sys.exit(1)
conn.commit()
finally:
conn.close()
file_store.remove_files_for_relative_path(skill_data, str(rel))
print(f"✅ 已删除图片 id={iid}")
def cmd_feedback(
image_id: str,
status: str,
account_id: Optional[str] = None,
error_msg: Optional[str] = None,
) -> None:
init_db()
if not str(image_id).strip().isdigit():
print("❌ 图片 id 必须是纯数字。")
sys.exit(1)
iid = int(image_id)
ts = now_unix()
conn = get_conn()
try:
if ir.fetch_by_id(conn, iid) is None:
print("❌ 没有 id 为 {} 的图片记录。".format(iid))
sys.exit(1)
ir.update_feedback(conn, iid, status, account_id, error_msg, ts)
conn.commit()
finally:
conn.close()
print("✅ 状态已更新")