2026-09-03 00:44:38 +08:00
|
|
|
"""otto 活字印刷 —— 入口(元数据 + 依赖)。"""
|
2026-09-01 13:13:40 +08:00
|
|
|
|
2026-09-03 00:44:38 +08:00
|
|
|
from __future__ import annotations
|
|
|
|
|
|
|
|
|
|
from pathlib import Path
|
|
|
|
|
|
|
|
|
|
from nonebot import get_driver, require
|
2026-09-01 13:13:40 +08:00
|
|
|
from nonebot.plugin import PluginMetadata
|
|
|
|
|
|
|
|
|
|
require("nonebot_plugin_alconna")
|
|
|
|
|
|
|
|
|
|
__plugin_meta__ = PluginMetadata(
|
|
|
|
|
name="otto活字印刷",
|
|
|
|
|
description="鬼畜音源活字印刷(otto语音合成)",
|
|
|
|
|
usage="otto 一些内容 生成otto语音\notto 一些内容 -reverse 生成并倒放",
|
|
|
|
|
type="application",
|
|
|
|
|
)
|
|
|
|
|
|
2026-09-03 00:44:38 +08:00
|
|
|
_PLUGIN_ROOT = Path(__file__).resolve().parent
|
|
|
|
|
# 生成音频统一落到 hexi/data/temp/otto(与 video_analysis 的临时目录约定一致)。
|
|
|
|
|
# 协议端(NapCat)通常与 bot 后端不在同一台机器,无法直接访问本地文件,
|
|
|
|
|
# 所以先落盘再通过 FastAPI 路由以 http URL 提供给 NapCat 下载。
|
|
|
|
|
_TEMP_ROOT = _PLUGIN_ROOT.parent.parent / "data" / "temp" / "otto"
|
|
|
|
|
|
|
|
|
|
_driver = get_driver()
|
|
|
|
|
|
2026-09-01 13:13:40 +08:00
|
|
|
|
2026-09-03 00:44:38 +08:00
|
|
|
@_driver.on_startup
|
|
|
|
|
async def _register_media_route() -> None:
|
|
|
|
|
"""挂载 /api/otto/{filename},供协议端跨机器下载生成的语音。"""
|
|
|
|
|
from fastapi import HTTPException
|
|
|
|
|
from fastapi.responses import FileResponse
|
|
|
|
|
from nonebot import get_app
|
2026-09-01 13:13:40 +08:00
|
|
|
|
2026-09-03 00:44:38 +08:00
|
|
|
app = get_app()
|
2026-09-01 13:13:40 +08:00
|
|
|
|
2026-09-03 00:44:38 +08:00
|
|
|
def serve_otto_file(filename: str):
|
|
|
|
|
root = _TEMP_ROOT.resolve()
|
|
|
|
|
target = (root / filename).resolve()
|
|
|
|
|
if root != target.parent and root not in target.parents:
|
|
|
|
|
raise HTTPException(status_code=403, detail="Forbidden")
|
|
|
|
|
if not target.is_file():
|
|
|
|
|
raise HTTPException(status_code=404, detail="Not Found")
|
|
|
|
|
return FileResponse(target, media_type="audio/mpeg")
|
2026-09-01 13:13:40 +08:00
|
|
|
|
2026-09-03 00:44:38 +08:00
|
|
|
if not any(getattr(r, "path", None) == "/api/otto/{filename}" for r in app.routes):
|
|
|
|
|
app.add_api_route(
|
|
|
|
|
"/api/otto/{filename}",
|
|
|
|
|
serve_otto_file,
|
|
|
|
|
methods=["GET"],
|
|
|
|
|
name="otto_media",
|
|
|
|
|
)
|
2026-09-01 13:13:40 +08:00
|
|
|
|
|
|
|
|
|
2026-09-03 00:44:38 +08:00
|
|
|
from .handlers import otto # noqa: E402,F401
|