refactor: 按模块重构项目结构
- 删除 vars 全局状态,按职责拆分 internal/ 包:scanner/probe/classify/organize/mover/store/digest - 数据驱动归类规则替代图片/视频重复分支,store 改为结构体实例 - build.sh 按系统类型编译:Windows 用 upx 压缩,macOS/Linux 不压缩 - 忽略目录拆分:图片_已忽略 / 视频_已忽略 - 输出构建产物加入 .gitignore
This commit is contained in:
@@ -1,58 +1,70 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
_ "embed"
|
||||
"fmt"
|
||||
_ "image/gif" // 导入gif支持
|
||||
_ "image/jpeg" // 导入jpeg支持
|
||||
_ "image/png" // 导入png支持
|
||||
"kenaito-media-picker/core"
|
||||
"kenaito-media-picker/store"
|
||||
"kenaito-media-picker/util"
|
||||
"kenaito-media-picker/vars"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"time"
|
||||
|
||||
"kenaito-media-picker/internal/organize"
|
||||
"kenaito-media-picker/internal/probe"
|
||||
"kenaito-media-picker/internal/scanner"
|
||||
"kenaito-media-picker/internal/store"
|
||||
)
|
||||
|
||||
func main() {
|
||||
fmt.Println("=== 警告:该程序会改变目录结构,将在5秒后开始执行")
|
||||
time.Sleep(time.Second * 5)
|
||||
|
||||
rootDir, err := os.Getwd()
|
||||
if err != nil {
|
||||
fmt.Println("=== 获取当前路径异常", err)
|
||||
return
|
||||
}
|
||||
pickerDir := filepath.Join(rootDir, filepath.Base(rootDir)+"-picker")
|
||||
vars.GlobalPickerDir = pickerDir
|
||||
fmt.Printf("=== 整理输出目录(白名单): %s \n", pickerDir)
|
||||
scanner := core.FileScanner{}
|
||||
scanner.DoScan(rootDir)
|
||||
scanner.DoFilter()
|
||||
// 初始化媒体信息数据库(失败不影响整理,仅无法记录)
|
||||
if err := store.Init(filepath.Join(rootDir, store.DBFileName)); err != nil {
|
||||
|
||||
// 1. 扫描并过滤(跳过输出目录、数据库与 ffprobe 相关文件)
|
||||
res, err := scanner.Scan(scanner.Options{
|
||||
RootDir: rootDir,
|
||||
SkipDir: pickerDir,
|
||||
SkipNames: []string{store.DBFileName, probe.FFprobeExeName, "ffprobe_mac"},
|
||||
})
|
||||
if err != nil {
|
||||
fmt.Println("=== 扫描失败:", err)
|
||||
return
|
||||
}
|
||||
res.Filter()
|
||||
|
||||
// 2. 初始化媒体信息数据库(失败不影响整理,仅无法记录)
|
||||
st, err := store.Open(filepath.Join(rootDir, store.DBFileName))
|
||||
if err != nil {
|
||||
fmt.Println("=== 初始化数据库失败(继续整理, 不记录媒体信息):", err)
|
||||
st = nil
|
||||
}
|
||||
defer store.Close()
|
||||
// 释放内嵌ffprobe(按当前系统);失败只跳过媒体整理,图片照常处理
|
||||
ffprobeReady := true
|
||||
if len(vars.GlobalImagePathList) > 0 || len(vars.GlobalMediaPathList) > 0 {
|
||||
if err := util.ReleaseFFprobe(); err != nil {
|
||||
if st != nil {
|
||||
defer st.Close()
|
||||
}
|
||||
|
||||
// 3. 释放内嵌 ffprobe(按当前系统);失败只跳过媒体整理,图片照常处理
|
||||
ffprobePath := ""
|
||||
if (len(res.Images) > 0 || len(res.Media) > 0) && probe.HasEmbeddedFFprobe() {
|
||||
if err := probe.ReleaseFFprobe(); err != nil {
|
||||
fmt.Println("=== 释放解码器失败, 视频/音频整理将跳过(图片照常处理):", err)
|
||||
ffprobeReady = false
|
||||
} else {
|
||||
ffprobePath = probe.FFprobePath()
|
||||
defer probe.RemoveFFprobe()
|
||||
}
|
||||
}
|
||||
defer util.RemoveFFprobe()
|
||||
if len(vars.GlobalImagePathList) > 0 {
|
||||
core.DoHandleImage(pickerDir)
|
||||
|
||||
// 4. 整理
|
||||
org := organize.New(pickerDir, ffprobePath, st)
|
||||
if len(res.Images) > 0 {
|
||||
org.ProcessImages(res.Images)
|
||||
}
|
||||
if len(vars.GlobalMediaPathList) > 0 && ffprobeReady {
|
||||
core.DoHandleMedia(pickerDir)
|
||||
}
|
||||
// 所有移动完成后,回填文件的归类目录与去向
|
||||
for src, dest := range vars.GlobalPath2DestDirMap {
|
||||
if err := store.UpdateMediaDest(src, dest); err != nil {
|
||||
fmt.Printf("=== 更新媒体去向失败: %s, 错误: %v\n", src, err)
|
||||
}
|
||||
if len(res.Media) > 0 && ffprobePath != "" {
|
||||
org.ProcessMedia(res.Media)
|
||||
}
|
||||
org.Flush()
|
||||
fmt.Println("=== 整理完成")
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user