clean up and add comments

This commit is contained in:
David Christofas
2020-03-09 17:03:33 +01:00
parent 975387822b
commit 4647168160
6 changed files with 56 additions and 41 deletions
+3 -3
View File
@@ -38,11 +38,11 @@ type Config struct {
Debug Debug
HTTP HTTP
Tracing Tracing
FilesystemStorage FilesystemStorage
FileSystemStorage FileSystemStorage
}
// FilesystemStorage defines the available filesystem storage configuration.
type FilesystemStorage struct {
// FileSystemStorage defines the available filesystem storage configuration.
type FileSystemStorage struct {
RootDirectory string
}
+2 -2
View File
@@ -28,7 +28,7 @@ func NewService(opts ...Option) Service {
config: options.Config,
mux: m,
manager: thumbnails.SimpleManager{
Storage: storage.NewInMemoryStorage(),
Storage: storage.NewFileSystemStorage(options.Config.FileSystemStorage),
},
source: imgsource.WebDav{
Basepath: "http://localhost:9140/remote.php/webdav/",
@@ -71,7 +71,7 @@ func (g Thumbnails) Thumbnails(w http.ResponseWriter, r *http.Request) {
w.Write([]byte("can't encode that"))
return
}
ctx := thumbnails.ThumbnailContext{
ctx := thumbnails.Context{
Width: width,
Height: height,
ImagePath: filePath,
+11
View File
@@ -8,31 +8,42 @@ import (
"strings"
)
// Encoder encodes the thumbnail to a specific format.
type Encoder interface {
// Encode encodes the image to a format.
Encode(io.Writer, image.Image) error
// Types returns the formats suffixes.
Types() []string
}
// PngEncoder encodes to png
type PngEncoder struct{}
// Encode encodes to png format
func (e PngEncoder) Encode(w io.Writer, i image.Image) error {
return png.Encode(w, i)
}
// Types returns the png suffix
func (e PngEncoder) Types() []string {
return []string{"png"}
}
// JpegEncoder encodes to jpg.
type JpegEncoder struct{}
// Encode encodes to jpg
func (e JpegEncoder) Encode(w io.Writer, i image.Image) error {
return jpeg.Encode(w, i, nil)
}
// Types returns the jpg suffixes.
func (e JpegEncoder) Types() []string {
return []string{"jpeg", "jpg"}
}
// EncoderForType returns the encoder for a given file type
// or nil if the type is not supported.
func EncoderForType(fileType string) Encoder {
switch strings.ToLower(fileType) {
case "png":
+26 -18
View File
@@ -11,12 +11,21 @@ import (
"github.com/owncloud/ocis-thumbnails/pkg/config"
)
type FileSystem struct {
cfg config.FilesystemStorage
// NewFileSystemStorage creates a new instanz of FileSystem
func NewFileSystemStorage(cfg config.FileSystemStorage) FileSystem {
return FileSystem{
dir: cfg.RootDirectory,
}
}
// FileSystem represents a storage for the thumbnails using the local file system.
type FileSystem struct {
dir string
}
// Get loads the image from the file system.
func (s FileSystem) Get(key string) []byte {
content, err := ioutil.ReadFile(filepath.Join(s.cfg.RootDirectory, key))
content, err := ioutil.ReadFile(filepath.Join(s.dir, key))
if err != nil {
return nil
}
@@ -24,11 +33,12 @@ func (s FileSystem) Get(key string) []byte {
return content
}
// Set writes the image to the file system.
func (s FileSystem) Set(key string, img []byte) error {
path := filepath.Join(s.cfg.RootDirectory, key)
folder := filepath.Dir(path)
if err := createFolderIfNotExists(folder); err != nil {
return fmt.Errorf("error while creating folder %s", folder)
path := filepath.Join(s.dir, key)
dir := filepath.Dir(path)
if err := os.MkdirAll(dir, 0700); err != nil {
return fmt.Errorf("error while creating directory %s", dir)
}
f, err := os.Create(path)
@@ -44,7 +54,15 @@ func (s FileSystem) Set(key string, img []byte) error {
return nil
}
func (s FileSystem) BuildKey(ctx StorageContext) string {
// BuildKey generate the unique key for a thumbnail.
// The key is structure as follows:
//
// <first two letters of etag>/<next two letters of etag>/<rest of etag>/<width>x<height>.<filetype>
//
// 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(ctx Context) string {
etag := ctx.ETag
filetype := ctx.Types[0]
filename := strconv.Itoa(ctx.Width) + "x" + strconv.Itoa(ctx.Height) + "." + filetype
@@ -60,13 +78,3 @@ func (s FileSystem) BuildKey(ctx StorageContext) string {
return key.String()
}
func createFolderIfNotExists(folder string) error {
if _, err := os.Stat(folder); os.IsNotExist(err) {
err := os.MkdirAll(folder, 0700)
if err != nil {
return err
}
}
return nil
}
+3 -2
View File
@@ -1,6 +1,7 @@
package storage
type StorageContext struct {
// Context combines different attributes needed for storage operations.
type Context struct {
ETag string
Types []string
Width int
@@ -11,5 +12,5 @@ type StorageContext struct {
type Storage interface {
Get(string) []byte
Set(string, []byte) error
BuildKey(StorageContext) string
BuildKey(Context) string
}
+11 -16
View File
@@ -3,14 +3,13 @@ package thumbnails
import (
"bytes"
"image"
"time"
"github.com/nfnt/resize"
"github.com/owncloud/ocis-thumbnails/pkg/thumbnails/storage"
)
// ThumbnailContext bundles information needed to generate a thumbnail for afile
type ThumbnailContext struct {
// Context bundles information needed to generate a thumbnail for afile
type Context struct {
Width int
Height int
ImagePath string
@@ -21,8 +20,10 @@ type ThumbnailContext struct {
// Manager is responsible for generating thumbnails
type Manager interface {
// Get will return a thumbnail for a file
Get(ThumbnailContext, image.Image) ([]byte, error)
GetStored(ThumbnailContext) []byte
Get(Context, image.Image) ([]byte, error)
// GetStored loads the thumbnail from the storage.
// It will return nil if no image is stored for the given context.
GetStored(Context) []byte
}
// SimpleManager is a simple implementation of Manager
@@ -31,7 +32,7 @@ type SimpleManager struct {
}
// Get implements the Get Method of Manager
func (s SimpleManager) Get(ctx ThumbnailContext, img image.Image) ([]byte, error) {
func (s SimpleManager) Get(ctx Context, img image.Image) ([]byte, error) {
thumbnail := s.generate(ctx, img)
key := s.Storage.BuildKey(mapToStorageContext(ctx))
@@ -48,25 +49,19 @@ func (s SimpleManager) Get(ctx ThumbnailContext, img image.Image) ([]byte, error
// GetStored tries to get the stored thumbnail and return it.
// If there is no cached thumbnail it will return nil
func (s SimpleManager) GetStored(ctx ThumbnailContext) []byte {
func (s SimpleManager) GetStored(ctx Context) []byte {
key := s.Storage.BuildKey(mapToStorageContext(ctx))
stored := s.Storage.Get(key)
if stored == nil {
return nil
}
return stored
}
func (s SimpleManager) generate(ctx ThumbnailContext, img image.Image) image.Image {
// TODO: remove, just for demo purposes
time.Sleep(time.Second * 2)
func (s SimpleManager) generate(ctx Context, img image.Image) image.Image {
thumbnail := resize.Thumbnail(uint(ctx.Width), uint(ctx.Height), img, resize.Lanczos2)
return thumbnail
}
func mapToStorageContext(ctx ThumbnailContext) storage.StorageContext {
sCtx := storage.StorageContext{
func mapToStorageContext(ctx Context) storage.Context {
sCtx := storage.Context{
ETag: ctx.ETag,
Width: ctx.Width,
Height: ctx.Height,