feat: parse and display all available EPUB metadata fields

Add parsing for dc:publisher, dc:date, dc:subject, dc:rights,
dc:contributor, dc:identifier (prefers ISBN scheme), and
calibre:rating. All new fields serialized in BookMetadataCache
(version bumped to 7) and displayed in BookInfoActivity with
rating shown as N/5 scale.

Made-with: Cursor
This commit is contained in:
cottongin
2026-03-09 02:43:10 -04:00
parent 1a3e7109e3
commit 8025e6fb0d
10 changed files with 269 additions and 7 deletions

View File

@@ -81,6 +81,13 @@ bool Epub::parseContentOpf(BookMetadataCache::BookMetadata& bookMetadata) {
bookMetadata.series = opfParser.series;
bookMetadata.seriesIndex = opfParser.seriesIndex;
bookMetadata.description = opfParser.description;
bookMetadata.publisher = opfParser.publisher;
bookMetadata.date = opfParser.date;
bookMetadata.subjects = opfParser.subjects;
bookMetadata.rights = opfParser.rights;
bookMetadata.contributor = opfParser.contributor;
bookMetadata.identifier = opfParser.identifier;
bookMetadata.rating = opfParser.rating;
// Guide-based cover fallback: if no cover found via metadata/properties,
// try extracting the image reference from the guide's cover page XHTML
@@ -547,6 +554,48 @@ const std::string& Epub::getDescription() const {
return bookMetadataCache->coreMetadata.description;
}
const std::string& Epub::getPublisher() const {
static std::string blank;
if (!bookMetadataCache || !bookMetadataCache->isLoaded()) return blank;
return bookMetadataCache->coreMetadata.publisher;
}
const std::string& Epub::getDate() const {
static std::string blank;
if (!bookMetadataCache || !bookMetadataCache->isLoaded()) return blank;
return bookMetadataCache->coreMetadata.date;
}
const std::string& Epub::getSubjects() const {
static std::string blank;
if (!bookMetadataCache || !bookMetadataCache->isLoaded()) return blank;
return bookMetadataCache->coreMetadata.subjects;
}
const std::string& Epub::getRights() const {
static std::string blank;
if (!bookMetadataCache || !bookMetadataCache->isLoaded()) return blank;
return bookMetadataCache->coreMetadata.rights;
}
const std::string& Epub::getContributor() const {
static std::string blank;
if (!bookMetadataCache || !bookMetadataCache->isLoaded()) return blank;
return bookMetadataCache->coreMetadata.contributor;
}
const std::string& Epub::getIdentifier() const {
static std::string blank;
if (!bookMetadataCache || !bookMetadataCache->isLoaded()) return blank;
return bookMetadataCache->coreMetadata.identifier;
}
const std::string& Epub::getRating() const {
static std::string blank;
if (!bookMetadataCache || !bookMetadataCache->isLoaded()) return blank;
return bookMetadataCache->coreMetadata.rating;
}
std::string Epub::getCoverBmpPath(bool cropped) const {
const auto coverFileName = std::string("cover") + (cropped ? "_crop" : "");
return cachePath + "/" + coverFileName + ".bmp";