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

@@ -60,6 +60,7 @@ void BookInfoActivity::onEnter() {
}
std::string title, author, series, seriesIndex, description, language;
std::string publisher, date, subjects, rights, contributor, identifier, rating;
if (FsHelpers::hasEpubExtension(fileName)) {
Epub epub(filePath, "/.crosspoint");
@@ -78,6 +79,13 @@ void BookInfoActivity::onEnter() {
seriesIndex = epub.getSeriesIndex();
description = normalizeWhitespace(epub.getDescription());
language = epub.getLanguage();
publisher = epub.getPublisher();
date = epub.getDate();
subjects = epub.getSubjects();
rights = epub.getRights();
contributor = epub.getContributor();
identifier = epub.getIdentifier();
rating = epub.getRating();
const int coverH = renderer.getScreenHeight() * 2 / 5;
if (epub.generateThumbBmp(coverH)) {
@@ -129,7 +137,8 @@ void BookInfoActivity::onEnter() {
title = fileName;
}
buildLayout(title, author, series, seriesIndex, description, language, fileSize);
buildLayout(title, author, series, seriesIndex, description, language, fileSize, publisher, date, subjects, rights,
contributor, identifier, rating);
requestUpdate();
}
@@ -137,9 +146,12 @@ void BookInfoActivity::onExit() { Activity::onExit(); }
void BookInfoActivity::buildLayout(const std::string& title, const std::string& author, const std::string& series,
const std::string& seriesIndex, const std::string& description,
const std::string& language, size_t fileSize) {
const std::string& language, size_t fileSize, const std::string& publisher,
const std::string& date, const std::string& subjects, const std::string& rights,
const std::string& contributor, const std::string& identifier,
const std::string& rating) {
const int contentW = renderer.getScreenWidth() - MARGIN * 2;
fields.reserve(6);
fields.reserve(13);
auto addField = [&](const char* label, const std::string& text, bool bold, EpdFontFamily::Style style) {
if (text.empty()) return;
@@ -161,12 +173,28 @@ void BookInfoActivity::buildLayout(const std::string& title, const std::string&
addField(tr(STR_SERIES), seriesStr, false, EpdFontFamily::REGULAR);
}
addField(tr(STR_PUBLISHER), publisher, false, EpdFontFamily::REGULAR);
addField(tr(STR_DATE), date, false, EpdFontFamily::REGULAR);
addField(tr(STR_SUBJECTS), subjects, false, EpdFontFamily::REGULAR);
if (!rating.empty()) {
int ratingVal = atoi(rating.c_str());
if (ratingVal > 0 && ratingVal <= 10) {
char ratingBuf[8];
snprintf(ratingBuf, sizeof(ratingBuf), "%d / 5", (ratingVal + 1) / 2);
addField(tr(STR_RATING), std::string(ratingBuf), false, EpdFontFamily::REGULAR);
}
}
addField(tr(STR_LANGUAGE), language, false, EpdFontFamily::REGULAR);
addField(tr(STR_ISBN), identifier, false, EpdFontFamily::REGULAR);
addField(tr(STR_CONTRIBUTOR), contributor, false, EpdFontFamily::REGULAR);
if (fileSize > 0) {
addField(tr(STR_FILE_SIZE), formatFileSize(fileSize), false, EpdFontFamily::REGULAR);
}
addField(tr(STR_RIGHTS), rights, false, EpdFontFamily::REGULAR);
addField(tr(STR_DESCRIPTION), description, false, EpdFontFamily::REGULAR);
const int lineH10 = renderer.getLineHeight(UI_10_FONT_ID);

View File

@@ -33,6 +33,8 @@ class BookInfoActivity final : public Activity {
void buildLayout(const std::string& title, const std::string& author, const std::string& series,
const std::string& seriesIndex, const std::string& description, const std::string& language,
size_t fileSize);
size_t fileSize, const std::string& publisher, const std::string& date,
const std::string& subjects, const std::string& rights, const std::string& contributor,
const std::string& identifier, const std::string& rating);
static std::string formatFileSize(size_t bytes);
};