Jelajahi Sumber

重构视频列表缓存功能,准备做字幕下载任务完成后更新视频列表的功能

Signed-off-by: allan716 <[email protected]>
allan716 3 tahun lalu
induk
melakukan
0ceac8732c

+ 1 - 1
cmd/chinesesubfinder/main.go

@@ -89,7 +89,7 @@ func main() {
 		common.SetApiToken("")
 	}
 	// 是否开启开发模式,跳过某些流程
-	//settings.GetSettings().SpeedDevMode = true
+	settings.GetSettings().SpeedDevMode = true
 	// ------------------------------------------------------------------------
 	// 前置的任务,热修复、字幕修改文件名格式、提前下载好浏览器
 	if settings.GetSettings().SpeedDevMode == false {

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

@@ -20,8 +20,6 @@ type ControllerBase struct {
 	videoScanAndRefreshHelperIsRunning  bool
 	videoScanAndRefreshHelperLocker     lock.Lock
 	videoScanAndRefreshHelperErrMessage string
-	MovieInfos                          []backend.MovieInfo
-	SeasonInfos                         []backend.SeasonInfo
 }
 
 func NewControllerBase(log *logrus.Logger, cronHelper *cron_helper.CronHelper) *ControllerBase {
@@ -32,13 +30,6 @@ func NewControllerBase(log *logrus.Logger, cronHelper *cron_helper.CronHelper) *
 		// 这里因为不进行任务的添加,仅仅是扫描,所以 downloadQueue 可以为 nil
 		videoScanAndRefreshHelper:       video_scan_and_refresh_helper.NewVideoScanAndRefreshHelper(cronHelper.FileDownloader, nil),
 		videoScanAndRefreshHelperLocker: lock.NewLock(),
-		MovieInfos:                      make([]backend.MovieInfo, 0),
-		SeasonInfos:                     make([]backend.SeasonInfo, 0),
-	}
-
-	err := cb.loadVideoListCache()
-	if err != nil {
-		cb.log.Errorln("loadVideoListCache", err)
 	}
 
 	return cb

+ 6 - 68
internal/backend/controllers/v1/video_list.go

@@ -1,16 +1,12 @@
 package v1
 
 import (
-	"github.com/allanpk716/ChineseSubFinder/internal/pkg/my_folder"
-	"github.com/allanpk716/ChineseSubFinder/internal/pkg/my_util"
-	"github.com/allanpk716/ChineseSubFinder/internal/pkg/strcut_json"
 	"github.com/allanpk716/ChineseSubFinder/internal/pkg/video_scan_and_refresh_helper"
 	"github.com/allanpk716/ChineseSubFinder/internal/types/backend"
 	"github.com/allanpk716/ChineseSubFinder/internal/types/common"
 	TTaskqueue "github.com/allanpk716/ChineseSubFinder/internal/types/task_queue"
 	"github.com/gin-gonic/gin"
 	"net/http"
-	"path/filepath"
 )
 
 func (cb *ControllerBase) RefreshVideoListStatusHandler(c *gin.Context) {
@@ -75,18 +71,10 @@ func (cb *ControllerBase) RefreshVideoListHandler(c *gin.Context) {
 
 		pathUrlMap := cb.StaticFileSystemBackEnd.GetPathUrlMap()
 
-		cb.MovieInfos = make([]backend.MovieInfo, 0)
-		cb.SeasonInfos = make([]backend.SeasonInfo, 0)
 		MovieInfos, SeasonInfos := cb.videoScanAndRefreshHelper.ScrabbleUpVideoList(scanVideoResult, pathUrlMap)
 
-		cb.MovieInfos = append(cb.MovieInfos, MovieInfos...)
-		cb.SeasonInfos = append(cb.SeasonInfos, SeasonInfos...)
-		// 缓存到本地
-		err = cb.saveVideoListCache()
-		if err != nil {
-			cb.log.Errorln("saveVideoListCache", err)
-			return
-		}
+		// 缓存视频列表
+		cb.cronHelper.SetMovieAndSeasonInfo(MovieInfos, SeasonInfos)
 	}()
 
 	c.JSON(http.StatusOK, backend.ReplyRefreshVideoList{
@@ -138,60 +126,10 @@ func (cb *ControllerBase) VideoListHandler(c *gin.Context) {
 		cb.ErrorProcess(c, "VideoListHandler", err)
 	}()
 
+	outMovieInfos, outSeasonInfo := cb.cronHelper.GetMovieInfoAndSeasonInfo()
+
 	c.JSON(http.StatusOK, backend.ReplyVideoList{
-		MovieInfos:  cb.MovieInfos,
-		SeasonInfos: cb.SeasonInfos,
+		MovieInfos:  outMovieInfos,
+		SeasonInfos: outSeasonInfo,
 	})
 }
-
-func (cb *ControllerBase) saveVideoListCache() error {
-
-	// 缓存下来
-	cacheCenterFolder, err := my_folder.GetRootCacheCenterFolder()
-	if err != nil {
-		return err
-	}
-
-	movieInfosFileName := filepath.Join(cacheCenterFolder, "movie_infos.json")
-	seasonInfosFileName := filepath.Join(cacheCenterFolder, "season_infos.json")
-
-	err = strcut_json.ToFile(movieInfosFileName, cb.MovieInfos)
-	if err != nil {
-		return err
-	}
-
-	err = strcut_json.ToFile(seasonInfosFileName, cb.SeasonInfos)
-	if err != nil {
-		return err
-	}
-
-	return nil
-}
-
-func (cb *ControllerBase) loadVideoListCache() error {
-
-	// 缓存下来
-	cacheCenterFolder, err := my_folder.GetRootCacheCenterFolder()
-	if err != nil {
-		return err
-	}
-
-	movieInfosFileName := filepath.Join(cacheCenterFolder, "movie_infos.json")
-	seasonInfosFileName := filepath.Join(cacheCenterFolder, "season_infos.json")
-
-	if my_util.IsFile(movieInfosFileName) == true {
-		err = strcut_json.ToStruct(movieInfosFileName, &cb.MovieInfos)
-		if err != nil {
-			return err
-		}
-	}
-
-	if my_util.IsFile(seasonInfosFileName) == true {
-		err = strcut_json.ToStruct(seasonInfosFileName, &cb.SeasonInfos)
-		if err != nil {
-			return err
-		}
-	}
-
-	return nil
-}

+ 211 - 0
internal/logic/cron_helper/cache_info.go

@@ -0,0 +1,211 @@
+package cron_helper
+
+import (
+	"github.com/allanpk716/ChineseSubFinder/internal/pkg/my_folder"
+	"github.com/allanpk716/ChineseSubFinder/internal/pkg/my_util"
+	"github.com/allanpk716/ChineseSubFinder/internal/pkg/strcut_json"
+	"github.com/allanpk716/ChineseSubFinder/internal/types/backend"
+	"path/filepath"
+)
+
+func (ch *CronHelper) SetMovieAndSeasonInfo(movieInfos []backend.MovieInfo, seasonInfos []backend.SeasonInfo) {
+	ch.cacheLocker.Lock()
+	defer ch.cacheLocker.Unlock()
+
+	ch.setMovieAndSeasonInfo(movieInfos, seasonInfos)
+}
+
+func (ch *CronHelper) GetMovieInfoAndSeasonInfo() ([]backend.MovieInfo, []backend.SeasonInfo) {
+	// 需要把本实例中的缓存 map 转换到 Web 传递的结构体中
+	ch.cacheLocker.Lock()
+	defer ch.cacheLocker.Unlock()
+
+	outMovieInfos := make([]backend.MovieInfo, 0)
+	outSeasonInfo := make([]backend.SeasonInfo, 0)
+	for _, movieInfo := range ch.movieInfoMap {
+
+		nowMovieInfo := backend.MovieInfo{
+			Name:                     movieInfo.Name,
+			DirRootUrl:               movieInfo.DirRootUrl,
+			VideoFPath:               movieInfo.VideoFPath,
+			VideoUrl:                 movieInfo.VideoUrl,
+			MediaServerInsideVideoID: movieInfo.MediaServerInsideVideoID,
+			SubFPathList:             make([]string, 0),
+		}
+		nowMovieInfo.SubFPathList = append(nowMovieInfo.SubFPathList, movieInfo.SubFPathList...)
+		outMovieInfos = append(outMovieInfos, nowMovieInfo)
+	}
+
+	for _, seasonInfo := range ch.seasonInfoMap {
+
+		nowSeasonInfo := backend.SeasonInfo{
+			Name:          seasonInfo.Name,
+			RootDirPath:   seasonInfo.RootDirPath,
+			DirRootUrl:    seasonInfo.DirRootUrl,
+			OneVideoInfos: make([]backend.OneVideoInfo, 0),
+		}
+
+		for _, oneVideoInfo := range seasonInfo.OneVideoInfoMap {
+
+			nowOneVideoInfo := backend.OneVideoInfo{
+
+				Name:                     oneVideoInfo.Name,
+				VideoFPath:               oneVideoInfo.VideoFPath,
+				VideoUrl:                 oneVideoInfo.VideoUrl,
+				Season:                   oneVideoInfo.Season,
+				Episode:                  oneVideoInfo.Episode,
+				MediaServerInsideVideoID: oneVideoInfo.MediaServerInsideVideoID,
+				SubFPathList:             make([]string, 0),
+			}
+			nowOneVideoInfo.SubFPathList = append(nowOneVideoInfo.SubFPathList, oneVideoInfo.SubFPathList...)
+			nowSeasonInfo.OneVideoInfos = append(nowSeasonInfo.OneVideoInfos, nowOneVideoInfo)
+		}
+
+		outSeasonInfo = append(outSeasonInfo, nowSeasonInfo)
+	}
+
+	return outMovieInfos, outSeasonInfo
+}
+
+func (ch *CronHelper) setMovieAndSeasonInfo(movieInfos []backend.MovieInfo, seasonInfos []backend.SeasonInfo, skip ...bool) {
+	// 需要把 Web 传递的结构体 转换到 本实例中的缓存 map
+
+	// 清空
+	ch.movieInfoMap = make(map[string]MovieInfo)
+	ch.seasonInfoMap = make(map[string]SeasonInfo)
+
+	for _, movieInfo := range movieInfos {
+
+		nowMovieInfo := MovieInfo{
+			Name:                     movieInfo.Name,
+			DirRootUrl:               movieInfo.DirRootUrl,
+			VideoFPath:               movieInfo.VideoFPath,
+			VideoUrl:                 movieInfo.VideoUrl,
+			MediaServerInsideVideoID: movieInfo.MediaServerInsideVideoID,
+			SubFPathList:             make([]string, 0),
+		}
+		nowMovieInfo.SubFPathList = append(nowMovieInfo.SubFPathList, movieInfo.SubFPathList...)
+		ch.movieInfoMap[movieInfo.VideoFPath] = nowMovieInfo
+	}
+
+	for _, seasonInfo := range seasonInfos {
+
+		nowSeasonInfo := SeasonInfo{
+			Name:            seasonInfo.Name,
+			RootDirPath:     seasonInfo.RootDirPath,
+			DirRootUrl:      seasonInfo.DirRootUrl,
+			OneVideoInfoMap: make(map[string]OneVideoInfo),
+		}
+
+		for _, oneVideoInfo := range seasonInfo.OneVideoInfos {
+
+			nowOneVideoInfo := OneVideoInfo{
+				Name:                     oneVideoInfo.Name,
+				VideoFPath:               oneVideoInfo.VideoFPath,
+				VideoUrl:                 oneVideoInfo.VideoUrl,
+				Season:                   oneVideoInfo.Season,
+				Episode:                  oneVideoInfo.Episode,
+				MediaServerInsideVideoID: oneVideoInfo.MediaServerInsideVideoID,
+				SubFPathList:             make([]string, 0),
+			}
+			nowOneVideoInfo.SubFPathList = append(nowOneVideoInfo.SubFPathList, oneVideoInfo.SubFPathList...)
+
+			nowSeasonInfo.OneVideoInfoMap[oneVideoInfo.VideoFPath] = nowOneVideoInfo
+		}
+
+		ch.seasonInfoMap[seasonInfo.RootDirPath] = nowSeasonInfo
+	}
+
+	if len(skip) > 0 && skip[0] == true {
+
+	} else {
+		err := ch.saveVideoListCache(movieInfos, seasonInfos)
+		if err != nil {
+			ch.log.Errorln("saveVideoListCache err:", err)
+			return
+		}
+	}
+}
+
+func (ch *CronHelper) saveVideoListCache(movieInfos []backend.MovieInfo, seasonInfos []backend.SeasonInfo) error {
+
+	// 缓存下来
+	cacheCenterFolder, err := my_folder.GetRootCacheCenterFolder()
+	if err != nil {
+		return err
+	}
+
+	movieInfosFileName := filepath.Join(cacheCenterFolder, "movie_infos.json")
+	seasonInfosFileName := filepath.Join(cacheCenterFolder, "season_infos.json")
+
+	err = strcut_json.ToFile(movieInfosFileName, movieInfos)
+	if err != nil {
+		return err
+	}
+
+	err = strcut_json.ToFile(seasonInfosFileName, seasonInfos)
+	if err != nil {
+		return err
+	}
+
+	return nil
+}
+
+func (ch *CronHelper) loadVideoListCache() error {
+
+	// 缓存下来
+	cacheCenterFolder, err := my_folder.GetRootCacheCenterFolder()
+	if err != nil {
+		return err
+	}
+
+	movieInfosFileName := filepath.Join(cacheCenterFolder, "movie_infos.json")
+	seasonInfosFileName := filepath.Join(cacheCenterFolder, "season_infos.json")
+
+	movieInfos := make([]backend.MovieInfo, 0)
+	seasonInfos := make([]backend.SeasonInfo, 0)
+
+	if my_util.IsFile(movieInfosFileName) == true {
+		err = strcut_json.ToStruct(movieInfosFileName, &movieInfos)
+		if err != nil {
+			return err
+		}
+	}
+
+	if my_util.IsFile(seasonInfosFileName) == true {
+		err = strcut_json.ToStruct(seasonInfosFileName, &seasonInfos)
+		if err != nil {
+			return err
+		}
+	}
+
+	ch.setMovieAndSeasonInfo(movieInfos, seasonInfos, true)
+
+	return nil
+}
+
+type MovieInfo struct {
+	Name                     string   `json:"name"`
+	DirRootUrl               string   `json:"dir_root_url"`
+	VideoFPath               string   `json:"video_f_path"`
+	VideoUrl                 string   `json:"video_url"`
+	MediaServerInsideVideoID string   `json:"media_server_inside_video_id"`
+	SubFPathList             []string `json:"sub_f_path_list"`
+}
+
+type SeasonInfo struct {
+	Name            string                  `json:"name"`
+	RootDirPath     string                  `json:"root_dir_path"`
+	DirRootUrl      string                  `json:"dir_root_url"`
+	OneVideoInfoMap map[string]OneVideoInfo `json:"one_video_info"` // Key VideoFPath
+}
+
+type OneVideoInfo struct {
+	Name                     string   `json:"name"`
+	VideoFPath               string   `json:"video_f_path"`
+	VideoUrl                 string   `json:"video_url"`
+	Season                   int      `json:"season"`
+	Episode                  int      `json:"episode"`
+	SubFPathList             []string `json:"sub_f_path_list"`
+	MediaServerInsideVideoID string   `json:"media_server_inside_video_id"`
+}

+ 12 - 0
internal/logic/cron_helper/cron_helper.go

@@ -30,6 +30,10 @@ type CronHelper struct {
 	entryIDSupplierCheck          cron.EntryID
 	entryIDQueueDownloader        cron.EntryID
 	entryIDScanPlayedVideoSubInfo cron.EntryID
+
+	cacheLocker   sync.Mutex
+	movieInfoMap  map[string]MovieInfo  // 给 Web 界面使用的,Key: VideoFPath
+	seasonInfoMap map[string]SeasonInfo // 给 Web 界面使用的,Key: RootDirPath
 }
 
 func NewCronHelper(fileDownloader *file_downloader.FileDownloader) *CronHelper {
@@ -40,6 +44,9 @@ func NewCronHelper(fileDownloader *file_downloader.FileDownloader) *CronHelper {
 		Settings:       fileDownloader.Settings,
 		// 实例化下载队列
 		DownloadQueue: task_queue.NewTaskQueue(fileDownloader.CacheCenter),
+
+		movieInfoMap:  make(map[string]MovieInfo),
+		seasonInfoMap: make(map[string]SeasonInfo),
 	}
 
 	var err error
@@ -61,6 +68,11 @@ func NewCronHelper(fileDownloader *file_downloader.FileDownloader) *CronHelper {
 		sub_formatter.GetSubFormatter(ch.log, ch.Settings.AdvancedSettings.SubNameFormatter),
 		ch.FileDownloader, ch.DownloadQueue)
 
+	err = ch.loadVideoListCache()
+	if err != nil {
+		fileDownloader.Log.Errorln("loadVideoListCache error:", err)
+	}
+
 	return &ch
 }