Files
2026-07-27 19:31:43 +08:00

97 lines
2.4 KiB
Go

package api
import (
"net/http"
"litepan/internal/domain"
"litepan/internal/playback"
)
type fileDTO struct {
ID string `json:"id"`
Name string `json:"name"`
Size int64 `json:"size"`
IsDir bool `json:"is_dir"`
ModTime string `json:"mod_time,omitempty"`
}
func fileToDTO(f domain.FileItem) fileDTO {
dto := fileDTO{ID: f.ID, Name: f.Name, Size: f.Size, IsDir: f.IsDir}
if !f.ModTime.IsZero() {
dto.ModTime = FormatAPITime(f.ModTime)
}
return dto
}
func (h *Handler) listFiles(w http.ResponseWriter, r *http.Request) {
accID, err := parseQueryInt64(r, "account_id")
if err != nil {
writeErr(w, err)
return
}
parent := r.URL.Query().Get("parent_id")
forceRefresh := r.URL.Query().Get("force_refresh") == "true"
items, err := h.files.List(r.Context(), accID, parent, forceRefresh)
if err != nil {
writeErr(w, err)
return
}
dtos := make([]fileDTO, 0, len(items))
for _, it := range items {
dtos = append(dtos, fileToDTO(it))
}
writeOK(w, map[string]any{"parent_id": parent, "items": dtos})
}
func (h *Handler) fileInfo(w http.ResponseWriter, r *http.Request) {
accID, err := parseQueryInt64(r, "account_id")
if err != nil {
writeErr(w, err)
return
}
fileID := r.URL.Query().Get("file_id")
if fileID == "" {
writeErr(w, domain.Errorf(domain.CodeValidation, "缺少 file_id"))
return
}
info, err := h.files.Info(r.Context(), accID, fileID)
if err != nil {
writeErr(w, err)
return
}
writeOK(w, fileToDTO(*info))
}
// downloadFile 经播放网关解析直链:302 或 Range 代理。
func (h *Handler) downloadFile(w http.ResponseWriter, r *http.Request) {
accID, err := parseQueryInt64(r, "account_id")
if err != nil {
writeErr(w, err)
return
}
fileID := r.URL.Query().Get("file_id")
if fileID == "" {
writeErr(w, domain.Errorf(domain.CodeValidation, "缺少 file_id"))
return
}
req := playback.Request{AccountID: accID, FileID: fileID}
intent := playback.Intent{
ForceProxy: r.URL.Query().Get("force_proxy") == "1",
FileName: r.URL.Query().Get("file_name"),
Inline: r.URL.Query().Get("inline") == "1",
}
if r.URL.Query().Get("redirect") == "0" {
res, err := h.playback.Resolve(r.Context(), accID, fileID, r.UserAgent(), false)
if err != nil {
writeErr(w, err)
return
}
writeOK(w, map[string]any{"url": res.Link.URL})
return
}
if err := h.playback.ServeHTTP(w, r, req, intent); err != nil {
writeErr(w, err)
}
}