diff --git a/internal/services/media_scanner.go b/internal/services/media_scanner.go index a962226..3ba5707 100644 --- a/internal/services/media_scanner.go +++ b/internal/services/media_scanner.go @@ -3152,8 +3152,34 @@ func (s *MediaScanner) updateMediaItem(ctx context.Context, existing database.Me utils.ApplyMetadataOverrides(¶ms, existing) params.MetadataOverrides = utils.MergeOverrides(existing.MetadataOverrides) - _, err = s.db.UpdateMediaItem(ctx, params) - return err + if _, err = s.db.UpdateMediaItem(ctx, params); err != nil { + return err + } + + // Format flags are file-derived facts, not user metadata: refresh them on + // every update so a force rescan (the admin's backfill tool) can + // reclassify rows created before a classifyFormatGroup arm existed. + // Mirrors the creation path above. + ext := strings.ToLower(filepath.Ext(path)) + var epubIsFixedLayout bool + if ext == ".epub" { + isFixed, fixedErr := s.DetectFixedLayoutEPUB(path) + epubIsFixedLayout = fixedErr == nil && isFixed + } + formatGroup, isReflowable, hasFixedLayout := classifyFormatGroup(ext, epubIsFixedLayout) + mimeType := s.getMimeType(path) + if err := s.db.UpdateMediaItemFormatGroup(ctx, database.UpdateMediaItemFormatGroupParams{ + ID: existing.ID, + FormatGroup: formatGroup, + FormatMimetype: pgtype.Text{String: mimeType, Valid: mimeType != ""}, + IsReflowable: pgtype.Bool{Bool: isReflowable, Valid: true}, + HasFixedLayout: pgtype.Bool{Bool: hasFixedLayout, Valid: true}, + TotalCharacters: pgtype.Int8{Int64: metadata.TotalCharacters, Valid: metadata.TotalCharacters > 0}, + ChapterCount: pgtype.Int4{Int32: metadata.ChapterCount, Valid: metadata.ChapterCount > 0}, + }); err != nil { + fmt.Printf("Warning: failed to update format info for %s: %v\n", path, err) + } + return nil } // RescanMediaItem re-extracts metadata for a single media item and updates it.