mirror of https://github.com/Xhofe/alist
feat(local): support thumbnail cache (close #4216)
parent
4b0c01158d
commit
daad61443c
|
@ -1,7 +1,6 @@
|
|||
package local
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"context"
|
||||
"errors"
|
||||
"fmt"
|
||||
|
@ -20,7 +19,6 @@ import (
|
|||
"github.com/alist-org/alist/v3/internal/sign"
|
||||
"github.com/alist-org/alist/v3/pkg/utils"
|
||||
"github.com/alist-org/alist/v3/server/common"
|
||||
"github.com/disintegration/imaging"
|
||||
_ "golang.org/x/image/webp"
|
||||
)
|
||||
|
||||
|
@ -54,6 +52,12 @@ func (d *Local) Init(ctx context.Context) error {
|
|||
}
|
||||
d.Addition.RootFolderPath = abs
|
||||
}
|
||||
if d.ThumbCacheFolder != "" && !utils.Exists(d.ThumbCacheFolder) {
|
||||
err := os.MkdirAll(d.ThumbCacheFolder, os.FileMode(d.mkdirPerm))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
|
@ -135,36 +139,18 @@ func (d *Local) Link(ctx context.Context, file model.Obj, args model.LinkArgs) (
|
|||
fullPath := file.GetPath()
|
||||
var link model.Link
|
||||
if args.Type == "thumb" && utils.Ext(file.GetName()) != "svg" {
|
||||
var srcBuf *bytes.Buffer
|
||||
if utils.GetFileType(file.GetName()) == conf.VIDEO {
|
||||
videoBuf, err := GetSnapshot(fullPath, 10)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
srcBuf = videoBuf
|
||||
} else {
|
||||
imgData, err := os.ReadFile(fullPath)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
imgBuf := bytes.NewBuffer(imgData)
|
||||
srcBuf = imgBuf
|
||||
}
|
||||
|
||||
image, err := imaging.Decode(srcBuf)
|
||||
buf, thumbPath, err := d.getThumb(file)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
thumbImg := imaging.Resize(image, 144, 0, imaging.Lanczos)
|
||||
var buf bytes.Buffer
|
||||
err = imaging.Encode(&buf, thumbImg, imaging.PNG)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
size := buf.Len()
|
||||
link.Data = io.NopCloser(&buf)
|
||||
link.Header = http.Header{
|
||||
"Content-Length": []string{strconv.Itoa(size)},
|
||||
"Content-Type": []string{"image/png"},
|
||||
}
|
||||
if thumbPath != nil {
|
||||
link.FilePath = thumbPath
|
||||
} else {
|
||||
link.Data = io.NopCloser(buf)
|
||||
link.Header.Set("Content-Length", strconv.Itoa(buf.Len()))
|
||||
}
|
||||
} else {
|
||||
link.FilePath = &fullPath
|
||||
|
|
|
@ -7,9 +7,10 @@ import (
|
|||
|
||||
type Addition struct {
|
||||
driver.RootPath
|
||||
Thumbnail bool `json:"thumbnail" required:"true" help:"enable thumbnail"`
|
||||
ShowHidden bool `json:"show_hidden" default:"true" required:"false" help:"show hidden directories and files"`
|
||||
MkdirPerm string `json:"mkdir_perm" default:"777"`
|
||||
Thumbnail bool `json:"thumbnail" required:"true" help:"enable thumbnail"`
|
||||
ThumbCacheFolder string `json:"thumb_cache_folder"`
|
||||
ShowHidden bool `json:"show_hidden" default:"true" required:"false" help:"show hidden directories and files"`
|
||||
MkdirPerm string `json:"mkdir_perm" default:"777"`
|
||||
}
|
||||
|
||||
var config = driver.Config{
|
||||
|
|
|
@ -7,7 +7,12 @@ import (
|
|||
"os"
|
||||
"path/filepath"
|
||||
"sort"
|
||||
"strings"
|
||||
|
||||
"github.com/alist-org/alist/v3/internal/conf"
|
||||
"github.com/alist-org/alist/v3/internal/model"
|
||||
"github.com/alist-org/alist/v3/pkg/utils"
|
||||
"github.com/disintegration/imaging"
|
||||
ffmpeg "github.com/u2takey/ffmpeg-go"
|
||||
)
|
||||
|
||||
|
@ -55,3 +60,52 @@ func readDir(dirname string) ([]fs.FileInfo, error) {
|
|||
sort.Slice(list, func(i, j int) bool { return list[i].Name() < list[j].Name() })
|
||||
return list, nil
|
||||
}
|
||||
|
||||
func (d *Local) getThumb(file model.Obj) (*bytes.Buffer, *string, error) {
|
||||
fullPath := file.GetPath()
|
||||
thumbPrefix := "alist_thumb_"
|
||||
thumbName := thumbPrefix + utils.GetMD5Encode(fullPath) + ".png"
|
||||
if d.ThumbCacheFolder != "" {
|
||||
// skip if the file is a thumbnail
|
||||
if strings.HasPrefix(file.GetName(), thumbPrefix) {
|
||||
return nil, &fullPath, nil
|
||||
}
|
||||
thumbPath := filepath.Join(d.ThumbCacheFolder, thumbName)
|
||||
if utils.Exists(thumbPath) {
|
||||
return nil, &thumbPath, nil
|
||||
}
|
||||
}
|
||||
var srcBuf *bytes.Buffer
|
||||
if utils.GetFileType(file.GetName()) == conf.VIDEO {
|
||||
videoBuf, err := GetSnapshot(fullPath, 10)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
srcBuf = videoBuf
|
||||
} else {
|
||||
imgData, err := os.ReadFile(fullPath)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
imgBuf := bytes.NewBuffer(imgData)
|
||||
srcBuf = imgBuf
|
||||
}
|
||||
|
||||
image, err := imaging.Decode(srcBuf)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
thumbImg := imaging.Resize(image, 144, 0, imaging.Lanczos)
|
||||
var buf bytes.Buffer
|
||||
err = imaging.Encode(&buf, thumbImg, imaging.PNG)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
if d.ThumbCacheFolder != "" {
|
||||
err = os.WriteFile(filepath.Join(d.ThumbCacheFolder, thumbName), buf.Bytes(), 0666)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
}
|
||||
return &buf, nil, nil
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue