Преглед на файлове

新增支持 zimuku 每一季第一集的 IMDB ID 搜索这一季的字幕的功能,同时修复 zimuku 搜索的 bug

Signed-off-by: allan716 <[email protected]>
allan716 преди 3 години
родител
ревизия
0afe714dcc

+ 6 - 2
internal/logic/series_helper/seriesHelper.go

@@ -1,6 +1,7 @@
 package series_helper
 
 import (
+	"errors"
 	"github.com/allanpk716/ChineseSubFinder/internal/ifaces"
 	"github.com/allanpk716/ChineseSubFinder/internal/logic/sub_parser/ass"
 	"github.com/allanpk716/ChineseSubFinder/internal/logic/sub_parser/srt"
@@ -393,9 +394,12 @@ func getEpsInfoAndSubDic(log *logrus.Logger,
 
 	episodeInfo, err := decode.GetImdbInfo4OneSeriesEpisode(videoFile)
 	if err != nil {
-		log.Errorln("model.GetImdbInfo4OneSeriesEpisode", videoFile, err)
-		return
+		if errors.Is(err, common.CanNotFindIMDBID) == false {
+			log.Errorln("model.GetImdbInfo4OneSeriesEpisode", videoFile, err)
+			return
+		}
 	}
+
 	epsKey := my_util.GetEpisodeKeyName(info.Season, info.Episode)
 	_, ok := EpisodeDict[epsKey]
 	if ok == false {

+ 65 - 12
internal/logic/sub_supplier/zimuku/zimuku.go

@@ -162,26 +162,79 @@ func (s *Supplier) GetSubListFromFile4Series(seriesInfo *series.SeriesInfo) ([]s
 	// 比如,其实可以搜索剧集名称,应该可以得到多个季的列表,然后分析再继续
 	// 现在粗暴点,直接一季搜索一次,跟电影的搜索一样,在首个影片就停止,然后继续往下
 	AllSeasonSubResult := SubResult{}
-	for value := range seriesInfo.SeasonDict {
-		// 第一级界面,找到影片的详情界面
-		keyword := seriesInfo.Name + " 第" + zh.Uint64(value).String() + "季"
-		s.log.Debugln(s.GetSupplierName(), "step 0", "0 times", "keyword:", keyword)
-		filmDetailPageUrl, err := s.step0(browser, keyword)
+	for value := range seriesInfo.NeedDlSeasonDict {
+
+		/*
+			经过网友的测试反馈,每一季 zimuku 是支持这一季的第一集的 IMDB ID 可以搜索到这一季的信息 #253
+			1. 那么在搜索某一集的时候,需要根据这一集去找这一季的第一集,然后读取它的 IMDB ID 信息,然后优先用于搜索这一季的信息
+			2. 如果是搜索季,就直接推算到达季文件夹的位置,搜索所有文件找到第一集,获取它的 IMDB ID
+			是不是有点绕···
+		*/
+		findSeasonFirstEpsIMDBId := ""
+		videoList, err := my_util.SearchMatchedVideoFile(s.log, seriesInfo.DirPath)
 		if err != nil {
-			s.log.Errorln(s.GetSupplierName(), "step 0", "0 times", "keyword:", keyword, err)
-			// 如果只是搜索不到,则继续换关键词
-			if err != common2.ZiMuKuSearchKeyWordStep0DetailPageUrlNotFound {
-				s.log.Errorln(s.GetSupplierName(), "ZiMuKuSearchKeyWordStep0DetailPageUrlNotFound", keyword, err)
+			s.log.Errorln("GetSubListFromFile4Series.SearchMatchedVideoFile, Season:", value, "Error:", err)
+			continue
+		}
+		for _, oneVideoFPath := range videoList {
+			oneVideoInfo, err := decode.GetVideoInfoFromFileName(filepath.Base(oneVideoFPath))
+			if err != nil {
+				s.log.Errorln("GetVideoInfoFromFileName", oneVideoInfo, err)
 				continue
 			}
-			keyword = seriesInfo.Name
+			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
+				break
+			}
+		}
+
+		filmDetailPageUrl := ""
+		if findSeasonFirstEpsIMDBId != "" {
+			// 第一级界面,找到影片的详情界面
+			// 使用上面得到的这一季第一集的 IMDB ID 进行搜索这一季的信息
+			keyword := findSeasonFirstEpsIMDBId
 			s.log.Debugln(s.GetSupplierName(), "step 0", "1 times", "keyword:", keyword)
 			filmDetailPageUrl, err = s.step0(browser, keyword)
 			if err != nil {
-				s.log.Errorln(s.GetSupplierName(), "1 times", "keyword:", keyword, err)
-				continue
+				s.log.Errorln(s.GetSupplierName(), "step 0", "0 times", "keyword:", keyword, err)
+				// 如果只是搜索不到,则继续换关键词
+				if err != common2.ZiMuKuSearchKeyWordStep0DetailPageUrlNotFound {
+					s.log.Errorln(s.GetSupplierName(), "ZiMuKuSearchKeyWordStep0DetailPageUrlNotFound", keyword, err)
+					continue
+				}
+			}
+		}
+		// 如果上面找到了,那么 filmDetailPageUrl 就应该不为空,如果没有找到就是空
+		if filmDetailPageUrl == "" {
+			// 第一级界面,找到影片的详情界面
+			keyword := seriesInfo.Name + " 第" + zh.Uint64(value).String() + "季"
+			s.log.Debugln(s.GetSupplierName(), "step 0", "0 times", "keyword:", keyword)
+			filmDetailPageUrl, err = s.step0(browser, keyword)
+			if err != nil {
+				s.log.Errorln(s.GetSupplierName(), "step 0", "0 times", "keyword:", keyword, err)
+				// 如果只是搜索不到,则继续换关键词
+				if err != common2.ZiMuKuSearchKeyWordStep0DetailPageUrlNotFound {
+					s.log.Errorln(s.GetSupplierName(), "ZiMuKuSearchKeyWordStep0DetailPageUrlNotFound", keyword, err)
+					continue
+				}
+
+				// 直接更换为这个剧目的 Name 的搜索,不带季度关键词信息
+				keyword = seriesInfo.Name
+				s.log.Debugln(s.GetSupplierName(), "step 0", "1 times", "keyword:", keyword)
+				filmDetailPageUrl, err = s.step0(browser, keyword)
+				if err != nil {
+					s.log.Errorln(s.GetSupplierName(), "1 times", "keyword:", keyword, err)
+					continue
+				}
 			}
 		}
+
 		// 第二级界面,有多少个字幕
 		s.log.Debugln(s.GetSupplierName(), "step 1", filmDetailPageUrl)
 		subResult, err := s.step1(browser, filmDetailPageUrl)

+ 6 - 6
internal/logic/sub_supplier/zimuku/zimuku_test.go

@@ -25,7 +25,7 @@ func TestSupplier_GetSubListFromKeyword(t *testing.T) {
 
 	//imdbId1 := "tt3228774"
 	videoName := "黑白魔女库伊拉"
-	s := NewSupplier(file_downloader.NewFileDownloader(cache_center.NewCacheCenter(settings.NewSettings(), log_helper.GetLogger4Tester())))
+	s := NewSupplier(file_downloader.NewFileDownloader(cache_center.NewCacheCenter("test", settings.NewSettings(), log_helper.GetLogger4Tester())))
 	outList, err := s.getSubListFromKeyword(browser, videoName)
 	if err != nil {
 		t.Error(err)
@@ -55,7 +55,7 @@ func TestSupplier_GetSubListFromFile(t *testing.T) {
 
 	rootDir := unit_test_helper.GetTestDataResourceRootPath([]string{"sub_spplier"}, 5, true)
 	movie1 := filepath.Join(rootDir, "zimuku", "movies", "The Devil All the Time (2020)", "The Devil All the Time (2020) WEBDL-1080p.mkv")
-	s := NewSupplier(file_downloader.NewFileDownloader(cache_center.NewCacheCenter(settings.NewSettings(), log_helper.GetLogger4Tester())))
+	s := NewSupplier(file_downloader.NewFileDownloader(cache_center.NewCacheCenter("test", settings.NewSettings(), log_helper.GetLogger4Tester())))
 	outList, err := s.getSubListFromMovie(browser, movie1)
 	if err != nil {
 		t.Error(err)
@@ -75,7 +75,7 @@ func TestSupplier_GetSubListFromFile4Series(t *testing.T) {
 
 	// 可以指定几集去调试
 	epsMap := make(map[int][]int, 0)
-	epsMap[4] = []int{5}
+	epsMap[4] = []int{1}
 	//epsMap[1] = []int{1, 2, 3}
 
 	rootDir := unit_test_helper.GetTestDataResourceRootPath([]string{"sub_spplier"}, 5, true)
@@ -91,7 +91,7 @@ func TestSupplier_GetSubListFromFile4Series(t *testing.T) {
 		t.Fatal(err)
 	}
 
-	s := NewSupplier(file_downloader.NewFileDownloader(cache_center.NewCacheCenter(settings.NewSettings(), log_helper.GetLogger4Tester())))
+	s := NewSupplier(file_downloader.NewFileDownloader(cache_center.NewCacheCenter("test", settings.NewSettings(), log_helper.GetLogger4Tester())))
 	outList, err := s.GetSubListFromFile4Series(seriesInfo)
 	if err != nil {
 		t.Fatal(err)
@@ -129,7 +129,7 @@ func TestSupplier_getSubListFromKeyword(t *testing.T) {
 	//imdbID := "tt15299712" // 云南虫谷
 	//imdbID := "tt3626476"  // Vacation Friends (2021)
 	imdbID := "tt11192306" // Superman.and.Lois
-	zimuku := NewSupplier(file_downloader.NewFileDownloader(cache_center.NewCacheCenter(settings.NewSettings(), log_helper.GetLogger4Tester())))
+	zimuku := NewSupplier(file_downloader.NewFileDownloader(cache_center.NewCacheCenter("test", settings.NewSettings(), log_helper.GetLogger4Tester())))
 	subInfos, err := zimuku.getSubListFromKeyword(browser, imdbID)
 	if err != nil {
 		t.Fatal(err)
@@ -154,7 +154,7 @@ func TestSupplier_step3(t *testing.T) {
 
 func TestSupplier_CheckAlive(t *testing.T) {
 
-	s := NewSupplier(file_downloader.NewFileDownloader(cache_center.NewCacheCenter(settings.NewSettings(), log_helper.GetLogger4Tester())))
+	s := NewSupplier(file_downloader.NewFileDownloader(cache_center.NewCacheCenter("test", settings.NewSettings(), log_helper.GetLogger4Tester())))
 	alive, _ := s.CheckAlive()
 	if alive == false {
 		t.Fatal("CheckAlive == false")

+ 12 - 24
internal/pkg/decode/decode.go

@@ -82,6 +82,10 @@ func getImdbAndYearNfo(nfoFilePath string, rootKey string) (types.VideoIMDBInfo,
 		imdbInfo.ReleaseDate = t.Text()
 		break
 	}
+	for _, t := range doc.FindElements("./" + rootKey + "/aired") {
+		imdbInfo.ReleaseDate = t.Text()
+		break
+	}
 	//---------------------------------------------------------------------
 	for _, t := range doc.FindElements("./" + rootKey + "/premiered") {
 		imdbInfo.ReleaseDate = t.Text()
@@ -140,7 +144,7 @@ func GetImdbInfo4Movie(movieFileFullPath string) (types.VideoIMDBInfo, error) {
 	if movieNameNfoFPath != "" {
 		imdbInfo, err = getImdbAndYearNfo(movieNameNfoFPath, "movie")
 		if err != nil {
-			return types.VideoIMDBInfo{}, err
+			return imdbInfo, err
 		}
 		return imdbInfo, nil
 	}
@@ -195,7 +199,7 @@ func GetImdbInfo4SeriesDir(seriesDir string) (types.VideoIMDBInfo, error) {
 	}
 	imdbInfo, err = getImdbAndYearNfo(nfoFilePath, "tvshow")
 	if err != nil {
-		return types.VideoIMDBInfo{}, err
+		return imdbInfo, err
 	}
 	return imdbInfo, nil
 }
@@ -232,13 +236,13 @@ func GetSeriesSeasonImdbInfoFromEpisode(oneEpFPath string) (types.VideoIMDBInfo,
 		var imdbInfo types.VideoIMDBInfo
 		imdbInfo, err = getImdbAndYearNfo(nfoFilePath, "tvshow")
 		if err != nil {
-			return types.VideoIMDBInfo{}, err
+			return imdbInfo, err
 		}
 		return imdbInfo, nil
 	}
 }
 
-// GetImdbInfo4OneSeriesEpisode 获取这一集的 IMDB info
+// GetImdbInfo4OneSeriesEpisode 获取这一集的 IMDB info,可能会因为没有获取到 IMDB ID 而返回 common.CanNotFindIMDBID 错误,但是 imdbInfo 其他信息是可用的
 func GetImdbInfo4OneSeriesEpisode(oneEpFPath string) (types.VideoIMDBInfo, error) {
 
 	// 从这一集的视频文件全路径去推算对应的 nfo 文件是否存在
@@ -248,29 +252,13 @@ func GetImdbInfo4OneSeriesEpisode(oneEpFPath string) (types.VideoIMDBInfo, error
 	EpNfoFileName = strings.ReplaceAll(EpNfoFileName, filepath.Ext(oneEpFPath), suffixNameNfo)
 	// 全路径
 	EpNfoFPath := filepath.Join(EPdir, EpNfoFileName)
-	//
-	imdbInfo := types.VideoIMDBInfo{}
-	doc := etree.NewDocument()
-	doc.ReadSettings.Permissive = true
-	// 这里会遇到一个梗,下面的关键词,可能是小写、大写、首字母大写
-	// 读取文件转换为全部的小写,然后在解析 xml ? etree 在转换为小写后,某些类型的文件的内容会崩溃···
-	// 所以这里很傻的方式解决
-	err := doc.ReadFromFile(EpNfoFPath)
+
+	imdbInfo, err := getImdbAndYearNfo(EpNfoFPath, "episodedetails")
 	if err != nil {
 		return imdbInfo, err
 	}
-	for _, t := range doc.FindElements("./episodedetails/aired") {
-		imdbInfo.ReleaseDate = t.Text()
-		break
-	}
-	for _, t := range doc.FindElements("./episodedetails/premiered") {
-		imdbInfo.ReleaseDate = t.Text()
-		break
-	}
-	if imdbInfo.ReleaseDate != "" {
-		return imdbInfo, nil
-	}
-	return imdbInfo, common2.CanNotFindEpAiredTime
+
+	return imdbInfo, nil
 }
 
 // GetVideoInfoFromFileName 从文件名推断文件信息