subSupplierHub.go 8.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248
  1. package sub_supplier
  2. import (
  3. "path/filepath"
  4. "github.com/allanpk716/ChineseSubFinder/pkg/ifaces"
  5. "github.com/allanpk716/ChineseSubFinder/pkg/types/backend"
  6. "github.com/allanpk716/ChineseSubFinder/pkg/types/emby"
  7. "github.com/allanpk716/ChineseSubFinder/pkg/types/series"
  8. movieHelper "github.com/allanpk716/ChineseSubFinder/pkg/logic/movie_helper"
  9. seriesHelper "github.com/allanpk716/ChineseSubFinder/pkg/logic/series_helper"
  10. "github.com/allanpk716/ChineseSubFinder/pkg/settings"
  11. "github.com/allanpk716/ChineseSubFinder/pkg/sub_helper"
  12. "github.com/sirupsen/logrus"
  13. "gopkg.in/errgo.v2/fmt/errors"
  14. )
  15. type SubSupplierHub struct {
  16. settings *settings.Settings
  17. log *logrus.Logger
  18. Suppliers []ifaces.ISupplier
  19. }
  20. func NewSubSupplierHub(one ifaces.ISupplier, _inSupplier ...ifaces.ISupplier) *SubSupplierHub {
  21. s := SubSupplierHub{}
  22. s.settings = one.GetSettings()
  23. s.log = one.GetLogger()
  24. s.Suppliers = make([]ifaces.ISupplier, 0)
  25. s.Suppliers = append(s.Suppliers, one)
  26. if len(_inSupplier) > 0 {
  27. for _, supplier := range _inSupplier {
  28. s.Suppliers = append(s.Suppliers, supplier)
  29. }
  30. }
  31. return &s
  32. }
  33. // AddSubSupplier 添加一个下载器,目前目标是给 SubHD 使用
  34. func (d *SubSupplierHub) AddSubSupplier(one ifaces.ISupplier) {
  35. d.Suppliers = append(d.Suppliers, one)
  36. }
  37. // DelSubSupplier 移除一个下载器
  38. func (d *SubSupplierHub) DelSubSupplier(one ifaces.ISupplier) {
  39. for i := 0; i < len(d.Suppliers); i++ {
  40. if one.GetSupplierName() == d.Suppliers[i].GetSupplierName() {
  41. d.Suppliers = append(d.Suppliers[:i], d.Suppliers[i+1:]...)
  42. }
  43. }
  44. }
  45. // MovieNeedDlSub 电影是否符合要求需要下载字幕,比如
  46. func (d *SubSupplierHub) MovieNeedDlSub(videoFullPath string, forcedScanAndDownloadSub bool) bool {
  47. if forcedScanAndDownloadSub == true {
  48. return true
  49. }
  50. var err error
  51. if d.settings.AdvancedSettings.ScanLogic.SkipChineseMovie == true {
  52. var skip bool
  53. // 跳过中文的电影,不是一定要跳过的
  54. skip, err = movieHelper.SkipChineseMovie(d.log, videoFullPath, d.settings.AdvancedSettings.ProxySettings)
  55. if err != nil {
  56. d.log.Warnln("SkipChineseMovie", videoFullPath, err)
  57. }
  58. if skip == true {
  59. return false
  60. }
  61. }
  62. var needDlSub = false
  63. if forcedScanAndDownloadSub == true {
  64. // 强制下载字幕
  65. needDlSub = true
  66. } else {
  67. needDlSub, err = movieHelper.MovieNeedDlSub(d.log, videoFullPath, d.settings.AdvancedSettings.TaskQueue.ExpirationTime)
  68. if err != nil {
  69. d.log.Errorln(errors.Newf("MovieNeedDlSub %v %v", videoFullPath, err))
  70. return false
  71. }
  72. }
  73. return needDlSub
  74. }
  75. // SeriesNeedDlSub 连续剧是否符合要求需要下载字幕
  76. func (d *SubSupplierHub) SeriesNeedDlSub(seriesRootPath string, forcedScanAndDownloadSub bool, need2AnalyzeSub bool) (bool, *series.SeriesInfo, error) {
  77. if forcedScanAndDownloadSub == false {
  78. if d.settings.AdvancedSettings.ScanLogic.SkipChineseSeries == true {
  79. var skip bool
  80. var err error
  81. // 跳过中文的电影,不是一定要跳过的
  82. skip, _, err = seriesHelper.SkipChineseSeries(d.log, seriesRootPath, d.settings.AdvancedSettings.ProxySettings)
  83. if err != nil {
  84. d.log.Warnln("SkipChineseMovie", seriesRootPath, err)
  85. }
  86. if skip == true {
  87. return false, nil, nil
  88. }
  89. }
  90. }
  91. // 读取本地的视频和字幕信息
  92. seriesInfo, err := seriesHelper.ReadSeriesInfoFromDir(d.log, seriesRootPath,
  93. d.settings.AdvancedSettings.TaskQueue.ExpirationTime,
  94. forcedScanAndDownloadSub,
  95. need2AnalyzeSub,
  96. d.settings.AdvancedSettings.ProxySettings)
  97. if err != nil {
  98. return false, nil, errors.Newf("ReadSeriesInfoFromDir %v %v", seriesRootPath, err)
  99. }
  100. return true, seriesInfo, nil
  101. }
  102. // SeriesNeedDlSubFromEmby 连续剧是否符合要求需要下载字幕
  103. func (d *SubSupplierHub) SeriesNeedDlSubFromEmby(seriesRootPath string, seriesVideoList []emby.EmbyMixInfo, ExpirationTime int, skipChineseMovie, forcedScanAndDownloadSub bool) (bool, *series.SeriesInfo, error) {
  104. if skipChineseMovie == true {
  105. var skip bool
  106. var err error
  107. // 跳过中文的电影,不是一定要跳过的
  108. skip, _, err = seriesHelper.SkipChineseSeries(d.log, seriesRootPath, d.settings.AdvancedSettings.ProxySettings)
  109. if err != nil {
  110. d.log.Warnln("SkipChineseMovie", seriesRootPath, err)
  111. }
  112. if skip == true {
  113. return false, nil, nil
  114. }
  115. }
  116. // 读取本地的视频和字幕信息
  117. seriesInfo, err := seriesHelper.ReadSeriesInfoFromEmby(d.log, seriesRootPath, seriesVideoList, ExpirationTime, forcedScanAndDownloadSub, false, d.settings.AdvancedSettings.ProxySettings)
  118. if err != nil {
  119. return false, nil, errors.Newf("ReadSeriesInfoFromDir %v %v", seriesRootPath, err)
  120. }
  121. return true, seriesInfo, nil
  122. }
  123. // DownloadSub4Movie 某一个电影字幕下载,下载完毕后,返回下载缓存每个字幕的位置,这里将只关心下载字幕,判断是否在时间范围内要不要下载不在这里判断,包括是否是中文视频的问题
  124. func (d *SubSupplierHub) DownloadSub4Movie(videoFullPath string, index int64) ([]string, error) {
  125. // 下载所有字幕
  126. subInfos := movieHelper.OneMovieDlSubInAllSite(d.log, d.Suppliers, videoFullPath, index)
  127. if subInfos == nil || len(subInfos) < 1 {
  128. d.log.Warningln("OneMovieDlSubInAllSite.subInfos == 0, No Sub Downloaded.")
  129. return nil, nil
  130. }
  131. // 整理字幕,比如解压什么的
  132. organizeSubFiles, err := sub_helper.OrganizeDlSubFiles(d.log, filepath.Base(videoFullPath), subInfos, true)
  133. if err != nil {
  134. return nil, errors.Newf("OrganizeDlSubFiles %v %v", videoFullPath, err)
  135. }
  136. // 因为是下载电影,需要合并返回
  137. var outSubFileFullPathList = make([]string, 0)
  138. for s := range organizeSubFiles {
  139. outSubFileFullPathList = append(outSubFileFullPathList, organizeSubFiles[s]...)
  140. }
  141. for i, subFile := range outSubFileFullPathList {
  142. d.log.Debugln("OneMovieDlSubInAllSite", videoFullPath, i, "SubFileFPath:", subFile)
  143. }
  144. return outSubFileFullPathList, nil
  145. }
  146. // DownloadSub4Series 某一部连续剧的字幕下载,下载完毕后,返回下载缓存每个字幕的位置(通用的下载逻辑,前面把常规(没有媒体服务器模式)和 Emby 这样的模式都转换到想到的下载接口上
  147. func (d *SubSupplierHub) DownloadSub4Series(seriesDirPath string, seriesInfo *series.SeriesInfo, index int64) (map[string][]string, error) {
  148. organizeSubFiles, err := d.dlSubFromSeriesInfo(seriesDirPath, index, seriesInfo)
  149. if err != nil {
  150. return nil, err
  151. }
  152. return organizeSubFiles, nil
  153. }
  154. // CheckSubSiteStatus 检测多个字幕提供的网站是否是有效的,是否下载次数超限
  155. func (d *SubSupplierHub) CheckSubSiteStatus(proxySettings ...*settings.ProxySettings) backend.ReplyCheckStatus {
  156. outStatus := backend.ReplyCheckStatus{
  157. SubSiteStatus: make([]backend.SiteStatus, 0),
  158. }
  159. // 测试提供字幕的网站是有效的
  160. d.log.Infoln("Check Sub Supplier Start...")
  161. for _, supplier := range d.Suppliers {
  162. bAlive, speed := supplier.CheckAlive(proxySettings...)
  163. if bAlive == false {
  164. d.log.Warningln(supplier.GetSupplierName(), "Check Alive = false")
  165. } else {
  166. d.log.Infoln(supplier.GetSupplierName(), "Check Alive = true, Speed =", speed, "ms")
  167. }
  168. outStatus.SubSiteStatus = append(outStatus.SubSiteStatus, backend.SiteStatus{
  169. Name: supplier.GetSupplierName(),
  170. Valid: bAlive,
  171. Speed: speed,
  172. })
  173. }
  174. suppliersLen := len(d.Suppliers)
  175. for i := 0; i < suppliersLen; {
  176. // 网络检测是否有效,以及每次的下载次数限制检测
  177. if d.Suppliers[i].IsAlive() == false || d.Suppliers[i].OverDailyDownloadLimit() == true {
  178. d.DelSubSupplier(d.Suppliers[i])
  179. // 删除后,从头再来
  180. suppliersLen = len(d.Suppliers)
  181. i = 0
  182. continue
  183. }
  184. i++
  185. }
  186. for _, supplier := range d.Suppliers {
  187. if supplier.IsAlive() == true {
  188. d.log.Infoln("Alive Supplier:", supplier.GetSupplierName())
  189. }
  190. }
  191. d.log.Infoln("Check Sub Supplier End")
  192. return outStatus
  193. }
  194. func (d *SubSupplierHub) dlSubFromSeriesInfo(seriesDirPath string, index int64, seriesInfo *series.SeriesInfo) (map[string][]string, error) {
  195. // 下载好的字幕
  196. subInfos := seriesHelper.DownloadSubtitleInAllSiteByOneSeries(d.log, d.Suppliers, seriesInfo, index)
  197. // 整理字幕,比如解压什么的
  198. // 每一集 SxEx - 对应解压整理后的字幕列表
  199. if len(subInfos) < 1 {
  200. d.log.Warningln("DownloadSubtitleInAllSiteByOneSeries.subInfos == 0, No Sub Downloaded.")
  201. }
  202. organizeSubFiles, err := sub_helper.OrganizeDlSubFiles(d.log, filepath.Base(seriesDirPath), subInfos, false)
  203. if err != nil {
  204. return nil, errors.Newf("OrganizeDlSubFiles %v %v", seriesDirPath, err)
  205. }
  206. return organizeSubFiles, nil
  207. }