diff options
Diffstat (limited to 'internal')
| -rw-r--r-- | internal/api/handlers.go | 15 | ||||
| -rw-r--r-- | internal/model/scan.go | 74 |
2 files changed, 88 insertions, 1 deletions
diff --git a/internal/api/handlers.go b/internal/api/handlers.go index ad2e608..433de7d 100644 --- a/internal/api/handlers.go +++ b/internal/api/handlers.go @@ -405,12 +405,22 @@ func (s *Server) handleListMedia(w http.ResponseWriter, r *http.Request) { if !requireService(w, s.mediaSvc) { return } - filter := parseMediaListQuery(r.URL.Query()) + path := r.URL.Path + q := r.URL.Query() + setID := q.Get("set_id") + setIDs := q.Get("set_ids") + search := q.Get("search") + typ := q.Get("type") + start := time.Now() + filter := parseMediaListQuery(q) media, err := s.mediaSvc.ListMedia(r.Context(), userIDFromContext(r), filter) + dur := time.Since(start) if err != nil { + fmt.Printf("[api] %s set_id=%s set_ids=%s search=%q type=%s error=%v (took %s)\n", path, setID, setIDs, search, typ, err, dur) writeJSON(w, http.StatusInternalServerError, map[string]string{"error": err.Error()}) return } + fmt.Printf("[api] %s set_id=%s set_ids=%s search=%q type=%s returned=%d (took %s)\n", path, setID, setIDs, search, typ, len(media), dur) writeJSON(w, http.StatusOK, media) } @@ -547,6 +557,7 @@ func (s *Server) handleRestore(w http.ResponseWriter, r *http.Request) { func (s *Server) serveFileResult(w http.ResponseWriter, r *http.Request, res *service.FileResult, attachment bool) { f, err := os.Open(res.Path) if err != nil { + fmt.Printf("[api] stream file=%s error=open_failed\n", res.FileName) http.Error(w, "not found", http.StatusNotFound) return } @@ -554,6 +565,7 @@ func (s *Server) serveFileResult(w http.ResponseWriter, r *http.Request, res *se stat, err := f.Stat() if err != nil { + fmt.Printf("[api] stream file=%s error=stat_failed\n", res.FileName) http.Error(w, "not found", http.StatusNotFound) return } @@ -566,6 +578,7 @@ func (s *Server) serveFileResult(w http.ResponseWriter, r *http.Request, res *se // needing to sniff, which avoids buffering delays during streaming. w.Header().Set("Content-Type", mimeTypeForFilename(res.FileName)) w.Header().Set("Accept-Ranges", "bytes") + fmt.Printf("[api] stream file=%s size=%d bytes range=%s\n", res.FileName, stat.Size(), r.Header.Get("Range")) http.ServeContent(w, r, res.FileName, stat.ModTime(), f) } diff --git a/internal/model/scan.go b/internal/model/scan.go new file mode 100644 index 0000000..675b5dd --- /dev/null +++ b/internal/model/scan.go @@ -0,0 +1,74 @@ +package model + +import "sync" + +// ScanProgress tracks the state of an in-progress or recently completed scan. +type ScanProgress struct { + mu sync.RWMutex + Running bool `json:"running"` + CurrentSet string `json:"current_set,omitempty"` + SetsTotal int `json:"sets_total"` + SetsDone int `json:"sets_done"` + FilesTotal int `json:"files_total"` + FilesDone int `json:"files_done"` + LastError string `json:"last_error,omitempty"` +} + +func (p *ScanProgress) Start(setsTotal int) { + p.mu.Lock() + defer p.mu.Unlock() + p.Running = true + p.SetsTotal = setsTotal + p.SetsDone = 0 + p.FilesTotal = 0 + p.FilesDone = 0 + p.LastError = "" +} + +func (p *ScanProgress) SetCurrentSet(name string) { + p.mu.Lock() + defer p.mu.Unlock() + p.CurrentSet = name +} + +func (p *ScanProgress) IncrementFile() { + p.mu.Lock() + defer p.mu.Unlock() + p.FilesDone++ +} + +func (p *ScanProgress) SetFilesTotal(total int) { + p.mu.Lock() + defer p.mu.Unlock() + p.FilesTotal = total +} + +func (p *ScanProgress) IncrementSet() { + p.mu.Lock() + defer p.mu.Unlock() + p.SetsDone++ +} + +func (p *ScanProgress) Done(err error) { + p.mu.Lock() + defer p.mu.Unlock() + p.Running = false + p.CurrentSet = "" + if err != nil { + p.LastError = err.Error() + } +} + +func (p *ScanProgress) Copy() ScanProgress { + p.mu.RLock() + defer p.mu.RUnlock() + return ScanProgress{ + Running: p.Running, + CurrentSet: p.CurrentSet, + SetsTotal: p.SetsTotal, + SetsDone: p.SetsDone, + FilesTotal: p.FilesTotal, + FilesDone: p.FilesDone, + LastError: p.LastError, + } +} |
