Files
HeXi/hexi/plugins/nonebot_plugin_huoziyinshua/__init__.py
T
sansenhoshiandClaude 9371a28e35 refactor: restructure plugins per MTSS standard, consolidate assets to res/
Per docs/plugin-audit-report.md (plugins normalized to
Trigger(handlers) → Service(services) → Model(repository/models) + utils):

- Split monolithic __init__.py into handlers/services/utils across
  dailywife, deer_pipe, dice, galgame_card, helldivers_tools,
  huoziyinshua, learning_chat, makeaquote, mc_server_status,
  ncm_saying, picfinder_take, picstatus, random_jm_code, regif,
  steam_info, video_analysis, group_tools
- Move static assets under res/: deer_pipe font/img, makeaquote font,
  helldivers img/templates, huoziyinshua HuoZiYinShua
- Add config.py + register_config_items to ncm_saying, random_jm_code,
  group_tools; learning_chat unified config bridge
- Remove deprecated: voice_trans plugin, bf_bot/test.py, dead code in
  dailywife/deer_pipe, empty dirs, debug scripts under helldivers temp
- Disable brash_general_supercredits_tools (stub comment only)
- bot.py: optional stdout/stderr redirect to log file for Web log viewer,
  force ANSI colorize on non-TTY sinks
- Move runtime data (jm_code.json) out of plugin dir into hexi/data
- Docs: plugin-audit-report.md; README reflects removed plugins

Co-Authored-By: Claude <noreply@anthropic.com>
2026-09-03 00:44:38 +08:00

56 lines
1.9 KiB
Python

"""otto 活字印刷 —— 入口(元数据 + 依赖)。"""
from __future__ import annotations
from pathlib import Path
from nonebot import get_driver, require
from nonebot.plugin import PluginMetadata
require("nonebot_plugin_alconna")
__plugin_meta__ = PluginMetadata(
name="otto活字印刷",
description="鬼畜音源活字印刷(otto语音合成)",
usage="otto 一些内容 生成otto语音\notto 一些内容 -reverse 生成并倒放",
type="application",
)
_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()
@_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
app = get_app()
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")
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",
)
from .handlers import otto # noqa: E402,F401