resolves gh-1916

This commit is contained in:
Cy Allen Scott 2022-04-22 14:58:34 -04:00
parent 6c22cb3b32
commit 274dfd244d
3 changed files with 72 additions and 93 deletions

View File

@ -56,11 +56,6 @@ type FileOptions struct {
Content bool
}
type FileThumbnail struct {
Dir string
Path string
}
// NewFileInfo creates a File object from a path and a given user. This File
// object will be automatically filled depending on if it is a directory
// or a file. If it's a video file, it will also detect any subtitles.
@ -91,32 +86,16 @@ func NewFileInfo(opts FileOptions) (*FileInfo, error) {
return file, err
}
func NewThumbnailInfo(opts FileOptions) (*FileInfo, error) {
return NewFileInfo(FileOptions{
Fs: opts.Fs,
Path: NewFileThumbnail(opts).Path,
Modify: opts.Modify,
Expand: opts.Expand,
ReadHeader: opts.ReadHeader,
Checker: opts.Checker,
})
}
func ThumbnailPath(path string) string {
dir := os.Getenv("XDG_CACHE_HOME")
func NewFileThumbnail(opts FileOptions) FileThumbnail {
dir, name := filepath.Split(opts.Path)
hash := md5.Sum([]byte(name))
thumbnailName := hex.EncodeToString(hash[:]) + ".jpg"
thumbnailPath := path.Join(dir, ".filebrowser", thumbnailName)
dir, _ = filepath.Split(thumbnailPath)
return FileThumbnail{
Dir: dir,
Path: thumbnailPath,
if dir == "" {
dir = filepath.Join(os.Getenv("HOME"), ".cache")
}
hash := md5.Sum([]byte(path))
return filepath.Join(dir, "thumbnails", "xx-large", hex.EncodeToString(hash[:])+".png")
}
func stat(opts FileOptions) (*FileInfo, error) {
@ -237,6 +216,37 @@ func (i *FileInfo) RealPath() string {
return i.Path
}
func (i *FileInfo) Thumbnail() (*FileInfo, error) {
realPath := i.RealPath()
path := ThumbnailPath(realPath)
dir, _ := filepath.Split(path)
info, err := os.Stat(path)
if err != nil {
return nil, err
}
file := &FileInfo{
Fs: i.Fs,
Dir: dir,
Path: path,
Name: info.Name(),
ModTime: info.ModTime(),
Mode: info.Mode(),
IsDir: info.IsDir(),
Size: info.Size(),
Extension: filepath.Ext(info.Name()),
Token: i.Token,
Type: "image",
}
return file, err
}
//nolint:goconst
//TODO: use constants
func (i *FileInfo) detectType(modify, saveContent, readHeader bool) error {
@ -263,7 +273,6 @@ func (i *FileInfo) detectType(modify, saveContent, readHeader bool) error {
switch {
case strings.HasPrefix(mimetype, "video"):
i.Type = "video"
i.detectThumbnail()
i.detectSubtitles()
return nil
case strings.HasPrefix(mimetype, "audio"):
@ -343,14 +352,7 @@ func (i *FileInfo) detectSubtitles() {
}
func (i *FileInfo) detectThumbnail() {
dir, name := filepath.Split(i.RealPath())
hash := md5.Sum([]byte(name))
thumbnailName := hex.EncodeToString(hash[:])
path := path.Join(dir, ".filebrowser", thumbnailName+".jpg")
_, err := os.Stat(path)
_, err := i.Thumbnail()
if err == nil {
i.IsThumbsEnabled = true
@ -410,6 +412,10 @@ func (i *FileInfo) readListing(checker rules.Checker, readHeader bool) error {
if err != nil {
return err
}
if !file.IsThumbsEnabled {
file.detectThumbnail()
}
}
listing.Items = append(listing.Items, file)

View File

@ -7,6 +7,7 @@ import (
"fmt"
"io"
"net/http"
"os"
"github.com/gorilla/mux"
@ -59,16 +60,9 @@ func previewHandler(imgSvc ImgService, fileCache FileCache, enableThumbnails, re
setContentDisposition(w, r, file)
thumbnail, err := files.NewThumbnailInfo(files.FileOptions{
Fs: d.user.Fs,
Path: "/" + vars["path"],
Modify: d.user.Perm.Modify,
Expand: true,
ReadHeader: d.server.TypeDetectionByHeader,
Checker: d,
})
thumbnail, err := file.Thumbnail()
if err == nil && thumbnail != nil {
return rawFileHandler(w, r, thumbnail)
return handleThumbnail(w, r, thumbnail)
}
switch file.Type {
@ -80,6 +74,18 @@ func previewHandler(imgSvc ImgService, fileCache FileCache, enableThumbnails, re
})
}
func handleThumbnail(w http.ResponseWriter, r *http.Request, file *files.FileInfo) (int, error) {
fd, err := os.Open(file.Path)
if err != nil {
return http.StatusInternalServerError, err
}
defer fd.Close()
w.Header().Set("Cache-Control", "private")
http.ServeContent(w, r, file.Name, file.ModTime, fd)
return 0, nil
}
func handleImagePreview(
w http.ResponseWriter,
r *http.Request,

View File

@ -77,14 +77,7 @@ func resourceDeleteHandler(fileCache FileCache) handleFunc {
return errToStatus(err), err
}
thumbnail, err := files.NewThumbnailInfo(files.FileOptions{
Fs: d.user.Fs,
Path: r.URL.Path,
Modify: d.user.Perm.Modify,
Expand: false,
ReadHeader: d.server.TypeDetectionByHeader,
Checker: d,
})
thumbnail, err := file.Thumbnail()
if err == nil && thumbnail != nil {
d.user.Fs.RemoveAll(thumbnail.Path)
}
@ -311,30 +304,23 @@ func patchAction(ctx context.Context, action, src, dst string, d *data, fileCach
return errors.ErrPermissionDenied
}
srcThumbnail, err := files.NewThumbnailInfo(files.FileOptions{
file, err := files.NewFileInfo(files.FileOptions{
Fs: d.user.Fs,
Path: src,
Modify: d.user.Perm.Modify,
Expand: false,
ReadHeader: d.server.TypeDetectionByHeader,
ReadHeader: false,
Checker: d,
})
if err != nil {
return err
}
srcThumbnail, err := file.Thumbnail()
if err == nil && srcThumbnail != nil {
destThumbnail := files.NewFileThumbnail(files.FileOptions{
Fs: d.user.Fs,
Path: dst,
Modify: d.user.Perm.Modify,
Expand: false,
ReadHeader: d.server.TypeDetectionByHeader,
Checker: d,
})
destThumbnail := files.ThumbnailPath(dst)
_, err := os.Stat(destThumbnail.Dir)
if err != nil {
fileutils.CreateDir(d.user.Fs, srcThumbnail.Dir, destThumbnail.Dir)
}
fileutils.Copy(d.user.Fs, srcThumbnail.Path, destThumbnail.Path)
fileutils.Copy(d.user.Fs, srcThumbnail.Path, destThumbnail)
}
return fileutils.Copy(d.user.Fs, src, dst)
@ -363,30 +349,11 @@ func patchAction(ctx context.Context, action, src, dst string, d *data, fileCach
return err
}
srcThumbnail, err := files.NewThumbnailInfo(files.FileOptions{
Fs: d.user.Fs,
Path: src,
Modify: d.user.Perm.Modify,
Expand: false,
ReadHeader: d.server.TypeDetectionByHeader,
Checker: d,
})
srcThumbnail, err := file.Thumbnail()
if err == nil && srcThumbnail != nil {
destThumbnail := files.NewFileThumbnail(files.FileOptions{
Fs: d.user.Fs,
Path: dst,
Modify: d.user.Perm.Modify,
Expand: false,
ReadHeader: d.server.TypeDetectionByHeader,
Checker: d,
})
destThumbnail := files.ThumbnailPath(dst)
_, err := os.Stat(destThumbnail.Dir)
if err != nil {
fileutils.CreateDir(d.user.Fs, srcThumbnail.Dir, destThumbnail.Dir)
}
fileutils.MoveFile(d.user.Fs, srcThumbnail.Path, destThumbnail.Path)
fileutils.MoveFile(d.user.Fs, srcThumbnail.Path, destThumbnail)
}
return fileutils.MoveFile(d.user.Fs, src, dst)