gpaste/files/filestore_fs.go

133 lines
2.1 KiB
Go
Raw Normal View History

2022-01-20 02:40:32 +00:00
package files
2022-01-19 00:03:24 +00:00
import (
"encoding/json"
"fmt"
"io"
"os"
"path/filepath"
)
type FSFileStore struct {
dir string
metadata map[string]*File
}
func NewFSFileStore(dir string) (*FSFileStore, error) {
s := &FSFileStore{
dir: dir,
metadata: make(map[string]*File),
}
err := s.readMetadata()
return s, err
}
2022-01-27 10:36:16 +00:00
2022-01-19 00:03:24 +00:00
func (s *FSFileStore) Store(f *File) error {
defer f.Body.Close()
metadata := &File{
ID: f.ID,
OriginalFilename: f.OriginalFilename,
MaxViews: f.MaxViews,
ExpiresOn: f.ExpiresOn,
}
path := filepath.Join(s.dir, f.ID)
2022-01-24 19:25:52 +00:00
2022-01-19 00:03:24 +00:00
dst, err := os.Create(path)
if err != nil {
return err
}
defer dst.Close()
2022-01-24 14:52:15 +00:00
n, err := io.Copy(dst, f.Body)
if err != nil {
2022-01-19 00:03:24 +00:00
return err
}
2022-01-24 19:25:52 +00:00
2022-01-19 00:03:24 +00:00
s.metadata[f.ID] = metadata
2022-01-24 14:52:15 +00:00
s.metadata[f.ID].FileSize = n
2022-01-24 19:25:52 +00:00
2022-01-19 00:03:24 +00:00
if err := s.writeMetadata(); err != nil {
delete(s.metadata, f.ID)
return err
}
2022-01-24 19:25:52 +00:00
2022-01-19 00:03:24 +00:00
return nil
}
func (s *FSFileStore) Get(id string) (*File, error) {
metadata, ok := s.metadata[id]
if !ok {
return nil, fmt.Errorf("no such item")
}
path := filepath.Join(s.dir, id)
2022-01-24 19:25:52 +00:00
2022-01-19 00:03:24 +00:00
f, err := os.Open(path)
if err != nil {
return nil, err
}
2022-01-24 19:25:52 +00:00
2022-01-19 00:03:24 +00:00
metadata.Body = f
2022-01-24 19:25:52 +00:00
2022-01-19 00:03:24 +00:00
return metadata, nil
}
func (s *FSFileStore) Delete(id string) error {
path := filepath.Join(s.dir, id)
if err := os.Remove(path); err != nil {
return err
}
2022-01-24 19:25:52 +00:00
2022-01-19 00:03:24 +00:00
delete(s.metadata, id)
2022-01-24 19:25:52 +00:00
2022-01-19 00:03:24 +00:00
return nil
}
func (s *FSFileStore) List() ([]string, error) {
2022-01-24 19:25:52 +00:00
results := make([]string, 0, len(s.metadata))
2022-01-19 00:03:24 +00:00
for k := range s.metadata {
results = append(results, k)
}
2022-01-24 19:25:52 +00:00
2022-01-19 00:03:24 +00:00
return results, nil
}
func (s *FSFileStore) writeMetadata() error {
path := filepath.Join(s.dir, "metadata.json")
2022-01-24 19:25:52 +00:00
2022-01-19 00:03:24 +00:00
f, err := os.Create(path)
if err != nil {
return err
}
defer f.Close()
encoder := json.NewEncoder(f)
if err := encoder.Encode(s.metadata); err != nil {
return err
}
2022-01-24 19:25:52 +00:00
2022-01-19 00:03:24 +00:00
return nil
}
func (s *FSFileStore) readMetadata() error {
path := filepath.Join(s.dir, "metadata.json")
2022-01-24 19:25:52 +00:00
2022-01-19 00:03:24 +00:00
f, err := os.Open(path)
if err != nil {
// TODO: Handle errors better
return nil
}
defer f.Close()
decoder := json.NewDecoder(f)
if err := decoder.Decode(&s.metadata); err != nil {
return err
}
2022-01-24 19:25:52 +00:00
2022-01-19 00:03:24 +00:00
return nil
}