Browse Source

提取获取 movie.xml 和 *.nfo 文件的信息为 imdbInfo

Signed-off-by: allan716 <[email protected]>
allan716 4 years ago
parent
commit
d0059520ca
6 changed files with 95 additions and 81 deletions
  1. 8 0
      common/imdbInfo.go
  2. 2 0
      go.sum
  3. 33 31
      model/decode.go
  4. 13 13
      model/decode_test.go
  5. 31 29
      sub_supplier/subhd/subhd.go
  6. 8 8
      sub_supplier/zimuku/zimuku.go

+ 8 - 0
common/imdbInfo.go

@@ -0,0 +1,8 @@
+package common
+
+type ImdbInfo struct {
+	ImdbId string
+	Year string
+	Title string
+	OriginalTitle string
+}

+ 2 - 0
go.sum

@@ -17,6 +17,7 @@ github.com/BurntSushi/xgb v0.0.0-20160522181843-27f122750802/go.mod h1:IVnqGOEym
 github.com/OneOfOne/xxhash v1.2.2/go.mod h1:HSdplMjZKSmBqAxg5vPj2TmRDmfkzw+cTzAElWljhcU=
 github.com/PuerkitoBio/goquery v1.6.1 h1:FgjbQZKl5HTmcn4sKBgvx8vv63nhyhIpv7lJpFGCWpk=
 github.com/PuerkitoBio/goquery v1.6.1/go.mod h1:GsLWisAFVj4WgDibEWF4pvYnkVQBpKBKeU+7zCJoLcc=
+github.com/StalkR/httpcache v1.0.0 h1:Px+QK86m7FEEvCfpfC+C0sNiUnRrLQyMVVJ6LKiXNvk=
 github.com/StalkR/httpcache v1.0.0/go.mod h1:yvbaYwH6w1USHPqgspMSwumbLwWE+B7jIZgfLYkTw1M=
 github.com/StalkR/imdb v1.0.7 h1:T9ra3IObhWoNB2I2CNT6EFe8sTQH56adKJdEQi1q0Ig=
 github.com/StalkR/imdb v1.0.7/go.mod h1:nxQmP4/nGtTVICl2+UmwhCnosVwVClmksdyptjE5Lj8=
@@ -74,6 +75,7 @@ github.com/gogo/protobuf v1.2.1/go.mod h1:hp+jE20tsWTFYpLwKvXlhS1hjn+gTNwPg2I6zV
 github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q=
 github.com/golang/groupcache v0.0.0-20190129154638-5b532d6fd5ef/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc=
 github.com/golang/groupcache v0.0.0-20190702054246-869f871628b6/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc=
+github.com/golang/groupcache v0.0.0-20200121045136-8c9f03a8e57e h1:1r7pUrabqp18hOBcwBwiTsbnFeTZHV9eER/QT5JVZxY=
 github.com/golang/groupcache v0.0.0-20200121045136-8c9f03a8e57e/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc=
 github.com/golang/mock v1.1.1/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A=
 github.com/golang/mock v1.2.0/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A=

+ 33 - 31
model/decode.go

@@ -13,64 +13,66 @@ import (
 	"strings"
 )
 
-func getImdbAndYearMovieXml(movieFilePath string) (string, string, error) {
+func getImdbAndYearMovieXml(movieFilePath string) (common.ImdbInfo, error) {
+
+	videoInfo := common.ImdbInfo{}
 	doc := etree.NewDocument()
 	if err := doc.ReadFromFile(movieFilePath); err != nil {
-		return "", "", err
+		return videoInfo, err
 	}
-	imdbId := ""
 	for _, t := range doc.FindElements("//IMDB") {
-		imdbId = t.Text()
+		videoInfo.ImdbId = t.Text()
 		break
 	}
-	year := ""
 	for _, t := range doc.FindElements("//ProductionYear") {
-		year = t.Text()
+		videoInfo.Year = t.Text()
 		break
 	}
-	if imdbId != "" {
-		return imdbId, year, nil
+	if videoInfo.ImdbId != "" {
+		return videoInfo, nil
 	}
-	return "", "", common.CanNotFindIMDBID
+	return videoInfo, common.CanNotFindIMDBID
 }
 
-func getImdbAndYearNfo(nfoFilePath string) (string, string, error) {
+func getImdbAndYearNfo(nfoFilePath string) (common.ImdbInfo, error) {
+
+	imdbInfo := common.ImdbInfo{}
 	doc := etree.NewDocument()
 	// 这里会遇到一个梗,下面的关键词,可能是小写、大写、首字母大写
 	// 读取文件转换为全部的小写,然后在解析 xml ? etree 在转换为小写后,某些类型的文件的内容会崩溃···
 	// 所以这里很傻的方式解决
 	err := doc.ReadFromFile(nfoFilePath)
 	if err != nil {
-		return "", "", err
+		return imdbInfo, err
 	}
-	imdbId := ""
 	for _, t := range doc.FindElements("//uniqueid[@type='imdb']") {
-		imdbId = t.Text()
+		imdbInfo.ImdbId = t.Text()
 		break
 	}
 	for _, t := range doc.FindElements("//uniqueid[@type='Imdb']") {
-		imdbId = t.Text()
+		imdbInfo.ImdbId = t.Text()
 		break
 	}
 	for _, t := range doc.FindElements("//uniqueid[@type='IMDB']") {
-		imdbId = t.Text()
+		imdbInfo.ImdbId = t.Text()
 		break
 	}
-	year := ""
 	for _, t := range doc.FindElements("./movie/year") {
-		year = t.Text()
+		imdbInfo.Year = t.Text()
 		break
 	}
-	if imdbId != "" {
-		return imdbId, year, nil
+	if imdbInfo.ImdbId != "" {
+		return imdbInfo, nil
 	}
-	return "",  "", common.CanNotFindIMDBID
+	return imdbInfo, common.CanNotFindIMDBID
 }
 
-func GetImdbIdAndYear(dirPth string) (string, string, error) {
+func GetImdbInfo(dirPth string) (common.ImdbInfo, error) {
+
+	imdbInfo := common.ImdbInfo{}
 	dir, err := ioutil.ReadDir(dirPth)
 	if err != nil {
-		return "", "", err
+		return imdbInfo, err
 	}
 	pathSep := string(os.PathSeparator)
 	// 优先找 movie.xml 这个是 raddarr 下载的电影会存下来的,可以在 Metadata 设置 Emby
@@ -95,32 +97,32 @@ func GetImdbIdAndYear(dirPth string) (string, string, error) {
 	}
 	// 根据找到的开始解析
 	if movieFilePath == "" && nfoFilePath == "" {
-		return "", "", common.NoMetadataFile
+		return imdbInfo, common.NoMetadataFile
 	}
 
 	if movieFilePath != "" {
-		outId, outYear, err := getImdbAndYearMovieXml(movieFilePath)
+		imdbInfo, err = getImdbAndYearMovieXml(movieFilePath)
 		if err != nil {
 			GetLogger().Errorln("getImdbAndYearMovieXml error, move on:", err)
 		} else {
-			return outId, outYear, nil
+			return imdbInfo, nil
 		}
 	}
 
 	if nfoFilePath != "" {
-		outId, outYear, err := getImdbAndYearNfo(nfoFilePath)
+		imdbInfo, err = getImdbAndYearNfo(nfoFilePath)
 		if err != nil {
-			return "","", err
+			return imdbInfo, err
 		} else {
-			return outId, outYear, nil
+			return imdbInfo, nil
 		}
 	}
 
-	return "", "", common.CanNotFindIMDBID
+	return imdbInfo, common.CanNotFindIMDBID
 }
 
-//GetVideoInfo 从文件名推断视频文件的信息
-func GetVideoInfo(videoFileName string) (*PTN.TorrentInfo, error) {
+//GetVideoInfoFromFileName 从文件名推断视频文件的信息
+func GetVideoInfoFromFileName(videoFileName string) (*PTN.TorrentInfo, error) {
 
 	parse, err := PTN.Parse(filepath.Base(videoFileName))
 	if err != nil {

+ 13 - 13
model/decode_test.go

@@ -7,26 +7,26 @@ import (
 func Test_GetIMDB_ID(t *testing.T)  {
 
 	serPath := "X:\\连续剧\\The Bad Batch"
-	id, year, err := GetImdbIdAndYear(serPath)
+	imdbInfo, err := GetImdbInfo(serPath)
 	if err != nil {
 		t.Fatal(err)
 	}
-	println(id, year)
+	println(imdbInfo.ImdbId, imdbInfo.Year)
 }
 
 func Test_get_IMDB_movie_xml(t *testing.T) {
     wantid := "tt0993840"
     wantyear:= "2021"
 	dirPth := "x:\\电影\\Army of the Dead (2021)\\movie.xml"
-	id, year, err := getImdbAndYearMovieXml(dirPth)
+	imdbInfo, err := getImdbAndYearMovieXml(dirPth)
 	if err != nil {
 		t.Error(err)
 	}
-	if id != wantid {
-		t.Errorf("Test_get_IMDB_movie_xml() got = %v, want %v", id, wantid)
+	if imdbInfo.ImdbId != wantid {
+		t.Errorf("Test_get_IMDB_movie_xml() got = %v, want %v", imdbInfo.ImdbId, wantid)
 	}
-	if year != wantyear {
-		t.Errorf("Test_get_IMDB_movie_xml() got = %v, want %v", year, wantyear)
+	if imdbInfo.Year != wantyear {
+		t.Errorf("Test_get_IMDB_movie_xml() got = %v, want %v", imdbInfo.Year, wantyear)
 	}
 }
 
@@ -34,15 +34,15 @@ func Test_get_IMDB_nfo(t *testing.T) {
 	wantid := "tt0993840"
 	wantyear:= "2021"
 	dirPth := "X:\\电影\\Army of the Dead (2021)\\Army of the Dead (2021) WEBDL-1080p.nfo"
-	id, year, err := getImdbAndYearNfo(dirPth)
+	imdbInfo, err := getImdbAndYearNfo(dirPth)
 	if err != nil {
 		t.Error(err)
 	}
-	if id != wantid {
-		t.Errorf("Test_get_IMDB_movie_xml() id = %v, wantid %v", id, wantid)
+	if imdbInfo.ImdbId != wantid {
+		t.Errorf("Test_get_IMDB_movie_xml() id = %v, wantid %v", imdbInfo.ImdbId, wantid)
 	}
-	if year != wantyear {
-		t.Errorf("Test_get_IMDB_movie_xml() year = %v, wantyear %v", id, wantyear)
+	if imdbInfo.Year != wantyear {
+		t.Errorf("Test_get_IMDB_movie_xml() year = %v, wantyear %v", imdbInfo.Year, wantyear)
 	}
 }
 
@@ -56,7 +56,7 @@ func Test_VideoInfo(t *testing.T) {
 	//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"
-	info, err := GetVideoInfo(subTitle)
+	info, err := GetVideoInfoFromFileName(subTitle)
 	if err != nil {
 		t.Error(err)
 	}

+ 31 - 29
sub_supplier/subhd/subhd.go

@@ -18,7 +18,6 @@ import (
 	"path"
 	"path/filepath"
 	"regexp"
-	"strconv"
 	"strings"
 	"time"
 )
@@ -68,7 +67,7 @@ func (s Supplier) GetSubListFromFile(filePath string) ([]common.SupplierSubInfo,
 		如果找不到,再靠文件名提取影片名称去查找
 	*/
 	// 得到这个视频文件名中的信息
-	info, err := model.GetVideoInfo(filePath)
+	info, err := model.GetVideoInfoFromFileName(filePath)
 	if err != nil {
 		return nil, err
 	}
@@ -76,16 +75,16 @@ func (s Supplier) GetSubListFromFile(filePath string) ([]common.SupplierSubInfo,
 	fileRootDirPath := filepath.Dir(filePath)
 	// 目前测试来看,加入 年 这个关键词去搜索,对 2020 年后的影片有利,因为网站有统一的详细页面了,而之前的,没有,会影响识别
 	// 所以,year >= 2020 年,则可以多加一个关键词(年)去搜索影片
-	imdbId, year, err := model.GetImdbIdAndYear(fileRootDirPath)
+	imdbInfo, err := model.GetImdbInfo(fileRootDirPath)
 	if err != nil {
 		// 允许的错误,跳过,继续进行文件名的搜索
-		s.log.Errorln("model.GetImdbIdAndYear", err)
+		s.log.Errorln("model.GetImdbInfo", err)
 	}
 	var subInfoList []common.SupplierSubInfo
 
-	if imdbId != "" {
+	if imdbInfo.ImdbId != "" {
 		// 先用 imdb id 找
-		subInfoList, err = s.GetSubListFromKeyword(imdbId)
+		subInfoList, err = s.GetSubListFromKeyword(imdbInfo.ImdbId)
 		if err != nil {
 			// 允许的错误,跳过,继续进行文件名的搜索
 			s.log.Errorln("GetSubListFromKeyword", "IMDBID can not found sub", filePath, err)
@@ -96,7 +95,7 @@ func (s Supplier) GetSubListFromFile(filePath string) ([]common.SupplierSubInfo,
 		}
 	}
 	// 如果没有,那么就用文件名查找
-	searchKeyword := model.VideoNameSearchKeywordMaker(info.Title, year)
+	searchKeyword := model.VideoNameSearchKeywordMaker(info.Title, imdbInfo.Year)
 	subInfoList, err = s.GetSubListFromKeyword(searchKeyword)
 	if err != nil {
 		return nil, err
@@ -284,9 +283,9 @@ func (s Supplier) downloadSubFile(browser *rod.Browser, page *rod.Page, hasWater
 		wait := browser.WaitDownload(tmpDir)
 		getDownloadFile:= func() ([]byte, string, error) {
 			info := wait()
-			path := filepath.Join(tmpDir, info.GUID)
-			defer func() { _ = os.Remove(path) }()
-			b, err := ioutil.ReadFile(path)
+			downloadPath := filepath.Join(tmpDir, info.GUID)
+			defer func() { _ = os.Remove(downloadPath) }()
+			b, err := ioutil.ReadFile(downloadPath)
 			if err != nil {
 				return nil, "", err
 			}
@@ -346,19 +345,19 @@ func (s Supplier) passWaterWall(page *rod.Page)  {
 	bgbox := shape.Box()
 	height, width := uint(math.Round(bgbox.Height)), uint(math.Round(bgbox.Width))
 	//裁剪圖像
-	shadowbg_img, _ := jpeg.Decode(bytes.NewReader(shadowbg))
-	shadowbg_img = resize.Resize(width, height, shadowbg_img, resize.Lanczos3)
-	fullbg_img, _ := jpeg.Decode(bytes.NewReader(fullbg))
-	fullbg_img = resize.Resize(width, height, fullbg_img, resize.Lanczos3)
+	shadowbgImg, _ := jpeg.Decode(bytes.NewReader(shadowbg))
+	shadowbgImg = resize.Resize(width, height, shadowbgImg, resize.Lanczos3)
+	fullbgImg, _ := jpeg.Decode(bytes.NewReader(fullbg))
+	fullbgImg = resize.Resize(width, height, fullbgImg, resize.Lanczos3)
 
 	//啓始left,排除干擾部份,所以右移10個像素
-	left := fullbg_img.Bounds().Min.X + 10
+	left := fullbgImg.Bounds().Min.X + 10
 	//啓始top, 排除干擾部份, 所以下移10個像素
-	top := fullbg_img.Bounds().Min.Y + 10
+	top := fullbgImg.Bounds().Min.Y + 10
 	//最大left, 排除干擾部份, 所以左移10個像素
-	maxleft := fullbg_img.Bounds().Max.X - 10
+	maxleft := fullbgImg.Bounds().Max.X - 10
 	//最大top, 排除干擾部份, 所以上移10個像素
-	maxtop := fullbg_img.Bounds().Max.Y - 10
+	maxtop := fullbgImg.Bounds().Max.Y - 10
 	//rgb比较阈值, 超出此阈值及代表找到缺口位置
 	threshold := 20
 	//缺口偏移, 拖動按鈕初始會偏移27.5
@@ -373,13 +372,13 @@ func (s Supplier) passWaterWall(page *rod.Page)  {
 search:
 	for i := left; i <= maxleft; i++ {
 		for j := top; j <= maxtop; j++ {
-			color_a_R, color_a_G, color_a_B, _ := fullbg_img.At(i, j).RGBA()
-			color_b_R, color_b_G, color_b_B, _ := shadowbg_img.At(i, j).RGBA()
-			color_a_R, color_a_G, color_a_B = color_a_R>>8, color_a_G>>8, color_a_B>>8
-			color_b_R, color_b_G, color_b_B = color_b_R>>8, color_b_G>>8, color_b_B>>8
-			if abs(int(color_a_R)-int(color_b_R)) > threshold ||
-				abs(int(color_a_G)-int(color_b_G)) > threshold ||
-				abs(int(color_a_B)-int(color_b_B)) > threshold {
+			colorAR, colorAG, colorAB, _ := fullbgImg.At(i, j).RGBA()
+			colorBR, colorBG, colorBB, _ := shadowbgImg.At(i, j).RGBA()
+			colorAR, colorAG, colorAB = colorAR>>8, colorAG>>8, colorAB>>8
+			colorBR, colorBG, colorBB = colorBR>>8, colorBG>>8, colorBB>>8
+			if abs(int(colorAR)-int(colorBR)) > threshold ||
+				abs(int(colorAG)-int(colorBG)) > threshold ||
+				abs(int(colorAB)-int(colorBB)) > threshold {
 				distance += float64(i)
 				s.log.Debug("對比完畢, 偏移量:", distance)
 				break search
@@ -387,15 +386,18 @@ search:
 		}
 	}
 	//獲取拖動按鈕形狀
-	dragbtnbox := iframe.MustElement("#tcaptcha_drag_thumb").MustShape().Box()
+	dragBtnBox := iframe.MustElement("#tcaptcha_drag_thumb").MustShape().Box()
 	//启用滑鼠功能
 	mouse := page.Mouse
 	//模擬滑鼠移動至拖動按鈕處, 右移3的原因: 拖動按鈕比滑塊圖大3個像素
-	mouse.MustMove(dragbtnbox.X+3, dragbtnbox.Y+(dragbtnbox.Height/2))
+	mouse.MustMove(dragBtnBox.X+3, dragBtnBox.Y+(dragBtnBox.Height/2))
 	//按下滑鼠左鍵
 	mouse.MustDown("left")
 	//開始拖動
-	mouse.Move(dragbtnbox.X+distance, dragbtnbox.Y+(dragbtnbox.Height/2), 20)
+	err = mouse.Move(dragBtnBox.X+distance, dragBtnBox.Y+(dragBtnBox.Height/2), 20)
+	if err != nil {
+		s.log.Errorln("mouse.Move", err)
+	}
 	//鬆開滑鼠左鍵, 拖动完毕
 	mouse.MustUp("left")
 
@@ -405,7 +407,7 @@ search:
 		if err == nil {
 			page.MustScreenshot(path.Join(nowProcessRoot, "result.png"))
 		} else {
-			s.log.Error(err)
+			s.log.Errorln("model.GetDebugFolder", err)
 		}
 	}
 }

+ 8 - 8
sub_supplier/zimuku/zimuku.go

@@ -42,8 +42,8 @@ func (s Supplier) GetSubListFromFile4Movie(filePath string) ([]common.SupplierSu
 
 func (s Supplier) GetSubListFromFile4Series(seriesPath string) ([]common.SupplierSubInfo, error) {
 	// 只考虑 IMDB 去查询,文件名目前发现可能会跟电影重复,导致很麻烦,本来也有前置要求要削刮器处理的
-	// TODO !GetImdbIdAndYear 需要输出 title 以及 originaltitle
-	imdbId, _, err := model.GetImdbIdAndYear(seriesPath)
+	// TODO !GetImdbInfo 需要输出 title 以及 originaltitle
+	imdbId, _, err := model.GetImdbInfo(seriesPath)
 	if err != nil {
 		return nil, err
 	}
@@ -73,7 +73,7 @@ func (s Supplier) GetSubListFromFile(filePath string) ([]common.SupplierSubInfo,
 		如果找不到,再靠文件名提取影片名称去查找
 	*/
 	// 得到这个视频文件名中的信息
-	info, err := model.GetVideoInfo(filePath)
+	info, err := model.GetVideoInfoFromFileName(filePath)
 	if err != nil {
 		return nil, err
 	}
@@ -81,16 +81,16 @@ func (s Supplier) GetSubListFromFile(filePath string) ([]common.SupplierSubInfo,
 	fileRootDirPath := filepath.Dir(filePath)
 	// 目前测试来看,加入 年 这个关键词去搜索,对 2020 年后的影片有利,因为网站有统一的详细页面了,而之前的,没有,会影响识别
 	// 所以,year >= 2020 年,则可以多加一个关键词(年)去搜索影片
-	imdbId, year, err := model.GetImdbIdAndYear(fileRootDirPath)
+	imdbInfo, err := model.GetImdbInfo(fileRootDirPath)
 	if err != nil {
 		// 允许的错误,跳过,继续进行文件名的搜索
-		s.log.Errorln("model.GetImdbIdAndYear", err)
+		s.log.Errorln("model.GetImdbInfo", err)
 	}
 	var subInfoList []common.SupplierSubInfo
 
-	if imdbId != "" {
+	if imdbInfo.ImdbId != "" {
 		// 先用 imdb id 找
-		subInfoList, err = s.GetSubListFromKeyword(imdbId)
+		subInfoList, err = s.GetSubListFromKeyword(imdbInfo.ImdbId)
 		if err != nil {
 			// 允许的错误,跳过,继续进行文件名的搜索
 			s.log.Errorln("GetSubListFromKeyword", "IMDBID can not found sub", filePath, err)
@@ -102,7 +102,7 @@ func (s Supplier) GetSubListFromFile(filePath string) ([]common.SupplierSubInfo,
 	}
 
 	// 如果没有,那么就用文件名查找
-	searchKeyword := model.VideoNameSearchKeywordMaker(info.Title, year)
+	searchKeyword := model.VideoNameSearchKeywordMaker(info.Title, imdbInfo.Year)
 	subInfoList, err = s.GetSubListFromKeyword(searchKeyword)
 	if err != nil {
 		return nil, err