From a7aa4c55d89a616bbc81d9542f45ff24bfacfef5 Mon Sep 17 00:00:00 2001 From: jpirnay Date: Wed, 20 May 2026 18:46:11 +0200 Subject: [PATCH] fix: Prefer epub format over derived formats when downloading from opds server (#1480) ## Summary * **What is the goal of this PR?** Prefer epub format over kepub or other formats offered from an OPDS server * **What changes are included?** ## Additional Context Should address #1419 --- ### AI Usage While CrossPoint doesn't have restrictions on AI tools in contributing, please be transparent about their usage as it helps set the right context for reviewers. Did you use AI tools to help write this code? _**< NO >**_ --------- Co-authored-by: Arthur Tazhitdinov --- lib/OpdsParser/OpdsParser.cpp | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/lib/OpdsParser/OpdsParser.cpp b/lib/OpdsParser/OpdsParser.cpp index ef769f11..af619d1c 100644 --- a/lib/OpdsParser/OpdsParser.cpp +++ b/lib/OpdsParser/OpdsParser.cpp @@ -110,8 +110,16 @@ void XMLCALL OpdsParser::startElement(void* userData, const XML_Char* name, cons if (self->inEntry) { if (rel && type && strstr(rel, "opds-spec.org/acquisition") != nullptr && strcmp(type, "application/epub+zip") == 0) { - self->currentEntry.type = OpdsEntryType::BOOK; - self->currentEntry.href = href; + // Prefer plain EPUB links over derived formats when multiple + // acquisition links are present for one entry. + const bool isPlainEpub = strstr(href, ".epub") != nullptr || strstr(href, "/epub/") != nullptr; + const bool alreadyHasPlainEpub = self->currentEntry.type == OpdsEntryType::BOOK && + (self->currentEntry.href.find(".epub") != std::string::npos || + self->currentEntry.href.find("/epub/") != std::string::npos); + if (self->currentEntry.type != OpdsEntryType::BOOK || (isPlainEpub && !alreadyHasPlainEpub)) { + self->currentEntry.type = OpdsEntryType::BOOK; + self->currentEntry.href = href; + } } else if (type && strstr(type, "application/atom+xml") != nullptr) { if (self->currentEntry.type != OpdsEntryType::BOOK) { self->currentEntry.type = OpdsEntryType::NAVIGATION;