utils.go 3.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119
  1. package utils
  2. import (
  3. "fmt"
  4. "os"
  5. "path/filepath"
  6. "regexp"
  7. "xg_dba/internal/models"
  8. "github.com/mitchellh/mapstructure"
  9. "github.com/spf13/viper"
  10. )
  11. // fileExists 检查给定路径的文件是否存在。
  12. func FileExists(filename string) bool {
  13. info, err := os.Stat(filename)
  14. if os.IsNotExist(err) {
  15. return false
  16. }
  17. return !info.IsDir()
  18. }
  19. // parseTomlFile 使用 viper 解析 TOML 文件到提供的结构体中。
  20. func ParseTomlFile1(filePath string, v interface{}) error {
  21. // 为了防止 viper 的全局状态干扰解析结果,使用新的 viper 实例
  22. vp := viper.New()
  23. vp.SetConfigFile(filePath)
  24. vp.SetConfigType("toml")
  25. if err := vp.ReadInConfig(); err != nil {
  26. return err
  27. }
  28. // 使用 `vp.AllSettings()` 将配置映射到提供的结构体
  29. settings := vp.AllSettings()
  30. if err := DecodeSettings(settings, v); err != nil {
  31. return err
  32. }
  33. return nil
  34. }
  35. // parseTomlFile 使用 viper 解析 TOML 文件到提供的结构体中。
  36. func ParseTomlFile(filePath string, v interface{}) error {
  37. // 创建一个新的 viper 实例,防止全局状态干扰
  38. vp := viper.New()
  39. vp.SetConfigFile(filePath)
  40. vp.SetConfigType("toml")
  41. // 读取配置文件
  42. if err := vp.ReadInConfig(); err != nil {
  43. return err
  44. }
  45. // 将配置文件内容解析到提供的结构体
  46. if err := vp.Unmarshal(v); err != nil {
  47. return err
  48. }
  49. return nil
  50. }
  51. // decodeSettings 将 viper 的设置映射解码到目标结构体。
  52. func DecodeSettings(settings map[string]interface{}, v interface{}) error {
  53. decoderConfig := &mapstructure.DecoderConfig{
  54. Result: v,
  55. TagName: "toml",
  56. WeaklyTypedInput: true,
  57. }
  58. decoder, err := mapstructure.NewDecoder(decoderConfig)
  59. if err != nil {
  60. return err
  61. }
  62. return decoder.Decode(settings)
  63. }
  64. // getLatestOsInfoFile 在给定目录中查找最新的 os_info TOML 文件。
  65. // 它查找匹配模式 "os_info_<timestamp>.toml" 的文件,并返回最新的一个。
  66. func GetLatestOsInfoFiles(dirPath string) (map[string]models.SystemMetaInfo, error) {
  67. // 编译正则表达式,匹配并捕获 <ip> 和 <timestamp>
  68. pattern := regexp.MustCompile(`^(\d{1,3}(?:\.\d{1,3}){3})_os_info_(\d{8}_\d{6})\.toml$`)
  69. files, err := os.ReadDir(dirPath)
  70. if err != nil {
  71. return nil, err
  72. }
  73. // 创建用于存储最新文件的映射
  74. latestFiles := make(map[string]string)
  75. latestTimestamps := make(map[string]string)
  76. for _, file := range files {
  77. if !file.IsDir() {
  78. name := file.Name()
  79. matches := pattern.FindStringSubmatch(name)
  80. if len(matches) == 3 {
  81. ip := matches[1]
  82. timestamp := matches[2]
  83. // 比较并更新最新的时间戳
  84. if prevTimestamp, exists := latestTimestamps[ip]; !exists || timestamp > prevTimestamp {
  85. latestTimestamps[ip] = timestamp
  86. latestFiles[ip] = filepath.Join(dirPath, name)
  87. }
  88. }
  89. }
  90. }
  91. systemMeta := make(map[string]models.SystemMetaInfo)
  92. for ip, path := range latestFiles {
  93. fmt.Printf("Latest os_info file for %s: %s\n", ip, path)
  94. var systemMetaInfo models.SystemMetaInfo
  95. if err := ParseTomlFile(path, &systemMetaInfo); err != nil {
  96. return nil, err
  97. }
  98. systemMeta[ip] = systemMetaInfo
  99. fmt.Println("获取目录中最新的 os_info.toml 文件:", systemMetaInfo)
  100. }
  101. return systemMeta, nil
  102. }