summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPaul Buetow <paul@buetow.org>2026-05-06 08:09:30 +0300
committerPaul Buetow <paul@buetow.org>2026-05-06 08:09:30 +0300
commitad6f2ae6f6aa14926ef63a7fe124093dcceb024b (patch)
tree515309f431add4fe9d9b2bf2909bbc89fced12e5
parent885dd0912dd0e4f9df86b6676a6c467bdb367660 (diff)
fix(scanner, browse): fallback to original image when thumbnail generation fails for cover.jpg
When scanning image files (e.g. cover.jpg in audiobook folders), thumbnailForImage can fail or produce a missing .thumbnails/cover.jpg. This caused broken thumbnails in the grid. - scanner.go buildThumbnailPath: after generating an image thumbnail, verify the output file exists via fs.Stat. If it does not exist, fall back to using the original image path as the thumbnail_path. - browse.go GetThumbnail: if os.Stat(ThumbnailPath) fails and the media type is image, fall back to serving the original AbsPath. All tests pass.
-rw-r--r--internal/scanner/scanner.go11
-rw-r--r--internal/service/browse.go26
2 files changed, 29 insertions, 8 deletions
diff --git a/internal/scanner/scanner.go b/internal/scanner/scanner.go
index 30b20d1..34e0ca5 100644
--- a/internal/scanner/scanner.go
+++ b/internal/scanner/scanner.go
@@ -202,7 +202,16 @@ func (s *FSScanner) buildThumbnailPath(ctx context.Context, path, setPath string
if ext == ".svg" {
return path, nil
}
- return s.thumbnailForImage(ctx, path, setPath)
+ thumbPath, err := s.thumbnailForImage(ctx, path, setPath)
+ if err != nil {
+ return "", err
+ }
+ if thumbPath != "" {
+ if _, statErr := s.fs.Stat(thumbPath); statErr == nil {
+ return thumbPath, nil
+ }
+ }
+ return path, nil
}
return "", nil
}
diff --git a/internal/service/browse.go b/internal/service/browse.go
index b420d70..0df399b 100644
--- a/internal/service/browse.go
+++ b/internal/service/browse.go
@@ -183,14 +183,26 @@ func (s *browseService) GetThumbnail(ctx context.Context, mediaID, userID int64)
return nil, errors.New("thumbnail not found")
}
info, err := os.Stat(media.ThumbnailPath)
- if err != nil {
- return nil, fmt.Errorf("stat thumbnail: %w", err)
+ if err == nil {
+ return &FileResult{
+ Path: media.ThumbnailPath,
+ FileName: filepath.Base(media.ThumbnailPath),
+ FileSize: info.Size(),
+ }, nil
}
- return &FileResult{
- Path: media.ThumbnailPath,
- FileName: filepath.Base(media.ThumbnailPath),
- FileSize: info.Size(),
- }, nil
+ // If the generated thumbnail is missing, fall back to the original file
+ // for image media so that cover.jpg and similar files still render.
+ if media.Type == model.MediaTypeImage {
+ info, err = os.Stat(media.AbsPath)
+ if err == nil {
+ return &FileResult{
+ Path: media.AbsPath,
+ FileName: filepath.Base(media.AbsPath),
+ FileSize: info.Size(),
+ }, nil
+ }
+ }
+ return nil, fmt.Errorf("stat thumbnail: %w", err)
}
func (s *browseService) RegenerateThumbnail(ctx context.Context, mediaID, userID int64) error {