You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 

129 rivejä
2.8 KiB

  1. package storage
  2. import (
  3. "bytes"
  4. "encoding/json"
  5. "fmt"
  6. "io"
  7. "log"
  8. "os"
  9. "path/filepath"
  10. )
  11. type LocalStorage struct {
  12. Storage
  13. basedir string
  14. logger *log.Logger
  15. }
  16. func NewLocalStorage(basedir string, logger *log.Logger) (*LocalStorage, error) {
  17. return &LocalStorage{basedir: basedir, logger: logger}, nil
  18. }
  19. func (s *LocalStorage) Type() string {
  20. return "local"
  21. }
  22. func (s *LocalStorage) Get(token string, filename string) (reader io.ReadCloser, metadata Metadata, err error) {
  23. path := filepath.Join(s.basedir, token, filename)
  24. // content type , content length
  25. reader, err = os.Open(path)
  26. if err != nil {
  27. return nil, Metadata{}, err
  28. }
  29. metadata, err = s.Head(token, filename)
  30. if err != nil {
  31. return nil, Metadata{}, err
  32. }
  33. return reader, metadata, nil
  34. }
  35. func (s *LocalStorage) Head(token string, filename string) (metadata Metadata, err error) {
  36. path := filepath.Join(s.basedir, token, filename)
  37. fi, err := os.Open(path)
  38. if err != nil {
  39. return
  40. }
  41. err = json.NewDecoder(fi).Decode(&metadata)
  42. if err != nil {
  43. return Metadata{}, err
  44. }
  45. return metadata, nil
  46. }
  47. func (s *LocalStorage) Meta(token string, filename string, metadata Metadata) error {
  48. return s.putMetadata(token, filename, metadata)
  49. }
  50. func (s *LocalStorage) Put(token string, filename string, reader io.Reader, metadata Metadata) error {
  51. err := s.putMetadata(token, filename, metadata)
  52. if err != nil {
  53. return err
  54. }
  55. err = s.put(token, filename, reader)
  56. if err != nil {
  57. //Delete the metadata if the put failed
  58. _ = s.Delete(token, fmt.Sprintf("%s.metadata", filename))
  59. }
  60. return err
  61. }
  62. func (s *LocalStorage) put(token string, filename string, reader io.Reader) error {
  63. var f io.WriteCloser
  64. var err error
  65. path := filepath.Join(s.basedir, token)
  66. if err = os.MkdirAll(path, 0700); err != nil && !os.IsExist(err) {
  67. return err
  68. }
  69. if f, err = os.OpenFile(filepath.Join(path, filename), os.O_RDWR|os.O_CREATE|os.O_TRUNC, 0600); err != nil {
  70. return err
  71. }
  72. defer f.Close()
  73. _, err = io.Copy(f, reader)
  74. return err
  75. }
  76. func (s *LocalStorage) putMetadata(token string, filename string, metadata Metadata) error {
  77. buffer := &bytes.Buffer{}
  78. if err := json.NewEncoder(buffer).Encode(metadata); err != nil {
  79. log.Printf("%s", err.Error())
  80. return err
  81. } else if err := s.put(token, filename, buffer); err != nil {
  82. log.Printf("%s", err.Error())
  83. return nil
  84. }
  85. return nil
  86. }
  87. func (s *LocalStorage) Delete(token string, filename string) (err error) {
  88. metadata := filepath.Join(s.basedir, token, fmt.Sprintf("%s.metadata", filename))
  89. _ = os.Remove(metadata)
  90. path := filepath.Join(s.basedir, token, filename)
  91. err = os.Remove(path)
  92. return
  93. }
  94. func (s *LocalStorage) IsNotExist(err error) bool {
  95. if err == nil {
  96. return false
  97. }
  98. return os.IsNotExist(err)
  99. }
  100. func (s *LocalStorage) DeleteExpired() error {
  101. return nil
  102. }