cache_info.go 9.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281
  1. package downloader
  2. import (
  3. "path/filepath"
  4. "github.com/allanpk716/ChineseSubFinder/pkg"
  5. backend2 "github.com/allanpk716/ChineseSubFinder/pkg/types/backend"
  6. "github.com/allanpk716/ChineseSubFinder/pkg/types/common"
  7. "github.com/allanpk716/ChineseSubFinder/pkg/types/task_queue"
  8. "github.com/allanpk716/ChineseSubFinder/pkg/my_util"
  9. "github.com/allanpk716/ChineseSubFinder/pkg/strcut_json"
  10. "github.com/allanpk716/ChineseSubFinder/pkg/sub_helper"
  11. )
  12. func (d *Downloader) SetMovieAndSeasonInfo(movieInfos []backend2.MovieInfo, seasonInfos []backend2.SeasonInfo) {
  13. d.cacheLocker.Lock()
  14. defer d.cacheLocker.Unlock()
  15. d.setMovieAndSeasonInfo(movieInfos, seasonInfos)
  16. }
  17. func (d *Downloader) GetMovieInfoAndSeasonInfo() ([]backend2.MovieInfo, []backend2.SeasonInfo) {
  18. // 需要把本实例中的缓存 map 转换到 Web 传递的结构体中
  19. d.cacheLocker.Lock()
  20. defer d.cacheLocker.Unlock()
  21. // 全部都获取
  22. return d.getMovieInfoAndSeasonInfo(0)
  23. }
  24. func (d *Downloader) UpdateInfo(job task_queue.OneJob) {
  25. d.cacheLocker.Lock()
  26. defer d.cacheLocker.Unlock()
  27. // 搜索字幕
  28. matchedSubFileByOneVideo, err := sub_helper.SearchMatchedSubFileByOneVideo(d.log, job.VideoFPath)
  29. if err != nil {
  30. d.log.Errorln("SearchMatchedSubFileByOneVideo", err)
  31. return
  32. }
  33. if job.VideoType == common.Movie {
  34. // 更新 movieInfo
  35. // 更新缓存, 存在,更新, 不存在,跳过
  36. if oneMovieInfo, ok := d.movieInfoMap[job.VideoFPath]; ok == true {
  37. oneMovieInfo.MediaServerInsideVideoID = job.MediaServerInsideVideoID
  38. oneMovieInfo.SubFPathList = matchedSubFileByOneVideo
  39. d.movieInfoMap[job.VideoFPath] = oneMovieInfo
  40. // 写入本地缓存
  41. backendMovieInfo, _ := d.getMovieInfoAndSeasonInfo(1)
  42. err = d.saveVideoListCache(backendMovieInfo, nil)
  43. if err != nil {
  44. d.log.Errorln("saveVideoListCache", job.VideoFPath, err)
  45. return
  46. }
  47. }
  48. } else if job.VideoType == common.Series {
  49. // 更新 seasonInfo
  50. // 更新缓存, 存在,更新, 不存在,跳过
  51. if oneSeasonInfo, ok := d.seasonInfoMap[job.SeriesRootDirPath]; ok == true {
  52. if nowOneVideoInfo, ok := oneSeasonInfo.OneVideoInfoMap[job.VideoFPath]; ok == true {
  53. nowOneVideoInfo.MediaServerInsideVideoID = job.MediaServerInsideVideoID
  54. nowOneVideoInfo.SubFPathList = matchedSubFileByOneVideo
  55. d.seasonInfoMap[job.SeriesRootDirPath].OneVideoInfoMap[job.VideoFPath] = nowOneVideoInfo
  56. // 写入本地缓存
  57. _, backendSeasonInfo := d.getMovieInfoAndSeasonInfo(2)
  58. err = d.saveVideoListCache(nil, backendSeasonInfo)
  59. if err != nil {
  60. d.log.Errorln("saveVideoListCache", job.VideoFPath, err)
  61. return
  62. }
  63. }
  64. }
  65. }
  66. }
  67. func (d *Downloader) setMovieAndSeasonInfo(movieInfos []backend2.MovieInfo, seasonInfos []backend2.SeasonInfo, skip ...bool) {
  68. // 需要把 Web 传递的结构体 转换到 本实例中的缓存 map
  69. // 清空
  70. d.movieInfoMap = make(map[string]MovieInfo)
  71. d.seasonInfoMap = make(map[string]SeasonInfo)
  72. for _, movieInfo := range movieInfos {
  73. nowMovieInfo := MovieInfo{
  74. Name: movieInfo.Name,
  75. DirRootUrl: movieInfo.DirRootUrl,
  76. VideoFPath: movieInfo.VideoFPath,
  77. VideoUrl: movieInfo.VideoUrl,
  78. MediaServerInsideVideoID: movieInfo.MediaServerInsideVideoID,
  79. SubFPathList: make([]string, 0),
  80. }
  81. nowMovieInfo.SubFPathList = append(nowMovieInfo.SubFPathList, movieInfo.SubFPathList...)
  82. d.movieInfoMap[movieInfo.VideoFPath] = nowMovieInfo
  83. }
  84. for _, seasonInfo := range seasonInfos {
  85. nowSeasonInfo := SeasonInfo{
  86. Name: seasonInfo.Name,
  87. RootDirPath: seasonInfo.RootDirPath,
  88. DirRootUrl: seasonInfo.DirRootUrl,
  89. OneVideoInfoMap: make(map[string]OneVideoInfo),
  90. }
  91. for _, oneVideoInfo := range seasonInfo.OneVideoInfos {
  92. nowOneVideoInfo := OneVideoInfo{
  93. Name: oneVideoInfo.Name,
  94. VideoFPath: oneVideoInfo.VideoFPath,
  95. VideoUrl: oneVideoInfo.VideoUrl,
  96. Season: oneVideoInfo.Season,
  97. Episode: oneVideoInfo.Episode,
  98. MediaServerInsideVideoID: oneVideoInfo.MediaServerInsideVideoID,
  99. SubFPathList: make([]string, 0),
  100. }
  101. nowOneVideoInfo.SubFPathList = append(nowOneVideoInfo.SubFPathList, oneVideoInfo.SubFPathList...)
  102. nowSeasonInfo.OneVideoInfoMap[oneVideoInfo.VideoFPath] = nowOneVideoInfo
  103. }
  104. d.seasonInfoMap[seasonInfo.RootDirPath] = nowSeasonInfo
  105. }
  106. if len(skip) > 0 && skip[0] == true {
  107. } else {
  108. err := d.saveVideoListCache(movieInfos, seasonInfos)
  109. if err != nil {
  110. d.log.Errorln("saveVideoListCache err:", err)
  111. return
  112. }
  113. }
  114. }
  115. func (d *Downloader) getMovieInfoAndSeasonInfo(AllorFrontorEnd int) ([]backend2.MovieInfo, []backend2.SeasonInfo) {
  116. outMovieInfos := make([]backend2.MovieInfo, 0)
  117. outSeasonInfo := make([]backend2.SeasonInfo, 0)
  118. // AllorFrontorEnd == 0, 全部, AllorFrontorEnd == 1, MovieInfo, AllorFrontorEnd == 2, SeasonInfo
  119. if AllorFrontorEnd == 0 || AllorFrontorEnd == 1 {
  120. for _, movieInfo := range d.movieInfoMap {
  121. nowMovieInfo := backend2.MovieInfo{
  122. Name: movieInfo.Name,
  123. DirRootUrl: movieInfo.DirRootUrl,
  124. VideoFPath: movieInfo.VideoFPath,
  125. VideoUrl: movieInfo.VideoUrl,
  126. MediaServerInsideVideoID: movieInfo.MediaServerInsideVideoID,
  127. SubFPathList: make([]string, 0),
  128. }
  129. nowMovieInfo.SubFPathList = append(nowMovieInfo.SubFPathList, movieInfo.SubFPathList...)
  130. outMovieInfos = append(outMovieInfos, nowMovieInfo)
  131. }
  132. }
  133. if AllorFrontorEnd == 0 || AllorFrontorEnd == 2 {
  134. for _, seasonInfo := range d.seasonInfoMap {
  135. nowSeasonInfo := backend2.SeasonInfo{
  136. Name: seasonInfo.Name,
  137. RootDirPath: seasonInfo.RootDirPath,
  138. DirRootUrl: seasonInfo.DirRootUrl,
  139. OneVideoInfos: make([]backend2.OneVideoInfo, 0),
  140. }
  141. for _, oneVideoInfo := range seasonInfo.OneVideoInfoMap {
  142. nowOneVideoInfo := backend2.OneVideoInfo{
  143. Name: oneVideoInfo.Name,
  144. VideoFPath: oneVideoInfo.VideoFPath,
  145. VideoUrl: oneVideoInfo.VideoUrl,
  146. Season: oneVideoInfo.Season,
  147. Episode: oneVideoInfo.Episode,
  148. MediaServerInsideVideoID: oneVideoInfo.MediaServerInsideVideoID,
  149. SubFPathList: make([]string, 0),
  150. }
  151. nowOneVideoInfo.SubFPathList = append(nowOneVideoInfo.SubFPathList, oneVideoInfo.SubFPathList...)
  152. nowSeasonInfo.OneVideoInfos = append(nowSeasonInfo.OneVideoInfos, nowOneVideoInfo)
  153. }
  154. outSeasonInfo = append(outSeasonInfo, nowSeasonInfo)
  155. }
  156. }
  157. return outMovieInfos, outSeasonInfo
  158. }
  159. func (d *Downloader) saveVideoListCache(movieInfos []backend2.MovieInfo, seasonInfos []backend2.SeasonInfo) error {
  160. // 缓存下来
  161. cacheCenterFolder, err := pkg.GetRootCacheCenterFolder()
  162. if err != nil {
  163. return err
  164. }
  165. movieInfosFileName := filepath.Join(cacheCenterFolder, "movie_infos.json")
  166. seasonInfosFileName := filepath.Join(cacheCenterFolder, "season_infos.json")
  167. if movieInfos != nil && len(movieInfos) > 0 {
  168. err = strcut_json.ToFile(movieInfosFileName, movieInfos)
  169. if err != nil {
  170. return err
  171. }
  172. }
  173. if seasonInfos != nil && len(seasonInfos) > 0 {
  174. err = strcut_json.ToFile(seasonInfosFileName, seasonInfos)
  175. if err != nil {
  176. return err
  177. }
  178. }
  179. return nil
  180. }
  181. func (d *Downloader) loadVideoListCache() error {
  182. // 缓存下来
  183. cacheCenterFolder, err := pkg.GetRootCacheCenterFolder()
  184. if err != nil {
  185. return err
  186. }
  187. movieInfosFileName := filepath.Join(cacheCenterFolder, "movie_infos.json")
  188. seasonInfosFileName := filepath.Join(cacheCenterFolder, "season_infos.json")
  189. movieInfos := make([]backend2.MovieInfo, 0)
  190. seasonInfos := make([]backend2.SeasonInfo, 0)
  191. if my_util.IsFile(movieInfosFileName) == true {
  192. err = strcut_json.ToStruct(movieInfosFileName, &movieInfos)
  193. if err != nil {
  194. return err
  195. }
  196. }
  197. if my_util.IsFile(seasonInfosFileName) == true {
  198. err = strcut_json.ToStruct(seasonInfosFileName, &seasonInfos)
  199. if err != nil {
  200. return err
  201. }
  202. }
  203. d.setMovieAndSeasonInfo(movieInfos, seasonInfos, true)
  204. return nil
  205. }
  206. type MovieInfo struct {
  207. Name string `json:"name"`
  208. DirRootUrl string `json:"dir_root_url"`
  209. VideoFPath string `json:"video_f_path"`
  210. VideoUrl string `json:"video_url"`
  211. MediaServerInsideVideoID string `json:"media_server_inside_video_id"`
  212. SubFPathList []string `json:"sub_f_path_list"`
  213. }
  214. type SeasonInfo struct {
  215. Name string `json:"name"`
  216. RootDirPath string `json:"root_dir_path"`
  217. DirRootUrl string `json:"dir_root_url"`
  218. OneVideoInfoMap map[string]OneVideoInfo `json:"one_video_info"` // Key VideoFPath
  219. }
  220. type OneVideoInfo struct {
  221. Name string `json:"name"`
  222. VideoFPath string `json:"video_f_path"`
  223. VideoUrl string `json:"video_url"`
  224. Season int `json:"season"`
  225. Episode int `json:"episode"`
  226. SubFPathList []string `json:"sub_f_path_list"`
  227. MediaServerInsideVideoID string `json:"media_server_inside_video_id"`
  228. }