| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215 |
- package xunlei
- import (
- "crypto/sha1"
- "fmt"
- "github.com/allanpk716/ChineseSubFinder/internal/common"
- "github.com/allanpk716/ChineseSubFinder/internal/pkg/language"
- "github.com/allanpk716/ChineseSubFinder/internal/pkg/log_helper"
- "github.com/allanpk716/ChineseSubFinder/internal/pkg/my_util"
- "github.com/allanpk716/ChineseSubFinder/internal/pkg/notify_center"
- "github.com/allanpk716/ChineseSubFinder/internal/pkg/sub_parser_hub"
- "github.com/allanpk716/ChineseSubFinder/internal/types"
- "github.com/allanpk716/ChineseSubFinder/internal/types/series"
- "github.com/allanpk716/ChineseSubFinder/internal/types/supplier"
- "github.com/sirupsen/logrus"
- "math"
- "os"
- "path/filepath"
- )
- type Supplier struct {
- reqParam types.ReqParam
- log *logrus.Logger
- topic int
- }
- func NewSupplier(_reqParam ...types.ReqParam) *Supplier {
- sup := Supplier{}
- sup.log = log_helper.GetLogger()
- sup.topic = common.DownloadSubsPerSite
- if len(_reqParam) > 0 {
- sup.reqParam = _reqParam[0]
- if sup.reqParam.Topic > 0 && sup.reqParam.Topic != sup.topic {
- sup.topic = sup.reqParam.Topic
- }
- }
- return &sup
- }
- func (s Supplier) GetSupplierName() string {
- return common.SubSiteXunLei
- }
- func (s Supplier) GetReqParam() types.ReqParam {
- return s.reqParam
- }
- func (s Supplier) GetSubListFromFile4Movie(filePath string) ([]supplier.SubInfo, error) {
- return s.getSubListFromFile(filePath)
- }
- func (s Supplier) GetSubListFromFile4Series(seriesInfo *series.SeriesInfo) ([]supplier.SubInfo, error) {
- return s.downloadSub4Series(seriesInfo)
- }
- func (s Supplier) GetSubListFromFile4Anime(seriesInfo *series.SeriesInfo) ([]supplier.SubInfo, error) {
- return s.downloadSub4Series(seriesInfo)
- }
- func (s Supplier) getSubListFromFile(filePath string) ([]supplier.SubInfo, error) {
- defer func() {
- s.log.Debugln(s.GetSupplierName(), filePath, "End...")
- }()
- s.log.Debugln(s.GetSupplierName(), filePath, "Start...")
- cid, err := s.getCid(filePath)
- var jsonList SublistSliceXunLei
- var tmpXunLeiSubListChinese = make([]SublistXunLei, 0)
- var outSubList []supplier.SubInfo
- if len(cid) == 0 {
- return nil, common.XunLeiCIdIsEmpty
- }
- httpClient := my_util.NewHttpClient(s.reqParam)
- resp, err := httpClient.R().
- SetResult(&jsonList).
- Get(fmt.Sprintf(common.SubXunLeiRootUrl, cid))
- if err != nil {
- if resp != nil {
- s.log.Errorln(s.GetSupplierName(), "NewHttpClient:", filePath, err.Error())
- notify_center.Notify.Add(s.GetSupplierName()+" NewHttpClient", fmt.Sprintf("filePath: %s, resp: %s, error: %s", filePath, resp.String(), err.Error()))
- }
- return nil, err
- }
- // 剔除空的
- for _, v := range jsonList.Sublist {
- if len(v.Scid) > 0 && v.Scid != "" {
- // 符合中文语言的先加入列表
- tmpLang := language.LangConverter4Sub_Supplier(v.Language)
- if language.HasChineseLang(tmpLang) == true && sub_parser_hub.IsSubTypeWanted(v.Sname) == true {
- tmpXunLeiSubListChinese = append(tmpXunLeiSubListChinese, v)
- }
- }
- }
- // TODO 这里需要考虑,可以设置为高级选项,不够就用 unknow 来补充
- // 如果不够,再补 unknow
- if len(tmpXunLeiSubListChinese) < s.topic {
- for _, v := range jsonList.Sublist {
- if len(tmpXunLeiSubListChinese) >= s.topic {
- break
- }
- if len(v.Scid) > 0 && v.Scid != "" {
- tmpLang := language.LangConverter4Sub_Supplier(v.Language)
- if language.HasChineseLang(tmpLang) == false {
- tmpXunLeiSubListChinese = append(tmpXunLeiSubListChinese, v)
- }
- }
- }
- }
- // 再开始下载字幕
- for i, v := range tmpXunLeiSubListChinese {
- tmpLang := language.LangConverter4Sub_Supplier(v.Language)
- data, filename, err := my_util.DownFile(v.Surl)
- if err != nil {
- s.log.Errorln("xunlei pkg.DownFile:", err)
- continue
- }
- ext := ""
- if filename == "" {
- ext = filepath.Ext(v.Surl)
- } else {
- ext = filepath.Ext(filename)
- }
- outSubList = append(outSubList, *supplier.NewSubInfo(s.GetSupplierName(), int64(i), v.Sname, tmpLang, v.Surl, v.Svote, v.Roffset, ext, data))
- }
- return outSubList, nil
- }
- func (s Supplier) getSubListFromKeyword(keyword string) ([]supplier.SubInfo, error) {
- panic("not implemented")
- }
- //getCid 获取指定文件的唯一 cid
- func (s Supplier) 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
- }
- func (s Supplier) downloadSub4Series(seriesInfo *series.SeriesInfo) ([]supplier.SubInfo, error) {
- var allSupplierSubInfo = make([]supplier.SubInfo, 0)
- // 这里拿到的 seriesInfo ,里面包含了,需要下载字幕的 Eps 信息
- for _, episodeInfo := range seriesInfo.NeedDlEpsKeyList {
- one, err := s.getSubListFromFile(episodeInfo.FileFullPath)
- if err != nil {
- s.log.Errorln(s.GetSupplierName(), "getSubListFromFile", episodeInfo.Season, episodeInfo.Episode,
- episodeInfo.FileFullPath)
- continue
- }
- if one == nil {
- // 没有搜索到字幕
- s.log.Infoln(s.GetSupplierName(), "Not Find Sub can be download",
- episodeInfo.Title, episodeInfo.Season, episodeInfo.Episode)
- continue
- }
- // 需要赋值给字幕结构
- for i, _ := range one {
- one[i].Season = episodeInfo.Season
- one[i].Episode = episodeInfo.Episode
- }
- allSupplierSubInfo = append(allSupplierSubInfo, one...)
- }
- // 返回前,需要把每一个 Eps 的 Season Episode 信息填充到每个 SubInfo 中
- return allSupplierSubInfo, 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
- }
- const LangUnknow = "未知语言"
|