Browse Source

重构,完成剧集信息的本地读取

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

+ 30 - 0
common/seriesInfo.go

@@ -0,0 +1,30 @@
+package common
+/*
+	这里只需要分为三层结构,因为有 sonarr 和 TMM 整理过
+	所以命名很标注,使用 GetVideoInfoFromFileName 读取 SxxExx 问题不大
+*/
+type SeriesInfo struct {
+	ImdbId	   string
+	Name       string
+	Year	   int
+	EpList	   []EpisodeInfo
+	DirPath    string
+}
+
+type EpisodeInfo struct {
+	Title      string
+	Season     int
+	Episode    int
+	SubList	   []SubInfo
+	Dir		   string	// 这里需要记录字幕的位置,因为需要在同级目录匹配相应的字幕才行
+	FileFullPath string 	// 视频文件的全路径
+}
+
+type SubInfo struct {
+	Title      string
+	Season     int
+	Episode    int
+	Language   Language
+	Dir		   string	// 这里需要记录字幕的位置,因为需要在同级目录匹配相应的视频才行
+	FileFullPath string 	// 字幕文件的全路径
+}

+ 1 - 0
common/videoInfo.go

@@ -1,5 +1,6 @@
 package common
 
+// VideoInfo 从 movie.xml *.nfo 中解析出的视频信息
 type VideoInfo struct {
 	ImdbId string
 	TVdbId string

+ 2 - 65
downloader.go

@@ -11,7 +11,6 @@ import (
 	"github.com/allanpk716/ChineseSubFinder/sub_supplier/zimuku"
 	"github.com/go-rod/rod/lib/utils"
 	"github.com/sirupsen/logrus"
-	"io/ioutil"
 	"os"
 	"path"
 	"path/filepath"
@@ -22,8 +21,6 @@ type Downloader struct {
 	reqParam      common.ReqParam
 	log           *logrus.Logger
 	topic         int                        // 最多能够下载 Top 几的字幕,每一个网站
-	wantedExtList []string                   // 人工确认的需要监控的视频后缀名
-	defExtList    []string                   // 内置支持的视频后缀名列表
 	mk            *mark_system.MarkingSystem // MarkingSystem
 }
 
@@ -38,12 +35,6 @@ func NewDownloader(_reqParam ...common.ReqParam) *Downloader {
 			downloader.topic = downloader.reqParam.Topic
 		}
 	}
-	downloader.defExtList = make([]string, 0)
-	downloader.defExtList = append(downloader.defExtList, common.VideoExtMp4)
-	downloader.defExtList = append(downloader.defExtList, common.VideoExtMkv)
-	downloader.defExtList = append(downloader.defExtList, common.VideoExtRmvb)
-	downloader.defExtList = append(downloader.defExtList, common.VideoExtIso)
-
 	var sitesSequence = make([]string, 0)
 	// TODO 这里写固定了抉择字幕的顺序
 	sitesSequence = append(sitesSequence, common.SubSiteZiMuKu)
@@ -52,29 +43,9 @@ func NewDownloader(_reqParam ...common.ReqParam) *Downloader {
 	sitesSequence = append(sitesSequence, common.SubSiteShooter)
 	downloader.mk = mark_system.NewMarkingSystem(sitesSequence)
 
-	if len(_reqParam) > 0 {
-		// 如果用户设置了关注的视频后缀名列表,则用ta的
-		if len(downloader.reqParam.UserExtList) > 0 {
-			downloader.wantedExtList = downloader.reqParam.UserExtList
-		} else {
-			// 不然就是内置默认的
-			downloader.wantedExtList = downloader.defExtList
-		}
-	} else {
-		// 不然就是内置默认的
-		downloader.wantedExtList = downloader.defExtList
-	}
 	return &downloader
 }
 
-func (d Downloader) GetNowSupportExtList() []string {
-	return d.wantedExtList
-}
-
-func (d Downloader) GetDefSupportExtList() []string {
-	return d.defExtList
-}
-
 func (d Downloader) DownloadSub4Movie(dir string) error {
 	defer func() {
 		// 抉择完毕,需要清理缓存目录
@@ -83,7 +54,7 @@ func (d Downloader) DownloadSub4Movie(dir string) error {
 			d.log.Error(err)
 		}
 	}()
-	nowVideoList, err := d.searchMatchedVideoFile(dir)
+	nowVideoList, err := model.SearchMatchedVideoFile(dir)
 	if err != nil {
 		return err
 	}
@@ -172,43 +143,9 @@ func (d Downloader) writeSubFile2VideoPath(videoFileFullPath string, finalSubFil
 	return nil
 }
 
-// searchMatchedVideoFile 搜索符合后缀名的视频文件
-func (d Downloader) searchMatchedVideoFile(dir string) ([]string, error) {
 
-	var fileFullPathList = make([]string, 0)
-	pathSep := string(os.PathSeparator)
-	files, err := ioutil.ReadDir(dir)
-	if err != nil {
-		return nil, err
-	}
-	for _, curFile := range files {
-		fullPath := dir + pathSep + curFile.Name()
-		if curFile.IsDir() {
-			// 内层的错误就无视了
-			oneList, _ := d.searchMatchedVideoFile(fullPath)
-			if oneList != nil {
-				fileFullPathList = append(fileFullPathList, oneList...)
-			}
-		} else {
-			// 这里就是文件了
-			if d.isWantedVideoExtDef(curFile.Name()) == true {
-				fileFullPathList = append(fileFullPathList, fullPath)
-			}
-		}
-	}
-	return fileFullPathList, nil
-}
 
-// isWantedVideoExtDef 后缀名是否符合规则
-func (d Downloader) isWantedVideoExtDef(fileName string) bool {
-	fileName = strings.ToLower(filepath.Ext(fileName))
-	for _, s := range d.wantedExtList {
-		if s == fileName {
-			return true
-		}
-	}
-	return false
-}
+
 
 func (d Downloader) copySubFile2DesFolder(desFolder string, subFiles []string) error {
 

+ 0 - 21
downloader_test.go

@@ -2,30 +2,9 @@ package main
 
 import (
 	"github.com/allanpk716/ChineseSubFinder/common"
-	shooter2 "github.com/allanpk716/ChineseSubFinder/sub_supplier/shooter"
 	"testing"
 )
 
-func TestDownloader_searchFile(t *testing.T) {
-
-	//dirRoot := "X:\\动漫\\EVA"
-	dirRoot := "X:\\电影\\Spiral From the Book of Saw (2021)"
-
-	dl := NewDownloader()
-	files, err := dl.searchMatchedVideoFile(dirRoot)
-	if err != nil {
-		t.Fatal(err)
-	}
-	sp := shooter2.NewSupplier()
-	for i, file := range files {
-		println(i, file)
-		_, err := sp.ComputeFileHash(file)
-		if err != nil {
-			t.Fatal(err)
-		}
-	}
-}
-
 func TestDownloader_DownloadSub(t *testing.T) {
 	var err error
 	//dirRoot := "X:\\电影\\Spiral From the Book of Saw (2021)"

+ 3 - 2
model/decode_test.go

@@ -4,7 +4,7 @@ import (
 	"testing"
 )
 
-func Test_GetIMDB_ID(t *testing.T)  {
+func Test_GetIMDB_Info(t *testing.T)  {
 
 	serPath := "X:\\连续剧\\The Bad Batch"
 	imdbInfo, err := GetImdbInfo(serPath)
@@ -53,9 +53,10 @@ func Test_VideoInfo(t *testing.T) {
 	//subTitle := "機動戦士Zガンダム WEBDL-1080p.mkv"
 	//subTitle := "机动战士Z高达:星之继承者 (2005) 1080p TrueHD.mkv"
 	//subTitle := "X:\\连续剧\\The Bad Batch\\Season 1\\The Bad Batch - S01E01 - Aftermath WEBDL-1080p.mkv"
+	subTitle := "X:\\连续剧\\Money.Heist\\Season 1\\Money.Heist.S01E01.SPANISH.WEBRip.x264-ION10.zh-cn.ssa"
 	//subTitle := "Spiral.From.the.Book.of.Saw.2021.1080p.WEBRip.x264-RARBG.chi.srt"
 	//subTitle := "Spiral.From.the.Book.of.Saw.2021.1080p.WEBRip.x264-RARBG.eng.srt"
-	subTitle := "东城梅尔 第一季第一集【YYeTs字幕组 简繁英双语字幕】Mare.of.Easttown.S01E01.Miss.Lady.Hawk.Herself.720p/1080p.AMZN.WEB-DL.DDP5.1.H.264-TEPES"
+	//subTitle := "东城梅尔 第一季第一集【YYeTs字幕组 简繁英双语字幕】Mare.of.Easttown.S01E01.Miss.Lady.Hawk.Herself.720p/1080p.AMZN.WEB-DL.DDP5.1.H.264-TEPES"
 	info, err := GetVideoInfoFromFileName(subTitle)
 	if err != nil {
 		t.Error(err)

+ 2 - 0
model/imdb.go

@@ -8,9 +8,11 @@ import (
 // GetVideoInfoFromIMDB 从 IMDB ID 查询影片的信息
 func GetVideoInfoFromIMDB(imdbID string) (*imdb.Title, error) {
 	client := http.DefaultClient
+
 	t, err := imdb.NewTitle(client, imdbID)
 	if err != nil {
 		return nil, err
 	}
+
 	return t, nil
 }

+ 2 - 2
model/imdb_test.go

@@ -4,10 +4,10 @@ import "testing"
 
 func TestGetVideoInfoFromIMDB(t *testing.T) {
 	//imdbID := "tt12708542" // 星球大战:残次品
-	//imdbID := "tt7016936"	// 杀死伊芙
+	imdbID := "tt7016936"	// 杀死伊芙
 	//imdbID := "tt2990738" 	// 恐怖直播
 	//imdbID := "tt3032476" 	// 风骚律师
-	imdbID := "tt6468322" 	// 纸钞屋
+	//imdbID := "tt6468322" 	// 纸钞屋
 	imdbInfo, err := GetVideoInfoFromIMDB(imdbID)
 	if err != nil {
 		t.Fatal(err)

+ 0 - 36
model/tvdb.go

@@ -1,36 +0,0 @@
-package model
-
-import (
-	"github.com/allanpk716/ChineseSubFinder/common"
-	"github.com/go-resty/resty/v2"
-)
-
-type TVDB struct {
-	reqParam common.ReqParam
-	httpClient *resty.Client
-}
-
-// TODO 从 TVDB ID 查找对应的影片信息,得到中文名称,然后再去搜索字幕
-// 半泽直树 zho 半澤直樹 zhtw
-// 到了 list 列表搜索 zho ,第一个元素,然后找它的父级,获取 text 应该就能拿到中文名称了
-func NewTVDB(_reqParam ...common.ReqParam) *TVDB {
-	tv := TVDB{}
-	if len(_reqParam) > 0 {
-		tv.reqParam = _reqParam[0]
-	}
-	tv.httpClient = NewHttpClient(tv.reqParam)
-	return &tv
-}
-
-func (t TVDB) SearchAndGetChineseName() error {
-	resp, err := t.httpClient.R().
-		SetQueryParams(map[string]string{
-			"query": ,
-		}).
-		Get(common.TVDBSearchUrl)
-	if err != nil {
-		return err
-	}
-	println(resp)
-	return nil
-}

+ 0 - 23
model/tvdb_test.go

@@ -1,23 +0,0 @@
-package model
-
-import (
-	"testing"
-)
-
-func TestNewTVDB(t *testing.T) {
-
-	configViper, err := InitConfigure()
-	if err != nil {
-		t.Fatal(err)
-	}
-	c, err := ReadConfig(configViper)
-	if err != nil {
-		t.Fatal(err)
-	}
-
-	tv := NewTVDB(c.TVdbApiKey)
-	err = tv.login()
-	if err != nil {
-		t.Fatal(err)
-	}
-}

+ 86 - 1
model/util.go

@@ -9,6 +9,7 @@ import (
 	"net/http"
 	"os"
 	"path"
+	"path/filepath"
 	"regexp"
 	"strconv"
 	"strings"
@@ -84,7 +85,7 @@ func GetFileName(resp *http.Response) string {
 	return matched[1]
 }
 
-// AddBaseUrl 判断入的 url 是否需要拼接 baseUrl
+// AddBaseUrl 判断入的 url 是否需要拼接 baseUrl
 func AddBaseUrl(baseUrl, url string) string {
 	if strings.Contains(url, "://") {
 		return url
@@ -173,6 +174,7 @@ func IsDir(path string) bool {
 	return s.IsDir()
 }
 
+// VideoNameSearchKeywordMaker 拼接视频搜索的 title 和 年份
 func VideoNameSearchKeywordMaker(title string, year string) string {
 	iYear, err := strconv.Atoi(year)
 	if err != nil {
@@ -188,7 +190,90 @@ func VideoNameSearchKeywordMaker(title string, year string) string {
 	return searchKeyword
 }
 
+// SearchMatchedVideoFile 搜索符合后缀名的视频文件
+func SearchMatchedVideoFile(dir string) ([]string, error) {
+
+	var fileFullPathList = make([]string, 0)
+	pathSep := string(os.PathSeparator)
+	files, err := ioutil.ReadDir(dir)
+	if err != nil {
+		return nil, err
+	}
+	for _, curFile := range files {
+		fullPath := dir + pathSep + curFile.Name()
+		if curFile.IsDir() {
+			// 内层的错误就无视了
+			oneList, _ := SearchMatchedVideoFile(fullPath)
+			if oneList != nil {
+				fileFullPathList = append(fileFullPathList, oneList...)
+			}
+		} else {
+			// 这里就是文件了
+			if IsWantedVideoExtDef(curFile.Name()) == true {
+				fileFullPathList = append(fileFullPathList, fullPath)
+			}
+		}
+	}
+	return fileFullPathList, nil
+}
+
+// SearchMatchedSubFile 搜索符合后缀名的视频文件
+func SearchMatchedSubFile(dir string) ([]string, error) {
+	// 这里有个梗,会出现 __MACOSX 这类文件夹,那么里面会有一样的文件,需要用文件大小排除一下,至少大于 1 kb 吧
+	var fileFullPathList = make([]string, 0)
+	pathSep := string(os.PathSeparator)
+	files, err := ioutil.ReadDir(dir)
+	if err != nil {
+		return nil, err
+	}
+	for _, curFile := range files {
+		fullPath := dir + pathSep + curFile.Name()
+		if curFile.IsDir() {
+			// 内层的错误就无视了
+			oneList, _ := SearchMatchedSubFile(fullPath)
+			if oneList != nil {
+				fileFullPathList = append(fileFullPathList, oneList...)
+			}
+		} else {
+			// 这里就是文件了
+			if curFile.Size() < 1000 {
+				continue
+			}
+			if IsSubExtWanted(filepath.Ext(curFile.Name())) == true {
+				fileFullPathList = append(fileFullPathList, fullPath)
+			}
+		}
+	}
+	return fileFullPathList, nil
+}
+
+// IsWantedVideoExtDef 后缀名是否符合规则
+func IsWantedVideoExtDef(fileName string) bool {
+	// TODO 强制使用固定的视频后缀名匹配列表,后续有需求再考虑额实现外部可配置的列表
+
+	if len(wantedExtList) < 1 {
+		defExtList = append(defExtList, common.VideoExtMp4)
+		defExtList = append(defExtList, common.VideoExtMkv)
+		defExtList = append(defExtList, common.VideoExtRmvb)
+		defExtList = append(defExtList, common.VideoExtIso)
+
+		wantedExtList = append(defExtList, common.VideoExtMp4)
+		wantedExtList = append(defExtList, common.VideoExtMkv)
+		wantedExtList = append(defExtList, common.VideoExtRmvb)
+		wantedExtList = append(defExtList, common.VideoExtIso)
+	}
+	fileName = strings.ToLower(filepath.Ext(fileName))
+	for _, s := range wantedExtList {
+		if s == fileName {
+			return true
+		}
+	}
+	return false
+}
+
 var (
 	defDebugFolder = ""
 	defTmpFolder = ""
+	wantedExtList = make([]string, 0)                   // 人工确认的需要监控的视频后缀名
+	defExtList    = make([]string, 0)                  // 内置支持的视频后缀名列表
 )

+ 112 - 0
seriesHelper.go

@@ -0,0 +1,112 @@
+package main
+
+import (
+	"github.com/allanpk716/ChineseSubFinder/common"
+	"github.com/allanpk716/ChineseSubFinder/model"
+	"github.com/allanpk716/ChineseSubFinder/sub_parser/ass"
+	"github.com/allanpk716/ChineseSubFinder/sub_parser/srt"
+	"path/filepath"
+	"strconv"
+)
+
+// ReadSeriesInfoFromDir 读取剧集的信息
+func ReadSeriesInfoFromDir(seriesDir string) (*common.SeriesInfo, error) {
+	seriesInfo := common.SeriesInfo{}
+
+	subParserHub := model.NewSubParserHub(ass.NewParser(), srt.NewParser())
+	// 只考虑 IMDB 去查询,文件名目前发现可能会跟电影重复,导致很麻烦,本来也有前置要求要削刮器处理的
+	videoInfo, err := model.GetImdbInfo(seriesDir)
+	if err != nil {
+		return nil, err
+	}
+	// 使用 IMDB ID 得到通用的剧集名称
+	imdbInfo, err := model.GetVideoInfoFromIMDB(videoInfo.ImdbId)
+	if err != nil {
+		return nil, err
+	}
+	// 以 IMDB 的信息为准
+	seriesInfo.Name = imdbInfo.Name
+	seriesInfo.ImdbId = imdbInfo.ID
+	seriesInfo.Year = imdbInfo.Year
+	seriesInfo.DirPath = seriesDir
+	seriesInfo.EpList = make([]common.EpisodeInfo, 0)
+	// 搜索所有的视频
+	videoFiles, err := model.SearchMatchedVideoFile(seriesDir)
+	if err != nil {
+		return nil, err
+	}
+	// 搜索所有的字幕
+	subFiles, err := model.SearchMatchedSubFile(seriesDir)
+	if err != nil {
+		return nil, err
+	}
+	// 字幕字典 S01E01 - []SubInfo
+	SubDict := make(map[string][]common.SubInfo)
+	for _, subFile := range subFiles {
+
+		info, err := model.GetVideoInfoFromFileName(subFile)
+		if err != nil {
+			model.GetLogger().Errorln(err)
+			continue
+		}
+		subParserFileInfo, err := subParserHub.DetermineFileTypeFromFile(subFile)
+		if err != nil {
+			model.GetLogger().Errorln(err)
+			continue
+		}
+		epsKey := "S" + strconv.Itoa(info.Season) + "E" +strconv.Itoa(info.Episode)
+		oneFileSubInfo := common.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([]common.SubInfo, 0)
+		}
+		SubDict[epsKey] = append(SubDict[epsKey], oneFileSubInfo)
+	}
+	// 视频字典 S01E01 - EpisodeInfo
+	EpisodeDict := make(map[string]common.EpisodeInfo)
+	for _, videoFile := range videoFiles {
+		// 正常来说,一集只有一个格式的视频,也就是 S01E01 只有一个,如果有多个则会只保存第一个
+		info, err := model.GetVideoInfoFromFileName(videoFile)
+		if err != nil {
+			model.GetLogger().Errorln(err)
+			continue
+		}
+		epsKey := "S" + strconv.Itoa(info.Season) + "E" +strconv.Itoa(info.Episode)
+		_, ok := EpisodeDict[epsKey]
+		if ok == false {
+			// 初始化
+			oneFileEpInfo := common.EpisodeInfo{
+				Title: info.Title,
+				Season: info.Season,
+				Episode: info.Episode,
+				Dir: filepath.Dir(videoFile),
+				FileFullPath: videoFile,
+			}
+			// 需要匹配同级目录下的字幕
+			oneFileEpInfo.SubList = make([]common.SubInfo, 0)
+			for _, subInfo := range SubDict[epsKey] {
+				if subInfo.Dir == oneFileEpInfo.Dir {
+					oneFileEpInfo.SubList = append(oneFileEpInfo.SubList, subInfo)
+				}
+			}
+			EpisodeDict[epsKey] = oneFileEpInfo
+		} else {
+			// 存在则跳过
+			continue
+		}
+	}
+
+	for _, episodeInfo := range EpisodeDict {
+		seriesInfo.EpList = append(seriesInfo.EpList, episodeInfo)
+	}
+
+	return &seriesInfo, nil
+}

+ 22 - 0
seriesHelper_test.go

@@ -0,0 +1,22 @@
+package main
+
+import (
+	"testing"
+)
+
+func TestReadSeriesInfoFromDir(t *testing.T) {
+
+	series := "X:\\连续剧\\Money.Heist"
+	seriesInfo, err := ReadSeriesInfoFromDir(series)
+	if err != nil {
+		t.Fatal(err)
+	}
+
+	println(seriesInfo.Name, seriesInfo.Year, seriesInfo.ImdbId)
+	for i, info := range seriesInfo.EpList {
+		println("Video:", i, info.Season, info.Episode)
+		for j, subInfo := range info.SubList {
+			println("Sub:", j, subInfo.Title, subInfo.Season, subInfo.Episode, subInfo.Language.String())
+		}
+	}
+}

+ 2 - 30
sub_supplier/subSupplierHub.go

@@ -152,7 +152,7 @@ func (d SubSupplierHub) organizeDlSubFiles(subInfos []common.SupplierSubInfo) ([
 				continue
 			}
 			// 搜索这个目录下的所有符合字幕格式的文件
-			subFileFullPaths, err := d.searchMatchedSubFile(unzipTmpFolder)
+			subFileFullPaths, err := model.SearchMatchedSubFile(unzipTmpFolder)
 			if err != nil {
 				d.log.Errorln("searchMatchedSubFile", subInfo.FromWhere, subInfo.Name, subInfo.TopN, err)
 				continue
@@ -176,35 +176,7 @@ func (d SubSupplierHub) organizeDlSubFiles(subInfos []common.SupplierSubInfo) ([
 	return siteSubInfoDict, nil
 }
 
-// searchMatchedSubFile 搜索符合后缀名的视频文件
-func (d SubSupplierHub) searchMatchedSubFile(dir string) ([]string, error) {
-	// 这里有个梗,会出现 __MACOSX 这类文件夹,那么里面会有一样的文件,需要用文件大小排除一下,至少大于 1 kb 吧
-	var fileFullPathList = make([]string, 0)
-	pathSep := string(os.PathSeparator)
-	files, err := ioutil.ReadDir(dir)
-	if err != nil {
-		return nil, err
-	}
-	for _, curFile := range files {
-		fullPath := dir + pathSep + curFile.Name()
-		if curFile.IsDir() {
-			// 内层的错误就无视了
-			oneList, _ := d.searchMatchedSubFile(fullPath)
-			if oneList != nil {
-				fileFullPathList = append(fileFullPathList, oneList...)
-			}
-		} else {
-			// 这里就是文件了
-			if curFile.Size() < 1000 {
-				continue
-			}
-			if model.IsSubExtWanted(filepath.Ext(curFile.Name())) == true {
-				fileFullPathList = append(fileFullPathList, fullPath)
-			}
-		}
-	}
-	return fileFullPathList, nil
-}
+
 
 // 返回的名称包含,那个网站下载的,这个网站中排名第几,文件名
 func (d SubSupplierHub) getFrontNameAndOrgName(info common.SupplierSubInfo) string {

+ 7 - 90
sub_supplier/zimuku/zimuku.go

@@ -41,18 +41,13 @@ func (s Supplier) GetSubListFromFile4Movie(filePath string) ([]common.SupplierSu
 }
 
 func (s Supplier) GetSubListFromFile4Series(seriesPath string) ([]common.SupplierSubInfo, error) {
-	// 只考虑 IMDB 去查询,文件名目前发现可能会跟电影重复,导致很麻烦,本来也有前置要求要削刮器处理的
-	// TODO !GetImdbInfo 需要输出 title 以及 originaltitle
-	imdbId, _, err := model.GetImdbInfo(seriesPath)
-	if err != nil {
-		return nil, err
-	}
-	// 使用 IMDB 去
-	imdbInfo, err := model.GetVideoInfoFromIMDB(imdbId)
-	if err != nil {
-		return nil, err
-	}
-	subInfoList, err := s.GetSubListFromKeyword(imdbInfo.Name)
+
+	/*
+		去网站搜索的时候,有个比较由意思的逻辑,有些剧集,哪怕只有一季,sonarr 也会给它命名为 Season 1
+		但是在 zimuku 搜索的时候,如果你加上 XXX 第一季 就搜索不出来
+	*/
+
+	subInfoList, err := s.GetSubListFromKeyword(seriesPath)
 	if err != nil {
 		return nil, err
 	}
@@ -338,84 +333,6 @@ func (s Supplier) Step3(subDownloadPageUrl string) (string, []byte, error) {
 	return "", nil, common.ZiMuKuDownloadUrlStep3AllFailed
 }
 
-// Step1Discard 第一级界面,有多少个字幕,弃用,直接再搜索出来的结果界面匹配会遇到一个问题,就是 “还有8个字幕,点击查看” 类似此问题
-func (s Supplier) Step1Discard(keyword string) (SubResult, error) {
-	httpClient := model.NewHttpClient(s.reqParam)
-	// 第一级界面,有多少个字幕
-	resp, err := httpClient.R().
-		SetQueryParams(map[string]string{
-			"q": keyword,
-		}).
-		Get(common.SubZiMuKuSearchUrl)
-	if err != nil {
-		return SubResult{}, err
-	}
-	// 解析 html
-	doc, err := goquery.NewDocumentFromReader(strings.NewReader(resp.String()))
-	if err != nil {
-		return SubResult{}, err
-	}
-	// 具体解析这个页面
-	var subResult SubResult
-	subResult.SubInfos = SubInfos{}
-	// 这一级找到的是这个关键词出来的所有的影片的信息,可能有多个 Title,但是仅仅处理第一个
-	doc.Find("div[class=title]").EachWithBreak(func(i int, selectionTitleRoot *goquery.Selection) bool {
-
-		// 找到"又名",是第二个 P
-		selectionTitleRoot.Find("p").Each(func(i int, s *goquery.Selection) {
-			if i == 1 {
-				subResult.OtherName = s.Text()
-			}
-		})
-		// 找到字幕的列表,读取相应的信息
-		selectionTitleRoot.Find("div table tbody tr").Each(func(i int, sTr *goquery.Selection) {
-			aa := sTr.Find("a[href]")
-			subDetailUrl, ok := aa.Attr("href")
-			var subInfo SubInfo
-			if ok {
-				// 字幕的标题
-				subResult.Title = aa.Text()
-				// 字幕的详情界面
-				subInfo.DetailUrl = subDetailUrl
-				// 找到这个 tr 下面的第二个和第三个 td
-				sTr.Find("td").Each(func(i int, sTd *goquery.Selection) {
-					if i == 1 {
-						// 评分
-						vote, ok := sTd.Find("i").Attr("title")
-						if ok == false {
-							return
-						}
-						number, err := model.GetNumber2Float(vote)
-						if err != nil {
-							return
-						}
-						subInfo.Score = number
-					} else if i == 2{
-						// 下载量
-						number, err := model.GetNumber2int(sTd.Text())
-						if err != nil {
-							return
-						}
-						subInfo.DownloadTimes = number
-					}
-				})
-				// 计算优先级
-				subInfo.Priority = subInfo.Score * float32(subInfo.DownloadTimes)
-				// 加入列表
-				subResult.SubInfos = append(subResult.SubInfos, subInfo)
-			}
-
-		})
-		// EachWithBreak 使用这个,就能阻断继续遍历
-		return false
-	})
-	// 这里要判断,一级界面是否OK 了,不行就返回
-	if subResult.Title == "" || len(subResult.SubInfos) == 0 {
-		return SubResult{}, nil
-	}
-	return subResult, nil
-}
-
 type SubResult struct {
 	Title     string   // 字幕的标题
 	OtherName string   // 影片又名