fix(move): resolve full per-photo file list so videos actually move

The move resolved photos via the /photos search, whose merged Files array is
trimmed (often omitting a photo's video file) and which applies PhotoPrism's
quality/review/archive filters — so a video's .mov was never listed to move
and nothing happened. Resolve each UID via GET /photos/:uid instead (full file
list, no filters), shared by photos-move and heap-convert via resolvePhotosFull.
Unresolved UIDs are reported as skipped rather than aborting the batch.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
2026-06-23 22:52:56 +02:00
parent a52f171946
commit e1e508671e
2 changed files with 59 additions and 22 deletions

View File

@@ -90,9 +90,10 @@ func handleHeapConvert(cfg *Config, pp *ppClient) gin.HandlerFunc {
c.JSON(http.StatusBadRequest, gin.H{"error": "invalid targetFolder"})
return
}
// Pull the heap's photos via the q=album:UID query. count=1000 covers
// every realistic heap; merged=true expands stacked variants so we
// move the JPG/HEIC sibling alongside the primary.
// Pull the heap's membership via the q=album:UID query (count=1000
// covers every realistic heap). We only need the UID list here — the
// search's Files array is trimmed and drops videos, so we re-resolve
// each photo's full file set below via resolvePhotosFull.
q := url.QueryEscape("album:" + albumUID)
listURL := "/api/v1/photos?q=" + q + "&count=1000&merged=true"
resp, err := pp.call(c.Request.Context(), http.MethodGet, listURL, token, nil)
@@ -104,17 +105,31 @@ func handleHeapConvert(cfg *Config, pp *ppClient) gin.HandlerFunc {
c.JSON(resp.Status, gin.H{"error": "list photos failed"})
return
}
var photos []heapPhoto
if err := json.Unmarshal(resp.Body, &photos); err != nil {
var listed []heapPhoto
if err := json.Unmarshal(resp.Body, &listed); err != nil {
c.JSON(http.StatusBadGateway, gin.H{"error": "decode photo list"})
return
}
uids := make([]string, 0, len(listed))
for _, p := range listed {
uids = append(uids, p.UID)
}
// Re-fetch each photo's complete file list so videos (and other multi-
// file photos) move whole — the album search alone would orphan the
// .mov. See resolvePhotosFull.
photos, resolveErrs, err := resolvePhotosFull(c.Request.Context(), pp, token, uids)
if err != nil {
c.JSON(http.StatusBadGateway, gin.H{"error": err.Error()})
return
}
moved, copied, errs, err := movePhotoFiles(cfg, pp, token, photos, targetAbs, subfolder, mode)
if err != nil {
c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()})
return
}
errs = append(resolveErrs, errs...)
heapDeleted := false
if deleteHeap {