Pārlūkot izejas kodu

重构项目结构

Signed-off-by: allan716 <[email protected]>
allan716 4 gadi atpakaļ
vecāks
revīzija
1e14cc2bea
71 mainītis faili ar 836 papildinājumiem un 784 dzēšanām
  1. 4 4
      .gitignore
  2. 0 8
      common/VideoType.go
  3. 0 16
      common/config.go
  4. 0 29
      common/reqParam.go
  5. 0 28
      common/supplierSubInfo.go
  6. 62 58
      downloader.go
  7. 8 8
      downloader_test.go
  8. 0 12
      interface/iSubParser.go
  9. 0 16
      interface/iSupplier.go
  10. 0 0
      internal/common/constvalue.go
  11. 0 0
      internal/common/selferr.go
  12. 0 0
      internal/common/subtypes.go
  13. 0 0
      internal/common/urls.go
  14. 8 0
      internal/common/videotype.go
  15. 14 0
      internal/interface/iSubParser.go
  16. 20 0
      internal/interface/iSupplier.go
  17. 0 0
      internal/logic/charset/charset.go
  18. 0 0
      internal/logic/charset/charset_test.go
  19. 38 36
      internal/logic/emby_helper/embyhelper.go
  20. 5 5
      internal/logic/emby_helper/embyhelper_test.go
  21. 23 23
      internal/logic/mark_system/markingsystem.go
  22. 32 30
      internal/logic/movie_helper/moviehelper.go
  23. 63 59
      internal/logic/series_helper/seriesHelper.go
  24. 0 0
      internal/logic/series_helper/seriesHelper_test.go
  25. 12 11
      internal/logic/sub_parser/ass/ass.go
  26. 0 0
      internal/logic/sub_parser/ass/ass_test.go
  27. 12 11
      internal/logic/sub_parser/srt/srt.go
  28. 0 0
      internal/logic/sub_parser/srt/srt_test.go
  29. 26 23
      internal/logic/sub_supplier/shooter/shooter.go
  30. 2 2
      internal/logic/sub_supplier/shooter/shooter_test.go
  31. 23 22
      internal/logic/sub_supplier/subSupplierHub.go
  32. 0 0
      internal/logic/sub_supplier/subhd/.rod.backup
  33. 54 51
      internal/logic/sub_supplier/subhd/subhd.go
  34. 2 2
      internal/logic/sub_supplier/subhd/subhd_test.go
  35. 30 27
      internal/logic/sub_supplier/xunlei/xunlei.go
  36. 2 2
      internal/logic/sub_supplier/xunlei/xunlei_test.go
  37. 55 52
      internal/logic/sub_supplier/zimuku/zimuku.go
  38. 2 2
      internal/logic/sub_supplier/zimuku/zimuku_test.go
  39. 1 1
      internal/pkg/NotifyCenter.go
  40. 1 1
      internal/pkg/NotifyCenter_test.go
  41. 4 4
      internal/pkg/config.go
  42. 4 4
      internal/pkg/deal_sub.go
  43. 21 20
      internal/pkg/decode.go
  44. 1 1
      internal/pkg/decode_test.go
  45. 16 15
      internal/pkg/emby.go
  46. 3 3
      internal/pkg/emby_test.go
  47. 9 0
      internal/pkg/globalvalue.go
  48. 4 4
      internal/pkg/imdb.go
  49. 1 1
      internal/pkg/imdb_test.go
  50. 105 105
      internal/pkg/language.go
  51. 1 1
      internal/pkg/loghelper.go
  52. 1 1
      internal/pkg/pass_water_wall.go
  53. 1 1
      internal/pkg/pass_water_wall_test.go
  54. 1 1
      internal/pkg/random.go
  55. 1 1
      internal/pkg/rodHelper.go
  56. 1 1
      internal/pkg/rodHelper_test.go
  57. 12 11
      internal/pkg/subParserHub.go
  58. 12 10
      internal/pkg/sub_helper.go
  59. 1 1
      internal/pkg/unarchiveFile.go
  60. 1 1
      internal/pkg/unarchiveFile_test.go
  61. 19 25
      internal/pkg/util.go
  62. 18 0
      internal/types/config.go
  63. 1 1
      internal/types/emby/config.go
  64. 6 6
      internal/types/emby/type.go
  65. 1 1
      internal/types/language.go
  66. 31 0
      internal/types/reqparam.go
  67. 12 9
      internal/types/series/info.go
  68. 5 3
      internal/types/subparser/fileinfo.go
  69. 30 0
      internal/types/supplier/subinfo.go
  70. 1 1
      internal/types/videoInfo.go
  71. 13 13
      main.go

+ 4 - 4
.gitignore

@@ -1,5 +1,5 @@
 /.idea
-/sub_supplier/subhd/result.png
+/internal/logic/sub_supplier/subhd/result.png
 /common/result.png
 /result.png
 /Logs
@@ -11,9 +11,9 @@
 /ChineseSubFinder.exe
 /*.zip
 /*.rar
-/sub_supplier/subhd/Logs
+/internal/logic/sub_supplier/subhd/Logs
 /model/config.yaml
-/sub_supplier/zimuku/Logs
+/internal/logic/sub_supplier/zimuku/Logs
 /dist
-/emby_helper/config.yaml
+/internal/logic/emby_helper/config.yaml
 /emby_helper/Logs/*.log

+ 0 - 8
common/VideoType.go

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

+ 0 - 16
common/config.go

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

+ 0 - 29
common/reqParam.go

@@ -1,29 +0,0 @@
-package common
-
-// 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
-	EmbyConfig 		EmbyConfig
-	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,
-		SubTypePriority: 0,
-	}
-	return &r
-}

+ 0 - 28
common/supplierSubInfo.go

@@ -1,28 +0,0 @@
-package common
-
-type SupplierSubInfo struct {
-	FromWhere string         `json:"from_where"` // 从哪个网站下载来的
-	TopN      int64          `json:"top_n"`      // 是 Top 几?
-	Name      string         `json:"name"`       // 字幕的名称,这个比较随意,优先是影片的名称,然后才是从网上下载字幕的对应名称
-	Language  Language 		 `json:"language"`   // 字幕的语言
-	FileUrl   string         `json:"file-url"`   // 字幕文件下载的路径
-	Score     int64          `json:"score"`      // TODO 字幕的评分,需要有一个独立的评价体系。首先是每个网站自己的评价排序,然后再到统一的评分体系
-	Offset    int64          `json:"offset"`     // 字幕的偏移
-	Ext       string         `json:"ext"`        // 字幕文件的后缀名带点,有可能是直接能用的字幕文件,也可能是压缩包
-	Data      []byte         `json:"data"`       // 字幕文件的二进制数据
-	Season    int			 `json:"season"`     // 第几季,默认-1
-	Episode   int			 `json:"episode"`    // 第几集,默认-1
-	IsFullSeason bool		 `json:"is_full_season"`    // 是否是全季的字幕
-}
-
-func NewSupplierSubInfo(fromWhere string, topN int64, name string, language Language, fileUrl string,
-	score int64, offset int64, ext string, data []byte) *SupplierSubInfo {
-
-	s := SupplierSubInfo{FromWhere: fromWhere, TopN: topN,Name: name, Language: language, FileUrl: fileUrl,
-		Score: score, Offset: offset, Ext: ext, Data: data}
-
-	s.Season = -1
-	s.Episode = -1
-
-	return &s
-}

+ 62 - 58
downloader.go

@@ -1,16 +1,20 @@
 package main
 
 import (
-	"github.com/allanpk716/ChineseSubFinder/common"
-	"github.com/allanpk716/ChineseSubFinder/emby_helper"
-	"github.com/allanpk716/ChineseSubFinder/mark_system"
-	"github.com/allanpk716/ChineseSubFinder/model"
-	"github.com/allanpk716/ChineseSubFinder/series_helper"
-	"github.com/allanpk716/ChineseSubFinder/sub_supplier"
-	"github.com/allanpk716/ChineseSubFinder/sub_supplier/shooter"
-	"github.com/allanpk716/ChineseSubFinder/sub_supplier/subhd"
-	"github.com/allanpk716/ChineseSubFinder/sub_supplier/xunlei"
-	"github.com/allanpk716/ChineseSubFinder/sub_supplier/zimuku"
+	common2 "github.com/allanpk716/ChineseSubFinder/internal/common"
+	emby_helper2 "github.com/allanpk716/ChineseSubFinder/internal/logic/emby_helper"
+	mark_system2 "github.com/allanpk716/ChineseSubFinder/internal/logic/mark_system"
+	series_helper2 "github.com/allanpk716/ChineseSubFinder/internal/logic/series_helper"
+	sub_supplier2 "github.com/allanpk716/ChineseSubFinder/internal/logic/sub_supplier"
+	shooter2 "github.com/allanpk716/ChineseSubFinder/internal/logic/sub_supplier/shooter"
+	subhd2 "github.com/allanpk716/ChineseSubFinder/internal/logic/sub_supplier/subhd"
+	xunlei2 "github.com/allanpk716/ChineseSubFinder/internal/logic/sub_supplier/xunlei"
+	zimuku2 "github.com/allanpk716/ChineseSubFinder/internal/logic/sub_supplier/zimuku"
+	"github.com/allanpk716/ChineseSubFinder/internal/pkg"
+	"github.com/allanpk716/ChineseSubFinder/internal/types"
+	"github.com/allanpk716/ChineseSubFinder/internal/types/emby"
+	"github.com/allanpk716/ChineseSubFinder/internal/types/series"
+	"github.com/allanpk716/ChineseSubFinder/internal/types/subparser"
 	"github.com/go-rod/rod/lib/utils"
 	"github.com/panjf2000/ants/v2"
 	"github.com/sirupsen/logrus"
@@ -24,20 +28,20 @@ import (
 
 // Downloader 实例化一次用一次,不要反复的使用,很多临时标志位需要清理。
 type Downloader struct {
-	reqParam      common.ReqParam
-	log           *logrus.Logger
-	topic         int                        // 最多能够下载 Top 几的字幕,每一个网站
-	mk            *mark_system.MarkingSystem // MarkingSystem
-	embyHelper	  *emby_helper.EmbyHelper
-	movieDirList  []string									//  多个需要搜索字幕的电影目录
-	seriesSubNeedDlMap map[string][]common.EmbyMixInfo		//  多个需要搜索字幕的连续剧目录
+	reqParam           types.ReqParam
+	log                *logrus.Logger
+	topic              int                         // 最多能够下载 Top 几的字幕,每一个网站
+	mk                 *mark_system2.MarkingSystem // MarkingSystem
+	embyHelper         *emby_helper2.EmbyHelper
+	movieDirList       []string                           //  多个需要搜索字幕的电影目录
+	seriesSubNeedDlMap map[string][]emby.EmbyMixInfo //  多个需要搜索字幕的连续剧目录
 }
 
-func NewDownloader(_reqParam ...common.ReqParam) *Downloader {
+func NewDownloader(_reqParam ...types.ReqParam) *Downloader {
 
 	var downloader Downloader
-	downloader.log = model.GetLogger()
-	downloader.topic = common.DownloadSubsPerSite
+	downloader.log = pkg.GetLogger()
+	downloader.topic = common2.DownloadSubsPerSite
 	if len(_reqParam) > 0 {
 		downloader.reqParam = _reqParam[0]
 		if downloader.reqParam.Topic > 0 && downloader.reqParam.Topic != downloader.topic {
@@ -51,22 +55,22 @@ func NewDownloader(_reqParam ...common.ReqParam) *Downloader {
 		}
 		// 初始化 Emby API 接口
 		if downloader.reqParam.EmbyConfig.Url != "" && downloader.reqParam.EmbyConfig.ApiKey != "" {
-			downloader.embyHelper = emby_helper.NewEmbyHelper(downloader.reqParam.EmbyConfig)
+			downloader.embyHelper = emby_helper2.NewEmbyHelper(downloader.reqParam.EmbyConfig)
 		}
 	} else {
-		downloader.reqParam = *common.NewReqParam()
+		downloader.reqParam = *types.NewReqParam()
 	}
 
 	var sitesSequence = make([]string, 0)
 	// TODO 这里写固定了抉择字幕的顺序
-	sitesSequence = append(sitesSequence, common.SubSiteZiMuKu)
-	sitesSequence = append(sitesSequence, common.SubSiteSubHd)
-	sitesSequence = append(sitesSequence, common.SubSiteXunLei)
-	sitesSequence = append(sitesSequence, common.SubSiteShooter)
-	downloader.mk = mark_system.NewMarkingSystem(sitesSequence, downloader.reqParam.SubTypePriority)
+	sitesSequence = append(sitesSequence, common2.SubSiteZiMuKu)
+	sitesSequence = append(sitesSequence, common2.SubSiteSubHd)
+	sitesSequence = append(sitesSequence, common2.SubSiteXunLei)
+	sitesSequence = append(sitesSequence, common2.SubSiteShooter)
+	downloader.mk = mark_system2.NewMarkingSystem(sitesSequence, downloader.reqParam.SubTypePriority)
 
 	downloader.movieDirList = make([]string, 0)
-	downloader.seriesSubNeedDlMap = make(map[string][]common.EmbyMixInfo)
+	downloader.seriesSubNeedDlMap = make(map[string][]emby.EmbyMixInfo)
 
 	return &downloader
 }
@@ -77,7 +81,7 @@ func (d *Downloader) GetUpdateVideoListFromEmby(movieRootDir, seriesRootDir stri
 		return nil
 	}
 	var err error
-	var moviveList []common.EmbyMixInfo
+	var moviveList []emby.EmbyMixInfo
 	moviveList, d.seriesSubNeedDlMap, err = d.embyHelper.GetRecentlyAddVideoList(movieRootDir, seriesRootDir)
 	if err != nil {
 		return err
@@ -114,7 +118,7 @@ func (d Downloader) RefreshEmbySubList() error {
 func (d Downloader) DownloadSub4Movie(dir string) error {
 	defer func() {
 		// 所有的电影字幕下载完成,抉择完成,需要清理缓存目录
-		err := model.ClearRootTmpFolder()
+		err := pkg.ClearRootTmpFolder()
 		if err != nil {
 			d.log.Error("ClearRootTmpFolder", err)
 		}
@@ -125,7 +129,7 @@ func (d Downloader) DownloadSub4Movie(dir string) error {
 	// 是否是通过 emby api 获取的列表
 	if d.embyHelper == nil {
 		// 没有填写 emby api 的信息,那么就走常规的全文件扫描流程
-		d.movieDirList, err = model.SearchMatchedVideoFile(dir)
+		d.movieDirList, err = pkg.SearchMatchedVideoFile(dir)
 		if err != nil {
 			return err
 		}
@@ -142,11 +146,11 @@ func (d Downloader) DownloadSub4Movie(dir string) error {
 		inData := i.(InputData)
 		// -----------------------------------------------------
 		// 构建每个字幕站点下载者的实例
-		var subSupplierHub = sub_supplier.NewSubSupplierHub(
-			subhd.NewSupplier(d.reqParam),
-			zimuku.NewSupplier(d.reqParam),
-			xunlei.NewSupplier(d.reqParam),
-			shooter.NewSupplier(d.reqParam),
+		var subSupplierHub = sub_supplier2.NewSubSupplierHub(
+			subhd2.NewSupplier(d.reqParam),
+			zimuku2.NewSupplier(d.reqParam),
+			xunlei2.NewSupplier(d.reqParam),
+			shooter2.NewSupplier(d.reqParam),
 		)
 		// 字幕都下载缓存好了,需要抉择存哪一个,优先选择中文双语的,然后到中文
 		organizeSubFiles, err := subSupplierHub.DownloadSub4Movie(inData.OneVideoFullPath, inData.Index)
@@ -166,7 +170,7 @@ func (d Downloader) DownloadSub4Movie(dir string) error {
 	p, err := ants.NewPoolWithFunc(d.reqParam.Threads, func(inData interface{}) {
 		data := inData.(InputData)
 		defer data.Wg.Done()
-		ctx, cancel := context.WithTimeout(context.Background(), common.OneVideoProcessTimeOut)
+		ctx, cancel := context.WithTimeout(context.Background(), common2.OneVideoProcessTimeOut)
 		defer cancel()
 
 		done := make(chan error, 1)
@@ -213,7 +217,7 @@ func (d Downloader) DownloadSub4Series(dir string) error {
 	var err error
 	defer func() {
 		// 所有的连续剧字幕下载完成,抉择完成,需要清理缓存目录
-		err := model.ClearRootTmpFolder()
+		err := pkg.ClearRootTmpFolder()
 		if err != nil {
 			d.log.Error("ClearRootTmpFolder", err)
 		}
@@ -225,15 +229,15 @@ func (d Downloader) DownloadSub4Series(dir string) error {
 	seriesDlFunc := func(i interface{}) error {
 		inData := i.(InputData)
 		// 构建每个字幕站点下载者的实例
-		var subSupplierHub *sub_supplier.SubSupplierHub
-		subSupplierHub = sub_supplier.NewSubSupplierHub(
-			zimuku.NewSupplier(d.reqParam),
-			subhd.NewSupplier(d.reqParam),
-			xunlei.NewSupplier(d.reqParam),
-			shooter.NewSupplier(d.reqParam),
+		var subSupplierHub *sub_supplier2.SubSupplierHub
+		subSupplierHub = sub_supplier2.NewSubSupplierHub(
+			zimuku2.NewSupplier(d.reqParam),
+			subhd2.NewSupplier(d.reqParam),
+			xunlei2.NewSupplier(d.reqParam),
+			shooter2.NewSupplier(d.reqParam),
 		)
 		// 这里拿到了这一部连续剧的所有的剧集信息,以及所有下载到的字幕信息
-		var seriesInfo *common.SeriesInfo
+		var seriesInfo *series.SeriesInfo
 		var organizeSubFiles map[string][]string
 		// 是否是通过 emby api 获取的列表
 		if d.embyHelper == nil {
@@ -272,7 +276,7 @@ func (d Downloader) DownloadSub4Series(dir string) error {
 				continue
 			}
 			// 匹配对应的 Eps 去处理
-			seasonEpsKey := model.GetEpisodeKeyName(episodeInfo.Season, episodeInfo.Episode)
+			seasonEpsKey := pkg.GetEpisodeKeyName(episodeInfo.Season, episodeInfo.Episode)
 			d.oneVideoSelectBestSub(episodeInfo.FileFullPath, fullSeasonSubDict[seasonEpsKey])
 		}
 
@@ -281,7 +285,7 @@ func (d Downloader) DownloadSub4Series(dir string) error {
 	p, err := ants.NewPoolWithFunc(d.reqParam.Threads, func(inData interface{}) {
 		data := inData.(InputData)
 		defer data.Wg.Done()
-		ctx, cancel := context.WithTimeout(context.Background(), common.OneVideoProcessTimeOut)
+		ctx, cancel := context.WithTimeout(context.Background(), common2.OneVideoProcessTimeOut)
 		defer cancel()
 
 		done := make(chan error, 1)
@@ -315,7 +319,7 @@ func (d Downloader) DownloadSub4Series(dir string) error {
 	var seriesDirList = make([]string, 0)
 	if d.embyHelper == nil {
 		// 遍历连续剧总目录下的第一层目录
-		seriesDirList, err = series_helper.GetSeriesList(dir)
+		seriesDirList, err = series_helper2.GetSeriesList(dir)
 		if err != nil {
 			return err
 		}
@@ -353,7 +357,7 @@ func (d Downloader) oneVideoSelectBestSub(oneVideoFullPath string, organizeSubFi
 	// -------------------------------------------------
 	if d.reqParam.SaveMultiSub == false {
 		// 选择最优的一个字幕
-		var finalSubFile *common.SubParserFileInfo
+		var finalSubFile *subparser.FileInfo
 		finalSubFile = d.mk.SelectOneSubFile(organizeSubFiles)
 		if finalSubFile == nil {
 			d.log.Warnln("Found", len(organizeSubFiles), " subtitles but not one fit:", oneVideoFullPath)
@@ -384,12 +388,12 @@ func (d Downloader) oneVideoSelectBestSub(oneVideoFullPath string, organizeSubFi
 }
 
 // saveFullSeasonSub 这里就需要单独存储到连续剧每一季的文件夹的特殊文件夹中
-func (d Downloader) saveFullSeasonSub(seriesInfo *common.SeriesInfo, organizeSubFiles map[string][]string) map[string][]string {
+func (d Downloader) saveFullSeasonSub(seriesInfo *series.SeriesInfo, organizeSubFiles map[string][]string) map[string][]string {
 
 	var fullSeasonSubDict = make(map[string][]string)
 
 	for _, season := range seriesInfo.SeasonDict {
-		seasonKey := model.GetEpisodeKeyName(season, 0)
+		seasonKey := pkg.GetEpisodeKeyName(season, 0)
 		subs, ok := organizeSubFiles[seasonKey]
 		if ok == false {
 			continue
@@ -399,18 +403,18 @@ func (d Downloader) saveFullSeasonSub(seriesInfo *common.SeriesInfo, organizeSub
 			newSeasonSubRootPath := path.Join(seriesInfo.DirPath, "Sub_"+seasonKey)
 			_ = os.MkdirAll(newSeasonSubRootPath, os.ModePerm)
 			newSubFullPath := path.Join(newSeasonSubRootPath, subFileName)
-			_, err := model.CopyFile(newSubFullPath, sub)
+			_, err := pkg.CopyFile(newSubFullPath, sub)
 			if err != nil {
 				d.log.Errorln("saveFullSeasonSub", subFileName, err)
 				continue
 			}
 			// 从字幕的文件名推断是 哪一季 的 那一集
-			_, gusSeason, gusEpisode, err := model.GetSeasonAndEpisodeFromSubFileName(subFileName)
+			_, gusSeason, gusEpisode, err := pkg.GetSeasonAndEpisodeFromSubFileName(subFileName)
 			if err != nil {
 				return nil
 			}
 			// 把整季的字幕缓存位置也提供出去,如果之前没有下载到的,这里返回出来的可以补上
-			seasonEpsKey := model.GetEpisodeKeyName(gusSeason, gusEpisode)
+			seasonEpsKey := pkg.GetEpisodeKeyName(gusSeason, gusEpisode)
 			_, ok := fullSeasonSubDict[seasonEpsKey]
 			if ok == false {
 				// 初始化
@@ -424,9 +428,9 @@ func (d Downloader) saveFullSeasonSub(seriesInfo *common.SeriesInfo, organizeSub
 }
 
 // 在前面需要进行语言的筛选、排序,这里仅仅是存储
-func (d Downloader) writeSubFile2VideoPath(videoFileFullPath string, finalSubFile common.SubParserFileInfo, extraSubPreName string) error {
+func (d Downloader) writeSubFile2VideoPath(videoFileFullPath string, finalSubFile subparser.FileInfo, extraSubPreName string) error {
 	videoRootPath := filepath.Dir(videoFileFullPath)
-	embyLanExtName := model.Lang2EmbyName(finalSubFile.Lang)
+	embyLanExtName := pkg.Lang2EmbyName(finalSubFile.Lang)
 	// 构建视频文件加 emby 的字幕预研要求名称
 	videoFileNameWithOutExt := strings.ReplaceAll(filepath.Base(videoFileFullPath),
 		filepath.Ext(videoFileFullPath), "")
@@ -450,7 +454,7 @@ func (d Downloader) copySubFile2DesFolder(desFolder string, subFiles []string) e
 
 	// 需要进行字幕文件的缓存
 	// 把缓存的文件夹新建出来
-	desFolderFullPath := path.Join(desFolder, common.SubTmpFolderName)
+	desFolderFullPath := path.Join(desFolder, common2.SubTmpFolderName)
 	err := os.MkdirAll(desFolderFullPath, os.ModePerm)
 	if err != nil {
 		return err
@@ -458,7 +462,7 @@ func (d Downloader) copySubFile2DesFolder(desFolder string, subFiles []string) e
 	// 复制下载在 tmp 文件夹中的字幕文件到视频文件夹下面
 	for _, subFile := range subFiles {
 		newFn := path.Join(desFolderFullPath, filepath.Base(subFile))
-		_, err = model.CopyFile(newFn, subFile)
+		_, err = pkg.CopyFile(newFn, subFile)
 		if err != nil {
 			return err
 		}

+ 8 - 8
downloader_test.go

@@ -1,10 +1,10 @@
 package main
 
 import (
-	"github.com/allanpk716/ChineseSubFinder/common"
-	"github.com/allanpk716/ChineseSubFinder/model"
-	"github.com/allanpk716/ChineseSubFinder/sub_parser/ass"
-	"github.com/allanpk716/ChineseSubFinder/sub_parser/srt"
+	ass2 "github.com/allanpk716/ChineseSubFinder/internal/logic/sub_parser/ass"
+	srt2 "github.com/allanpk716/ChineseSubFinder/internal/logic/sub_parser/srt"
+	"github.com/allanpk716/ChineseSubFinder/internal/pkg"
+	"github.com/allanpk716/ChineseSubFinder/internal/types"
 	"testing"
 )
 
@@ -19,7 +19,7 @@ func TestDownloader_DownloadSub4Movie(t *testing.T) {
 	//dirRoot := "X:\\电影\\冰海陷落 (2018)"
 	//dirRoot := "X:\\电影"
 
-	dl := NewDownloader(common.ReqParam{
+	dl := NewDownloader(types.ReqParam{
 		SaveMultiSub: true,
 		SubTypePriority: 1,
 		EmbyConfig: config.EmbyConfig,
@@ -49,7 +49,7 @@ func TestDownloader_DownloadSub4Series(t *testing.T) {
 	dirRoot := "X:\\连续剧"
 
 	// 如果需要调试 Emby 一定需要 dirRoot := "X:\\连续剧"
-	dl := NewDownloader(common.ReqParam{
+	dl := NewDownloader(types.ReqParam{
 		SaveMultiSub: true,
 		SubTypePriority: 1,
 		EmbyConfig: config.EmbyConfig,
@@ -66,7 +66,7 @@ func TestDownloader_DownloadSub4Series(t *testing.T) {
 
 func TestDownloader_GetUpdateVideoListFromEmby(t *testing.T) {
 	var err error
-	dl := NewDownloader(common.ReqParam{
+	dl := NewDownloader(types.ReqParam{
 		SaveMultiSub: true,
 		SubTypePriority: 1,
 		EmbyConfig: config.EmbyConfig,
@@ -84,6 +84,6 @@ func TestDownloader_SubParserHub(t *testing.T) {
 	//subFile := "X:\\连续剧\\瑞克和莫蒂 (2013)\\Season 4\\瑞克和莫蒂 - S04E01 - Rick and Morty.zh.srt"
 	subFile := "X:\\连续剧\\黑钱胜地 (2017)\\Sub_S3E0\\[subhd]_0_Ozark.S03E07.iNTERNAL.720p.WEB.x264-GHOSTS.chs.eng.ass"
 
-	subParserHub := model.NewSubParserHub(ass.NewParser(), srt.NewParser())
+	subParserHub := pkg.NewSubParserHub(ass2.NewParser(), srt2.NewParser())
 	subParserHub.IsSubHasChinese(subFile)
 }

+ 0 - 12
interface/iSubParser.go

@@ -1,12 +0,0 @@
-package _interface
-
-import "github.com/allanpk716/ChineseSubFinder/common"
-
-type ISubParser interface {
-
-	GetParserName() string
-
-	DetermineFileTypeFromFile(filePath string) (*common.SubParserFileInfo, error)
-
-	DetermineFileTypeFromBytes(inBytes []byte, nowExt string) (*common.SubParserFileInfo, error)
-}

+ 0 - 16
interface/iSupplier.go

@@ -1,16 +0,0 @@
-package _interface
-
-import "github.com/allanpk716/ChineseSubFinder/common"
-
-type ISupplier interface {
-
-	GetSupplierName() string
-
-	GetReqParam() common.ReqParam
-
-	GetSubListFromFile4Movie(filePath string) ([]common.SupplierSubInfo, error)
-
-	GetSubListFromFile4Series(seriesInfo *common.SeriesInfo) ([]common.SupplierSubInfo, error)
-	
-	GetSubListFromFile4Anime(seriesInfo *common.SeriesInfo) ([]common.SupplierSubInfo, error)
-}

+ 0 - 0
common/common.go → internal/common/constvalue.go


+ 0 - 0
common/selferr.go → internal/common/selferr.go


+ 0 - 0
common/subType.go → internal/common/subtypes.go


+ 0 - 0
common/urls.go → internal/common/urls.go


+ 8 - 0
internal/common/videotype.go

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

+ 14 - 0
internal/interface/iSubParser.go

@@ -0,0 +1,14 @@
+package _interface
+
+import (
+	"github.com/allanpk716/ChineseSubFinder/internal/types/subparser"
+)
+
+type ISubParser interface {
+
+	GetParserName() string
+
+	DetermineFileTypeFromFile(filePath string) (*subparser.FileInfo, error)
+
+	DetermineFileTypeFromBytes(inBytes []byte, nowExt string) (*subparser.FileInfo, error)
+}

+ 20 - 0
internal/interface/iSupplier.go

@@ -0,0 +1,20 @@
+package _interface
+
+import (
+	"github.com/allanpk716/ChineseSubFinder/internal/types"
+	"github.com/allanpk716/ChineseSubFinder/internal/types/series"
+	"github.com/allanpk716/ChineseSubFinder/internal/types/supplier"
+)
+
+type ISupplier interface {
+
+	GetSupplierName() string
+
+	GetReqParam() types.ReqParam
+
+	GetSubListFromFile4Movie(filePath string) ([]supplier.SubInfo, error)
+
+	GetSubListFromFile4Series(seriesInfo *series.SeriesInfo) ([]supplier.SubInfo, error)
+	
+	GetSubListFromFile4Anime(seriesInfo *series.SeriesInfo) ([]supplier.SubInfo, error)
+}

+ 0 - 0
charset/charset.go → internal/logic/charset/charset.go


+ 0 - 0
charset/charset_test.go → internal/logic/charset/charset_test.go


+ 38 - 36
emby_helper/embyhelper.go → internal/logic/emby_helper/embyhelper.go

@@ -1,8 +1,10 @@
 package emby_helper
 
 import (
-	"github.com/allanpk716/ChineseSubFinder/common"
-	"github.com/allanpk716/ChineseSubFinder/model"
+	common2 "github.com/allanpk716/ChineseSubFinder/internal/common"
+	"github.com/allanpk716/ChineseSubFinder/internal/pkg"
+	"github.com/allanpk716/ChineseSubFinder/internal/types"
+	"github.com/allanpk716/ChineseSubFinder/internal/types/emby"
 	"github.com/panjf2000/ants/v2"
 	"golang.org/x/net/context"
 	"path"
@@ -13,22 +15,22 @@ import (
 )
 
 type EmbyHelper struct {
-	embyApi     *model.EmbyApi
-	EmbyConfig 	common.EmbyConfig
+	embyApi    *pkg.EmbyApi
+	EmbyConfig emby.EmbyConfig
 	threads    int
 	timeOut    time.Duration
 	listLock   sync.Mutex
 }
 
-func NewEmbyHelper(embyConfig common.EmbyConfig) *EmbyHelper {
+func NewEmbyHelper(embyConfig emby.EmbyConfig) *EmbyHelper {
 	em := EmbyHelper{EmbyConfig: embyConfig}
-	em.embyApi = model.NewEmbyHelper(embyConfig)
+	em.embyApi = pkg.NewEmbyHelper(embyConfig)
 	em.threads = 6
 	em.timeOut = 5 * time.Second
 	return &em
 }
 
-func (em *EmbyHelper) GetRecentlyAddVideoList(movieRootDir, seriesRootDir string) ([]common.EmbyMixInfo, map[string][]common.EmbyMixInfo, error) {
+func (em *EmbyHelper) GetRecentlyAddVideoList(movieRootDir, seriesRootDir string) ([]emby.EmbyMixInfo, map[string][]emby.EmbyMixInfo, error) {
 
 	// 获取电影和连续剧的文件夹名称
 	movieFolderName := filepath.Base(movieRootDir)
@@ -77,12 +79,12 @@ func (em *EmbyHelper) GetRecentlyAddVideoList(movieRootDir, seriesRootDir string
 		noSubSeriesList[i].VideoFileFullPath = path.Join(seriesRootDir, info.VideoFileRelativePath)
 	}
 	// 需要将连续剧零散的每一集,进行合并到一个连续剧下面,也就是这个连续剧有那些需要更新的
-	var seriesMap = make(map[string][]common.EmbyMixInfo)
+	var seriesMap = make(map[string][]emby.EmbyMixInfo)
 	for _, info := range noSubSeriesList {
 		_, ok := seriesMap[info.VideoFolderName]
 		if ok == false {
 			// 不存在则新建初始化
-			seriesMap[info.VideoFolderName] = make([]common.EmbyMixInfo, 0)
+			seriesMap[info.VideoFolderName] = make([]emby.EmbyMixInfo, 0)
 		}
 		seriesMap[info.VideoFolderName] = append(seriesMap[info.VideoFolderName], info)
 	}
@@ -102,10 +104,10 @@ func (em *EmbyHelper) RefreshEmbySubList() (bool, error) {
 	return true, nil
 }
 
-func (em *EmbyHelper) filterEmbyVideoList(videoFolderName string, videoIdList []string, isMovieOrSeries bool) ([]common.EmbyMixInfo, error) {
-	var filterVideoEmbyInfo = make([]common.EmbyMixInfo, 0)
+func (em *EmbyHelper) filterEmbyVideoList(videoFolderName string, videoIdList []string, isMovieOrSeries bool) ([]emby.EmbyMixInfo, error) {
+	var filterVideoEmbyInfo = make([]emby.EmbyMixInfo, 0)
 
-	queryFunc := func(m string) (*common.EmbyMixInfo, error) {
+	queryFunc := func(m string) (*emby.EmbyMixInfo, error) {
 		info, err := em.embyApi.GetItemVideoInfo(m)
 		if err != nil {
 			return nil, err
@@ -114,7 +116,7 @@ func (em *EmbyHelper) filterEmbyVideoList(videoFolderName string, videoIdList []
 		if err != nil {
 			return nil, err
 		}
-		mixInfo := common.EmbyMixInfo{Ancestors: ancs, VideoInfo: info}
+		mixInfo := emby.EmbyMixInfo{Ancestors: ancs, VideoInfo: info}
 		if isMovieOrSeries == true {
 			// 电影
 			// 过滤掉不符合要求的
@@ -179,7 +181,7 @@ func (em *EmbyHelper) filterEmbyVideoList(videoFolderName string, videoIdList []
 		case outData := <- done:
 			// 收到结果,需要加锁
 			if outData.Err != nil {
-				model.GetLogger().Errorln("filterEmbyVideoList.NewPoolWithFunc got Err", outData.Err)
+				pkg.GetLogger().Errorln("filterEmbyVideoList.NewPoolWithFunc got Err", outData.Err)
 				return
 			}
 			if outData.Info == nil {
@@ -190,9 +192,9 @@ func (em *EmbyHelper) filterEmbyVideoList(videoFolderName string, videoIdList []
 			em.listLock.Unlock()
 			return
 		case p := <- panicChan:
-			model.GetLogger().Errorln("filterEmbyVideoList.NewPoolWithFunc got panic", p)
+			pkg.GetLogger().Errorln("filterEmbyVideoList.NewPoolWithFunc got panic", p)
 		case <-ctx.Done():
-			model.GetLogger().Errorln("filterEmbyVideoList.NewPoolWithFunc got time out", ctx.Err())
+			pkg.GetLogger().Errorln("filterEmbyVideoList.NewPoolWithFunc got time out", ctx.Err())
 			return
 		}
 	})
@@ -206,7 +208,7 @@ func (em *EmbyHelper) filterEmbyVideoList(videoFolderName string, videoIdList []
 		wg.Add(1)
 		err = p.Invoke(InputData{Id: m, Wg: &wg})
 		if err != nil {
-			model.GetLogger().Errorln("filterEmbyVideoList ants.Invoke", err)
+			pkg.GetLogger().Errorln("filterEmbyVideoList ants.Invoke", err)
 		}
 	}
 	wg.Wait()
@@ -214,12 +216,12 @@ func (em *EmbyHelper) filterEmbyVideoList(videoFolderName string, videoIdList []
 	return filterVideoEmbyInfo, nil
 }
 
-func (em *EmbyHelper) filterNoChineseSubVideoList(videoList []common.EmbyMixInfo) ([]common.EmbyMixInfo, error) {
+func (em *EmbyHelper) filterNoChineseSubVideoList(videoList []emby.EmbyMixInfo) ([]emby.EmbyMixInfo, error) {
 	currentTime := time.Now()
-	dayRange_3Months, _ := time.ParseDuration(common.DownloadSubDuring3Months)
-	dayRange_7Days, _ := time.ParseDuration(common.DownloadSubDuring7Days)
+	dayRange_3Months, _ := time.ParseDuration(common2.DownloadSubDuring3Months)
+	dayRange_7Days, _ := time.ParseDuration(common2.DownloadSubDuring7Days)
 
-	var noSubVideoList = make([]common.EmbyMixInfo, 0)
+	var noSubVideoList = make([]emby.EmbyMixInfo, 0)
 	// TODO 这里有一种情况需要考虑的,如果内置有中文的字幕,那么是否需要跳过,目前暂定的一定要有外置的字幕
 	for _, info := range videoList {
 
@@ -295,18 +297,18 @@ func (em *EmbyHelper) langStringOK(inLang string) bool {
 		}
 	}
 	switch nextString {
-	case em.replaceLangString(common.Emby_chi),
-		em.replaceLangString(common.Emby_chn),
-		em.replaceLangString(common.Emby_chs),
-		em.replaceLangString(common.Emby_cht),
-		em.replaceLangString(common.Emby_chs_en),
-		em.replaceLangString(common.Emby_cht_en),
-		em.replaceLangString(common.Emby_chs_jp),
-		em.replaceLangString(common.Emby_cht_jp),
-		em.replaceLangString(common.Emby_chs_kr),
-		em.replaceLangString(common.Emby_cht_kr):
+	case em.replaceLangString(types.Emby_chi),
+		em.replaceLangString(types.Emby_chn),
+		em.replaceLangString(types.Emby_chs),
+		em.replaceLangString(types.Emby_cht),
+		em.replaceLangString(types.Emby_chs_en),
+		em.replaceLangString(types.Emby_cht_en),
+		em.replaceLangString(types.Emby_chs_jp),
+		em.replaceLangString(types.Emby_cht_jp),
+		em.replaceLangString(types.Emby_chs_kr),
+		em.replaceLangString(types.Emby_cht_kr):
 			return true
-	case em.replaceLangString(common.Emby_chinese):
+	case em.replaceLangString(types.Emby_chinese):
 		return true
 	default:
 		return false
@@ -317,9 +319,9 @@ func (em *EmbyHelper) langStringOK(inLang string) bool {
 func (em *EmbyHelper) subTypeStringOK(inSubType string) bool {
 
 	tmpString := strings.ToLower(inSubType)
-	if tmpString == common.SubTypeSRT ||
-		tmpString == common.SubTypeASS ||
-		tmpString == common.SubTypeSSA {
+	if tmpString == common2.SubTypeSRT ||
+		tmpString == common2.SubTypeASS ||
+		tmpString == common2.SubTypeSSA {
 		return true
 	}
 
@@ -339,6 +341,6 @@ type InputData struct {
 }
 
 type OutData struct {
-	Info 	*common.EmbyMixInfo
+	Info 	*emby.EmbyMixInfo
 	Err 	error
 }

+ 5 - 5
emby_helper/embyhelper_test.go → internal/logic/emby_helper/embyhelper_test.go

@@ -1,18 +1,18 @@
 package emby_helper
 
 import (
-	"github.com/allanpk716/ChineseSubFinder/common"
-	"github.com/allanpk716/ChineseSubFinder/model"
+	"github.com/allanpk716/ChineseSubFinder/internal/pkg"
+	"github.com/allanpk716/ChineseSubFinder/internal/types"
 	"testing"
 )
 
 func init() {
 	var err error
-	configViper, err := model.InitConfigure()
+	configViper, err := pkg.InitConfigure()
 	if err != nil {
 		return
 	}
-	config, err = model.ReadConfig(configViper)
+	config, err = pkg.ReadConfig(configViper)
 	if err != nil {
 		return
 	}
@@ -30,7 +30,7 @@ func TestEmbyHelper_GetRecentlyAddVideoList(t *testing.T) {
 }
 
 var (
-	config *common.Config
+	config *types.Config
 )
 
 func TestEmbyHelper_RefreshEmbySubList(t *testing.T) {

+ 23 - 23
mark_system/marking_system.go → internal/logic/mark_system/markingsystem.go

@@ -1,10 +1,10 @@
 package mark_system
 
 import (
-	"github.com/allanpk716/ChineseSubFinder/common"
-	"github.com/allanpk716/ChineseSubFinder/model"
-	"github.com/allanpk716/ChineseSubFinder/sub_parser/ass"
-	"github.com/allanpk716/ChineseSubFinder/sub_parser/srt"
+	ass2 "github.com/allanpk716/ChineseSubFinder/internal/logic/sub_parser/ass"
+	srt2 "github.com/allanpk716/ChineseSubFinder/internal/logic/sub_parser/srt"
+	"github.com/allanpk716/ChineseSubFinder/internal/pkg"
+	"github.com/allanpk716/ChineseSubFinder/internal/types/subparser"
 	"github.com/sirupsen/logrus"
 )
 
@@ -13,20 +13,20 @@ type MarkingSystem struct {
 	log *logrus.Logger
 	subSiteSequence []string			// 网站的优先级,从高到低
 	SubTypePriority int					// 字幕格式的优先级
-	subParserHub *model.SubParserHub
+	subParserHub *pkg.SubParserHub
 }
 
 func NewMarkingSystem(subSiteSequence []string, subTypePriority int) *MarkingSystem {
 	mk := MarkingSystem{subSiteSequence: subSiteSequence,
-		log: model.GetLogger(),
+		log:             pkg.GetLogger(),
 		SubTypePriority: subTypePriority,
-		subParserHub: model.NewSubParserHub(ass.NewParser(), srt.NewParser())}
+		subParserHub:    pkg.NewSubParserHub(ass2.NewParser(), srt2.NewParser())}
 	return &mk
 }
 
 // SelectOneSubFile 选择最优的一个字幕文件
-func (m MarkingSystem) SelectOneSubFile(organizeSubFiles []string) *common.SubParserFileInfo {
-	var finalSubFile *common.SubParserFileInfo
+func (m MarkingSystem) SelectOneSubFile(organizeSubFiles []string) *subparser.FileInfo {
+	var finalSubFile *subparser.FileInfo
 	subInfoDict := m.parseSubFileInfo(organizeSubFiles)
 	// 优先级别暂定 subSiteSequence: zimuku -> subhd -> xunlei -> shooter
 	// 这里需要循环四轮:
@@ -41,13 +41,13 @@ func (m MarkingSystem) SelectOneSubFile(organizeSubFiles []string) *common.SubPa
 				continue
 			}
 			if i == 0 {
-				finalSubFile = model.SelectChineseBestBilingualSubtitle(infos, m.SubTypePriority)
+				finalSubFile = pkg.SelectChineseBestBilingualSubtitle(infos, m.SubTypePriority)
 			} else if i == 1 {
-				finalSubFile = model.SelectChineseBestSubtitle(infos, m.SubTypePriority)
+				finalSubFile = pkg.SelectChineseBestSubtitle(infos, m.SubTypePriority)
 			} else if i == 2 {
-				finalSubFile = model.SelectChineseBestBilingualSubtitle(infos, 0)
+				finalSubFile = pkg.SelectChineseBestBilingualSubtitle(infos, 0)
 			} else if i == 3 {
-				finalSubFile = model.SelectChineseBestSubtitle(infos, 0)
+				finalSubFile = pkg.SelectChineseBestSubtitle(infos, 0)
 			}
 			if finalSubFile != nil {
 				return finalSubFile
@@ -58,11 +58,11 @@ func (m MarkingSystem) SelectOneSubFile(organizeSubFiles []string) *common.SubPa
 }
 
 // SelectEachSiteTop1SubFile 每个网站最优的文件
-func (m MarkingSystem) SelectEachSiteTop1SubFile(organizeSubFiles []string) ([]string, []common.SubParserFileInfo) {
+func (m MarkingSystem) SelectEachSiteTop1SubFile(organizeSubFiles []string) ([]string, []subparser.FileInfo) {
 	// 每个文件都带有出处 [subhd]
-	var finalSubFile *common.SubParserFileInfo
+	var finalSubFile *subparser.FileInfo
 	var outSiteName = make([]string, 0)
-	var outSubParserFileInfos = make([]common.SubParserFileInfo, 0)
+	var outSubParserFileInfos = make([]subparser.FileInfo, 0)
 	subInfoDict := m.parseSubFileInfo(organizeSubFiles)
 	// 这里需要循环四轮:
 	// 第一轮,双语、字幕类型自定义,优先
@@ -73,13 +73,13 @@ func (m MarkingSystem) SelectEachSiteTop1SubFile(organizeSubFiles []string) ([]s
 		for siteName, infos := range subInfoDict {
 			// 每个网站保存一个
 			if i == 0 {
-				finalSubFile = model.SelectChineseBestBilingualSubtitle(infos, m.SubTypePriority)
+				finalSubFile = pkg.SelectChineseBestBilingualSubtitle(infos, m.SubTypePriority)
 			} else if i == 1 {
-				finalSubFile = model.SelectChineseBestSubtitle(infos, m.SubTypePriority)
+				finalSubFile = pkg.SelectChineseBestSubtitle(infos, m.SubTypePriority)
 			} else if i == 2 {
-				finalSubFile = model.SelectChineseBestBilingualSubtitle(infos, 0)
+				finalSubFile = pkg.SelectChineseBestBilingualSubtitle(infos, 0)
 			} else if i == 3 {
-				finalSubFile = model.SelectChineseBestSubtitle(infos, 0)
+				finalSubFile = pkg.SelectChineseBestSubtitle(infos, 0)
 			}
 			if finalSubFile != nil {
 				outSiteName = append(outSiteName, siteName)
@@ -92,9 +92,9 @@ func (m MarkingSystem) SelectEachSiteTop1SubFile(organizeSubFiles []string) ([]s
 }
 
 // parseSubFileInfo 从文件解析字幕信息
-func (m MarkingSystem) parseSubFileInfo(organizeSubFiles []string) map[string][]common.SubParserFileInfo {
+func (m MarkingSystem) parseSubFileInfo(organizeSubFiles []string) map[string][]subparser.FileInfo {
 	// 一个网站可能就算取了 Top1 字幕,也可能是返回一个压缩包,然后解压完就是多个字幕,所以
-	var subInfoDict = make(map[string][]common.SubParserFileInfo)
+	var subInfoDict = make(map[string][]subparser.FileInfo)
 	// 拿到现有的字幕列表,开始抉择
 	// 先判断当前字幕是什么语言(如果是简体,还需要考虑,判断这个字幕是简体还是繁体)
 	for _, oneSubFileFullPath := range organizeSubFiles {
@@ -112,7 +112,7 @@ func (m MarkingSystem) parseSubFileInfo(organizeSubFiles []string) map[string][]
 		_, ok := subInfoDict[subFileInfo.FromWhereSite]
 		if ok == false {
 			// 新建
-			subInfoDict[subFileInfo.FromWhereSite] = make([]common.SubParserFileInfo, 0)
+			subInfoDict[subFileInfo.FromWhereSite] = make([]subparser.FileInfo, 0)
 		}
 		// 添加
 		subInfoDict[subFileInfo.FromWhereSite] = append(subInfoDict[subFileInfo.FromWhereSite], *subFileInfo)

+ 32 - 30
movie_helper/movieHelper.go → internal/logic/movie_helper/moviehelper.go

@@ -1,11 +1,13 @@
 package movie_helper
 
 import (
-	"github.com/allanpk716/ChineseSubFinder/common"
-	_interface "github.com/allanpk716/ChineseSubFinder/interface"
-	"github.com/allanpk716/ChineseSubFinder/model"
-	"github.com/allanpk716/ChineseSubFinder/sub_parser/ass"
-	"github.com/allanpk716/ChineseSubFinder/sub_parser/srt"
+	common2 "github.com/allanpk716/ChineseSubFinder/internal/common"
+	_interface2 "github.com/allanpk716/ChineseSubFinder/internal/interface"
+	ass2 "github.com/allanpk716/ChineseSubFinder/internal/logic/sub_parser/ass"
+	srt2 "github.com/allanpk716/ChineseSubFinder/internal/logic/sub_parser/srt"
+	"github.com/allanpk716/ChineseSubFinder/internal/pkg"
+	"github.com/allanpk716/ChineseSubFinder/internal/types"
+	"github.com/allanpk716/ChineseSubFinder/internal/types/supplier"
 	"github.com/jinzhu/now"
 	"io/ioutil"
 	"path/filepath"
@@ -14,17 +16,17 @@ import (
 )
 
 // OneMovieDlSubInAllSite 一部电影在所有的网站下载相应的字幕
-func OneMovieDlSubInAllSite(Suppliers []_interface.ISupplier, oneVideoFullPath string, i int) []common.SupplierSubInfo {
-	var outSUbInfos = make([]common.SupplierSubInfo, 0)
+func OneMovieDlSubInAllSite(Suppliers []_interface2.ISupplier, oneVideoFullPath string, i int) []supplier.SubInfo {
+	var outSUbInfos = make([]supplier.SubInfo, 0)
 	// 同时进行查询
-	subInfosChannel := make(chan []common.SupplierSubInfo)
-	model.GetLogger().Infoln("DlSub Start", oneVideoFullPath)
+	subInfosChannel := make(chan []supplier.SubInfo)
+	pkg.GetLogger().Infoln("DlSub Start", oneVideoFullPath)
 	for _, supplier := range Suppliers {
 		supplier := supplier
 		go func() {
 			subInfos, err := OneMovieDlSubInOneSite(oneVideoFullPath, i, supplier)
 			if err != nil {
-				model.GetLogger().Errorln(supplier.GetSupplierName(), "oneMovieDlSubInOneSite", err)
+				pkg.GetLogger().Errorln(supplier.GetSupplierName(), "oneMovieDlSubInOneSite", err)
 			}
 			subInfosChannel <- subInfos
 		}()
@@ -35,22 +37,22 @@ func OneMovieDlSubInAllSite(Suppliers []_interface.ISupplier, oneVideoFullPath s
 			outSUbInfos = append(outSUbInfos, v...)
 		}
 	}
-	model.GetLogger().Infoln("DlSub End", oneVideoFullPath)
+	pkg.GetLogger().Infoln("DlSub End", oneVideoFullPath)
 	return outSUbInfos
 }
 
 // OneMovieDlSubInOneSite 一部电影在一个站点下载字幕
-func OneMovieDlSubInOneSite(oneVideoFullPath string, i int, supplier _interface.ISupplier) ([]common.SupplierSubInfo, error) {
+func OneMovieDlSubInOneSite(oneVideoFullPath string, i int, supplier _interface2.ISupplier) ([]supplier.SubInfo, error) {
 	defer func() {
-		model.GetLogger().Infoln(i, supplier.GetSupplierName(), "End...")
+		pkg.GetLogger().Infoln(i, supplier.GetSupplierName(), "End...")
 	}()
-	model.GetLogger().Infoln(i, supplier.GetSupplierName(), "Start...")
+	pkg.GetLogger().Infoln(i, supplier.GetSupplierName(), "Start...")
 	subInfos, err := supplier.GetSubListFromFile4Movie(oneVideoFullPath)
 	if err != nil {
 		return nil, err
 	}
 	// 把后缀名给改好
-	model.ChangeVideoExt2SubExt(subInfos)
+	pkg.ChangeVideoExt2SubExt(subInfos)
 
 	return subInfos, nil
 }
@@ -67,11 +69,11 @@ func MovieHasSub(videoFilePath string) (bool, error) {
 			continue
 		} else {
 			// 文件
-			if model.IsSubExtWanted(curFile.Name()) == false {
+			if pkg.IsSubExtWanted(curFile.Name()) == false {
 				continue
 			}
 			// 字幕文件是否包含中文
-			if model.NewSubParserHub(ass.NewParser(), srt.NewParser()).IsSubHasChinese(filepath.Join(dir, curFile.Name())) == true {
+			if pkg.NewSubParserHub(ass2.NewParser(), srt2.NewParser()).IsSubHasChinese(filepath.Join(dir, curFile.Name())) == true {
 				return true, nil
 			}
 		}
@@ -80,21 +82,21 @@ func MovieHasSub(videoFilePath string) (bool, error) {
 	return false, nil
 }
 
-func SkipChineseMovie(videoFullPath string, _reqParam ...common.ReqParam) (bool, error) {
-	var reqParam common.ReqParam
+func SkipChineseMovie(videoFullPath string, _reqParam ...types.ReqParam) (bool, error) {
+	var reqParam types.ReqParam
 	if len(_reqParam) > 0 {
 		reqParam = _reqParam[0]
 	}
-	imdbInfo, err := model.GetImdbInfo4Movie(videoFullPath)
+	imdbInfo, err := pkg.GetImdbInfo4Movie(videoFullPath)
 	if err != nil {
 		return false, err
 	}
-	t, err := model.GetVideoInfoFromIMDB(imdbInfo.ImdbId, reqParam)
+	t, err := pkg.GetVideoInfoFromIMDB(imdbInfo.ImdbId, reqParam)
 	if err != nil {
 		return false, err
 	}
 	if len(t.Languages) > 0 && strings.ToLower(t.Languages[0]) == "chinese" {
-		model.GetLogger().Infoln("Skip", videoFullPath, "Sub Download, because movie is Chinese")
+		pkg.GetLogger().Infoln("Skip", videoFullPath, "Sub Download, because movie is Chinese")
 		return true, nil
 	}
 	return false, nil
@@ -108,8 +110,8 @@ func MovieNeedDlSub(videoFullPath string) (bool, error) {
 	}
 	// 资源下载的时间后的多少天内都进行字幕的自动下载,替换原有的字幕
 	currentTime := time.Now()
-	dayRange, _ := time.ParseDuration(common.DownloadSubDuring3Months)
-	mInfo, modifyTime, err := model.GetVideoInfoFromFileFullPath(videoFullPath)
+	dayRange, _ := time.ParseDuration(common2.DownloadSubDuring3Months)
+	mInfo, modifyTime, err := pkg.GetVideoInfoFromFileFullPath(videoFullPath)
 	if err != nil {
 		return false, err
 	}
@@ -120,14 +122,14 @@ func MovieNeedDlSub(videoFullPath string) (bool, error) {
 			return true, nil
 		} else {
 			// 有字幕了,没必要每次都刷新,跳过
-			model.GetLogger().Infoln("Skip", filepath.Base(videoFullPath), "Sub Download, because movie has sub and published more than 2 years")
+			pkg.GetLogger().Infoln("Skip", filepath.Base(videoFullPath), "Sub Download, because movie has sub and published more than 2 years")
 			return false, nil
 		}
 	} else {
 		// 读取不到 IMDB 信息也能接受
-		videoIMDBInfo, err := model.GetImdbInfo4Movie(videoFullPath)
+		videoIMDBInfo, err := pkg.GetImdbInfo4Movie(videoFullPath)
 		if err != nil {
-			model.GetLogger().Errorln("MovieNeedDlSub.GetImdbInfo4Movie", err)
+			pkg.GetLogger().Errorln("MovieNeedDlSub.GetImdbInfo4Movie", err)
 		}
 		// 如果播出时间能够读取到,那么就以这个完后推算 3个月
 		// 如果读取不到 Aired Time 那么,下载后的 ModifyTime 3个月天内,都进行字幕的下载
@@ -135,7 +137,7 @@ func MovieNeedDlSub(videoFullPath string) (bool, error) {
 		if videoIMDBInfo.ReleaseDate != "" {
 			baseTime, err = now.Parse(videoIMDBInfo.ReleaseDate)
 			if err != nil {
-				model.GetLogger().Errorln("Movie parse AiredTime", err)
+				pkg.GetLogger().Errorln("Movie parse AiredTime", err)
 				baseTime = modifyTime
 			}
 		} else {
@@ -148,11 +150,11 @@ func MovieNeedDlSub(videoFullPath string) (bool, error) {
 			return true, nil
 		} else {
 			if baseTime.Add(dayRange).After(currentTime) == false {
-				model.GetLogger().Infoln("Skip", filepath.Base(videoFullPath), "Sub Download, because movie has sub and downloaded or aired more than 3 months")
+				pkg.GetLogger().Infoln("Skip", filepath.Base(videoFullPath), "Sub Download, because movie has sub and downloaded or aired more than 3 months")
 				return false, nil
 			}
 			if found == true {
-				model.GetLogger().Infoln("Skip", filepath.Base(videoFullPath), "Sub Download, because sub file found")
+				pkg.GetLogger().Infoln("Skip", filepath.Base(videoFullPath), "Sub Download, because sub file found")
 				return false, nil
 			}
 

+ 63 - 59
series_helper/seriesHelper.go → internal/logic/series_helper/seriesHelper.go

@@ -2,11 +2,15 @@ package series_helper
 
 import (
 	"github.com/StalkR/imdb"
-	"github.com/allanpk716/ChineseSubFinder/common"
-	_interface "github.com/allanpk716/ChineseSubFinder/interface"
-	"github.com/allanpk716/ChineseSubFinder/model"
-	"github.com/allanpk716/ChineseSubFinder/sub_parser/ass"
-	"github.com/allanpk716/ChineseSubFinder/sub_parser/srt"
+	common2 "github.com/allanpk716/ChineseSubFinder/internal/common"
+	_interface2 "github.com/allanpk716/ChineseSubFinder/internal/interface"
+	ass2 "github.com/allanpk716/ChineseSubFinder/internal/logic/sub_parser/ass"
+	srt2 "github.com/allanpk716/ChineseSubFinder/internal/logic/sub_parser/srt"
+	"github.com/allanpk716/ChineseSubFinder/internal/pkg"
+	"github.com/allanpk716/ChineseSubFinder/internal/types"
+	"github.com/allanpk716/ChineseSubFinder/internal/types/emby"
+	"github.com/allanpk716/ChineseSubFinder/internal/types/series"
+	"github.com/allanpk716/ChineseSubFinder/internal/types/supplier"
 	"github.com/jinzhu/now"
 	"io/ioutil"
 	"path"
@@ -17,48 +21,48 @@ import (
 )
 
 // ReadSeriesInfoFromDir 读取剧集的信息,只有那些 Eps 需要下载字幕的 NeedDlEpsKeyList
-func ReadSeriesInfoFromDir(seriesDir string, imdbInfo *imdb.Title) (*common.SeriesInfo, error) {
+func ReadSeriesInfoFromDir(seriesDir string, imdbInfo *imdb.Title) (*series.SeriesInfo, error) {
 
-	subParserHub := model.NewSubParserHub(ass.NewParser(), srt.NewParser())
+	subParserHub := pkg.NewSubParserHub(ass2.NewParser(), srt2.NewParser())
 
 	seriesInfo, err := getSeriesInfoFromDir(seriesDir, imdbInfo)
 	if err != nil {
 		return nil, err
 	}
 	// 搜索所有的视频
-	videoFiles, err := model.SearchMatchedVideoFile(seriesDir)
+	videoFiles, err := pkg.SearchMatchedVideoFile(seriesDir)
 	if err != nil {
 		return nil, err
 	}
 	// 搜索所有的字幕
-	subFiles, err := model.SearchMatchedSubFile(seriesDir)
+	subFiles, err := pkg.SearchMatchedSubFile(seriesDir)
 	if err != nil {
 		return nil, err
 	}
 	// 字幕字典 S01E01 - []SubInfo
-	SubDict := make(map[string][]common.SubInfo)
+	SubDict := make(map[string][]series.SubInfo)
 	for _, subFile := range subFiles {
 		// 判断这个字幕是否包含中文
 		if subParserHub.IsSubHasChinese(subFile) == false {
 			continue
 		}
-		info, _, err := model.GetVideoInfoFromFileFullPath(subFile)
+		info, _, err := pkg.GetVideoInfoFromFileFullPath(subFile)
 		if err != nil {
-			model.GetLogger().Errorln(err)
+			pkg.GetLogger().Errorln(err)
 			continue
 		}
 		subParserFileInfo, err := subParserHub.DetermineFileTypeFromFile(subFile)
 		if err != nil {
-			model.GetLogger().Errorln(err)
+			pkg.GetLogger().Errorln(err)
 			continue
 		}
 		if subParserFileInfo == nil {
 			// 说明这个字幕无法解析
-			model.GetLogger().Warnln("ReadSeriesInfoFromDir", seriesInfo.DirPath, "DetermineFileTypeFromFile is nil")
+			pkg.GetLogger().Warnln("ReadSeriesInfoFromDir", seriesInfo.DirPath, "DetermineFileTypeFromFile is nil")
 			continue
 		}
-		epsKey := model.GetEpisodeKeyName(info.Season, info.Episode)
-		oneFileSubInfo := common.SubInfo{
+		epsKey := pkg.GetEpisodeKeyName(info.Season, info.Episode)
+		oneFileSubInfo := series.SubInfo{
 			Title:        info.Title,
 			Season:       info.Season,
 			Episode:      info.Episode,
@@ -69,12 +73,12 @@ func ReadSeriesInfoFromDir(seriesDir string, imdbInfo *imdb.Title) (*common.Seri
 		_, ok := SubDict[epsKey]
 		if ok == false {
 			// 初始化
-			SubDict[epsKey] = make([]common.SubInfo, 0)
+			SubDict[epsKey] = make([]series.SubInfo, 0)
 		}
 		SubDict[epsKey] = append(SubDict[epsKey], oneFileSubInfo)
 	}
 	// 视频字典 S01E01 - EpisodeInfo
-	EpisodeDict := make(map[string]common.EpisodeInfo)
+	EpisodeDict := make(map[string]series.EpisodeInfo)
 	for _, videoFile := range videoFiles {
 		getEpsInfoAndSubDic(videoFile, EpisodeDict, SubDict)
 	}
@@ -90,16 +94,16 @@ func ReadSeriesInfoFromDir(seriesDir string, imdbInfo *imdb.Title) (*common.Seri
 }
 
 // ReadSeriesInfoFromEmby 将 Emby API 读取到的数据进行转换到通用的结构中,需要填充那些剧集需要下载,这样要的是一个连续剧的,不是所有的传入
-func ReadSeriesInfoFromEmby(seriesDir string, imdbInfo *imdb.Title, seriesList []common.EmbyMixInfo) (*common.SeriesInfo, error) {
+func ReadSeriesInfoFromEmby(seriesDir string, imdbInfo *imdb.Title, seriesList []emby.EmbyMixInfo) (*series.SeriesInfo, error) {
 
 	seriesInfo, err := getSeriesInfoFromDir(seriesDir, imdbInfo)
 	if err != nil {
 		return nil, err
 	}
 	seriesInfo.NeedDlSeasonDict = make(map[int]int)
-	seriesInfo.NeedDlEpsKeyList = make(map[string]common.EpisodeInfo)
-	EpisodeDict := make(map[string]common.EpisodeInfo)
-	SubDict := make(map[string][]common.SubInfo)
+	seriesInfo.NeedDlEpsKeyList = make(map[string]series.EpisodeInfo)
+	EpisodeDict := make(map[string]series.EpisodeInfo)
+	SubDict := make(map[string][]series.SubInfo)
 	for _, info := range seriesList {
 		getEpsInfoAndSubDic(info.VideoFileFullPath, EpisodeDict, SubDict)
 	}
@@ -115,56 +119,56 @@ func ReadSeriesInfoFromEmby(seriesDir string, imdbInfo *imdb.Title, seriesList [
 }
 
 // SkipChineseSeries 跳过中文连续剧
-func SkipChineseSeries(seriesRootPath string, _reqParam ...common.ReqParam) (bool, *imdb.Title, error) {
-	var reqParam common.ReqParam
+func SkipChineseSeries(seriesRootPath string, _reqParam ...types.ReqParam) (bool, *imdb.Title, error) {
+	var reqParam types.ReqParam
 	if len(_reqParam) > 0 {
 		reqParam = _reqParam[0]
 	}
-	imdbInfo, err := model.GetImdbInfo4SeriesDir(seriesRootPath)
+	imdbInfo, err := pkg.GetImdbInfo4SeriesDir(seriesRootPath)
 	if err != nil {
 		return false, nil, err
 	}
-	t, err := model.GetVideoInfoFromIMDB(imdbInfo.ImdbId, reqParam)
+	t, err := pkg.GetVideoInfoFromIMDB(imdbInfo.ImdbId, reqParam)
 	if err != nil {
 		return false, nil, err
 	}
 	if len(t.Languages) > 0 && strings.ToLower(t.Languages[0]) == "chinese" {
-		model.GetLogger().Infoln("Skip", filepath.Base(seriesRootPath), "Sub Download, because series is Chinese")
+		pkg.GetLogger().Infoln("Skip", filepath.Base(seriesRootPath), "Sub Download, because series is Chinese")
 		return true, t, nil
 	}
 	return false, t, nil
 }
 
 // OneSeriesDlSubInAllSite 一部连续剧在所有的网站下载相应的字幕
-func OneSeriesDlSubInAllSite(Suppliers []_interface.ISupplier, seriesInfo *common.SeriesInfo, i int) []common.SupplierSubInfo {
+func OneSeriesDlSubInAllSite(Suppliers []_interface2.ISupplier, seriesInfo *series.SeriesInfo, i int) []supplier.SubInfo {
 	defer func() {
-		model.GetLogger().Infoln("DlSub End", seriesInfo.DirPath)
+		pkg.GetLogger().Infoln("DlSub End", seriesInfo.DirPath)
 	}()
-	model.GetLogger().Infoln("DlSub Start", seriesInfo.DirPath)
-	model.GetLogger().Debugln(seriesInfo.Name, "IMDB ID:", seriesInfo.ImdbId, "NeedDownloadSubs:", len(seriesInfo.NeedDlEpsKeyList))
-	var outSUbInfos = make([]common.SupplierSubInfo, 0)
+	pkg.GetLogger().Infoln("DlSub Start", seriesInfo.DirPath)
+	pkg.GetLogger().Debugln(seriesInfo.Name, "IMDB ID:", seriesInfo.ImdbId, "NeedDownloadSubs:", len(seriesInfo.NeedDlEpsKeyList))
+	var outSUbInfos = make([]supplier.SubInfo, 0)
 	if len(seriesInfo.NeedDlEpsKeyList) < 1 {
 		return outSUbInfos
 	}
 	for key, _ := range seriesInfo.NeedDlEpsKeyList {
-		model.GetLogger().Debugln(key)
+		pkg.GetLogger().Debugln(key)
 	}
 	// 同时进行查询
-	subInfosChannel := make(chan []common.SupplierSubInfo)
+	subInfosChannel := make(chan []supplier.SubInfo)
 	for _, supplier := range Suppliers {
 		supplier := supplier
 		go func() {
 			defer func() {
-				model.GetLogger().Infoln(i, supplier.GetSupplierName(), "End...")
+				pkg.GetLogger().Infoln(i, supplier.GetSupplierName(), "End...")
 			}()
-			model.GetLogger().Infoln(i, supplier.GetSupplierName(), "Start...")
+			pkg.GetLogger().Infoln(i, supplier.GetSupplierName(), "Start...")
 			// 一次性把这一部连续剧的所有字幕下载完
 			subInfos, err := supplier.GetSubListFromFile4Series(seriesInfo)
 			if err != nil {
-				model.GetLogger().Errorln(supplier.GetSupplierName(), "GetSubListFromFile4Series", err)
+				pkg.GetLogger().Errorln(supplier.GetSupplierName(), "GetSubListFromFile4Series", err)
 			}
 			// 把后缀名给改好
-			model.ChangeVideoExt2SubExt(subInfos)
+			pkg.ChangeVideoExt2SubExt(subInfos)
 
 			subInfosChannel <- subInfos
 		}()
@@ -191,7 +195,7 @@ func GetSeriesList(dir string) ([]string, error) {
 		if curFile.IsDir() == false {
 
 			// 如果发现有 tvshow.nfo 文件,那么就任务这个目录就是剧集的目录
-			if strings.ToLower(curFile.Name()) == model.MetadateTVNfo {
+			if strings.ToLower(curFile.Name()) == pkg.MetadateTVNfo {
 				seriesDirList = make([]string, 0)
 				seriesDirList = append(seriesDirList, dir)
 				return seriesDirList, nil
@@ -206,12 +210,12 @@ func GetSeriesList(dir string) ([]string, error) {
 }
 
 // whichSeasonEpsNeedDownloadSub 有那些 Eps 需要下载的,按 SxEx 反回 epsKey
-func whichSeasonEpsNeedDownloadSub(seriesInfo *common.SeriesInfo) (map[string]common.EpisodeInfo, map[int]int) {
-	var needDlSubEpsList = make(map[string]common.EpisodeInfo, 0)
+func whichSeasonEpsNeedDownloadSub(seriesInfo *series.SeriesInfo) (map[string]series.EpisodeInfo, map[int]int) {
+	var needDlSubEpsList = make(map[string]series.EpisodeInfo, 0)
 	var needDlSeasonList = make(map[int]int, 0)
 	currentTime := time.Now()
 	// 3个月
-	dayRange, _ := time.ParseDuration(common.DownloadSubDuring3Months)
+	dayRange, _ := time.ParseDuration(common2.DownloadSubDuring3Months)
 	for _, epsInfo := range seriesInfo.EpList {
 		// 如果没有字幕,则加入下载列表
 		// 如果每一集的播出时间能够读取到,那么就以这个完后推算 3个月
@@ -221,7 +225,7 @@ func whichSeasonEpsNeedDownloadSub(seriesInfo *common.SeriesInfo) (map[string]co
 		if epsInfo.AiredTime != "" {
 			baseTime, err = now.Parse(epsInfo.AiredTime)
 			if err != nil {
-				model.GetLogger().Errorln("SeriesInfo parse AiredTime", err)
+				pkg.GetLogger().Errorln("SeriesInfo parse AiredTime", err)
 				baseTime = epsInfo.ModifyTime
 			}
 		} else {
@@ -230,24 +234,24 @@ func whichSeasonEpsNeedDownloadSub(seriesInfo *common.SeriesInfo) (map[string]co
 
 		if len(epsInfo.SubAlreadyDownloadedList) < 1 || baseTime.Add(dayRange).After(currentTime) == true {
 			// 添加
-			epsKey := model.GetEpisodeKeyName(epsInfo.Season, epsInfo.Episode)
+			epsKey := pkg.GetEpisodeKeyName(epsInfo.Season, epsInfo.Episode)
 			needDlSubEpsList[epsKey] = epsInfo
 			needDlSeasonList[epsInfo.Season] = epsInfo.Season
 		} else {
 			if len(epsInfo.SubAlreadyDownloadedList) > 0 {
-				model.GetLogger().Infoln("Skip because find sub file and downloaded or aired over 3 months,", epsInfo.Title, epsInfo.Season, epsInfo.Episode)
+				pkg.GetLogger().Infoln("Skip because find sub file and downloaded or aired over 3 months,", epsInfo.Title, epsInfo.Season, epsInfo.Episode)
 			} else if baseTime.Add(dayRange).After(currentTime) == false {
-				model.GetLogger().Infoln("Skip because 3 months pass,", epsInfo.Title, epsInfo.Season, epsInfo.Episode)
+				pkg.GetLogger().Infoln("Skip because 3 months pass,", epsInfo.Title, epsInfo.Season, epsInfo.Episode)
 			}
 		}
 	}
 	return needDlSubEpsList, needDlSeasonList
 }
 
-func getSeriesInfoFromDir(seriesDir string, imdbInfo *imdb.Title) (*common.SeriesInfo, error) {
-	seriesInfo := common.SeriesInfo{}
+func getSeriesInfoFromDir(seriesDir string, imdbInfo *imdb.Title) (*series.SeriesInfo, error) {
+	seriesInfo := series.SeriesInfo{}
 	// 只考虑 IMDB 去查询,文件名目前发现可能会跟电影重复,导致很麻烦,本来也有前置要求要削刮器处理的
-	videoInfo, err := model.GetImdbInfo4SeriesDir(seriesDir)
+	videoInfo, err := pkg.GetImdbInfo4SeriesDir(seriesDir)
 	if err != nil {
 		return nil, err
 	}
@@ -264,35 +268,35 @@ func getSeriesInfoFromDir(seriesDir string, imdbInfo *imdb.Title) (*common.Serie
 		if err != nil {
 			// 不是必须的
 			seriesInfo.Year = 0
-			model.GetLogger().Warnln("ReadSeriesInfoFromDir.GetImdbInfo4SeriesDir.strconv.Atoi", err)
+			pkg.GetLogger().Warnln("ReadSeriesInfoFromDir.GetImdbInfo4SeriesDir.strconv.Atoi", err)
 		} else {
 			seriesInfo.Year = iYear
 		}
 	}
 	seriesInfo.ReleaseDate = videoInfo.ReleaseDate
 	seriesInfo.DirPath = seriesDir
-	seriesInfo.EpList = make([]common.EpisodeInfo, 0)
+	seriesInfo.EpList = make([]series.EpisodeInfo, 0)
 	seriesInfo.SeasonDict = make(map[int]int)
 	return &seriesInfo, nil
 }
 
-func getEpsInfoAndSubDic(videoFile string, EpisodeDict map[string]common.EpisodeInfo, SubDict map[string][]common.SubInfo) {
+func getEpsInfoAndSubDic(videoFile string, EpisodeDict map[string]series.EpisodeInfo, SubDict map[string][]series.SubInfo) {
 	// 正常来说,一集只有一个格式的视频,也就是 S01E01 只有一个,如果有多个则会只保存第一个
-	info, modifyTime, err := model.GetVideoInfoFromFileFullPath(videoFile)
+	info, modifyTime, err := pkg.GetVideoInfoFromFileFullPath(videoFile)
 	if err != nil {
-		model.GetLogger().Errorln("model.GetVideoInfoFromFileFullPath", err)
+		pkg.GetLogger().Errorln("model.GetVideoInfoFromFileFullPath", err)
 		return
 	}
-	episodeInfo, err := model.GetImdbInfo4OneSeriesEpisode(videoFile)
+	episodeInfo, err := pkg.GetImdbInfo4OneSeriesEpisode(videoFile)
 	if err != nil {
-		model.GetLogger().Errorln("model.GetImdbInfo4OneSeriesEpisode", err)
+		pkg.GetLogger().Errorln("model.GetImdbInfo4OneSeriesEpisode", err)
 		return
 	}
-	epsKey := model.GetEpisodeKeyName(info.Season, info.Episode)
+	epsKey := pkg.GetEpisodeKeyName(info.Season, info.Episode)
 	_, ok := EpisodeDict[epsKey]
 	if ok == false {
 		// 初始化
-		oneFileEpInfo := common.EpisodeInfo{
+		oneFileEpInfo := series.EpisodeInfo{
 			Title:        info.Title,
 			Season:       info.Season,
 			Episode:      info.Episode,
@@ -302,7 +306,7 @@ func getEpsInfoAndSubDic(videoFile string, EpisodeDict map[string]common.Episode
 			AiredTime:    episodeInfo.ReleaseDate,
 		}
 		// 需要匹配同级目录下的字幕
-		oneFileEpInfo.SubAlreadyDownloadedList = make([]common.SubInfo, 0)
+		oneFileEpInfo.SubAlreadyDownloadedList = make([]series.SubInfo, 0)
 		for _, subInfo := range SubDict[epsKey] {
 			if subInfo.Dir == oneFileEpInfo.Dir {
 				oneFileEpInfo.SubAlreadyDownloadedList = append(oneFileEpInfo.SubAlreadyDownloadedList, subInfo)

+ 0 - 0
series_helper/seriesHelper_test.go → internal/logic/series_helper/seriesHelper_test.go


+ 12 - 11
sub_parser/ass/ass.go → internal/logic/sub_parser/ass/ass.go

@@ -1,8 +1,9 @@
 package ass
 
 import (
-	"github.com/allanpk716/ChineseSubFinder/common"
-	"github.com/allanpk716/ChineseSubFinder/model"
+	common2 "github.com/allanpk716/ChineseSubFinder/internal/common"
+	"github.com/allanpk716/ChineseSubFinder/internal/pkg"
+	"github.com/allanpk716/ChineseSubFinder/internal/types/subparser"
 	"io/ioutil"
 	"path/filepath"
 	"regexp"
@@ -22,16 +23,16 @@ func (p Parser) GetParserName() string {
 }
 
 // DetermineFileTypeFromFile 确定字幕文件的类型,是双语字幕或者某一种语言等等信息
-func (p Parser) DetermineFileTypeFromFile(filePath string) (*common.SubParserFileInfo, error) {
+func (p Parser) DetermineFileTypeFromFile(filePath string) (*subparser.FileInfo, error) {
 	nowExt := filepath.Ext(filePath)
-	if strings.ToLower(nowExt) != common.SubExtASS && strings.ToLower(nowExt) != common.SubExtSSA {
+	if strings.ToLower(nowExt) != common2.SubExtASS && strings.ToLower(nowExt) != common2.SubExtSSA {
 		return nil ,nil
 	}
 	fBytes, err := ioutil.ReadFile(filePath)
 	if err != nil {
 		return nil ,err
 	}
-	inBytes, err := model.ChangeFileCoding2UTF8(fBytes)
+	inBytes, err := pkg.ChangeFileCoding2UTF8(fBytes)
 	if err != nil {
 		return nil, err
 	}
@@ -39,7 +40,7 @@ func (p Parser) DetermineFileTypeFromFile(filePath string) (*common.SubParserFil
 }
 
 // DetermineFileTypeFromBytes 确定字幕文件的类型,是双语字幕或者某一种语言等等信息
-func (p Parser) DetermineFileTypeFromBytes(inBytes []byte, nowExt string) (*common.SubParserFileInfo, error){
+func (p Parser) DetermineFileTypeFromBytes(inBytes []byte, nowExt string) (*subparser.FileInfo, error){
 	allString :=string(inBytes)
 	// 注意,需要替换掉 \r 不然正则表达式会有问题
 	allString = strings.ReplaceAll(allString, "\r", "")
@@ -49,9 +50,9 @@ func (p Parser) DetermineFileTypeFromBytes(inBytes []byte, nowExt string) (*comm
 	if len(matched) < 1 {
 		return nil ,nil
 	}
-	subFileInfo := common.SubParserFileInfo{}
+	subFileInfo := subparser.FileInfo{}
 	subFileInfo.Ext = nowExt
-	subFileInfo.Dialogues = make([]common.OneDialogue, 0)
+	subFileInfo.Dialogues = make([]subparser.OneDialogue, 0)
 	// 这里需要统计一共有几个 \N,以及这个数量在整体行数中的比例,这样就知道是不是双语字幕了
 	countLineFeed := 0
 	// 有意义的对话统计数,排除 Style 类型
@@ -80,7 +81,7 @@ func (p Parser) DetermineFileTypeFromBytes(inBytes []byte, nowExt string) (*comm
 		endTime := oneLine[2]
 		nowStyleName := oneLine[3]
 		nowText := oneLine[4]
-		odl := common.OneDialogue{
+		odl := subparser.OneDialogue{
 			StyleName: nowStyleName,
 			StartTime: startTime,
 			EndTime: endTime,
@@ -118,10 +119,10 @@ func (p Parser) DetermineFileTypeFromBytes(inBytes []byte, nowExt string) (*comm
 	langDict = make(map[int]int)
 	var chLines = make([]string, 0)
 	for _, dialogue := range subFileInfo.Dialogues {
-		model.DetectSubLangAndStatistics(dialogue.Lines, langDict, &chLines)
+		pkg.DetectSubLangAndStatistics(dialogue.Lines, langDict, &chLines)
 	}
 	// 从统计出来的字典,找出 Top 1 或者 2 的出来,然后计算出是什么语言的字幕
-	detectLang := model.SubLangStatistics2SubLangType(float32(countLineFeed), float32(usefullDialogueCount), langDict, chLines)
+	detectLang := pkg.SubLangStatistics2SubLangType(float32(countLineFeed), float32(usefullDialogueCount), langDict, chLines)
 	subFileInfo.Lang = detectLang
 	subFileInfo.Data = inBytes
 	return &subFileInfo, nil

+ 0 - 0
sub_parser/ass/ass_test.go → internal/logic/sub_parser/ass/ass_test.go


+ 12 - 11
sub_parser/srt/srt.go → internal/logic/sub_parser/srt/srt.go

@@ -1,8 +1,9 @@
 package srt
 
 import (
-	"github.com/allanpk716/ChineseSubFinder/common"
-	"github.com/allanpk716/ChineseSubFinder/model"
+	common2 "github.com/allanpk716/ChineseSubFinder/internal/common"
+	"github.com/allanpk716/ChineseSubFinder/internal/pkg"
+	"github.com/allanpk716/ChineseSubFinder/internal/types/subparser"
 	"io/ioutil"
 	"path/filepath"
 	"regexp"
@@ -22,16 +23,16 @@ func (p Parser) GetParserName() string {
 }
 
 // DetermineFileTypeFromFile 确定字幕文件的类型,是双语字幕或者某一种语言等等信息
-func (p Parser) DetermineFileTypeFromFile(filePath string) (*common.SubParserFileInfo, error) {
+func (p Parser) DetermineFileTypeFromFile(filePath string) (*subparser.FileInfo, error) {
 	nowExt := filepath.Ext(filePath)
-	if strings.ToLower(nowExt) != common.SubExtSRT {
+	if strings.ToLower(nowExt) != common2.SubExtSRT {
 		return nil ,nil
 	}
 	fBytes, err := ioutil.ReadFile(filePath)
 	if err != nil {
 		return nil ,err
 	}
-	inBytes, err := model.ChangeFileCoding2UTF8(fBytes)
+	inBytes, err := pkg.ChangeFileCoding2UTF8(fBytes)
 	if err != nil {
 		return nil, err
 	}
@@ -39,7 +40,7 @@ func (p Parser) DetermineFileTypeFromFile(filePath string) (*common.SubParserFil
 }
 
 // DetermineFileTypeFromBytes 确定字幕文件的类型,是双语字幕或者某一种语言等等信息
-func (p Parser) DetermineFileTypeFromBytes(inBytes []byte, nowExt string) (*common.SubParserFileInfo, error){
+func (p Parser) DetermineFileTypeFromBytes(inBytes []byte, nowExt string) (*subparser.FileInfo, error){
 
 	allString := string(inBytes)
 	// 注意,需要替换掉 \r 不然正则表达式会有问题
@@ -50,16 +51,16 @@ func (p Parser) DetermineFileTypeFromBytes(inBytes []byte, nowExt string) (*comm
 	if len(matched) < 1 {
 		return nil ,nil
 	}
-	subFileInfo := common.SubParserFileInfo{}
+	subFileInfo := subparser.FileInfo{}
 	subFileInfo.Ext = nowExt
-	subFileInfo.Dialogues = make([]common.OneDialogue, 0)
+	subFileInfo.Dialogues = make([]subparser.OneDialogue, 0)
 	// 这里需要统计一共有几个 \N,以及这个数量在整体行数中的比例,这样就知道是不是双语字幕了
 	countLineFeed := 0
 	for _, oneDial := range matched {
 		startTime := oneDial[2]
 		endTime := oneDial[3]
 		nowText := oneDial[4]
-		odl := common.OneDialogue{
+		odl := subparser.OneDialogue{
 			StartTime: startTime,
 			EndTime: endTime,
 		}
@@ -81,10 +82,10 @@ func (p Parser) DetermineFileTypeFromBytes(inBytes []byte, nowExt string) (*comm
 	langDict = make(map[int]int)
 	var chLines = make([]string, 0)
 	for _, dialogue := range subFileInfo.Dialogues {
-		model.DetectSubLangAndStatistics(dialogue.Lines, langDict, &chLines)
+		pkg.DetectSubLangAndStatistics(dialogue.Lines, langDict, &chLines)
 	}
 	// 从统计出来的字典,找出 Top 1 或者 2 的出来,然后计算出是什么语言的字幕
-	detectLang := model.SubLangStatistics2SubLangType(float32(countLineFeed), float32(len(matched)), langDict, chLines)
+	detectLang := pkg.SubLangStatistics2SubLangType(float32(countLineFeed), float32(len(matched)), langDict, chLines)
 	subFileInfo.Lang = detectLang
 	subFileInfo.Data = inBytes
 	return &subFileInfo, nil

+ 0 - 0
sub_parser/srt/srt_test.go → internal/logic/sub_parser/srt/srt_test.go


+ 26 - 23
sub_supplier/shooter/shooter.go → internal/logic/sub_supplier/shooter/shooter.go

@@ -3,8 +3,11 @@ package shooter
 import (
 	"crypto/md5"
 	"fmt"
-	"github.com/allanpk716/ChineseSubFinder/common"
-	"github.com/allanpk716/ChineseSubFinder/model"
+	common2 "github.com/allanpk716/ChineseSubFinder/internal/common"
+	"github.com/allanpk716/ChineseSubFinder/internal/pkg"
+	"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"
@@ -13,16 +16,16 @@ import (
 )
 
 type Supplier struct {
-	reqParam common.ReqParam
+	reqParam types.ReqParam
 	log      *logrus.Logger
 	topic    int
 }
 
-func NewSupplier(_reqParam ...common.ReqParam) *Supplier {
+func NewSupplier(_reqParam ...types.ReqParam) *Supplier {
 
 	sup := Supplier{}
-	sup.log = model.GetLogger()
-	sup.topic = common.DownloadSubsPerSite
+	sup.log = pkg.GetLogger()
+	sup.topic = common2.DownloadSubsPerSite
 	if len(_reqParam) > 0 {
 		sup.reqParam = _reqParam[0]
 		if sup.reqParam.Topic > 0 && sup.reqParam.Topic != sup.topic {
@@ -33,30 +36,30 @@ func NewSupplier(_reqParam ...common.ReqParam) *Supplier {
 }
 
 func (s Supplier) GetSupplierName() string {
-	return common.SubSiteShooter
+	return common2.SubSiteShooter
 }
 
-func (s Supplier) GetReqParam() common.ReqParam{
+func (s Supplier) GetReqParam() types.ReqParam {
 	return s.reqParam
 }
 
-func (s Supplier) GetSubListFromFile4Movie(filePath string) ([]common.SupplierSubInfo, error){
+func (s Supplier) GetSubListFromFile4Movie(filePath string) ([]supplier.SubInfo, error){
 	return s.getSubListFromFile(filePath)
 }
 
-func (s Supplier) GetSubListFromFile4Series(seriesInfo *common.SeriesInfo) ([]common.SupplierSubInfo, error) {
+func (s Supplier) GetSubListFromFile4Series(seriesInfo *series.SeriesInfo) ([]supplier.SubInfo, error) {
 	return s.downloadSub4Series(seriesInfo)
 }
 
-func (s Supplier) GetSubListFromFile4Anime(seriesInfo *common.SeriesInfo) ([]common.SupplierSubInfo, error){
+func (s Supplier) GetSubListFromFile4Anime(seriesInfo *series.SeriesInfo) ([]supplier.SubInfo, error){
 	return s.downloadSub4Series(seriesInfo)
 }
 
-func (s Supplier) getSubListFromFile(filePath string) ([]common.SupplierSubInfo, error) {
+func (s Supplier) getSubListFromFile(filePath string) ([]supplier.SubInfo, error) {
 
 	// 可以提供的字幕查询 eng或者chn
 	const qLan = "Chn"
-	var outSubInfoList []common.SupplierSubInfo
+	var outSubInfoList []supplier.SubInfo
 	var jsonList []SublistShooter
 
 	hash, err := s.computeFileHash(filePath)
@@ -64,12 +67,12 @@ func (s Supplier) getSubListFromFile(filePath string) ([]common.SupplierSubInfo,
 		return nil, err
 	}
 	if hash == "" {
-		return nil, common.ShooterFileHashIsEmpty
+		return nil, common2.ShooterFileHashIsEmpty
 	}
 
 	fileName := filepath.Base(filePath)
 
-	httpClient := model.NewHttpClient(s.reqParam)
+	httpClient := pkg.NewHttpClient(s.reqParam)
 
 	_, err = httpClient.R().
 		SetFormData(map[string]string{
@@ -79,7 +82,7 @@ func (s Supplier) getSubListFromFile(filePath string) ([]common.SupplierSubInfo,
 			"lang": qLan,
 		}).
 		SetResult(&jsonList).
-		Post(common.SubShooterRootUrl)
+		Post(common2.SubShooterRootUrl)
 	if err != nil {
 		return nil, err
 	}
@@ -90,13 +93,13 @@ func (s Supplier) getSubListFromFile(filePath string) ([]common.SupplierSubInfo,
 				subExt = "." + subExt
 			}
 
-			data, _, err := model.DownFile(file.Link)
+			data, _, err := pkg.DownFile(file.Link)
 			if err != nil {
 				s.log.Error(err)
 				continue
 			}
 
-			onSub := common.NewSupplierSubInfo(s.GetSupplierName(), int64(i), fileName, common.ChineseSimple, file.Link, 0, shooter.Delay, subExt, data)
+			onSub := supplier.NewSubInfo(s.GetSupplierName(), int64(i), fileName, types.ChineseSimple, file.Link, 0, shooter.Delay, subExt, data)
 			outSubInfoList = append(outSubInfoList, *onSub)
 			// 如果够了那么多个字幕就返回
 			if len(outSubInfoList) >= s.topic {
@@ -109,7 +112,7 @@ func (s Supplier) getSubListFromFile(filePath string) ([]common.SupplierSubInfo,
 	return outSubInfoList, nil
 }
 
-func (s Supplier) getSubListFromKeyword(keyword string) ([]common.SupplierSubInfo, error) {
+func (s Supplier) getSubListFromKeyword(keyword string) ([]supplier.SubInfo, error) {
 	panic("not implemented")
 }
 
@@ -126,7 +129,7 @@ func (s Supplier) computeFileHash(filePath string) (string, error) {
 	}
 	size := float64(stat.Size())
 	if size < 0xF000 {
-		return "", common.VideoFileIsTooSmall
+		return "", common2.VideoFileIsTooSmall
 	}
 	samplePositions := [4]int64{
 		4 * 1024,
@@ -151,8 +154,8 @@ func (s Supplier) computeFileHash(filePath string) (string, error) {
 	return hash, nil
 }
 
-func (s Supplier) downloadSub4Series(seriesInfo *common.SeriesInfo) ([]common.SupplierSubInfo, error) {
-	var allSupplierSubInfo = make([]common.SupplierSubInfo, 0)
+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)
@@ -166,7 +169,7 @@ func (s Supplier) downloadSub4Series(seriesInfo *common.SeriesInfo) ([]common.Su
 		}
 		allSupplierSubInfo = append(allSupplierSubInfo, one...)
 	}
-	// 返回前,需要把每一个 Eps 的 Season Episode 信息填充到每个 SupplierSubInfo 中
+	// 返回前,需要把每一个 Eps 的 Season Episode 信息填充到每个 SubInfo 中
 	return allSupplierSubInfo, nil
 }
 

+ 2 - 2
sub_supplier/shooter/shooter_test.go → internal/logic/sub_supplier/shooter/shooter_test.go

@@ -1,7 +1,7 @@
 package shooter
 
 import (
-	"github.com/allanpk716/ChineseSubFinder/common"
+	"github.com/allanpk716/ChineseSubFinder/internal/types"
 	"testing"
 )
 
@@ -12,7 +12,7 @@ func TestNewSupplier(t *testing.T) {
 	//movie1 := "X:\\电影\\机动战士Z高达:星之继承者 (2005)\\机动战士Z高达:星之继承者 (2005) 1080p TrueHD.mkv"
 	//movie1 := "X:\\连续剧\\The Bad Batch\\Season 1\\The Bad Batch - S01E01 - Aftermath WEBDL-1080p.mkv"
 	movie1 := "X:\\电影\\An Invisible Sign (2010)\\An Invisible Sign (2010) 720p AAC.mp4"
-	shooter := NewSupplier(common.ReqParam{Topic: 3})
+	shooter := NewSupplier(types.ReqParam{Topic: 3})
 	outList, err := shooter.getSubListFromFile(movie1)
 	if err != nil {
 		t.Error(err)

+ 23 - 22
sub_supplier/subSupplierHub.go → internal/logic/sub_supplier/subSupplierHub.go

@@ -1,26 +1,27 @@
 package sub_supplier
 
 import (
-	"github.com/allanpk716/ChineseSubFinder/common"
-	"github.com/allanpk716/ChineseSubFinder/interface"
-	"github.com/allanpk716/ChineseSubFinder/model"
-	"github.com/allanpk716/ChineseSubFinder/movie_helper"
-	"github.com/allanpk716/ChineseSubFinder/series_helper"
+	_interface2 "github.com/allanpk716/ChineseSubFinder/internal/interface"
+	movie_helper2 "github.com/allanpk716/ChineseSubFinder/internal/logic/movie_helper"
+	series_helper2 "github.com/allanpk716/ChineseSubFinder/internal/logic/series_helper"
+	"github.com/allanpk716/ChineseSubFinder/internal/pkg"
+	"github.com/allanpk716/ChineseSubFinder/internal/types/emby"
+	"github.com/allanpk716/ChineseSubFinder/internal/types/series"
 	"github.com/sirupsen/logrus"
 	"gopkg.in/errgo.v2/fmt/errors"
 	"path/filepath"
 )
 
 type SubSupplierHub struct {
-	Suppliers []_interface.ISupplier
+	Suppliers []_interface2.ISupplier
 
 	log *logrus.Logger
 }
 
-func NewSubSupplierHub(one _interface.ISupplier,_inSupplier ..._interface.ISupplier) *SubSupplierHub {
+func NewSubSupplierHub(one _interface2.ISupplier,_inSupplier ..._interface2.ISupplier) *SubSupplierHub {
 	s := SubSupplierHub{}
-	s.log = model.GetLogger()
-	s.Suppliers = make([]_interface.ISupplier, 0)
+	s.log = pkg.GetLogger()
+	s.Suppliers = make([]_interface2.ISupplier, 0)
 	s.Suppliers = append(s.Suppliers, one)
 	if len(_inSupplier) > 0 {
 		for _, supplier := range _inSupplier {
@@ -35,7 +36,7 @@ func NewSubSupplierHub(one _interface.ISupplier,_inSupplier ..._interface.ISuppl
 func (d SubSupplierHub) DownloadSub4Movie(videoFullPath string, index int) ([]string, error) {
 
 	// 跳过中文的电影,不是一定要跳过的
-	skip, err := movie_helper.SkipChineseMovie(videoFullPath, d.Suppliers[0].GetReqParam())
+	skip, err := movie_helper2.SkipChineseMovie(videoFullPath, d.Suppliers[0].GetReqParam())
 	if err != nil {
 		d.log.Warnln("SkipChineseMovie", videoFullPath, err)
 	}
@@ -43,16 +44,16 @@ func (d SubSupplierHub) DownloadSub4Movie(videoFullPath string, index int) ([]st
 		return nil, nil
 	}
 
-	needDlSub, err := movie_helper.MovieNeedDlSub(videoFullPath)
+	needDlSub, err := movie_helper2.MovieNeedDlSub(videoFullPath)
 	if err != nil {
 		return nil, errors.Newf("MovieNeedDlSub %v %v", videoFullPath , err)
 	}
 	if needDlSub == true {
 		// 需要下载字幕
 		// 下载所有字幕
-		subInfos := movie_helper.OneMovieDlSubInAllSite(d.Suppliers, videoFullPath, index)
+		subInfos := movie_helper2.OneMovieDlSubInAllSite(d.Suppliers, videoFullPath, index)
 		// 整理字幕,比如解压什么的
-		organizeSubFiles, err := model.OrganizeDlSubFiles(filepath.Base(videoFullPath), subInfos)
+		organizeSubFiles, err := pkg.OrganizeDlSubFiles(filepath.Base(videoFullPath), subInfos)
 		if err != nil {
 			return nil, errors.Newf("OrganizeDlSubFiles %v %v", videoFullPath , err)
 		}
@@ -69,10 +70,10 @@ func (d SubSupplierHub) DownloadSub4Movie(videoFullPath string, index int) ([]st
 }
 
 // DownloadSub4Series 某一部连续剧的字幕下载,下载完毕后,返回下载缓存每个字幕的位置
-func (d SubSupplierHub) DownloadSub4Series(seriesDirPath string, index int) (*common.SeriesInfo, map[string][]string, error) {
+func (d SubSupplierHub) DownloadSub4Series(seriesDirPath string, index int) (*series.SeriesInfo, map[string][]string, error) {
 
 	// 跳过中文的连续剧,不是一定要跳过的
-	skip, imdbInfo, err := series_helper.SkipChineseSeries(seriesDirPath, d.Suppliers[0].GetReqParam())
+	skip, imdbInfo, err := series_helper2.SkipChineseSeries(seriesDirPath, d.Suppliers[0].GetReqParam())
 	if err != nil {
 		d.log.Warnln("SkipChineseSeries", seriesDirPath, err)
 	}
@@ -80,7 +81,7 @@ func (d SubSupplierHub) DownloadSub4Series(seriesDirPath string, index int) (*co
 		return nil, nil, nil
 	}
 	// 读取本地的视频和字幕信息
-	seriesInfo, err := series_helper.ReadSeriesInfoFromDir(seriesDirPath, imdbInfo)
+	seriesInfo, err := series_helper2.ReadSeriesInfoFromDir(seriesDirPath, imdbInfo)
 	if err != nil {
 		return nil, nil, errors.Newf("ReadSeriesInfoFromDir %v %v", seriesDirPath , err)
 	}
@@ -92,10 +93,10 @@ func (d SubSupplierHub) DownloadSub4Series(seriesDirPath string, index int) (*co
 }
 
 // DownloadSub4SeriesFromEmby 通过 Emby 查询到的信息进行字幕下载,下载完毕后,返回下载缓存每个字幕的位置
-func (d SubSupplierHub) DownloadSub4SeriesFromEmby(seriesDirPath string, seriesList []common.EmbyMixInfo, index int) (*common.SeriesInfo, map[string][]string, error) {
+func (d SubSupplierHub) DownloadSub4SeriesFromEmby(seriesDirPath string, seriesList []emby.EmbyMixInfo, index int) (*series.SeriesInfo, map[string][]string, error) {
 
 	// 跳过中文的连续剧,不是一定要跳过的
-	skip, imdbInfo, err := series_helper.SkipChineseSeries(seriesDirPath, d.Suppliers[0].GetReqParam())
+	skip, imdbInfo, err := series_helper2.SkipChineseSeries(seriesDirPath, d.Suppliers[0].GetReqParam())
 	if err != nil {
 		d.log.Warnln("SkipChineseSeries", seriesDirPath, err)
 	}
@@ -103,7 +104,7 @@ func (d SubSupplierHub) DownloadSub4SeriesFromEmby(seriesDirPath string, seriesL
 		return nil, nil, nil
 	}
 	// 读取本地的视频和字幕信息
-	seriesInfo, err := series_helper.ReadSeriesInfoFromEmby(seriesDirPath, imdbInfo, seriesList)
+	seriesInfo, err := series_helper2.ReadSeriesInfoFromEmby(seriesDirPath, imdbInfo, seriesList)
 	if err != nil {
 		return nil, nil, errors.Newf("ReadSeriesInfoFromDir %v %v", seriesDirPath , err)
 	}
@@ -114,12 +115,12 @@ func (d SubSupplierHub) DownloadSub4SeriesFromEmby(seriesDirPath string, seriesL
 	return seriesInfo, organizeSubFiles, nil
 }
 
-func (d SubSupplierHub) dlSubFromSeriesInfo(seriesDirPath string, index int, seriesInfo *common.SeriesInfo, err error) (map[string][]string, error) {
+func (d SubSupplierHub) dlSubFromSeriesInfo(seriesDirPath string, index int, seriesInfo *series.SeriesInfo, err error) (map[string][]string, error) {
 	// 下载好的字幕
-	subInfos := series_helper.OneSeriesDlSubInAllSite(d.Suppliers, seriesInfo, index)
+	subInfos := series_helper2.OneSeriesDlSubInAllSite(d.Suppliers, seriesInfo, index)
 	// 整理字幕,比如解压什么的
 	// 每一集 SxEx - 对应解压整理后的字幕列表
-	organizeSubFiles, err := model.OrganizeDlSubFiles(filepath.Base(seriesDirPath), subInfos)
+	organizeSubFiles, err := pkg.OrganizeDlSubFiles(filepath.Base(seriesDirPath), subInfos)
 	if err != nil {
 		return nil, errors.Newf("OrganizeDlSubFiles %v %v", seriesDirPath, err)
 	}

+ 0 - 0
sub_supplier/subhd/.rod.backup → internal/logic/sub_supplier/subhd/.rod.backup


+ 54 - 51
sub_supplier/subhd/subhd.go → internal/logic/sub_supplier/subhd/subhd.go

@@ -5,8 +5,11 @@ import (
 	"fmt"
 	"github.com/PuerkitoBio/goquery"
 	"github.com/Tnze/go.num/v2/zh"
-	"github.com/allanpk716/ChineseSubFinder/common"
-	"github.com/allanpk716/ChineseSubFinder/model"
+	common2 "github.com/allanpk716/ChineseSubFinder/internal/common"
+	"github.com/allanpk716/ChineseSubFinder/internal/pkg"
+	"github.com/allanpk716/ChineseSubFinder/internal/types"
+	"github.com/allanpk716/ChineseSubFinder/internal/types/series"
+	"github.com/allanpk716/ChineseSubFinder/internal/types/supplier"
 	"github.com/go-rod/rod"
 	"github.com/go-rod/rod/lib/launcher"
 	"github.com/go-rod/rod/lib/proto"
@@ -25,17 +28,17 @@ import (
 )
 
 type Supplier struct {
-	reqParam    common.ReqParam
+	reqParam    types.ReqParam
 	log         *logrus.Logger
 	topic       int
 	rodLauncher *launcher.Launcher
 }
 
-func NewSupplier(_reqParam ...common.ReqParam) *Supplier {
+func NewSupplier(_reqParam ...types.ReqParam) *Supplier {
 
 	sup := Supplier{}
-	sup.log = model.GetLogger()
-	sup.topic = common.DownloadSubsPerSite
+	sup.log = pkg.GetLogger()
+	sup.topic = common2.DownloadSubsPerSite
 	if len(_reqParam) > 0 {
 		sup.reqParam = _reqParam[0]
 		if sup.reqParam.Topic > 0 && sup.reqParam.Topic != sup.topic {
@@ -46,20 +49,20 @@ func NewSupplier(_reqParam ...common.ReqParam) *Supplier {
 }
 
 func (s Supplier) GetSupplierName() string {
-	return common.SubSiteSubHd
+	return common2.SubSiteSubHd
 }
 
-func (s Supplier) GetReqParam() common.ReqParam{
+func (s Supplier) GetReqParam() types.ReqParam {
 	return s.reqParam
 }
 
-func (s Supplier) GetSubListFromFile4Movie(filePath string) ([]common.SupplierSubInfo, error){
+func (s Supplier) GetSubListFromFile4Movie(filePath string) ([]supplier.SubInfo, error){
 	return s.getSubListFromFile4Movie(filePath)
 }
 
-func (s Supplier) GetSubListFromFile4Series(seriesInfo *common.SeriesInfo) ([]common.SupplierSubInfo, error) {
+func (s Supplier) GetSubListFromFile4Series(seriesInfo *series.SeriesInfo) ([]supplier.SubInfo, error) {
 
-	var subInfos = make([]common.SupplierSubInfo, 0)
+	var subInfos = make([]supplier.SubInfo, 0)
 	var subList = make([]HdListItem, 0)
 	for value := range seriesInfo.NeedDlSeasonDict {
 		// 第一级界面,找到影片的详情界面
@@ -99,7 +102,7 @@ func (s Supplier) GetSubListFromFile4Series(seriesInfo *common.SeriesInfo) ([]co
 	// 下载字幕
 	var browser *rod.Browser
 	// 是用本地的 Browser 还是远程的,推荐是远程的
-	browser, err := model.NewBrowser(s.reqParam.HttpProxy)
+	browser, err := pkg.NewBrowser(s.reqParam.HttpProxy)
 	if err != nil {
 		return nil, err
 	}
@@ -110,7 +113,7 @@ func (s Supplier) GetSubListFromFile4Series(seriesInfo *common.SeriesInfo) ([]co
 			s.log.Errorln("subhd step2Ex", err)
 			continue
 		}
-		oneSubInfo := common.NewSupplierSubInfo(s.GetSupplierName(), int64(i), hdContent.Filename, common.ChineseSimple, model.AddBaseUrl(common.SubSubHDRootUrl, item.Url), 0,
+		oneSubInfo := supplier.NewSubInfo(s.GetSupplierName(), int64(i), hdContent.Filename, types.ChineseSimple, pkg.AddBaseUrl(common2.SubSubHDRootUrl, item.Url), 0,
 			0, hdContent.Ext, hdContent.Data)
 		oneSubInfo.Season = item.Season
 		oneSubInfo.Episode = item.Episode
@@ -120,11 +123,11 @@ func (s Supplier) GetSubListFromFile4Series(seriesInfo *common.SeriesInfo) ([]co
 	return subInfos, nil
 }
 
-func (s Supplier) GetSubListFromFile4Anime(seriesInfo *common.SeriesInfo) ([]common.SupplierSubInfo, error){
+func (s Supplier) GetSubListFromFile4Anime(seriesInfo *series.SeriesInfo) ([]supplier.SubInfo, error){
 	panic("not implemented")
 }
 
-func (s Supplier) getSubListFromFile4Movie(filePath string) ([]common.SupplierSubInfo, error) {
+func (s Supplier) getSubListFromFile4Movie(filePath string) ([]supplier.SubInfo, error) {
 	/*
 		虽然是传入视频文件路径,但是其实需要读取对应的视频文件目录下的
 		movie.xml 以及 *.nfo,找到 IMDB id
@@ -132,19 +135,19 @@ func (s Supplier) getSubListFromFile4Movie(filePath string) ([]common.SupplierSu
 		如果找不到,再靠文件名提取影片名称去查找
 	*/
 	// 得到这个视频文件名中的信息
-	info, _, err := model.GetVideoInfoFromFileFullPath(filePath)
+	info, _, err := pkg.GetVideoInfoFromFileFullPath(filePath)
 	if err != nil {
 		return nil, err
 	}
 	// 找到这个视频文件,尝试得到 IMDB ID
 	// 目前测试来看,加入 年 这个关键词去搜索,对 2020 年后的影片有利,因为网站有统一的详细页面了,而之前的,没有,会影响识别
 	// 所以,year >= 2020 年,则可以多加一个关键词(年)去搜索影片
-	imdbInfo, err := model.GetImdbInfo4Movie(filePath)
+	imdbInfo, err := pkg.GetImdbInfo4Movie(filePath)
 	if err != nil {
 		// 允许的错误,跳过,继续进行文件名的搜索
 		s.log.Errorln("model.GetImdbInfo", err)
 	}
-	var subInfoList []common.SupplierSubInfo
+	var subInfoList []supplier.SubInfo
 
 	if imdbInfo.ImdbId != "" {
 		// 先用 imdb id 找
@@ -160,7 +163,7 @@ func (s Supplier) getSubListFromFile4Movie(filePath string) ([]common.SupplierSu
 		}
 	}
 	// 如果没有,那么就用文件名查找
-	searchKeyword := model.VideoNameSearchKeywordMaker(info.Title, imdbInfo.Year)
+	searchKeyword := pkg.VideoNameSearchKeywordMaker(info.Title, imdbInfo.Year)
 	subInfoList, err = s.getSubListFromKeyword4Movie(searchKeyword)
 	if err != nil {
 		s.log.Errorln(s.GetSupplierName(), "keyword:", searchKeyword)
@@ -170,9 +173,9 @@ func (s Supplier) getSubListFromFile4Movie(filePath string) ([]common.SupplierSu
 	return subInfoList, nil
 }
 
-func (s Supplier) getSubListFromKeyword4Movie(keyword string) ([]common.SupplierSubInfo, error) {
+func (s Supplier) getSubListFromKeyword4Movie(keyword string) ([]supplier.SubInfo, error) {
 
-	var subInfos  []common.SupplierSubInfo
+	var subInfos  []supplier.SubInfo
 	detailPageUrl, err := s.step0(keyword)
 	if err != nil {
 		return nil, err
@@ -188,7 +191,7 @@ func (s Supplier) getSubListFromKeyword4Movie(keyword string) ([]common.Supplier
 
 	var browser *rod.Browser
 	// 是用本地的 Browser 还是远程的,推荐是远程的
-	browser, err = model.NewBrowser(s.reqParam.HttpProxy)
+	browser, err = pkg.NewBrowser(s.reqParam.HttpProxy)
 	if err != nil {
 		return nil, err
 	}
@@ -201,27 +204,27 @@ func (s Supplier) getSubListFromKeyword4Movie(keyword string) ([]common.Supplier
 			s.log.Errorln("step2Ex", err)
 			return nil, err
 		}
-		subInfos = append(subInfos, *common.NewSupplierSubInfo(s.GetSupplierName(), int64(i), hdContent.Filename, common.ChineseSimple, model.AddBaseUrl(common.SubSubHDRootUrl, item.Url), 0, 0, hdContent.Ext, hdContent.Data))
+		subInfos = append(subInfos, *supplier.NewSubInfo(s.GetSupplierName(), int64(i), hdContent.Filename, types.ChineseSimple, pkg.AddBaseUrl(common2.SubSubHDRootUrl, item.Url), 0, 0, hdContent.Ext, hdContent.Data))
 	}
 
 	return subInfos, nil
 }
 
-func (s Supplier) whichEpisodeNeedDownloadSub(seriesInfo *common.SeriesInfo, allSubList []HdListItem) []HdListItem {
+func (s Supplier) whichEpisodeNeedDownloadSub(seriesInfo *series.SeriesInfo, allSubList []HdListItem) []HdListItem {
 	// 字幕很多,考虑效率,需要做成字典
 	// key SxEx - SubInfos
-	var allSubDict = make(map[string][]HdListItem )
+	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 := model.GetSeasonAndEpisodeFromSubFileName(subInfo.Title)
+		_, season, episode, err := pkg.GetSeasonAndEpisodeFromSubFileName(subInfo.Title)
 		if err != nil {
 			s.log.Errorln("whichEpisodeNeedDownloadSub.GetVideoInfoFromFileFullPath", subInfo.Title, err)
 			continue
 		}
 		subInfo.Season = season
 		subInfo.Episode = episode
-		epsKey := model.GetEpisodeKeyName(season, episode)
+		epsKey := pkg.GetEpisodeKeyName(season, episode)
 		_, ok := allSubDict[epsKey]
 		if ok == false {
 			// 初始化
@@ -266,11 +269,11 @@ func (s Supplier) step0(keyword string) (string, error) {
 	var err error
 	defer func() {
 		if err != nil {
-			model.Notify.Add("subhd_step0", err.Error())
+			pkg.Notify.Add("subhd_step0", err.Error())
 		}
 	}()
 
-	result, err := s.httpGet(fmt.Sprintf(common.SubSubHDSearchUrl, url.QueryEscape(keyword)))
+	result, err := s.httpGet(fmt.Sprintf(common2.SubSubHDSearchUrl, url.QueryEscape(keyword)))
 	if err != nil {
 		return "", err
 	}
@@ -278,9 +281,9 @@ func (s Supplier) step0(keyword string) (string, error) {
 	re := regexp.MustCompile(`共\s*(\d+)\s*条`)
 	matched := re.FindAllStringSubmatch(result, -1)
 	if len(matched) < 1 {
-		return "",  common.SubHDStep0SubCountElementNotFound
+		return "", common2.SubHDStep0SubCountElementNotFound
 	}
-	subCount, err := model.GetNumber2int(matched[0][0])
+	subCount, err := pkg.GetNumber2int(matched[0][0])
 	if err != nil {
 		return "", err
 	}
@@ -298,7 +301,7 @@ func (s Supplier) step0(keyword string) (string, error) {
 	if ok == true{
 
 		if len(imgSelection.Nodes) < 2 {
-			return "",  common.SubHDStep0ImgParentLessThan2
+			return "", common2.SubHDStep0ImgParentLessThan2
 		}
 		step1Url := ""
 		if imgSelection.Nodes[0].Parent.Data == "a" {
@@ -319,7 +322,7 @@ func (s Supplier) step0(keyword string) (string, error) {
 			}
 		}
 		if step1Url == "" {
-			return "",  common.SubHDStep0HrefIsNull
+			return "", common2.SubHDStep0HrefIsNull
 		}
 		return step1Url, nil
 		//imgName := filepath.Base(imgUrl)
@@ -331,7 +334,7 @@ func (s Supplier) step0(keyword string) (string, error) {
 		//	return "/d/" + strings.ReplaceAll(imgName, imgExt, ""), nil
 		//}
 	} else{
-		return "",  common.SubHDStep0HrefIsNull
+		return "", common2.SubHDStep0HrefIsNull
 	}
 	//re = regexp.MustCompile(`<a\shref="(/d/[\w]+)">\s?<img`)
 	//matched = re.FindAllStringSubmatch(result, -1)
@@ -346,10 +349,10 @@ func (s Supplier) step1(detailPageUrl string, isMovieOrSeries bool) ([]HdListIte
 	var err error
 	defer func() {
 		if err != nil {
-			model.Notify.Add("subhd_step1", err.Error())
+			pkg.Notify.Add("subhd_step1", err.Error())
 		}
 	}()
-	detailPageUrl = model.AddBaseUrl(common.SubSubHDRootUrl, detailPageUrl)
+	detailPageUrl = pkg.AddBaseUrl(common2.SubSubHDRootUrl, detailPageUrl)
 	result, err := s.httpGet(detailPageUrl)
 	if err != nil {
 		return nil, err
@@ -378,18 +381,18 @@ func (s Supplier) step1(detailPageUrl string, isMovieOrSeries bool) ([]HdListIte
 		title := strings.TrimSpace(tr.Find(oneSubTrTitleKeyword).Text())
 		// 字幕类型
 		insideSubType := tr.Find(oneSubLangAndTypeKeyword).Text()
-		if model.IsSubTypeWanted(insideSubType) == false {
+		if pkg.IsSubTypeWanted(insideSubType) == false {
 			return true
 		}
 		// 下载的次数
-		downCount, err := model.GetNumber2int(tr.Find(oneSubTrDownloadCountKeyword).Eq(1).Text())
+		downCount, err := pkg.GetNumber2int(tr.Find(oneSubTrDownloadCountKeyword).Eq(1).Text())
 		if err != nil {
 			return true
 		}
 
 		listItem := HdListItem{}
 		listItem.Url = downUrl
-		listItem.BaseUrl = common.SubSubHDRootUrl
+		listItem.BaseUrl = common2.SubSubHDRootUrl
 		listItem.Title = title
 		listItem.DownCount = downCount
 
@@ -413,21 +416,21 @@ func (s Supplier) step2Ex(browser *rod.Browser, subDownloadPageUrl string) (*HdC
 	var err error
 	defer func() {
 		if err != nil {
-			model.Notify.Add("subhd_step2Ex", err.Error())
+			pkg.Notify.Add("subhd_step2Ex", err.Error())
 		}
 	}()
-	subDownloadPageUrl = model.AddBaseUrl(common.SubSubHDRootUrl, subDownloadPageUrl)
+	subDownloadPageUrl = pkg.AddBaseUrl(common2.SubSubHDRootUrl, subDownloadPageUrl)
 	// 默认超时是 60s,如果是调试模式则是 5 min
-	tt := common.HTMLTimeOut
+	tt := common2.HTMLTimeOut
 	if s.reqParam.DebugMode == true {
-		tt = common.OneVideoProcessTimeOut
+		tt = common2.OneVideoProcessTimeOut
 	}
-	page, err := model.NewPageNavigate(browser, subDownloadPageUrl, tt, 5)
+	page, err := pkg.NewPageNavigate(browser, subDownloadPageUrl, tt, 5)
 	if err != nil {
 		return nil, err
 	}
 	page.MustSetUserAgent(&proto.NetworkSetUserAgentOverride{
-		UserAgent: model.RandomUserAgent(true),
+		UserAgent: pkg.RandomUserAgent(true),
 	})
 	err = page.WaitLoad()
 	if err != nil {
@@ -451,7 +454,7 @@ func (s Supplier) step2Ex(browser *rod.Browser, subDownloadPageUrl string) (*HdC
 
 	if hasWaterWall == false && hasDownBtn == false {
 		// 都没有,则返回故障,无法下载
-		return nil, common.SubHDStep2ExCannotFindDownloadBtn
+		return nil, common2.SubHDStep2ExCannotFindDownloadBtn
 	}
 	// 下载字幕
 	content, err := s.downloadSubFile(browser, page, hasWaterWall, BtnElemenString)
@@ -542,7 +545,7 @@ func (s Supplier) passWaterWall(page *rod.Page)  {
 	shadowbg := slideBgEl.MustResource()
 	// 取得原始圖像
 	src := slideBgEl.MustProperty("src")
-	fullbg, _, err := model.DownFile(strings.Replace(src.String(), "img_index=1", "img_index=0", 1))
+	fullbg, _, err := pkg.DownFile(strings.Replace(src.String(), "img_index=1", "img_index=0", 1))
 	if err != nil {
 		panic(err)
 	}
@@ -612,7 +615,7 @@ search:
 
 	if s.reqParam.DebugMode == true {
 		//截圖保存
-		nowProcessRoot, err := model.GetDebugFolder()
+		nowProcessRoot, err := pkg.GetDebugFolder()
 		if err == nil {
 			page.MustScreenshot(path.Join(nowProcessRoot, "result.png"))
 		} else {
@@ -623,7 +626,7 @@ search:
 
 func (s Supplier) httpGet(url string) (string, error) {
 	s.reqParam.Referer = url
-	httpClient := model.NewHttpClient(s.reqParam)
+	httpClient := pkg.NewHttpClient(s.reqParam)
 	resp, err := httpClient.R().Get(url)
 	if err != nil {
 		return "", err
@@ -632,7 +635,7 @@ func (s Supplier) httpGet(url string) (string, error) {
 	//搜索验证 点击继续搜索
 	if strings.Contains(recvText, "搜索验证") || strings.Contains(recvText, "搜索频率") {
 		s.log.Debugln("搜索验证 or 搜索频率 reload", url)
-		time.Sleep(model.RandomSecondDuration(5, 10))
+		time.Sleep(pkg.RandomSecondDuration(5, 10))
 		return s.httpGet(url)
 	}
 	return resp.String(), nil

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

@@ -1,7 +1,7 @@
 package subhd
 
 import (
-	"github.com/allanpk716/ChineseSubFinder/series_helper"
+	series_helper2 "github.com/allanpk716/ChineseSubFinder/internal/logic/series_helper"
 	"testing"
 )
 
@@ -40,7 +40,7 @@ func TestSupplier_GetSubListFromFile4Series(t *testing.T) {
 
 
 	// 读取本地的视频和字幕信息
-	seriesInfo, err := series_helper.ReadSeriesInfoFromDir(ser, nil)
+	seriesInfo, err := series_helper2.ReadSeriesInfoFromDir(ser, nil)
 	if err != nil {
 		t.Fatal(err)
 	}

+ 30 - 27
sub_supplier/xunlei/xunlei.go → internal/logic/sub_supplier/xunlei/xunlei.go

@@ -3,8 +3,11 @@ package xunlei
 import (
 	"crypto/sha1"
 	"fmt"
-	"github.com/allanpk716/ChineseSubFinder/common"
-	"github.com/allanpk716/ChineseSubFinder/model"
+	common2 "github.com/allanpk716/ChineseSubFinder/internal/common"
+	"github.com/allanpk716/ChineseSubFinder/internal/pkg"
+	"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"
@@ -12,16 +15,16 @@ import (
 )
 
 type Supplier struct {
-	reqParam common.ReqParam
+	reqParam types.ReqParam
 	log      *logrus.Logger
 	topic    int
 }
 
-func NewSupplier(_reqParam ...common.ReqParam) *Supplier {
+func NewSupplier(_reqParam ...types.ReqParam) *Supplier {
 
 	sup := Supplier{}
-	sup.log = model.GetLogger()
-	sup.topic = common.DownloadSubsPerSite
+	sup.log = pkg.GetLogger()
+	sup.topic = common2.DownloadSubsPerSite
 	if len(_reqParam) > 0 {
 		sup.reqParam = _reqParam[0]
 		if sup.reqParam.Topic > 0 && sup.reqParam.Topic != sup.topic {
@@ -32,38 +35,38 @@ func NewSupplier(_reqParam ...common.ReqParam) *Supplier {
 }
 
 func (s Supplier) GetSupplierName() string {
-	return common.SubSiteXunLei
+	return common2.SubSiteXunLei
 }
 
-func (s Supplier) GetReqParam() common.ReqParam{
+func (s Supplier) GetReqParam() types.ReqParam {
 	return s.reqParam
 }
 
-func (s Supplier) GetSubListFromFile4Movie(filePath string) ([]common.SupplierSubInfo, error){
+func (s Supplier) GetSubListFromFile4Movie(filePath string) ([]supplier.SubInfo, error){
 	return s.getSubListFromFile(filePath)
 }
 
-func (s Supplier) GetSubListFromFile4Series(seriesInfo *common.SeriesInfo) ([]common.SupplierSubInfo, error) {
+func (s Supplier) GetSubListFromFile4Series(seriesInfo *series.SeriesInfo) ([]supplier.SubInfo, error) {
 	return s.downloadSub4Series(seriesInfo)
 }
 
-func (s Supplier) GetSubListFromFile4Anime(seriesInfo *common.SeriesInfo) ([]common.SupplierSubInfo, error){
+func (s Supplier) GetSubListFromFile4Anime(seriesInfo *series.SeriesInfo) ([]supplier.SubInfo, error){
 	return s.downloadSub4Series(seriesInfo)
 }
 
-func (s Supplier) getSubListFromFile(filePath string) ([]common.SupplierSubInfo, error) {
+func (s Supplier) getSubListFromFile(filePath string) ([]supplier.SubInfo, error) {
 
 	cid, err := s.getCid(filePath)
 	var jsonList SublistSliceXunLei
 	var tmpXunLeiSubListChinese = make([]SublistXunLei, 0)
-	var outSubList []common.SupplierSubInfo
+	var outSubList []supplier.SubInfo
 	if len(cid) == 0 {
-		return outSubList, common.XunLeiCIdIsEmpty
+		return outSubList, common2.XunLeiCIdIsEmpty
 	}
-	httpClient := model.NewHttpClient(s.reqParam)
+	httpClient := pkg.NewHttpClient(s.reqParam)
 	_, err = httpClient.R().
 		SetResult(&jsonList).
-		Get(fmt.Sprintf(common.SubXunLeiRootUrl, cid))
+		Get(fmt.Sprintf(common2.SubXunLeiRootUrl, cid))
 	if err != nil {
 		return outSubList, err
 	}
@@ -71,8 +74,8 @@ func (s Supplier) getSubListFromFile(filePath string) ([]common.SupplierSubInfo,
 	for _, v := range jsonList.Sublist {
 		if len(v.Scid) > 0 && v.Scid != "" {
 			// 符合中文语言的先加入列表
-			tmpLang := model.LangConverter(v.Language)
-			if model.HasChineseLang(tmpLang) == true && model.IsSubTypeWanted(v.Sname) == true {
+			tmpLang := pkg.LangConverter(v.Language)
+			if pkg.HasChineseLang(tmpLang) == true && pkg.IsSubTypeWanted(v.Sname) == true {
 				tmpXunLeiSubListChinese = append(tmpXunLeiSubListChinese, v)
 			}
 		}
@@ -85,8 +88,8 @@ func (s Supplier) getSubListFromFile(filePath string) ([]common.SupplierSubInfo,
 				break
 			}
 			if len(v.Scid) > 0 && v.Scid != "" {
-				tmpLang := model.LangConverter(v.Language)
-				if model.HasChineseLang(tmpLang) == false {
+				tmpLang := pkg.LangConverter(v.Language)
+				if pkg.HasChineseLang(tmpLang) == false {
 					tmpXunLeiSubListChinese = append(tmpXunLeiSubListChinese, v)
 				}
 			}
@@ -94,8 +97,8 @@ func (s Supplier) getSubListFromFile(filePath string) ([]common.SupplierSubInfo,
 	}
 	// 再开始下载字幕
 	for i, v := range tmpXunLeiSubListChinese {
-		tmpLang := model.LangConverter(v.Language)
-		data, filename, err := model.DownFile(v.Surl)
+		tmpLang := pkg.LangConverter(v.Language)
+		data, filename, err := pkg.DownFile(v.Surl)
 		if err != nil {
 			s.log.Error(err)
 			continue
@@ -107,14 +110,14 @@ func (s Supplier) getSubListFromFile(filePath string) ([]common.SupplierSubInfo,
 			ext = filepath.Ext(filename)
 		}
 
-		outSubList = append(outSubList, *common.NewSupplierSubInfo(s.GetSupplierName(), int64(i), v.Sname, tmpLang, v.Surl, v.Svote, v.Roffset, ext, data))
+		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) ([]common.SupplierSubInfo, error) {
+func (s Supplier) getSubListFromKeyword(keyword string) ([]supplier.SubInfo, error) {
 	panic("not implemented")
 }
 
@@ -155,8 +158,8 @@ func (s Supplier) getCid(filePath string) (string, error) {
 	return hash, nil
 }
 
-func (s Supplier) downloadSub4Series(seriesInfo *common.SeriesInfo) ([]common.SupplierSubInfo, error) {
-	var allSupplierSubInfo = make([]common.SupplierSubInfo, 0)
+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)
@@ -170,7 +173,7 @@ func (s Supplier) downloadSub4Series(seriesInfo *common.SeriesInfo) ([]common.Su
 		}
 		allSupplierSubInfo = append(allSupplierSubInfo, one...)
 	}
-	// 返回前,需要把每一个 Eps 的 Season Episode 信息填充到每个 SupplierSubInfo 中
+	// 返回前,需要把每一个 Eps 的 Season Episode 信息填充到每个 SubInfo 中
 	return allSupplierSubInfo, nil
 }
 

+ 2 - 2
sub_supplier/xunlei/xunlei_test.go → internal/logic/sub_supplier/xunlei/xunlei_test.go

@@ -1,7 +1,7 @@
 package xunlei
 
 import (
-	"github.com/allanpk716/ChineseSubFinder/common"
+	"github.com/allanpk716/ChineseSubFinder/internal/types"
 	"testing"
 )
 
@@ -12,7 +12,7 @@ func TestGetList(t *testing.T) {
 	//movie1:= "X:\\电影\\Spiral From the Book of Saw (2021)\\Spiral From the Book of Saw (2021) WEBDL-1080p.mkv"
 	//movie1 := "X:\\电影\\机动战士Z高达:星之继承者 (2005)\\机动战士Z高达:星之继承者 (2005) 1080p TrueHD.mkv"
 	//movie1 := "X:\\连续剧\\The Bad Batch\\Season 1\\The Bad Batch - S01E01 - Aftermath WEBDL-1080p.mkv"
-	xunlie := NewSupplier(common.ReqParam{Topic: 3})
+	xunlie := NewSupplier(types.ReqParam{Topic: 3})
 	outList, err := xunlie.getSubListFromFile(movie1)
 	if err != nil {
 		t.Error(err)

+ 55 - 52
sub_supplier/zimuku/zimuku.go → internal/logic/sub_supplier/zimuku/zimuku.go

@@ -4,8 +4,11 @@ import (
 	"fmt"
 	"github.com/PuerkitoBio/goquery"
 	"github.com/Tnze/go.num/v2/zh"
-	"github.com/allanpk716/ChineseSubFinder/common"
-	"github.com/allanpk716/ChineseSubFinder/model"
+	common2 "github.com/allanpk716/ChineseSubFinder/internal/common"
+	"github.com/allanpk716/ChineseSubFinder/internal/pkg"
+	"github.com/allanpk716/ChineseSubFinder/internal/types"
+	"github.com/allanpk716/ChineseSubFinder/internal/types/series"
+	"github.com/allanpk716/ChineseSubFinder/internal/types/supplier"
 	"github.com/sirupsen/logrus"
 	"path/filepath"
 	"regexp"
@@ -14,16 +17,16 @@ import (
 )
 
 type Supplier struct {
-	reqParam common.ReqParam
+	reqParam types.ReqParam
 	log      *logrus.Logger
 	topic    int
 }
 
-func NewSupplier(_reqParam ...common.ReqParam) *Supplier {
+func NewSupplier(_reqParam ...types.ReqParam) *Supplier {
 
 	sup := Supplier{}
-	sup.log = model.GetLogger()
-	sup.topic = common.DownloadSubsPerSite
+	sup.log = pkg.GetLogger()
+	sup.topic = common2.DownloadSubsPerSite
 	if len(_reqParam) > 0 {
 		sup.reqParam = _reqParam[0]
 		if sup.reqParam.Topic > 0 && sup.reqParam.Topic != sup.topic {
@@ -34,18 +37,18 @@ func NewSupplier(_reqParam ...common.ReqParam) *Supplier {
 }
 
 func (s Supplier) GetSupplierName() string {
-	return common.SubSiteZiMuKu
+	return common2.SubSiteZiMuKu
 }
 
-func (s Supplier) GetReqParam() common.ReqParam{
+func (s Supplier) GetReqParam() types.ReqParam {
 	return s.reqParam
 }
 
-func (s Supplier) GetSubListFromFile4Movie(filePath string) ([]common.SupplierSubInfo, error){
+func (s Supplier) GetSubListFromFile4Movie(filePath string) ([]supplier.SubInfo, error){
 	return s.getSubListFromMovie(filePath)
 }
 
-func (s Supplier) GetSubListFromFile4Series(seriesInfo *common.SeriesInfo) ([]common.SupplierSubInfo, error) {
+func (s Supplier) GetSubListFromFile4Series(seriesInfo *series.SeriesInfo) ([]supplier.SubInfo, error) {
 	var err error
 	/*
 		去网站搜索的时候,有个比较由意思的逻辑,有些剧集,哪怕只有一季,sonarr 也会给它命名为 Season 1
@@ -63,7 +66,7 @@ func (s Supplier) GetSubListFromFile4Series(seriesInfo *common.SeriesInfo) ([]co
 		if err != nil {
 			s.log.Errorln(keyword)
 			// 如果只是搜索不到,则继续换关键词
-			if err != common.ZiMuKuSearchKeyWordStep0DetailPageUrlNotFound {
+			if err != common2.ZiMuKuSearchKeyWordStep0DetailPageUrlNotFound {
 				return nil, err
 			}
 			keyword := seriesInfo.Name
@@ -94,15 +97,15 @@ func (s Supplier) GetSubListFromFile4Series(seriesInfo *common.SeriesInfo) ([]co
 	// 剩下的部分跟 GetSubListFroKeyword 一样,就是去下载了
 	outSubInfoList := s.whichSubInfoNeedDownload(subInfoNeedDownload, err)
 
-	// 返回前,需要把每一个 Eps 的 Season Episode 信息填充到每个 SupplierSubInfo 中
+	// 返回前,需要把每一个 Eps 的 Season Episode 信息填充到每个 SubInfo 中
 	return outSubInfoList, nil
 }
 
-func (s Supplier) GetSubListFromFile4Anime(seriesInfo *common.SeriesInfo) ([]common.SupplierSubInfo, error){
+func (s Supplier) GetSubListFromFile4Anime(seriesInfo *series.SeriesInfo) ([]supplier.SubInfo, error){
 	panic("not implemented")
 }
 
-func (s Supplier) getSubListFromMovie(fileFPath string) ([]common.SupplierSubInfo, error) {
+func (s Supplier) getSubListFromMovie(fileFPath string) ([]supplier.SubInfo, error) {
 
 	/*
 		虽然是传入视频文件路径,但是其实需要读取对应的视频文件目录下的
@@ -111,19 +114,19 @@ func (s Supplier) getSubListFromMovie(fileFPath string) ([]common.SupplierSubInf
 		如果找不到,再靠文件名提取影片名称去查找
 	*/
 	// 得到这个视频文件名中的信息
-	info, _, err := model.GetVideoInfoFromFileFullPath(fileFPath)
+	info, _, err := pkg.GetVideoInfoFromFileFullPath(fileFPath)
 	if err != nil {
 		return nil, err
 	}
 	// 找到这个视频文件,尝试得到 IMDB ID
 	// 目前测试来看,加入 年 这个关键词去搜索,对 2020 年后的影片有利,因为网站有统一的详细页面了,而之前的,没有,会影响识别
 	// 所以,year >= 2020 年,则可以多加一个关键词(年)去搜索影片
-	imdbInfo, err := model.GetImdbInfo4Movie(fileFPath)
+	imdbInfo, err := pkg.GetImdbInfo4Movie(fileFPath)
 	if err != nil {
 		// 允许的错误,跳过,继续进行文件名的搜索
 		s.log.Errorln("model.GetImdbInfo", err)
 	}
-	var subInfoList []common.SupplierSubInfo
+	var subInfoList []supplier.SubInfo
 
 	if imdbInfo.ImdbId != "" {
 		// 先用 imdb id 找
@@ -140,7 +143,7 @@ func (s Supplier) getSubListFromMovie(fileFPath string) ([]common.SupplierSubInf
 	}
 
 	// 如果没有,那么就用文件名查找
-	searchKeyword := model.VideoNameSearchKeywordMaker(info.Title, imdbInfo.Year)
+	searchKeyword := pkg.VideoNameSearchKeywordMaker(info.Title, imdbInfo.Year)
 	subInfoList, err = s.getSubListFromKeyword(searchKeyword)
 	if err != nil {
 		s.log.Errorln(s.GetSupplierName(), "keyword:", searchKeyword)
@@ -150,9 +153,9 @@ func (s Supplier) getSubListFromMovie(fileFPath string) ([]common.SupplierSubInf
 	return subInfoList, nil
 }
 
-func (s Supplier) getSubListFromKeyword(keyword string) ([]common.SupplierSubInfo, error) {
+func (s Supplier) getSubListFromKeyword(keyword string) ([]supplier.SubInfo, error) {
 
-	var outSubInfoList []common.SupplierSubInfo
+	var outSubInfoList []supplier.SubInfo
 	// 第一级界面,找到影片的详情界面
 	filmDetailPageUrl, err := s.step0(keyword)
 	if err != nil {
@@ -172,21 +175,21 @@ func (s Supplier) getSubListFromKeyword(keyword string) ([]common.SupplierSubInf
 	return outSubInfoList, nil
 }
 
-func (s Supplier) whichEpisodeNeedDownloadSub(seriesInfo *common.SeriesInfo, AllSeasonSubResult SubResult) []SubInfo {
+func (s Supplier) whichEpisodeNeedDownloadSub(seriesInfo *series.SeriesInfo, AllSeasonSubResult SubResult) []SubInfo {
 	// 字幕很多,考虑效率,需要做成字典
 	// key SxEx - SubInfos
 	var allSubDict = make(map[string]SubInfos)
 	// 全季的字幕列表
 	var oneSeasonSubDict  = make(map[string]SubInfos)
 	for _, subInfo := range AllSeasonSubResult.SubInfos {
-		_, season, episode, err := model.GetSeasonAndEpisodeFromSubFileName(subInfo.Name)
+		_, season, episode, err := pkg.GetSeasonAndEpisodeFromSubFileName(subInfo.Name)
 		if err != nil {
 			s.log.Errorln("whichEpisodeNeedDownloadSub.GetVideoInfoFromFileFullPath", subInfo.Name, err)
 			continue
 		}
 		subInfo.Season = season
 		subInfo.Episode = episode
-		epsKey := model.GetEpisodeKeyName(season, episode)
+		epsKey := pkg.GetEpisodeKeyName(season, episode)
 		_, ok := allSubDict[epsKey]
 		if ok == false {
 			// 初始化
@@ -226,9 +229,9 @@ func (s Supplier) whichEpisodeNeedDownloadSub(seriesInfo *common.SeriesInfo, All
 	return subInfoNeedDownload
 }
 
-func (s Supplier) whichSubInfoNeedDownload(subInfos SubInfos, err error) []common.SupplierSubInfo {
+func (s Supplier) whichSubInfoNeedDownload(subInfos SubInfos, err error) []supplier.SubInfo {
 
-	var outSubInfoList = make([]common.SupplierSubInfo, 0)
+	var outSubInfoList = make([]supplier.SubInfo, 0)
 	for i := range subInfos {
 		err = s.step2(&subInfos[i])
 		if err != nil {
@@ -241,8 +244,8 @@ func (s Supplier) whichSubInfoNeedDownload(subInfos SubInfos, err error) []commo
 	// 首先过滤出中文的字幕,同时需要满足是支持的字幕
 	var tmpSubInfo = make([]SubInfo, 0)
 	for _, subInfo := range subInfos {
-		tmpLang := model.LangConverter(subInfo.Lang)
-		if model.HasChineseLang(tmpLang) == true && model.IsSubTypeWanted(subInfo.Ext) == true {
+		tmpLang := pkg.LangConverter(subInfo.Lang)
+		if pkg.HasChineseLang(tmpLang) == true && pkg.IsSubTypeWanted(subInfo.Ext) == true {
 			tmpSubInfo = append(tmpSubInfo, subInfo)
 		}
 	}
@@ -252,8 +255,8 @@ func (s Supplier) whichSubInfoNeedDownload(subInfos SubInfos, err error) []commo
 			if len(tmpSubInfo) >= s.topic {
 				break
 			}
-			tmpLang := model.LangConverter(subInfo.Lang)
-			if model.HasChineseLang(tmpLang) == false {
+			tmpLang := pkg.LangConverter(subInfo.Lang)
+			if pkg.HasChineseLang(tmpLang) == false {
 				tmpSubInfo = append(tmpSubInfo, subInfo)
 			}
 		}
@@ -268,7 +271,7 @@ func (s Supplier) whichSubInfoNeedDownload(subInfos SubInfos, err error) []commo
 		}
 		// 默认都是包含中文字幕的,然后具体使用的时候再进行区分
 
-		oneSubInfo := common.NewSupplierSubInfo(s.GetSupplierName(), int64(i), fileName, common.ChineseSimple, model.AddBaseUrl(common.SubZiMuKuRootUrl, subInfo.SubDownloadPageUrl), 0,
+		oneSubInfo := supplier.NewSubInfo(s.GetSupplierName(), int64(i), fileName, types.ChineseSimple, pkg.AddBaseUrl(common2.SubZiMuKuRootUrl, subInfo.SubDownloadPageUrl), 0,
 			0, filepath.Ext(fileName), data)
 
 		oneSubInfo.Season = subInfo.Season
@@ -276,7 +279,7 @@ func (s Supplier) whichSubInfoNeedDownload(subInfos SubInfos, err error) []commo
 		outSubInfoList = append(outSubInfoList, *oneSubInfo)
 	}
 
-	// 返回前,需要把每一个 Eps 的 Season Episode 信息填充到每个 SupplierSubInfo 中
+	// 返回前,需要把每一个 Eps 的 Season Episode 信息填充到每个 SubInfo 中
 	return outSubInfoList
 }
 
@@ -285,16 +288,16 @@ func (s Supplier) step0(keyword string) (string, error) {
 	var err error
 	defer func() {
 		if err != nil {
-			model.Notify.Add("zimuku_step0", err.Error())
+			pkg.Notify.Add("zimuku_step0", err.Error())
 		}
 	}()
-	httpClient := model.NewHttpClient(s.reqParam)
+	httpClient := pkg.NewHttpClient(s.reqParam)
 	// 第一级界面,有多少个字幕
 	resp, err := httpClient.R().
 		SetQueryParams(map[string]string{
 			"q": keyword,
 		}).
-		Get(common.SubZiMuKuSearchUrl)
+		Get(common2.SubZiMuKuSearchUrl)
 	if err != nil {
 		return "", err
 	}
@@ -302,7 +305,7 @@ func (s Supplier) step0(keyword string) (string, error) {
 	re := regexp.MustCompile(`<p\s+class="tt\s+clearfix"><a\s+href="(/subs/[\w]+\.html)"\s+target="_blank"><b>(.*?)</b></a></p>`)
 	matched := re.FindAllStringSubmatch(resp.String(), -1)
 	if len(matched) < 1 {
-		return "", common.ZiMuKuSearchKeyWordStep0DetailPageUrlNotFound
+		return "", common2.ZiMuKuSearchKeyWordStep0DetailPageUrlNotFound
 	}
 	// 影片的详情界面 url
 	filmDetailPageUrl := matched[0][1]
@@ -314,11 +317,11 @@ func (s Supplier) step1(filmDetailPageUrl string) (SubResult, error) {
 	var err error
 	defer func() {
 		if err != nil {
-			model.Notify.Add("zimuku_step1", err.Error())
+			pkg.Notify.Add("zimuku_step1", err.Error())
 		}
 	}()
-	filmDetailPageUrl = model.AddBaseUrl(common.SubZiMuKuRootUrl, filmDetailPageUrl)
-	httpClient := model.NewHttpClient(s.reqParam)
+	filmDetailPageUrl = pkg.AddBaseUrl(common2.SubZiMuKuRootUrl, filmDetailPageUrl)
+	httpClient := pkg.NewHttpClient(s.reqParam)
 	resp, err := httpClient.R().
 		Get(filmDetailPageUrl)
 	if err != nil {
@@ -372,7 +375,7 @@ func (s Supplier) step1(filmDetailPageUrl string) (SubResult, error) {
 		if !exists {
 			rate = ""
 		}
-		vote, err := model.GetNumber2Float(rate)
+		vote, err := pkg.GetNumber2Float(rate)
 		if err != nil {
 			return
 		}
@@ -380,13 +383,13 @@ func (s Supplier) step1(filmDetailPageUrl string) (SubResult, error) {
 		downCountNub := 0
 		downCount := tr.Find("td").Eq(counterIndex).Text()
 		if strings.Contains(downCount, "万") {
-			fNumb, err := model.GetNumber2Float(downCount)
+			fNumb, err := pkg.GetNumber2Float(downCount)
 			if err != nil {
 				return
 			}
 			downCountNub = int(fNumb * 10000)
 		} else {
-			downCountNub, err = model.GetNumber2int(downCount)
+			downCountNub, err = pkg.GetNumber2int(downCount)
 			if err != nil {
 				return
 			}
@@ -415,11 +418,11 @@ func (s Supplier) step2(subInfo *SubInfo) error {
 	var err error
 	defer func() {
 		if err != nil {
-			model.Notify.Add("zimuku_step2", err.Error())
+			pkg.Notify.Add("zimuku_step2", err.Error())
 		}
 	}()
-	detailUrl := model.AddBaseUrl(common.SubZiMuKuRootUrl, subInfo.DetailUrl)
-	httpClient := model.NewHttpClient(s.reqParam)
+	detailUrl := pkg.AddBaseUrl(common2.SubZiMuKuRootUrl, subInfo.DetailUrl)
+	httpClient := pkg.NewHttpClient(s.reqParam)
 	resp, err := httpClient.R().
 		Get(detailUrl)
 	if err != nil {
@@ -430,12 +433,12 @@ func (s Supplier) step2(subInfo *SubInfo) error {
 	matched := re.FindAllStringSubmatch(resp.String(), -1)
 	if matched == nil || len(matched) == 0 || len(matched[0]) == 0 {
 		s.log.Debug(detailUrl)
-		return common.ZiMuKuDownloadUrlStep2NotFound
+		return common2.ZiMuKuDownloadUrlStep2NotFound
 	}
 	if strings.Contains(matched[0][1], "://") {
 		subInfo.SubDownloadPageUrl = matched[0][1]
 	} else {
-		subInfo.SubDownloadPageUrl = fmt.Sprintf("%s%s", common.SubZiMuKuRootUrl, matched[0][1])
+		subInfo.SubDownloadPageUrl = fmt.Sprintf("%s%s", common2.SubZiMuKuRootUrl, matched[0][1])
 	}
 	return nil
 }
@@ -445,11 +448,11 @@ func (s Supplier) step3(subDownloadPageUrl string) (string, []byte, error) {
 	var err error
 	defer func() {
 		if err != nil {
-			model.Notify.Add("zimuku_step3", err.Error())
+			pkg.Notify.Add("zimuku_step3", err.Error())
 		}
 	}()
-	subDownloadPageUrl = model.AddBaseUrl(common.SubZiMuKuRootUrl, subDownloadPageUrl)
-	httpClient := model.NewHttpClient(s.reqParam)
+	subDownloadPageUrl = pkg.AddBaseUrl(common2.SubZiMuKuRootUrl, subDownloadPageUrl)
+	httpClient := pkg.NewHttpClient(s.reqParam)
 	resp, err := httpClient.R().
 		Get(subDownloadPageUrl)
 	if err != nil {
@@ -459,14 +462,14 @@ func (s Supplier) step3(subDownloadPageUrl string) (string, []byte, error) {
 	matched := re.FindAllStringSubmatch(resp.String(), -1)
 	if matched == nil || len(matched) == 0 || len(matched[0]) == 0 {
 		s.log.Debug(subDownloadPageUrl)
-		return "", nil, common.ZiMuKuDownloadUrlStep3NotFound
+		return "", nil, common2.ZiMuKuDownloadUrlStep3NotFound
 	}
 	var filename string
 	var data []byte
 
 	s.reqParam.Referer = subDownloadPageUrl
 	for i := 0; i < len(matched); i++ {
-		data, filename, err = model.DownFile(model.AddBaseUrl(common.SubZiMuKuRootUrl, matched[i][1]), s.reqParam)
+		data, filename, err = pkg.DownFile(pkg.AddBaseUrl(common2.SubZiMuKuRootUrl, matched[i][1]), s.reqParam)
 		if err != nil {
 			s.log.Errorln("ZiMuKu step3 DownloadFile", err)
 			continue
@@ -474,7 +477,7 @@ func (s Supplier) step3(subDownloadPageUrl string) (string, []byte, error) {
 		return filename, data, nil
 	}
 	s.log.Debug(subDownloadPageUrl)
-	return "", nil, common.ZiMuKuDownloadUrlStep3AllFailed
+	return "", nil, common2.ZiMuKuDownloadUrlStep3AllFailed
 }
 
 type SubResult struct {

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

@@ -1,7 +1,7 @@
 package zimuku
 
 import (
-	"github.com/allanpk716/ChineseSubFinder/series_helper"
+	series_helper2 "github.com/allanpk716/ChineseSubFinder/internal/logic/series_helper"
 	"testing"
 )
 
@@ -46,7 +46,7 @@ func TestSupplier_GetSubListFromFile4Series(t *testing.T) {
 	//ser := "X:\\连续剧\\Money.Heist"
 
 	// 读取本地的视频和字幕信息
-	seriesInfo, err := series_helper.ReadSeriesInfoFromDir(ser, nil)
+	seriesInfo, err := series_helper2.ReadSeriesInfoFromDir(ser, nil)
 	if err != nil {
 		t.Fatal(err)
 	}

+ 1 - 1
model/NotifyCenter.go → internal/pkg/NotifyCenter.go

@@ -1,4 +1,4 @@
-package model
+package pkg
 
 import (
 	"github.com/go-resty/resty/v2"

+ 1 - 1
model/NotifyCenter_test.go → internal/pkg/NotifyCenter_test.go

@@ -1,4 +1,4 @@
-package model
+package pkg
 
 import (
 	"testing"

+ 4 - 4
model/config.go → internal/pkg/config.go

@@ -1,7 +1,7 @@
-package model
+package pkg
 
 import (
-	"github.com/allanpk716/ChineseSubFinder/common"
+	"github.com/allanpk716/ChineseSubFinder/internal/types"
 	"github.com/spf13/viper"
 )
 import "errors"
@@ -21,8 +21,8 @@ func InitConfigure() (*viper.Viper, error) {
 	return v, nil
 }
 // ReadConfig 读取配置文件
-func ReadConfig(viper *viper.Viper) (*common.Config, error) {
-	conf := &common.Config{}
+func ReadConfig(viper *viper.Viper) (*types.Config, error) {
+	conf := &types.Config{}
 	err := viper.Unmarshal(conf)
 	if err != nil {
 		return nil, err

+ 4 - 4
model/deal_sub.go → internal/pkg/deal_sub.go

@@ -1,13 +1,13 @@
-package model
+package pkg
 
 import (
-	"github.com/allanpk716/ChineseSubFinder/common"
+	"github.com/allanpk716/ChineseSubFinder/internal/types/supplier"
 	"path/filepath"
 	"strconv"
 )
 
 // GetFrontNameAndOrgName 返回的名称包含,那个网站下载的,这个网站中排名第几,文件名
-func GetFrontNameAndOrgName(info *common.SupplierSubInfo) string {
+func GetFrontNameAndOrgName(info *supplier.SubInfo) string {
 
 	infoName := ""
 	path, err := GetVideoInfoFromFileName(info.Name)
@@ -23,6 +23,6 @@ func GetFrontNameAndOrgName(info *common.SupplierSubInfo) string {
 }
 
 // AddFrontName 添加文件的前缀
-func AddFrontName(info common.SupplierSubInfo, orgName string) string {
+func AddFrontName(info supplier.SubInfo, orgName string) string {
 	return "[" + info.FromWhere + "]_" + strconv.FormatInt(info.TopN,10) + "_" + orgName
 }

+ 21 - 20
model/decode.go → internal/pkg/decode.go

@@ -1,8 +1,9 @@
-package model
+package pkg
 
 import (
 	"errors"
-	"github.com/allanpk716/ChineseSubFinder/common"
+	common2 "github.com/allanpk716/ChineseSubFinder/internal/common"
+	"github.com/allanpk716/ChineseSubFinder/internal/types"
 	"github.com/beevik/etree"
 	PTN "github.com/middelink/go-parse-torrent-name"
 	"io/ioutil"
@@ -15,9 +16,9 @@ import (
 	"time"
 )
 
-func getImdbAndYearMovieXml(movieFilePath string) (common.VideoIMDBInfo, error) {
+func getImdbAndYearMovieXml(movieFilePath string) (types.VideoIMDBInfo, error) {
 
-	videoInfo := common.VideoIMDBInfo{}
+	videoInfo := types.VideoIMDBInfo{}
 	doc := etree.NewDocument()
 	if err := doc.ReadFromFile(movieFilePath); err != nil {
 		return videoInfo, err
@@ -33,11 +34,11 @@ func getImdbAndYearMovieXml(movieFilePath string) (common.VideoIMDBInfo, error)
 	if videoInfo.ImdbId != "" {
 		return videoInfo, nil
 	}
-	return videoInfo, common.CanNotFindIMDBID
+	return videoInfo, common2.CanNotFindIMDBID
 }
 
-func getImdbAndYearNfo(nfoFilePath string, rootKey string) (common.VideoIMDBInfo, error) {
-	imdbInfo := common.VideoIMDBInfo{}
+func getImdbAndYearNfo(nfoFilePath string, rootKey string) (types.VideoIMDBInfo, error) {
+	imdbInfo := types.VideoIMDBInfo{}
 	doc := etree.NewDocument()
 	// 这里会遇到一个梗,下面的关键词,可能是小写、大写、首字母大写
 	// 读取文件转换为全部的小写,然后在解析 xml ? etree 在转换为小写后,某些类型的文件的内容会崩溃···
@@ -85,11 +86,11 @@ func getImdbAndYearNfo(nfoFilePath string, rootKey string) (common.VideoIMDBInfo
 	if imdbInfo.ImdbId != "" {
 		return imdbInfo, nil
 	}
-	return imdbInfo, common.CanNotFindIMDBID
+	return imdbInfo, common2.CanNotFindIMDBID
 }
 
-func GetImdbInfo4Movie(movieFileFullPath string) (common.VideoIMDBInfo, error) {
-	imdbInfo := common.VideoIMDBInfo{}
+func GetImdbInfo4Movie(movieFileFullPath string) (types.VideoIMDBInfo, error) {
+	imdbInfo := types.VideoIMDBInfo{}
 	// movie 当前的目录
 	dirPth := filepath.Dir(movieFileFullPath)
 	// 与 movie 文件名一致的 nfo 文件名称
@@ -128,13 +129,13 @@ func GetImdbInfo4Movie(movieFileFullPath string) (common.VideoIMDBInfo, error) {
 	}
 	// 根据找到的开始解析
 	if movieNameNfoFPath == "" && movieXmlFPath == "" && nfoFilePath == "" {
-		return imdbInfo, common.NoMetadataFile
+		return imdbInfo, common2.NoMetadataFile
 	}
 	// 优先分析 movieName.nfo 文件
 	if movieNameNfoFPath != "" {
 		imdbInfo, err = getImdbAndYearNfo(movieNameNfoFPath, "movie")
 		if err != nil {
-			return common.VideoIMDBInfo{}, err
+			return types.VideoIMDBInfo{}, err
 		}
 		return imdbInfo, nil
 	}
@@ -157,11 +158,11 @@ func GetImdbInfo4Movie(movieFileFullPath string) (common.VideoIMDBInfo, error) {
 		}
 	}
 
-	return imdbInfo, common.CanNotFindIMDBID
+	return imdbInfo, common2.CanNotFindIMDBID
 }
 
-func GetImdbInfo4SeriesDir(seriesDir string) (common.VideoIMDBInfo, error) {
-	imdbInfo := common.VideoIMDBInfo{}
+func GetImdbInfo4SeriesDir(seriesDir string) (types.VideoIMDBInfo, error) {
+	imdbInfo := types.VideoIMDBInfo{}
 	dir, err := ioutil.ReadDir(seriesDir)
 	if err != nil {
 		return imdbInfo, err
@@ -186,16 +187,16 @@ func GetImdbInfo4SeriesDir(seriesDir string) (common.VideoIMDBInfo, error) {
 	}
 	// 根据找到的开始解析
 	if nfoFilePath == "" {
-		return imdbInfo, common.NoMetadataFile
+		return imdbInfo, common2.NoMetadataFile
 	}
 	imdbInfo, err = getImdbAndYearNfo(nfoFilePath, "tvshow")
 	if err != nil {
-		return common.VideoIMDBInfo{}, err
+		return types.VideoIMDBInfo{}, err
 	}
 	return imdbInfo, nil
 }
 
-func GetImdbInfo4OneSeriesEpisode(oneEpFPath string) (common.VideoIMDBInfo, error) {
+func GetImdbInfo4OneSeriesEpisode(oneEpFPath string) (types.VideoIMDBInfo, error) {
 
 	// 从这一集的视频文件全路径去推算对应的 nfo 文件是否存在
 	EPdir := filepath.Dir(oneEpFPath)
@@ -205,7 +206,7 @@ func GetImdbInfo4OneSeriesEpisode(oneEpFPath string) (common.VideoIMDBInfo, erro
 	// 全路径
 	EpNfoFPath := path.Join(EPdir, EpNfoFileName)
 	//
-	imdbInfo := common.VideoIMDBInfo{}
+	imdbInfo := types.VideoIMDBInfo{}
 	doc := etree.NewDocument()
 	// 这里会遇到一个梗,下面的关键词,可能是小写、大写、首字母大写
 	// 读取文件转换为全部的小写,然后在解析 xml ? etree 在转换为小写后,某些类型的文件的内容会崩溃···
@@ -225,7 +226,7 @@ func GetImdbInfo4OneSeriesEpisode(oneEpFPath string) (common.VideoIMDBInfo, erro
 	if imdbInfo.ReleaseDate != "" {
 		return imdbInfo, nil
 	}
-	return imdbInfo, common.CanNotFindEpAiredTime
+	return imdbInfo, common2.CanNotFindEpAiredTime
 }
 
 // GetVideoInfoFromFileName 从文件名推断文件信息

+ 1 - 1
model/decode_test.go → internal/pkg/decode_test.go

@@ -1,4 +1,4 @@
-package model
+package pkg
 
 import (
 	"testing"

+ 16 - 15
model/emby.go → internal/pkg/emby.go

@@ -1,8 +1,9 @@
-package model
+package pkg
 
 import (
 	"fmt"
-	"github.com/allanpk716/ChineseSubFinder/common"
+	common2 "github.com/allanpk716/ChineseSubFinder/internal/common"
+	"github.com/allanpk716/ChineseSubFinder/internal/types/emby"
 	"github.com/go-resty/resty/v2"
 	"github.com/panjf2000/ants/v2"
 	"golang.org/x/net/context"
@@ -11,18 +12,18 @@ import (
 )
 
 type EmbyApi struct {
-	embyConfig common.EmbyConfig
+	embyConfig emby.EmbyConfig
 	threads    int
 	timeOut    time.Duration
 }
 
-func NewEmbyHelper(embyConfig common.EmbyConfig) *EmbyApi {
+func NewEmbyHelper(embyConfig emby.EmbyConfig) *EmbyApi {
 	em := EmbyApi{}
 	em.embyConfig = embyConfig
-	if em.embyConfig.LimitCount < common.EmbyApiGetItemsLimitMin ||
-		em.embyConfig.LimitCount > common.EmbyApiGetItemsLimitMax {
+	if em.embyConfig.LimitCount < common2.EmbyApiGetItemsLimitMin ||
+		em.embyConfig.LimitCount > common2.EmbyApiGetItemsLimitMax {
 
-		em.embyConfig.LimitCount = common.EmbyApiGetItemsLimitMin
+		em.embyConfig.LimitCount = common2.EmbyApiGetItemsLimitMin
 	}
 	em.threads = 6
 	em.timeOut = 5 * time.Second
@@ -89,9 +90,9 @@ func (em EmbyApi) RefreshRecentlyVideoInfo() error {
 }
 
 // GetRecentlyItems 在 API 调试界面 -- ItemsService
-func (em EmbyApi) GetRecentlyItems() (common.EmbyRecentlyItems, error) {
+func (em EmbyApi) GetRecentlyItems() (emby.EmbyRecentlyItems, error) {
 
-	var recItems common.EmbyRecentlyItems
+	var recItems emby.EmbyRecentlyItems
 	_, err := em.getNewClient().R().
 		SetQueryParams(map[string]string{
 			"api_key":          em.embyConfig.ApiKey,
@@ -106,16 +107,16 @@ func (em EmbyApi) GetRecentlyItems() (common.EmbyRecentlyItems, error) {
 		SetResult(&recItems).
 		Get(em.embyConfig.Url + "/emby/Items")
 	if err != nil {
-		return common.EmbyRecentlyItems{}, err
+		return emby.EmbyRecentlyItems{}, err
 	}
 
 	return recItems, nil
 }
 
 // GetItemAncestors 在 API 调试界面 -- LibraryService
-func (em EmbyApi) GetItemAncestors(id string) ([]common.EmbyItemsAncestors, error) {
+func (em EmbyApi) GetItemAncestors(id string) ([]emby.EmbyItemsAncestors, error) {
 
-	var recItems []common.EmbyItemsAncestors
+	var recItems []emby.EmbyItemsAncestors
 
 	_, err := em.getNewClient().R().
 		SetQueryParams(map[string]string{
@@ -131,9 +132,9 @@ func (em EmbyApi) GetItemAncestors(id string) ([]common.EmbyItemsAncestors, erro
 }
 
 // GetItemVideoInfo 在 API 调试界面 -- UserLibraryService
-func (em EmbyApi) GetItemVideoInfo(id string) (common.EmbyVideoInfo, error) {
+func (em EmbyApi) GetItemVideoInfo(id string) (emby.EmbyVideoInfo, error) {
 
-	var recItem common.EmbyVideoInfo
+	var recItem emby.EmbyVideoInfo
 
 	_, err := em.getNewClient().R().
 		SetQueryParams(map[string]string{
@@ -142,7 +143,7 @@ func (em EmbyApi) GetItemVideoInfo(id string) (common.EmbyVideoInfo, error) {
 		SetResult(&recItem).
 		Get(em.embyConfig.Url + "/emby/LiveTv/Programs/" + id)
 	if err != nil {
-		return common.EmbyVideoInfo{}, err
+		return emby.EmbyVideoInfo{}, err
 	}
 
 	return recItem, nil

+ 3 - 3
model/emby_test.go → internal/pkg/emby_test.go

@@ -1,7 +1,7 @@
-package model
+package pkg
 
 import (
-	"github.com/allanpk716/ChineseSubFinder/common"
+	"github.com/allanpk716/ChineseSubFinder/internal/types"
 	"testing"
 )
 
@@ -64,5 +64,5 @@ func TestEmbyHelper_UpdateVideoSubList(t *testing.T) {
 }
 
 var (
-	config *common.Config
+	config *types.Config
 )

+ 9 - 0
internal/pkg/globalvalue.go

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

+ 4 - 4
model/imdb.go → internal/pkg/imdb.go

@@ -1,13 +1,13 @@
-package model
+package pkg
 
 import (
 	"github.com/StalkR/imdb"
-	"github.com/allanpk716/ChineseSubFinder/common"
+	"github.com/allanpk716/ChineseSubFinder/internal/types"
 )
 
 // GetVideoInfoFromIMDB 从 IMDB ID 查询影片的信息
-func GetVideoInfoFromIMDB(imdbID string, _reqParam ...common.ReqParam) (*imdb.Title, error) {
-	var reqParam common.ReqParam
+func GetVideoInfoFromIMDB(imdbID string, _reqParam ...types.ReqParam) (*imdb.Title, error) {
+	var reqParam types.ReqParam
 	if len(_reqParam) > 0 {
 		reqParam = _reqParam[0]
 	}

+ 1 - 1
model/imdb_test.go → internal/pkg/imdb_test.go

@@ -1,4 +1,4 @@
-package model
+package pkg
 
 import "testing"
 

+ 105 - 105
model/language.go → internal/pkg/language.go

@@ -1,9 +1,9 @@
-package model
+package pkg
 
 import (
 	"github.com/abadojack/whatlanggo"
-	"github.com/allanpk716/ChineseSubFinder/charset"
-	"github.com/allanpk716/ChineseSubFinder/common"
+	"github.com/allanpk716/ChineseSubFinder/internal/logic/charset"
+	"github.com/allanpk716/ChineseSubFinder/internal/types"
 	"github.com/axgle/mahonia"
 	"github.com/go-creed/sat"
 	chardet2 "github.com/nzlov/chardet"
@@ -13,70 +13,70 @@ import (
 )
 
 // LangConverter 语言转换器
-func LangConverter(subLang string) common.Language {
+func LangConverter(subLang string) types.Language {
 	/*
 		xunlei:未知语言、简体&英语、繁体&英语、简体、繁体、英语
 	*/
-	if strings.Contains(subLang, common.MatchLangDouble) {
+	if strings.Contains(subLang, types.MatchLangDouble) {
 		// 双语 - 简英
-		return common.ChineseSimpleEnglish
-	} else if strings.Contains(subLang, common.MatchLangChs) {
+		return types.ChineseSimpleEnglish
+	} else if strings.Contains(subLang, types.MatchLangChs) {
 		// 优先简体
-		if strings.Contains(subLang, common.MatchLangEn) {
+		if strings.Contains(subLang, types.MatchLangEn) {
 			// 简英
-			return common.ChineseSimpleEnglish
-		} else if strings.Contains(subLang, common.MatchLangJp) {
+			return types.ChineseSimpleEnglish
+		} else if strings.Contains(subLang, types.MatchLangJp) {
 			// 简日
-			return common.ChineseSimpleJapanese
-		} else if strings.Contains(subLang, common.MatchLangKr) {
+			return types.ChineseSimpleJapanese
+		} else if strings.Contains(subLang, types.MatchLangKr) {
 			// 简韩
-			return common.ChineseSimpleKorean
+			return types.ChineseSimpleKorean
 		}
 		// 默认简体中文
-		return common.ChineseSimple
-	} else if strings.Contains(subLang, common.MatchLangCht) {
+		return types.ChineseSimple
+	} else if strings.Contains(subLang, types.MatchLangCht) {
 		// 然后是繁体
-		if strings.Contains(subLang, common.MatchLangEn) {
+		if strings.Contains(subLang, types.MatchLangEn) {
 			// 繁英
-			return common.ChineseTraditionalEnglish
-		} else if strings.Contains(subLang, common.MatchLangJp) {
+			return types.ChineseTraditionalEnglish
+		} else if strings.Contains(subLang, types.MatchLangJp) {
 			// 繁日
-			return common.ChineseTraditionalJapanese
-		} else if strings.Contains(subLang, common.MatchLangKr) {
+			return types.ChineseTraditionalJapanese
+		} else if strings.Contains(subLang, types.MatchLangKr) {
 			// 繁韩
-			return common.ChineseTraditionalKorean
+			return types.ChineseTraditionalKorean
 		}
 		// 默认繁体中文
-		return common.ChineseTraditional
-	} else if strings.Contains(subLang, common.MatchLangEn) {
+		return types.ChineseTraditional
+	} else if strings.Contains(subLang, types.MatchLangEn) {
 		// 英文
-		return common.English
-	} else if strings.Contains(subLang, common.MatchLangJp) {
+		return types.English
+	} else if strings.Contains(subLang, types.MatchLangJp) {
 		// 日文
-		return common.Japanese
-	} else if strings.Contains(subLang, common.MatchLangKr) {
+		return types.Japanese
+	} else if strings.Contains(subLang, types.MatchLangKr) {
 		// 韩文
-		return common.Korean
+		return types.Korean
 	} else {
 		// 都没有,则标记未知
-		return common.Unknow
+		return types.Unknow
 	}
 }
 
 // HasChineseLang 是否包含中文
-func HasChineseLang(lan common.Language) bool {
+func HasChineseLang(lan types.Language) bool {
 	switch lan {
-	case common.ChineseSimple,
-		common.ChineseTraditional,
+	case types.ChineseSimple,
+		types.ChineseTraditional,
 
-		common.ChineseSimpleEnglish,
-		common.ChineseTraditionalEnglish,
+		types.ChineseSimpleEnglish,
+		types.ChineseTraditionalEnglish,
 
-		common.ChineseSimpleJapanese,
-		common.ChineseTraditionalJapanese,
+		types.ChineseSimpleJapanese,
+		types.ChineseTraditionalJapanese,
 
-		common.ChineseSimpleKorean,
-		common.ChineseTraditionalKorean:
+		types.ChineseSimpleKorean,
+		types.ChineseTraditionalKorean:
 		return true
 	default:
 		return false
@@ -84,16 +84,16 @@ func HasChineseLang(lan common.Language) bool {
 }
 
 // IsBilingualSubtitle 是否是双语字幕
-func IsBilingualSubtitle(lan common.Language) bool {
+func IsBilingualSubtitle(lan types.Language) bool {
 	switch lan {
-	case common.ChineseSimpleEnglish,
-	common.ChineseTraditionalEnglish,
+	case types.ChineseSimpleEnglish,
+		types.ChineseTraditionalEnglish,
 
-	common.ChineseSimpleJapanese,
-	common.ChineseTraditionalJapanese,
+		types.ChineseSimpleJapanese,
+		types.ChineseTraditionalJapanese,
 
-	common.ChineseSimpleKorean,
-	common.ChineseTraditionalKorean:
+		types.ChineseSimpleKorean,
+		types.ChineseTraditionalKorean:
 		return true
 	default:
 		return false
@@ -101,34 +101,34 @@ func IsBilingualSubtitle(lan common.Language) bool {
 }
 
 // Lang2EmbyName 从语言转换到 Emby 能够识别的字幕命名
-func Lang2EmbyName(lan common.Language) string {
+func Lang2EmbyName(lan types.Language) string {
 	switch lan {
-	case common.Unknow:                     				// 未知语言
-		return common.Emby_unknow
-	case common.ChineseSimple:                              // 简体中文
-		return common.Emby_chs
-	case common.ChineseTraditional:                         // 繁体中文
-		return common.Emby_cht
-	case common.ChineseSimpleEnglish:                       // 简英双语字幕
-		return common.Emby_chs_en
-	case common.ChineseTraditionalEnglish:                  // 繁英双语字幕
-		return common.Emby_cht_en
-	case common.English:                                    // 英文
-		return common.Emby_en
-	case common.Japanese:                                   // 日语
-		return common.Emby_jp
-	case common.ChineseSimpleJapanese:                      // 简日双语字幕
-		return common.Emby_chs_jp
-	case common.ChineseTraditionalJapanese:                 // 繁日双语字幕
-		return common.Emby_cht_jp
-	case common.Korean:                                     // 韩语
-		return common.Emby_kr
-	case common.ChineseSimpleKorean:                        // 简韩双语字幕
-		return common.Emby_chs_kr
-	case common.ChineseTraditionalKorean:                   // 繁韩双语字幕
-		return common.Emby_cht_kr
+	case types.Unknow: // 未知语言
+		return types.Emby_unknow
+	case types.ChineseSimple: // 简体中文
+		return types.Emby_chs
+	case types.ChineseTraditional: // 繁体中文
+		return types.Emby_cht
+	case types.ChineseSimpleEnglish: // 简英双语字幕
+		return types.Emby_chs_en
+	case types.ChineseTraditionalEnglish: // 繁英双语字幕
+		return types.Emby_cht_en
+	case types.English: // 英文
+		return types.Emby_en
+	case types.Japanese: // 日语
+		return types.Emby_jp
+	case types.ChineseSimpleJapanese: // 简日双语字幕
+		return types.Emby_chs_jp
+	case types.ChineseTraditionalJapanese: // 繁日双语字幕
+		return types.Emby_cht_jp
+	case types.Korean: // 韩语
+		return types.Emby_kr
+	case types.ChineseSimpleKorean: // 简韩双语字幕
+		return types.Emby_chs_kr
+	case types.ChineseTraditionalKorean: // 繁韩双语字幕
+		return types.Emby_cht_kr
 	default:
-		return common.Emby_unknow
+		return types.Emby_unknow
 	}
 }
 
@@ -180,7 +180,7 @@ func DetectSubLangAndStatistics(lines []string, langDict map[int]int, chLines *[
 }
 
 // SubLangStatistics2SubLangType 由分析的信息转换为具体是什么字幕的语言类型
-func SubLangStatistics2SubLangType(countLineFeed, AllLines float32, langDict map[int]int, chLines []string) common.Language {
+func SubLangStatistics2SubLangType(countLineFeed, AllLines float32, langDict map[int]int, chLines []string) types.Language {
 	const basePer = 0.8
 	// 是否是双语?
 	isDouble := false
@@ -233,23 +233,23 @@ func SubLangStatistics2SubLangType(countLineFeed, AllLines float32, langDict map
 		// 首先得在外面统计就知道是双语
 		if hasChinese && hasEnglish {
 			// 简体	英文
-			return chIsChsOrCht(common.ChineseSimpleEnglish, isNoOrChsOrCht)
+			return chIsChsOrCht(types.ChineseSimpleEnglish, isNoOrChsOrCht)
 		} else if hasChinese && hasJapanese {
 			// 简体 日文
-			return chIsChsOrCht(common.ChineseSimpleJapanese, isNoOrChsOrCht)
+			return chIsChsOrCht(types.ChineseSimpleJapanese, isNoOrChsOrCht)
 		} else if hasChinese && hasKorean {
 			// 简体 韩文
-			return chIsChsOrCht(common.ChineseSimpleKorean, isNoOrChsOrCht)
+			return chIsChsOrCht(types.ChineseSimpleKorean, isNoOrChsOrCht)
 		} else if hasChinese {
-			return chIsChsOrCht(common.ChineseSimple, isNoOrChsOrCht)
+			return chIsChsOrCht(types.ChineseSimple, isNoOrChsOrCht)
 		} else if hasEnglish {
-			return common.English
+			return types.English
 		} else if hasJapanese {
-			return common.Japanese
+			return types.Japanese
 		} else if hasKorean {
-			return common.Korean
+			return types.Korean
 		} else {
-			return common.Unknow
+			return types.Unknow
 		}
 	} else {
 		// 如果比例达不到,那么就是单语言,所以最多的那个就是当前的语言
@@ -258,79 +258,79 @@ func SubLangStatistics2SubLangType(countLineFeed, AllLines float32, langDict map
 			// 那么起码要占比 80% 对吧
 			perLines = float32(countChinese) / AllLines
 			if perLines > basePer {
-				return chIsChsOrCht(common.ChineseSimple, isNoOrChsOrCht)
+				return chIsChsOrCht(types.ChineseSimple, isNoOrChsOrCht)
 			}
 		}
 		if hasEnglish {
 			// 那么起码要占比 80% 对吧
 			perLines = float32(countEnglish) / AllLines
 			if perLines > basePer {
-				return common.English
+				return types.English
 			}
 		}
 		if hasJapanese {
 			// 那么起码要占比 80% 对吧
 			perLines = float32(countJapanese) / AllLines
 			if perLines > basePer {
-				return common.Japanese
+				return types.Japanese
 			}
 		}
 		if hasKorean {
 			// 那么起码要占比 80% 对吧
 			perLines = float32(countKorean) / AllLines
 			if perLines > basePer {
-				return common.Korean
+				return types.Korean
 			}
 		}
 
-		return common.Unknow
+		return types.Unknow
 	}
 
 }
 
 // 跟中文相关的再使用,其他的无需传入
-func chIsChsOrCht(language common.Language, isNoOrChsOrCht int) common.Language {
+func chIsChsOrCht(language types.Language, isNoOrChsOrCht int) types.Language {
 	// 输出原来的
 	if isNoOrChsOrCht == 0 || isNoOrChsOrCht == 1 {
 		return language
 	}
 	switch language {
-	case common.ChineseSimpleEnglish:
+	case types.ChineseSimpleEnglish:
 		// 简体	英文
-		return common.ChineseTraditionalEnglish
-	case common.ChineseSimpleJapanese:
+		return types.ChineseTraditionalEnglish
+	case types.ChineseSimpleJapanese:
 		// 简体 日文
-		return common.ChineseTraditionalJapanese
-	case common.ChineseSimpleKorean:
+		return types.ChineseTraditionalJapanese
+	case types.ChineseSimpleKorean:
 		// 简体 韩文
-		return common.ChineseTraditionalKorean
-	case common.ChineseSimple:
+		return types.ChineseTraditionalKorean
+	case types.ChineseSimple:
 		// 简体
-		return common.ChineseTraditional
+		return types.ChineseTraditional
 	default:
 		return language
 	}
 }
 
 // IsChineseSimpleOrTraditional 暂时弃用,在 SubLangStatistics2SubLangType 检测语言,通过 unicode 做到。 从字幕的文件名称中尝试确认是简体还是繁体,不需要判断双语问题,有额外的解析器完成。只可能出现 ChineseSimple ChineseTraditional Unknow 三种情况
-func IsChineseSimpleOrTraditional(inputFileName string, orgLang common.Language) common.Language {
-	if strings.Contains(inputFileName, common.SubNameKeywordChineseSimple) || strings.Contains(inputFileName, common.MatchLangChs) {
+func IsChineseSimpleOrTraditional(inputFileName string, orgLang types.Language) types.Language {
+	if strings.Contains(inputFileName, types.SubNameKeywordChineseSimple) || strings.Contains(inputFileName, types.MatchLangChs) {
 		// 简体中文关键词的匹配
 		return orgLang
-	} else if strings.Contains(inputFileName, common.SubNameKeywordTraditional) || strings.Contains(inputFileName, common.MatchLangCht) {
+	} else if strings.Contains(inputFileName, types.SubNameKeywordTraditional) || strings.Contains(inputFileName, types.MatchLangCht) {
 		// 繁体中文关键词的匹配
-		if orgLang == common.ChineseSimple {
+		if orgLang == types.ChineseSimple {
 			// 简体 -> 繁体
-			return common.ChineseTraditional
-		} else if orgLang == common.ChineseSimpleEnglish {
+			return types.ChineseTraditional
+		} else if orgLang == types.ChineseSimpleEnglish {
 			// 简体英文 -> 繁体英文
-			return common.ChineseTraditionalEnglish
-		} else if orgLang == common.ChineseSimpleJapanese {
+			return types.ChineseTraditionalEnglish
+		} else if orgLang == types.ChineseSimpleJapanese {
 			// 简体日文 -> 繁体日文
-			return common.ChineseTraditionalJapanese
-		} else if orgLang == common.ChineseSimpleKorean {
+			return types.ChineseTraditionalJapanese
+		} else if orgLang == types.ChineseSimpleKorean {
 			// 简体韩文 -> 繁体韩文
-			return common.ChineseTraditionalKorean
+			return types.ChineseTraditionalKorean
 		}
 		// 进来了都不是,那么就返回原来的语言
 		return orgLang

+ 1 - 1
model/loghelper.go → internal/pkg/loghelper.go

@@ -1,4 +1,4 @@
-package model
+package pkg
 
 import (
 	rotatelogs "github.com/lestrrat-go/file-rotatelogs"

+ 1 - 1
model/pass_water_wall.go → internal/pkg/pass_water_wall.go

@@ -1,4 +1,4 @@
-package model
+package pkg
 
 import (
 	"bytes"

+ 1 - 1
model/pass_water_wall_test.go → internal/pkg/pass_water_wall_test.go

@@ -1,4 +1,4 @@
-package model
+package pkg
 
 import (
 	"testing"

+ 1 - 1
model/random.go → internal/pkg/random.go

@@ -1,4 +1,4 @@
-package model
+package pkg
 
 import (
 	browser "github.com/EDDYCJY/fake-useragent"

+ 1 - 1
model/rodHelper.go → internal/pkg/rodHelper.go

@@ -1,4 +1,4 @@
-package model
+package pkg
 
 import (
 	"context"

+ 1 - 1
model/rodHelper_test.go → internal/pkg/rodHelper_test.go

@@ -1,4 +1,4 @@
-package model
+package pkg
 
 import (
 	"github.com/go-rod/rod/lib/proto"

+ 12 - 11
model/subParserHub.go → internal/pkg/subParserHub.go

@@ -1,21 +1,22 @@
-package model
+package pkg
 
 import (
-	"github.com/allanpk716/ChineseSubFinder/common"
-	"github.com/allanpk716/ChineseSubFinder/interface"
+	common2 "github.com/allanpk716/ChineseSubFinder/internal/common"
+	_interface2 "github.com/allanpk716/ChineseSubFinder/internal/interface"
+	"github.com/allanpk716/ChineseSubFinder/internal/types/subparser"
 	"path/filepath"
 	"regexp"
 	"strings"
 )
 
 type SubParserHub struct {
-	Parser []_interface.ISubParser
+	Parser []_interface2.ISubParser
 }
 
 // NewSubParserHub 处理的字幕文件需要符合 [siteName]_ 的前缀描述,是本程序专用的
-func NewSubParserHub(parser _interface.ISubParser, _parser ..._interface.ISubParser) *SubParserHub {
+func NewSubParserHub(parser _interface2.ISubParser, _parser ..._interface2.ISubParser) *SubParserHub {
 	s := SubParserHub{}
-	s.Parser = make([]_interface.ISubParser, 0)
+	s.Parser = make([]_interface2.ISubParser, 0)
 	s.Parser = append(s.Parser, parser)
 	if len(_parser) > 0 {
 		for _, one := range _parser {
@@ -26,7 +27,7 @@ func NewSubParserHub(parser _interface.ISubParser, _parser ..._interface.ISubPar
 }
 
 // DetermineFileTypeFromFile 确定字幕文件的类型,是双语字幕或者某一种语言等等信息,如果返回 nil ,那么就说明都没有字幕的格式匹配上
-func (p SubParserHub) DetermineFileTypeFromFile(filePath string) (*common.SubParserFileInfo, error){
+func (p SubParserHub) DetermineFileTypeFromFile(filePath string) (*subparser.FileInfo, error){
 	for _, parser := range p.Parser {
 		subFileInfo, err := parser.DetermineFileTypeFromFile(filePath)
 		if err != nil {
@@ -85,9 +86,9 @@ func (p SubParserHub) getFromWhereSite(filePath string) string {
 // IsSubTypeWanted 这里匹配的字幕的格式,不包含 Ext 的 . 小数点,注意,仅仅是包含关系
 func IsSubTypeWanted(subName string) bool {
 	nowLowerName := strings.ToLower(subName)
-	if strings.Contains(nowLowerName, common.SubTypeASS) ||
-		strings.Contains(nowLowerName, common.SubTypeSSA) ||
-		strings.Contains(nowLowerName, common.SubTypeSRT) {
+	if strings.Contains(nowLowerName, common2.SubTypeASS) ||
+		strings.Contains(nowLowerName, common2.SubTypeSSA) ||
+		strings.Contains(nowLowerName, common2.SubTypeSRT) {
 		return true
 	}
 
@@ -98,7 +99,7 @@ func IsSubTypeWanted(subName string) bool {
 func IsSubExtWanted(subName string) bool {
 	inExt := filepath.Ext(subName)
 	switch strings.ToLower(inExt) {
-	case common.SubExtSSA,common.SubExtASS,common.SubExtSRT:
+	case common2.SubExtSSA, common2.SubExtASS, common2.SubExtSRT:
 		return true
 	default:
 		return false

+ 12 - 10
model/sub_helper.go → internal/pkg/sub_helper.go

@@ -1,7 +1,9 @@
-package model
+package pkg
 
 import (
-	"github.com/allanpk716/ChineseSubFinder/common"
+	common2 "github.com/allanpk716/ChineseSubFinder/internal/common"
+	"github.com/allanpk716/ChineseSubFinder/internal/types/subparser"
+	"github.com/allanpk716/ChineseSubFinder/internal/types/supplier"
 	"github.com/go-rod/rod/lib/utils"
 	"os"
 	"path"
@@ -10,7 +12,7 @@ import (
 )
 
 // OrganizeDlSubFiles 需要从汇总来是网站字幕中,解压对应的压缩包中的字幕出来
-func OrganizeDlSubFiles(tmpFolderName string, subInfos []common.SupplierSubInfo) (map[string][]string, error) {
+func OrganizeDlSubFiles(tmpFolderName string, subInfos []supplier.SubInfo) (map[string][]string, error) {
 
 	// 缓存列表,整理后的字幕列表
 	// SxEx - []string 字幕的路径
@@ -88,7 +90,7 @@ func OrganizeDlSubFiles(tmpFolderName string, subInfos []common.SupplierSubInfo)
 }
 
 // ChangeVideoExt2SubExt 检测 Name,如果是视频的后缀名就改为字幕的后缀名
-func ChangeVideoExt2SubExt(subInfos []common.SupplierSubInfo) {
+func ChangeVideoExt2SubExt(subInfos []supplier.SubInfo) {
 	for x, info := range subInfos {
 		tmpSubFileName := info.Name
 		// 如果后缀名是下载字幕目标的后缀名  或者 是压缩包格式的,则跳过
@@ -101,7 +103,7 @@ func ChangeVideoExt2SubExt(subInfos []common.SupplierSubInfo) {
 }
 
 // SelectChineseBestBilingualSubtitle 找到合适的双语中文字幕,简体->繁体,以及 字幕类型的优先级选择
-func SelectChineseBestBilingualSubtitle(subs []common.SubParserFileInfo, subTypePriority int) *common.SubParserFileInfo {
+func SelectChineseBestBilingualSubtitle(subs []subparser.FileInfo, subTypePriority int) *subparser.FileInfo {
 
 	// 先傻一点实现优先双语的,之前的写法有 bug
 	for _, info := range subs {
@@ -110,7 +112,7 @@ func SelectChineseBestBilingualSubtitle(subs []common.SubParserFileInfo, subType
 			// 字幕的优先级 0 - 原样, 1 - srt , 2 - ass/ssa
 			if subTypePriority == 1 {
 				// 1 - srt
-				if strings.ToLower(info.Ext) == common.SubExtSRT {
+				if strings.ToLower(info.Ext) == common2.SubExtSRT {
 					// 优先双语
 					if IsBilingualSubtitle(info.Lang) == true {
 						return &info
@@ -118,7 +120,7 @@ func SelectChineseBestBilingualSubtitle(subs []common.SubParserFileInfo, subType
 				}
 			} else if subTypePriority == 2 {
 				//  2 - ass/ssa
-				if strings.ToLower(info.Ext) == common.SubExtASS || strings.ToLower(info.Ext) == common.SubExtSSA {
+				if strings.ToLower(info.Ext) == common2.SubExtASS || strings.ToLower(info.Ext) == common2.SubExtSSA {
 					// 优先双语
 					if IsBilingualSubtitle(info.Lang) == true {
 						return &info
@@ -137,7 +139,7 @@ func SelectChineseBestBilingualSubtitle(subs []common.SubParserFileInfo, subType
 }
 
 // SelectChineseBestSubtitle 找到合适的中文字幕,简体->繁体,以及 字幕类型的优先级选择
-func SelectChineseBestSubtitle(subs []common.SubParserFileInfo, subTypePriority int) *common.SubParserFileInfo {
+func SelectChineseBestSubtitle(subs []subparser.FileInfo, subTypePriority int) *subparser.FileInfo {
 
 	// 先傻一点实现优先双语的,之前的写法有 bug
 	for _, info := range subs {
@@ -146,12 +148,12 @@ func SelectChineseBestSubtitle(subs []common.SubParserFileInfo, subTypePriority
 			// 字幕的优先级 0 - 原样, 1 - srt , 2 - ass/ssa
 			if subTypePriority == 1 {
 				// 1 - srt
-				if strings.ToLower(info.Ext) == common.SubExtSRT {
+				if strings.ToLower(info.Ext) == common2.SubExtSRT {
 					return &info
 				}
 			} else if subTypePriority == 2 {
 				//  2 - ass/ssa
-				if strings.ToLower(info.Ext) == common.SubExtASS || strings.ToLower(info.Ext) == common.SubExtSSA {
+				if strings.ToLower(info.Ext) == common2.SubExtASS || strings.ToLower(info.Ext) == common2.SubExtSSA {
 					return &info
 				}
 			} else {

+ 1 - 1
model/unarchiveFile.go → internal/pkg/unarchiveFile.go

@@ -1,4 +1,4 @@
-package model
+package pkg
 
 import (
 	"archive/zip"

+ 1 - 1
model/unarchiveFile_test.go → internal/pkg/unarchiveFile_test.go

@@ -1,4 +1,4 @@
-package model
+package pkg
 
 import (
 	"testing"

+ 19 - 25
model/util.go → internal/pkg/util.go

@@ -1,9 +1,10 @@
-package model
+package pkg
 
 import (
 	"fmt"
 	browser "github.com/EDDYCJY/fake-useragent"
-	"github.com/allanpk716/ChineseSubFinder/common"
+	common2 "github.com/allanpk716/ChineseSubFinder/internal/common"
+	"github.com/allanpk716/ChineseSubFinder/internal/types"
 	"github.com/go-resty/resty/v2"
 	"io"
 	"io/ioutil"
@@ -18,13 +19,13 @@ import (
 )
 
 // NewHttpClient 新建一个 resty 的对象
-func NewHttpClient(_reqParam ...common.ReqParam) *resty.Client {
+func NewHttpClient(_reqParam ...types.ReqParam) *resty.Client {
 	//const defUserAgent = "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"
 	//const defUserAgent = "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.77 Safari/537.36 Edg/91.0.864.41"
 	// 随机的 Browser
 	defUserAgent := browser.Random()
 
-	var reqParam common.ReqParam
+	var reqParam types.ReqParam
 	var HttpProxy, UserAgent, Referer string
 
 	if len(_reqParam) > 0 {
@@ -43,7 +44,7 @@ func NewHttpClient(_reqParam ...common.ReqParam) *resty.Client {
 	}
 
 	httpClient := resty.New()
-	httpClient.SetTimeout(common.HTMLTimeOut)
+	httpClient.SetTimeout(common2.HTMLTimeOut)
 	if HttpProxy != "" {
 		httpClient.SetProxy(HttpProxy)
 	} else {
@@ -62,8 +63,8 @@ func NewHttpClient(_reqParam ...common.ReqParam) *resty.Client {
 }
 
 // DownFile 从指定的 url 下载文件
-func DownFile(urlStr string, _reqParam ...common.ReqParam) ([]byte, string, error)  {
-	var reqParam common.ReqParam
+func DownFile(urlStr string, _reqParam ...types.ReqParam) ([]byte, string, error)  {
+	var reqParam types.ReqParam
 	if len(_reqParam) > 0 {
 		reqParam = _reqParam[0]
 	}
@@ -102,7 +103,7 @@ func AddBaseUrl(baseUrl, url string) string {
 func GetDebugFolder() (string, error) {
 	if defDebugFolder == "" {
 		nowProcessRoot, _ := os.Getwd()
-		nowProcessRoot = path.Join(nowProcessRoot, common.DebugFolder)
+		nowProcessRoot = path.Join(nowProcessRoot, common2.DebugFolder)
 		err := os.MkdirAll(nowProcessRoot, os.ModePerm)
 		if err != nil {
 			return "", err
@@ -117,7 +118,7 @@ func GetDebugFolder() (string, error) {
 func GetRootTmpFolder() (string, error) {
 	if defTmpFolder == "" {
 		nowProcessRoot, _ := os.Getwd()
-		nowProcessRoot = path.Join(nowProcessRoot, common.TmpFolder)
+		nowProcessRoot = path.Join(nowProcessRoot, common2.TmpFolder)
 		err := os.MkdirAll(nowProcessRoot, os.ModePerm)
 		if err != nil {
 			return "", err
@@ -306,15 +307,15 @@ func IsWantedVideoExtDef(fileName string) bool {
 	// TODO 强制使用固定的视频后缀名匹配列表,后续有需求再考虑额实现外部可配置的列表
 
 	if len(wantedExtList) < 1 {
-		defExtList = append(defExtList, common.VideoExtMp4)
-		defExtList = append(defExtList, common.VideoExtMkv)
-		defExtList = append(defExtList, common.VideoExtRmvb)
-		defExtList = append(defExtList, common.VideoExtIso)
+		defExtList = append(defExtList, common2.VideoExtMp4)
+		defExtList = append(defExtList, common2.VideoExtMkv)
+		defExtList = append(defExtList, common2.VideoExtRmvb)
+		defExtList = append(defExtList, common2.VideoExtIso)
 
-		wantedExtList = append(defExtList, common.VideoExtMp4)
-		wantedExtList = append(defExtList, common.VideoExtMkv)
-		wantedExtList = append(defExtList, common.VideoExtRmvb)
-		wantedExtList = append(defExtList, common.VideoExtIso)
+		wantedExtList = append(defExtList, common2.VideoExtMp4)
+		wantedExtList = append(defExtList, common2.VideoExtMkv)
+		wantedExtList = append(defExtList, common2.VideoExtRmvb)
+		wantedExtList = append(defExtList, common2.VideoExtIso)
 	}
 	fileName = strings.ToLower(filepath.Ext(fileName))
 	for _, s := range wantedExtList {
@@ -336,11 +337,4 @@ func ReloadBrowser() {
 		return
 	}
 	defer page.Close()
-}
-
-var (
-	defDebugFolder = ""
-	defTmpFolder = ""
-	wantedExtList = make([]string, 0)                   // 人工确认的需要监控的视频后缀名
-	defExtList    = make([]string, 0)                  // 内置支持的视频后缀名列表
-)
+}

+ 18 - 0
internal/types/config.go

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

+ 1 - 1
common/embyconfig.go → internal/types/emby/config.go

@@ -1,4 +1,4 @@
-package common
+package emby
 
 type EmbyConfig struct {
 	Url			string 		//	Emby 的地址,需要带上端口号 http://192.168.1.2:8089

+ 6 - 6
common/emby.go → internal/types/emby/type.go

@@ -1,4 +1,4 @@
-package common
+package emby
 
 import (
 	"strings"
@@ -45,12 +45,12 @@ type EmbyVideoInfo struct {
 }
 
 type EmbyMixInfo struct {
-	VideoFolderName	string			// 电影就是电影的文件夹名称,连续剧就是对应的剧集的 root 文件夹
-	VideoFileName string			// 视频文件名
+	VideoFolderName       string			// 电影就是电影的文件夹名称,连续剧就是对应的剧集的 root 文件夹
+	VideoFileName         string			// 视频文件名
 	VideoFileRelativePath string	// 视频文件的相对路径(注意,这里还是需要补齐 x:/电影 这样的 root 路径的,仅仅算相对路径)
-	VideoFileFullPath string
-	Ancestors []EmbyItemsAncestors
-	VideoInfo EmbyVideoInfo
+	VideoFileFullPath     string
+	Ancestors             []EmbyItemsAncestors
+	VideoInfo             EmbyVideoInfo
 }
 
 type Time time.Time

+ 1 - 1
common/language.go → internal/types/language.go

@@ -1,4 +1,4 @@
-package common
+package types
 
 const (
 	SubNameKeywordChineseSimple = "chs"

+ 31 - 0
internal/types/reqparam.go

@@ -0,0 +1,31 @@
+package types
+
+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
+	EmbyConfig                    emby.EmbyConfig
+	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,
+		SubTypePriority: 0,
+	}
+	return &r
+}

+ 12 - 9
common/seriesInfo.go → internal/types/series/info.go

@@ -1,6 +1,9 @@
-package common
+package series
 
-import "time"
+import (
+	"github.com/allanpk716/ChineseSubFinder/internal/types"
+	"time"
+)
 
 /*
 	这里只需要分为三层结构,因为有 sonarr 和 TMM 整理过
@@ -15,7 +18,7 @@ type SeriesInfo struct {
 	DirPath          string
 	SeasonDict       map[int]int
 	NeedDlSeasonDict map[int]int
-	NeedDlEpsKeyList map[string]EpisodeInfo		// SxEx
+	NeedDlEpsKeyList map[string]EpisodeInfo // SxEx
 }
 
 type EpisodeInfo struct {
@@ -26,14 +29,14 @@ type EpisodeInfo struct {
 	Dir                      string    // 这里需要记录字幕的位置,因为需要在同级目录匹配相应的字幕才行
 	FileFullPath             string    // 视频文件的全路径
 	ModifyTime               time.Time // 创建时间
-	AiredTime				 string    // 播出的时间
+	AiredTime				 string   // 播出的时间
 }
 
 type SubInfo struct {
-	Title      string
-	Season     int
-	Episode    int
-	Language   Language
-	Dir		   string	// 这里需要记录字幕的位置,因为需要在同级目录匹配相应的视频才行
+	Title        string
+	Season       int
+	Episode      int
+	Language     types.Language
+	Dir          string	// 这里需要记录字幕的位置,因为需要在同级目录匹配相应的视频才行
 	FileFullPath string 	// 字幕文件的全路径
 }

+ 5 - 3
common/subParserFileInfo.go → internal/types/subparser/fileinfo.go

@@ -1,10 +1,12 @@
-package common
+package subparser
 
-type SubParserFileInfo struct {
+import "github.com/allanpk716/ChineseSubFinder/internal/types"
+
+type FileInfo struct {
 	FromWhereSite string         // 从那个网站下载的
 	Name          string         // 字幕的名称,注意,这里需要额外的赋值,不会自动检测
 	Ext           string         // 字幕的后缀名
-	Lang          Language // 识别出来的语言
+	Lang          types.Language // 识别出来的语言
 	FileFullPath  string         // 字幕文件的全路径
 	Data          []byte         // 字幕的二进制文件内容
 	Dialogues     []OneDialogue  // 整个字幕文件的所有对话

+ 30 - 0
internal/types/supplier/subinfo.go

@@ -0,0 +1,30 @@
+package supplier
+
+import "github.com/allanpk716/ChineseSubFinder/internal/types"
+
+type SubInfo struct {
+	FromWhere    string         `json:"from_where"`     // 从哪个网站下载来的
+	TopN         int64          `json:"top_n"`          // 是 Top 几?
+	Name         string         `json:"name"`           // 字幕的名称,这个比较随意,优先是影片的名称,然后才是从网上下载字幕的对应名称
+	Language     types.Language `json:"language"`       // 字幕的语言
+	FileUrl      string         `json:"file-url"`       // 字幕文件下载的路径
+	Score        int64          `json:"score"`          // TODO 字幕的评分,需要有一个独立的评价体系。首先是每个网站自己的评价排序,然后再到统一的评分体系
+	Offset       int64          `json:"offset"`         // 字幕的偏移
+	Ext          string         `json:"ext"`            // 字幕文件的后缀名带点,有可能是直接能用的字幕文件,也可能是压缩包
+	Data         []byte         `json:"data"`           // 字幕文件的二进制数据
+	Season       int            `json:"season"`         // 第几季,默认-1
+	Episode      int            `json:"episode"`        // 第几集,默认-1
+	IsFullSeason bool           `json:"is_full_season"` // 是否是全季的字幕
+}
+
+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,
+		Score: score, Offset: offset, Ext: ext, Data: data}
+
+	s.Season = -1
+	s.Episode = -1
+
+	return &s
+}

+ 1 - 1
common/videoInfo.go → internal/types/videoInfo.go

@@ -1,4 +1,4 @@
-package common
+package types
 
 // VideoIMDBInfo 从 movie.xml *.nfo 中解析出的视频信息
 type VideoIMDBInfo struct {

+ 13 - 13
main.go

@@ -1,8 +1,8 @@
 package main
 
 import (
-	"github.com/allanpk716/ChineseSubFinder/common"
-	"github.com/allanpk716/ChineseSubFinder/model"
+	"github.com/allanpk716/ChineseSubFinder/internal/pkg"
+	"github.com/allanpk716/ChineseSubFinder/internal/types"
 	"github.com/robfig/cron/v3"
 	"github.com/sirupsen/logrus"
 	"github.com/spf13/viper"
@@ -10,13 +10,13 @@ import (
 
 func init() {
 	var err error
-	log = model.GetLogger()
-	configViper, err = model.InitConfigure()
+	log = pkg.GetLogger()
+	configViper, err = pkg.InitConfigure()
 	if err != nil {
 		log.Errorln("InitConfigure", err)
 		return 
 	}
-	config, err = model.ReadConfig(configViper)
+	config, err = pkg.ReadConfig(configViper)
 	if err != nil {
 		log.Errorln("ReadConfig", err)
 		return 
@@ -38,22 +38,22 @@ func main() {
 		httpProxy = ""
 	}
 	// 判断文件夹是否存在
-	if model.IsDir(config.MovieFolder) == false {
+	if pkg.IsDir(config.MovieFolder) == false {
 		log.Errorln("MovieFolder not found")
 		return
 	}
-	if model.IsDir(config.SeriesFolder) == false {
+	if pkg.IsDir(config.SeriesFolder) == false {
 		log.Errorln("SeriesFolder not found")
 		return
 	}
 
-	model.Notify = model.NewNotifyCenter(config.WhenSubSupplierInvalidWebHook)
+	pkg.Notify = pkg.NewNotifyCenter(config.WhenSubSupplierInvalidWebHook)
 
 	log.Infoln("MovieFolder:", config.MovieFolder)
 	log.Infoln("SeriesFolder:", config.SeriesFolder)
 
 	// ReloadBrowser 提前把浏览器下载好
-	model.ReloadBrowser()
+	pkg.ReloadBrowser()
 
 	//任务还没执行完,下一次执行时间到来,下一次执行就跳过不执行
 	c := cron.New(cron.WithChain(cron.SkipIfStillRunning(cron.DefaultLogger)))
@@ -80,12 +80,12 @@ func main() {
 func DownLoadStart(httpProxy string) {
 	defer func() {
 		log.Infoln("Download One End...")
-		model.Notify.Send()
+		pkg.Notify.Send()
 	}()
-	model.Notify.Clear()
+	pkg.Notify.Clear()
 
 	// 下载实例
-	downloader := NewDownloader(common.ReqParam{
+	downloader := NewDownloader(types.ReqParam{
 		HttpProxy:       httpProxy,
 		DebugMode:       config.DebugMode,
 		SaveMultiSub:    config.SaveMultiSub,
@@ -131,5 +131,5 @@ func DownLoadStart(httpProxy string) {
 var(
 	log         *logrus.Logger
 	configViper *viper.Viper
-	config      *common.Config
+	config      *types.Config
 )