[add] SUI Template MediaSearch

This commit is contained in:
Max 2023-11-18 17:41:17 +08:00
parent d1fb3a137d
commit 1baaede53f
7 changed files with 113 additions and 17 deletions

1
go.mod
View file

@ -105,6 +105,7 @@ require (
github.com/youmark/pkcs8 v0.0.0-20201027041543-1326539a0a0a // indirect
go.mongodb.org/mongo-driver v1.13.0 // indirect
golang.org/x/arch v0.6.0 // indirect
golang.org/x/image v0.14.0 // indirect
golang.org/x/mod v0.14.0 // indirect
golang.org/x/net v0.18.0 // indirect
golang.org/x/oauth2 v0.14.0 // indirect

3
go.sum
View file

@ -261,8 +261,9 @@ golang.org/x/crypto v0.0.0-20220622213112-05595931fe9d/go.mod h1:IxCIyHEi3zRg3s0
golang.org/x/crypto v0.12.0/go.mod h1:NF0Gs7EO5K4qLn+Ylc+fih8BSTeIjAP05siRnAh98yw=
golang.org/x/crypto v0.15.0 h1:frVn1TEaCEaZcn3Tmd7Y2b5KKPaZ+I32Q2OA3kYp5TA=
golang.org/x/crypto v0.15.0/go.mod h1:4ChreQoLWfG3xLDer1WdlH5NdlQ3+mwnQq1YTKY+72g=
golang.org/x/image v0.11.0 h1:ds2RoQvBvYTiJkwpSFDwCcDFNX7DqjL2WsUgTNk0Ooo=
golang.org/x/image v0.11.0/go.mod h1:bglhjqbqVuEb9e9+eNR45Jfu7D+T4Qan+NhQk8Ck2P8=
golang.org/x/image v0.14.0 h1:tNgSxAFe3jC4uYqvZdTr84SZoM1KfwdC9SKIFrLjFn4=
golang.org/x/image v0.14.0/go.mod h1:HUYqC05R2ZcZ3ejNQsIHQDQiwWM4JBqmm6MKANTp4LE=
golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4=
golang.org/x/mod v0.8.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs=
golang.org/x/mod v0.14.0 h1:dGoOF9QVLYng8IHTm7BAyWqCqSheQ5pYWGhzW00YJr0=

View file

@ -168,7 +168,7 @@ var dsl = []byte(`
"method": "GET",
"guard": "-",
"process": "sui.Template.Asset",
"in": ["$param.id", "$param.template_id", "$param.path"],
"in": ["$param.id", "$param.template_id", "$param.path", "$query.w", "$query.h"],
"out": {
"status": 200,
"body": "?:content",
@ -185,7 +185,7 @@ var dsl = []byte(`
"guard": "query-jwt",
"method": "GET",
"process": "sui.Page.Asset",
"in": ["$param.id", "$param.template_id", "$param.path"],
"in": ["$param.id", "$param.template_id", "$param.path", "$query.w", "$query.h"],
"out": {
"status": 200,
"body": "?:content",

View file

@ -102,7 +102,9 @@ func TemplateAsset(process *process.Process) interface{} {
exception.New(err.Error(), 500).Throw()
}
asset, err := tmpl.Asset(process.ArgsString(2))
w := process.ArgsInt(3, 0)
h := process.ArgsInt(4, 0)
asset, err := tmpl.Asset(process.ArgsString(2), uint(w), uint(h))
if err != nil {
exception.New(err.Error(), 404).Throw()
}

View file

@ -39,7 +39,7 @@ type ITemplate interface {
Locales() []SelectOption
Themes() []SelectOption
Asset(file string) (*Asset, error)
Asset(file string, width, height uint) (*Asset, error)
AssetUpload(reader io.Reader, name string) (string, error)
MediaSearch(query url.Values, page int, pageSize int) (MediaSearchResult, error)

View file

@ -3,7 +3,6 @@ package local
import (
"fmt"
"io"
"math"
"net/url"
"os"
"path/filepath"
@ -54,17 +53,32 @@ func (tmpl *Template) Themes() []core.SelectOption {
// MediaSearch search the asset
func (tmpl *Template) MediaSearch(query url.Values, page int, pageSize int) (core.MediaSearchResult, error) {
res := core.MediaSearchResult{Data: []core.Media{}, Page: page, PageSize: pageSize}
keyword := query.Get("keyword")
types := query["types"]
if types == nil {
types = []string{"image", "video", "audio"}
}
exts := tmpl.mediaExts(types)
path := filepath.Join(tmpl.Root, "__assets", "upload")
files, total, pagecnt, err := tmpl.local.fs.List(path, exts, page, pageSize, func(s string) bool {
if keyword == "" {
return true
}
return strings.Contains(s, keyword)
})
total := 124
pagecnt := int(math.Ceil(float64(total) / float64(pageSize)))
for i := 0; i < pageSize; i++ {
test := fmt.Sprintf("https://plus.unsplash.com/premium_photo-1671641797903-fd39ec702b16?auto=format&fit=crop&q=80&w=2334&ixlib=rb-4.0.3&ixid=M3wxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8fA%%3D%%3D&id=%d", (page-1)*pageSize+i)
thumb := fmt.Sprintf("https://plus.unsplash.com/premium_photo-1671641797903-fd39ec702b16?auto=format&fit=crop&q=80&w=100&ixlib=rb-4.0.3&ixid=M3wxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8fA%%3D%%3D&id=%d", (page-1)*pageSize+i)
if err != nil {
return res, err
}
for _, file := range files {
file = strings.TrimPrefix(file, filepath.Join(tmpl.Root, "__assets", "upload"))
res.Data = append(res.Data, core.Media{
ID: test,
URL: test,
Thumb: thumb,
Type: "image",
ID: file,
URL: filepath.Join("@assets", "upload", file),
Thumb: filepath.Join("@assets", "upload", file),
Type: tmpl.mediaType(file),
Width: 100,
Height: 100,
})
@ -86,6 +100,57 @@ func (tmpl *Template) MediaSearch(query url.Values, page int, pageSize int) (cor
return res, nil
}
func (tmpl *Template) mediaExts(types []string) []string {
exts := []string{}
for _, typ := range types {
switch typ {
case "image":
exts = append(exts, []string{".jpg", ".jpeg", ".png"}...)
break
case "video":
exts = append(exts, []string{".mp4"}...)
break
case "audio":
exts = append(exts, []string{".mp3"}...)
break
}
}
return exts
}
func (tmpl *Template) mediaType(file string) string {
ext := strings.ToLower(filepath.Ext(file))
switch ext {
case ".jpg":
return "image"
case ".jpeg":
return "image"
case ".png":
return "image"
case ".gif":
return "image"
case ".bmp":
return "image"
case ".mp4":
return "video"
case ".mp3":
return "audio"
}
return "file"
}
// AssetUpload upload the asset
func (tmpl *Template) AssetUpload(reader io.Reader, name string) (string, error) {
@ -101,11 +166,15 @@ func (tmpl *Template) AssetUpload(reader io.Reader, name string) (string, error)
}
// Asset get the asset
func (tmpl *Template) Asset(file string) (*core.Asset, error) {
func (tmpl *Template) Asset(file string, width, height uint) (*core.Asset, error) {
file = filepath.Join(tmpl.Root, "__assets", file)
if exist, _ := tmpl.local.fs.Exists(file); exist {
if width > 0 || height > 0 {
return tmpl.assetThumb(file, width, height)
}
content, err := tmpl.local.fs.ReadFile(file)
if err != nil {
return nil, err
@ -145,3 +214,26 @@ func (tmpl *Template) Asset(file string) (*core.Asset, error) {
return nil, fmt.Errorf("Asset %s not found", file)
}
func (tmpl *Template) assetThumb(file string, width, height uint) (*core.Asset, error) {
cacheFile := filepath.Join(tmpl.Root, "__assets", ".cache", fmt.Sprintf("%dx%d", width, height), file)
exist, _ := tmpl.local.fs.Exists(cacheFile)
if !exist {
err := tmpl.local.fs.Resize(file, cacheFile, width, height)
if err != nil {
return nil, err
}
}
typ, err := tmpl.local.fs.MimeType(file)
if err != nil {
return nil, err
}
content, err := tmpl.local.fs.ReadFile(cacheFile)
if err != nil {
return nil, err
}
return &core.Asset{Type: typ, Content: content}, nil
}

View file

@ -59,7 +59,7 @@ func TestTemplateAsset(t *testing.T) {
t.Fatalf("GetTemplate error: %v", err)
}
asset, err := tmpl.Asset("/css/tailwind.css")
asset, err := tmpl.Asset("/css/tailwind.css", 0, 0)
if err != nil {
t.Fatalf("Asset error: %v", err)
}