settings.go 5.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213
  1. package settings
  2. import (
  3. "net/url"
  4. "os"
  5. "path/filepath"
  6. "strings"
  7. "sync"
  8. "github.com/allanpk716/ChineseSubFinder/pkg/strcut_json"
  9. )
  10. type Settings struct {
  11. SpeedDevMode bool // 是否为开发模式,代码开启这个会跳过某些流程,加快测试速度
  12. configFPath string
  13. UserInfo *UserInfo `json:"user_info"`
  14. CommonSettings *CommonSettings `json:"common_settings"`
  15. SubtitleSources *SubtitleSources `json:"subtitle_sources"`
  16. AdvancedSettings *AdvancedSettings `json:"advanced_settings"`
  17. EmbySettings *EmbySettings `json:"emby_settings"`
  18. DeveloperSettings *DeveloperSettings `json:"developer_settings"`
  19. TimelineFixerSettings *TimelineFixerSettings `json:"timeline_fixer_settings"`
  20. ExperimentalFunction *ExperimentalFunction `json:"experimental_function"`
  21. }
  22. // Get 获取 Settings 的实例
  23. func Get(reloadSettings ...bool) *Settings {
  24. _settingsLocker.Lock()
  25. defer _settingsLocker.Unlock()
  26. if _settings == nil {
  27. _settingsOnce.Do(func() {
  28. if _configRootPath == "" {
  29. panic("请先调用 SetConfigRootPath 设置配置文件的根目录")
  30. }
  31. _settings = NewSettings(_configRootPath)
  32. if isFile(_settings.configFPath) == false {
  33. err := os.MkdirAll(filepath.Dir(_settings.configFPath), os.ModePerm)
  34. if err != nil {
  35. panic("创建配置文件目录失败," + err.Error())
  36. }
  37. // 配置文件不存在,新建一个空白的
  38. err = _settings.Save()
  39. if err != nil {
  40. panic("Can't Save Config File:" + configName + " Error: " + err.Error())
  41. }
  42. } else {
  43. // 读取存在的文件
  44. err := _settings.read()
  45. if err != nil {
  46. panic("Can't Read Config File:" + configName + " Error: " + err.Error())
  47. }
  48. }
  49. })
  50. // 是否需要重新读取配置信息,这个可能在每次保存配置文件后需要操作
  51. if len(reloadSettings) >= 1 {
  52. if reloadSettings[0] == true {
  53. err := _settings.read()
  54. if err != nil {
  55. panic("Can't Read Config File:" + configName + " Error: " + err.Error())
  56. }
  57. }
  58. }
  59. }
  60. return _settings
  61. }
  62. // SetFullNewSettings 从 Web 端传入新的 Settings 完整设置
  63. func SetFullNewSettings(inSettings *Settings) error {
  64. _settingsLocker.Lock()
  65. defer _settingsLocker.Unlock()
  66. nowConfigFPath := _settings.configFPath
  67. _settings = inSettings
  68. _settings.configFPath = nowConfigFPath
  69. return _settings.Save()
  70. }
  71. // SetConfigRootPath 需要先设置这个信息再调用 Get
  72. func SetConfigRootPath(configRootPath string) {
  73. _configRootPath = configRootPath
  74. }
  75. func NewSettings(configRootDirFPath string) *Settings {
  76. nowConfigFPath := filepath.Join(configRootDirFPath, configName)
  77. return &Settings{
  78. configFPath: nowConfigFPath,
  79. UserInfo: &UserInfo{},
  80. CommonSettings: NewCommonSettings(),
  81. SubtitleSources: NewSubtitleSources(),
  82. AdvancedSettings: NewAdvancedSettings(),
  83. EmbySettings: NewEmbySettings(),
  84. DeveloperSettings: NewDeveloperSettings(),
  85. TimelineFixerSettings: NewTimelineFixerSettings(),
  86. ExperimentalFunction: NewExperimentalFunction(),
  87. }
  88. }
  89. func (s *Settings) read() error {
  90. // 需要检查 url 是否正确
  91. newEmbyAddressUrl := removeSuffixAddressSlash(s.EmbySettings.AddressUrl)
  92. _, err := url.Parse(newEmbyAddressUrl)
  93. if err != nil {
  94. return err
  95. }
  96. err = strcut_json.ToStruct(s.configFPath, s)
  97. if err != nil {
  98. return err
  99. }
  100. s.EmbySettings.AddressUrl = newEmbyAddressUrl
  101. return nil
  102. }
  103. func (s *Settings) Save() error {
  104. // 需要检查 url 是否正确
  105. newEmbyAddressUrl := removeSuffixAddressSlash(s.EmbySettings.AddressUrl)
  106. _, err := url.Parse(newEmbyAddressUrl)
  107. if err != nil {
  108. return err
  109. }
  110. s.EmbySettings.AddressUrl = newEmbyAddressUrl
  111. return strcut_json.ToFile(s.configFPath, s)
  112. }
  113. func (s *Settings) GetNoPasswordSettings() *Settings {
  114. nowSettings := NewSettings(_configRootPath)
  115. err := nowSettings.read()
  116. if err != nil {
  117. panic("Can't Read Config File:" + configName + " Error: " + err.Error())
  118. }
  119. // 需要关闭本地代理的实例,否则无法进行 clone 操作
  120. //_ = s.AdvancedSettings.ProxySettings.CloseLocalHttpProxyServer()
  121. //nowSettings := clone.Clone(s).(*Settings)
  122. nowSettings.UserInfo.Password = noPassword4Show
  123. return nowSettings
  124. }
  125. // Check 检测,某些参数有范围限制
  126. func (s *Settings) Check() {
  127. // 每个网站最多找 Top 几的字幕结果,评价系统成熟后,才有设计的意义
  128. if s.AdvancedSettings.Topic < 0 || s.AdvancedSettings.Topic > 3 {
  129. s.AdvancedSettings.Topic = 1
  130. }
  131. // 如果 Debug 模式开启了,强制设置线程数为1,方便定位问题
  132. if s.AdvancedSettings.DebugMode == true {
  133. s.CommonSettings.Threads = 1
  134. } else {
  135. // 并发线程的范围控制
  136. if s.CommonSettings.Threads <= 0 || s.CommonSettings.Threads > 6 {
  137. s.CommonSettings.Threads = 6
  138. }
  139. }
  140. }
  141. // isDir 存在且是文件夹
  142. func isDir(path string) bool {
  143. s, err := os.Stat(path)
  144. if err != nil {
  145. return false
  146. }
  147. return s.IsDir()
  148. }
  149. // isFile 存在且是文件
  150. func isFile(filePath string) bool {
  151. s, err := os.Stat(filePath)
  152. if err != nil {
  153. return false
  154. }
  155. return !s.IsDir()
  156. }
  157. // 将字符串后面最后一个字符,如果是 / 那么则替换掉,多个也会
  158. func removeSuffixAddressSlash(orgAddressUrlString string) string {
  159. outString := orgAddressUrlString
  160. for {
  161. if strings.HasSuffix(outString, "/") == true {
  162. outString = outString[:len(outString)-1]
  163. } else {
  164. break
  165. }
  166. }
  167. return outString
  168. }
  169. var (
  170. _settings *Settings
  171. _settingsLocker sync.Mutex
  172. _settingsOnce sync.Once
  173. _configRootPath string
  174. )
  175. const (
  176. noPassword4Show = "******" // 填充使用
  177. configName = "ChineseSubFinderSettings.json"
  178. )