122 lines
3.2 KiB
Go
122 lines
3.2 KiB
Go
package api
|
|
|
|
import (
|
|
"encoding/json"
|
|
"net/http"
|
|
"os"
|
|
"strings"
|
|
|
|
"github.com/gin-gonic/gin"
|
|
|
|
"kenaito-media-picker/internal/config"
|
|
"kenaito-media-picker/internal/store"
|
|
)
|
|
|
|
// hentaiDetectorReadyKey 记录最近一次扫描时二次元检测服务是否真的起来了。
|
|
const hentaiDetectorReadyKey = "hentai.detectorReady"
|
|
|
|
// HentaiController 二次元识别相关接口的控制器。
|
|
type HentaiController struct {
|
|
store *store.Store
|
|
}
|
|
|
|
// NewHentaiController 创建二次元识别控制器。
|
|
func NewHentaiController(st *store.Store) *HentaiController {
|
|
return &HentaiController{store: st}
|
|
}
|
|
|
|
// hentaiView 列表里展示的一条记录。
|
|
type hentaiView struct {
|
|
Id int64 `json:"id"`
|
|
FileName string `json:"fileName"`
|
|
Score float64 `json:"score"`
|
|
Rating string `json:"rating"`
|
|
Threshold float64 `json:"threshold"`
|
|
Path string `json:"path"`
|
|
TopTags string `json:"topTags"`
|
|
CreatedAt string `json:"createdAt"`
|
|
}
|
|
|
|
// List 处理 GET /api/hentai/list:查全部二次元识别记录(按检测分从高到低)。
|
|
func (c *HentaiController) List(ctx *gin.Context) {
|
|
list, err := c.store.ListHentai()
|
|
if err != nil {
|
|
Error(ctx, http.StatusInternalServerError, "查询二次元识别记录失败:"+err.Error())
|
|
return
|
|
}
|
|
views := make([]hentaiView, 0, len(list))
|
|
for _, r := range list {
|
|
path := r.MovedPath
|
|
if path == "" {
|
|
path = r.FilePath
|
|
}
|
|
views = append(views, hentaiView{
|
|
Id: r.Id,
|
|
FileName: r.FileName,
|
|
Score: r.Score,
|
|
Rating: r.Rating,
|
|
Threshold: r.Threshold,
|
|
Path: path,
|
|
TopTags: r.TopTags,
|
|
CreatedAt: r.CreatedAt.Format("2006-01-02 15:04:05"),
|
|
})
|
|
}
|
|
Success(ctx, map[string]interface{}{
|
|
"list": views,
|
|
"total": len(views),
|
|
"hentaiEnabled": config.GetAppConfig().HentaiEnabled,
|
|
"hentaiDetector": c.store == nil || c.store.GetConfig(hentaiDetectorReadyKey) != "0",
|
|
})
|
|
}
|
|
|
|
// Preview 处理 GET /api/hentai/preview?path=xxx:把指定图片文件返回给浏览器做预览。
|
|
func (c *HentaiController) Preview(ctx *gin.Context) {
|
|
path := strings.TrimSpace(ctx.Query("path"))
|
|
if path == "" {
|
|
Error(ctx, http.StatusBadRequest, "缺少 path 参数")
|
|
return
|
|
}
|
|
if _, err := os.Stat(path); err != nil {
|
|
Error(ctx, http.StatusNotFound, "图片不存在或已被移动: "+path)
|
|
return
|
|
}
|
|
ctx.File(path)
|
|
}
|
|
|
|
// Tags 处理 GET /api/hentai/tags?id=xxx:查某条记录的标签详情。
|
|
func (c *HentaiController) Tags(ctx *gin.Context) {
|
|
id := ctx.Query("id")
|
|
if id == "" {
|
|
Error(ctx, http.StatusBadRequest, "缺少 id 参数")
|
|
return
|
|
}
|
|
var idInt int64
|
|
if _, err := json.Number(id).Int64(); err != nil {
|
|
Error(ctx, http.StatusBadRequest, "id 格式错误")
|
|
return
|
|
}
|
|
idInt, _ = json.Number(id).Int64()
|
|
|
|
record, err := c.store.GetHentaiById(idInt)
|
|
if err != nil {
|
|
Error(ctx, http.StatusInternalServerError, "查询记录失败:"+err.Error())
|
|
return
|
|
}
|
|
if record == nil {
|
|
Error(ctx, http.StatusNotFound, "记录不存在")
|
|
return
|
|
}
|
|
|
|
var tags []map[string]interface{}
|
|
if record.TopTags != "" {
|
|
if err := json.Unmarshal([]byte(record.TopTags), &tags); err != nil {
|
|
tags = nil
|
|
}
|
|
}
|
|
|
|
Success(ctx, map[string]interface{}{
|
|
"id": record.Id,
|
|
"topTags": tags,
|
|
})
|
|
}
|