Browse Source

重构调整从视频文件获取 Season Eps 等信息的方式,由文件名改为优先从 nfo 文件

Signed-off-by: allan716 <[email protected]>
allan716 3 years ago
parent
commit
b5240c31a2

+ 7 - 5
internal/backend/controllers/v1/api.go

@@ -3,6 +3,9 @@ package v1
 import (
 	"errors"
 	"fmt"
+	"net/http"
+	"path/filepath"
+
 	"github.com/allanpk716/ChineseSubFinder/internal/dao"
 	"github.com/allanpk716/ChineseSubFinder/internal/models"
 	"github.com/allanpk716/ChineseSubFinder/internal/pkg/decode"
@@ -11,8 +14,6 @@ import (
 	"github.com/allanpk716/ChineseSubFinder/internal/types/common"
 	TTaskqueue "github.com/allanpk716/ChineseSubFinder/internal/types/task_queue"
 	"github.com/gin-gonic/gin"
-	"net/http"
-	"path/filepath"
 )
 
 // AddJobHandler 外部 API 接口添加任务的处理
@@ -50,8 +51,9 @@ func (cb *ControllerBase) AddJobHandler(c *gin.Context) {
 	)
 
 	if videoListAdd.VideoType == 1 {
+		// 连续剧
 		// 连续剧的时候需要额外提交信息
-		torrentInfo, err := decode.GetVideoInfoFromFileName(videoListAdd.PhysicalVideoFileFullPath)
+		epsVideoNfoInfo, err := decode.GetVideoNfoInfo4OneSeriesEpisode(videoListAdd.PhysicalVideoFileFullPath)
 		if err != nil {
 			return
 		}
@@ -60,8 +62,8 @@ func (cb *ControllerBase) AddJobHandler(c *gin.Context) {
 			err = errors.New(fmt.Sprintf("decode.GetSeriesDirRootFPath == Empty, %s", videoListAdd.PhysicalVideoFileFullPath))
 			return
 		}
-		nowJob.Season = torrentInfo.Season
-		nowJob.Episode = torrentInfo.Episode
+		nowJob.Season = epsVideoNfoInfo.Season
+		nowJob.Episode = epsVideoNfoInfo.Episode
 		nowJob.SeriesRootDirPath = seriesInfoDirPath
 	}
 

+ 3 - 3
internal/backend/controllers/v1/video_list.go

@@ -111,7 +111,7 @@ func (cb *ControllerBase) VideoListAddHandler(c *gin.Context) {
 
 	if videoType == common.Series {
 		// 如果是连续剧,需要额外的读取这一个剧集的信息
-		torrentInfo, err := decode.GetVideoInfoFromFileName(videoListAdd.PhysicalVideoFileFullPath)
+		epsVideoNfoInfo, err := decode.GetVideoNfoInfo4OneSeriesEpisode(videoListAdd.PhysicalVideoFileFullPath)
 		if err != nil {
 			return
 		}
@@ -120,8 +120,8 @@ func (cb *ControllerBase) VideoListAddHandler(c *gin.Context) {
 			err = errors.New(fmt.Sprintf("decode.GetSeriesDirRootFPath == Empty, %s", videoListAdd.PhysicalVideoFileFullPath))
 			return
 		}
-		oneJob.Season = torrentInfo.Season
-		oneJob.Episode = torrentInfo.Episode
+		oneJob.Season = epsVideoNfoInfo.Season
+		oneJob.Episode = epsVideoNfoInfo.Episode
 		oneJob.SeriesRootDirPath = seriesInfoDirPath
 	}
 

+ 1 - 1
internal/logic/emby_helper/embyhelper.go

@@ -480,7 +480,7 @@ func (em *EmbyHelper) autoFindMappingPathWithMixInfoByIMDBId(mixInfo *emby.EmbyM
 	}
 
 	// 获取 IMDB 信息
-	localIMDBInfo, err := imdb_helper.GetVideoIMDBInfoFromLocal(em.log, types.VideoIMDBInfo{ImdbId: mixInfo.IMDBId}, true)
+	localIMDBInfo, err := imdb_helper.GetVideoIMDBInfoFromLocal(em.log, types.VideoNfoInfo{ImdbId: mixInfo.IMDBId}, true)
 	if err != nil {
 
 		if errors.Is(err, common2.SkipCreateInDB) == true {

+ 10 - 14
internal/logic/movie_helper/moviehelper.go

@@ -1,6 +1,11 @@
 package movie_helper
 
 import (
+	"os"
+	"path/filepath"
+	"strings"
+	"time"
+
 	"github.com/allanpk716/ChineseSubFinder/internal/ifaces"
 	"github.com/allanpk716/ChineseSubFinder/internal/logic/sub_parser/ass"
 	"github.com/allanpk716/ChineseSubFinder/internal/logic/sub_parser/srt"
@@ -13,10 +18,6 @@ import (
 	"github.com/allanpk716/ChineseSubFinder/internal/types/supplier"
 	"github.com/jinzhu/now"
 	"github.com/sirupsen/logrus"
-	"os"
-	"path/filepath"
-	"strings"
-	"time"
 )
 
 // OneMovieDlSubInAllSite 一部电影在所有的网站下载相应的字幕
@@ -121,7 +122,7 @@ func MovieHasChineseSub(log *logrus.Logger, videoFilePath string) (bool, []strin
 // SkipChineseMovie 跳过中文的电影
 func SkipChineseMovie(log *logrus.Logger, videoFullPath string, _proxySettings ...*settings.ProxySettings) (bool, error) {
 
-	imdbInfo, err := decode.GetImdbInfo4Movie(videoFullPath)
+	imdbInfo, err := decode.GetVideoNfoInfo4Movie(videoFullPath)
 	if err != nil {
 		return false, err
 	}
@@ -145,12 +146,12 @@ func MovieNeedDlSub(log *logrus.Logger, videoFullPath string, ExpirationTime int
 	}
 	// 资源下载的时间后的多少天内都进行字幕的自动下载,替换原有的字幕
 	currentTime := time.Now()
-	mInfo, modifyTime, err := decode.GetVideoInfoFromFileFullPath(videoFullPath)
+	videoNfoInfo4Movie, modifyTime, err := decode.GetVideoInfoFromFileFullPath(videoFullPath, true)
 	if err != nil {
 		return false, err
 	}
 	// 如果这个视频发布的时间早于现在有两个年的间隔
-	if mInfo.Year > 0 && currentTime.Year()-2 > mInfo.Year {
+	if videoNfoInfo4Movie.GetYear() > 0 && currentTime.Year()-2 > videoNfoInfo4Movie.GetYear() {
 		if found == false {
 			// 需要下载的
 			return true, nil
@@ -160,16 +161,11 @@ func MovieNeedDlSub(log *logrus.Logger, videoFullPath string, ExpirationTime int
 			return false, nil
 		}
 	} else {
-		// 读取不到 IMDB 信息也能接受
-		videoIMDBInfo, err := decode.GetImdbInfo4Movie(videoFullPath)
-		if err != nil {
-			log.Errorln("MovieNeedDlSub.GetImdbInfo4Movie", err)
-		}
 		// 如果播出时间能够读取到,那么就以这个完后推算 3个月
 		// 如果读取不到 Aired Time 那么,下载后的 ModifyTime 3个月天内,都进行字幕的下载
 		var baseTime time.Time
-		if videoIMDBInfo.ReleaseDate != "" {
-			baseTime, err = now.Parse(videoIMDBInfo.ReleaseDate)
+		if videoNfoInfo4Movie.ReleaseDate != "" {
+			baseTime, err = now.Parse(videoNfoInfo4Movie.ReleaseDate)
 			if err != nil {
 				log.Errorln("Movie parse AiredTime", err)
 				baseTime = modifyTime

+ 7 - 7
internal/logic/scan_played_video_subinfo/scan_played_video_subinfo.go

@@ -362,12 +362,12 @@ func (s *ScanPlayedVideoSubInfo) dealOneVideo(index int, videoFPath, orgSubFPath
 
 	// 通过视频的绝对路径,从本地的视频文件对应的 nfo 获取到这个视频的 IMDB ID,
 	var err error
-	var imdbInfo4Video types.VideoIMDBInfo
+	var imdbInfo4Video types.VideoNfoInfo
 
 	if isMovie == true {
-		imdbInfo4Video, err = decode.GetImdbInfo4Movie(videoFPath)
+		imdbInfo4Video, err = decode.GetVideoNfoInfo4Movie(videoFPath)
 	} else {
-		imdbInfo4Video, err = decode.GetSeriesSeasonImdbInfoFromEpisode(videoFPath)
+		imdbInfo4Video, err = decode.GetSeriesSeasonVideoNfoInfoFromEpisode(videoFPath)
 	}
 	if err != nil {
 		// 如果找不到当前电影的 IMDB Info 本地文件,那么就跳过
@@ -527,13 +527,13 @@ func (s *ScanPlayedVideoSubInfo) dealOneVideo(index int, videoFPath, orgSubFPath
 
 	if isMovie == false {
 		// 连续剧的时候,如果可能应该获取是 第几季  第几集
-		torrentInfo, _, err := decode.GetVideoInfoFromFileFullPath(videoFPath)
+		epsVideoNfoInfo, err := decode.GetVideoNfoInfo4OneSeriesEpisode(videoFPath)
 		if err != nil {
-			s.log.Warningln("ScanPlayedVideoSubInfo.Scan", videoTypes, ".GetVideoInfoFromFileFullPath", imdbInfo4Video.Title, err)
+			s.log.Warningln("ScanPlayedVideoSubInfo.Scan", videoTypes, ".GetVideoNfoInfo4OneSeriesEpisode", imdbInfo4Video.Title, err)
 			return
 		}
-		oneVideoSubInfo.Season = torrentInfo.Season
-		oneVideoSubInfo.Episode = torrentInfo.Episode
+		oneVideoSubInfo.Season = epsVideoNfoInfo.Season
+		oneVideoSubInfo.Episode = epsVideoNfoInfo.Episode
 	}
 
 	s.log.Debugln(10)

+ 53 - 52
internal/logic/series_helper/seriesHelper.go

@@ -1,7 +1,10 @@
 package series_helper
 
 import (
-	"errors"
+	"path/filepath"
+	"strconv"
+	"time"
+
 	"github.com/allanpk716/ChineseSubFinder/internal/ifaces"
 	"github.com/allanpk716/ChineseSubFinder/internal/logic/sub_parser/ass"
 	"github.com/allanpk716/ChineseSubFinder/internal/logic/sub_parser/srt"
@@ -19,9 +22,6 @@ import (
 	"github.com/emirpasic/gods/maps/treemap"
 	"github.com/jinzhu/now"
 	"github.com/sirupsen/logrus"
-	"path/filepath"
-	"strconv"
-	"time"
 )
 
 func readSeriesInfo(log *logrus.Logger, seriesDir string, need2AnalyzeSub bool) (*series.SeriesInfo, map[string][]series.SubInfo, error) {
@@ -40,47 +40,56 @@ func readSeriesInfo(log *logrus.Logger, seriesDir string, need2AnalyzeSub bool)
 		return seriesInfo, SubDict, nil
 	}
 
-	// 搜索所有的字幕
 	subParserHub := sub_parser_hub.NewSubParserHub(log, ass.NewParser(log), srt.NewParser(log))
-	subFiles, err := sub_helper.SearchMatchedSubFileByDir(log, seriesDir)
+	// 先搜索这个目录下,所有符合条件的视频
+	matchedVideoFile, err := my_util.SearchMatchedVideoFile(log, seriesDir)
 	if err != nil {
 		return nil, nil, err
 	}
-	for _, subFile := range subFiles {
+	// 然后再从这个视频找到对用匹配的字幕
+	for _, oneVideoFPath := range matchedVideoFile {
 
-		info, _, err := decode.GetVideoInfoFromFileFullPath(subFile)
+		subFiles, err := sub_helper.SearchMatchedSubFileByOneVideo(log, oneVideoFPath)
 		if err != nil {
-			log.Errorln(err)
-			continue
+			return nil, nil, err
 		}
-		bFind, subParserFileInfo, err := subParserHub.DetermineFileTypeFromFile(subFile)
+		epsVideoNfoInfo, err := decode.GetVideoNfoInfo4OneSeriesEpisode(oneVideoFPath)
 		if err != nil {
-			log.Errorln("DetermineFileTypeFromFile", subFile, err)
-			continue
-		}
-		if bFind == false {
-			log.Warnln("DetermineFileTypeFromFile", subFile, "not support SubType")
-			continue
-		}
-		// 判断这个字幕是否包含中文
-		if subParserHub.IsSubHasChinese(subParserFileInfo) == false {
+			log.Errorln(err)
 			continue
 		}
-		epsKey := my_util.GetEpisodeKeyName(info.Season, info.Episode)
-		oneFileSubInfo := series.SubInfo{
-			Title:        info.Title,
-			Season:       info.Season,
-			Episode:      info.Episode,
-			Language:     subParserFileInfo.Lang,
-			Dir:          filepath.Dir(subFile),
-			FileFullPath: subFile,
-		}
-		_, ok := SubDict[epsKey]
-		if ok == false {
-			// 初始化
-			SubDict[epsKey] = make([]series.SubInfo, 0)
+
+		for _, subFile := range subFiles {
+
+			bFind, subParserFileInfo, err := subParserHub.DetermineFileTypeFromFile(subFile)
+			if err != nil {
+				log.Errorln("DetermineFileTypeFromFile", subFile, err)
+				continue
+			}
+			if bFind == false {
+				log.Warnln("DetermineFileTypeFromFile", subFile, "not support SubType")
+				continue
+			}
+			// 判断这个字幕是否包含中文
+			if subParserHub.IsSubHasChinese(subParserFileInfo) == false {
+				continue
+			}
+			epsKey := my_util.GetEpisodeKeyName(epsVideoNfoInfo.Season, epsVideoNfoInfo.Episode)
+			oneFileSubInfo := series.SubInfo{
+				Title:        epsVideoNfoInfo.Title,
+				Season:       epsVideoNfoInfo.Season,
+				Episode:      epsVideoNfoInfo.Episode,
+				Language:     subParserFileInfo.Lang,
+				Dir:          filepath.Dir(subFile),
+				FileFullPath: subFile,
+			}
+			_, ok := SubDict[epsKey]
+			if ok == false {
+				// 初始化
+				SubDict[epsKey] = make([]series.SubInfo, 0)
+			}
+			SubDict[epsKey] = append(SubDict[epsKey], oneFileSubInfo)
 		}
-		SubDict[epsKey] = append(SubDict[epsKey], oneFileSubInfo)
 	}
 
 	return seriesInfo, SubDict, nil
@@ -145,7 +154,7 @@ func ReadSeriesInfoFromEmby(log *logrus.Logger, seriesDir string, seriesVideoLis
 // SkipChineseSeries 跳过中文连续剧
 func SkipChineseSeries(log *logrus.Logger, seriesRootPath string, _proxySettings ...*settings.ProxySettings) (bool, *models.IMDBInfo, error) {
 
-	imdbInfo, err := decode.GetImdbInfo4SeriesDir(seriesRootPath)
+	imdbInfo, err := decode.GetVideoNfoInfo4SeriesDir(seriesRootPath)
 	if err != nil {
 		return false, nil, err
 	}
@@ -314,7 +323,7 @@ func whichSeasonEpsNeedDownloadSub(log *logrus.Logger, seriesInfo *series.Series
 func GetSeriesInfoFromDir(log *logrus.Logger, seriesDir string) (*series.SeriesInfo, error) {
 	seriesInfo := series.SeriesInfo{}
 	// 只考虑 IMDB 去查询,文件名目前发现可能会跟电影重复,导致很麻烦,本来也有前置要求要削刮器处理的
-	videoInfo, err := decode.GetImdbInfo4SeriesDir(seriesDir)
+	videoInfo, err := decode.GetVideoNfoInfo4SeriesDir(seriesDir)
 	if err != nil {
 		return nil, err
 	}
@@ -348,7 +357,7 @@ func GetSeriesInfoFromDir(log *logrus.Logger, seriesDir string) (*series.SeriesI
 		if err != nil {
 			// 不是必须的
 			seriesInfo.Year = 0
-			log.Warnln("ReadSeriesInfoFromDir.GetImdbInfo4SeriesDir.strconv.Atoi", seriesDir, err)
+			log.Warnln("ReadSeriesInfoFromDir.GetVideoNfoInfo4SeriesDir.strconv.Atoi", seriesDir, err)
 		} else {
 			seriesInfo.Year = iYear
 		}
@@ -367,7 +376,7 @@ func getEpsInfoAndSubDic(log *logrus.Logger,
 	SubDict map[string][]series.SubInfo,
 	epsMap ...map[int][]int) {
 	// 正常来说,一集只有一个格式的视频,也就是 S01E01 只有一个,如果有多个则会只保存第一个
-	info, modifyTime, err := decode.GetVideoInfoFromFileFullPath(videoFile)
+	episodeInfo, modifyTime, err := decode.GetVideoInfoFromFileFullPath(videoFile, false)
 	if err != nil {
 		log.Errorln("model.GetVideoInfoFromFileFullPath", videoFile, err)
 		return
@@ -375,13 +384,13 @@ func getEpsInfoAndSubDic(log *logrus.Logger,
 
 	if len(epsMap) > 0 {
 		// 如果这个视频不在需要下载的 Eps 列表中,那么就跳过后续的逻辑
-		epsList, ok := epsMap[0][info.Season]
+		epsList, ok := epsMap[0][episodeInfo.Season]
 		if ok == false {
 			return
 		}
 		found := false
 		for _, oneEpsID := range epsList {
-			if oneEpsID == info.Episode {
+			if oneEpsID == episodeInfo.Episode {
 				// 在需要下载的 Eps 列表中
 				found = true
 				break
@@ -392,22 +401,14 @@ func getEpsInfoAndSubDic(log *logrus.Logger,
 		}
 	}
 
-	episodeInfo, err := decode.GetImdbInfo4OneSeriesEpisode(videoFile)
-	if err != nil {
-		if errors.Is(err, common.CanNotFindIMDBID) == false {
-			log.Errorln("model.GetImdbInfo4OneSeriesEpisode", videoFile, err)
-			return
-		}
-	}
-
-	epsKey := my_util.GetEpisodeKeyName(info.Season, info.Episode)
+	epsKey := my_util.GetEpisodeKeyName(episodeInfo.Season, episodeInfo.Episode)
 	_, ok := EpisodeDict[epsKey]
 	if ok == false {
 		// 初始化
 		oneFileEpInfo := series.EpisodeInfo{
-			Title:        info.Title,
-			Season:       info.Season,
-			Episode:      info.Episode,
+			Title:        episodeInfo.Title,
+			Season:       episodeInfo.Season,
+			Episode:      episodeInfo.Episode,
 			Dir:          filepath.Dir(videoFile),
 			FileFullPath: videoFile,
 			ModifyTime:   modifyTime,

+ 4 - 3
internal/logic/series_helper/seriesHelper_test.go

@@ -1,15 +1,16 @@
 package series_helper
 
 import (
+	"testing"
+
 	"github.com/allanpk716/ChineseSubFinder/internal/pkg/log_helper"
 	"github.com/allanpk716/ChineseSubFinder/internal/pkg/unit_test_helper"
-	"testing"
 )
 
 func TestReadSeriesInfoFromDir(t *testing.T) {
 
-	series := unit_test_helper.GetTestDataResourceRootPath([]string{"series", "Loki"}, 4, false)
-	seriesInfo, err := ReadSeriesInfoFromDir(log_helper.GetLogger4Tester(), series, 90, false, false)
+	//series := unit_test_helper.GetTestDataResourceRootPath([]string{"series", "Loki"}, 4, false)
+	seriesInfo, err := ReadSeriesInfoFromDir(log_helper.GetLogger4Tester(), "X:\\连续剧\\黑袍纠察队 (2019)", 90, false, true)
 	if err != nil {
 		t.Fatal(err)
 	}

+ 1 - 1
internal/logic/sub_supplier/subhd/subhd.go

@@ -230,7 +230,7 @@ func (s *Supplier) getSubListFromFile4Movie(filePath string) ([]supplier.SubInfo
 	// 找到这个视频文件,尝试得到 IMDB ID
 	// 目前测试来看,加入 年 这个关键词去搜索,对 2020 年后的影片有利,因为网站有统一的详细页面了,而之前的,没有,会影响识别
 	// 所以,year >= 2020 年,则可以多加一个关键词(年)去搜索影片
-	imdbInfo, err := decode.GetImdbInfo4Movie(filePath)
+	imdbInfo, err := decode.GetVideoNfoInfo4Movie(filePath)
 	if err != nil {
 		// 允许的错误,跳过,继续进行文件名的搜索
 		s.log.Errorln("model.GetImdbInfo", err)

+ 8 - 19
internal/logic/sub_supplier/zimuku/zimuku.go

@@ -178,19 +178,14 @@ func (s *Supplier) GetSubListFromFile4Series(seriesInfo *series.SeriesInfo) ([]s
 			continue
 		}
 		for _, oneVideoFPath := range videoList {
-			oneVideoInfo, err := decode.GetVideoInfoFromFileName(filepath.Base(oneVideoFPath))
+			oneVideoInfo, err := decode.GetVideoNfoInfo4OneSeriesEpisode(oneVideoFPath)
 			if err != nil {
 				s.log.Errorln("GetVideoInfoFromFileName", oneVideoInfo, err)
 				continue
 			}
 			if oneVideoInfo.Season == value && oneVideoInfo.Episode == 1 {
 				// 这一季的第一集
-				episodeInfo, err := decode.GetImdbInfo4OneSeriesEpisode(oneVideoFPath)
-				if err != nil {
-					s.log.Errorln("GetImdbInfo4OneSeriesEpisode", oneVideoFPath, err)
-					break
-				}
-				findSeasonFirstEpsIMDBId = episodeInfo.ImdbId
+				findSeasonFirstEpsIMDBId = oneVideoInfo.ImdbId
 				break
 			}
 		}
@@ -278,24 +273,18 @@ func (s *Supplier) getSubListFromMovie(browser *rod.Browser, fileFPath string) (
 		优先通过 IMDB id 去查找字幕
 		如果找不到,再靠文件名提取影片名称去查找
 	*/
-	// 得到这个视频文件名中的信息
-	info, _, err := decode.GetVideoInfoFromFileFullPath(fileFPath)
-	if err != nil {
-		return nil, err
-	}
-	s.log.Debugln(s.GetSupplierName(), fileFPath, "GetVideoInfoFromFileFullPath -> Title:", info.Title)
 	// 找到这个视频文件,尝试得到 IMDB ID
 	// 目前测试来看,加入 年 这个关键词去搜索,对 2020 年后的影片有利,因为网站有统一的详细页面了,而之前的,没有,会影响识别
 	// 所以,year >= 2020 年,则可以多加一个关键词(年)去搜索影片
-	imdbInfo, err := decode.GetImdbInfo4Movie(fileFPath)
+	imdbInfo, err := decode.GetVideoNfoInfo4Movie(fileFPath)
 	if err != nil {
 		// 允许的错误,跳过,继续进行文件名的搜索
 		s.log.Errorln("model.GetImdbInfo", err)
 	} else {
-		s.log.Debugln(s.GetSupplierName(), fileFPath, "GetImdbInfo4Movie -> Title:", imdbInfo.Title)
-		s.log.Debugln(s.GetSupplierName(), fileFPath, "GetImdbInfo4Movie -> OriginalTitle:", imdbInfo.OriginalTitle)
-		s.log.Debugln(s.GetSupplierName(), fileFPath, "GetImdbInfo4Movie -> Year:", imdbInfo.Year)
-		s.log.Debugln(s.GetSupplierName(), fileFPath, "GetImdbInfo4Movie -> ImdbId:", imdbInfo.ImdbId)
+		s.log.Debugln(s.GetSupplierName(), fileFPath, "GetVideoNfoInfo4Movie -> Title:", imdbInfo.Title)
+		s.log.Debugln(s.GetSupplierName(), fileFPath, "GetVideoNfoInfo4Movie -> OriginalTitle:", imdbInfo.OriginalTitle)
+		s.log.Debugln(s.GetSupplierName(), fileFPath, "GetVideoNfoInfo4Movie -> Year:", imdbInfo.Year)
+		s.log.Debugln(s.GetSupplierName(), fileFPath, "GetVideoNfoInfo4Movie -> ImdbId:", imdbInfo.ImdbId)
 	}
 
 	var subInfoList []supplier.SubInfo
@@ -317,7 +306,7 @@ func (s *Supplier) getSubListFromMovie(browser *rod.Browser, fileFPath string) (
 		}
 	}
 	// 如果没有,那么就用文件名查找
-	searchKeyword := my_util.VideoNameSearchKeywordMaker(s.log, info.Title, imdbInfo.Year)
+	searchKeyword := my_util.VideoNameSearchKeywordMaker(s.log, imdbInfo.Title, imdbInfo.Year)
 
 	s.log.Debugln(s.GetSupplierName(), fileFPath, "VideoNameSearchKeywordMaker Keyword:", searchKeyword)
 

+ 200 - 65
internal/pkg/decode/decode.go

@@ -2,30 +2,56 @@ package decode
 
 import (
 	"errors"
-	"github.com/allanpk716/ChineseSubFinder/internal/types"
-	common2 "github.com/allanpk716/ChineseSubFinder/internal/types/common"
-	"github.com/beevik/etree"
-	PTN "github.com/middelink/go-parse-torrent-name"
 	"os"
 	"path/filepath"
 	"regexp"
 	"strconv"
 	"strings"
 	"time"
+
+	"github.com/allanpk716/ChineseSubFinder/internal/types"
+	common2 "github.com/allanpk716/ChineseSubFinder/internal/types/common"
+	"github.com/beevik/etree"
+	PTN "github.com/middelink/go-parse-torrent-name"
 )
 
-func getImdbAndYearMovieXml(movieFilePath string) (types.VideoIMDBInfo, error) {
+func getVideoNfoInfoFromMovieXml(movieFilePath string) (types.VideoNfoInfo, error) {
 
-	videoInfo := types.VideoIMDBInfo{}
+	videoInfo := types.VideoNfoInfo{}
 	doc := etree.NewDocument()
 	doc.ReadSettings.Permissive = true
 	if err := doc.ReadFromFile(movieFilePath); err != nil {
 		return videoInfo, err
 	}
+	// --------------------------------------------------
+	// IMDB
+	for _, t := range doc.FindElements("//imdb") {
+		videoInfo.ImdbId = t.Text()
+		break
+	}
 	for _, t := range doc.FindElements("//IMDB") {
 		videoInfo.ImdbId = t.Text()
 		break
 	}
+	for _, t := range doc.FindElements("//Imdb") {
+		videoInfo.ImdbId = t.Text()
+		break
+	}
+	// --------------------------------------------------
+	// TMDB
+	for _, t := range doc.FindElements("//tmdb") {
+		videoInfo.TmdbId = t.Text()
+		break
+	}
+	for _, t := range doc.FindElements("//TMDB") {
+		videoInfo.TmdbId = t.Text()
+		break
+	}
+	for _, t := range doc.FindElements("//Tmdb") {
+		videoInfo.TmdbId = t.Text()
+		break
+	}
+	// --------------------------------------------------
 	for _, t := range doc.FindElements("//ProductionYear") {
 		videoInfo.Year = t.Text()
 		break
@@ -36,8 +62,8 @@ func getImdbAndYearMovieXml(movieFilePath string) (types.VideoIMDBInfo, error) {
 	return videoInfo, common2.CanNotFindIMDBID
 }
 
-func getImdbAndYearNfo(nfoFilePath string, rootKey string) (types.VideoIMDBInfo, error) {
-	imdbInfo := types.VideoIMDBInfo{}
+func getVideoNfoInfo(nfoFilePath string, rootKey string) (types.VideoNfoInfo, error) {
+	imdbInfo := types.VideoNfoInfo{}
 	doc := etree.NewDocument()
 	doc.ReadSettings.Permissive = true
 	// 这里会遇到一个梗,下面的关键词,可能是小写、大写、首字母大写
@@ -52,6 +78,7 @@ func getImdbAndYearNfo(nfoFilePath string, rootKey string) (types.VideoIMDBInfo,
 		break
 	}
 	//---------------------------------------------------------------------
+	// IMDB
 	for _, t := range doc.FindElements("./" + rootKey + "/imdbid") {
 		imdbInfo.ImdbId = t.Text()
 		break
@@ -73,10 +100,113 @@ func getImdbAndYearNfo(nfoFilePath string, rootKey string) (types.VideoIMDBInfo,
 		break
 	}
 	//---------------------------------------------------------------------
+	// TMDB
+	for _, t := range doc.FindElements("./" + rootKey + "/tmdbid") {
+		imdbInfo.TmdbId = t.Text()
+		break
+	}
+	for _, t := range doc.FindElements("./" + rootKey + "/tmdb_id") {
+		imdbInfo.TmdbId = t.Text()
+		break
+	}
+	for _, t := range doc.FindElements("//uniqueid[@type='tmdb']") {
+		imdbInfo.TmdbId = t.Text()
+		break
+	}
+	for _, t := range doc.FindElements("//uniqueid[@type='Tmdb']") {
+		imdbInfo.TmdbId = t.Text()
+		break
+	}
+	for _, t := range doc.FindElements("//uniqueid[@type='TMDB']") {
+		imdbInfo.TmdbId = t.Text()
+		break
+	}
+	//---------------------------------------------------------------------
+	// TVDB
+	for _, t := range doc.FindElements("./" + rootKey + "/tvdbid") {
+		imdbInfo.TVdbId = t.Text()
+		break
+	}
+	for _, t := range doc.FindElements("./" + rootKey + "/tvdb_id") {
+		imdbInfo.TVdbId = t.Text()
+		break
+	}
+	for _, t := range doc.FindElements("//uniqueid[@type='tvdb']") {
+		imdbInfo.TVdbId = t.Text()
+		break
+	}
+	for _, t := range doc.FindElements("//uniqueid[@type='Tvdb']") {
+		imdbInfo.TVdbId = t.Text()
+		break
+	}
+	for _, t := range doc.FindElements("//uniqueid[@type='TVDB']") {
+		imdbInfo.TVdbId = t.Text()
+		break
+	}
+	//---------------------------------------------------------------------
+	//Season        int
+	//Episode       int
+	for _, t := range doc.FindElements("./" + rootKey + "/Season") {
+		season, err := strconv.Atoi(t.Text())
+		if err != nil {
+			continue
+		}
+		imdbInfo.Season = season
+		break
+	}
+	for _, t := range doc.FindElements("./" + rootKey + "/season") {
+		season, err := strconv.Atoi(t.Text())
+		if err != nil {
+			continue
+		}
+		imdbInfo.Season = season
+		break
+	}
+	for _, t := range doc.FindElements("./" + rootKey + "/SEASON") {
+		season, err := strconv.Atoi(t.Text())
+		if err != nil {
+			continue
+		}
+		imdbInfo.Season = season
+		break
+	}
+	for _, t := range doc.FindElements("./" + rootKey + "/Episode") {
+		episode, err := strconv.Atoi(t.Text())
+		if err != nil {
+			continue
+		}
+		imdbInfo.Episode = episode
+		break
+	}
+	for _, t := range doc.FindElements("./" + rootKey + "/episode") {
+		episode, err := strconv.Atoi(t.Text())
+		if err != nil {
+			continue
+		}
+		imdbInfo.Episode = episode
+		break
+	}
+	for _, t := range doc.FindElements("./" + rootKey + "/EPISODE") {
+		episode, err := strconv.Atoi(t.Text())
+		if err != nil {
+			continue
+		}
+		imdbInfo.Episode = episode
+		break
+	}
+	//---------------------------------------------------------------------
 	for _, t := range doc.FindElements("./" + rootKey + "/year") {
 		imdbInfo.Year = t.Text()
 		break
 	}
+	for _, t := range doc.FindElements("./" + rootKey + "/Year") {
+		imdbInfo.Year = t.Text()
+		break
+	}
+	for _, t := range doc.FindElements("./" + rootKey + "/YEAR") {
+		imdbInfo.Year = t.Text()
+		break
+	}
 	//---------------------------------------------------------------------
 	for _, t := range doc.FindElements("./" + rootKey + "/releasedate") {
 		imdbInfo.ReleaseDate = t.Text()
@@ -91,15 +221,15 @@ func getImdbAndYearNfo(nfoFilePath string, rootKey string) (types.VideoIMDBInfo,
 		imdbInfo.ReleaseDate = t.Text()
 		break
 	}
-	if imdbInfo.ImdbId != "" {
-		return imdbInfo, nil
-	}
-	return imdbInfo, common2.CanNotFindIMDBID
+	//if imdbInfo.ImdbId != "" {
+	//	return imdbInfo, nil
+	//}
+	return imdbInfo, nil
 }
 
-// GetImdbInfo4Movie 从电影视频文件获取 IMDB info,只能确定拿到 IMDB ID 是靠谱的
-func GetImdbInfo4Movie(movieFileFullPath string) (types.VideoIMDBInfo, error) {
-	imdbInfo := types.VideoIMDBInfo{}
+// GetVideoNfoInfo4Movie 从电影视频文件获取 IMDB info,只能确定拿到 IMDB ID 是靠谱的
+func GetVideoNfoInfo4Movie(movieFileFullPath string) (types.VideoNfoInfo, error) {
+	imdbInfo := types.VideoNfoInfo{}
 	// movie 当前的目录
 	dirPth := filepath.Dir(movieFileFullPath)
 	// 与 movie 文件名一致的 nfo 文件名称
@@ -142,24 +272,25 @@ func GetImdbInfo4Movie(movieFileFullPath string) (types.VideoIMDBInfo, error) {
 	}
 	// 优先分析 movieName.nfo 文件
 	if movieNameNfoFPath != "" {
-		imdbInfo, err = getImdbAndYearNfo(movieNameNfoFPath, "movie")
+		imdbInfo, err = getVideoNfoInfo(movieNameNfoFPath, "movie")
 		if err != nil {
 			return imdbInfo, err
 		}
 		return imdbInfo, nil
 	}
 
-	if movieXmlFPath != "" {
-		imdbInfo, err = getImdbAndYearMovieXml(movieXmlFPath)
+	if nfoFilePath != "" {
+		imdbInfo, err = getVideoNfoInfo(nfoFilePath, "movie")
 		if err != nil {
+			return imdbInfo, err
 		} else {
 			return imdbInfo, nil
 		}
 	}
-	if nfoFilePath != "" {
-		imdbInfo, err = getImdbAndYearNfo(nfoFilePath, "movie")
+
+	if movieXmlFPath != "" {
+		imdbInfo, err = getVideoNfoInfoFromMovieXml(movieXmlFPath)
 		if err != nil {
-			return imdbInfo, err
 		} else {
 			return imdbInfo, nil
 		}
@@ -168,9 +299,9 @@ func GetImdbInfo4Movie(movieFileFullPath string) (types.VideoIMDBInfo, error) {
 	return imdbInfo, common2.CanNotFindIMDBID
 }
 
-// GetImdbInfo4SeriesDir 从一个连续剧的根目录获取 IMDB info
-func GetImdbInfo4SeriesDir(seriesDir string) (types.VideoIMDBInfo, error) {
-	imdbInfo := types.VideoIMDBInfo{}
+// GetVideoNfoInfo4SeriesDir 从一个连续剧的根目录获取 IMDB info
+func GetVideoNfoInfo4SeriesDir(seriesDir string) (types.VideoNfoInfo, error) {
+	imdbInfo := types.VideoNfoInfo{}
 	dir, err := os.ReadDir(seriesDir)
 	if err != nil {
 		return imdbInfo, err
@@ -197,15 +328,15 @@ func GetImdbInfo4SeriesDir(seriesDir string) (types.VideoIMDBInfo, error) {
 	if nfoFilePath == "" {
 		return imdbInfo, common2.NoMetadataFile
 	}
-	imdbInfo, err = getImdbAndYearNfo(nfoFilePath, "tvshow")
+	imdbInfo, err = getVideoNfoInfo(nfoFilePath, "tvshow")
 	if err != nil {
 		return imdbInfo, err
 	}
 	return imdbInfo, nil
 }
 
-// GetSeriesSeasonImdbInfoFromEpisode 从一集获取这个 Series 的 IMDB info
-func GetSeriesSeasonImdbInfoFromEpisode(oneEpFPath string) (types.VideoIMDBInfo, error) {
+// GetSeriesSeasonVideoNfoInfoFromEpisode 从一集获取这个 Series 的 IMDB info
+func GetSeriesSeasonVideoNfoInfoFromEpisode(oneEpFPath string) (types.VideoNfoInfo, error) {
 
 	var err error
 	// 当前季的路径
@@ -230,20 +361,20 @@ func GetSeriesSeasonImdbInfoFromEpisode(oneEpFPath string) (types.VideoIMDBInfo,
 		seasonDir := filepath.Base(EPdir)
 		seriesDir := EPdir[:len(EPdir)-len(seasonDir)]
 
-		return GetImdbInfo4SeriesDir(seriesDir)
+		return GetVideoNfoInfo4SeriesDir(seriesDir)
 
 	} else {
-		var imdbInfo types.VideoIMDBInfo
-		imdbInfo, err = getImdbAndYearNfo(nfoFilePath, "tvshow")
+		var videoNfoInfo types.VideoNfoInfo
+		videoNfoInfo, err = getVideoNfoInfo(nfoFilePath, "tvshow")
 		if err != nil {
-			return imdbInfo, err
+			return videoNfoInfo, err
 		}
-		return imdbInfo, nil
+		return videoNfoInfo, nil
 	}
 }
 
-// GetImdbInfo4OneSeriesEpisode 获取这一集的 IMDB info,可能会因为没有获取到 IMDB ID 而返回 common.CanNotFindIMDBID 错误,但是 imdbInfo 其他信息是可用的
-func GetImdbInfo4OneSeriesEpisode(oneEpFPath string) (types.VideoIMDBInfo, error) {
+// GetVideoNfoInfo4OneSeriesEpisode 获取这一集的 IMDB info,可能会因为没有获取到 IMDB ID 而返回 common.CanNotFindIMDBID 错误,但是 imdbInfo 其他信息是可用的
+func GetVideoNfoInfo4OneSeriesEpisode(oneEpFPath string) (types.VideoNfoInfo, error) {
 
 	// 从这一集的视频文件全路径去推算对应的 nfo 文件是否存在
 	EPdir := filepath.Dir(oneEpFPath)
@@ -253,7 +384,7 @@ func GetImdbInfo4OneSeriesEpisode(oneEpFPath string) (types.VideoIMDBInfo, error
 	// 全路径
 	EpNfoFPath := filepath.Join(EPdir, EpNfoFileName)
 
-	imdbInfo, err := getImdbAndYearNfo(EpNfoFPath, "episodedetails")
+	imdbInfo, err := getVideoNfoInfo(EpNfoFPath, "episodedetails")
 	if err != nil {
 		return imdbInfo, err
 	}
@@ -261,24 +392,6 @@ func GetImdbInfo4OneSeriesEpisode(oneEpFPath string) (types.VideoIMDBInfo, error
 	return imdbInfo, nil
 }
 
-// GetVideoInfoFromFileName 从文件名推断文件信息
-func GetVideoInfoFromFileName(fileName string) (*PTN.TorrentInfo, error) {
-
-	parse, err := PTN.Parse(fileName)
-	if err != nil {
-		return nil, err
-	}
-	compile, err := regexp.Compile(regFixTitle2)
-	if err != nil {
-		return nil, err
-	}
-	match := compile.ReplaceAllString(parse.Title, "")
-	match = strings.TrimRight(match, "")
-	parse.Title = match
-
-	return parse, nil
-}
-
 // GetSeriesDirRootFPath 从一集的绝对路径推断这个连续剧的根目录绝对路径
 func GetSeriesDirRootFPath(oneEpFPath string) string {
 
@@ -291,21 +404,41 @@ func GetSeriesDirRootFPath(oneEpFPath string) string {
 	}
 }
 
-//GetVideoInfoFromFileFullPath 从全文件路径推断文件信息
-func GetVideoInfoFromFileFullPath(videoFileFullPath string) (*PTN.TorrentInfo, time.Time, error) {
+// GetVideoInfoFromFileName 从文件名推断文件信息,这个应该是次要方案,优先还是从 nfo 文件获取这些信息
+func GetVideoInfoFromFileName(fileName string) (*PTN.TorrentInfo, error) {
 
-	parse, err := PTN.Parse(filepath.Base(videoFileFullPath))
+	parse, err := PTN.Parse(fileName)
 	if err != nil {
-		return nil, time.Time{}, err
+		return nil, err
 	}
 	compile, err := regexp.Compile(regFixTitle2)
 	if err != nil {
-		return nil, time.Time{}, err
+		return nil, err
 	}
 	match := compile.ReplaceAllString(parse.Title, "")
 	match = strings.TrimRight(match, "")
 	parse.Title = match
 
+	return parse, nil
+}
+
+//GetVideoInfoFromFileFullPath 从全文件路径推断文件信息,这个应该是次要方案,优先还是从 nfo 文件获取这些信息
+func GetVideoInfoFromFileFullPath(videoFileFullPath string, isMovie bool) (types.VideoNfoInfo, time.Time, error) {
+
+	var err error
+	var videoNfoInfo types.VideoNfoInfo
+	if isMovie == true {
+		videoNfoInfo, err = GetVideoNfoInfo4Movie(videoFileFullPath)
+		if err != nil {
+			return types.VideoNfoInfo{}, time.Time{}, err
+		}
+
+	} else {
+		videoNfoInfo, err = GetVideoNfoInfo4OneSeriesEpisode(videoFileFullPath)
+		if err != nil {
+			return types.VideoNfoInfo{}, time.Time{}, err
+		}
+	}
 	/*
 		这里有个特殊情况,如果是某一种蓝光的文件结构,不是一个单一的视频文件
 		* 失控玩家 (2021)
@@ -321,36 +454,38 @@ func GetVideoInfoFromFileFullPath(videoFileFullPath string) (*PTN.TorrentInfo, t
 
 	*/
 	if IsFile(videoFileFullPath) == true {
+
 		// 常见的视频情况
 		fInfo, err := os.Stat(videoFileFullPath)
 		if err != nil {
-			return nil, time.Time{}, err
+			return types.VideoNfoInfo{}, time.Time{}, err
 		}
 
-		return parse, fInfo.ModTime(), nil
+		return videoNfoInfo, fInfo.ModTime(), nil
+
 	} else {
 		// 再次判断是否是蓝光结构
 		// 因为在前面扫描视频的时候,发现特殊的蓝光结构会伪造一个不存在的 xx.mp4 的视频文件过来,这里就需要额外检测一次
 		bok, idBDMVFPath, _ := IsFakeBDMVWorked(videoFileFullPath)
 		if bok == false {
-			return nil, time.Time{}, errors.New("GetVideoInfoFromFileFullPath.IsFakeBDMVWorked == false")
+			return types.VideoNfoInfo{}, time.Time{}, errors.New("GetVideoInfoFromFileFullPath.IsFakeBDMVWorked == false")
 		}
 
 		// 获取这个蓝光 ID BDMV 文件的时间
 		fInfo, err := os.Stat(idBDMVFPath)
 		if err != nil {
-			return nil, time.Time{}, err
+			return types.VideoNfoInfo{}, time.Time{}, err
 		}
-		return parse, fInfo.ModTime(), nil
+		return videoNfoInfo, fInfo.ModTime(), nil
 	}
 }
 
-// GetSeasonAndEpisodeFromSubFileName 从文件名推断 季 和 集 的信息 Season Episode
+// GetSeasonAndEpisodeFromSubFileName 从文件名推断 季 和 集 的信息 Season Episode,这个应该是次要方案,优先还是从 nfo 文件获取这些信息
 func GetSeasonAndEpisodeFromSubFileName(videoFileName string) (bool, int, int, error) {
 	upperName := strings.ToUpper(videoFileName)
 	// 先进行单个 Episode 的匹配
 	// Killing.Eve.S02E01.Do.You.Know.How
-	var re = regexp.MustCompile(`(?m)\.S(\d+)E(\d+)\.`)
+	var re = regexp.MustCompile(`(?m)\.S(\d+).*?E(\d+)\.`)
 	matched := re.FindAllStringSubmatch(upperName, -1)
 	if matched == nil || len(matched) < 1 {
 		// Killing.Eve.S02.Do.You.Know.How

+ 21 - 20
internal/pkg/decode/decode_test.go

@@ -1,11 +1,12 @@
 package decode
 
 import (
-	"github.com/allanpk716/ChineseSubFinder/internal/pkg/unit_test_helper"
-	"github.com/allanpk716/ChineseSubFinder/internal/types"
 	"path/filepath"
 	"reflect"
 	"testing"
+
+	"github.com/allanpk716/ChineseSubFinder/internal/pkg/unit_test_helper"
+	"github.com/allanpk716/ChineseSubFinder/internal/types"
 )
 
 func TestGetImdbAndYearMovieXml(t *testing.T) {
@@ -15,7 +16,7 @@ func TestGetImdbAndYearMovieXml(t *testing.T) {
 	wantid := "tt0993840"
 	wantyear := "2021"
 	dirPth := filepath.Join(rootDir, "movie.xml")
-	imdbInfo, err := getImdbAndYearMovieXml(dirPth)
+	imdbInfo, err := getVideoNfoInfoFromMovieXml(dirPth)
 	if err != nil {
 		t.Error(err)
 	}
@@ -35,7 +36,7 @@ func Test_getImdbAndYearNfo(t *testing.T) {
 	tests := []struct {
 		name    string
 		args    args
-		want    types.VideoIMDBInfo
+		want    types.VideoNfoInfo
 		wantErr bool
 	}{
 		{
@@ -43,7 +44,7 @@ func Test_getImdbAndYearNfo(t *testing.T) {
 				nfoFilePath: filepath.Join(unit_test_helper.GetTestDataResourceRootPath([]string{"movies", "Army of the Dead (2021)"}, 4, false), "Army of the Dead (2021) WEBDL-1080p.nfo"),
 				rootKey:     "movie",
 			},
-			want: types.VideoIMDBInfo{
+			want: types.VideoNfoInfo{
 				ImdbId:      "tt0993840",
 				Title:       "活死人军团",
 				Year:        "2021",
@@ -56,7 +57,7 @@ func Test_getImdbAndYearNfo(t *testing.T) {
 				nfoFilePath: filepath.Join(unit_test_helper.GetTestDataResourceRootPath([]string{"nfo_files", "tvshow"}, 4, false), "tvshow_00 (2).nfo"),
 				rootKey:     "tvshow",
 			},
-			want: types.VideoIMDBInfo{
+			want: types.VideoNfoInfo{
 				ImdbId:      "tt0346314",
 				Title:       "Ghost in the Shell: Stand Alone Complex",
 				ReleaseDate: "2002-10-01",
@@ -68,7 +69,7 @@ func Test_getImdbAndYearNfo(t *testing.T) {
 				nfoFilePath: filepath.Join(unit_test_helper.GetTestDataResourceRootPath([]string{"nfo_files", "tvshow"}, 4, false), "tvshow_00 (3).nfo"),
 				rootKey:     "tvshow",
 			},
-			want: types.VideoIMDBInfo{
+			want: types.VideoNfoInfo{
 				ImdbId:      "tt1856010",
 				Title:       "House of Cards (US)",
 				ReleaseDate: "2013-02-01",
@@ -78,13 +79,13 @@ func Test_getImdbAndYearNfo(t *testing.T) {
 	}
 	for _, tt := range tests {
 		t.Run(tt.name, func(t *testing.T) {
-			got, err := getImdbAndYearNfo(tt.args.nfoFilePath, tt.args.rootKey)
+			got, err := getVideoNfoInfo(tt.args.nfoFilePath, tt.args.rootKey)
 			if (err != nil) != tt.wantErr {
-				t.Errorf("getImdbAndYearNfo() error = %v, wantErr %v", err, tt.wantErr)
+				t.Errorf("getVideoNfoInfo() error = %v, wantErr %v", err, tt.wantErr)
 				return
 			}
 			if !reflect.DeepEqual(got, tt.want) {
-				t.Errorf("getImdbAndYearNfo() got = %v, want %v", got, tt.want)
+				t.Errorf("getVideoNfoInfo() got = %v, want %v", got, tt.want)
 			}
 		})
 	}
@@ -130,13 +131,13 @@ func TestGetImdbInfo4SeriesDir(t *testing.T) {
 	tests := []struct {
 		name    string
 		args    args
-		want    types.VideoIMDBInfo
+		want    types.VideoNfoInfo
 		wantErr bool
 	}{
 		{
 			name: "Loki",
 			args: args{seriesDir: unit_test_helper.GetTestDataResourceRootPath([]string{"series", "Loki"}, 4, false)},
-			want: types.VideoIMDBInfo{
+			want: types.VideoNfoInfo{
 				ImdbId:      "tt9140554",
 				Title:       "Loki",
 				ReleaseDate: "2021-06-09",
@@ -146,7 +147,7 @@ func TestGetImdbInfo4SeriesDir(t *testing.T) {
 		{
 			name: "辛普森一家",
 			args: args{seriesDir: unit_test_helper.GetTestDataResourceRootPath([]string{"series", "辛普森一家"}, 4, false)},
-			want: types.VideoIMDBInfo{
+			want: types.VideoNfoInfo{
 				ImdbId:      "tt0096697",
 				Title:       "The Simpsons",
 				ReleaseDate: "1989-12-17",
@@ -156,13 +157,13 @@ func TestGetImdbInfo4SeriesDir(t *testing.T) {
 	}
 	for _, tt := range tests {
 		t.Run(tt.name, func(t *testing.T) {
-			got, err := GetImdbInfo4SeriesDir(tt.args.seriesDir)
+			got, err := GetVideoNfoInfo4SeriesDir(tt.args.seriesDir)
 			if (err != nil) != tt.wantErr {
-				t.Errorf("GetImdbInfo4SeriesDir() error = %v, wantErr %v", err, tt.wantErr)
+				t.Errorf("GetVideoNfoInfo4SeriesDir() error = %v, wantErr %v", err, tt.wantErr)
 				return
 			}
 			if !reflect.DeepEqual(got, tt.want) {
-				t.Errorf("GetImdbInfo4SeriesDir() got = %v, want %v", got, tt.want)
+				t.Errorf("GetVideoNfoInfo4SeriesDir() got = %v, want %v", got, tt.want)
 			}
 		})
 	}
@@ -186,7 +187,7 @@ func TestGetImdbInfo4Movie(t *testing.T) {
 	//tests := []struct {
 	//	name    string
 	//	args    args
-	//	want    types.VideoIMDBInfo
+	//	want    types.VideoNfoInfo
 	//	wantErr bool
 	//}{
 	//	{name: "00", args: args{
@@ -195,13 +196,13 @@ func TestGetImdbInfo4Movie(t *testing.T) {
 	//}
 	//for _, tt := range tests {
 	//	t.Run(tt.name, func(t *testing.T) {
-	//		got, err := GetImdbInfo4Movie(tt.args.movieFileFullPath)
+	//		got, err := GetVideoNfoInfo4Movie(tt.args.movieFileFullPath)
 	//		if (err != nil) != tt.wantErr {
-	//			t.Errorf("GetImdbInfo4Movie() error = %v, wantErr %v", err, tt.wantErr)
+	//			t.Errorf("GetVideoNfoInfo4Movie() error = %v, wantErr %v", err, tt.wantErr)
 	//			return
 	//		}
 	//		if !reflect.DeepEqual(got, tt.want) {
-	//			t.Errorf("GetImdbInfo4Movie() got = %v, want %v", got, tt.want)
+	//			t.Errorf("GetVideoNfoInfo4Movie() got = %v, want %v", got, tt.want)
 	//		}
 	//	})
 	//}

+ 3 - 3
internal/pkg/downloader/downloader.go

@@ -390,7 +390,7 @@ func (d *Downloader) seriesDlFunc(ctx context.Context, job taskQueue2.OneJob, do
 
 	if job.VideoType == common.Series && job.SeriesRootDirPath == "" {
 		// 连续剧的时候需要额外提交信息
-		torrentInfo, err := decode.GetVideoInfoFromFileName(job.VideoFPath)
+		epsVideoNfoInfo, err := decode.GetVideoNfoInfo4OneSeriesEpisode(job.VideoFPath)
 		if err != nil {
 			return err
 		}
@@ -400,8 +400,8 @@ func (d *Downloader) seriesDlFunc(ctx context.Context, job taskQueue2.OneJob, do
 			return err
 		}
 
-		job.Season = torrentInfo.Season
-		job.Episode = torrentInfo.Episode
+		job.Season = epsVideoNfoInfo.Season
+		job.Episode = epsVideoNfoInfo.Episode
 		job.SeriesRootDirPath = seriesInfoDirPath
 	}
 

+ 6 - 6
internal/pkg/imdb_helper/imdb.go

@@ -18,7 +18,7 @@ import (
 )
 
 // GetVideoInfoFromIMDBWeb 从 IMDB 网站 ID 查询影片的信息
-func GetVideoInfoFromIMDBWeb(imdbInfo types.VideoIMDBInfo, _proxySettings ...*settings.ProxySettings) (*imdb.Title, error) {
+func GetVideoInfoFromIMDBWeb(imdbInfo types.VideoNfoInfo, _proxySettings ...*settings.ProxySettings) (*imdb.Title, error) {
 
 	client, err := my_util.NewHttpClient(_proxySettings...)
 	if err != nil {
@@ -45,7 +45,7 @@ func GetVideoInfoFromIMDBWeb(imdbInfo types.VideoIMDBInfo, _proxySettings ...*se
 }
 
 // GetVideoIMDBInfoFromLocal 从本地获取 IMDB 信息,注意,如果需要跳过,那么返回 Error == common.SkipCreateInDB
-func GetVideoIMDBInfoFromLocal(log *logrus.Logger, imdbInfo types.VideoIMDBInfo, skipCreate ...bool) (*models.IMDBInfo, error) {
+func GetVideoIMDBInfoFromLocal(log *logrus.Logger, imdbInfo types.VideoNfoInfo, skipCreate ...bool) (*models.IMDBInfo, error) {
 
 	/*
 		这里需要注意一个细节,之前理想情况下是从 Web 获取完整的 IMDB Info 回来,放入本地存储
@@ -94,7 +94,7 @@ func GetVideoIMDBInfoFromLocal(log *logrus.Logger, imdbInfo types.VideoIMDBInfo,
 }
 
 // IsChineseVideo 从 imdbID 去查询判断是否是中文视频
-func IsChineseVideo(log *logrus.Logger, imdbInfo types.VideoIMDBInfo, _proxySettings ...*settings.ProxySettings) (bool, *models.IMDBInfo, error) {
+func IsChineseVideo(log *logrus.Logger, imdbInfo types.VideoNfoInfo, _proxySettings ...*settings.ProxySettings) (bool, *models.IMDBInfo, error) {
 
 	const chName0 = "chinese"
 	const chName1 = "mandarin"
@@ -151,11 +151,11 @@ func IsChineseVideo(log *logrus.Logger, imdbInfo types.VideoIMDBInfo, _proxySett
 func GetIMDBInfo(log *logrus.Logger, videoFPath string, isMovie bool, _proxySettings ...*settings.ProxySettings) (*models.IMDBInfo, error) {
 
 	var err error
-	var imdbInfo4Video types.VideoIMDBInfo
+	var imdbInfo4Video types.VideoNfoInfo
 	if isMovie == true {
-		imdbInfo4Video, err = decode.GetImdbInfo4Movie(videoFPath)
+		imdbInfo4Video, err = decode.GetVideoNfoInfo4Movie(videoFPath)
 	} else {
-		imdbInfo4Video, err = decode.GetSeriesSeasonImdbInfoFromEpisode(videoFPath)
+		imdbInfo4Video, err = decode.GetSeriesSeasonVideoNfoInfoFromEpisode(videoFPath)
 	}
 	if err != nil {
 		// 如果找不到当前电影的 IMDB Info 本地文件,那么就跳过

+ 4 - 3
internal/pkg/imdb_helper/imdb_test.go

@@ -1,9 +1,10 @@
 package imdb_helper
 
 import (
+	"testing"
+
 	"github.com/allanpk716/ChineseSubFinder/internal/pkg/log_helper"
 	"github.com/allanpk716/ChineseSubFinder/internal/types"
-	"testing"
 )
 
 func TestGetVideoInfoFromIMDB(t *testing.T) {
@@ -14,7 +15,7 @@ func TestGetVideoInfoFromIMDB(t *testing.T) {
 	//imdbID := "tt6468322" 	// 纸钞屋
 	//imdbID := "tt15299712" // 云南虫谷
 	imdbID := "tt6856242" // The King`s Man
-	imdbInfo, err := GetVideoInfoFromIMDBWeb(types.VideoIMDBInfo{ImdbId: imdbID})
+	imdbInfo, err := GetVideoInfoFromIMDBWeb(types.VideoNfoInfo{ImdbId: imdbID})
 	if err != nil {
 		t.Fatal(err)
 	}
@@ -46,7 +47,7 @@ func TestIsChineseVideo(t *testing.T) {
 	}
 	for _, tt := range tests {
 		t.Run(tt.name, func(t *testing.T) {
-			got, _, err := IsChineseVideo(log_helper.GetLogger4Tester(), types.VideoIMDBInfo{ImdbId: tt.args.imdbID})
+			got, _, err := IsChineseVideo(log_helper.GetLogger4Tester(), types.VideoNfoInfo{ImdbId: tt.args.imdbID})
 			if (err != nil) != tt.wantErr {
 				t.Errorf("IsChineseVideo() error = %v, wantErr %v", err, tt.wantErr)
 				return

+ 2 - 2
internal/pkg/mix_media_info/mix_media_info.go

@@ -163,11 +163,11 @@ func KeyWordSelect(mediaInfo *models.MediaInfo, videoFPath string, isMovie bool,
 
 	if isMovie == false {
 		// 连续剧需要额外补充 S01E01 这样的信息
-		infoFromFileName, err := decode.GetVideoInfoFromFileName(videoFPath)
+		epsVideoNfoInfo, err := decode.GetVideoNfoInfo4OneSeriesEpisode(videoFPath)
 		if err != nil {
 			return "", err
 		}
-		keyWord += " " + my_util.GetEpisodeKeyName(infoFromFileName.Season, infoFromFileName.Episode, true)
+		keyWord += " " + my_util.GetEpisodeKeyName(epsVideoNfoInfo.Season, epsVideoNfoInfo.Episode, true)
 	}
 
 	return keyWord, nil

+ 8 - 8
internal/pkg/video_scan_and_refresh_helper/video_scan_and_refresh_helper.go

@@ -828,7 +828,7 @@ func (v *VideoScanAndRefreshHelper) scrabbleUpVideoListEmby(emby *EmbyScanVideoR
 				v.processLocker.Unlock()
 
 				videoFileName := filepath.Base(oneEpsMixInfo.PhysicalVideoFileFullPath)
-				infoFromFileName, err := decode.GetVideoInfoFromFileName(videoFileName)
+				epsVideoNfoInfo, err := decode.GetVideoNfoInfo4OneSeriesEpisode(oneEpsMixInfo.PhysicalVideoFileFullPath)
 				if err != nil {
 					v.log.Errorln("GetVideoInfoFromFileName", err)
 					break
@@ -839,8 +839,8 @@ func (v *VideoScanAndRefreshHelper) scrabbleUpVideoListEmby(emby *EmbyScanVideoR
 					Name:                     videoFileName,
 					VideoFPath:               oneEpsMixInfo.PhysicalVideoFileFullPath,
 					VideoUrl:                 epsFUrl,
-					Season:                   infoFromFileName.Season,
-					Episode:                  infoFromFileName.Episode,
+					Season:                   epsVideoNfoInfo.Season,
+					Episode:                  epsVideoNfoInfo.Episode,
 					MediaServerInsideVideoID: oneEpsMixInfo.VideoInfo.Id,
 					SubFPathList:             make([]string, 0),
 				}
@@ -974,10 +974,10 @@ func (v *VideoScanAndRefreshHelper) updateLocalVideoCacheInfo(scanVideoResult *S
 		taskData := inData.(*task_control.TaskData)
 		movieInputData := taskData.DataEx.(TaskInputData)
 		v.log.Infoln("updateLocalVideoCacheInfo", movieInputData.Index, movieInputData.InputPath)
-		videoImdbInfo, err := decode.GetImdbInfo4Movie(movieInputData.InputPath)
+		videoImdbInfo, err := decode.GetVideoNfoInfo4Movie(movieInputData.InputPath)
 		if err != nil {
 			// 允许的错误,跳过,继续进行文件名的搜索
-			v.log.Warningln("GetImdbInfo4Movie", movieInputData.Index, err)
+			v.log.Warningln("GetVideoNfoInfo4Movie", movieInputData.Index, err)
 			return err
 		}
 		// 获取 IMDB 信息
@@ -1028,9 +1028,9 @@ func (v *VideoScanAndRefreshHelper) updateLocalVideoCacheInfo(scanVideoResult *S
 		seriesInputData := taskData.DataEx.(TaskInputData)
 		v.log.Infoln("updateLocalVideoCacheInfo", seriesInputData.Index, seriesInputData.InputPath)
 
-		videoInfo, err := decode.GetImdbInfo4SeriesDir(seriesInputData.InputPath)
+		videoInfo, err := decode.GetVideoNfoInfo4SeriesDir(seriesInputData.InputPath)
 		if err != nil {
-			v.log.Warningln("GetImdbInfo4SeriesDir", seriesInputData.InputPath, err)
+			v.log.Warningln("GetVideoNfoInfo4SeriesDir", seriesInputData.InputPath, err)
 			return err
 		}
 
@@ -1247,7 +1247,7 @@ func (v *VideoScanAndRefreshHelper) filterMovieAndSeriesNeedDownloadEmby(emby *E
 				mixInfo.VideoInfo.Id,
 			)
 
-			info, _, err := decode.GetVideoInfoFromFileFullPath(mixInfo.PhysicalVideoFileFullPath)
+			info, err := decode.GetSeriesSeasonVideoNfoInfoFromEpisode(mixInfo.PhysicalVideoFileFullPath)
 			if err != nil {
 				v.log.Warningln("filterMovieAndSeriesNeedDownloadEmby.Series.GetVideoInfoFromFileFullPath", err)
 				continue

+ 5 - 4
internal/types/task_queue/task_queue.go

@@ -3,13 +3,14 @@ package task_queue
 import (
 	"crypto/sha256"
 	"fmt"
+	"path/filepath"
+	"time"
+
 	"github.com/allanpk716/ChineseSubFinder/internal/pkg/decode"
 	"github.com/allanpk716/ChineseSubFinder/internal/pkg/sub_file_hash"
 	"github.com/allanpk716/ChineseSubFinder/internal/types/common"
 	"github.com/allanpk716/ChineseSubFinder/internal/types/emby"
 	"github.com/araddon/dateparse"
-	"path/filepath"
-	"time"
 )
 
 type OneJob struct {
@@ -63,13 +64,13 @@ func NewOneJob(videoType common.VideoType, videoFPath string, taskPriority int,
 	// 需要获取这个视频的创建时间或者发布时间
 	if ob.VideoType == common.Movie {
 
-		imdbInfo4Movie, err := decode.GetImdbInfo4Movie(videoFPath)
+		imdbInfo4Movie, err := decode.GetVideoNfoInfo4Movie(videoFPath)
 		if err == nil {
 			createTime, _ := dateparse.ParseAny(imdbInfo4Movie.ReleaseDate)
 			ob.CreatedTime = emby.Time(createTime)
 		}
 	} else if ob.VideoType == common.Series {
-		imdbInfo4Eps, err := decode.GetImdbInfo4OneSeriesEpisode(videoFPath)
+		imdbInfo4Eps, err := decode.GetVideoNfoInfo4OneSeriesEpisode(videoFPath)
 		if err == nil {
 			createTime, _ := dateparse.ParseAny(imdbInfo4Eps.ReleaseDate)
 			ob.CreatedTime = emby.Time(createTime)

+ 0 - 11
internal/types/videoInfo.go

@@ -1,11 +0,0 @@
-package types
-
-// VideoIMDBInfo 从 movie.xml *.nfo 中解析出的视频信息
-type VideoIMDBInfo struct {
-	ImdbId        string
-	TVdbId        string
-	Year          string
-	Title         string
-	OriginalTitle string
-	ReleaseDate   string
-}

+ 25 - 0
internal/types/video_nfo_info.go

@@ -0,0 +1,25 @@
+package types
+
+import "strconv"
+
+// VideoNfoInfo 从 movie.xml *.nfo 中解析出的视频信息
+type VideoNfoInfo struct {
+	ImdbId        string
+	TmdbId        string
+	TVdbId        string
+	Season        int
+	Episode       int
+	Year          string
+	Title         string
+	OriginalTitle string
+	ReleaseDate   string
+}
+
+func (v *VideoNfoInfo) GetYear() int {
+
+	atoi, err := strconv.Atoi(v.Year)
+	if err != nil {
+		return 0
+	}
+	return atoi
+}