refactor: 移除 nsfw.python 配置项,自动在 PATH 中查找 python
This commit is contained in:
@@ -12,20 +12,3 @@ ffmpeg.path=
|
|||||||
organize.rotateImages=false
|
organize.rotateImages=false
|
||||||
# 探测/认类型/移动阶段的并发 worker 数(默认 4;0 表示用满全部 CPU 核数)
|
# 探测/认类型/移动阶段的并发 worker 数(默认 4;0 表示用满全部 CPU 核数)
|
||||||
organize.workers=8
|
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
|
|
||||||
|
|||||||
@@ -19,23 +19,15 @@ import (
|
|||||||
// - FFmpegPath:ffmpeg 程序路径(用于把带 EXIF 旋转标记的图片转正);留空自动在 PATH 里找
|
// - FFmpegPath:ffmpeg 程序路径(用于把带 EXIF 旋转标记的图片转正);留空自动在 PATH 里找
|
||||||
// - RotateImages:是否处理图片 EXIF 旋转(默认 true);false 则完全不处理,按存储方向/尺寸归类
|
// - RotateImages:是否处理图片 EXIF 旋转(默认 true);false 则完全不处理,按存储方向/尺寸归类
|
||||||
// - Workers:探测/MIME/移动阶段的并发 worker 数(默认 4;设 0 表示用满全部 CPU 核数)
|
// - Workers:探测/MIME/移动阶段的并发 worker 数(默认 4;设 0 表示用满全部 CPU 核数)
|
||||||
// - NSFWEnabled:是否开启色情图片识别(本地 python + NudeNet,默认 false)
|
//
|
||||||
// - NSFWPython:python 可执行文件路径;留空自动在 PATH 里找
|
// 注意:NSFW 检测相关配置已改为从数据库读取(通过网页「系统配置」设置)
|
||||||
// - NSFWThreshold:判定阈值 0~1(默认 0.5)
|
|
||||||
// - AnimeNSFWEnabled:是否开启动漫色情图片识别(本地 python + WD Tagger v3,默认 false)
|
|
||||||
// - AnimeNSFWThreshold:动漫判定阈值 0~1(默认 0.5)
|
|
||||||
type Config struct {
|
type Config struct {
|
||||||
Port int
|
Port int
|
||||||
Dsn string
|
Dsn string
|
||||||
AutoOpen bool
|
AutoOpen bool
|
||||||
FFmpegPath string
|
FFmpegPath string
|
||||||
RotateImages bool
|
RotateImages bool
|
||||||
Workers int
|
Workers int
|
||||||
NSFWEnabled bool
|
|
||||||
NSFWPython string
|
|
||||||
NSFWThreshold float64
|
|
||||||
AnimeNSFWEnabled bool
|
|
||||||
AnimeNSFWThreshold float64
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// appConfig 当前生效的配置(程序运行期间一直不变)。
|
// appConfig 当前生效的配置(程序运行期间一直不变)。
|
||||||
@@ -49,7 +41,7 @@ func GetAppConfig() Config {
|
|||||||
// LoadAppConfig 从 application.properties 读配置;文件不存在就用默认值。
|
// LoadAppConfig 从 application.properties 读配置;文件不存在就用默认值。
|
||||||
func LoadAppConfig() {
|
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)
|
p, err := properties.LoadFile("application.properties", properties.UTF8)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@@ -74,23 +66,6 @@ func LoadAppConfig() {
|
|||||||
appConfig.Workers = n
|
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 数:
|
// WorkerCount 返回探测/MIME/移动阶段使用的并发 worker 数:
|
||||||
|
|||||||
@@ -674,7 +674,6 @@ func (s *ScanService) runScan(ctx context.Context, rootDir, destDir string) erro
|
|||||||
// ---------- 第五步(可选):色情识别 ----------
|
// ---------- 第五步(可选):色情识别 ----------
|
||||||
// 从数据库读取 NSFW 配置(支持运行时修改,立即生效)
|
// 从数据库读取 NSFW 配置(支持运行时修改,立即生效)
|
||||||
nsfwType := s.store.GetConfig("nsfw.type") // "" / "human" / "anime"
|
nsfwType := s.store.GetConfig("nsfw.type") // "" / "human" / "anime"
|
||||||
pythonPath := config.GetAppConfig().NSFWPython
|
|
||||||
|
|
||||||
nsfwDet := (*nsfw.Detector)(nil)
|
nsfwDet := (*nsfw.Detector)(nil)
|
||||||
s.setNsfwDetectorReady(false)
|
s.setNsfwDetectorReady(false)
|
||||||
@@ -685,7 +684,7 @@ func (s *ScanService) runScan(ctx context.Context, rootDir, destDir string) erro
|
|||||||
threshold = t
|
threshold = t
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if d, err := nsfw.Start(pythonPath, threshold); err != nil {
|
if d, err := nsfw.Start("", threshold); err != nil {
|
||||||
fmt.Printf("=== 色情识别未启用(图片照常处理): %v\n", err)
|
fmt.Printf("=== 色情识别未启用(图片照常处理): %v\n", err)
|
||||||
} else {
|
} else {
|
||||||
nsfwDet = d
|
nsfwDet = d
|
||||||
@@ -704,7 +703,7 @@ func (s *ScanService) runScan(ctx context.Context, rootDir, destDir string) erro
|
|||||||
threshold = t
|
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)
|
fmt.Printf("=== 动漫色情识别未启用(图片照常处理): %v\n", err)
|
||||||
} else {
|
} else {
|
||||||
animeNsfwDet = d
|
animeNsfwDet = d
|
||||||
|
|||||||
Reference in New Issue
Block a user