A fork of https://github.com/crosspoint-reader/crosspoint-reader
0
fork

Configure Feed

Select the types of activity you want to include in your feed.

at records-reader 110 lines 2.9 kB view raw
1#pragma once 2#include <Print.h> 3#include <expat.h> 4 5#include <string> 6#include <vector> 7 8/** 9 * Type of OPDS entry. 10 */ 11enum class OpdsEntryType { 12 NAVIGATION, // Link to another catalog 13 BOOK // Downloadable book 14}; 15 16/** 17 * Represents an entry from an OPDS feed (either a navigation link or a book). 18 */ 19struct OpdsEntry { 20 OpdsEntryType type = OpdsEntryType::NAVIGATION; 21 std::string title; 22 std::string author; // Only for books 23 std::string href; // Navigation URL or epub download URL 24 std::string id; 25}; 26 27// Legacy alias for backward compatibility 28using OpdsBook = OpdsEntry; 29 30/** 31 * Parser for OPDS (Open Publication Distribution System) Atom feeds. 32 * Uses the Expat XML parser to parse OPDS catalog entries. 33 * 34 * Usage: 35 * OpdsParser parser; 36 * if (parser.parse(xmlData, xmlLength)) { 37 * for (const auto& entry : parser.getEntries()) { 38 * if (entry.type == OpdsEntryType::BOOK) { 39 * // Downloadable book 40 * } else { 41 * // Navigation link to another catalog 42 * } 43 * } 44 * } 45 */ 46class OpdsParser final : public Print { 47 public: 48 OpdsParser(); 49 ~OpdsParser(); 50 51 // Disable copy 52 const std::string& getSearchTemplate() const { return searchTemplate; } 53 const std::string& getNextPageUrl() const { return nextPageUrl; } 54 const std::string& getPrevPageUrl() const { return prevPageUrl; } 55 OpdsParser(const OpdsParser&) = delete; 56 OpdsParser& operator=(const OpdsParser&) = delete; 57 58 size_t write(uint8_t) override; 59 size_t write(const uint8_t*, size_t) override; 60 61 void flush() override; 62 63 bool error() const; 64 65 operator bool() { return !error(); } 66 67 /** 68 * Get the parsed entries (both navigation and book entries). 69 * @return Vector of OpdsEntry entries 70 */ 71 const std::vector<OpdsEntry>& getEntries() const& { return entries; } 72 std::vector<OpdsEntry> getEntries() && { return std::move(entries); } 73 74 /** 75 * Get only book entries (legacy compatibility). 76 * @return Vector of book entries 77 */ 78 std::vector<OpdsEntry> getBooks() const; 79 80 /** 81 * Clear all parsed entries. 82 */ 83 void clear(); 84 85 private: 86 // Expat callbacks 87 static void XMLCALL startElement(void* userData, const XML_Char* name, const XML_Char** atts); 88 static void XMLCALL endElement(void* userData, const XML_Char* name); 89 static void XMLCALL characterData(void* userData, const XML_Char* s, int len); 90 91 std::string searchTemplate; 92 std::string nextPageUrl; 93 std::string prevPageUrl; 94 // Helper to find attribute value 95 static const char* findAttribute(const XML_Char** atts, const char* name); 96 97 XML_Parser parser = nullptr; 98 std::vector<OpdsEntry> entries; 99 OpdsEntry currentEntry; 100 std::string currentText; 101 102 // Parser state 103 bool inEntry = false; 104 bool inTitle = false; 105 bool inAuthor = false; 106 bool inAuthorName = false; 107 bool inId = false; 108 109 bool errorOccured = false; 110};