Browse Source

添加迅雷的字幕搜索

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

+ 6 - 0
README.md

@@ -38,3 +38,9 @@
   * shooter(通过视频文件的唯一ID)
 
   * 迅雷(通过视频文件的唯一ID)
+
+## 感谢
+
+感谢下面项目的帮助
+
+* [Andyfoo/GoSubTitleSearcher: 字幕搜索查询(go语言版),支持4k 2160p,1080p,720p视频字幕搜索,集合了字幕库、迅雷、射手、SubHD查询接口。 (github.com)](https://github.com/Andyfoo/GoSubTitleSearcher)

+ 5 - 0
common/common.go

@@ -0,0 +1,5 @@
+package common
+
+import "time"
+
+const HTMLTimeOut = 20 * time.Second

+ 1 - 0
common/selferr.go

@@ -5,4 +5,5 @@ 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")
 )

+ 3 - 0
common/urls.go

@@ -0,0 +1,3 @@
+package common
+
+const SubXunleiRootUrl = "http://sub.xmp.sandai.net:8000/subxl/%s.json"

+ 5 - 1
go.mod

@@ -2,4 +2,8 @@ module github.com/allanpk716/ChineseSubFinder
 
 go 1.15
 
-require github.com/beevik/etree v1.1.0
+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
+)

+ 15 - 0
go.sum

@@ -1,16 +1,31 @@
+github.com/PuerkitoBio/goquery v1.6.1 h1:FgjbQZKl5HTmcn4sKBgvx8vv63nhyhIpv7lJpFGCWpk=
+github.com/PuerkitoBio/goquery v1.6.1/go.mod h1:GsLWisAFVj4WgDibEWF4pvYnkVQBpKBKeU+7zCJoLcc=
+github.com/andybalholm/cascadia v1.1.0 h1:BuuO6sSfQNFRu1LppgbD25Hr2vLYW25JvxHs5zzsLTo=
+github.com/andybalholm/cascadia v1.1.0/go.mod h1:GsXiBklL0woXo1j/WYWtSYYC4ouU9PqHO0sqidkEA4Y=
 github.com/basgys/goxml2json v1.1.0 h1:4ln5i4rseYfXNd86lGEB+Vi652IsIXIvggKM/BhUKVw=
 github.com/basgys/goxml2json v1.1.0/go.mod h1:wH7a5Np/Q4QoECFIU8zTQlZwZkrilY0itPfecMw41Dw=
 github.com/beevik/etree v1.1.0 h1:T0xke/WvNtMoCqgzPhkX2r4rjY3GDZFi+FjpRZY2Jbs=
 github.com/beevik/etree v1.1.0/go.mod h1:r8Aw8JqVegEf0w2fDnATrX9VpkMcyFeM0FhwO62wh+A=
+github.com/go-resty/resty/v2 v2.6.0 h1:joIR5PNLM2EFqqESUjCMGXrWmXNHEU9CEiK813oKYS4=
+github.com/go-resty/resty/v2 v2.6.0/go.mod h1:PwvJS6hvaPkjtjNg9ph+VrSD92bi5Zq73w/BIH7cC3Q=
 github.com/thedevsaddam/gojsonq v1.9.1 h1:zQulEP43nwmq5EKrNWyIgJVbqDeMdC1qzXM/f5O15a0=
 github.com/thedevsaddam/gojsonq v2.3.0+incompatible h1:i2lFTvGY4LvoZ2VUzedsFlRiyaWcJm3Uh6cQ9+HyQA8=
 github.com/thedevsaddam/gojsonq/v2 v2.5.2 h1:CoMVaYyKFsVj6TjU6APqAhAvC07hTI6IQen8PHzHYY0=
 github.com/thedevsaddam/gojsonq/v2 v2.5.2/go.mod h1:bv6Xa7kWy82uT0LnXPE2SzGqTj33TAEeR560MdJkiXs=
+golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
+golang.org/x/net v0.0.0-20180218175443-cbe0f9307d01/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
+golang.org/x/net v0.0.0-20200202094626-16171245cfb2/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
+golang.org/x/net v0.0.0-20210405180319-a5a99cb37ef4 h1:4nGaVu0QrbjT/AK2PRLuQfQuh6DJve+pELhqTdAj3x0=
+golang.org/x/net v0.0.0-20210405180319-a5a99cb37ef4/go.mod h1:p54w0d4576C0XHj96bSt6lcn1PtDYWL6XObtHCRCNQM=
 golang.org/x/net v0.0.0-20210525063256-abc453219eb5 h1:wjuX4b5yYQnEQHzd+CBcrcC6OVR2J1CN6mUy0oSxIPo=
 golang.org/x/net v0.0.0-20210525063256-abc453219eb5/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
+golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
 golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
+golang.org/x/sys v0.0.0-20210330210617-4fbd30eecc44/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
 golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
 golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
+golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
+golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
 golang.org/x/text v0.3.6 h1:aRYxNxv6iGQlyVaZmk6ZgYEDa+Jg18DxebPSrd6bg1M=
 golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
 golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=

+ 5 - 0
sub_supplier/iSupplier.go

@@ -0,0 +1,5 @@
+package sub_supplier
+
+type iSupplier interface {
+	GetSubListFromFile(filePath string, httpProxy string) ([]SubInfo, error)
+}

+ 3 - 0
sub_supplier/shooter/shooter.go

@@ -0,0 +1,3 @@
+package shooter
+
+

+ 14 - 0
sub_supplier/sublist.go

@@ -0,0 +1,14 @@
+package sub_supplier
+
+type SubInfo struct {
+	Name 		string `json:"name"`
+	Language 	string `json:"language"`
+	Rate 		string `json:"rate"`
+	FileUrl     string `json:"file-url"`
+	Vote    	int64  `json:"vote"`
+	Offset  	int64  `json:"offset"`
+}
+
+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}
+}

+ 107 - 0
sub_supplier/xunlei/xunlei.go

@@ -0,0 +1,107 @@
+package xunlei
+
+import (
+	"crypto/sha1"
+	"encoding/json"
+	"fmt"
+	"github.com/allanpk716/ChineseSubFinder/common"
+	"github.com/allanpk716/ChineseSubFinder/sub_supplier"
+	"github.com/go-resty/resty/v2"
+	"math"
+	"os"
+)
+
+
+
+type SupplierXunLei struct {
+
+}
+
+func NewSupplierXunLei() *SupplierXunLei {
+	return &SupplierXunLei{}
+}
+
+func (s SupplierXunLei) GetSubListFromFile(filePath string, httpProxy string) ([]sub_supplier.SubInfo, error) {
+	cid, err := s.getCid(filePath)
+	var jsonList SublistSliceXunLei
+	var outSubList []sub_supplier.SubInfo
+	if len(cid) == 0 {
+		return outSubList, common.CIdIsEmpty
+	}
+	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",
+	})
+	resp, err := httpClient.R().Get(fmt.Sprintf(common.SubXunleiRootUrl, cid))
+	if err != nil {
+		return outSubList, err
+	}
+	// 解析
+	err = json.Unmarshal([]byte(resp.String()), &jsonList)
+	if err != nil {
+		return outSubList, err
+	}
+	// 剔除空的
+	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))
+		}
+	}
+	return outSubList, nil
+}
+
+//getCid 获取指定文件的唯一 cid
+func (s SupplierXunLei) getCid(filePath string) (string, error) {
+	hash := ""
+	sha1Ctx := sha1.New()
+
+	fp, err := os.Open(filePath)
+	if err != nil {
+		return "", err
+	}
+	defer fp.Close()
+	stat, err := fp.Stat()
+	if err != nil {
+		return "", err
+	}
+	fileLength := stat.Size()
+	if fileLength < 0xF000 {
+		return "", err
+	}
+	bufferSize := int64(0x5000)
+	positions := []int64{0, int64(math.Floor(float64(fileLength) / 3)), fileLength - bufferSize}
+	for _, position := range positions {
+		var buffer = make([]byte, bufferSize)
+		_, err = fp.Seek(position, 0)
+		if err != nil {
+			return "", err
+		}
+		_, err = fp.Read(buffer)
+		if err != nil {
+			return "", err
+		}
+		sha1Ctx.Write(buffer)
+	}
+
+	hash = fmt.Sprintf("%X", sha1Ctx.Sum(nil))
+	return hash, nil
+}
+
+type SublistXunLei struct {
+	Scid     string `json:"scid"`
+	Sname    string `json:"sname"`
+	Language string `json:"language"`
+	Rate     string `json:"rate"`
+	Surl     string `json:"surl"`
+	Svote    int64  `json:"svote"`
+	Roffset  int64  `json:"roffset"`
+}
+
+type SublistSliceXunLei struct {
+	Sublist []SublistXunLei
+}

+ 19 - 0
sub_supplier/xunlei/xunlei_test.go

@@ -0,0 +1,19 @@
+package xunlei
+
+import (
+	"testing"
+)
+
+func TestGetList(t *testing.T) {
+
+	xunlie := NewSupplierXunLei()
+	outList, err := xunlie.GetSubListFromFile("X:\\电影\\Spiral From the Book of Saw (2021)\\Spiral From the Book of Saw (2021) WEBDL-1080p.mkv", "")
+	if err != nil {
+		t.Error(err)
+	}
+	println(outList)
+
+	for i, sublist := range outList {
+		println(i, sublist.Language, sublist.Rate, sublist.Vote, sublist.FileUrl)
+	}
+}