imdb.go 6.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198
  1. package imdb_helper
  2. import (
  3. "errors"
  4. "fmt"
  5. "strconv"
  6. "strings"
  7. "github.com/allanpk716/ChineseSubFinder/pkg/types"
  8. "github.com/allanpk716/ChineseSubFinder/pkg/types/common"
  9. "github.com/StalkR/imdb"
  10. "github.com/allanpk716/ChineseSubFinder/internal/dao"
  11. "github.com/allanpk716/ChineseSubFinder/internal/models"
  12. "github.com/allanpk716/ChineseSubFinder/pkg/decode"
  13. "github.com/allanpk716/ChineseSubFinder/pkg/my_util"
  14. "github.com/allanpk716/ChineseSubFinder/pkg/notify_center"
  15. "github.com/allanpk716/ChineseSubFinder/pkg/settings"
  16. "github.com/sirupsen/logrus"
  17. )
  18. // GetVideoInfoFromIMDBWeb 从 IMDB 网站 ID 查询影片的信息
  19. func GetVideoInfoFromIMDBWeb(imdbInfo types.VideoNfoInfo, _proxySettings ...*settings.ProxySettings) (*imdb.Title, error) {
  20. client, err := my_util.NewHttpClient(_proxySettings...)
  21. if err != nil {
  22. return nil, err
  23. }
  24. t, err := imdb.NewTitle(client.GetClient(), imdbInfo.ImdbId)
  25. if err != nil {
  26. notify_center.Notify.Add("imdb model - imdb.NewTitle :", err.Error())
  27. return nil, err
  28. }
  29. if t.Year == 0 {
  30. // IMDB 信息获取的库(1.0.7),目前有bug,比如,tt6856242 年份为 0
  31. if imdbInfo.Year != "" {
  32. year, err := strconv.Atoi(imdbInfo.Year)
  33. if err != nil {
  34. return nil, err
  35. }
  36. t.Year = year
  37. }
  38. }
  39. return t, nil
  40. }
  41. // GetVideoIMDBInfoFromLocal 从本地获取 IMDB 信息,注意,如果需要跳过,那么返回 Error == common.SkipCreateInDB
  42. func GetVideoIMDBInfoFromLocal(log *logrus.Logger, imdbInfo types.VideoNfoInfo, skipCreate ...bool) (*models.IMDBInfo, error) {
  43. /*
  44. 这里需要注意一个细节,之前理想情况下是从 Web 获取完整的 IMDB Info 回来,放入本地存储
  45. 获取的时候如果本地有就拿本地的,没有则从 Web 获取,然后写入本地存储
  46. 但是实际的使用中发现,其实只有在判断视频是否是中文的时候才有必要去获取 Web 上完整的 IMDB Info 信息
  47. 如果一开始就需要从 Web 上获取,那么这个过程非常的缓慢,很耽误时间,所以还是切换为两层逻辑
  48. 1. 第一次,优先获取本地的 IMDB Info,写入数据库缓存
  49. 2. 如果需要判断视频是否是中文的时候,再去获取 Web 上完整的 IMDB Info 信息,更新写入本地存储
  50. 3. 因为现在默认是不跳过中文视频扫描的,所以如果开启后,则会再判断的时候访问外网获取,然后写入本地,过程会比较慢
  51. 4. 同时,再发送字幕和 IMDB Info 到服务器的时候,也需要判断是否 IMDB Info 信息是否齐全,否则就需要从外网获取齐全后再上传
  52. */
  53. log.Debugln("GetVideoIMDBInfoFromLocal", "IMDBID:", imdbInfo.ImdbId, "TMDBID:", imdbInfo.TmdbId, imdbInfo.Title, imdbInfo.Season, imdbInfo.Episode)
  54. log.Debugln("GetVideoIMDBInfoFromLocal", 0)
  55. if imdbInfo.ImdbId != "" {
  56. // 优先从 IMDB ID 去查找本地的信息
  57. // 首先从数据库中查找是否存在这个 IMDB 信息,如果不存在再使用 Web 查找,且写入数据库
  58. var imdbInfos []models.IMDBInfo
  59. // 把嵌套关联的 has many 的信息都查询出来
  60. dao.GetDb().
  61. Preload("VideoSubInfos").
  62. Limit(1).Where(&models.IMDBInfo{IMDBID: imdbInfo.ImdbId}).Find(&imdbInfos)
  63. log.Debugln("GetVideoIMDBInfoFromLocal", 1)
  64. if len(imdbInfos) <= 0 {
  65. if len(skipCreate) > 0 && skipCreate[0] == true {
  66. log.Debugln(fmt.Sprintf("skip insert, imdbInfo.ImdbId = %v", imdbInfo.ImdbId))
  67. return nil, common.SkipCreateInDB
  68. }
  69. // 没有找到,新增,存储本地,但是信息肯定是不完整的,需要在判断是否是中文的时候再次去外网获取补全信息
  70. log.Debugln("GetVideoIMDBInfoFromLocal", 2)
  71. // 存入数据库
  72. nowIMDBInfo := models.NewIMDBInfo(imdbInfo.ImdbId, "", 0, "", []string{}, []string{})
  73. dao.GetDb().Create(nowIMDBInfo)
  74. log.Debugln("GetVideoIMDBInfoFromLocal", 3)
  75. return nowIMDBInfo, nil
  76. } else {
  77. log.Debugln("GetVideoIMDBInfoFromLocal", 4)
  78. // 找到
  79. return &imdbInfos[0], nil
  80. }
  81. } else if imdbInfo.TmdbId != "" {
  82. // 如果 IMDB ID 在本地没有获取到,但是 TMDB ID 获取到了,那么就从 Web 去查询 IMDB ID 出来
  83. } else {
  84. // 都没有,那么就报错
  85. log.Debugln("GetVideoIMDBInfoFromLocal IMDB TMDB ID is empty")
  86. return nil, errors.New("IMDB TMDB ID is empty")
  87. }
  88. }
  89. // IsChineseVideo 从 imdbID 去查询判断是否是中文视频
  90. func IsChineseVideo(log *logrus.Logger, imdbInfo types.VideoNfoInfo, _proxySettings ...*settings.ProxySettings) (bool, *models.IMDBInfo, error) {
  91. const chName0 = "chinese"
  92. const chName1 = "mandarin"
  93. log.Debugln("IsChineseVideo", 0)
  94. localIMDBInfo, err := GetVideoIMDBInfoFromLocal(log, imdbInfo)
  95. if err != nil {
  96. return false, nil, err
  97. }
  98. if len(localIMDBInfo.Description) <= 0 {
  99. // 需要去外网获去补全信息,然后更新本地的信息
  100. log.Debugln("IsChineseVideo", 1)
  101. t, err := GetVideoInfoFromIMDBWeb(imdbInfo, _proxySettings...)
  102. if err != nil {
  103. log.Errorln("IsChineseVideo.getVideoInfoFromIMDBWeb,", imdbInfo.Title, err)
  104. return false, nil, err
  105. }
  106. log.Debugln("IsChineseVideo", 2)
  107. localIMDBInfo.Year = t.Year
  108. localIMDBInfo.Name = t.Name
  109. localIMDBInfo.Year = t.Year
  110. localIMDBInfo.AKA = t.AKA
  111. localIMDBInfo.Description = t.Description
  112. localIMDBInfo.Languages = t.Languages
  113. log.Debugln("IsChineseVideo", 3)
  114. dao.GetDb().Save(localIMDBInfo)
  115. log.Debugln("IsChineseVideo", 4)
  116. }
  117. if len(localIMDBInfo.Languages) < 1 {
  118. return false, localIMDBInfo, nil
  119. }
  120. firstLangLowCase := strings.ToLower(localIMDBInfo.Languages[0])
  121. log.Debugln("IsChineseVideo", 5)
  122. // 判断第一语言是否是中文
  123. switch firstLangLowCase {
  124. case chName0, chName1:
  125. return true, localIMDBInfo, nil
  126. default:
  127. return false, localIMDBInfo, nil
  128. }
  129. }
  130. // GetIMDBInfo 先从本地拿缓存,如果没有就从 Web 获取
  131. func GetIMDBInfo(log *logrus.Logger, videoFPath string, isMovie bool, _proxySettings ...*settings.ProxySettings) (*models.IMDBInfo, error) {
  132. var err error
  133. var imdbInfo4Video types.VideoNfoInfo
  134. if isMovie == true {
  135. imdbInfo4Video, err = decode.GetVideoNfoInfo4Movie(videoFPath)
  136. } else {
  137. imdbInfo4Video, err = decode.GetSeriesSeasonVideoNfoInfoFromEpisode(videoFPath)
  138. }
  139. if err != nil {
  140. // 如果找不到当前电影的 IMDB Info 本地文件,那么就跳过
  141. log.Warningln("getSubListFromFile", videoFPath, err)
  142. return nil, err
  143. }
  144. imdbInfo, err := GetVideoIMDBInfoFromLocal(log, imdbInfo4Video)
  145. if err != nil {
  146. log.Warningln("GetVideoIMDBInfoFromLocal", videoFPath, err)
  147. return nil, err
  148. }
  149. if len(imdbInfo.Description) <= 0 {
  150. // 需要去外网获去补全信息,然后更新本地的信息
  151. t, err := GetVideoInfoFromIMDBWeb(imdbInfo4Video, _proxySettings...)
  152. if err != nil {
  153. log.Errorln("GetVideoInfoFromIMDBWeb,", imdbInfo4Video.Title, err)
  154. return nil, err
  155. }
  156. imdbInfo.Year = t.Year
  157. imdbInfo.AKA = t.AKA
  158. imdbInfo.Description = t.Description
  159. imdbInfo.Languages = t.Languages
  160. dao.GetDb().Save(imdbInfo)
  161. }
  162. return imdbInfo, nil
  163. }