From dd2bb8fd5096c2f7ef7efd985285a0f08276a100 Mon Sep 17 00:00:00 2001 From: Odboy Date: Sun, 7 Sep 2025 21:09:43 +0800 Subject: [PATCH] =?UTF-8?q?refactor:=20=E7=A7=BB=E9=99=A4=20nsfw.python=20?= =?UTF-8?q?=E9=85=8D=E7=BD=AE=E9=A1=B9=EF=BC=8C=E8=87=AA=E5=8A=A8=E5=9C=A8?= =?UTF-8?q?=20PATH=20=E4=B8=AD=E6=9F=A5=E6=89=BE=20python?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- application.properties | 17 ---------------- internal/config/config.go | 43 ++++++++------------------------------- internal/service/scan.go | 5 ++--- 3 files changed, 11 insertions(+), 54 deletions(-) diff --git a/application.properties b/application.properties index b1738b6..01d9788 100644 --- a/application.properties +++ b/application.properties @@ -12,20 +12,3 @@ ffmpeg.path= organize.rotateImages=false # 探测/认类型/移动阶段的并发 worker 数(默认 4;0 表示用满全部 CPU 核数) organize.workers=8 -# 色情图片识别(需本机安装 python 与 nudenet:pip install nudenet) -# true=开启,判为色情的图片移入「图片_敏感_*」目录(明暗子目录照常);false=关闭(默认) -# 模型:优先加载程序运行目录下 lib/human_nwfs/320n.onnx(推荐随程序分发,离线可用); -# 本地没有会自动下载到该位置,下载失败再回退用 nudenet 自带模型 -# NSFW是用来识别真人图片的 -nsfw.enabled=false -# python 可执行文件路径;留空自动在 PATH 里找 python/python3/py -nsfw.python=C:\\Users\\Administrator\\AppData\\Local\\Programs\\Python\\Python312\\python.exe -# 判定阈值 0~1,敏感部位检测分高于此才算色情 -nsfw.threshold=0.27 -# 动漫色情图片识别(需本机安装 python 与 onnxruntime/opencv/numpy:pip install onnxruntime opencv-python numpy) -# true=开启,判定为色情的动漫图片同样移入「图片_敏感_*」目录;false=关闭(默认) -# 模型:WD Tagger v3 (eva02-large),首次启动自动从 HuggingFace 下载到 lib/anime_nsfw/(约 1.26GB) -# AnimeNSFW是用来识别动漫/二次元图片的 -anime_nsfw.enabled=true -# 判定阈值 0~1,explicit/questionable 分数高于此才算色情 -anime_nsfw.threshold=0.5 diff --git a/internal/config/config.go b/internal/config/config.go index 8011f93..8690683 100644 --- a/internal/config/config.go +++ b/internal/config/config.go @@ -19,23 +19,15 @@ import ( // - FFmpegPath:ffmpeg 程序路径(用于把带 EXIF 旋转标记的图片转正);留空自动在 PATH 里找 // - RotateImages:是否处理图片 EXIF 旋转(默认 true);false 则完全不处理,按存储方向/尺寸归类 // - Workers:探测/MIME/移动阶段的并发 worker 数(默认 4;设 0 表示用满全部 CPU 核数) -// - NSFWEnabled:是否开启色情图片识别(本地 python + NudeNet,默认 false) -// - NSFWPython:python 可执行文件路径;留空自动在 PATH 里找 -// - NSFWThreshold:判定阈值 0~1(默认 0.5) -// - AnimeNSFWEnabled:是否开启动漫色情图片识别(本地 python + WD Tagger v3,默认 false) -// - AnimeNSFWThreshold:动漫判定阈值 0~1(默认 0.5) +// +// 注意:NSFW 检测相关配置已改为从数据库读取(通过网页「系统配置」设置) type Config struct { - Port int - Dsn string - AutoOpen bool - FFmpegPath string - RotateImages bool - Workers int - NSFWEnabled bool - NSFWPython string - NSFWThreshold float64 - AnimeNSFWEnabled bool - AnimeNSFWThreshold float64 + Port int + Dsn string + AutoOpen bool + FFmpegPath string + RotateImages bool + Workers int } // appConfig 当前生效的配置(程序运行期间一直不变)。 @@ -49,7 +41,7 @@ func GetAppConfig() Config { // LoadAppConfig 从 application.properties 读配置;文件不存在就用默认值。 func LoadAppConfig() { // 先给一套默认值 - appConfig = Config{Port: 8080, Dsn: "media-info.db", AutoOpen: true, RotateImages: true, Workers: 4, NSFWThreshold: 0.5, AnimeNSFWThreshold: 0.5} + appConfig = Config{Port: 8080, Dsn: "media-info.db", AutoOpen: true, RotateImages: true, Workers: 4} p, err := properties.LoadFile("application.properties", properties.UTF8) if err != nil { @@ -74,23 +66,6 @@ func LoadAppConfig() { appConfig.Workers = n } } - // 色情识别:默认关;python 路径留空自动在 PATH 找;阈值只认 0~1 之间的小数 - appConfig.NSFWEnabled = p.GetBool("nsfw.enabled", false) - if v, ok := p.Get("nsfw.python"); ok && v != "" { - appConfig.NSFWPython = v - } - if v, ok := p.Get("nsfw.threshold"); ok && strings.TrimSpace(v) != "" { - if t, err := strconv.ParseFloat(strings.TrimSpace(v), 64); err == nil && t > 0 && t < 1 { - appConfig.NSFWThreshold = t - } - } - // 动漫色情识别:默认关;阈值只认 0~1 之间的小数 - appConfig.AnimeNSFWEnabled = p.GetBool("anime_nsfw.enabled", false) - if v, ok := p.Get("anime_nsfw.threshold"); ok && strings.TrimSpace(v) != "" { - if t, err := strconv.ParseFloat(strings.TrimSpace(v), 64); err == nil && t > 0 && t < 1 { - appConfig.AnimeNSFWThreshold = t - } - } } // WorkerCount 返回探测/MIME/移动阶段使用的并发 worker 数: diff --git a/internal/service/scan.go b/internal/service/scan.go index 4e9136a..089fd29 100644 --- a/internal/service/scan.go +++ b/internal/service/scan.go @@ -674,7 +674,6 @@ func (s *ScanService) runScan(ctx context.Context, rootDir, destDir string) erro // ---------- 第五步(可选):色情识别 ---------- // 从数据库读取 NSFW 配置(支持运行时修改,立即生效) nsfwType := s.store.GetConfig("nsfw.type") // "" / "human" / "anime" - pythonPath := config.GetAppConfig().NSFWPython nsfwDet := (*nsfw.Detector)(nil) s.setNsfwDetectorReady(false) @@ -685,7 +684,7 @@ func (s *ScanService) runScan(ctx context.Context, rootDir, destDir string) erro threshold = t } } - if d, err := nsfw.Start(pythonPath, threshold); err != nil { + if d, err := nsfw.Start("", threshold); err != nil { fmt.Printf("=== 色情识别未启用(图片照常处理): %v\n", err) } else { nsfwDet = d @@ -704,7 +703,7 @@ func (s *ScanService) runScan(ctx context.Context, rootDir, destDir string) erro threshold = t } } - if d, err := anime_nsfw.Start(pythonPath, threshold); err != nil { + if d, err := anime_nsfw.Start("", threshold); err != nil { fmt.Printf("=== 动漫色情识别未启用(图片照常处理): %v\n", err) } else { animeNsfwDet = d