Browse Source

完成shooter

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

+ 5 - 3
common/selferr.go

@@ -3,7 +3,9 @@ package common
 import "errors"
 
 var(
-	NoMetadataFile = errors.New("no metadata file, movie.xml or *.nfo")
-	CanNotFindIMDBID = errors.New("can not find IMDB Id")
-	CIdIsEmpty = errors.New("cid is empty")
+	NoMetadataFile         = errors.New("no metadata file, movie.xml or *.nfo")
+	CanNotFindIMDBID       = errors.New("can not find IMDB Id")
+	XunLeiCIdIsEmpty       = errors.New("cid is empty")
+	VideoFileIsTooSmall    = errors.New("video file is too small")
+	ShooterFileHashIsEmpty = errors.New("filehash is empty")
 )

+ 4 - 1
common/urls.go

@@ -1,3 +1,6 @@
 package common
 
-const SubXunleiRootUrl = "http://sub.xmp.sandai.net:8000/subxl/%s.json"
+const (
+	SubXunLeiRootUrl = "http://sub.xmp.sandai.net:8000/subxl/%s.json"
+	SubShooterRootUrl = "https://www.shooter.cn/api/subapi.php"
+)

+ 1 - 0
common/util.go

@@ -0,0 +1 @@
+package common

+ 1 - 1
go.mod

@@ -5,5 +5,5 @@ go 1.15
 require (
 	github.com/PuerkitoBio/goquery v1.6.1 // indirect
 	github.com/beevik/etree v1.1.0
-	github.com/go-resty/resty/v2 v2.6.0 // indirect
+	github.com/go-resty/resty/v2 v2.6.0
 )

+ 112 - 0
sub_supplier/shooter/shooter.go

@@ -1,7 +1,119 @@
 package shooter
 
+import (
+	"crypto/md5"
+	"fmt"
+	"github.com/allanpk716/ChineseSubFinder/common"
+	"github.com/allanpk716/ChineseSubFinder/sub_supplier"
+	"github.com/go-resty/resty/v2"
+	"math"
+	"os"
+	"path/filepath"
+	"strings"
+)
 
 type Supplier struct {
 
+}
 
+func NewSupplier() *Supplier {
+	return &Supplier{}
+}
+
+func (s Supplier) GetSubListFromFile(filePath string, httpProxy string) ([]sub_supplier.SubInfo, error) {
+
+	const qLan = "Chn"
+	var outSubInfoList []sub_supplier.SubInfo
+	var jsonList []SublistShooter
+
+	hash, err := s.computeFileHash(filePath)
+	if err != nil {
+		return nil, err
+	}
+	if hash == "" {
+		return nil, common.ShooterFileHashIsEmpty
+	}
+
+	fileName := filepath.Base(filePath)
+
+	httpClient := resty.New()
+	httpClient.SetTimeout(common.HTMLTimeOut)
+	if httpProxy != "" {
+		httpClient.SetProxy(httpProxy)
+	}
+	httpClient.SetHeaders(map[string]string{
+		"Content-Type": "application/json",
+		"User-Agent": "Mozilla/5.0 (Macintosh; U; Intel Mac OS X 10_6_8; en-us) AppleWebKit/534.50 (KHTML, like Gecko) Version/5.1 Safari/534.50",
+	})
+	_, err = httpClient.R().
+		SetFormData(map[string]string{
+			"filehash": hash,
+			"pathinfo": fileName,
+			"format": "json",
+			"lang": qLan,
+		}).
+		SetResult(&jsonList).
+		Post(common.SubShooterRootUrl)
+	if err != nil {
+		return nil, err
+	}
+	for _, shooter := range jsonList {
+		for _, file := range shooter.Files {
+			subExt := file.Ext
+			if strings.Contains(file.Ext, ".") == false {
+				subExt = "." + subExt
+			}
+			outSubInfoList = append(outSubInfoList, *sub_supplier.NewSubInfo(fileName, qLan, "", file.Link, 0, shooter.Delay, subExt))
+		}
+	}
+	return outSubInfoList, nil
+}
+
+func (s Supplier) computeFileHash(filePath string) (string, error) {
+	hash := ""
+	fp, err := os.Open(filePath)
+	if err != nil {
+		return "", err
+	}
+	defer fp.Close()
+	stat, err := fp.Stat()
+	if err != nil {
+		return "", err
+	}
+	size := float64(stat.Size())
+	if size < 0xF000 {
+		return "", common.VideoFileIsTooSmall
+	}
+	samplePositions := [4]int64{
+		4 * 1024,
+		int64(math.Floor(size / 3 * 2)),
+		int64(math.Floor(size / 3)),
+		int64(size - 8*1024)}
+	var samples [4][]byte
+	for i, position := range samplePositions {
+		samples[i] = make([]byte, 4*1024)
+		_, err = fp.ReadAt(samples[i], position)
+		if err != nil {
+			return "", err
+		}
+	}
+	for _, sample := range samples {
+		if len(hash) > 0 {
+			hash += ";"
+		}
+		hash += fmt.Sprintf("%x", md5.Sum(sample))
+	}
+
+	return hash, nil
+}
+
+
+type FilesShooter struct {
+	Ext  string `json:"ext"`
+	Link string `json:"link"`
+}
+type SublistShooter struct {
+	Desc  string         `json:"desc"`
+	Delay int64          `json:"delay"`
+	Files []FilesShooter `json:"files"`
 }

+ 19 - 0
sub_supplier/shooter/shooter_test.go

@@ -0,0 +1,19 @@
+package shooter
+
+import (
+	"testing"
+)
+
+func TestNewSupplier(t *testing.T) {
+
+	shooter := NewSupplier()
+	outList, err := shooter.GetSubListFromFile("X:\\电影\\消失爱人 (2016)\\消失爱人 (2016) 720p AAC.rmvb", "")
+	if err != nil {
+		t.Error(err)
+	}
+	println(outList)
+
+	for i, sublist := range outList {
+		println(i, sublist.Language, sublist.Rate, sublist.Vote, sublist.FileUrl)
+	}
+}

+ 3 - 2
sub_supplier/sublist.go

@@ -7,8 +7,9 @@ type SubInfo struct {
 	FileUrl     string `json:"file-url"`
 	Vote    	int64  `json:"vote"`
 	Offset  	int64  `json:"offset"`
+	Ext			string `json:"ext"`		// 字幕文件的后缀名带点,有可能是直接能用的字幕文件,也可能是压缩包
 }
 
-func NewSubInfo(name string, language string, rate string, fileUrl string, vote int64, offset int64) *SubInfo {
-	return &SubInfo{Name: name, Language: language, Rate: rate, FileUrl: fileUrl, Vote: vote, Offset: offset}
+func NewSubInfo(name string, language string, rate string, fileUrl string, vote int64, offset int64, ext string) *SubInfo {
+	return &SubInfo{Name: name, Language: language, Rate: rate, FileUrl: fileUrl, Vote: vote, Offset: offset, Ext: ext}
 }

+ 4 - 3
sub_supplier/xunlei/xunlei.go

@@ -9,6 +9,7 @@ import (
 	"github.com/go-resty/resty/v2"
 	"math"
 	"os"
+	"path/filepath"
 )
 
 
@@ -26,7 +27,7 @@ func (s Supplier) GetSubListFromFile(filePath string, httpProxy string) ([]sub_s
 	var jsonList SublistSliceXunLei
 	var outSubList []sub_supplier.SubInfo
 	if len(cid) == 0 {
-		return outSubList, common.CIdIsEmpty
+		return outSubList, common.XunLeiCIdIsEmpty
 	}
 	httpClient := resty.New()
 	httpClient.SetTimeout(common.HTMLTimeOut)
@@ -37,7 +38,7 @@ func (s Supplier) GetSubListFromFile(filePath string, httpProxy string) ([]sub_s
 		"Content-Type": "application/json",
 		"User-Agent": "Mozilla/5.0 (Macintosh; U; Intel Mac OS X 10_6_8; en-us) AppleWebKit/534.50 (KHTML, like Gecko) Version/5.1 Safari/534.50",
 	})
-	resp, err := httpClient.R().Get(fmt.Sprintf(common.SubXunleiRootUrl, cid))
+	resp, err := httpClient.R().Get(fmt.Sprintf(common.SubXunLeiRootUrl, cid))
 	if err != nil {
 		return outSubList, err
 	}
@@ -49,7 +50,7 @@ func (s Supplier) GetSubListFromFile(filePath string, httpProxy string) ([]sub_s
 	// 剔除空的
 	for _, v := range jsonList.Sublist {
 		if len(v.Scid) > 0 {
-			outSubList = append(outSubList, *sub_supplier.NewSubInfo(v.Sname, v.Language, v.Rate, v.Surl, v.Svote, v.Roffset))
+			outSubList = append(outSubList, *sub_supplier.NewSubInfo(v.Sname, v.Language, v.Rate, v.Surl, v.Svote, v.Roffset, filepath.Ext(v.Surl)))
 		}
 	}
 	return outSubList, nil