mirror of https://github.com/Xhofe/alist
feat(local): support thumbnail cache (close #4216)
parent
4b0c01158d
commit
daad61443c
|
@ -1,7 +1,6 @@
|
||||||
package local
|
package local
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"bytes"
|
|
||||||
"context"
|
"context"
|
||||||
"errors"
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
|
@ -20,7 +19,6 @@ import (
|
||||||
"github.com/alist-org/alist/v3/internal/sign"
|
"github.com/alist-org/alist/v3/internal/sign"
|
||||||
"github.com/alist-org/alist/v3/pkg/utils"
|
"github.com/alist-org/alist/v3/pkg/utils"
|
||||||
"github.com/alist-org/alist/v3/server/common"
|
"github.com/alist-org/alist/v3/server/common"
|
||||||
"github.com/disintegration/imaging"
|
|
||||||
_ "golang.org/x/image/webp"
|
_ "golang.org/x/image/webp"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -54,6 +52,12 @@ func (d *Local) Init(ctx context.Context) error {
|
||||||
}
|
}
|
||||||
d.Addition.RootFolderPath = abs
|
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
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -135,36 +139,18 @@ func (d *Local) Link(ctx context.Context, file model.Obj, args model.LinkArgs) (
|
||||||
fullPath := file.GetPath()
|
fullPath := file.GetPath()
|
||||||
var link model.Link
|
var link model.Link
|
||||||
if args.Type == "thumb" && utils.Ext(file.GetName()) != "svg" {
|
if args.Type == "thumb" && utils.Ext(file.GetName()) != "svg" {
|
||||||
var srcBuf *bytes.Buffer
|
buf, thumbPath, err := d.getThumb(file)
|
||||||
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)
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
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{
|
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 {
|
} else {
|
||||||
link.FilePath = &fullPath
|
link.FilePath = &fullPath
|
||||||
|
|
|
@ -7,9 +7,10 @@ import (
|
||||||
|
|
||||||
type Addition struct {
|
type Addition struct {
|
||||||
driver.RootPath
|
driver.RootPath
|
||||||
Thumbnail bool `json:"thumbnail" required:"true" help:"enable thumbnail"`
|
Thumbnail bool `json:"thumbnail" required:"true" help:"enable thumbnail"`
|
||||||
ShowHidden bool `json:"show_hidden" default:"true" required:"false" help:"show hidden directories and files"`
|
ThumbCacheFolder string `json:"thumb_cache_folder"`
|
||||||
MkdirPerm string `json:"mkdir_perm" default:"777"`
|
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{
|
var config = driver.Config{
|
||||||
|
|
|
@ -7,7 +7,12 @@ import (
|
||||||
"os"
|
"os"
|
||||||
"path/filepath"
|
"path/filepath"
|
||||||
"sort"
|
"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"
|
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() })
|
sort.Slice(list, func(i, j int) bool { return list[i].Name() < list[j].Name() })
|
||||||
return list, nil
|
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