backup_email.go 3.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139
  1. package jobs
  2. import (
  3. "gadmin/internal/cron/jobs/types"
  4. "gadmin/utility"
  5. "gadmin/utility/character"
  6. "io"
  7. "io/ioutil"
  8. "os"
  9. "path/filepath"
  10. "sort"
  11. "strings"
  12. "time"
  13. "github.com/sirupsen/logrus"
  14. "github.com/spf13/cast"
  15. )
  16. var BackupEmail = new(jBackupEmail)
  17. const EmailBackupPath = "/email/" // 备份二级路径
  18. type jBackupEmail struct{}
  19. func (j *jBackupEmail) Run() {
  20. logrus.WithField("source", "email").Info("BackupEmail Run.....")
  21. j.createDir()
  22. data, err := ioutil.ReadFile(os.Getenv("STORAGE_EMAILS"))
  23. if err != nil {
  24. logrus.WithField("source", "email").Errorf("Run read file err:%v", err.Error())
  25. return
  26. }
  27. if j.getLastMd5() != character.Md5Content(data) {
  28. dstFileName := j.backupPath() + time.Now().Format("2006-01-02-150405")
  29. j.copyFile(dstFileName, os.Getenv("STORAGE_EMAILS"))
  30. j.cleanupExpired()
  31. return
  32. }
  33. logrus.WithField("source", "email").Infof("neglect..")
  34. }
  35. func (j *jBackupEmail) getLastMd5() string {
  36. lastName := ""
  37. lastIndex := 0
  38. err := filepath.Walk(j.backupPath(), func(pat string, info os.FileInfo, err error) error {
  39. n := cast.ToInt(strings.ReplaceAll(info.Name(), "-", ""))
  40. if n > lastIndex {
  41. lastIndex = n
  42. lastName = info.Name()
  43. }
  44. return nil
  45. })
  46. if err != nil {
  47. logrus.WithField("source", "email").Errorf("getLastMd5 file err = %v\n", err)
  48. }
  49. if lastIndex == 0 {
  50. return ""
  51. }
  52. data, err := os.ReadFile(j.backupPath() + lastName)
  53. if err != nil {
  54. logrus.WithField("source", "email").Errorf("getLastMd5 read file err:%v", err.Error())
  55. return ""
  56. }
  57. return character.Md5Content(data)
  58. }
  59. func (j *jBackupEmail) copyFile(dstFileName string, srcFileName string) (written int64, err error) {
  60. srcFile, err := os.Open(srcFileName)
  61. if err != nil {
  62. logrus.WithField("source", "email").Errorf("open file err = %v\n", err)
  63. return
  64. }
  65. defer srcFile.Close()
  66. dstFile, err := os.Create(dstFileName)
  67. if err != nil {
  68. logrus.WithField("source", "email").Errorf("open file err = %v\n", err)
  69. return
  70. }
  71. defer dstFile.Close()
  72. return io.Copy(dstFile, srcFile)
  73. }
  74. func (j *jBackupEmail) cleanupExpired() {
  75. var files types.SrcFiles
  76. err := filepath.Walk(j.backupPath(), func(pat string, info os.FileInfo, err error) error {
  77. index := cast.ToInt(strings.ReplaceAll(info.Name(), "-", ""))
  78. if index > 0 {
  79. files = append(files, types.SrcFile{
  80. Name: info.Name(),
  81. Index: index,
  82. })
  83. }
  84. return nil
  85. })
  86. if err != nil {
  87. logrus.WithField("source", "email").Errorf("getLastMd5 file err = %v\n", err)
  88. }
  89. // 倒序,最新的备份排在最前面
  90. sort.Sort(files)
  91. // 保留最新的100份,之前的加入到清理
  92. var cleanFiles types.SrcFiles
  93. for k, v := range files {
  94. if k+1 > 100 {
  95. cleanFiles = append(cleanFiles, v)
  96. }
  97. }
  98. if len(cleanFiles) == 0 {
  99. return
  100. }
  101. for _, v := range cleanFiles {
  102. path := j.backupPath() + v.Name
  103. logrus.WithField("source", "email").Infoln("清理邮件备份:", path)
  104. if err := os.Remove(path); err != nil {
  105. logrus.WithField("source", "email").Errorf("os.Remove err:%v", err)
  106. }
  107. }
  108. }
  109. func (j *jBackupEmail) createDir() {
  110. utility.CreateDir(j.backupPath())
  111. }
  112. func (j *jBackupEmail) backupPath() string {
  113. return os.Getenv("BACKUP_PATH") + EmailBackupPath
  114. }