Skip to content
Snippets Groups Projects
cache.go 1.64 KiB
Newer Older
package thumbnailer

import (
	"io"
	"os"
	"path/filepath"
)

// ThumbnailCache allows access to thumbnails stored in a directory. Each
// thumbnail has a key, which uniquely identifies it. The key should be a unique
// ID from a database or the original file's hash.
type ThumbnailCache struct {
	Directory      string
	ThumbnailerURL string
}

// NewThumbnailCache creates a new *ThumbnailCache.
func NewThumbnailCache(directory, thumbnailerURL string) *ThumbnailCache {
	return &ThumbnailCache{
		Directory:      directory,
		ThumbnailerURL: thumbnailerURL,
	}
}

// GetThumbnail returns a thumbnail that is cached. If no cached copy exists, a
// exists, a NoCachedCopy error is returned.
func (c *ThumbnailCache) GetThumbnail(key string) (io.ReadCloser, error) {
	if key == "" {
		return nil, NoKeySpecified
	}
	path := filepath.Join(c.Directory, key)
	data, err := os.Open(path)
	if os.IsNotExist(err) {
		return nil, NoCachedCopy
	}
	return data, err
}

// SetThumbnail stores a thumbnail with the specified key.
func (c *ThumbnailCache) SetThumbnail(key string, data io.Reader) error {
	if key == "" {
		return NoKeySpecified
	}
	path := filepath.Join(c.Directory, key)
	file, err := os.Create(path)
	if err != nil {
		return err
	}
	defer file.Close()
	_, err = io.Copy(file, data)
	if err != nil {
		_ = os.Remove(path)
	}
	return err
}

// Transform generates a thumbnail and caches it.
func (c *ThumbnailCache) Transform(key string, contentType string, data io.Reader) error {
	if key == "" {
		return NoKeySpecified
	}
	outputImage, err := Transform(c.ThumbnailerURL, contentType, data)
	if err != nil {
		return err
	}
	return c.SetThumbnail(key, outputImage)
}