109 lines
2.2 KiB
Go
109 lines
2.2 KiB
Go
package api
|
|
|
|
import (
|
|
"bytes"
|
|
"errors"
|
|
"io"
|
|
"log"
|
|
"msw-open-music/pkg/database"
|
|
"net/http"
|
|
"os"
|
|
"os/exec"
|
|
"path"
|
|
"strconv"
|
|
"strings"
|
|
)
|
|
|
|
func (api *API) HandelGetFileAvatar(w http.ResponseWriter, r *http.Request) {
|
|
var err error
|
|
q := r.URL.Query()
|
|
ids := q["id"]
|
|
if len(ids) == 0 {
|
|
err = errors.New(`parameter "id" can't be empty`)
|
|
api.HandleError(w, r, err)
|
|
return
|
|
}
|
|
id, err := strconv.Atoi(ids[0])
|
|
if err != nil {
|
|
api.HandleError(w, r, err)
|
|
return
|
|
}
|
|
file, err := api.Db.GetFile(int64(id))
|
|
if err != nil {
|
|
api.HandleError(w, r, err)
|
|
return
|
|
}
|
|
path, err := file.Path()
|
|
if err != nil {
|
|
api.HandleError(w, r, err)
|
|
return
|
|
}
|
|
log.Println("[api] Get avatar of file", path)
|
|
buff := make([]byte, 0)
|
|
cache := bytes.NewBuffer(buff)
|
|
cmd := exec.Command("ffmpeg", "-i", path, "-c:v", "libwebp_anim", "-update", "1", "-frames:v", "1", "-f", "image2pipe", "-")
|
|
cmd.Stdout = cache
|
|
|
|
err = cmd.Run()
|
|
if err != nil {
|
|
api.HandleGetAlternativeFileAvatar(w, r, file)
|
|
return
|
|
}
|
|
|
|
w.Header().Set("Content-Type", "image/webp")
|
|
io.Copy(w, cache)
|
|
}
|
|
|
|
func (api *API) HandleGetAlternativeFileAvatar(w http.ResponseWriter, r *http.Request, f *database.File) {
|
|
var err error
|
|
dir, err := f.Dir()
|
|
if err != nil {
|
|
api.HandleError(w, r, err)
|
|
return
|
|
}
|
|
log.Println("[api] Get alternative avatar in dir", dir)
|
|
files, err := os.ReadDir(dir)
|
|
if err != nil {
|
|
api.HandleError(w, r, err)
|
|
return
|
|
}
|
|
avatar, err := findAvatarFile(files)
|
|
avatarPath := path.Join(dir, avatar)
|
|
if err != nil {
|
|
api.HandleError(w, r, err)
|
|
return
|
|
}
|
|
cmd := exec.Command("ffmpeg", "-i", avatarPath, "-c:v", "libwebp_anim", "-f", "image2pipe", "-")
|
|
cmd.Stdout = w
|
|
w.Header().Set("Content-Type", "image/webp")
|
|
|
|
err = cmd.Run()
|
|
if err != nil {
|
|
api.HandleError(w, r, err)
|
|
return
|
|
}
|
|
}
|
|
|
|
func findAvatarFile(files []os.DirEntry) (string, error) {
|
|
for _, file := range files {
|
|
if isAvatarType(file.Name()) {
|
|
return file.Name(), nil
|
|
}
|
|
}
|
|
return "", errors.New("Cannot find avatar file")
|
|
}
|
|
|
|
var avatarFileTypes = []string{
|
|
".jpg",
|
|
".png",
|
|
}
|
|
|
|
func isAvatarType(filename string) bool {
|
|
for _, t := range avatarFileTypes {
|
|
if strings.HasSuffix(strings.ToLower(filename), t) {
|
|
return true
|
|
}
|
|
}
|
|
return false
|
|
}
|