Pārlūkot izejas kodu

保存进度

Signed-off-by: allan716 <[email protected]>
allan716 3 gadi atpakaļ
vecāks
revīzija
aca47a9e41

+ 3 - 3
internal/logic/series_helper/seriesHelper.go

@@ -110,7 +110,7 @@ func ReadSeriesInfoFromDir(seriesDir string, forcedScanAndDownloadSub bool, _pro
 }
 
 // ReadSeriesInfoFromEmby 将 Emby API 读取到的数据进行转换到通用的结构中,需要填充那些剧集需要下载,这样要的是一个连续剧的,不是所有的传入(只有那些 Eps 需要下载字幕的 NeedDlEpsKeyList)
-func ReadSeriesInfoFromEmby(seriesDir string, seriesList []emby.EmbyMixInfo, _proxySettings ...*settings.ProxySettings) (*series.SeriesInfo, error) {
+func ReadSeriesInfoFromEmby(seriesDir string, seriesVideoList []emby.EmbyMixInfo, forcedScanAndDownloadSub bool, _proxySettings ...*settings.ProxySettings) (*series.SeriesInfo, error) {
 
 	seriesInfo, SubDict, err := readSeriesInfo(seriesDir, _proxySettings...)
 	if err != nil {
@@ -118,7 +118,7 @@ func ReadSeriesInfoFromEmby(seriesDir string, seriesList []emby.EmbyMixInfo, _pr
 	}
 
 	EpisodeDict := make(map[string]series.EpisodeInfo)
-	for _, info := range seriesList {
+	for _, info := range seriesVideoList {
 		getEpsInfoAndSubDic(info.PhysicalVideoFileFullPath, EpisodeDict, SubDict)
 	}
 
@@ -127,7 +127,7 @@ func ReadSeriesInfoFromEmby(seriesDir string, seriesList []emby.EmbyMixInfo, _pr
 		seriesInfo.SeasonDict[episodeInfo.Season] = episodeInfo.Season
 	}
 
-	seriesInfo.NeedDlEpsKeyList, seriesInfo.NeedDlSeasonDict = whichSeasonEpsNeedDownloadSub(seriesInfo, false)
+	seriesInfo.NeedDlEpsKeyList, seriesInfo.NeedDlSeasonDict = whichSeasonEpsNeedDownloadSub(seriesInfo, forcedScanAndDownloadSub)
 
 	return seriesInfo, nil
 }

+ 29 - 20
internal/logic/sub_supplier/subSupplierHub.go

@@ -54,10 +54,10 @@ func (d *SubSupplierHub) DelSubSupplier(one ifaces.ISupplier) {
 }
 
 // MovieNeedDlSub 电影是否符合要求需要下载字幕,比如
-func (d *SubSupplierHub) MovieNeedDlSub(videoFullPath string, skipChineseMovie, forcedScanAndDownloadSub bool) bool {
+func (d *SubSupplierHub) MovieNeedDlSub(videoFullPath string, forcedScanAndDownloadSub bool) bool {
 
 	var err error
-	if skipChineseMovie == true {
+	if d.settings.AdvancedSettings.ScanLogic.SkipChineseMovie == true {
 		var skip bool
 		// 跳过中文的电影,不是一定要跳过的
 		skip, err = movieHelper.SkipChineseMovie(videoFullPath, d.settings.AdvancedSettings.ProxySettings)
@@ -85,9 +85,9 @@ func (d *SubSupplierHub) MovieNeedDlSub(videoFullPath string, skipChineseMovie,
 }
 
 // SeriesNeedDlSub 连续剧是否符合要求需要下载字幕
-func (d *SubSupplierHub) SeriesNeedDlSub(seriesRootPath string, skipChineseMovie, forcedScanAndDownloadSub bool) (bool, *series.SeriesInfo, error) {
+func (d *SubSupplierHub) SeriesNeedDlSub(seriesRootPath string, forcedScanAndDownloadSub bool) (bool, *series.SeriesInfo, error) {
 
-	if skipChineseMovie == true {
+	if d.settings.AdvancedSettings.ScanLogic.SkipChineseSeries == true {
 		var skip bool
 		var err error
 		// 跳过中文的电影,不是一定要跳过的
@@ -109,6 +109,30 @@ func (d *SubSupplierHub) SeriesNeedDlSub(seriesRootPath string, skipChineseMovie
 	return true, seriesInfo, nil
 }
 
+// SeriesNeedDlSubFromEmby 连续剧是否符合要求需要下载字幕
+func (d *SubSupplierHub) SeriesNeedDlSubFromEmby(seriesRootPath string, seriesVideoList []emby.EmbyMixInfo, skipChineseMovie, forcedScanAndDownloadSub bool) (bool, *series.SeriesInfo, error) {
+
+	if skipChineseMovie == true {
+		var skip bool
+		var err error
+		// 跳过中文的电影,不是一定要跳过的
+		skip, _, err = seriesHelper.SkipChineseSeries(seriesRootPath, d.settings.AdvancedSettings.ProxySettings)
+		if err != nil {
+			d.log.Warnln("SkipChineseMovie", seriesRootPath, err)
+		}
+		if skip == true {
+			return false, nil, nil
+		}
+	}
+	// 读取本地的视频和字幕信息
+	seriesInfo, err := seriesHelper.ReadSeriesInfoFromEmby(seriesRootPath, seriesVideoList, forcedScanAndDownloadSub, d.settings.AdvancedSettings.ProxySettings)
+	if err != nil {
+		return false, nil, errors.Newf("ReadSeriesInfoFromDir %v %v", seriesRootPath, err)
+	}
+
+	return true, seriesInfo, nil
+}
+
 // DownloadSub4Movie 某一个电影字幕下载,下载完毕后,返回下载缓存每个字幕的位置,这里将只关心下载字幕,判断是否在时间范围内要不要下载不在这里判断,包括是否是中文视频的问题
 func (d *SubSupplierHub) DownloadSub4Movie(videoFullPath string, index int) ([]string, error) {
 
@@ -132,7 +156,7 @@ func (d *SubSupplierHub) DownloadSub4Movie(videoFullPath string, index int) ([]s
 	return outSubFileFullPathList, nil
 }
 
-// DownloadSub4Series 某一部连续剧的字幕下载,下载完毕后,返回下载缓存每个字幕的位置
+// DownloadSub4Series 某一部连续剧的字幕下载,下载完毕后,返回下载缓存每个字幕的位置(通用的下载逻辑,前面把常规(没有媒体服务器模式)和 Emby 这样的模式都转换到想到的下载接口上
 func (d *SubSupplierHub) DownloadSub4Series(seriesDirPath string, seriesInfo *series.SeriesInfo, index int) (map[string][]string, error) {
 
 	organizeSubFiles, err := d.dlSubFromSeriesInfo(seriesDirPath, index, seriesInfo)
@@ -142,21 +166,6 @@ func (d *SubSupplierHub) DownloadSub4Series(seriesDirPath string, seriesInfo *se
 	return organizeSubFiles, nil
 }
 
-// DownloadSub4SeriesFromEmby 通过 Emby 查询到的信息进行字幕下载,下载完毕后,返回下载缓存每个字幕的位置
-func (d *SubSupplierHub) DownloadSub4SeriesFromEmby(seriesDirPath string, seriesList []emby.EmbyMixInfo, index int) (map[string][]string, error) {
-
-	// 读取本地的视频和字幕信息
-	seriesInfo, err := seriesHelper.ReadSeriesInfoFromEmby(seriesDirPath, seriesList, d.settings.AdvancedSettings.ProxySettings)
-	if err != nil {
-		return nil, errors.Newf("ReadSeriesInfoFromDir %v %v", seriesDirPath, err)
-	}
-	organizeSubFiles, err := d.dlSubFromSeriesInfo(seriesDirPath, index, seriesInfo)
-	if err != nil {
-		return nil, err
-	}
-	return organizeSubFiles, nil
-}
-
 // CheckSubSiteStatus 检测多个字幕提供的网站是否是有效的,是否下载次数超限
 func (d *SubSupplierHub) CheckSubSiteStatus() backend.ReplyCheckStatus {
 

+ 104 - 43
internal/pkg/downloader/downloader.go

@@ -120,7 +120,7 @@ func (d *Downloader) ScanMovieAndSeriesWait2DownloadSub() (*ScanVideoResult, err
 
 	var err error
 	// -----------------------------------------------------
-	// 优先判断特殊的操作
+	// 强制下载和常规模式(没有媒体服务器)
 	if d.needForcedScanAndDownSub == true || d.embyHelper == nil {
 
 		normalScanResult := NormalScanVideoResult{}
@@ -178,15 +178,25 @@ func (d *Downloader) ScanMovieAndSeriesWait2DownloadSub() (*ScanVideoResult, err
 // FilterMovieAndSeriesNeedDownload 过滤出需要下载字幕的视频,比如是否跳过中文的剧集,是否超过3个月的下载时间,丢入队列中
 func (d *Downloader) FilterMovieAndSeriesNeedDownload(scanVideoResult *ScanVideoResult) error {
 
-	// ----------------------------------------
-	// 过滤,电影
-	// ----------------------------------------
-	// 放入队列
-	// ----------------------------------------
-	// Normal
-	for _, oneMovieFPath := range scanVideoResult.Normal.MovieFileFullPathList {
+	err := d.filterMovieAndSeriesNeedDownloadNormal(scanVideoResult.Normal)
+	if err != nil {
+		return err
+	}
 
-		if d.subSupplierHub.MovieNeedDlSub(oneMovieFPath, true, d.needForcedScanAndDownSub) == false {
+	err = d.filterMovieAndSeriesNeedDownloadEmby(scanVideoResult.Emby)
+	if err != nil {
+		return err
+	}
+
+	return nil
+}
+
+func (d *Downloader) filterMovieAndSeriesNeedDownloadNormal(normal *NormalScanVideoResult) error {
+	// ----------------------------------------
+	// Normal 过滤,电影
+	for _, oneMovieFPath := range normal.MovieFileFullPathList {
+		// 放入队列
+		if d.subSupplierHub.MovieNeedDlSub(oneMovieFPath, d.needForcedScanAndDownSub) == false {
 			continue
 		}
 		_, err := d.downloadQueue.RPush(*TTaskqueue.NewOneJob(
@@ -196,17 +206,14 @@ func (d *Downloader) FilterMovieAndSeriesNeedDownload(scanVideoResult *ScanVideo
 			return err
 		}
 	}
-	// Emby
-
-	// ----------------------------------------
-	// 过滤,连续剧
+	// Normal 过滤,连续剧
 	// seriesDirMap: dir <--> seriesList
-	scanVideoResult.Normal.SeriesDirMap.Each(func(seriesRootPathName interface{}, seriesNames interface{}) {
+	normal.SeriesDirMap.Each(func(seriesRootPathName interface{}, seriesNames interface{}) {
 
 		for _, oneSeriesRootDir := range seriesNames.([]string) {
 
 			// 因为可能回去 Web 获取 IMDB 信息,所以这里的错误不返回
-			bNeedDlSub, seriesInfo, err := d.subSupplierHub.SeriesNeedDlSub(oneSeriesRootDir, true, d.needForcedScanAndDownSub)
+			bNeedDlSub, seriesInfo, err := d.subSupplierHub.SeriesNeedDlSub(oneSeriesRootDir, d.needForcedScanAndDownSub)
 			if err != nil {
 				d.log.Errorln("FilterMovieAndSeriesNeedDownload.SeriesNeedDlSub", err)
 				continue
@@ -214,11 +221,76 @@ func (d *Downloader) FilterMovieAndSeriesNeedDownload(scanVideoResult *ScanVideo
 			if bNeedDlSub == false {
 				continue
 			}
-			//RootDirPath:   seriesRootPathName.(string),
-			//OneSeriesPath: oneSeriesRootDir,
+
+			for _, episodeInfo := range seriesInfo.NeedDlEpsKeyList {
+				// 放入队列
+				oneJob := TTaskqueue.NewOneJob(
+					common.Series, episodeInfo.FileFullPath, 5,
+				)
+				oneJob.Season = episodeInfo.Season
+				oneJob.Episode = episodeInfo.Episode
+
+				_, err = d.downloadQueue.RPush(*oneJob)
+				if err != nil {
+					d.log.Errorln("FilterMovieAndSeriesNeedDownload.Normal.Series.NewOneJob", err)
+					continue
+				}
+			}
 		}
 	})
 
+	return nil
+}
+
+func (d *Downloader) filterMovieAndSeriesNeedDownloadEmby(emby *EmbyScanVideoResult) error {
+	// ----------------------------------------
+	// Emby 过滤,电影
+	for _, oneMovieFPath := range emby.MovieSubNeedDlEmbyMixInfoList {
+		// 放入队列
+		if d.subSupplierHub.MovieNeedDlSub(oneMovieFPath.PhysicalVideoFileFullPath, d.needForcedScanAndDownSub) == false {
+			continue
+		}
+		_, err := d.downloadQueue.RPush(*TTaskqueue.NewOneJob(
+			common.Movie, oneMovieFPath.PhysicalVideoFileFullPath, 5,
+		))
+		if err != nil {
+			return err
+		}
+	}
+	// Emby 过滤,连续剧
+
+	for _, embyMixInfos := range emby.SeriesSubNeedDlEmbyMixInfoMap {
+
+		for _, mixInfo := range embyMixInfos {
+
+			// 因为可能回去 Web 获取 IMDB 信息,所以这里的错误不返回
+			bNeedDlSub, seriesInfo, err := d.subSupplierHub.SeriesNeedDlSub(mixInfo.PhysicalRootPath, d.needForcedScanAndDownSub)
+			if err != nil {
+				d.log.Errorln("FilterMovieAndSeriesNeedDownload.SeriesNeedDlSub", err)
+				continue
+			}
+			if bNeedDlSub == false {
+				continue
+			}
+
+			for _, episodeInfo := range seriesInfo.NeedDlEpsKeyList {
+				// 放入队列
+				oneJob := TTaskqueue.NewOneJob(
+					common.Series, episodeInfo.FileFullPath, 5,
+				)
+				oneJob.Season = episodeInfo.Season
+				oneJob.Episode = episodeInfo.Episode
+
+				_, err = d.downloadQueue.RPush(*oneJob)
+				if err != nil {
+					d.log.Errorln("FilterMovieAndSeriesNeedDownload.Normal.Series.NewOneJob", err)
+					continue
+				}
+			}
+		}
+	}
+
+	return nil
 }
 
 // GetUpdateVideoListFromEmby 这里首先会进行近期影片的获取,然后对这些影片进行刷新,然后在获取字幕列表,最终得到需要字幕获取的 video 列表
@@ -297,7 +369,7 @@ func (d *Downloader) RefreshEmbySubList() error {
 	return nil
 }
 
-// DownloadSub4Movie 这里对接 Emby 的时候比较方便,只要更新 d.movieFileFullPathList 就行了,不像连续剧那么麻烦
+// DownloadSub4Movie 需要从队列中拿去一个去下载
 func (d *Downloader) DownloadSub4Movie() error {
 	defer func() {
 		// 所有的电影字幕下载完成,抉择完成,需要清理缓存目录
@@ -363,6 +435,7 @@ func (d *Downloader) DownloadSub4Movie() error {
 	return nil
 }
 
+// DownloadSub4Series 需要从队列中拿去一个去下载
 func (d *Downloader) DownloadSub4Series() error {
 	var err error
 	defer func() {
@@ -508,34 +581,22 @@ func (d *Downloader) seriesDlFunc(ctx context.Context, inData interface{}) error
 	var organizeSubFiles map[string][]string
 	// 设置任务的状态
 	pkgcommon.SetSubScanJobStatusScanSeriesMain(taskData.Index+1, taskData.Count, downloadInputData.OneSeriesPath)
-
-	if d.needForcedScanAndDownSub == true || d.embyHelper == nil {
-		organizeSubFiles, err = d.subSupplierHub.DownloadSub4Series(downloadInputData.OneSeriesPath,
-			downloadInputData.SeriesInfo,
-			taskData.Index)
-		if err != nil {
-			d.log.Errorln("subSupplierHub.DownloadSub4Series", downloadInputData.OneSeriesPath, err)
-			return err
-		}
-	} else {
-		// 先进行 emby_helper api 的操作
-		organizeSubFiles, err = d.subSupplierHub.DownloadSub4SeriesFromEmby(
-			filepath.Join(downloadInputData.RootDirPath, downloadInputData.OneSeriesPath),
-			seriesSubNeedDlMap[downloadInputData.OneSeriesPath],
-			taskData.Index)
-		if err != nil {
-			d.log.Errorln("subSupplierHub.DownloadSub4Series", downloadInputData.OneSeriesPath, err)
-			return err
-		}
+	// 下载的接口是统一的
+	organizeSubFiles, err = d.subSupplierHub.DownloadSub4Series(downloadInputData.OneSeriesPath,
+		downloadInputData.SeriesInfo,
+		taskData.Index)
+	if err != nil {
+		d.log.Errorln("subSupplierHub.DownloadSub4Series", downloadInputData.OneSeriesPath, err)
+		return err
 	}
+	// 是否下载到字幕了
 	if organizeSubFiles == nil || len(organizeSubFiles) < 1 {
 		d.log.Infoln("no sub found", filepath.Base(downloadInputData.OneSeriesPath))
 		return nil
 	}
-
 	// 只针对需要下载字幕的视频进行字幕的选择保存
 	subVideoCount := 0
-	for epsKey, episodeInfo := range seriesInfo.NeedDlEpsKeyList {
+	for epsKey, episodeInfo := range downloadInputData.SeriesInfo.NeedDlEpsKeyList {
 
 		stage := make(chan interface{}, 1)
 		go func() {
@@ -556,14 +617,14 @@ func (d *Downloader) seriesDlFunc(ctx context.Context, inData interface{}) error
 		subVideoCount++
 	}
 	// 这里会拿到一份季度字幕的列表比如,Key 是 S1E0 S2E0 S3E0,value 是新的存储位置
-	fullSeasonSubDict := d.saveFullSeasonSub(seriesInfo, organizeSubFiles)
+	fullSeasonSubDict := d.saveFullSeasonSub(downloadInputData.SeriesInfo, organizeSubFiles)
 	// TODO 季度的字幕包,应该优先于零散的字幕吧,暂定就这样了,注意是全部都替换
 	// 需要与有下载需求的季交叉
-	for _, episodeInfo := range seriesInfo.EpList {
+	for _, episodeInfo := range downloadInputData.SeriesInfo.EpList {
 
 		stage := make(chan interface{}, 1)
 
-		_, ok := seriesInfo.NeedDlSeasonDict[episodeInfo.Season]
+		_, ok := downloadInputData.SeriesInfo.NeedDlSeasonDict[episodeInfo.Season]
 		if ok == false {
 			continue
 		}
@@ -586,7 +647,7 @@ func (d *Downloader) seriesDlFunc(ctx context.Context, inData interface{}) error
 	}
 	// 是否清理全季的缓存字幕文件夹
 	if d.settings.AdvancedSettings.SaveFullSeasonTmpSubtitles == false {
-		err = sub_helper.DeleteOneSeasonSubCacheFolder(seriesInfo.DirPath)
+		err = sub_helper.DeleteOneSeasonSubCacheFolder(downloadInputData.SeriesInfo.DirPath)
 		if err != nil {
 			return err
 		}

+ 2 - 0
internal/pkg/settings/advanced_settings.go

@@ -15,6 +15,7 @@ type AdvancedSettings struct {
 	FixTimeLine                bool               `json:"fix_time_line"`                  // 开启校正字幕时间轴,默认 false
 	Topic                      int                `json:"topic"`                          // 搜索结果的时候,返回 Topic N 以内的
 	SuppliersSettings          *SuppliersSettings `json:"suppliers_settings"`             // 每个字幕源的设置
+	ScanLogic                  *ScanLogic         `json:"scan_logic"`                     // 扫描的逻辑
 	TaskQueue                  *TaskQueue         `json:"task_queue"`                     // 任务队列的设置
 }
 
@@ -24,6 +25,7 @@ func NewAdvancedSettings() *AdvancedSettings {
 		CustomVideoExts:   make([]string, 0),
 		Topic:             common.DownloadSubsPerSite,
 		SuppliersSettings: NewSuppliersSettings(),
+		ScanLogic:         NewScanLogic(false, false),
 		TaskQueue:         NewTaskQueue(),
 	}
 }

+ 10 - 0
internal/pkg/settings/scan_logic.go

@@ -0,0 +1,10 @@
+package settings
+
+type ScanLogic struct {
+	SkipChineseMovie  bool `json:"skip_chinese_movie" default:"false"`  // 跳过中文的电影
+	SkipChineseSeries bool `json:"skip_chinese_series" default:"false"` // 跳过中文的连续剧
+}
+
+func NewScanLogic(skipChineseMovie bool, skipChineseSeries bool) *ScanLogic {
+	return &ScanLogic{SkipChineseMovie: skipChineseMovie, SkipChineseSeries: skipChineseSeries}
+}