video_list_v2.go 9.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310
  1. package v1
  2. import (
  3. "fmt"
  4. "net/http"
  5. "time"
  6. "github.com/ChineseSubFinder/ChineseSubFinder/internal/models"
  7. "github.com/ChineseSubFinder/ChineseSubFinder/pkg/search"
  8. "github.com/ChineseSubFinder/ChineseSubFinder/pkg/sub_helper"
  9. "github.com/ChineseSubFinder/ChineseSubFinder/pkg/path_helper"
  10. backend2 "github.com/ChineseSubFinder/ChineseSubFinder/pkg/types/backend"
  11. vsh "github.com/ChineseSubFinder/ChineseSubFinder/pkg/video_scan_and_refresh_helper"
  12. "github.com/gin-gonic/gin"
  13. "github.com/pkg/errors"
  14. )
  15. // RefreshMainList 重构后的视频列表,比如 x:\电影\壮志凌云\壮志凌云.mp4 或者是连续剧的 x:\连续剧\绝命毒师 根目录
  16. func (cb *ControllerBase) RefreshMainList(c *gin.Context) {
  17. var err error
  18. defer func() {
  19. // 统一的异常处理
  20. cb.ErrorProcess(c, "RefreshMainList", err)
  21. }()
  22. if cb.videoScanAndRefreshHelperLocker.Lock() == false {
  23. // 已经在执行,跳过
  24. c.JSON(http.StatusOK, backend2.ReplyRefreshVideoList{
  25. Status: "running"})
  26. return
  27. }
  28. cb.videoScanAndRefreshHelperIsRunning = true
  29. go func() {
  30. startT := time.Now()
  31. cb.log.Infoln("------------------------------------")
  32. cb.log.Infoln("Video Scan Started By webui...")
  33. pathUrlMap := cb.GetPathUrlMap()
  34. cb.log.Infoln("---------------------------------")
  35. cb.log.Infoln("GetPathUrlMap")
  36. for s, s2 := range pathUrlMap {
  37. cb.log.Infoln("pathUrlMap", s, s2)
  38. }
  39. cb.log.Infoln("---------------------------------")
  40. defer func() {
  41. cb.videoScanAndRefreshHelperIsRunning = false
  42. cb.videoScanAndRefreshHelperLocker.Unlock()
  43. cb.log.Infoln("Video Scan Finished By webui, cost:", time.Since(startT).Minutes(), "min")
  44. cb.log.Infoln("------------------------------------")
  45. }()
  46. var err2 error
  47. cb.videoScanAndRefreshHelperErrMessage = ""
  48. var mainList *vsh.NormalScanVideoResult
  49. mainList, err2 = cb.videoListHelper.RefreshMainList()
  50. if err2 != nil {
  51. cb.log.Errorln("RefreshMainList", err2)
  52. cb.videoScanAndRefreshHelperErrMessage = err2.Error()
  53. return
  54. }
  55. err2 = cb.cronHelper.Downloader.SetMovieAndSeasonInfoV2(mainList)
  56. if err2 != nil {
  57. cb.log.Errorln("SetMovieAndSeasonInfoV2", err2)
  58. cb.videoScanAndRefreshHelperErrMessage = err2.Error()
  59. return
  60. }
  61. }()
  62. c.JSON(http.StatusOK, backend2.ReplyRefreshVideoList{
  63. Status: "running"})
  64. return
  65. }
  66. // VideoMainList 获取电影和连续剧的基础结构
  67. func (cb *ControllerBase) VideoMainList(c *gin.Context) {
  68. var err error
  69. defer func() {
  70. // 统一的异常处理
  71. cb.ErrorProcess(c, "MoviePoster", err)
  72. }()
  73. outMovieInfos, outSeasonInfo, err := cb.cronHelper.Downloader.GetMovieInfoAndSeasonInfoV2()
  74. if err != nil {
  75. cb.log.Errorln("GetMovieInfoAndSeasonInfoV2", err)
  76. return
  77. }
  78. c.JSON(http.StatusOK, backend2.ReplyMainList{
  79. MovieInfos: outMovieInfos,
  80. SeasonInfos: outSeasonInfo,
  81. })
  82. }
  83. // MoviePoster 获取电影海报
  84. func (cb *ControllerBase) MoviePoster(c *gin.Context) {
  85. var err error
  86. defer func() {
  87. // 统一的异常处理
  88. cb.ErrorProcess(c, "MoviePoster", err)
  89. }()
  90. movieInfo := backend2.MovieInfoV2{}
  91. err = c.ShouldBindJSON(&movieInfo)
  92. if err != nil {
  93. return
  94. }
  95. // 然后还需要将这个全路径信息转换为 静态文件服务器对应的路径返回给前端
  96. desUrl, found := cb.GetPathUrlMap()[movieInfo.MainRootDirFPath]
  97. if found == false {
  98. // 没有找到对应的 URL
  99. errMessage := fmt.Sprintf("MoviePoster.GetPathUrlMap can not find url for path %s", movieInfo.MainRootDirFPath)
  100. cb.log.Warningln(errMessage)
  101. err = errors.New(errMessage)
  102. return
  103. }
  104. posterFPath := cb.videoListHelper.GetMoviePoster(movieInfo.VideoFPath)
  105. posterUrl := path_helper.ChangePhysicalPathToSharePath(posterFPath, movieInfo.MainRootDirFPath, desUrl)
  106. c.JSON(http.StatusOK, backend2.PosterInfo{
  107. Url: posterUrl,
  108. })
  109. }
  110. // SeriesPoster 从一个连续剧的根目录中,获取连续剧的海报
  111. func (cb *ControllerBase) SeriesPoster(c *gin.Context) {
  112. var err error
  113. defer func() {
  114. // 统一的异常处理
  115. cb.ErrorProcess(c, "SeriesPoster", err)
  116. }()
  117. seriesInfo := backend2.SeasonInfoV2{}
  118. err = c.ShouldBindJSON(&seriesInfo)
  119. if err != nil {
  120. return
  121. }
  122. // 然后还需要将这个全路径信息转换为 静态文件服务器对应的路径返回给前端
  123. desUrl, found := cb.GetPathUrlMap()[seriesInfo.MainRootDirFPath]
  124. if found == false {
  125. // 没有找到对应的 URL
  126. errMessage := fmt.Sprintf("SeriesPoster.GetPathUrlMap can not find url for path %s", seriesInfo.MainRootDirFPath)
  127. cb.log.Warningln(errMessage)
  128. err = errors.New(errMessage)
  129. return
  130. }
  131. posterFPath := cb.videoListHelper.GetSeriesPoster(seriesInfo.RootDirPath)
  132. posterUrl := path_helper.ChangePhysicalPathToSharePath(posterFPath, seriesInfo.MainRootDirFPath, desUrl)
  133. c.JSON(http.StatusOK, backend2.PosterInfo{
  134. Url: posterUrl,
  135. })
  136. }
  137. // OneMovieSubs 由一部电影去搜索其当前目录下的对应字幕
  138. func (cb *ControllerBase) OneMovieSubs(c *gin.Context) {
  139. var err error
  140. defer func() {
  141. // 统一的异常处理
  142. cb.ErrorProcess(c, "OneMovieSubs", err)
  143. }()
  144. movieInfo := backend2.MovieInfoV2{}
  145. err = c.ShouldBindJSON(&movieInfo)
  146. if err != nil {
  147. return
  148. }
  149. // 然后还需要将这个全路径信息转换为 静态文件服务器对应的路径返回给前端
  150. desUrl, found := cb.GetPathUrlMap()[movieInfo.MainRootDirFPath]
  151. if found == false {
  152. // 没有找到对应的 URL
  153. errMessage := fmt.Sprintf("OneMovieSubs.GetPathUrlMap can not find url for path %s", movieInfo.MainRootDirFPath)
  154. cb.log.Warningln(errMessage)
  155. err = errors.New(errMessage)
  156. return
  157. }
  158. matchedSubs, err := sub_helper.SearchMatchedSubFileByOneVideo(cb.log, movieInfo.VideoFPath)
  159. if err != nil {
  160. cb.log.Errorln("OneMovieSubs.SearchMatchedSubFileByOneVideo", err)
  161. return
  162. }
  163. movieSubsInfo := backend2.MovieSubsInfo{
  164. SubUrlList: make([]string, 0),
  165. }
  166. // 将匹配到的字幕文件转换为 URL
  167. for _, sub := range matchedSubs {
  168. subUrl := path_helper.ChangePhysicalPathToSharePath(sub, movieInfo.MainRootDirFPath, desUrl)
  169. movieSubsInfo.SubUrlList = append(movieSubsInfo.SubUrlList, subUrl)
  170. movieSubsInfo.SubFPathList = append(movieSubsInfo.SubFPathList, sub)
  171. }
  172. c.JSON(http.StatusOK, movieSubsInfo)
  173. }
  174. func (cb *ControllerBase) OneSeriesSubs(c *gin.Context) {
  175. var err error
  176. defer func() {
  177. // 统一的异常处理
  178. cb.ErrorProcess(c, "OneSeriesSubs", err)
  179. }()
  180. seriesInfo := backend2.SeasonInfoV2{}
  181. err = c.ShouldBindJSON(&seriesInfo)
  182. if err != nil {
  183. return
  184. }
  185. // 然后还需要将这个全路径信息转换为 静态文件服务器对应的路径返回给前端
  186. desUrl, found := cb.GetPathUrlMap()[seriesInfo.MainRootDirFPath]
  187. if found == false {
  188. // 没有找到对应的 URL
  189. errMessage := fmt.Sprintf("OneSeriesSubs.GetPathUrlMap can not find url for path %s", seriesInfo.MainRootDirFPath)
  190. cb.log.Warningln(errMessage)
  191. err = errors.New(errMessage)
  192. return
  193. }
  194. seasonInfo, err := search.SeriesAllEpsAndSubtitles(cb.log, seriesInfo.RootDirPath)
  195. if err != nil {
  196. cb.log.Errorln("OneSeriesSubs.SeriesAllEpsAndSubtitles", err)
  197. return
  198. }
  199. for i, videoInfo := range seasonInfo.OneVideoInfos {
  200. for _, subFPath := range videoInfo.SubFPathList {
  201. subUrl := path_helper.ChangePhysicalPathToSharePath(subFPath, seriesInfo.MainRootDirFPath, desUrl)
  202. seasonInfo.OneVideoInfos[i].SubUrlList = append(seasonInfo.OneVideoInfos[i].SubUrlList, subUrl)
  203. }
  204. videoUrl := path_helper.ChangePhysicalPathToSharePath(videoInfo.VideoFPath, seriesInfo.MainRootDirFPath, desUrl)
  205. seasonInfo.OneVideoInfos[i].VideoUrl = videoUrl
  206. }
  207. c.JSON(http.StatusOK, seasonInfo)
  208. }
  209. // ScanSkipInfo 设置或者获取跳过扫描信息的状态
  210. func (cb *ControllerBase) ScanSkipInfo(c *gin.Context) {
  211. var err error
  212. defer func() {
  213. // 统一的异常处理
  214. cb.ErrorProcess(c, "ScanSkipInfo", err)
  215. }()
  216. switch c.Request.Method {
  217. case "POST":
  218. {
  219. // 查询
  220. videoSkipInfos := backend2.ReqVideoSkipInfos{}
  221. err = c.ShouldBindJSON(&videoSkipInfos)
  222. if err != nil {
  223. return
  224. }
  225. isSkips := make([]bool, 0)
  226. for _, videoSkipInfo := range videoSkipInfos.VideoSkipInfos {
  227. isSkip := cb.cronHelper.Downloader.ScanLogic.Get(videoSkipInfo.VideoType, videoSkipInfo.PhysicalVideoFileFullPath)
  228. isSkips = append(isSkips, isSkip)
  229. }
  230. c.JSON(http.StatusOK, backend2.ReplyVideoSkipInfo{
  231. IsSkips: isSkips,
  232. })
  233. return
  234. }
  235. case "PUT":
  236. {
  237. // 设置
  238. videoSkipInfos := backend2.ReqVideoSkipInfos{}
  239. err = c.ShouldBindJSON(&videoSkipInfos)
  240. if err != nil {
  241. return
  242. }
  243. for _, videoSkipInfo := range videoSkipInfos.VideoSkipInfos {
  244. var skipInfo *models.SkipScanInfo
  245. if videoSkipInfo.VideoType == 0 {
  246. // 电影
  247. skipInfo = models.NewSkipScanInfoByMovie(videoSkipInfo.PhysicalVideoFileFullPath, videoSkipInfo.IsSkip)
  248. } else {
  249. // 电视剧
  250. skipInfo = models.NewSkipScanInfoBySeriesEx(videoSkipInfo.PhysicalVideoFileFullPath, videoSkipInfo.IsSkip)
  251. }
  252. cb.cronHelper.Downloader.ScanLogic.Set(skipInfo)
  253. }
  254. c.JSON(http.StatusOK, backend2.ReplyCommon{
  255. Message: "ok"})
  256. return
  257. }
  258. default:
  259. c.JSON(http.StatusNoContent, backend2.ReplyCommon{Message: "ScanSkipInfo Request.Method Error"})
  260. }
  261. }