feat(scanner): fill sparse sidecars from embedded EPUB metadata
A sparse metadata.opf/metadata.json (title only, no description) left books thin even when the file itself carried rich data: the embedded extractors only ran when no sidecar existed at all. Now mergeMetadata fills blanks from the book's own OPF - title, author, description, publisher, language, ISBN, ASIN, series/number, publish date, tags, contributors - while sidecar values always win and unparseable files skip silently. Also covers .kepub, which the merge previously ignored while the extractor already supported it. Adds TestMergeMetadataEPUBGapFill asserting both directions: sidecar title/author survive, embedded description/publisher/language fill in.
This commit is contained in:
@@ -1161,7 +1161,7 @@ func (s *MediaScanner) mergeMetadata(path string, calibreMetadata *MediaMetadata
|
||||
ext := strings.ToLower(filepath.Ext(path))
|
||||
|
||||
// For EPUB files
|
||||
if ext == ".epub" {
|
||||
if ext == ".epub" || ext == ".kepub" {
|
||||
book, err := epub.ReadBook(path)
|
||||
if err == nil {
|
||||
genreTags := extractGenreTagsFromEPUB(book)
|
||||
@@ -1177,6 +1177,48 @@ func (s *MediaScanner) mergeMetadata(path string, calibreMetadata *MediaMetadata
|
||||
metadata.PageCount = int32(pageCount)
|
||||
}
|
||||
}
|
||||
|
||||
// Gap-fill: sidecar-sourced metadata wins, but blanks are filled from
|
||||
// the book's own OPF so a sparse metadata.opf/metadata.json doesn't
|
||||
// hide data the file carries. Never overwrites sidecar values.
|
||||
if embedded, err := s.extractEPUBMetadata(path); err == nil && embedded != nil {
|
||||
if metadata.Title == "" && embedded.Title != "" {
|
||||
metadata.Title = embedded.Title
|
||||
}
|
||||
if metadata.Author == "" && embedded.Author != "" {
|
||||
metadata.Author = embedded.Author
|
||||
}
|
||||
if metadata.Description == "" && embedded.Description != "" {
|
||||
metadata.Description = embedded.Description
|
||||
}
|
||||
if metadata.Publisher == "" && embedded.Publisher != "" {
|
||||
metadata.Publisher = embedded.Publisher
|
||||
}
|
||||
if metadata.Language == "" && embedded.Language != "" {
|
||||
metadata.Language = embedded.Language
|
||||
}
|
||||
if metadata.ISBN == "" && embedded.ISBN != "" {
|
||||
metadata.ISBN = embedded.ISBN
|
||||
}
|
||||
if metadata.ASIN == "" && embedded.ASIN != "" {
|
||||
metadata.ASIN = embedded.ASIN
|
||||
}
|
||||
if metadata.Series == "" && embedded.Series != "" {
|
||||
metadata.Series = embedded.Series
|
||||
}
|
||||
if metadata.SeriesNumber == 0 && embedded.SeriesNumber != 0 {
|
||||
metadata.SeriesNumber = embedded.SeriesNumber
|
||||
}
|
||||
if metadata.PublishDate.IsZero() && !embedded.PublishDate.IsZero() {
|
||||
metadata.PublishDate = embedded.PublishDate
|
||||
}
|
||||
if len(metadata.Tags) == 0 && len(embedded.Tags) > 0 {
|
||||
metadata.Tags = embedded.Tags
|
||||
}
|
||||
if len(metadata.Contributors) == 0 && len(embedded.Contributors) > 0 {
|
||||
metadata.Contributors = embedded.Contributors
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// For comic archives, try to extract ComicInfo.xml
|
||||
|
||||
Reference in New Issue
Block a user