T-583 标题提示词模板数据层
This commit is contained in:
@@ -245,6 +245,10 @@ def title_prompt_path(config=None) -> str:
|
||||
return data_path("title_prompt.txt", config=config)
|
||||
|
||||
|
||||
def title_templates_dir(config=None) -> str:
|
||||
return data_path("prompts", "title", config=config)
|
||||
|
||||
|
||||
def cover_prompts_dir(config=None) -> str:
|
||||
return data_path("prompts", "cover", config=config)
|
||||
|
||||
|
||||
+92
-18
@@ -8,6 +8,7 @@ from importlib import resources
|
||||
from . import appconfig
|
||||
|
||||
TITLE_PROMPT_PATH = appconfig.title_prompt_path()
|
||||
TITLE_TEMPLATES_DIR = appconfig.title_templates_dir()
|
||||
COVER_PROMPTS_DIR = appconfig.cover_prompts_dir()
|
||||
TEMPLATE_EXT = ".txt"
|
||||
INVALID_NAME_CHARS = set('\\/:*?"<>|')
|
||||
@@ -41,6 +42,7 @@ def save_title_prompt(text, path=TITLE_PROMPT_PATH) -> None:
|
||||
def ensure_default_prompts(
|
||||
title_prompt_path=TITLE_PROMPT_PATH,
|
||||
cover_prompts_dir=COVER_PROMPTS_DIR,
|
||||
title_templates_dir=None,
|
||||
) -> None:
|
||||
"""Seed bundled default prompts into an empty user data directory.
|
||||
|
||||
@@ -54,13 +56,20 @@ def ensure_default_prompts(
|
||||
if default_title:
|
||||
save_title_prompt(default_title, title_prompt_path)
|
||||
|
||||
if title_templates_dir is None:
|
||||
title_templates_dir = _title_templates_dir_for_prompt_path(title_prompt_path)
|
||||
if not list_templates(title_templates_dir):
|
||||
default_title = _read_default_prompt_text("title_prompt.txt")
|
||||
if default_title:
|
||||
save_template("默认", default_title, title_templates_dir)
|
||||
|
||||
if not list_cover_templates(cover_prompts_dir):
|
||||
for name, text in _iter_default_cover_templates():
|
||||
save_cover_template(name, text, cover_prompts_dir)
|
||||
|
||||
|
||||
def list_cover_templates(directory=COVER_PROMPTS_DIR):
|
||||
"""Return cover template names sorted by display name."""
|
||||
def list_templates(directory):
|
||||
"""Return prompt template names sorted by display name."""
|
||||
|
||||
if not os.path.isdir(directory):
|
||||
return []
|
||||
@@ -71,18 +80,18 @@ def list_cover_templates(directory=COVER_PROMPTS_DIR):
|
||||
return sorted(names, key=str.casefold)
|
||||
|
||||
|
||||
def load_cover_template(name, directory=COVER_PROMPTS_DIR) -> str:
|
||||
"""Load one cover prompt template."""
|
||||
def load_template(name, directory) -> str:
|
||||
"""Load one prompt template."""
|
||||
|
||||
path = _template_path(name, directory)
|
||||
if not os.path.exists(path):
|
||||
raise PromptError(f"封面提示词模板不存在: {_normalize_name(name)}")
|
||||
raise PromptError(f"提示词模板不存在: {_normalize_name(name)}")
|
||||
with open(path, "r", encoding="utf-8") as fh:
|
||||
return fh.read()
|
||||
|
||||
|
||||
def save_cover_template(name, text, directory=COVER_PROMPTS_DIR) -> None:
|
||||
"""Save one cover prompt template as UTF-8."""
|
||||
def save_template(name, text, directory) -> None:
|
||||
"""Save one prompt template as UTF-8."""
|
||||
|
||||
path = _template_path(name, directory)
|
||||
os.makedirs(os.path.dirname(path), exist_ok=True)
|
||||
@@ -90,26 +99,86 @@ def save_cover_template(name, text, directory=COVER_PROMPTS_DIR) -> None:
|
||||
fh.write(str(text or ""))
|
||||
|
||||
|
||||
def rename_cover_template(old, new, directory=COVER_PROMPTS_DIR) -> None:
|
||||
"""Rename a cover prompt template with duplicate-name protection."""
|
||||
def rename_template(old, new, directory) -> None:
|
||||
"""Rename a prompt template with duplicate-name protection."""
|
||||
|
||||
old_path = _template_path(old, directory)
|
||||
new_path = _template_path(new, directory)
|
||||
if not os.path.exists(old_path):
|
||||
raise PromptError(f"封面提示词模板不存在: {_normalize_name(old)}")
|
||||
raise PromptError(f"提示词模板不存在: {_normalize_name(old)}")
|
||||
if os.path.exists(new_path):
|
||||
raise PromptError(f"封面提示词模板已存在: {_normalize_name(new)}")
|
||||
raise PromptError(f"提示词模板已存在: {_normalize_name(new)}")
|
||||
os.makedirs(os.path.dirname(new_path), exist_ok=True)
|
||||
os.replace(old_path, new_path)
|
||||
|
||||
|
||||
def delete_template(name, directory) -> None:
|
||||
"""Delete one prompt template."""
|
||||
|
||||
path = _template_path(name, directory)
|
||||
if not os.path.exists(path):
|
||||
raise PromptError(f"提示词模板不存在: {_normalize_name(name)}")
|
||||
os.remove(path)
|
||||
|
||||
|
||||
def list_title_templates(directory=TITLE_TEMPLATES_DIR):
|
||||
"""Return title prompt template names sorted by display name."""
|
||||
|
||||
return list_templates(directory)
|
||||
|
||||
|
||||
def load_title_template(name, directory=TITLE_TEMPLATES_DIR) -> str:
|
||||
"""Load one title prompt template."""
|
||||
|
||||
return load_template(name, directory)
|
||||
|
||||
|
||||
def save_title_template(name, text, directory=TITLE_TEMPLATES_DIR) -> None:
|
||||
"""Save one title prompt template as UTF-8."""
|
||||
|
||||
save_template(name, text, directory)
|
||||
|
||||
|
||||
def rename_title_template(old, new, directory=TITLE_TEMPLATES_DIR) -> None:
|
||||
"""Rename a title prompt template with duplicate-name protection."""
|
||||
|
||||
rename_template(old, new, directory)
|
||||
|
||||
|
||||
def delete_title_template(name, directory=TITLE_TEMPLATES_DIR) -> None:
|
||||
"""Delete one title prompt template."""
|
||||
|
||||
delete_template(name, directory)
|
||||
|
||||
|
||||
def list_cover_templates(directory=COVER_PROMPTS_DIR):
|
||||
"""Return cover template names sorted by display name."""
|
||||
|
||||
return list_templates(directory)
|
||||
|
||||
|
||||
def load_cover_template(name, directory=COVER_PROMPTS_DIR) -> str:
|
||||
"""Load one cover prompt template."""
|
||||
|
||||
return load_template(name, directory)
|
||||
|
||||
|
||||
def save_cover_template(name, text, directory=COVER_PROMPTS_DIR) -> None:
|
||||
"""Save one cover prompt template as UTF-8."""
|
||||
|
||||
save_template(name, text, directory)
|
||||
|
||||
|
||||
def rename_cover_template(old, new, directory=COVER_PROMPTS_DIR) -> None:
|
||||
"""Rename a cover prompt template with duplicate-name protection."""
|
||||
|
||||
rename_template(old, new, directory)
|
||||
|
||||
|
||||
def delete_cover_template(name, directory=COVER_PROMPTS_DIR) -> None:
|
||||
"""Delete one cover prompt template."""
|
||||
|
||||
path = _template_path(name, directory)
|
||||
if not os.path.exists(path):
|
||||
raise PromptError(f"封面提示词模板不存在: {_normalize_name(name)}")
|
||||
os.remove(path)
|
||||
delete_template(name, directory)
|
||||
|
||||
|
||||
def render_prompt(template_text, task) -> str:
|
||||
@@ -150,14 +219,19 @@ def _normalize_name(name) -> str:
|
||||
value = value[: -len(TEMPLATE_EXT)]
|
||||
value = value.strip()
|
||||
if not value:
|
||||
raise PromptError("封面提示词模板名不能为空")
|
||||
raise PromptError("提示词模板名不能为空")
|
||||
if value in {".", ".."} or any(char in INVALID_NAME_CHARS for char in value):
|
||||
raise PromptError(f"封面提示词模板名非法: {value}")
|
||||
raise PromptError(f"提示词模板名非法: {value}")
|
||||
if os.path.basename(value) != value:
|
||||
raise PromptError(f"封面提示词模板名非法: {value}")
|
||||
raise PromptError(f"提示词模板名非法: {value}")
|
||||
return value
|
||||
|
||||
|
||||
def _title_templates_dir_for_prompt_path(title_prompt_path) -> str:
|
||||
data_root = os.path.dirname(os.path.abspath(title_prompt_path))
|
||||
return os.path.join(data_root, "prompts", "title")
|
||||
|
||||
|
||||
def _has_non_empty_file(path) -> bool:
|
||||
try:
|
||||
if not os.path.exists(path):
|
||||
|
||||
Reference in New Issue
Block a user