Files
ttstd-infinite-canvas/backend/internal/app/eagle_thumbnail.go

60 lines
1.8 KiB
Go

package app
import (
"errors"
"mime"
"net/http"
"net/url"
"os"
"path/filepath"
"strings"
)
func (s *Service) OpenEagleItemThumbnail(rawBaseURL string, itemID string) (*EagleFile, error) {
if strings.TrimSpace(itemID) == "" || strings.ContainsAny(itemID, "/\\?&") {
return nil, BadAuthRequest("Eagle 素材 ID 无效")
}
baseURL, err := validateEagleBaseURL(rawBaseURL)
if err != nil {
return nil, err
}
library, err := s.EagleLibrary(rawBaseURL)
if err != nil {
return nil, err
}
var response struct {
Status string `json:"status"`
Data string `json:"data"`
}
if err := eagleJSONRequest(http.MethodGet, baseURL, "/api/item/thumbnail?id="+url.QueryEscape(itemID), nil, &response); err != nil {
return nil, err
}
if response.Status != "success" || strings.TrimSpace(response.Data) == "" {
return nil, errors.New("Eagle 未返回缩略图路径")
}
thumbnailPath, err := url.PathUnescape(response.Data)
if err != nil {
return nil, errors.New("Eagle 缩略图路径编码无效")
}
thumbnailPath = filepath.Clean(filepath.FromSlash(thumbnailPath))
itemDir := filepath.Join(filepath.Clean(filepath.FromSlash(library.LibraryPath)), "images", itemID+".info")
rel, err := filepath.Rel(itemDir, thumbnailPath)
if err != nil || rel == "." || strings.HasPrefix(rel, ".."+string(filepath.Separator)) || rel == ".." {
return nil, errors.New("Eagle 缩略图路径不在当前素材库内")
}
file, err := os.Open(thumbnailPath)
if err != nil {
return nil, errors.New("无法读取 Eagle 缩略图")
}
stat, err := file.Stat()
if err != nil {
file.Close()
return nil, err
}
mimeType := mime.TypeByExtension(filepath.Ext(thumbnailPath))
if mimeType == "" {
mimeType = "application/octet-stream"
}
return &EagleFile{Path: thumbnailPath, Name: filepath.Base(thumbnailPath), Size: stat.Size(), MimeType: mimeType, Body: file}, nil
}