Contains the Concourse pipeline definition for building a line-server container
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.

174 lines
3.6 KiB

  1. package localfs
  2. import (
  3. "encoding/json"
  4. "io"
  5. "io/ioutil"
  6. "os"
  7. "path"
  8. "time"
  9. "github.com/andreimarcu/linx-server/backends"
  10. "github.com/andreimarcu/linx-server/helpers"
  11. )
  12. type LocalfsBackend struct {
  13. metaPath string
  14. filesPath string
  15. }
  16. type MetadataJSON struct {
  17. DeleteKey string `json:"delete_key"`
  18. Sha256sum string `json:"sha256sum"`
  19. Mimetype string `json:"mimetype"`
  20. Size int64 `json:"size"`
  21. Expiry int64 `json:"expiry"`
  22. ArchiveFiles []string `json:"archive_files,omitempty"`
  23. }
  24. func (b LocalfsBackend) Delete(key string) (err error) {
  25. err = os.Remove(path.Join(b.filesPath, key))
  26. if err != nil {
  27. return
  28. }
  29. err = os.Remove(path.Join(b.metaPath, key))
  30. return
  31. }
  32. func (b LocalfsBackend) Exists(key string) (bool, error) {
  33. _, err := os.Stat(path.Join(b.filesPath, key))
  34. return err == nil, err
  35. }
  36. func (b LocalfsBackend) Head(key string) (metadata backends.Metadata, err error) {
  37. f, err := os.Open(path.Join(b.metaPath, key))
  38. if os.IsNotExist(err) {
  39. return metadata, backends.NotFoundErr
  40. } else if err != nil {
  41. return metadata, backends.BadMetadata
  42. }
  43. defer f.Close()
  44. decoder := json.NewDecoder(f)
  45. mjson := MetadataJSON{}
  46. if err := decoder.Decode(&mjson); err != nil {
  47. return metadata, backends.BadMetadata
  48. }
  49. metadata.DeleteKey = mjson.DeleteKey
  50. metadata.Mimetype = mjson.Mimetype
  51. metadata.ArchiveFiles = mjson.ArchiveFiles
  52. metadata.Sha256sum = mjson.Sha256sum
  53. metadata.Expiry = time.Unix(mjson.Expiry, 0)
  54. metadata.Size = mjson.Size
  55. return
  56. }
  57. func (b LocalfsBackend) Get(key string) (metadata backends.Metadata, f io.ReadCloser, err error) {
  58. metadata, err = b.Head(key)
  59. if err != nil {
  60. return
  61. }
  62. f, err = os.Open(path.Join(b.filesPath, key))
  63. if err != nil {
  64. return
  65. }
  66. return
  67. }
  68. func (b LocalfsBackend) writeMetadata(key string, metadata backends.Metadata) error {
  69. metaPath := path.Join(b.metaPath, key)
  70. mjson := MetadataJSON{
  71. DeleteKey: metadata.DeleteKey,
  72. Mimetype: metadata.Mimetype,
  73. ArchiveFiles: metadata.ArchiveFiles,
  74. Sha256sum: metadata.Sha256sum,
  75. Expiry: metadata.Expiry.Unix(),
  76. Size: metadata.Size,
  77. }
  78. dst, err := os.Create(metaPath)
  79. if err != nil {
  80. return err
  81. }
  82. defer dst.Close()
  83. encoder := json.NewEncoder(dst)
  84. err = encoder.Encode(mjson)
  85. if err != nil {
  86. os.Remove(metaPath)
  87. return err
  88. }
  89. return nil
  90. }
  91. func (b LocalfsBackend) Put(key string, r io.Reader, expiry time.Time, deleteKey string) (m backends.Metadata, err error) {
  92. filePath := path.Join(b.filesPath, key)
  93. dst, err := os.Create(filePath)
  94. if err != nil {
  95. return
  96. }
  97. defer dst.Close()
  98. bytes, err := io.Copy(dst, r)
  99. if bytes == 0 {
  100. os.Remove(filePath)
  101. return m, backends.FileEmptyError
  102. } else if err != nil {
  103. os.Remove(filePath)
  104. return m, err
  105. }
  106. m.Expiry = expiry
  107. m.DeleteKey = deleteKey
  108. m.Size = bytes
  109. m.Mimetype, _ = helpers.DetectMime(dst)
  110. m.Sha256sum, _ = helpers.Sha256sum(dst)
  111. m.ArchiveFiles, _ = helpers.ListArchiveFiles(m.Mimetype, m.Size, dst)
  112. err = b.writeMetadata(key, m)
  113. if err != nil {
  114. os.Remove(filePath)
  115. return
  116. }
  117. return
  118. }
  119. func (b LocalfsBackend) Size(key string) (int64, error) {
  120. fileInfo, err := os.Stat(path.Join(b.filesPath, key))
  121. if err != nil {
  122. return 0, err
  123. }
  124. return fileInfo.Size(), nil
  125. }
  126. func (b LocalfsBackend) List() ([]string, error) {
  127. var output []string
  128. files, err := ioutil.ReadDir(b.filesPath)
  129. if err != nil {
  130. return nil, err
  131. }
  132. for _, file := range files {
  133. output = append(output, file.Name())
  134. }
  135. return output, nil
  136. }
  137. func NewLocalfsBackend(metaPath string, filesPath string) LocalfsBackend {
  138. return LocalfsBackend{
  139. metaPath: metaPath,
  140. filesPath: filesPath,
  141. }
  142. }