oss.go 2.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116
  1. package oss
  2. import (
  3. "bytes"
  4. "io"
  5. "io/ioutil"
  6. "strings"
  7. "github.com/qor/oss"
  8. "github.com/qor/oss/filesystem"
  9. "github.com/qor5/admin/media"
  10. )
  11. var (
  12. // URLTemplate default URL template
  13. URLTemplate = "/system/{{class}}/{{primary_key}}/{{column}}/{{filename_with_hash}}"
  14. // Storage the storage used to save medias
  15. Storage oss.StorageInterface = filesystem.New("public")
  16. _ media.Media = &OSS{}
  17. )
  18. // OSS common storage interface
  19. type OSS struct {
  20. media.Base
  21. }
  22. // DefaultURLTemplateHandler used to generate URL and save into database
  23. var DefaultURLTemplateHandler = func(oss OSS, option *media.Option) (url string) {
  24. if url = option.Get("URL"); url == "" {
  25. url = URLTemplate
  26. }
  27. url = strings.Join([]string{strings.TrimSuffix(Storage.GetEndpoint(), "/"), strings.TrimPrefix(url, "/")}, "/")
  28. if strings.HasPrefix(url, "/") {
  29. return url
  30. }
  31. for _, prefix := range []string{"https://", "http://"} {
  32. url = strings.TrimPrefix(url, prefix)
  33. }
  34. // convert `getqor.com/hello` => `//getqor.com/hello`
  35. return "//" + url
  36. }
  37. // GetURLTemplate URL's template
  38. func (o OSS) GetURLTemplate(option *media.Option) (url string) {
  39. return DefaultURLTemplateHandler(o, option)
  40. }
  41. // DefaultStoreHandler used to store reader with default Storage
  42. var DefaultStoreHandler = func(oss OSS, path string, option *media.Option, reader io.Reader) error {
  43. _, err := Storage.Put(path, reader)
  44. return err
  45. }
  46. // Store save reader's content with path
  47. func (o OSS) Store(path string, option *media.Option, reader io.Reader) error {
  48. return DefaultStoreHandler(o, path, option, reader)
  49. }
  50. // DefaultRetrieveHandler used to retrieve file
  51. var DefaultRetrieveHandler = func(oss OSS, path string) (media.FileInterface, error) {
  52. result, err := Storage.GetStream(path)
  53. if f, ok := result.(media.FileInterface); ok {
  54. return f, err
  55. }
  56. if err == nil {
  57. buf := []byte{}
  58. if buf, err = ioutil.ReadAll(result); err == nil {
  59. result := ClosingReadSeeker{bytes.NewReader(buf)}
  60. result.Seek(0, 0)
  61. return result, err
  62. }
  63. }
  64. return nil, err
  65. }
  66. // Retrieve retrieve file content with url
  67. func (o OSS) Retrieve(path string) (media.FileInterface, error) {
  68. return DefaultRetrieveHandler(o, path)
  69. }
  70. // URL return file's url with given style
  71. func (o OSS) URL(styles ...string) string {
  72. url := o.Base.URL(styles...)
  73. newurl, err := Storage.GetURL(url)
  74. if err != nil || len(newurl) == 0 {
  75. return url
  76. }
  77. return newurl
  78. }
  79. func (o OSS) String() string {
  80. url := o.Base.URL()
  81. newurl, err := Storage.GetURL(url)
  82. if err != nil || len(newurl) == 0 {
  83. return url
  84. }
  85. return newurl
  86. }
  87. // ClosingReadSeeker implement Closer interface for ReadSeeker
  88. type ClosingReadSeeker struct {
  89. io.ReadSeeker
  90. }
  91. // Close implement Closer interface for Buffer
  92. func (ClosingReadSeeker) Close() error {
  93. return nil
  94. }