media_library.go 4.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168
  1. package media_library
  2. import (
  3. "database/sql/driver"
  4. "encoding/json"
  5. "fmt"
  6. "math"
  7. "path"
  8. "strings"
  9. "github.com/qor5/admin/media"
  10. "github.com/qor5/admin/media/oss"
  11. "gorm.io/gorm"
  12. )
  13. var QorPreviewSizeName = "@qor_preview"
  14. var QorPreviewMaxSize = 200
  15. type MediaLibrary struct {
  16. gorm.Model
  17. SelectedType string
  18. File MediaLibraryStorage `sql:"size:4294967295;" mediaLibrary:"url:/system/{{class}}/{{primary_key}}/{{column}}.{{extension}}"`
  19. }
  20. type MediaOption struct {
  21. Video string `json:",omitempty"`
  22. FileName string `json:",omitempty"`
  23. URL string `json:",omitempty"`
  24. OriginalURL string `json:",omitempty"`
  25. CropOptions map[string]*media.CropOption `json:",omitempty"`
  26. Sizes map[string]*media.Size `json:",omitempty"`
  27. SelectedType string `json:",omitempty"`
  28. Description string `json:",omitempty"`
  29. Crop bool
  30. }
  31. func (mediaLibrary *MediaLibrary) ScanMediaOptions(mediaOption MediaOption) error {
  32. bytes, err := json.Marshal(mediaOption)
  33. if err == nil {
  34. return mediaLibrary.File.Scan(bytes)
  35. }
  36. return err
  37. }
  38. func (mediaLibrary *MediaLibrary) GetMediaOption() MediaOption {
  39. return MediaOption{
  40. Video: mediaLibrary.File.Video,
  41. FileName: mediaLibrary.File.GetFileName(),
  42. URL: mediaLibrary.File.URL(),
  43. OriginalURL: mediaLibrary.File.URL("original"),
  44. CropOptions: mediaLibrary.File.CropOptions,
  45. Sizes: mediaLibrary.File.GetSizes(),
  46. SelectedType: mediaLibrary.File.SelectedType,
  47. Description: mediaLibrary.File.Description,
  48. }
  49. }
  50. func (mediaLibrary *MediaLibrary) SetSelectedType(typ string) {
  51. mediaLibrary.SelectedType = typ
  52. }
  53. func (mediaLibrary *MediaLibrary) GetSelectedType() string {
  54. return mediaLibrary.SelectedType
  55. }
  56. type MediaLibraryStorage struct {
  57. oss.OSS
  58. Sizes map[string]*media.Size `json:",omitempty"`
  59. Video string
  60. SelectedType string
  61. Description string
  62. }
  63. func (mediaLibraryStorage MediaLibraryStorage) GetSizes() map[string]*media.Size {
  64. if len(mediaLibraryStorage.Sizes) == 0 && !(mediaLibraryStorage.GetFileHeader() != nil || mediaLibraryStorage.Crop) {
  65. return map[string]*media.Size{}
  66. }
  67. width := mediaLibraryStorage.Width
  68. height := mediaLibraryStorage.Height
  69. max := math.Max(float64(width), float64(height))
  70. if int(max) > QorPreviewMaxSize {
  71. ratio := float64(QorPreviewMaxSize) / max
  72. width = int(float64(width) * ratio)
  73. height = int(float64(height) * ratio)
  74. }
  75. var sizes = map[string]*media.Size{
  76. QorPreviewSizeName: {
  77. Width: width,
  78. Height: height,
  79. },
  80. }
  81. for key, value := range mediaLibraryStorage.Sizes {
  82. sizes[key] = value
  83. }
  84. return sizes
  85. }
  86. func (mediaLibraryStorage *MediaLibraryStorage) Scan(data interface{}) (err error) {
  87. switch values := data.(type) {
  88. case []byte:
  89. if mediaLibraryStorage.Sizes == nil {
  90. mediaLibraryStorage.Sizes = map[string]*media.Size{}
  91. }
  92. // cropOptions := mediaLibraryStorage.CropOptions
  93. sizeOptions := mediaLibraryStorage.Sizes
  94. if string(values) != "" {
  95. mediaLibraryStorage.Base.Scan(values)
  96. if err = json.Unmarshal(values, mediaLibraryStorage); err == nil {
  97. if mediaLibraryStorage.CropOptions == nil {
  98. mediaLibraryStorage.CropOptions = map[string]*media.CropOption{}
  99. }
  100. // for key, value := range cropOptions {
  101. // if _, ok := mediaLibraryStorage.CropOptions[key]; !ok {
  102. // mediaLibraryStorage.CropOptions[key] = value
  103. // }
  104. // }
  105. for key, value := range sizeOptions {
  106. if key == media.DefaultSizeKey {
  107. continue
  108. }
  109. if _, ok := mediaLibraryStorage.Sizes[key]; !ok {
  110. mediaLibraryStorage.Sizes[key] = value
  111. }
  112. }
  113. for key, value := range mediaLibraryStorage.CropOptions {
  114. if key == media.DefaultSizeKey {
  115. continue
  116. }
  117. if _, ok := mediaLibraryStorage.Sizes[key]; !ok {
  118. mediaLibraryStorage.Sizes[key] = &media.Size{Width: value.Width, Height: value.Height}
  119. }
  120. }
  121. }
  122. }
  123. case string:
  124. err = mediaLibraryStorage.Scan([]byte(values))
  125. case []string:
  126. for _, str := range values {
  127. if err = mediaLibraryStorage.Scan(str); err != nil {
  128. return err
  129. }
  130. }
  131. default:
  132. return mediaLibraryStorage.Base.Scan(data)
  133. }
  134. return nil
  135. }
  136. func (mediaLibraryStorage MediaLibraryStorage) Value() (driver.Value, error) {
  137. results, err := json.Marshal(mediaLibraryStorage)
  138. return string(results), err
  139. }
  140. func (mediaLibraryStorage MediaLibraryStorage) URL(styles ...string) string {
  141. if mediaLibraryStorage.Url != "" && len(styles) > 0 {
  142. ext := path.Ext(mediaLibraryStorage.Url)
  143. return fmt.Sprintf("%v.%v%v", strings.TrimSuffix(mediaLibraryStorage.Url, ext), styles[0], ext)
  144. }
  145. return mediaLibraryStorage.Url
  146. }