diff --git a/sui/api/api.go b/sui/api/api.go index 1ac51bd0..11e18a1a 100644 --- a/sui/api/api.go +++ b/sui/api/api.go @@ -193,6 +193,14 @@ var dsl = []byte(` } }, + { + "path": "/:id/media/:driver/search", + "method": "GET", + "process": "sui.Media.Search", + "in": ["$param.id", "$param.driver", ":query"], + "out": { "status": 200, "type": "application/json" } + }, + { "path": "/:id/preview/:template_id/*route", "guard": "query-jwt", diff --git a/sui/api/process.go b/sui/api/process.go index 4f8f2865..3372ba01 100644 --- a/sui/api/process.go +++ b/sui/api/process.go @@ -5,6 +5,7 @@ import ( "fmt" "net/url" "path/filepath" + "strconv" "strings" "github.com/gin-gonic/gin" @@ -48,6 +49,8 @@ func init() { "editor.renderaftersavetemp": EditorRenderAfterSaveTemp, "editor.sourceaftersavetemp": EditorSourceAfterSaveTemp, + "media.search": MediaSearch, + "preview.render": PreviewRender, "build.all": BuildAll, @@ -165,6 +168,83 @@ func TemplateAssetUpload(process *process.Process) interface{} { } } +// MediaSearch handle the find Template request +func MediaSearch(process *process.Process) interface{} { + + process.ValidateArgNums(2) + sui := get(process) + driver := process.ArgsString(1) + + query := url.Values{} + if process.NumOfArgs() > 2 { + switch v := process.Args[2].(type) { + case map[string]string: + for key, value := range v { + query.Set(key, value) + } + break + + case map[string]interface{}: + for key, value := range v { + query.Set(key, fmt.Sprintf("%v", value)) + } + break + + case map[string][]string: + query = v + break + + case url.Values: + query = v + break + } + } + + var err error + page := 1 + if v := query.Get("page"); v != "" { + page, err = strconv.Atoi(v) + if err != nil { + exception.New(err.Error(), 400).Throw() + } + query.Del("page") + } + + pageSize := 20 + if v := query.Get("pagesize"); v != "" { + pageSize, err = strconv.Atoi(v) + if err != nil { + exception.New(err.Error(), 400).Throw() + } + query.Del("pagesize") + } + + switch driver { + case "local": + templateID := query.Get("template") + if templateID == "" { + exception.New("the template is required", 400).Throw() + } + + tmpl, err := sui.GetTemplate(templateID) + if err != nil { + exception.New(err.Error(), 400).Throw() + } + + res, err := tmpl.MediaSearch(query, page, pageSize) + if err != nil { + exception.New(err.Error(), 500).Throw() + } + + return res + + default: + exception.New("the driver %s does not exist", 404, driver).Throw() + return nil + + } +} + // LocaleGet handle the find Template request func LocaleGet(process *process.Process) interface{} { process.ValidateArgNums(2) diff --git a/sui/core/interfaces.go b/sui/core/interfaces.go index 5a439c21..20bc9911 100644 --- a/sui/core/interfaces.go +++ b/sui/core/interfaces.go @@ -1,6 +1,9 @@ package core -import "io" +import ( + "io" + "net/url" +) // SUIs the loaded SUI instances var SUIs = map[string]SUI{} @@ -39,6 +42,8 @@ type ITemplate interface { Asset(file string) (*Asset, error) AssetUpload(reader io.Reader, name string) (string, error) + MediaSearch(query url.Values, page int, pageSize int) (MediaSearchResult, error) + Build(option *BuildOption) error SyncAssets(option *BuildOption) error } diff --git a/sui/core/types.go b/sui/core/types.go index d02f12b5..203b8028 100644 --- a/sui/core/types.go +++ b/sui/core/types.go @@ -102,6 +102,30 @@ type Asset struct { Content []byte `json:"content"` } +// Media is the struct for the media +type Media struct { + ID string `json:"id"` + Type string `json:"type"` + Content []byte `json:"content,omitempty"` + Width int `json:"width,omitempty"` + Height int `json:"height,omitempty"` + Size int `json:"size,omitempty"` + Length int `json:"length,omitempty"` + Thumb string `json:"thumb,omitempty"` + URL string `json:"url,omitempty"` +} + +// MediaSearchResult is the struct for the media search result +type MediaSearchResult struct { + Data []Media `json:"data"` + Total int `json:"total"` + Page int `json:"page"` + PageCount int `json:"pagecnt"` + PageSize int `json:"pagesize"` + Next int `json:"next"` + Prev int `json:"prev"` +} + // BuildOption is the struct for the option option type BuildOption struct { SSR bool `json:"ssr"` diff --git a/sui/storages/local/template.go b/sui/storages/local/template.go index 53ff37bd..2ecec3bc 100644 --- a/sui/storages/local/template.go +++ b/sui/storages/local/template.go @@ -3,6 +3,8 @@ package local import ( "fmt" "io" + "math" + "net/url" "os" "path/filepath" "strings" @@ -49,6 +51,40 @@ func (tmpl *Template) Themes() []core.SelectOption { return tmpl.Template.Themes } +// 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} + + 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) + res.Data = append(res.Data, core.Media{ + ID: test, + URL: test, + Thumb: test, + Type: "image", + Width: 100, + Height: 100, + }) + } + + res.Next = page + 1 + if (page+1)*pageSize >= total { + res.Next = 0 + } + + res.Prev = page - 1 + if page == 1 { + res.Prev = 0 + } + + res.Total = total + res.PageCount = pagecnt + + return res, nil +} + // AssetUpload upload the asset func (tmpl *Template) AssetUpload(reader io.Reader, name string) (string, error) {