feat: update ebook scanner to normalize metadata

Update extractEPUBMetadata:
- Normalize tags for display using NormalizeTags()
- Normalize contributors for display using NormalizeContributors()
- Preserves extracted metadata formatting while ensuring consistency

Update processEbookFile:
- Add normalization before database insert
- Generate tags_search using NormalizeTagsSearch()
- Generate contributors_search using NormalizeContributorsSearch()
- Pass both display and search fields to CreateMediaItem

Scanner now produces normalized metadata matching user input normalization,
ensuring consistency between scanned and manually entered media items.

Relates to Tags & Contributors Migration Phase 7
This commit is contained in:
2026-02-08 11:05:29 -05:00
parent 75cc26d5d1
commit eb8f83e1b9
+31 -21
View File
@@ -452,25 +452,35 @@ func (s *EbookScanner) processEbookFile(ctx context.Context, path string) error
return fmt.Errorf("no library found for file path: %s", path) return fmt.Errorf("no library found for file path: %s", path)
} }
// Normalize metadata fields for display
metadata.Contributors = utils.NormalizeContributors(metadata.Contributors)
metadata.Tags = utils.NormalizeTags(metadata.Tags)
// Normalize search fields
contributorsSearch := utils.NormalizeContributorsSearch(metadata.Contributors)
tagsSearch := utils.NormalizeTagsSearch(metadata.Tags)
// Create media item in database // Create media item in database
createdItem, err := s.db.CreateMediaItem(ctx, database.CreateMediaItemParams{ createdItem, err := s.db.CreateMediaItem(ctx, database.CreateMediaItemParams{
LibraryID: libraryID, LibraryID: libraryID,
Title: metadata.Title, Title: metadata.Title,
Author: pgtype.Text{String: metadata.Author, Valid: metadata.Author != ""}, Author: pgtype.Text{String: metadata.Author, Valid: metadata.Author != ""},
Isbn: pgtype.Text{String: utils.NormalizeISBN(metadata.ISBN), Valid: metadata.ISBN != ""}, Isbn: pgtype.Text{String: utils.NormalizeISBN(metadata.ISBN), Valid: metadata.ISBN != ""},
Asin: pgtype.Text{String: metadata.ASIN, Valid: metadata.ASIN != ""}, Asin: pgtype.Text{String: metadata.ASIN, Valid: metadata.ASIN != ""},
Description: pgtype.Text{String: metadata.Description, Valid: metadata.Description != ""}, Description: pgtype.Text{String: metadata.Description, Valid: metadata.Description != ""},
FilePath: path, FilePath: path,
FileSize: pgtype.Int8{Int64: info.Size(), Valid: true}, FileSize: pgtype.Int8{Int64: info.Size(), Valid: true},
MimeType: pgtype.Text{String: s.getMimeType(path), Valid: true}, MimeType: pgtype.Text{String: s.getMimeType(path), Valid: true},
CoverImagePath: pgtype.Text{String: metadata.CoverPath, Valid: metadata.CoverPath != ""}, CoverImagePath: pgtype.Text{String: metadata.CoverPath, Valid: metadata.CoverPath != ""},
Series: pgtype.Text{String: metadata.Series, Valid: metadata.Series != ""}, Series: pgtype.Text{String: metadata.Series, Valid: metadata.Series != ""},
SeriesNumber: pgtype.Int4{Int32: metadata.SeriesNumber, Valid: metadata.SeriesNumber > 0}, SeriesNumber: pgtype.Int4{Int32: metadata.SeriesNumber, Valid: metadata.SeriesNumber > 0},
Publisher: pgtype.Text{String: metadata.Publisher, Valid: metadata.Publisher != ""}, Publisher: pgtype.Text{String: metadata.Publisher, Valid: metadata.Publisher != ""},
DatePublished: pgtype.Date{Time: metadata.PublishDate, Valid: !metadata.PublishDate.IsZero()}, DatePublished: pgtype.Date{Time: metadata.PublishDate, Valid: !metadata.PublishDate.IsZero()},
Contributors: metadata.Contributors, Contributors: metadata.Contributors,
Tags: metadata.Tags, ContributorsSearch: contributorsSearch,
AddedByAdminID: s.adminID, Tags: metadata.Tags,
TagsSearch: tagsSearch,
AddedByAdminID: s.adminID,
}) })
if err != nil { if err != nil {
return fmt.Errorf("failed to create media item: %v", err) return fmt.Errorf("failed to create media item: %v", err)
@@ -576,8 +586,8 @@ func (s *EbookScanner) extractEPUBMetadata(path string) (*EbookMetadata, error)
// Contributors // Contributors
if contributors, err := book.MetadataByKey("contributor"); err == nil && len(contributors) > 0 { if contributors, err := book.MetadataByKey("contributor"); err == nil && len(contributors) > 0 {
// Already a []string from xml parsing, just assign // Normalize contributors for display
metadata.Contributors = contributors metadata.Contributors = utils.NormalizeContributors(contributors)
} }
// ISBN // ISBN
@@ -603,8 +613,8 @@ func (s *EbookScanner) extractEPUBMetadata(path string) (*EbookMetadata, error)
// Tags // Tags
if tags, err := book.MetadataByKey("subject"); err == nil && len(tags) > 0 { if tags, err := book.MetadataByKey("subject"); err == nil && len(tags) > 0 {
// Already a []string from xml parsing, just assign // Normalize tags for display
metadata.Tags = tags metadata.Tags = utils.NormalizeTags(tags)
} }
return metadata, nil return metadata, nil