浏览代码

正在重构

Signed-off-by: allan716 <[email protected]>
allan716 3 年之前
父节点
当前提交
3bfbf4613c

+ 1 - 1
cmd/chinesesubfinder/main.go

@@ -118,7 +118,7 @@ func main() {
 		common.SetApiToken("")
 		common.SetApiToken("")
 	}
 	}
 	// 是否开启开发模式,跳过某些流程
 	// 是否开启开发模式,跳过某些流程
-	settings.GetSettings().SpeedDevMode = false
+	settings.GetSettings().SpeedDevMode = true
 	if settings.GetSettings().SpeedDevMode == true {
 	if settings.GetSettings().SpeedDevMode == true {
 		loggerBase.Infoln("Speed Dev Mode is On")
 		loggerBase.Infoln("Speed Dev Mode is On")
 		pkg.SetLiteMode(true)
 		pkg.SetLiteMode(true)

+ 1 - 0
internal/backend/base_router.go

@@ -84,6 +84,7 @@ func InitRouter(
 		GroupV1.GET("/video/list/refresh-status", cbV1.RefreshVideoListStatusHandler)
 		GroupV1.GET("/video/list/refresh-status", cbV1.RefreshVideoListStatusHandler)
 		GroupV1.GET("/video/list", cbV1.VideoListHandler)
 		GroupV1.GET("/video/list", cbV1.VideoListHandler)
 		GroupV1.POST("/video/list/add", cbV1.VideoListAddHandler)
 		GroupV1.POST("/video/list/add", cbV1.VideoListAddHandler)
+		GroupV1.POST("/video/list/refresh_main_list", cbV1.RefreshMainList)
 	}
 	}
 
 
 	GroupAPIV1 := router.Group("/api/v1")
 	GroupAPIV1 := router.Group("/api/v1")

+ 4 - 0
internal/backend/controllers/v1/controller_base.go

@@ -3,6 +3,8 @@ package v1
 import (
 import (
 	"net/http"
 	"net/http"
 
 
+	"github.com/allanpk716/ChineseSubFinder/pkg/video_list_helper"
+
 	"github.com/allanpk716/ChineseSubFinder/pkg/types/backend"
 	"github.com/allanpk716/ChineseSubFinder/pkg/types/backend"
 
 
 	"github.com/allanpk716/ChineseSubFinder/pkg/lock"
 	"github.com/allanpk716/ChineseSubFinder/pkg/lock"
@@ -18,6 +20,7 @@ type ControllerBase struct {
 	cronHelper                          *cron_helper.CronHelper
 	cronHelper                          *cron_helper.CronHelper
 	pathUrlMap                          map[string]string
 	pathUrlMap                          map[string]string
 	videoScanAndRefreshHelper           *video_scan_and_refresh_helper.VideoScanAndRefreshHelper
 	videoScanAndRefreshHelper           *video_scan_and_refresh_helper.VideoScanAndRefreshHelper
+	videoListHelper                     *video_list_helper.VideoListHelper
 	videoScanAndRefreshHelperIsRunning  bool
 	videoScanAndRefreshHelperIsRunning  bool
 	videoScanAndRefreshHelperLocker     lock.Lock
 	videoScanAndRefreshHelperLocker     lock.Lock
 	videoScanAndRefreshHelperErrMessage string
 	videoScanAndRefreshHelperErrMessage string
@@ -33,6 +36,7 @@ func NewControllerBase(log *logrus.Logger, cronHelper *cron_helper.CronHelper, r
 		videoScanAndRefreshHelper: video_scan_and_refresh_helper.NewVideoScanAndRefreshHelper(
 		videoScanAndRefreshHelper: video_scan_and_refresh_helper.NewVideoScanAndRefreshHelper(
 			sub_formatter.GetSubFormatter(log, cronHelper.Settings.AdvancedSettings.SubNameFormatter),
 			sub_formatter.GetSubFormatter(log, cronHelper.Settings.AdvancedSettings.SubNameFormatter),
 			cronHelper.FileDownloader, nil),
 			cronHelper.FileDownloader, nil),
+		videoListHelper:                 video_list_helper.NewVideoListHelper(log, cronHelper.Settings),
 		videoScanAndRefreshHelperLocker: lock.NewLock(),
 		videoScanAndRefreshHelperLocker: lock.NewLock(),
 		restartSignal:                   restartSignal,
 		restartSignal:                   restartSignal,
 	}
 	}

+ 61 - 0
internal/backend/controllers/v1/video_list.go

@@ -10,6 +10,8 @@ import (
 	"github.com/allanpk716/ChineseSubFinder/pkg/types/common"
 	"github.com/allanpk716/ChineseSubFinder/pkg/types/common"
 	TTaskqueue "github.com/allanpk716/ChineseSubFinder/pkg/types/task_queue"
 	TTaskqueue "github.com/allanpk716/ChineseSubFinder/pkg/types/task_queue"
 
 
+	vsh "github.com/allanpk716/ChineseSubFinder/pkg/video_scan_and_refresh_helper"
+
 	"github.com/allanpk716/ChineseSubFinder/pkg/decode"
 	"github.com/allanpk716/ChineseSubFinder/pkg/decode"
 	"github.com/allanpk716/ChineseSubFinder/pkg/video_scan_and_refresh_helper"
 	"github.com/allanpk716/ChineseSubFinder/pkg/video_scan_and_refresh_helper"
 	"github.com/gin-gonic/gin"
 	"github.com/gin-gonic/gin"
@@ -187,3 +189,62 @@ func (cb *ControllerBase) VideoListHandler(c *gin.Context) {
 		SeasonInfos: outSeasonInfo,
 		SeasonInfos: outSeasonInfo,
 	})
 	})
 }
 }
+
+func (cb *ControllerBase) RefreshMainList(c *gin.Context) {
+
+	var err error
+	defer func() {
+		// 统一的异常处理
+		cb.ErrorProcess(c, "RefreshMainList", err)
+	}()
+
+	if cb.videoScanAndRefreshHelperLocker.Lock() == false {
+		// 已经在执行,跳过
+		c.JSON(http.StatusOK, backend2.ReplyRefreshVideoList{
+			Status: "running"})
+		return
+	}
+	cb.videoScanAndRefreshHelperIsRunning = true
+
+	go func() {
+
+		startT := time.Now()
+		cb.log.Infoln("------------------------------------")
+		cb.log.Infoln("Video Scan Started By webui...")
+
+		pathUrlMap := cb.GetPathUrlMap()
+		cb.log.Infoln("---------------------------------")
+		cb.log.Infoln("GetPathUrlMap")
+		for s, s2 := range pathUrlMap {
+			cb.log.Infoln("pathUrlMap", s, s2)
+		}
+		cb.log.Infoln("---------------------------------")
+
+		defer func() {
+			cb.videoScanAndRefreshHelperIsRunning = false
+			cb.videoScanAndRefreshHelperLocker.Unlock()
+			cb.log.Infoln("Video Scan Finished By webui, cost:", time.Since(startT).Minutes(), "min")
+			cb.log.Infoln("------------------------------------")
+		}()
+
+		var err2 error
+		cb.videoScanAndRefreshHelperErrMessage = ""
+		var mainList *vsh.NormalScanVideoResult
+		mainList, err2 = cb.videoListHelper.RefreshMainList()
+		if err2 != nil {
+			cb.log.Errorln("RefreshMainList", err2)
+			cb.videoScanAndRefreshHelperErrMessage = err2.Error()
+			return
+		}
+		err2 = cb.cronHelper.Downloader.SetMovieAndSeasonInfoV2(mainList)
+		if err2 != nil {
+			cb.log.Errorln("SetMovieAndSeasonInfoV2", err2)
+			cb.videoScanAndRefreshHelperErrMessage = err2.Error()
+			return
+		}
+	}()
+
+	c.JSON(http.StatusOK, backend2.ReplyRefreshVideoList{
+		Status: "running"})
+	return
+}

+ 91 - 1
pkg/downloader/cache_info.go

@@ -4,10 +4,10 @@ import (
 	"path/filepath"
 	"path/filepath"
 
 
 	"github.com/allanpk716/ChineseSubFinder/pkg"
 	"github.com/allanpk716/ChineseSubFinder/pkg"
-
 	backend2 "github.com/allanpk716/ChineseSubFinder/pkg/types/backend"
 	backend2 "github.com/allanpk716/ChineseSubFinder/pkg/types/backend"
 	"github.com/allanpk716/ChineseSubFinder/pkg/types/common"
 	"github.com/allanpk716/ChineseSubFinder/pkg/types/common"
 	"github.com/allanpk716/ChineseSubFinder/pkg/types/task_queue"
 	"github.com/allanpk716/ChineseSubFinder/pkg/types/task_queue"
+	vsh "github.com/allanpk716/ChineseSubFinder/pkg/video_scan_and_refresh_helper"
 
 
 	"github.com/allanpk716/ChineseSubFinder/pkg/my_util"
 	"github.com/allanpk716/ChineseSubFinder/pkg/my_util"
 	"github.com/allanpk716/ChineseSubFinder/pkg/strcut_json"
 	"github.com/allanpk716/ChineseSubFinder/pkg/strcut_json"
@@ -254,6 +254,96 @@ func (d *Downloader) loadVideoListCache() error {
 	return nil
 	return nil
 }
 }
 
 
+// SetMovieAndSeasonInfoV2 只把第一级目录的信息给缓存下来,比如 x:\电影\壮志凌云\壮志凌云.mp4 或者是连续剧的 x:\连续剧\绝命毒师 根目录
+func (d *Downloader) SetMovieAndSeasonInfoV2(mainList *vsh.NormalScanVideoResult) error {
+
+	d.cacheLocker.Lock()
+	defer d.cacheLocker.Unlock()
+	// 缓存下来
+	cacheCenterFolder, err := pkg.GetRootCacheCenterFolder()
+	if err != nil {
+		return err
+	}
+	var movieInfos = make([]backend2.MovieInfoV2, 0)
+	var seasonInfos = make([]backend2.SeasonInfoV2, 0)
+
+	movieInfosFileName := filepath.Join(cacheCenterFolder, "movie_main_list.json")
+	seasonInfosFileName := filepath.Join(cacheCenterFolder, "season_main_list.json")
+
+	if mainList != nil && mainList.MoviesDirMap != nil && mainList.MoviesDirMap.Size() > 0 {
+
+		for _, movieDirs := range mainList.MoviesDirMap.Values() {
+
+			for _, movieDir := range movieDirs.([]string) {
+				movieInfos = append(movieInfos, backend2.MovieInfoV2{
+					Name:       filepath.Base(movieDir),
+					VideoFPath: movieDir,
+				})
+			}
+		}
+
+		err = strcut_json.ToFile(movieInfosFileName, movieInfos)
+		if err != nil {
+			return err
+		}
+	}
+
+	if mainList != nil && mainList.SeriesDirMap != nil && mainList.SeriesDirMap.Size() > 0 {
+
+		for _, seriesDirs := range mainList.SeriesDirMap.Values() {
+
+			for _, seriesDir := range seriesDirs.([]string) {
+				seasonInfos = append(seasonInfos, backend2.SeasonInfoV2{
+					Name:        filepath.Base(seriesDir),
+					RootDirPath: seriesDir,
+				})
+			}
+		}
+
+		err = strcut_json.ToFile(seasonInfosFileName, seasonInfos)
+		if err != nil {
+			return err
+		}
+	}
+
+	return nil
+}
+
+// GetMovieInfoAndSeasonInfoV2 只把第一级目录的信息给缓存下来,比如 x:\电影\壮志凌云\壮志凌云.mp4 或者是连续剧的 x:\连续剧\绝命毒师 根目录
+func (d *Downloader) GetMovieInfoAndSeasonInfoV2() ([]backend2.MovieInfoV2, []backend2.SeasonInfoV2, error) {
+	// 需要把本实例中的缓存 map 转换到 Web 传递的结构体中
+	d.cacheLocker.Lock()
+	defer d.cacheLocker.Unlock()
+
+	// 缓存下来
+	cacheCenterFolder, err := pkg.GetRootCacheCenterFolder()
+	if err != nil {
+		return nil, nil, err
+	}
+
+	movieInfosFileName := filepath.Join(cacheCenterFolder, "movie_main_list.json")
+	seasonInfosFileName := filepath.Join(cacheCenterFolder, "season_main_list.json")
+
+	movieInfos := make([]backend2.MovieInfoV2, 0)
+	seasonInfos := make([]backend2.SeasonInfoV2, 0)
+
+	if my_util.IsFile(movieInfosFileName) == true {
+		err = strcut_json.ToStruct(movieInfosFileName, &movieInfos)
+		if err != nil {
+			return nil, nil, err
+		}
+	}
+
+	if my_util.IsFile(seasonInfosFileName) == true {
+		err = strcut_json.ToStruct(seasonInfosFileName, &seasonInfos)
+		if err != nil {
+			return nil, nil, err
+		}
+	}
+
+	return movieInfos, seasonInfos, nil
+}
+
 type MovieInfo struct {
 type MovieInfo struct {
 	Name                     string   `json:"name"`
 	Name                     string   `json:"name"`
 	DirRootUrl               string   `json:"dir_root_url"`
 	DirRootUrl               string   `json:"dir_root_url"`

+ 5 - 0
pkg/types/backend/reply_movie_list.go

@@ -8,3 +8,8 @@ type MovieInfo struct {
 	MediaServerInsideVideoID string   `json:"media_server_inside_video_id"`
 	MediaServerInsideVideoID string   `json:"media_server_inside_video_id"`
 	SubFPathList             []string `json:"sub_f_path_list"`
 	SubFPathList             []string `json:"sub_f_path_list"`
 }
 }
+
+type MovieInfoV2 struct {
+	Name       string `json:"name"`
+	VideoFPath string `json:"video_f_path"` // x:\电影\壮志凌云\壮志凌云.mp4
+}

+ 5 - 0
pkg/types/backend/reply_series_list.go

@@ -16,3 +16,8 @@ type OneVideoInfo struct {
 	SubFPathList             []string `json:"sub_f_path_list"`
 	SubFPathList             []string `json:"sub_f_path_list"`
 	MediaServerInsideVideoID string   `json:"media_server_inside_video_id"`
 	MediaServerInsideVideoID string   `json:"media_server_inside_video_id"`
 }
 }
+
+type SeasonInfoV2 struct {
+	Name        string `json:"name"`
+	RootDirPath string `json:"root_dir_path"` // x:\连续剧\绝命毒师
+}

+ 5 - 0
pkg/types/backend/reply_video_list.go

@@ -4,3 +4,8 @@ type ReplyVideoList struct {
 	MovieInfos  []MovieInfo  `json:"movie_infos"`
 	MovieInfos  []MovieInfo  `json:"movie_infos"`
 	SeasonInfos []SeasonInfo `json:"season_infos"`
 	SeasonInfos []SeasonInfo `json:"season_infos"`
 }
 }
+
+type ReplyMainList struct {
+	MovieInfos  []MovieInfoV2  `json:"movie_infos_v2"`
+	SeasonInfos []SeasonInfoV2 `json:"season_infos_v2"`
+}

+ 109 - 0
pkg/video_list_helper/poster.go

@@ -0,0 +1,109 @@
+package video_list_helper
+
+import (
+	"path/filepath"
+
+	"github.com/allanpk716/ChineseSubFinder/pkg/my_util"
+)
+
+// GetMoviePoster 获取电影的海报,如果为空就是没有找到
+func (v *VideoListHelper) GetMoviePoster(movieFPath string) string {
+	/*
+		ext 只考虑 jpg, png, bmp 三种格式
+		参考 TMM 的设置
+		1. poster.ext
+		2. movie.ext
+		3. folder.ext
+		4. <movie filename>-poster.ext
+		5. <movie filename>.ext
+		6. cover.ext
+	*/
+	for _, ext := range extList {
+
+		movieRootDir := filepath.Dir(movieFPath)
+		movieName := filepath.Base(movieFPath)
+		// 1. poster.ext
+		posterFPath := filepath.Join(movieRootDir, "poster"+ext)
+		if my_util.IsFile(posterFPath) {
+			return posterFPath
+		}
+		// 2. movie.ext
+		posterFPath = filepath.Join(movieRootDir, "movie"+ext)
+		if my_util.IsFile(posterFPath) {
+			return posterFPath
+		}
+		// 3. folder.ext
+		posterFPath = filepath.Join(movieRootDir, "folder"+ext)
+		if my_util.IsFile(posterFPath) {
+			return posterFPath
+		}
+		// 4. <movie filename>-poster.ext
+		posterFPath = filepath.Join(movieRootDir, movieName+"-poster"+ext)
+		if my_util.IsFile(posterFPath) {
+			return posterFPath
+		}
+		// 5. <movie filename>.ext
+		posterFPath = filepath.Join(movieRootDir, movieName+ext)
+		if my_util.IsFile(posterFPath) {
+			return posterFPath
+		}
+		// 6. cover.ext
+		posterFPath = filepath.Join(movieRootDir, "cover"+ext)
+		if my_util.IsFile(posterFPath) {
+			return posterFPath
+		}
+	}
+	return ""
+}
+
+// GetSeriesPoster 获取电视剧的海报,如果为空就是没有找到
+func (v *VideoListHelper) GetSeriesPoster(seriesDir string) string {
+	/*
+		参考 TMM 的设置
+		连续剧的
+		1. poster.ext
+		2. folder.ext
+		Season的
+		1. seasonXX-poster.ext
+		2. <season folder>/seasonXX.ext
+		3. <season folder>/folder.ext
+	*/
+	// 获取主封面
+	for _, ext := range extList {
+		// 1. poster.ext
+		posterFPath := filepath.Join(seriesDir, "poster"+ext)
+		if my_util.IsFile(posterFPath) {
+			return posterFPath
+		}
+		// 2. folder.ext
+		posterFPath = filepath.Join(seriesDir, "folder"+ext)
+		if my_util.IsFile(posterFPath) {
+			return posterFPath
+		}
+	}
+	//files, err := filepath.Glob(filepath.Join(seriesDir, "season*-poster.jpg"))
+	//if err != nil {
+	//	return nil, err
+	//}
+	//println(files)
+	// 获取每一季的封面
+	//dirEntry, err := os.ReadDir(seriesDir)
+	//if err != nil {
+	//	return nil, err
+	//}
+	//for _, fi := range dirEntry {
+	//	lowerName := strings.ToLower(fi.Name())
+	//
+	//}
+
+	return ""
+}
+
+var (
+	extList = []string{".jpg", ".png", ".bmp"}
+)
+
+type SeriesPosterInfo struct {
+	SeriesPoster    string
+	SeasonPosterMap map[int]string
+}

+ 19 - 0
pkg/video_list_helper/poster_test.go

@@ -0,0 +1,19 @@
+package video_list_helper
+
+import (
+	"testing"
+)
+
+func TestVideoListHelper_GetMoviePoster(t *testing.T) {
+
+	movieFPath := "X:\\movie\\The King's Man (2021)\\The King's Man (2021) WEBDL-1080p.mkv"
+	v := VideoListHelper{}
+	println("Poster:", v.GetMoviePoster(movieFPath))
+}
+
+func TestVideoListHelper_GetSeriesPoster(t *testing.T) {
+
+	seriesDir := "X:\\连续剧\\良医 (2017)"
+	v := VideoListHelper{}
+	println("Poster:", v.GetSeriesPoster(seriesDir))
+}

+ 7 - 0
pkg/video_list_helper/video_list_helper.go

@@ -16,6 +16,13 @@ type VideoListHelper struct {
 	log      *logrus.Logger     // 日志实例
 	log      *logrus.Logger     // 日志实例
 }
 }
 
 
+func NewVideoListHelper(log *logrus.Logger, settings *settings.Settings) *VideoListHelper {
+	return &VideoListHelper{
+		settings: settings,
+		log:      log,
+	}
+}
+
 // RefreshMainList 获取到电影、连续剧一级目录信息,不包含 Season 及其以下信息
 // RefreshMainList 获取到电影、连续剧一级目录信息,不包含 Season 及其以下信息
 // 只给出 Movie 的FullPath,Series 的 RootDirPath
 // 只给出 Movie 的FullPath,Series 的 RootDirPath
 func (v *VideoListHelper) RefreshMainList() (*vsh.NormalScanVideoResult, error) {
 func (v *VideoListHelper) RefreshMainList() (*vsh.NormalScanVideoResult, error) {