diff --git a/pkg/api/handle_avatar.go b/pkg/api/handle_avatar.go index f8cfdc6..146c7ef 100644 --- a/pkg/api/handle_avatar.go +++ b/pkg/api/handle_avatar.go @@ -1,11 +1,17 @@ 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) { @@ -33,14 +39,70 @@ func (api *API) HandelGetFileAvatar(w http.ResponseWriter, r *http.Request) { 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", "-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 { - w.Header().Set("Content-Type", "application/json") 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 +} diff --git a/pkg/database/struct.go b/pkg/database/struct.go index ad86a32..d131a83 100644 --- a/pkg/database/struct.go +++ b/pkg/database/struct.go @@ -6,13 +6,14 @@ import ( ) type File struct { - Db *Database `json:"-"` - ID int64 `json:"id"` - Folder_id int64 `json:"folder_id"` - Foldername string `json:"foldername"` - Realname string `json:"-"` - Filename string `json:"filename"` - Filesize int64 `json:"filesize"` + Db *Database `json:"-"` + ID int64 `json:"id"` + Folder_id int64 `json:"folder_id"` + Foldername string `json:"foldername"` + Realname string `json:"-"` + Filename string `json:"filename"` + Filesize int64 `json:"filesize"` + folderCache *Folder } type Folder struct { @@ -75,9 +76,23 @@ var ( ) func (f *File) Path() (string, error) { - folder, err := f.Db.GetFolder(f.Folder_id) + var err error + if f.folderCache == nil { + f.folderCache, err = f.Db.GetFolder(f.Folder_id) + } if err != nil { return "", err } - return filepath.Join(folder.Folder, f.Realname), nil + return filepath.Join(f.folderCache.Folder, f.Realname), nil +} + +func (f *File) Dir() (string, error) { + var err error + if f.folderCache == nil { + f.folderCache, err = f.Db.GetFolder(f.Folder_id) + } + if err != nil { + return "", err + } + return f.folderCache.Folder, nil }