resolves gh-1916
This commit is contained in:
parent
6c22cb3b32
commit
274dfd244d
@ -56,11 +56,6 @@ type FileOptions struct {
|
|||||||
Content bool
|
Content bool
|
||||||
}
|
}
|
||||||
|
|
||||||
type FileThumbnail struct {
|
|
||||||
Dir string
|
|
||||||
Path string
|
|
||||||
}
|
|
||||||
|
|
||||||
// NewFileInfo creates a File object from a path and a given user. This File
|
// 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
|
// 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.
|
// 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
|
return file, err
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewThumbnailInfo(opts FileOptions) (*FileInfo, error) {
|
func ThumbnailPath(path string) string {
|
||||||
return NewFileInfo(FileOptions{
|
dir := os.Getenv("XDG_CACHE_HOME")
|
||||||
Fs: opts.Fs,
|
|
||||||
Path: NewFileThumbnail(opts).Path,
|
|
||||||
Modify: opts.Modify,
|
|
||||||
Expand: opts.Expand,
|
|
||||||
ReadHeader: opts.ReadHeader,
|
|
||||||
Checker: opts.Checker,
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
func NewFileThumbnail(opts FileOptions) FileThumbnail {
|
if dir == "" {
|
||||||
dir, name := filepath.Split(opts.Path)
|
dir = filepath.Join(os.Getenv("HOME"), ".cache")
|
||||||
|
|
||||||
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,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
hash := md5.Sum([]byte(path))
|
||||||
|
|
||||||
|
return filepath.Join(dir, "thumbnails", "xx-large", hex.EncodeToString(hash[:])+".png")
|
||||||
}
|
}
|
||||||
|
|
||||||
func stat(opts FileOptions) (*FileInfo, error) {
|
func stat(opts FileOptions) (*FileInfo, error) {
|
||||||
@ -237,6 +216,37 @@ func (i *FileInfo) RealPath() string {
|
|||||||
return i.Path
|
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
|
//nolint:goconst
|
||||||
//TODO: use constants
|
//TODO: use constants
|
||||||
func (i *FileInfo) detectType(modify, saveContent, readHeader bool) error {
|
func (i *FileInfo) detectType(modify, saveContent, readHeader bool) error {
|
||||||
@ -263,7 +273,6 @@ func (i *FileInfo) detectType(modify, saveContent, readHeader bool) error {
|
|||||||
switch {
|
switch {
|
||||||
case strings.HasPrefix(mimetype, "video"):
|
case strings.HasPrefix(mimetype, "video"):
|
||||||
i.Type = "video"
|
i.Type = "video"
|
||||||
i.detectThumbnail()
|
|
||||||
i.detectSubtitles()
|
i.detectSubtitles()
|
||||||
return nil
|
return nil
|
||||||
case strings.HasPrefix(mimetype, "audio"):
|
case strings.HasPrefix(mimetype, "audio"):
|
||||||
@ -343,14 +352,7 @@ func (i *FileInfo) detectSubtitles() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (i *FileInfo) detectThumbnail() {
|
func (i *FileInfo) detectThumbnail() {
|
||||||
dir, name := filepath.Split(i.RealPath())
|
_, err := i.Thumbnail()
|
||||||
|
|
||||||
hash := md5.Sum([]byte(name))
|
|
||||||
thumbnailName := hex.EncodeToString(hash[:])
|
|
||||||
|
|
||||||
path := path.Join(dir, ".filebrowser", thumbnailName+".jpg")
|
|
||||||
|
|
||||||
_, err := os.Stat(path)
|
|
||||||
|
|
||||||
if err == nil {
|
if err == nil {
|
||||||
i.IsThumbsEnabled = true
|
i.IsThumbsEnabled = true
|
||||||
@ -410,6 +412,10 @@ func (i *FileInfo) readListing(checker rules.Checker, readHeader bool) error {
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if !file.IsThumbsEnabled {
|
||||||
|
file.detectThumbnail()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
listing.Items = append(listing.Items, file)
|
listing.Items = append(listing.Items, file)
|
||||||
|
|||||||
@ -7,6 +7,7 @@ import (
|
|||||||
"fmt"
|
"fmt"
|
||||||
"io"
|
"io"
|
||||||
"net/http"
|
"net/http"
|
||||||
|
"os"
|
||||||
|
|
||||||
"github.com/gorilla/mux"
|
"github.com/gorilla/mux"
|
||||||
|
|
||||||
@ -59,16 +60,9 @@ func previewHandler(imgSvc ImgService, fileCache FileCache, enableThumbnails, re
|
|||||||
|
|
||||||
setContentDisposition(w, r, file)
|
setContentDisposition(w, r, file)
|
||||||
|
|
||||||
thumbnail, err := files.NewThumbnailInfo(files.FileOptions{
|
thumbnail, err := file.Thumbnail()
|
||||||
Fs: d.user.Fs,
|
|
||||||
Path: "/" + vars["path"],
|
|
||||||
Modify: d.user.Perm.Modify,
|
|
||||||
Expand: true,
|
|
||||||
ReadHeader: d.server.TypeDetectionByHeader,
|
|
||||||
Checker: d,
|
|
||||||
})
|
|
||||||
if err == nil && thumbnail != nil {
|
if err == nil && thumbnail != nil {
|
||||||
return rawFileHandler(w, r, thumbnail)
|
return handleThumbnail(w, r, thumbnail)
|
||||||
}
|
}
|
||||||
|
|
||||||
switch file.Type {
|
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(
|
func handleImagePreview(
|
||||||
w http.ResponseWriter,
|
w http.ResponseWriter,
|
||||||
r *http.Request,
|
r *http.Request,
|
||||||
|
|||||||
@ -77,14 +77,7 @@ func resourceDeleteHandler(fileCache FileCache) handleFunc {
|
|||||||
return errToStatus(err), err
|
return errToStatus(err), err
|
||||||
}
|
}
|
||||||
|
|
||||||
thumbnail, err := files.NewThumbnailInfo(files.FileOptions{
|
thumbnail, err := file.Thumbnail()
|
||||||
Fs: d.user.Fs,
|
|
||||||
Path: r.URL.Path,
|
|
||||||
Modify: d.user.Perm.Modify,
|
|
||||||
Expand: false,
|
|
||||||
ReadHeader: d.server.TypeDetectionByHeader,
|
|
||||||
Checker: d,
|
|
||||||
})
|
|
||||||
if err == nil && thumbnail != nil {
|
if err == nil && thumbnail != nil {
|
||||||
d.user.Fs.RemoveAll(thumbnail.Path)
|
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
|
return errors.ErrPermissionDenied
|
||||||
}
|
}
|
||||||
|
|
||||||
srcThumbnail, err := files.NewThumbnailInfo(files.FileOptions{
|
file, err := files.NewFileInfo(files.FileOptions{
|
||||||
Fs: d.user.Fs,
|
Fs: d.user.Fs,
|
||||||
Path: src,
|
Path: src,
|
||||||
Modify: d.user.Perm.Modify,
|
Modify: d.user.Perm.Modify,
|
||||||
Expand: false,
|
Expand: false,
|
||||||
ReadHeader: d.server.TypeDetectionByHeader,
|
ReadHeader: false,
|
||||||
Checker: d,
|
Checker: d,
|
||||||
})
|
})
|
||||||
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,
|
|
||||||
})
|
|
||||||
|
|
||||||
_, err := os.Stat(destThumbnail.Dir)
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
fileutils.CreateDir(d.user.Fs, srcThumbnail.Dir, destThumbnail.Dir)
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
fileutils.Copy(d.user.Fs, srcThumbnail.Path, destThumbnail.Path)
|
srcThumbnail, err := file.Thumbnail()
|
||||||
|
if err == nil && srcThumbnail != nil {
|
||||||
|
destThumbnail := files.ThumbnailPath(dst)
|
||||||
|
|
||||||
|
fileutils.Copy(d.user.Fs, srcThumbnail.Path, destThumbnail)
|
||||||
}
|
}
|
||||||
|
|
||||||
return fileutils.Copy(d.user.Fs, src, dst)
|
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
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
srcThumbnail, err := files.NewThumbnailInfo(files.FileOptions{
|
srcThumbnail, err := file.Thumbnail()
|
||||||
Fs: d.user.Fs,
|
|
||||||
Path: src,
|
|
||||||
Modify: d.user.Perm.Modify,
|
|
||||||
Expand: false,
|
|
||||||
ReadHeader: d.server.TypeDetectionByHeader,
|
|
||||||
Checker: d,
|
|
||||||
})
|
|
||||||
if err == nil && srcThumbnail != nil {
|
if err == nil && srcThumbnail != nil {
|
||||||
destThumbnail := files.NewFileThumbnail(files.FileOptions{
|
destThumbnail := files.ThumbnailPath(dst)
|
||||||
Fs: d.user.Fs,
|
|
||||||
Path: dst,
|
|
||||||
Modify: d.user.Perm.Modify,
|
|
||||||
Expand: false,
|
|
||||||
ReadHeader: d.server.TypeDetectionByHeader,
|
|
||||||
Checker: d,
|
|
||||||
})
|
|
||||||
|
|
||||||
_, err := os.Stat(destThumbnail.Dir)
|
fileutils.MoveFile(d.user.Fs, srcThumbnail.Path, destThumbnail)
|
||||||
if err != nil {
|
|
||||||
fileutils.CreateDir(d.user.Fs, srcThumbnail.Dir, destThumbnail.Dir)
|
|
||||||
}
|
|
||||||
|
|
||||||
fileutils.MoveFile(d.user.Fs, srcThumbnail.Path, destThumbnail.Path)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return fileutils.MoveFile(d.user.Fs, src, dst)
|
return fileutils.MoveFile(d.user.Fs, src, dst)
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user