Browse Source

1,格式化代码
2,完成 hotfix 的统一入口以及对应的测试用例

Signed-off-by: allan716 <[email protected]>

allan716 4 years ago
parent
commit
060300c099
66 changed files with 507 additions and 318 deletions
  1. 1 0
      .gitignore
  2. 7 7
      internal/common/constvalue.go
  3. 8 8
      internal/common/selferr.go
  4. 5 5
      internal/common/urls.go
  5. 1 0
      internal/common/videotype.go
  6. 1 0
      internal/dao/hotfix.go
  7. 47 0
      internal/dao/init.go
  8. 11 11
      internal/downloader.go
  9. 1 1
      internal/downloader_test.go
  10. 2 4
      internal/ifaces/iHotFix.go
  11. 1 2
      internal/ifaces/iSubParser.go
  12. 2 3
      internal/ifaces/iSupplier.go
  13. 1 1
      internal/logic/charset/charset.go
  14. 10 10
      internal/logic/emby_helper/embyhelper.go
  15. 1 1
      internal/logic/emby_helper/embyhelper_test.go
  16. 5 5
      internal/logic/mark_system/markingsystem.go
  17. 2 2
      internal/logic/movie_helper/moviehelper.go
  18. 1 1
      internal/logic/series_helper/seriesHelper.go
  19. 16 13
      internal/logic/sub_parser/ass/ass.go
  20. 1 1
      internal/logic/sub_parser/ass/ass_test.go
  21. 5 6
      internal/logic/sub_parser/srt/srt.go
  22. 5 6
      internal/logic/sub_supplier/shooter/shooter.go
  23. 6 6
      internal/logic/sub_supplier/subSupplierHub.go
  24. 14 14
      internal/logic/sub_supplier/subhd/subhd.go
  25. 2 3
      internal/logic/sub_supplier/subhd/subhd_test.go
  26. 3 4
      internal/logic/sub_supplier/xunlei/xunlei.go
  27. 19 17
      internal/logic/sub_supplier/zimuku/zimuku.go
  28. 1 2
      internal/logic/sub_supplier/zimuku/zimuku_test.go
  29. 1 1
      internal/models/hotfix.go
  30. 0 1
      internal/models/settings.go
  31. 6 6
      internal/pkg/archive_helper/unarchiveFile.go
  32. 1 1
      internal/pkg/archive_helper/unarchiveFile_test.go
  33. 3 3
      internal/pkg/config.go
  34. 7 8
      internal/pkg/decode/decode.go
  35. 4 4
      internal/pkg/decode/decode_test.go
  36. 8 8
      internal/pkg/emby_helper/emby.go
  37. 1 1
      internal/pkg/emby_helper/emby_test.go
  38. 3 3
      internal/pkg/globalvalue.go
  39. 20 14
      internal/pkg/hot_fix/hot_fix_001.go
  40. 8 6
      internal/pkg/hot_fix/hot_fix_001_test.go
  41. 66 0
      internal/pkg/hot_fix/hot_fix_hub.go
  42. 48 0
      internal/pkg/hot_fix/hot_fix_hub_test.go
  43. 1 1
      internal/pkg/imdb_helper/imdb.go
  44. 2 2
      internal/pkg/imdb_helper/imdb_test.go
  45. 9 8
      internal/pkg/language/language.go
  46. 2 1
      internal/pkg/log_helper/loghelper.go
  47. 3 3
      internal/pkg/notify_center/NotifyCenter.go
  48. 7 8
      internal/pkg/pass_water_wall/pass_water_wall.go
  49. 4 4
      internal/pkg/random.go
  50. 1 1
      internal/pkg/rod_helper/rodHelper.go
  51. 1 1
      internal/pkg/rod_helper/rodHelper_test.go
  52. 2 2
      internal/pkg/sub_helper/subParserHub.go
  53. 5 5
      internal/pkg/sub_helper/sub_helper.go
  54. 1 1
      internal/pkg/sub_helper/sub_helper_test.go
  55. 6 5
      internal/pkg/util.go
  56. 4 4
      internal/types/config.go
  57. 3 3
      internal/types/emby/config.go
  58. 22 20
      internal/types/emby/type.go
  59. 6 0
      internal/types/hotfix.go
  60. 19 19
      internal/types/language.go
  61. 16 16
      internal/types/reqparam.go
  62. 4 4
      internal/types/series/info.go
  63. 4 4
      internal/types/subparser/fileinfo.go
  64. 1 1
      internal/types/supplier/subinfo.go
  65. 5 5
      internal/types/videoInfo.go
  66. 24 11
      main.go

+ 1 - 0
.gitignore

@@ -20,3 +20,4 @@
 /internal/config.yaml
 /internal/Logs/*.log
 /TestData/hotfix/001/test
+/internal/pkg/hot_fix/settings.db

+ 7 - 7
internal/common/constvalue.go

@@ -2,9 +2,9 @@ package common
 
 import "time"
 
-const HTMLTimeOut = 60 * time.Second             // HttpClient 超时时间
-const OneVideoProcessTimeOut = 20*60*time.Second // 一部电影、一个连续剧,最多的处理时间
-const DownloadSubsPerSite = 1                    // 默认,每个网站下载一个字幕,允许额外传参调整
+const HTMLTimeOut = 60 * time.Second                 // HttpClient 超时时间
+const OneVideoProcessTimeOut = 20 * 60 * time.Second // 一部电影、一个连续剧,最多的处理时间
+const DownloadSubsPerSite = 1                        // 默认,每个网站下载一个字幕,允许额外传参调整
 const EmbyApiGetItemsLimitMin = 50
 const EmbyApiGetItemsLimitMax = 50000
 
@@ -23,10 +23,10 @@ const (
 )
 
 const (
-	VideoExtMp4 = ".mp4"
-	VideoExtMkv = ".mkv"
+	VideoExtMp4  = ".mp4"
+	VideoExtMkv  = ".mkv"
 	VideoExtRmvb = ".rmvb"
-	VideoExtIso = ".iso"
+	VideoExtIso  = ".iso"
 
 	SubTmpFolderName = "subtmp"
-)
+)

+ 8 - 8
internal/common/selferr.go

@@ -2,21 +2,21 @@ package common
 
 import "errors"
 
-var(
+var (
 	NoMetadataFile         = errors.New("no metadata file, movie.xml or *.nfo")
 	CanNotFindIMDBID       = errors.New("can not find IMDB Id")
-	CanNotFindEpAiredTime       = errors.New("can not find Ep Aired Time")
+	CanNotFindEpAiredTime  = errors.New("can not find Ep Aired Time")
 	XunLeiCIdIsEmpty       = errors.New("cid is empty")
 	VideoFileIsTooSmall    = errors.New("video file is too small")
 	ShooterFileHashIsEmpty = errors.New("filehash is empty")
 
 	ZiMuKuSearchKeyWordStep0DetailPageUrlNotFound = errors.New("zimuku search keyword step0 not found, detail page url")
-	ZiMuKuDownloadUrlStep2NotFound = errors.New("zimuku download url step2 not found")
-	ZiMuKuDownloadUrlStep3NotFound = errors.New("zimuku download url step3 not found")
-	ZiMuKuDownloadUrlStep3AllFailed = errors.New("zimuku download url step3 all failed")
+	ZiMuKuDownloadUrlStep2NotFound                = errors.New("zimuku download url step2 not found")
+	ZiMuKuDownloadUrlStep3NotFound                = errors.New("zimuku download url step3 not found")
+	ZiMuKuDownloadUrlStep3AllFailed               = errors.New("zimuku download url step3 all failed")
 
 	SubHDStep0SubCountElementNotFound = errors.New("subhd step0 sub count element not found")
-	SubHDStep0ImgParentLessThan2 = errors.New("subhd step0 Img Parent less than 2")
-	SubHDStep0HrefIsNull = errors.New("subhd step0 href is Null")
-	SubHDStep2ExCannotFindDownloadBtn= errors.New("subhd step2ex can not find download btn")
+	SubHDStep0ImgParentLessThan2      = errors.New("subhd step0 Img Parent less than 2")
+	SubHDStep0HrefIsNull              = errors.New("subhd step0 href is Null")
+	SubHDStep2ExCannotFindDownloadBtn = errors.New("subhd step2ex can not find download btn")
 )

+ 5 - 5
internal/common/urls.go

@@ -4,12 +4,12 @@ const (
 	SubXunLeiRootUrl  = "http://sub.xmp.sandai.net:8000/subxl/%s.json"
 	SubShooterRootUrl = "https://www.shooter.cn/api/subapi.php"
 
-	SubZiMuKuRootUrl  = "http://zmk.pw"
-	SubZiMuKuSearchUrl  = SubZiMuKuRootUrl + "/search"
+	SubZiMuKuRootUrl   = "http://zmk.pw"
+	SubZiMuKuSearchUrl = SubZiMuKuRootUrl + "/search"
 
-	SubSubHDRootUrl  = "https://subhd.tv"
-	SubSubHDSearchUrl  = SubSubHDRootUrl + "/search/%s"
+	SubSubHDRootUrl   = "https://subhd.tv"
+	SubSubHDSearchUrl = SubSubHDRootUrl + "/search/%s"
 
-	TVDBRootUrl = "https://thetvdb.com"
+	TVDBRootUrl   = "https://thetvdb.com"
 	TVDBSearchUrl = TVDBRootUrl + "/search"
 )

+ 1 - 0
internal/common/videotype.go

@@ -1,6 +1,7 @@
 package common
 
 type VideoType int
+
 const (
 	Movie  VideoType = iota // 电影
 	Series                  // 连续剧,可能需要分美剧、日剧、韩剧?

+ 1 - 0
internal/dao/hotfix.go

@@ -0,0 +1 @@
+package dao

+ 47 - 0
internal/dao/init.go

@@ -0,0 +1,47 @@
+package dao
+
+import (
+	"errors"
+	"fmt"
+	"github.com/allanpk716/ChineseSubFinder/internal/models"
+	"github.com/allanpk716/ChineseSubFinder/internal/pkg"
+	"gorm.io/driver/sqlite"
+	"gorm.io/gorm"
+	"os"
+)
+
+// InitDb 初始化数据库
+func InitDb() error {
+	var err error
+	// 新建数据库
+	db, err = gorm.Open(sqlite.Open(dbFilename), &gorm.Config{})
+	if err != nil {
+		return errors.New(fmt.Sprintf("failed to connect database, %s", err.Error()))
+	}
+	// 迁移 schema
+	err = db.AutoMigrate(&models.HotFix{})
+	if err != nil {
+		return errors.New(fmt.Sprintf("db AutoMigrate error, %s", err.Error()))
+	}
+
+	return nil
+}
+
+// GetDb 获取数据库实例
+func GetDb() *gorm.DB {
+	return db
+}
+
+// DeleteDbFile 删除 Db 文件
+func DeleteDbFile() error {
+	if pkg.IsFile(dbFilename) == true {
+		return os.Remove(dbFilename)
+	}
+	return nil
+}
+
+var (
+	db *gorm.DB
+)
+
+const dbFilename = "settings.db"

+ 11 - 11
internal/downloader.go

@@ -158,7 +158,7 @@ func (d Downloader) DownloadSub4Movie(dir string) error {
 		// 字幕都下载缓存好了,需要抉择存哪一个,优先选择中文双语的,然后到中文
 		organizeSubFiles, err := subSupplierHub.DownloadSub4Movie(inData.OneVideoFullPath, inData.Index)
 		if err != nil {
-			d.log.Errorln("subSupplierHub.DownloadSub4Movie", inData.OneVideoFullPath ,err)
+			d.log.Errorln("subSupplierHub.DownloadSub4Movie", inData.OneVideoFullPath, err)
 			return err
 		}
 		if organizeSubFiles == nil || len(organizeSubFiles) < 1 {
@@ -189,9 +189,9 @@ func (d Downloader) DownloadSub4Movie(dir string) error {
 		}()
 
 		select {
-		case _ = <- done:
+		case _ = <-done:
 			return
-		case p := <- panicChan:
+		case p := <-panicChan:
 			d.log.Errorln("DownloadSub4Movie.NewPoolWithFunc got panic", p)
 		case <-ctx.Done():
 			d.log.Errorln("DownloadSub4Movie.NewPoolWithFunc got time out", ctx.Err())
@@ -209,7 +209,7 @@ func (d Downloader) DownloadSub4Movie(dir string) error {
 		wg.Add(1)
 		err = p.Invoke(InputData{OneVideoFullPath: oneVideoFullPath, Index: i, Wg: &wg})
 		if err != nil {
-			d.log.Errorln("DownloadSub4Movie ants.Invoke",err)
+			d.log.Errorln("DownloadSub4Movie ants.Invoke", err)
 		}
 	}
 	wg.Wait()
@@ -304,9 +304,9 @@ func (d Downloader) DownloadSub4Series(dir string) error {
 		}()
 
 		select {
-		case _ = <- done:
+		case _ = <-done:
 			return
-		case p := <- panicChan:
+		case p := <-panicChan:
 			d.log.Errorln("DownloadSub4Series.NewPoolWithFunc got panic", p)
 		case <-ctx.Done():
 			d.log.Errorln("DownloadSub4Series.NewPoolWithFunc got time out", ctx.Err())
@@ -337,7 +337,7 @@ func (d Downloader) DownloadSub4Series(dir string) error {
 		wg.Add(1)
 		err = p.Invoke(InputData{OneVideoFullPath: oneSeriesPath, Index: i, Wg: &wg})
 		if err != nil {
-			d.log.Errorln("DownloadSub4Series ants.Invoke",err)
+			d.log.Errorln("DownloadSub4Series ants.Invoke", err)
 		}
 	}
 	wg.Wait()
@@ -438,7 +438,7 @@ func (d Downloader) writeSubFile2VideoPath(videoFileFullPath string, finalSubFil
 	videoFileNameWithOutExt := strings.ReplaceAll(filepath.Base(videoFileFullPath),
 		filepath.Ext(videoFileFullPath), "")
 	if extraSubPreName != "" {
-		extraSubPreName = "[" + extraSubPreName +"]"
+		extraSubPreName = "[" + extraSubPreName + "]"
 	}
 	subNewName := videoFileNameWithOutExt + embyLanExtName + extraSubPreName + finalSubFile.Ext
 	desSubFullPath := path.Join(videoRootPath, subNewName)
@@ -476,6 +476,6 @@ func (d Downloader) copySubFile2DesFolder(desFolder string, subFiles []string) e
 
 type InputData struct {
 	OneVideoFullPath string
-	Index			int
-	Wg 				*sync.WaitGroup
-}
+	Index            int
+	Wg               *sync.WaitGroup
+}

+ 1 - 1
internal/downloader_test.go

@@ -89,4 +89,4 @@ func TestDownloader_SubParserHub(t *testing.T) {
 
 	subParserHub := sub_helper.NewSubParserHub(ass.NewParser(), srt.NewParser())
 	subParserHub.IsSubHasChinese(subFile)
-}
+}

+ 2 - 4
internal/ifaces/iHotFix.go

@@ -1,9 +1,7 @@
 package ifaces
 
-
 type IHotFix interface {
-
 	GetKey() string
 
-	Process() error
-}
+	Process() (interface{}, error)
+}

+ 1 - 2
internal/ifaces/iSubParser.go

@@ -5,10 +5,9 @@ import (
 )
 
 type ISubParser interface {
-
 	GetParserName() string
 
 	DetermineFileTypeFromFile(filePath string) (*subparser.FileInfo, error)
 
 	DetermineFileTypeFromBytes(inBytes []byte, nowExt string) (*subparser.FileInfo, error)
-}
+}

+ 2 - 3
internal/ifaces/iSupplier.go

@@ -7,7 +7,6 @@ import (
 )
 
 type ISupplier interface {
-
 	GetSupplierName() string
 
 	GetReqParam() types.ReqParam
@@ -15,6 +14,6 @@ type ISupplier interface {
 	GetSubListFromFile4Movie(filePath string) ([]supplier.SubInfo, error)
 
 	GetSubListFromFile4Series(seriesInfo *series.SeriesInfo) ([]supplier.SubInfo, error)
-	
+
 	GetSubListFromFile4Anime(seriesInfo *series.SeriesInfo) ([]supplier.SubInfo, error)
-}
+}

+ 1 - 1
internal/logic/charset/charset.go

@@ -111,4 +111,4 @@ func getEncoding(charset Charset) encoding.Encoding {
 		return e
 	}
 	return nil
-}
+}

+ 10 - 10
internal/logic/emby_helper/embyhelper.go

@@ -173,13 +173,13 @@ func (em *EmbyHelper) filterEmbyVideoList(videoFolderName string, videoIdList []
 			info, err := queryFunc(data.Id)
 			outData := OutData{
 				Info: info,
-				Err: err,
+				Err:  err,
 			}
 			done <- outData
 		}()
 
 		select {
-		case outData := <- done:
+		case outData := <-done:
 			// 收到结果,需要加锁
 			if outData.Err != nil {
 				log_helper.GetLogger().Errorln("filterEmbyVideoList.NewPoolWithFunc got Err", outData.Err)
@@ -192,7 +192,7 @@ func (em *EmbyHelper) filterEmbyVideoList(videoFolderName string, videoIdList []
 			filterVideoEmbyInfo = append(filterVideoEmbyInfo, *outData.Info)
 			em.listLock.Unlock()
 			return
-		case p := <- panicChan:
+		case p := <-panicChan:
 			log_helper.GetLogger().Errorln("filterEmbyVideoList.NewPoolWithFunc got panic", p)
 		case <-ctx.Done():
 			log_helper.GetLogger().Errorln("filterEmbyVideoList.NewPoolWithFunc got time out", ctx.Err())
@@ -269,7 +269,7 @@ func (em *EmbyHelper) filterNoChineseSubVideoList(videoList []emby.EmbyMixInfo)
 			noSubVideoList = append(noSubVideoList, info)
 		} else {
 			// 如果视频发布时间超过两年了,有字幕就直接跳过了,一般字幕稳定了
-			if currentTime.Year() - 2 > info.VideoInfo.PremiereDate.Year() {
+			if currentTime.Year()-2 > info.VideoInfo.PremiereDate.Year() {
 				continue
 			}
 			// 有中文字幕,且如果在三个月内,则需要继续下载字幕`
@@ -308,7 +308,7 @@ func (em *EmbyHelper) langStringOK(inLang string) bool {
 		em.replaceLangString(types.Emby_cht_jp),
 		em.replaceLangString(types.Emby_chs_kr),
 		em.replaceLangString(types.Emby_cht_kr):
-			return true
+		return true
 	case em.replaceLangString(types.Emby_chinese):
 		return true
 	default:
@@ -337,11 +337,11 @@ func (em *EmbyHelper) replaceLangString(inString string) string {
 }
 
 type InputData struct {
-	Id 		string
-	Wg 		*sync.WaitGroup
+	Id string
+	Wg *sync.WaitGroup
 }
 
 type OutData struct {
-	Info 	*emby.EmbyMixInfo
-	Err 	error
-}
+	Info *emby.EmbyMixInfo
+	Err  error
+}

+ 1 - 1
internal/logic/emby_helper/embyhelper_test.go

@@ -24,4 +24,4 @@ func TestEmbyHelper_RefreshEmbySubList(t *testing.T) {
 		t.Fatal(err)
 	}
 	println(bok)
-}
+}

+ 5 - 5
internal/logic/mark_system/markingsystem.go

@@ -11,10 +11,10 @@ import (
 
 // MarkingSystem 评价系统,解决字幕排序优先级问题
 type MarkingSystem struct {
-	log *logrus.Logger
-	subSiteSequence []string			// 网站的优先级,从高到低
-	SubTypePriority int					// 字幕格式的优先级
-	subParserHub *sub_helper.SubParserHub
+	log             *logrus.Logger
+	subSiteSequence []string // 网站的优先级,从高到低
+	SubTypePriority int      // 字幕格式的优先级
+	subParserHub    *sub_helper.SubParserHub
 }
 
 func NewMarkingSystem(subSiteSequence []string, subTypePriority int) *MarkingSystem {
@@ -119,4 +119,4 @@ func (m MarkingSystem) parseSubFileInfo(organizeSubFiles []string) map[string][]
 		subInfoDict[subFileInfo.FromWhereSite] = append(subInfoDict[subFileInfo.FromWhereSite], *subFileInfo)
 	}
 	return subInfoDict
-}
+}

+ 2 - 2
internal/logic/movie_helper/moviehelper.go

@@ -134,7 +134,7 @@ func MovieNeedDlSub(videoFullPath string) (bool, error) {
 		return false, err
 	}
 	// 如果这个视频发布的时间早于现在有两个年的间隔
-	if mInfo.Year > 0 &&  currentTime.Year() - 2 > mInfo.Year {
+	if mInfo.Year > 0 && currentTime.Year()-2 > mInfo.Year {
 		if found == false {
 			// 需要下载的
 			return true, nil
@@ -179,4 +179,4 @@ func MovieNeedDlSub(videoFullPath string) (bool, error) {
 			return false, nil
 		}
 	}
-}
+}

+ 1 - 1
internal/logic/series_helper/seriesHelper.go

@@ -322,4 +322,4 @@ func getEpsInfoAndSubDic(videoFile string, EpisodeDict map[string]series.Episode
 		return
 	}
 	return
-}
+}

+ 16 - 13
internal/logic/sub_parser/ass/ass.go

@@ -26,11 +26,11 @@ func (p Parser) GetParserName() string {
 func (p Parser) DetermineFileTypeFromFile(filePath string) (*subparser.FileInfo, error) {
 	nowExt := filepath.Ext(filePath)
 	if strings.ToLower(nowExt) != common.SubExtASS && strings.ToLower(nowExt) != common.SubExtSSA {
-		return nil ,nil
+		return nil, nil
 	}
 	fBytes, err := ioutil.ReadFile(filePath)
 	if err != nil {
-		return nil ,err
+		return nil, err
 	}
 	inBytes, err := language.ChangeFileCoding2UTF8(fBytes)
 	if err != nil {
@@ -40,15 +40,15 @@ func (p Parser) DetermineFileTypeFromFile(filePath string) (*subparser.FileInfo,
 }
 
 // DetermineFileTypeFromBytes 确定字幕文件的类型,是双语字幕或者某一种语言等等信息
-func (p Parser) DetermineFileTypeFromBytes(inBytes []byte, nowExt string) (*subparser.FileInfo, error){
-	allString :=string(inBytes)
+func (p Parser) DetermineFileTypeFromBytes(inBytes []byte, nowExt string) (*subparser.FileInfo, error) {
+	allString := string(inBytes)
 	// 注意,需要替换掉 \r 不然正则表达式会有问题
 	allString = strings.ReplaceAll(allString, "\r", "")
 	re := regexp.MustCompile(regString)
 	// 找到 start end text
 	matched := re.FindAllStringSubmatch(allString, -1)
 	if len(matched) < 1 {
-		return nil ,nil
+		return nil, nil
 	}
 	subFileInfo := subparser.FileInfo{}
 	subFileInfo.Ext = nowExt
@@ -84,24 +84,26 @@ func (p Parser) DetermineFileTypeFromBytes(inBytes []byte, nowExt string) (*subp
 		odl := subparser.OneDialogue{
 			StyleName: nowStyleName,
 			StartTime: startTime,
-			EndTime: endTime,
+			EndTime:   endTime,
 		}
 		odl.Lines = make([]string, 0)
 		// nowText 优先移除 \h 这个是替换空格, \h 是让两个词在一行,不换行显示
-		nowText = strings.ReplaceAll(nowText, `\h` , " ")
+		nowText = strings.ReplaceAll(nowText, `\h`, " ")
 		// nowText 这个需要先把 {} 花括号内的内容给移除
 		var re = regexp.MustCompile(`(?i){.*}`)
 		nowText1 := re.ReplaceAllString(nowText, "")
 		nowText1 = strings.TrimRight(nowText1, "\r")
 		// 然后判断是否有 \N 或者 \n
 		// 直接把 \n 替换为 \N 来解析
-		nowText1 = strings.ReplaceAll(nowText1, `\n` , `\N`)
-		if strings.Contains(nowText1,`\N`) {
+		nowText1 = strings.ReplaceAll(nowText1, `\n`, `\N`)
+		if strings.Contains(nowText1, `\N`) {
 			// 有,那么就需要再次切割,一般是双语字幕
 			var re2 = regexp.MustCompile(`(?i)(.*)\\N(.*)`)
 			for _, matched2 := range re2.FindAllStringSubmatch(nowText1, -1) {
 				for i, s := range matched2 {
-					if i == 0 {continue}
+					if i == 0 {
+						continue
+					}
 					odl.Lines = append(odl.Lines, s)
 				}
 			}
@@ -137,10 +139,11 @@ const (
 )
 
 type StyleNameInfo struct {
-	Name string
-	Count  int
+	Name  string
+	Count int
 }
 type StyleNameInfos []StyleNameInfo
+
 func (a StyleNameInfos) Len() int           { return len(a) }
 func (a StyleNameInfos) Less(i, j int) bool { return a[i].Count < a[j].Count }
 func (a StyleNameInfos) Swap(i, j int)      { a[i], a[j] = a[j], a[i] }
@@ -153,4 +156,4 @@ func sortMapByValue(m map[string]int) StyleNameInfos {
 	}
 	sort.Sort(sort.Reverse(p))
 	return p
-}
+}

+ 1 - 1
internal/logic/sub_parser/ass/ass_test.go

@@ -42,4 +42,4 @@ func TestParser_DetermineFileTypeFromFile(t *testing.T) {
 			println(got.Name, got.Ext, got.Lang)
 		})
 	}
-}
+}

+ 5 - 6
internal/logic/sub_parser/srt/srt.go

@@ -11,7 +11,6 @@ import (
 )
 
 type Parser struct {
-
 }
 
 func NewParser() *Parser {
@@ -26,11 +25,11 @@ func (p Parser) GetParserName() string {
 func (p Parser) DetermineFileTypeFromFile(filePath string) (*subparser.FileInfo, error) {
 	nowExt := filepath.Ext(filePath)
 	if strings.ToLower(nowExt) != common.SubExtSRT {
-		return nil ,nil
+		return nil, nil
 	}
 	fBytes, err := ioutil.ReadFile(filePath)
 	if err != nil {
-		return nil ,err
+		return nil, err
 	}
 	inBytes, err := language.ChangeFileCoding2UTF8(fBytes)
 	if err != nil {
@@ -40,7 +39,7 @@ func (p Parser) DetermineFileTypeFromFile(filePath string) (*subparser.FileInfo,
 }
 
 // DetermineFileTypeFromBytes 确定字幕文件的类型,是双语字幕或者某一种语言等等信息
-func (p Parser) DetermineFileTypeFromBytes(inBytes []byte, nowExt string) (*subparser.FileInfo, error){
+func (p Parser) DetermineFileTypeFromBytes(inBytes []byte, nowExt string) (*subparser.FileInfo, error) {
 
 	allString := string(inBytes)
 	// 注意,需要替换掉 \r 不然正则表达式会有问题
@@ -49,7 +48,7 @@ func (p Parser) DetermineFileTypeFromBytes(inBytes []byte, nowExt string) (*subp
 	// 找到 start end text
 	matched := re.FindAllStringSubmatch(allString, -1)
 	if len(matched) < 1 {
-		return nil ,nil
+		return nil, nil
 	}
 	subFileInfo := subparser.FileInfo{}
 	subFileInfo.Ext = nowExt
@@ -62,7 +61,7 @@ func (p Parser) DetermineFileTypeFromBytes(inBytes []byte, nowExt string) (*subp
 		nowText := oneDial[4]
 		odl := subparser.OneDialogue{
 			StartTime: startTime,
-			EndTime: endTime,
+			EndTime:   endTime,
 		}
 		odl.Lines = make([]string, 0)
 		nowText = strings.TrimRight(nowText, "\n")

+ 5 - 6
internal/logic/sub_supplier/shooter/shooter.go

@@ -44,7 +44,7 @@ func (s Supplier) GetReqParam() types.ReqParam {
 	return s.reqParam
 }
 
-func (s Supplier) GetSubListFromFile4Movie(filePath string) ([]supplier.SubInfo, error){
+func (s Supplier) GetSubListFromFile4Movie(filePath string) ([]supplier.SubInfo, error) {
 	return s.getSubListFromFile(filePath)
 }
 
@@ -52,7 +52,7 @@ func (s Supplier) GetSubListFromFile4Series(seriesInfo *series.SeriesInfo) ([]su
 	return s.downloadSub4Series(seriesInfo)
 }
 
-func (s Supplier) GetSubListFromFile4Anime(seriesInfo *series.SeriesInfo) ([]supplier.SubInfo, error){
+func (s Supplier) GetSubListFromFile4Anime(seriesInfo *series.SeriesInfo) ([]supplier.SubInfo, error) {
 	return s.downloadSub4Series(seriesInfo)
 }
 
@@ -79,8 +79,8 @@ func (s Supplier) getSubListFromFile(filePath string) ([]supplier.SubInfo, error
 		SetFormData(map[string]string{
 			"filehash": hash,
 			"pathinfo": fileName,
-			"format": "json",
-			"lang": qLan,
+			"format":   "json",
+			"lang":     qLan,
 		}).
 		SetResult(&jsonList).
 		Post(common.SubShooterRootUrl)
@@ -174,7 +174,6 @@ func (s Supplier) downloadSub4Series(seriesInfo *series.SeriesInfo) ([]supplier.
 	return allSupplierSubInfo, nil
 }
 
-
 type FilesShooter struct {
 	Ext  string `json:"ext"`
 	Link string `json:"link"`
@@ -183,4 +182,4 @@ type SublistShooter struct {
 	Desc  string         `json:"desc"`
 	Delay int64          `json:"delay"`
 	Files []FilesShooter `json:"files"`
-}
+}

+ 6 - 6
internal/logic/sub_supplier/subSupplierHub.go

@@ -19,7 +19,7 @@ type SubSupplierHub struct {
 	log *logrus.Logger
 }
 
-func NewSubSupplierHub(one ifaces.ISupplier,_inSupplier ...ifaces.ISupplier) *SubSupplierHub {
+func NewSubSupplierHub(one ifaces.ISupplier, _inSupplier ...ifaces.ISupplier) *SubSupplierHub {
 	s := SubSupplierHub{}
 	s.log = log_helper.GetLogger()
 	s.Suppliers = make([]ifaces.ISupplier, 0)
@@ -47,7 +47,7 @@ func (d SubSupplierHub) DownloadSub4Movie(videoFullPath string, index int) ([]st
 
 	needDlSub, err := movieHelper.MovieNeedDlSub(videoFullPath)
 	if err != nil {
-		return nil, errors.Newf("MovieNeedDlSub %v %v", videoFullPath , err)
+		return nil, errors.Newf("MovieNeedDlSub %v %v", videoFullPath, err)
 	}
 	if needDlSub == true {
 		// 需要下载字幕
@@ -56,7 +56,7 @@ func (d SubSupplierHub) DownloadSub4Movie(videoFullPath string, index int) ([]st
 		// 整理字幕,比如解压什么的
 		organizeSubFiles, err := sub_helper.OrganizeDlSubFiles(filepath.Base(videoFullPath), subInfos)
 		if err != nil {
-			return nil, errors.Newf("OrganizeDlSubFiles %v %v", videoFullPath , err)
+			return nil, errors.Newf("OrganizeDlSubFiles %v %v", videoFullPath, err)
 		}
 		// 因为是下载电影,需要合并返回
 		var outSubFileFullPathList = make([]string, 0)
@@ -84,7 +84,7 @@ func (d SubSupplierHub) DownloadSub4Series(seriesDirPath string, index int) (*se
 	// 读取本地的视频和字幕信息
 	seriesInfo, err := seriesHelper.ReadSeriesInfoFromDir(seriesDirPath, imdbInfo)
 	if err != nil {
-		return nil, nil, errors.Newf("ReadSeriesInfoFromDir %v %v", seriesDirPath , err)
+		return nil, nil, errors.Newf("ReadSeriesInfoFromDir %v %v", seriesDirPath, err)
 	}
 	organizeSubFiles, err := d.dlSubFromSeriesInfo(seriesDirPath, index, seriesInfo, err)
 	if err != nil {
@@ -107,7 +107,7 @@ func (d SubSupplierHub) DownloadSub4SeriesFromEmby(seriesDirPath string, seriesL
 	// 读取本地的视频和字幕信息
 	seriesInfo, err := seriesHelper.ReadSeriesInfoFromEmby(seriesDirPath, imdbInfo, seriesList)
 	if err != nil {
-		return nil, nil, errors.Newf("ReadSeriesInfoFromDir %v %v", seriesDirPath , err)
+		return nil, nil, errors.Newf("ReadSeriesInfoFromDir %v %v", seriesDirPath, err)
 	}
 	organizeSubFiles, err := d.dlSubFromSeriesInfo(seriesDirPath, index, seriesInfo, err)
 	if err != nil {
@@ -126,4 +126,4 @@ func (d SubSupplierHub) dlSubFromSeriesInfo(seriesDirPath string, index int, ser
 		return nil, errors.Newf("OrganizeDlSubFiles %v %v", seriesDirPath, err)
 	}
 	return organizeSubFiles, nil
-}
+}

+ 14 - 14
internal/logic/sub_supplier/subhd/subhd.go

@@ -61,7 +61,7 @@ func (s Supplier) GetReqParam() types.ReqParam {
 	return s.reqParam
 }
 
-func (s Supplier) GetSubListFromFile4Movie(filePath string) ([]supplier.SubInfo, error){
+func (s Supplier) GetSubListFromFile4Movie(filePath string) ([]supplier.SubInfo, error) {
 	return s.getSubListFromFile4Movie(filePath)
 }
 
@@ -128,7 +128,7 @@ func (s Supplier) GetSubListFromFile4Series(seriesInfo *series.SeriesInfo) ([]su
 	return subInfos, nil
 }
 
-func (s Supplier) GetSubListFromFile4Anime(seriesInfo *series.SeriesInfo) ([]supplier.SubInfo, error){
+func (s Supplier) GetSubListFromFile4Anime(seriesInfo *series.SeriesInfo) ([]supplier.SubInfo, error) {
 	panic("not implemented")
 }
 
@@ -163,7 +163,7 @@ func (s Supplier) getSubListFromFile4Movie(filePath string) ([]supplier.SubInfo,
 			s.log.Errorln("getSubListFromKeyword4Movie", "IMDBID can not found sub", filePath, err)
 		}
 		// 如果有就优先返回
-		if len(subInfoList) >0 {
+		if len(subInfoList) > 0 {
 			return subInfoList, nil
 		}
 	}
@@ -180,7 +180,7 @@ func (s Supplier) getSubListFromFile4Movie(filePath string) ([]supplier.SubInfo,
 
 func (s Supplier) getSubListFromKeyword4Movie(keyword string) ([]supplier.SubInfo, error) {
 
-	var subInfos  []supplier.SubInfo
+	var subInfos []supplier.SubInfo
 	detailPageUrl, err := s.step0(keyword)
 	if err != nil {
 		return nil, err
@@ -220,7 +220,7 @@ func (s Supplier) whichEpisodeNeedDownloadSub(seriesInfo *series.SeriesInfo, all
 	// key SxEx - SubInfos
 	var allSubDict = make(map[string][]HdListItem)
 	// 全季的字幕列表
-	var oneSeasonSubDict  = make(map[string][]HdListItem)
+	var oneSeasonSubDict = make(map[string][]HdListItem)
 	for _, subInfo := range allSubList {
 		_, season, episode, err := decode.GetSeasonAndEpisodeFromSubFileName(subInfo.Title)
 		if err != nil {
@@ -303,7 +303,7 @@ func (s Supplier) step0(keyword string) (string, error) {
 	}
 	imgSelection := doc.Find("img.rounded-start")
 	_, ok := imgSelection.Attr("src")
-	if ok == true{
+	if ok == true {
 
 		if len(imgSelection.Nodes) < 2 {
 			return "", common.SubHDStep0ImgParentLessThan2
@@ -338,7 +338,7 @@ func (s Supplier) step0(keyword string) (string, error) {
 		//} else {
 		//	return "/d/" + strings.ReplaceAll(imgName, imgExt, ""), nil
 		//}
-	} else{
+	} else {
 		return "", common.SubHDStep0HrefIsNull
 	}
 	//re = regexp.MustCompile(`<a\shref="(/d/[\w]+)">\s?<img`)
@@ -417,7 +417,7 @@ func (s Supplier) step1(detailPageUrl string, isMovieOrSeries bool) ([]HdListIte
 }
 
 // step2Ex 下载字幕 过防水墙
-func (s Supplier) step2Ex(browser *rod.Browser, subDownloadPageUrl string) (*HdContent, error)  {
+func (s Supplier) step2Ex(browser *rod.Browser, subDownloadPageUrl string) (*HdContent, error) {
 	var err error
 	defer func() {
 		if err != nil {
@@ -498,7 +498,7 @@ func (s Supplier) downloadSubFile(browser *rod.Browser, page *rod.Page, hasWater
 	err = rod.Try(func() {
 		tmpDir := filepath.Join(os.TempDir(), "rod", "downloads")
 		wait := browser.WaitDownload(tmpDir)
-		getDownloadFile:= func() ([]byte, string, error) {
+		getDownloadFile := func() ([]byte, string, error) {
 			info := wait()
 			downloadPath := filepath.Join(tmpDir, info.GUID)
 			defer func() { _ = os.Remove(downloadPath) }()
@@ -506,7 +506,7 @@ func (s Supplier) downloadSubFile(browser *rod.Browser, page *rod.Page, hasWater
 			if err != nil {
 				return nil, "", err
 			}
-			return b,info.SuggestedFilename, nil
+			return b, info.SuggestedFilename, nil
 		}
 
 		// 点击下载按钮
@@ -536,7 +536,7 @@ func (s Supplier) downloadSubFile(browser *rod.Browser, page *rod.Page, hasWater
 	return &hdContent, nil
 }
 
-func (s Supplier) passWaterWall(page *rod.Page)  {
+func (s Supplier) passWaterWall(page *rod.Page) {
 	//等待驗證碼窗體載入
 	page.MustElement("#tcaptcha_iframe").MustWaitLoad()
 	//進入到iframe
@@ -655,12 +655,12 @@ type HdListItem struct {
 	Lang       string `json:"lang"`
 	Rate       string `json:"rate"`
 	DownCount  int    `json:"downCount"`
-	Season    			int		// 第几季,默认-1
-	Episode   			int		// 第几集,默认-1
+	Season     int    // 第几季,默认-1
+	Episode    int    // 第几集,默认-1
 }
 
 type HdContent struct {
 	Filename string `json:"filename"`
 	Ext      string `json:"ext"`
 	Data     []byte `json:"data"`
-}
+}

+ 2 - 3
internal/logic/sub_supplier/subhd/subhd_test.go

@@ -33,12 +33,11 @@ func TestSupplier_GetSubListFromFile(t *testing.T) {
 func TestSupplier_GetSubListFromFile4Series(t *testing.T) {
 
 	//ser := "X:\\连续剧\\The Bad Batch"	// tt12708542
-	ser := "X:\\连续剧\\瑞克和莫蒂 (2013)"	//
+	ser := "X:\\连续剧\\瑞克和莫蒂 (2013)" //
 	//ser := "X:\\连续剧\\杀死伊芙 (2018)"	// tt7016936
 	//ser := "X:\\连续剧\\Money.Heist"
 	//ser := "X:\\连续剧\\黑钱胜地 (2017)"
 
-
 	// 读取本地的视频和字幕信息
 	seriesInfo, err := series_helper2.ReadSeriesInfoFromDir(ser, nil)
 	if err != nil {
@@ -53,4 +52,4 @@ func TestSupplier_GetSubListFromFile4Series(t *testing.T) {
 	for i, sublist := range outList {
 		println(i, sublist.Name, sublist.Ext, sublist.Language.String(), sublist.Score, len(sublist.Data))
 	}
-}
+}

+ 3 - 4
internal/logic/sub_supplier/xunlei/xunlei.go

@@ -45,7 +45,7 @@ func (s Supplier) GetReqParam() types.ReqParam {
 	return s.reqParam
 }
 
-func (s Supplier) GetSubListFromFile4Movie(filePath string) ([]supplier.SubInfo, error){
+func (s Supplier) GetSubListFromFile4Movie(filePath string) ([]supplier.SubInfo, error) {
 	return s.getSubListFromFile(filePath)
 }
 
@@ -53,7 +53,7 @@ func (s Supplier) GetSubListFromFile4Series(seriesInfo *series.SeriesInfo) ([]su
 	return s.downloadSub4Series(seriesInfo)
 }
 
-func (s Supplier) GetSubListFromFile4Anime(seriesInfo *series.SeriesInfo) ([]supplier.SubInfo, error){
+func (s Supplier) GetSubListFromFile4Anime(seriesInfo *series.SeriesInfo) ([]supplier.SubInfo, error) {
 	return s.downloadSub4Series(seriesInfo)
 }
 
@@ -116,7 +116,6 @@ func (s Supplier) getSubListFromFile(filePath string) ([]supplier.SubInfo, error
 		outSubList = append(outSubList, *supplier.NewSubInfo(s.GetSupplierName(), int64(i), v.Sname, tmpLang, v.Surl, v.Svote, v.Roffset, ext, data))
 	}
 
-
 	return outSubList, nil
 }
 
@@ -194,4 +193,4 @@ type SublistSliceXunLei struct {
 	Sublist []SublistXunLei
 }
 
-const LangUnknow = "未知语言"
+const LangUnknow = "未知语言"

+ 19 - 17
internal/logic/sub_supplier/zimuku/zimuku.go

@@ -49,7 +49,7 @@ func (s Supplier) GetReqParam() types.ReqParam {
 	return s.reqParam
 }
 
-func (s Supplier) GetSubListFromFile4Movie(filePath string) ([]supplier.SubInfo, error){
+func (s Supplier) GetSubListFromFile4Movie(filePath string) ([]supplier.SubInfo, error) {
 	return s.getSubListFromMovie(filePath)
 }
 
@@ -106,7 +106,7 @@ func (s Supplier) GetSubListFromFile4Series(seriesInfo *series.SeriesInfo) ([]su
 	return outSubInfoList, nil
 }
 
-func (s Supplier) GetSubListFromFile4Anime(seriesInfo *series.SeriesInfo) ([]supplier.SubInfo, error){
+func (s Supplier) GetSubListFromFile4Anime(seriesInfo *series.SeriesInfo) ([]supplier.SubInfo, error) {
 	panic("not implemented")
 }
 
@@ -142,7 +142,7 @@ func (s Supplier) getSubListFromMovie(fileFPath string) ([]supplier.SubInfo, err
 			s.log.Errorln("getSubListFromKeyword", "IMDBID can not found sub", fileFPath, err)
 		}
 		// 如果有就优先返回
-		if len(subInfoList) >0 {
+		if len(subInfoList) > 0 {
 			return subInfoList, nil
 		}
 	}
@@ -185,7 +185,7 @@ func (s Supplier) whichEpisodeNeedDownloadSub(seriesInfo *series.SeriesInfo, All
 	// key SxEx - SubInfos
 	var allSubDict = make(map[string]SubInfos)
 	// 全季的字幕列表
-	var oneSeasonSubDict  = make(map[string]SubInfos)
+	var oneSeasonSubDict = make(map[string]SubInfos)
 	for _, subInfo := range AllSeasonSubResult.SubInfos {
 		_, season, episode, err := decode.GetSeasonAndEpisodeFromSubFileName(subInfo.Name)
 		if err != nil {
@@ -492,22 +492,23 @@ type SubResult struct {
 }
 
 type SubInfo struct {
-	Name				string	// 字幕的名称
-	Lang				string	// 语言
-	AuthorInfo			string	// 作者
-	Ext					string	// 后缀名
-	Score				float32	// 评分
-	DownloadTimes 		int		// 下载的次数
-	Priority			float32	// 优先级,使用评分和次数乘积而来,类似于 Score 投票
-	DetailUrl			string	// 字幕的详情界面,需要再次分析具体的下载地址,地址需要拼接网站的根地址上去
-	SubDownloadPageUrl 	string	// 字幕的具体的下载页面,会有多个下载可用的链接
-	DownloadUrl			string	// 字幕的下载地址
-	Season    			int		// 第几季,默认-1
-	Episode   			int		// 第几集,默认-1
+	Name               string  // 字幕的名称
+	Lang               string  // 语言
+	AuthorInfo         string  // 作者
+	Ext                string  // 后缀名
+	Score              float32 // 评分
+	DownloadTimes      int     // 下载的次数
+	Priority           float32 // 优先级,使用评分和次数乘积而来,类似于 Score 投票
+	DetailUrl          string  // 字幕的详情界面,需要再次分析具体的下载地址,地址需要拼接网站的根地址上去
+	SubDownloadPageUrl string  // 字幕的具体的下载页面,会有多个下载可用的链接
+	DownloadUrl        string  // 字幕的下载地址
+	Season             int     // 第几季,默认-1
+	Episode            int     // 第几集,默认-1
 }
 
 // SubInfos 实现自定义排序
 type SubInfos []SubInfo
+
 func (s SubInfos) Len() int {
 	return len(s)
 }
@@ -517,7 +518,8 @@ func (s SubInfos) Less(i, j int) bool {
 func (s SubInfos) Swap(i, j int) { s[i], s[j] = s[j], s[i] }
 
 type SortByPriority struct{ SubInfos }
+
 // Less 根据元素的优先级降序排序
 func (s SortByPriority) Less(i, j int) bool {
 	return s.SubInfos[i].Priority > s.SubInfos[j].Priority
-}
+}

+ 1 - 2
internal/logic/sub_supplier/zimuku/zimuku_test.go

@@ -41,7 +41,7 @@ func TestSupplier_GetSubListFromFile(t *testing.T) {
 
 func TestSupplier_GetSubListFromFile4Series(t *testing.T) {
 
-	ser := "X:\\连续剧\\The Bad Batch"	// tt12708542
+	ser := "X:\\连续剧\\The Bad Batch" // tt12708542
 	//ser := "X:\\连续剧\\杀死伊芙 (2018)"	// tt12708542
 	//ser := "X:\\连续剧\\Money.Heist"
 
@@ -60,4 +60,3 @@ func TestSupplier_GetSubListFromFile4Series(t *testing.T) {
 		println(i, sublist.Name, sublist.Ext, sublist.Language.String(), sublist.Score, len(sublist.Data))
 	}
 }
-

+ 1 - 1
internal/models/hotfix.go

@@ -4,6 +4,6 @@ import "gorm.io/gorm"
 
 type HotFix struct {
 	gorm.Model
-	Key string		// Hotfix Key 针对修复的具体问题
+	Key  string // Hotfix Key 针对修复的具体问题
 	Done bool
 }

+ 0 - 1
internal/models/settings.go

@@ -4,5 +4,4 @@ import "gorm.io/gorm"
 
 type Settings struct {
 	gorm.Model
-
 }

+ 6 - 6
internal/pkg/archive_helper/unarchiveFile.go

@@ -53,7 +53,7 @@ func UnArchiveFile(fileFullPath, desRootPath string) error {
 			ContinueOnError:        false,
 			OverwriteExisting:      false,
 			ImplicitTopLevelFolder: false,
-			StripComponents: 1,
+			StripComponents:        1,
 		}
 		err := z.Walk(fileFullPath, func(f archiver.File) error {
 			if f.IsDir() == true {
@@ -61,8 +61,8 @@ func UnArchiveFile(fileFullPath, desRootPath string) error {
 			}
 			err := processOneFile(f, false, desRootPath)
 			if err != nil {
-					return err
-				}
+				return err
+			}
 			return nil
 		})
 		if err != nil {
@@ -74,7 +74,7 @@ func UnArchiveFile(fileFullPath, desRootPath string) error {
 			ContinueOnError:        false,
 			OverwriteExisting:      false,
 			ImplicitTopLevelFolder: false,
-			StripComponents: 1,
+			StripComponents:        1,
 		}
 		err := z.Walk(fileFullPath, func(f archiver.File) error {
 			if f.IsDir() == true {
@@ -166,9 +166,9 @@ func unArr7z(fileFullPath, desRootPath string) error {
 
 func IsWantedArchiveExtName(fileName string) bool {
 	switch strings.ToLower(filepath.Ext(fileName)) {
-	case ".zip", ".tar",".rar", "7z":
+	case ".zip", ".tar", ".rar", "7z":
 		return true
 	default:
 		return false
 	}
-}
+}

+ 1 - 1
internal/pkg/archive_helper/unarchiveFile_test.go

@@ -26,4 +26,4 @@ func TestUnArr(t *testing.T) {
 	if err != nil {
 		t.Fatal(err)
 	}
-}
+}

+ 3 - 3
internal/pkg/config.go

@@ -47,7 +47,7 @@ func readConfig(viper *viper.Viper) (*types.Config, error) {
 	return conf, nil
 }
 
-var(
-	config *types.Config
+var (
+	config     *types.Config
 	configOnce sync.Once
-)
+)

+ 7 - 8
internal/pkg/decode/decode.go

@@ -48,12 +48,12 @@ func getImdbAndYearNfo(nfoFilePath string, rootKey string) (types.VideoIMDBInfo,
 	if err != nil {
 		return imdbInfo, err
 	}
-	for _, t := range doc.FindElements("./" + rootKey +"/title") {
+	for _, t := range doc.FindElements("./" + rootKey + "/title") {
 		imdbInfo.Title = t.Text()
 		break
 	}
 	//---------------------------------------------------------------------
-	for _, t := range doc.FindElements("./" + rootKey +"/imdb_id") {
+	for _, t := range doc.FindElements("./" + rootKey + "/imdb_id") {
 		imdbInfo.ImdbId = t.Text()
 		break
 	}
@@ -70,7 +70,7 @@ func getImdbAndYearNfo(nfoFilePath string, rootKey string) (types.VideoIMDBInfo,
 		break
 	}
 	//---------------------------------------------------------------------
-	for _, t := range doc.FindElements("./" + rootKey +"/year") {
+	for _, t := range doc.FindElements("./" + rootKey + "/year") {
 		imdbInfo.Year = t.Text()
 		break
 	}
@@ -141,7 +141,6 @@ func GetImdbInfo4Movie(movieFileFullPath string) (types.VideoIMDBInfo, error) {
 		return imdbInfo, nil
 	}
 
-
 	if movieXmlFPath != "" {
 		imdbInfo, err = getImdbAndYearMovieXml(movieXmlFPath)
 		if err != nil {
@@ -288,14 +287,14 @@ func GetSeasonAndEpisodeFromSubFileName(videoFileName string) (bool, int, int, e
 		}
 		season, err := GetNumber2int(matched[0][1])
 		if err != nil {
-			return false,0, 0, err
+			return false, 0, 0, err
 		}
 		return true, season, 0, nil
 	} else {
 		// 一集的字幕
 		season, err := GetNumber2int(matched[0][1])
 		if err != nil {
-			return false,0, 0, err
+			return false, 0, 0, err
 		}
 		episode, err := GetNumber2int(matched[0][2])
 		if err != nil {
@@ -312,7 +311,7 @@ func GetNumber2Float(input string) (float32, error) {
 	if len(params) == 0 {
 		return 0, errors.New("get number not match")
 	}
-	fNum, err := strconv.ParseFloat(params[0],32)
+	fNum, err := strconv.ParseFloat(params[0], 32)
 	if err != nil {
 		return 0, errors.New("get number ParseFloat error")
 	}
@@ -343,4 +342,4 @@ const (
 	regFixTitle2 = "[`~!@#$%^&*()+-=|{}';'\\[\\].<>/?~!@#¥%……&*()——+|{}【】';”“’。、?]"
 	// 获取数字
 	regGetNumber = "(?:\\-)?\\d{1,}(?:\\.\\d{1,})?"
-)
+)

+ 4 - 4
internal/pkg/decode/decode_test.go

@@ -5,8 +5,8 @@ import (
 )
 
 func Test_get_IMDB_movie_xml(t *testing.T) {
-    wantid := "tt0993840"
-    wantyear:= "2021"
+	wantid := "tt0993840"
+	wantyear := "2021"
 	dirPth := "x:\\电影\\Army of the Dead (2021)\\movie.xml"
 	imdbInfo, err := getImdbAndYearMovieXml(dirPth)
 	if err != nil {
@@ -22,7 +22,7 @@ func Test_get_IMDB_movie_xml(t *testing.T) {
 
 func Test_get_IMDB_nfo(t *testing.T) {
 	wantid := "tt0993840"
-	wantyear:= "2021"
+	wantyear := "2021"
 	dirPth := "X:\\电影\\Army of the Dead (2021)\\Army of the Dead (2021) WEBDL-1080p.nfo"
 	imdbInfo, err := getImdbAndYearNfo(dirPth, "movie")
 	if err != nil {
@@ -96,4 +96,4 @@ func Test_getImdbAndYearNfo(t *testing.T) {
 	}
 
 	println(nfo.ImdbId, nfo.Year, nfo.ReleaseDate)
-}
+}

+ 8 - 8
internal/pkg/emby_helper/emby.go

@@ -61,12 +61,12 @@ func (em EmbyApi) RefreshRecentlyVideoInfo() error {
 		}()
 
 		select {
-		case err = <- done:
+		case err = <-done:
 			if err != nil {
 				log_helper.GetLogger().Errorln("RefreshRecentlyVideoInfo.NewPoolWithFunc got error", err)
 			}
 			return
-		case p := <- panicChan:
+		case p := <-panicChan:
 			log_helper.GetLogger().Errorln("RefreshRecentlyVideoInfo.NewPoolWithFunc got panic", p)
 		case <-ctx.Done():
 			log_helper.GetLogger().Errorln("RefreshRecentlyVideoInfo.NewPoolWithFunc got time out", ctx.Err())
@@ -121,7 +121,7 @@ func (em EmbyApi) GetItemAncestors(id string) ([]emby.EmbyItemsAncestors, error)
 
 	_, err := em.getNewClient().R().
 		SetQueryParams(map[string]string{
-			"api_key":          em.embyConfig.ApiKey,
+			"api_key": em.embyConfig.ApiKey,
 		}).
 		SetResult(&recItems).
 		Get(em.embyConfig.Url + "/emby_helper/Items/" + id + "/Ancestors")
@@ -139,7 +139,7 @@ func (em EmbyApi) GetItemVideoInfo(id string) (emby.EmbyVideoInfo, error) {
 
 	_, err := em.getNewClient().R().
 		SetQueryParams(map[string]string{
-			"api_key":          em.embyConfig.ApiKey,
+			"api_key": em.embyConfig.ApiKey,
 		}).
 		SetResult(&recItem).
 		Get(em.embyConfig.Url + "/emby_helper/LiveTv/Programs/" + id)
@@ -155,7 +155,7 @@ func (em EmbyApi) UpdateVideoSubList(id string) error {
 
 	_, err := em.getNewClient().R().
 		SetQueryParams(map[string]string{
-			"api_key":          em.embyConfig.ApiKey,
+			"api_key": em.embyConfig.ApiKey,
 		}).
 		Post(em.embyConfig.Url + "/emby_helper/Items/" + id + "/Refresh")
 	if err != nil {
@@ -173,6 +173,6 @@ func (em EmbyApi) getNewClient() *resty.Client {
 }
 
 type InputData struct {
-	Id 				string
-	Wg 				*sync.WaitGroup
-}
+	Id string
+	Wg *sync.WaitGroup
+}

+ 1 - 1
internal/pkg/emby_helper/emby_test.go

@@ -50,4 +50,4 @@ func TestEmbyHelper_UpdateVideoSubList(t *testing.T) {
 	if err != nil {
 		t.Fatal(err)
 	}
-}
+}

+ 3 - 3
internal/pkg/globalvalue.go

@@ -3,7 +3,7 @@ package pkg
 // util.go
 var (
 	defDebugFolder = ""
-	defTmpFolder = ""
-	wantedExtList = make([]string, 0)                   // 人工确认的需要监控的视频后缀名
-	defExtList    = make([]string, 0)                  // 内置支持的视频后缀名列表
+	defTmpFolder   = ""
+	wantedExtList  = make([]string, 0) // 人工确认的需要监控的视频后缀名
+	defExtList     = make([]string, 0) // 内置支持的视频后缀名列表
 )

+ 20 - 14
internal/pkg/hot_fix/hot_fix_001.go

@@ -15,7 +15,7 @@ import (
 	chs_en[shooter] -> Chinese(中英,shooter)
 */
 type HotFix001 struct {
-	movieRootDir string
+	movieRootDir  string
 	seriesRootDir string
 }
 
@@ -27,25 +27,27 @@ func (h HotFix001) GetKey() string {
 	return "001"
 }
 
-func (h HotFix001) Process() (renamedFiles, errFiles []string, err error) {
+func (h HotFix001) Process() (interface{}, error) {
 
-	renamedFiles = make([]string, 0)
-	errFiles = make([]string, 0)
+	var err error
+	outStruct := OutStruct001{}
+	outStruct.RenamedFiles = make([]string, 0)
+	outStruct.ErrFiles = make([]string, 0)
 	if pkg.IsDir(h.movieRootDir) == false {
-		return renamedFiles, errFiles, errors.New("movieRootDir path not exist: " + h.movieRootDir)
+		return outStruct, errors.New("movieRootDir path not exist: " + h.movieRootDir)
 	}
 	if pkg.IsDir(h.seriesRootDir) == false {
-		return renamedFiles, errFiles, errors.New("seriesRootDir path not exist: " + h.seriesRootDir)
+		return outStruct, errors.New("seriesRootDir path not exist: " + h.seriesRootDir)
 	}
 	// 先找出有那些电影文件夹和连续剧文件夹
 	var movieFullPathList = make([]string, 0)
 	movieFullPathList, err = pkg.SearchMatchedVideoFile(h.movieRootDir)
 	if err != nil {
-		return
+		return outStruct, err
 	}
 	seriesDirList, err := seriesHelper.GetSeriesList(h.seriesRootDir)
 	if err != nil {
-		return
+		return outStruct, err
 	}
 	// 搜索所有的字幕,找到相关的字幕进行修改
 	for _, one := range movieFullPathList {
@@ -63,10 +65,10 @@ func (h HotFix001) Process() (renamedFiles, errFiles []string, err error) {
 			}
 			err = os.Rename(fitSubName, newSubFileName)
 			if err != nil {
-				errFiles = append(errFiles, fitSubName)
+				outStruct.ErrFiles = append(outStruct.ErrFiles, fitSubName)
 				continue
 			}
-			renamedFiles = append(renamedFiles, newSubFileName)
+			outStruct.RenamedFiles = append(outStruct.RenamedFiles, newSubFileName)
 		}
 	}
 	// 连续剧
@@ -74,7 +76,7 @@ func (h HotFix001) Process() (renamedFiles, errFiles []string, err error) {
 	for _, oneSeriesDir := range seriesDirList {
 		seriesSubFiles, err = sub_helper.SearchMatchedSubFile(oneSeriesDir)
 		if err != nil {
-			return
+			return outStruct, err
 		}
 		// 判断是否是符合要求
 		for _, fitSubName := range seriesSubFiles {
@@ -84,13 +86,17 @@ func (h HotFix001) Process() (renamedFiles, errFiles []string, err error) {
 			}
 			err = os.Rename(fitSubName, newSubFileName)
 			if err != nil {
-				errFiles = append(errFiles, fitSubName)
+				outStruct.ErrFiles = append(outStruct.ErrFiles, fitSubName)
 				continue
 			}
-			renamedFiles = append(renamedFiles, newSubFileName)
+			outStruct.RenamedFiles = append(outStruct.RenamedFiles, newSubFileName)
 		}
 	}
 
+	return outStruct, nil
+}
 
-	return
+type OutStruct001 struct {
+	RenamedFiles []string
+	ErrFiles     []string
 }

+ 8 - 6
internal/pkg/hot_fix/hot_fix_001_test.go

@@ -27,20 +27,22 @@ func TestHotFix001_Process(t *testing.T) {
 	testSeriesDir := path.Join(testRootDir, seriesDir)
 	// 开始修复
 	hf001 := NewHotFix001(testMovieDir, testSeriesDir)
-	newSubFileName, errFiles, err := hf001.Process()
+	outData, err := hf001.Process()
+	outStruct := outData.(OutStruct001)
 	if err != nil {
-		for _, file := range errFiles {
+		for _, file := range outStruct.ErrFiles {
 			println("rename error:", file)
 		}
 		t.Fatal("Process ", err.Error())
 	}
-	if len(newSubFileName) < 1 {
+
+	if len(outStruct.RenamedFiles) < 1 {
 		t.Fatal("hf001.Process() not file processed")
 	}
 
 	// 检查修复的结果是否符合预期
 	var newSubFileNameMap = make(map[string]int)
-	for i, s := range newSubFileName {
+	for i, s := range outStruct.RenamedFiles {
 		if pkg.IsFile(s) == false {
 			t.Fatal("renamed file not found:", s)
 		}
@@ -54,7 +56,7 @@ func TestHotFix001_Process(t *testing.T) {
 	// 无罪之最 - S01E01 - 重建生活.chs[zimuku].ass
 	// Loki - S01E01 - Glorious Purpose WEBDL-1080p Proper.chs_en[zimuku].srt
 	// Loki - S01E01 - Glorious Purpose WEBDL-1080p Proper.cht_en[shooter].ass
-	var checkResults = []string {
+	var checkResults = []string{
 		"21座桥 (2019) 720p AAC.chinese(简,subhd).ass",
 		"21座桥 (2019) 720p AAC.chinese(简英,zimuku).ass",
 		"无罪之最 - S01E01 - 重建生活.chinese(简,shooter).ass",
@@ -64,7 +66,7 @@ func TestHotFix001_Process(t *testing.T) {
 		"Loki - S01E01 - Glorious Purpose WEBDL-1080p Proper.chinese(繁英,shooter).ass",
 	}
 
-	if len(newSubFileName) != len(checkResults) {
+	if len(outStruct.RenamedFiles) != len(checkResults) {
 		t.Fatal("newSubFileName.len != checkResults.len")
 	}
 

+ 66 - 0
internal/pkg/hot_fix/hot_fix_hub.go

@@ -0,0 +1,66 @@
+package hot_fix
+
+import (
+	"errors"
+	"fmt"
+	"github.com/allanpk716/ChineseSubFinder/internal/dao"
+	"github.com/allanpk716/ChineseSubFinder/internal/ifaces"
+	"github.com/allanpk716/ChineseSubFinder/internal/models"
+	"github.com/allanpk716/ChineseSubFinder/internal/pkg/log_helper"
+	"github.com/allanpk716/ChineseSubFinder/internal/types"
+)
+
+// HotFixProcess 去 DB 中查询 Hotfix 的标记,看有那些需要修复,那些已经修复完毕
+func HotFixProcess(param types.HotFixParam) error {
+
+	// -----------------------------------------------------------------------
+	// 一共有多少个 HotFix 要修复,需要固定下来
+	hotfixCases := []ifaces.IHotFix{
+		NewHotFix001(param.MovieRootDir, param.SeriesRootDir),
+	}
+	// -----------------------------------------------------------------------
+	// 找现在有多少个 hotfix 执行过了
+	var hotFixes []models.HotFix
+	result := dao.GetDb().Find(&hotFixes)
+	if result.Error != nil {
+		return errors.New(fmt.Sprintf("hotfix query all result failed, %s", result.Error))
+	}
+	// 数据库中是否有记录,记录了是否有运行都需要判断
+	var hotFixRecord = make(map[string]models.HotFix)
+	for _, fix := range hotFixes {
+		hotFixRecord[fix.Key] = fix
+	}
+	// 交叉对比,这个执行的顺序又上面 []ifaces.IHotFix 指定
+	for _, hotfixCase := range hotfixCases {
+		_, bFound := hotFixRecord[hotfixCase.GetKey()]
+		if bFound == false {
+			// 没有找到那么就需要进行修复
+			processResult, err := hotfixCase.Process()
+			// 找到对应的 hotfix 方案进行 interface 数据的转换输出
+			switch hotfixCase.GetKey() {
+			case "001":
+				outStruct := processResult.(OutStruct001)
+				if err != nil {
+					for i, file := range outStruct.ErrFiles {
+						log_helper.GetLogger().Errorln("hotfix 001, rename failed,", i, file)
+					}
+					// 如果任意故障则跳出后续的修复
+					log_helper.GetLogger().Errorln("hotfix 001 failed, break")
+					return err
+				}
+				break
+			default:
+				continue
+			}
+			// 执行成功则存入数据库中,标记完成
+			markHotFixDone := models.HotFix{Key: hotfixCase.GetKey(), Done: true}
+			result = dao.GetDb().Create(&markHotFixDone)
+			if result.Error != nil {
+				return errors.New(fmt.Sprintf("hotfix %s is done, but record failed, %s", hotfixCase.GetKey(), result.Error))
+			}
+		}
+		// 找到了,目前的逻辑是成功才插入,那么查询到了,就默认是执行成功了
+	}
+	return nil
+
+}

+ 48 - 0
internal/pkg/hot_fix/hot_fix_hub_test.go

@@ -0,0 +1,48 @@
+package hot_fix
+
+import (
+	"github.com/allanpk716/ChineseSubFinder/internal/dao"
+	"github.com/allanpk716/ChineseSubFinder/internal/models"
+	"github.com/allanpk716/ChineseSubFinder/internal/pkg"
+	"github.com/allanpk716/ChineseSubFinder/internal/types"
+	"path"
+	"testing"
+)
+
+func TestHotFixProcess(t *testing.T) {
+
+	// 先删除 db
+	err := dao.DeleteDbFile()
+	if err != nil {
+		t.Fatal(err)
+	}
+	// 新建 db
+	err = dao.InitDb()
+	if err != nil {
+		t.Fatal(err)
+	}
+	testDataPath := "..\\..\\..\\TestData\\hotfix\\001"
+	movieDir := "movies"
+	seriesDir := "series"
+	testRootDir, err := pkg.CopyTestData(testDataPath)
+	if err != nil {
+		t.Fatal(err)
+	}
+	// 测试文件夹
+	testMovieDir := path.Join(testRootDir, movieDir)
+	testSeriesDir := path.Join(testRootDir, seriesDir)
+	// 开始修复
+	err = HotFixProcess(types.HotFixParam{
+		MovieRootDir:  testMovieDir,
+		SeriesRootDir: testSeriesDir,
+	})
+	if err != nil {
+		t.Fatal(err)
+	}
+	// 判断数据库的标记是否正确
+	hotfixResult := models.HotFix{}
+	result := dao.GetDb().Where("key = ?", "001").First(&hotfixResult)
+	if result.Error != nil {
+		t.Fatal(result.Error)
+	}
+}

+ 1 - 1
internal/pkg/imdb_helper/imdb.go

@@ -20,4 +20,4 @@ func GetVideoInfoFromIMDB(imdbID string, _reqParam ...types.ReqParam) (*imdb.Tit
 	}
 
 	return t, nil
-}
+}

+ 2 - 2
internal/pkg/imdb_helper/imdb_test.go

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

+ 9 - 8
internal/pkg/language/language.go

@@ -136,18 +136,19 @@ func Lang2EmbyName(lan types.Language) string {
 func GetLangOptions() whatlanggo.Options {
 	return whatlanggo.Options{
 		Whitelist: map[whatlanggo.Lang]bool{
-			whatlanggo.Cmn: true,	// 中文	11
-			whatlanggo.Eng: true,	// 英文	15
-			whatlanggo.Jpn: true,	// 日文	32
-			whatlanggo.Kor: true,	// 韩文	37
+			whatlanggo.Cmn: true, // 中文	11
+			whatlanggo.Eng: true, // 英文	15
+			whatlanggo.Jpn: true, // 日文	32
+			whatlanggo.Kor: true, // 韩文	37
 		},
 	}
 }
+
 // IsWhiteListLang 是否是白名单语言
 func IsWhiteListLang(lang whatlanggo.Lang) bool {
 	switch lang {
 	// 中文 英文 日文 韩文
-	case whatlanggo.Cmn, whatlanggo.Eng,whatlanggo.Jpn,whatlanggo.Kor:
+	case whatlanggo.Cmn, whatlanggo.Eng, whatlanggo.Jpn, whatlanggo.Kor:
 		return true
 	default:
 		return false
@@ -207,7 +208,7 @@ func SubLangStatistics2SubLangType(countLineFeed, AllLines float32, langDict map
 			}
 		}
 		// 简体句子的占比超过 80%
-		if float32(isChsCount) / float32(len(chLines)) > 0.8 {
+		if float32(isChsCount)/float32(len(chLines)) > 0.8 {
 			isNoOrChsOrCht = 1
 		} else {
 			isNoOrChsOrCht = 2
@@ -398,6 +399,6 @@ func isDoubleLang(count0, count1 int) bool {
 }
 
 var (
-	chDict = sat.DefaultDict()
+	chDict   = sat.DefaultDict()
 	detector = chardet.NewTextDetector()
-)
+)

+ 2 - 1
internal/pkg/log_helper/loghelper.go

@@ -46,5 +46,6 @@ func GetLogger() *logrus.Logger {
 	})
 	return logger
 }
+
 var logger *logrus.Logger
-var logOnce sync.Once
+var logOnce sync.Once

+ 3 - 3
internal/pkg/notify_center/NotifyCenter.go

@@ -9,8 +9,8 @@ import (
 
 type NotifyCenter struct {
 	webhookUrl string
-	infos map[string]string
-	mu sync.Mutex
+	infos      map[string]string
+	mu         sync.Mutex
 }
 
 func NewNotifyCenter(webhookUrl string) *NotifyCenter {
@@ -49,4 +49,4 @@ func (n *NotifyCenter) Clear() {
 	n.infos = make(map[string]string)
 }
 
-var Notify *NotifyCenter
+var Notify *NotifyCenter

+ 7 - 8
internal/pkg/pass_water_wall/pass_water_wall.go

@@ -34,7 +34,6 @@ func SimulationTest() {
 	//等待缺口圖像載入
 	iframe.MustElement("#slideBg").MustWaitLoad()
 
-
 	//取得帶缺口圖像
 	shadowbg := iframe.MustElement("#slideBg").MustResource()
 	//取得原始圖像
@@ -83,11 +82,11 @@ search:
 		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 {
+			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 {
 				distance += float64(i)
 				fmt.Printf("info: 對比完畢, 偏移量: %v\n", distance)
 				break search
@@ -100,11 +99,11 @@ search:
 	//启用滑鼠功能
 	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)
+	mouse.Move(dragbtnbox.X+distance, dragbtnbox.Y+(dragbtnbox.Height/2), 20)
 	//鬆開滑鼠左鍵, 拖动完毕
 	mouse.MustUp("left")
 	//截圖保存

+ 4 - 4
internal/pkg/random.go

@@ -7,7 +7,7 @@ import (
 )
 
 func RandomSecondDuration(min, max int32) time.Duration {
-	tmp := random.Int31n(max - min) + min
+	tmp := random.Int31n(max-min) + min
 	return time.Duration(tmp) * time.Second
 }
 
@@ -20,8 +20,8 @@ func RandomUserAgent(UserOrSearchEngine bool) string {
 	}
 }
 
-var(
-	random = rand.New(rand.NewSource(time.Now().UnixNano()))
+var (
+	random       = rand.New(rand.NewSource(time.Now().UnixNano()))
 	engineUAList = []string{
 		// 百度搜索User-Agent:
 		// 百度 PC UA
@@ -75,4 +75,4 @@ var(
 		// 雅虎英文UA:
 		"Mozilla/5.0 (compatible; Yahoo! Slurp; http://help.yahoo.com/help/us/ysearch/slurp)",
 	}
-)
+)

+ 1 - 1
internal/pkg/rod_helper/rodHelper.go

@@ -230,7 +230,7 @@ func NewBrowserLoadPageByHijackRequests(desURL string, httpProxyURL string, time
 		})
 	})
 	if err != nil {
-		return nil ,err
+		return nil, err
 	}
 	go router.Run()
 

+ 1 - 1
internal/pkg/rod_helper/rodHelper_test.go

@@ -73,4 +73,4 @@ func TestNewBrowserFromDocker(t *testing.T) {
 	if err != nil {
 		t.Fatal(err)
 	}
-}
+}

+ 2 - 2
internal/pkg/sub_helper/subParserHub.go

@@ -29,7 +29,7 @@ func NewSubParserHub(parser ifaces.ISubParser, _parser ...ifaces.ISubParser) *Su
 }
 
 // DetermineFileTypeFromFile 确定字幕文件的类型,是双语字幕或者某一种语言等等信息,如果返回 nil ,那么就说明都没有字幕的格式匹配上
-func (p SubParserHub) DetermineFileTypeFromFile(filePath string) (*subparser.FileInfo, error){
+func (p SubParserHub) DetermineFileTypeFromFile(filePath string) (*subparser.FileInfo, error) {
 	for _, parser := range p.Parser {
 		subFileInfo, err := parser.DetermineFileTypeFromFile(filePath)
 		if err != nil {
@@ -106,4 +106,4 @@ func IsSubExtWanted(subName string) bool {
 	default:
 		return false
 	}
-}
+}

+ 5 - 5
internal/pkg/sub_helper/sub_helper.go

@@ -42,7 +42,7 @@ func OrganizeDlSubFiles(tmpFolderName string, subInfos []supplier.SubInfo) (map[
 		nowFileSaveFullPath := path.Join(tmpFolderFullPath, GetFrontNameAndOrgName(&subInfos[i]))
 		err = utils.OutputFile(nowFileSaveFullPath, subInfos[i].Data)
 		if err != nil {
-			log_helper.GetLogger().Errorln("getFrontNameAndOrgName - OutputFile",subInfos[i].FromWhere, subInfos[i].Name, subInfos[i].TopN, err)
+			log_helper.GetLogger().Errorln("getFrontNameAndOrgName - OutputFile", subInfos[i].FromWhere, subInfos[i].Name, subInfos[i].TopN, err)
 			continue
 		}
 		nowExt := strings.ToLower(subInfos[i].Ext)
@@ -187,12 +187,12 @@ func GetFrontNameAndOrgName(info *supplier.SubInfo) string {
 	}
 	info.Name = infoName
 
-	return "[" + info.FromWhere + "]_" + strconv.FormatInt(info.TopN,10) + "_" + infoName
+	return "[" + info.FromWhere + "]_" + strconv.FormatInt(info.TopN, 10) + "_" + infoName
 }
 
 // AddFrontName 添加文件的前缀
 func AddFrontName(info supplier.SubInfo, orgName string) string {
-	return "[" + info.FromWhere + "]_" + strconv.FormatInt(info.TopN,10) + "_" + orgName
+	return "[" + info.FromWhere + "]_" + strconv.FormatInt(info.TopN, 10) + "_" + orgName
 }
 
 // SearchMatchedSubFile 搜索符合后缀名的视频文件,排除 Sub_SxE0 这样的文件夹中的文件
@@ -336,6 +336,6 @@ func makeMixSubExtString(orgFileNameWithOutExt, lang string, ext, site string, b
 	return orgFileNameWithOutExt + types.Emby_chinese + "(" + lang + "," + site + ")" + tmpDefault + ext
 }
 
-var(
+var (
 	regOneSeasonSubFolderNameMatch = regexp.MustCompile(`(?m)^Sub_S\dE0`)
-)
+)

+ 1 - 1
internal/pkg/sub_helper/sub_helper_test.go

@@ -33,4 +33,4 @@ func TestIsOldVersionSubPrefixName(t *testing.T) {
 			}
 		})
 	}
-}
+}

+ 6 - 5
internal/pkg/util.go

@@ -55,7 +55,7 @@ func NewHttpClient(_reqParam ...types.ReqParam) *resty.Client {
 
 	httpClient.SetHeaders(map[string]string{
 		"Content-Type": "application/json",
-		"User-Agent": UserAgent,
+		"User-Agent":   UserAgent,
 	})
 	if len(Referer) > 0 {
 		httpClient.SetHeader("Referer", Referer)
@@ -65,7 +65,7 @@ func NewHttpClient(_reqParam ...types.ReqParam) *resty.Client {
 }
 
 // DownFile 从指定的 url 下载文件
-func DownFile(urlStr string, _reqParam ...types.ReqParam) ([]byte, string, error)  {
+func DownFile(urlStr string, _reqParam ...types.ReqParam) ([]byte, string, error) {
 	var reqParam types.ReqParam
 	if len(_reqParam) > 0 {
 		reqParam = _reqParam[0]
@@ -168,7 +168,7 @@ func GetTmpFolder(folderName string) (string, error) {
 	if err != nil {
 		return "", err
 	}
-	tmpFolderFullPath :=path.Join(rootPath, folderName)
+	tmpFolderFullPath := path.Join(rootPath, folderName)
 	err = os.MkdirAll(tmpFolderFullPath, os.ModePerm)
 	if err != nil {
 		return "", err
@@ -221,6 +221,7 @@ func IsDir(path string) bool {
 	}
 	return s.IsDir()
 }
+
 // IsFile 存在且是文件
 func IsFile(filePath string) bool {
 	s, err := os.Stat(filePath)
@@ -298,7 +299,7 @@ func IsWantedVideoExtDef(fileName string) bool {
 }
 
 func GetEpisodeKeyName(season, eps int) string {
-	return "S" + strconv.Itoa(season) + "E" +strconv.Itoa(eps)
+	return "S" + strconv.Itoa(season) + "E" + strconv.Itoa(eps)
 }
 
 // ReloadBrowser 提前把浏览器下载好
@@ -388,4 +389,4 @@ func CopyTestData(srcDir string) (string, error) {
 		return "", err
 	}
 	return testDir, nil
-}
+}

+ 4 - 4
internal/types/config.go

@@ -5,11 +5,11 @@ import "github.com/allanpk716/ChineseSubFinder/internal/types/emby"
 type Config struct {
 	UseProxy                      bool
 	HttpProxy                     string
-	EveryTime                     string		// 一轮扫描字幕下载的间隔时间
+	EveryTime                     string // 一轮扫描字幕下载的间隔时间
 	DebugMode                     bool
-	Threads                       int			// 同时并发的线程数(准确来说在go中不是线程,是 goroutine)
-	SubTypePriority               int	// 字幕下载的优先级,0 是自动,1 是 srt 优先,2 是 ass/ssa 优先
-	WhenSubSupplierInvalidWebHook string			// 当字幕网站失效的时候,触发的 webhook 地址,默认是 get
+	Threads                       int    // 同时并发的线程数(准确来说在go中不是线程,是 goroutine)
+	SubTypePriority               int    // 字幕下载的优先级,0 是自动,1 是 srt 优先,2 是 ass/ssa 优先
+	WhenSubSupplierInvalidWebHook string // 当字幕网站失效的时候,触发的 webhook 地址,默认是 get
 	EmbyConfig                    emby.EmbyConfig
 	SaveMultiSub                  bool
 	MovieFolder                   string

+ 3 - 3
internal/types/emby/config.go

@@ -1,7 +1,7 @@
 package emby
 
 type EmbyConfig struct {
-	Url			string 		//	Emby 的地址,需要带上端口号 http://192.168.1.2:8089
-	ApiKey		string		//	相应的 API Key
-	LimitCount		int		//	最多获取多少更新的内容
+	Url        string //	Emby 的地址,需要带上端口号 http://192.168.1.2:8089
+	ApiKey     string //	相应的 API Key
+	LimitCount int    //	最多获取多少更新的内容
 }

+ 22 - 20
internal/types/emby/type.go

@@ -7,31 +7,31 @@ import (
 
 type EmbyRecentlyItems struct {
 	Items []struct {
-		Name                string   `json:"Name,omitempty"`
-		Id                  string   `json:"Id,omitempty"`
-		IndexNumber         int      `json:"IndexNumber,omitempty"`
-		ParentIndexNumber   int      `json:"ParentIndexNumber,omitempty"`
-		Type        		string   `json:"Type,omitempty"`
-		SeriesName          string   `json:"SeriesName,omitempty"`
+		Name              string `json:"Name,omitempty"`
+		Id                string `json:"Id,omitempty"`
+		IndexNumber       int    `json:"IndexNumber,omitempty"`
+		ParentIndexNumber int    `json:"ParentIndexNumber,omitempty"`
+		Type              string `json:"Type,omitempty"`
+		SeriesName        string `json:"SeriesName,omitempty"`
 	} `json:"Items,omitempty"`
 	TotalRecordCount int `json:"TotalRecordCount,omitempty"`
 }
 
 type EmbyItemsAncestors struct {
-	Name                    string `json:"Name,omitempty"`
-	Path                    string `json:"Path,omitempty"`
-	Type                    string `json:"Type,omitempty"`
+	Name string `json:"Name,omitempty"`
+	Path string `json:"Path,omitempty"`
+	Type string `json:"Type,omitempty"`
 }
 
 type EmbyVideoInfo struct {
-	Name                         string    `json:"Name,omitempty"`
-	OriginalTitle                string    `json:"OriginalTitle,omitempty"`
-	Id                           string    `json:"Id,omitempty"`
-	DateCreated                  time.Time `json:"DateCreated,omitempty"`
-	PremiereDate				 time.Time `json:"PremiereDate,omitempty"`
-	SortName                     string    `json:"SortName,omitempty"`
-	Path                		 string   `json:"Path"`
-	MediaStreams []struct {
+	Name          string    `json:"Name,omitempty"`
+	OriginalTitle string    `json:"OriginalTitle,omitempty"`
+	Id            string    `json:"Id,omitempty"`
+	DateCreated   time.Time `json:"DateCreated,omitempty"`
+	PremiereDate  time.Time `json:"PremiereDate,omitempty"`
+	SortName      string    `json:"SortName,omitempty"`
+	Path          string    `json:"Path"`
+	MediaStreams  []struct {
 		Codec                  string `json:"Codec"`
 		Language               string `json:"Language"`
 		DisplayTitle           string `json:"DisplayTitle"`
@@ -45,18 +45,20 @@ type EmbyVideoInfo struct {
 }
 
 type EmbyMixInfo struct {
-	VideoFolderName       string			// 电影就是电影的文件夹名称,连续剧就是对应的剧集的 root 文件夹
-	VideoFileName         string			// 视频文件名
-	VideoFileRelativePath string	// 视频文件的相对路径(注意,这里还是需要补齐 x:/电影 这样的 root 路径的,仅仅算相对路径)
+	VideoFolderName       string // 电影就是电影的文件夹名称,连续剧就是对应的剧集的 root 文件夹
+	VideoFileName         string // 视频文件名
+	VideoFileRelativePath string // 视频文件的相对路径(注意,这里还是需要补齐 x:/电影 这样的 root 路径的,仅仅算相对路径)
 	VideoFileFullPath     string
 	Ancestors             []EmbyItemsAncestors
 	VideoInfo             EmbyVideoInfo
 }
 
 type Time time.Time
+
 const (
 	embyTimeFormart = "2006-01-02T15:04:05"
 )
+
 func (t *Time) UnmarshalJSON(data []byte) (err error) {
 
 	orgString := string(data)

+ 6 - 0
internal/types/hotfix.go

@@ -0,0 +1,6 @@
+package types
+
+type HotFixParam struct {
+	MovieRootDir  string
+	SeriesRootDir string
+}

+ 19 - 19
internal/types/language.go

@@ -2,11 +2,12 @@ package types
 
 const (
 	SubNameKeywordChineseSimple = "chs"
-	SubNameKeywordTraditional	 = "cht"
+	SubNameKeywordTraditional   = "cht"
 )
 
 // Language 语言类型,注意,这里默认还是查找的是中文字幕,只不过下载的时候可能附带了其他的
 type Language int
+
 const (
 	Unknow                     Language = iota // 未知语言
 	ChineseSimple                              // 简体中文
@@ -22,25 +23,24 @@ const (
 	ChineseTraditionalKorean                   // 繁韩双语字幕
 )
 
-
 // 需要符合 emby_helper 的格式要求,在后缀名前面
 const (
-	Emby_default = ".default"				// 指定这个字幕是默认的
-	Emby_unknow = ".unknow"					// 未知语言
-	Emby_chinese 	= ".chinese"			// 中文
-	Emby_chi 	= ".chi"					// 简体
-	Emby_chn 	= ".chn"					// 中国国家代码
-	Emby_chs 	= ".chs"					// 简体
-	Emby_cht 	= ".cht"					// 繁体
-	Emby_chs_en = ".chs_en"                 // 简英双语字幕
-	Emby_cht_en = ".cht_en"                	// 繁英双语字幕
-	Emby_en 	= ".en"                     // 英文
-	Emby_jp 	= ".jp"						// 日语
-	Emby_chs_jp = ".chs_jp"                 // 简日双语字幕
-	Emby_cht_jp = ".cht_jp"                	// 繁日双语字幕
-	Emby_kr 	= ".kr"                     // 韩语
-	Emby_chs_kr = ".chs_kr"                 // 简韩双语字幕
-	Emby_cht_kr = ".cht_kr"                	// 繁韩双语字幕
+	Emby_default = ".default" // 指定这个字幕是默认的
+	Emby_unknow  = ".unknow"  // 未知语言
+	Emby_chinese = ".chinese" // 中文
+	Emby_chi     = ".chi"     // 简体
+	Emby_chn     = ".chn"     // 中国国家代码
+	Emby_chs     = ".chs"     // 简体
+	Emby_cht     = ".cht"     // 繁体
+	Emby_chs_en  = ".chs_en"  // 简英双语字幕
+	Emby_cht_en  = ".cht_en"  // 繁英双语字幕
+	Emby_en      = ".en"      // 英文
+	Emby_jp      = ".jp"      // 日语
+	Emby_chs_jp  = ".chs_jp"  // 简日双语字幕
+	Emby_cht_jp  = ".cht_jp"  // 繁日双语字幕
+	Emby_kr      = ".kr"      // 韩语
+	Emby_chs_kr  = ".chs_kr"  // 简韩双语字幕
+	Emby_cht_kr  = ".cht_kr"  // 繁韩双语字幕
 )
 
 const (
@@ -86,4 +86,4 @@ func (l Language) String() string {
 	default:
 		return MathLangChnUnknow
 	}
-}
+}

+ 16 - 16
internal/types/reqparam.go

@@ -4,27 +4,27 @@ import "github.com/allanpk716/ChineseSubFinder/internal/types/emby"
 
 // ReqParam 可选择传入的参数
 type ReqParam struct {
-	UserExtList                   []string	// 用户确认的视频后缀名支持列表
-	SaveMultiSub                  bool		// 存储每个网站 Top1 的字幕
-	DebugMode                     bool			// 调试标志位
-	Threads                       int			// 同时并发的线程数(准确来说在go中不是线程,是 goroutine)
-	SubTypePriority               int	// 字幕下载的优先级,0 是自动,1 是 srt 优先,2 是 ass/ssa 优先
-	WhenSubSupplierInvalidWebHook string			// 当字幕网站失效的时候,触发的 webhook 地址,默认是 get
+	UserExtList                   []string // 用户确认的视频后缀名支持列表
+	SaveMultiSub                  bool     // 存储每个网站 Top1 的字幕
+	DebugMode                     bool     // 调试标志位
+	Threads                       int      // 同时并发的线程数(准确来说在go中不是线程,是 goroutine)
+	SubTypePriority               int      // 字幕下载的优先级,0 是自动,1 是 srt 优先,2 是 ass/ssa 优先
+	WhenSubSupplierInvalidWebHook string   // 当字幕网站失效的时候,触发的 webhook 地址,默认是 get
 	EmbyConfig                    emby.EmbyConfig
-	HttpProxy                     string		// HttpClient 相关
-	UserAgent                     string		// HttpClient 相关
-	Referer                       string		// HttpClient 相关
-	MediaType                     string		// HttpClient 相关
-	Charset                       string		// HttpClient 相关
-	Topic                         int			// 搜索结果的时候,返回 Topic N 以内的
+	HttpProxy                     string // HttpClient 相关
+	UserAgent                     string // HttpClient 相关
+	Referer                       string // HttpClient 相关
+	MediaType                     string // HttpClient 相关
+	Charset                       string // HttpClient 相关
+	Topic                         int    // 搜索结果的时候,返回 Topic N 以内的
 }
 
 func NewReqParam() *ReqParam {
 	r := ReqParam{
-		UserExtList: make([]string, 0),
-		SaveMultiSub: false,
-		DebugMode: false,
-		Threads: 2,
+		UserExtList:     make([]string, 0),
+		SaveMultiSub:    false,
+		DebugMode:       false,
+		Threads:         2,
 		SubTypePriority: 0,
 	}
 	return &r

+ 4 - 4
internal/types/series/info.go

@@ -13,7 +13,7 @@ type SeriesInfo struct {
 	ImdbId           string
 	Name             string
 	Year             int
-	ReleaseDate 	 string
+	ReleaseDate      string
 	EpList           []EpisodeInfo
 	DirPath          string
 	SeasonDict       map[int]int
@@ -29,7 +29,7 @@ type EpisodeInfo struct {
 	Dir                      string    // 这里需要记录字幕的位置,因为需要在同级目录匹配相应的字幕才行
 	FileFullPath             string    // 视频文件的全路径
 	ModifyTime               time.Time // 创建时间
-	AiredTime				 string   // 播出的时间
+	AiredTime                string    // 播出的时间
 }
 
 type SubInfo struct {
@@ -37,6 +37,6 @@ type SubInfo struct {
 	Season       int
 	Episode      int
 	Language     types.Language
-	Dir          string	// 这里需要记录字幕的位置,因为需要在同级目录匹配相应的视频才行
-	FileFullPath string 	// 字幕文件的全路径
+	Dir          string // 这里需要记录字幕的位置,因为需要在同级目录匹配相应的视频才行
+	FileFullPath string // 字幕文件的全路径
 }

+ 4 - 4
internal/types/subparser/fileinfo.go

@@ -14,8 +14,8 @@ type FileInfo struct {
 
 // OneDialogue 一句对话
 type OneDialogue struct {
-	StartTime string		// 开始时间
-	EndTime string			// 结束时间
-	StyleName	string			// StyleName
-	Lines	[]string		// 台词
+	StartTime string   // 开始时间
+	EndTime   string   // 结束时间
+	StyleName string   // StyleName
+	Lines     []string // 台词
 }

+ 1 - 1
internal/types/supplier/subinfo.go

@@ -20,7 +20,7 @@ type SubInfo struct {
 func NewSubInfo(fromWhere string, topN int64, name string, language types.Language, fileUrl string,
 	score int64, offset int64, ext string, data []byte) *SubInfo {
 
-	s := SubInfo{FromWhere: fromWhere, TopN: topN,Name: name, Language: language, FileUrl: fileUrl,
+	s := SubInfo{FromWhere: fromWhere, TopN: topN, Name: name, Language: language, FileUrl: fileUrl,
 		Score: score, Offset: offset, Ext: ext, Data: data}
 
 	s.Season = -1

+ 5 - 5
internal/types/videoInfo.go

@@ -2,10 +2,10 @@ package types
 
 // VideoIMDBInfo 从 movie.xml *.nfo 中解析出的视频信息
 type VideoIMDBInfo struct {
-	ImdbId string
-	TVdbId string
-	Year string
-	Title string
+	ImdbId        string
+	TVdbId        string
+	Year          string
+	Title         string
 	OriginalTitle string
-	ReleaseDate string
+	ReleaseDate   string
 }

+ 24 - 11
main.go

@@ -2,6 +2,7 @@ package main
 
 import (
 	"github.com/allanpk716/ChineseSubFinder/internal"
+	"github.com/allanpk716/ChineseSubFinder/internal/dao"
 	"github.com/allanpk716/ChineseSubFinder/internal/pkg"
 	"github.com/allanpk716/ChineseSubFinder/internal/pkg/log_helper"
 	"github.com/allanpk716/ChineseSubFinder/internal/pkg/notify_center"
@@ -35,7 +36,19 @@ func main() {
 		log.Errorln("SeriesFolder not found")
 		return
 	}
+	// ------ 数据库相关操作 Start ------
+	err := dao.InitDb()
+	if err != nil {
+		log.Errorln("dao.InitDb()", err)
+		return
+	}
+	// ------ 数据库相关操作 End ------
+
+	// ------ Hot Fix Start ------
+
+	// ------ Hot Fix End ------
 
+	// 初始化通知缓存模块
 	notify_center.Notify = notify_center.NewNotifyCenter(config.WhenSubSupplierInvalidWebHook)
 
 	log.Infoln("MovieFolder:", config.MovieFolder)
@@ -44,10 +57,10 @@ func main() {
 	// ReloadBrowser 提前把浏览器下载好
 	pkg.ReloadBrowser()
 
-	//任务还没执行完,下一次执行时间到来,下一次执行就跳过不执行
+	// 任务还没执行完,下一次执行时间到来,下一次执行就跳过不执行
 	c := cron.New(cron.WithChain(cron.SkipIfStillRunning(cron.DefaultLogger)))
 	// 定时器
-	entryID, err := c.AddFunc("@every " + config.EveryTime, func() {
+	entryID, err := c.AddFunc("@every "+config.EveryTime, func() {
 
 		DownLoadStart(httpProxy)
 	})
@@ -75,13 +88,13 @@ func DownLoadStart(httpProxy string) {
 
 	// 下载实例
 	downloader := internal.NewDownloader(types.ReqParam{
-		HttpProxy:       httpProxy,
-		DebugMode:       config.DebugMode,
-		SaveMultiSub:    config.SaveMultiSub,
-		Threads:         config.Threads,
-		SubTypePriority: config.SubTypePriority,
+		HttpProxy:                     httpProxy,
+		DebugMode:                     config.DebugMode,
+		SaveMultiSub:                  config.SaveMultiSub,
+		Threads:                       config.Threads,
+		SubTypePriority:               config.SubTypePriority,
 		WhenSubSupplierInvalidWebHook: config.WhenSubSupplierInvalidWebHook,
-		EmbyConfig: config.EmbyConfig,
+		EmbyConfig:                    config.EmbyConfig,
 	})
 
 	log.Infoln("Download One Started...")
@@ -117,7 +130,7 @@ func DownLoadStart(httpProxy string) {
 	}
 }
 
-var(
-	log         *logrus.Logger
-	config      *types.Config
+var (
+	log    *logrus.Logger
+	config *types.Config
 )