package storage import ( "github.com/owncloud/ocis/ocis-pkg/log" "github.com/owncloud/ocis/thumbnails/pkg/config" "github.com/pkg/errors" "os" "path/filepath" "strconv" ) const ( filesDir = "files" ) // NewFileSystemStorage creates a new instance of FileSystem func NewFileSystemStorage(cfg config.FileSystemStorage, logger log.Logger) *FileSystem { return &FileSystem{ root: cfg.RootDirectory, logger: logger, } } // FileSystem represents a storage for the thumbnails using the local file system. type FileSystem struct { root string logger log.Logger } // Get loads the image from the file system. func (s *FileSystem) Get(key string) ([]byte, bool) { img := filepath.Join(s.root, filesDir, key) content, err := os.ReadFile(img) if err != nil { if !os.IsNotExist(err) { s.logger.Debug().Str("err", err.Error()).Str("key", key).Msg("could not load thumbnail from store") } return nil, false } return content, true } // Set writes the image to the file system. func (s *FileSystem) Put(key string, img []byte) error { imgPath := filepath.Join(s.root, filesDir, key) dir := filepath.Dir(imgPath) if err := os.MkdirAll(dir, 0700); err != nil { return errors.Wrapf(err, "error while creating directory %s", dir) } if _, err := os.Stat(imgPath); os.IsNotExist(err) { f, err := os.Create(imgPath) if err != nil { return errors.Wrapf(err, "could not create file \"%s\"", key) } defer f.Close() if _, err = f.Write(img); err != nil { return errors.Wrapf(err, "could not write to file \"%s\"", key) } } return nil } // BuildKey generate the unique key for a thumbnail. // The key is structure as follows: // // ///x. // // e.g. 97/9f/4c8db98f7b82e768ef478d3c8612/500x300.png // // The key also represents the path to the thumbnail in the filesystem under the configured root directory. func (s *FileSystem) BuildKey(r Request) string { checksum := r.Checksum filetype := r.Types[0] filename := strconv.Itoa(r.Resolution.Dx()) + "x" + strconv.Itoa(r.Resolution.Dy()) + "." + filetype return filepath.Join(checksum[:2], checksum[2:4], checksum[4:], filename) }