util.go 3.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139
  1. package util
  2. import (
  3. "bytes"
  4. "context"
  5. "fmt"
  6. "io"
  7. "os"
  8. "time"
  9. "github.com/minio/minio-go/v7"
  10. )
  11. func DrainChannelBuffer[T any](ch <-chan T) (ok bool) {
  12. for {
  13. select {
  14. case _, ok = <-ch:
  15. if !ok {
  16. return
  17. }
  18. default:
  19. return true
  20. }
  21. }
  22. }
  23. func FmtMyTime(t time.Time) string {
  24. return t.Format("2006-01-02 15:04:05.000")
  25. }
  26. func FmtMyDate(t time.Time) string {
  27. return t.Format("2006-01-02")
  28. }
  29. func MinioObjectExists(minioClient *minio.Client, bucketName string, filePath string) (bool, error) {
  30. _, err := minioClient.StatObject(context.Background(), bucketName, filePath, minio.StatObjectOptions{})
  31. if err != nil {
  32. if minio.ToErrorResponse(err).Code == "NoSuchKey" {
  33. return false, nil
  34. }
  35. return false, fmt.Errorf("stat object failed: %w", err)
  36. }
  37. return true, nil
  38. }
  39. func MinioCreateFolderIfNotExists(minioClient *minio.Client, bucketName string, filePath string) error {
  40. exists, err := MinioObjectExists(minioClient, bucketName, filePath)
  41. if err != nil {
  42. return fmt.Errorf("check object exists failed: %w", err)
  43. }
  44. if exists {
  45. return nil
  46. }
  47. _, err = minioClient.PutObject(context.Background(), bucketName, filePath, nil, 0, minio.PutObjectOptions{})
  48. if err != nil {
  49. return fmt.Errorf("put object failed: %w", err)
  50. }
  51. return nil
  52. }
  53. func MinioUploadFile(minioClient *minio.Client, bucketName string, objPath string, localPath string, overwrite bool) (uploaded bool, err error) {
  54. if !overwrite {
  55. // First check if the object exists
  56. exists, err := MinioObjectExists(minioClient, bucketName, objPath)
  57. if err != nil {
  58. return false, fmt.Errorf("check object exists failed: %w", err)
  59. }
  60. if exists {
  61. return false, nil
  62. }
  63. }
  64. // Then upload the file
  65. _, err = minioClient.FPutObject(context.Background(), bucketName, objPath, localPath,
  66. minio.PutObjectOptions{ContentType: "application/octet-stream"})
  67. if err != nil {
  68. return false, fmt.Errorf("fput object failed: %w", err)
  69. }
  70. return true, nil
  71. }
  72. // Should only be used for small files
  73. func MinioUploadFileIfChanged(minioClient *minio.Client, bucketName string, objPath string, localPath string) (uploaded bool, err error) {
  74. // First check if the object exists
  75. exists, err := MinioObjectExists(minioClient, bucketName, objPath)
  76. if err != nil {
  77. return false, fmt.Errorf("check object exists failed: %w", err)
  78. }
  79. // Then check if the file has changed by comparing the content
  80. if exists {
  81. isUnchanged, err := func() (bool, error) {
  82. // Get the object
  83. obj, err := minioClient.GetObject(context.Background(), bucketName, objPath, minio.GetObjectOptions{})
  84. if err != nil {
  85. return false, fmt.Errorf("get object failed: %w", err)
  86. }
  87. defer obj.Close()
  88. // Compare the content (io.ReadAll)
  89. localFile, err := os.Open(localPath)
  90. if err != nil {
  91. return false, fmt.Errorf("open local file failed: %w", err)
  92. }
  93. defer localFile.Close()
  94. objContent, err := io.ReadAll(obj)
  95. if err != nil {
  96. return false, fmt.Errorf("read object content failed: %w", err)
  97. }
  98. localContent, err := io.ReadAll(localFile)
  99. if err != nil {
  100. return false, fmt.Errorf("read local content failed: %w", err)
  101. }
  102. if bytes.Equal(objContent, localContent) {
  103. return true, nil
  104. }
  105. return false, nil
  106. }()
  107. if err != nil {
  108. return false, err
  109. }
  110. if isUnchanged {
  111. return false, nil
  112. }
  113. }
  114. // Then upload the file
  115. _, err = minioClient.FPutObject(context.Background(), bucketName, objPath, localPath,
  116. minio.PutObjectOptions{ContentType: "application/octet-stream"})
  117. if err != nil {
  118. return false, fmt.Errorf("fput object failed: %w", err)
  119. }
  120. return true, nil
  121. }