sub_helper.go 4.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116
  1. package model
  2. import (
  3. "github.com/allanpk716/ChineseSubFinder/common"
  4. "github.com/go-rod/rod/lib/utils"
  5. "os"
  6. "path"
  7. "path/filepath"
  8. "strings"
  9. )
  10. // OrganizeDlSubFiles 需要从汇总来是网站字幕中,解压对应的压缩包中的字幕出来
  11. func OrganizeDlSubFiles(tmpFolderName string, subInfos []common.SupplierSubInfo) (map[string][]string, error) {
  12. // 缓存列表,整理后的字幕列表
  13. // SxEx - []string 字幕的路径
  14. var siteSubInfoDict = make(map[string][]string)
  15. tmpFolderFullPath, err := GetTmpFolder(tmpFolderName)
  16. if err != nil {
  17. return nil, err
  18. }
  19. // 把后缀名给改好
  20. ChangeVideoExt2SubExt(subInfos)
  21. // 第三方的解压库,首先不支持 io.Reader 的操作,也就是得缓存到本地硬盘再读取解压
  22. // 且使用 walk 会无法解压 rar,得指定具体的实例,太麻烦了,直接用通用的接口得了,就是得都缓存下来再判断
  23. // 基于以上两点,写了一堆啰嗦的逻辑···
  24. for _, subInfo := range subInfos {
  25. // 先存下来,保存是时候需要前缀,前缀就是从那个网站下载来的
  26. nowFileSaveFullPath := path.Join(tmpFolderFullPath, GetFrontNameAndOrgName(subInfo))
  27. err = utils.OutputFile(nowFileSaveFullPath, subInfo.Data)
  28. if err != nil {
  29. GetLogger().Errorln("getFrontNameAndOrgName - OutputFile",subInfo.FromWhere, subInfo.Name, subInfo.TopN, err)
  30. continue
  31. }
  32. nowExt := strings.ToLower(subInfo.Ext)
  33. epsKey := GetEpisodeKeyName(subInfo.Season, subInfo.Episode)
  34. _, ok := siteSubInfoDict[epsKey]
  35. if ok == false {
  36. // 不存在则实例化
  37. siteSubInfoDict[epsKey] = make([]string, 0)
  38. }
  39. if nowExt != ".zip" && nowExt != ".tar" && nowExt != ".rar" && nowExt != ".7z" {
  40. // 是否是受支持的字幕类型
  41. if IsSubExtWanted(nowExt) == false {
  42. continue
  43. }
  44. // 加入缓存列表
  45. siteSubInfoDict[epsKey] = append(siteSubInfoDict[epsKey], nowFileSaveFullPath)
  46. } else {
  47. // 那么就是需要解压的文件了
  48. // 解压,给一个单独的文件夹
  49. unzipTmpFolder := path.Join(tmpFolderFullPath, subInfo.FromWhere)
  50. err = os.MkdirAll(unzipTmpFolder, os.ModePerm)
  51. if err != nil {
  52. return nil, err
  53. }
  54. err = UnArchiveFile(nowFileSaveFullPath, unzipTmpFolder)
  55. // 解压完成后,遍历受支持的字幕列表,加入缓存列表
  56. if err != nil {
  57. GetLogger().Errorln("archiver.UnArchive", subInfo.FromWhere, subInfo.Name, subInfo.TopN, err)
  58. continue
  59. }
  60. // 搜索这个目录下的所有符合字幕格式的文件
  61. subFileFullPaths, err := SearchMatchedSubFile(unzipTmpFolder)
  62. if err != nil {
  63. GetLogger().Errorln("searchMatchedSubFile", subInfo.FromWhere, subInfo.Name, subInfo.TopN, err)
  64. continue
  65. }
  66. // 这里需要给这些下载到的文件进行改名,加是从那个网站来的前缀,后续好查找
  67. for _, fileFullPath := range subFileFullPaths {
  68. newSubName := AddFrontName(subInfo, filepath.Base(fileFullPath))
  69. newSubNameFullPath := path.Join(tmpFolderFullPath, newSubName)
  70. // 改名
  71. err = os.Rename(fileFullPath, newSubNameFullPath)
  72. if err != nil {
  73. GetLogger().Errorln("os.Rename", subInfo.FromWhere, subInfo.Name, subInfo.TopN, err)
  74. continue
  75. }
  76. // 加入缓存列表
  77. siteSubInfoDict[epsKey] = append(siteSubInfoDict[epsKey], newSubNameFullPath)
  78. }
  79. }
  80. }
  81. return siteSubInfoDict, nil
  82. }
  83. // ChangeVideoExt2SubExt 检测 Name,如果是视频的后缀名就改为字幕的后缀名
  84. func ChangeVideoExt2SubExt(subInfos []common.SupplierSubInfo) {
  85. for x, info := range subInfos {
  86. tmpSubFileName := info.Name
  87. // 如果后缀名是下载字幕目标的后缀名 或者 是压缩包格式的,则跳过
  88. if strings.Contains(tmpSubFileName, info.Ext) == true || IsWantedArchiveExtName(tmpSubFileName) == true {
  89. } else {
  90. subInfos[x].Name = tmpSubFileName + info.Ext
  91. }
  92. }
  93. }
  94. // FindChineseBestSubtitle 找到合适的中文字幕,优先简体双语,简体->繁体,以及 字幕类型的优先级选择
  95. func FindChineseBestSubtitle(subs []common.SubParserFileInfo) *common.SubParserFileInfo {
  96. for _, info := range subs {
  97. // 找到了中文字幕
  98. if HasChineseLang(info.Lang) == true {
  99. // 优先双语
  100. if IsBilingualSubtitle(info.Lang) == true {
  101. return &info
  102. }
  103. return &info
  104. }
  105. }
  106. return nil
  107. }