Calibre Web Epub Downloading + Calibre Wireless Device Syncing (#219)

## Summary

Adds support for browsing and downloading books from a Calibre-web
server via OPDS.
How it works
1. Configure server URL in Settings → Calibre Web URL (e.g.,
https://myserver.com:port I use Cloudflare tunnel to make my server
accessible anywhere fwiw)
2. "Calibre Library" will now show on the the home screen
3. Browse the catalog - navigate through categories like "By Newest",
"By Author", "By Series", etc.
4. Download books - select a book and press Confirm to download the EPUB
to your device
Navigation
- Up/Down - Move through entries
- Confirm - Open folder or download book
- Back - Go to parent catalog, or exit to home if at root
- Navigation entries show with > prefix, books show title and author
- Button hints update dynamically ("Open" for folders, "Download" for
books)
Technical details
- Fetches OPDS catalog from {server_url}/opds
- Parses both navigation feeds (catalog links) and acquisition feeds
(downloadable books)
- Maintains navigation history stack for back navigation
- Handles absolute paths in OPDS links correctly (e.g.,
/books/opds/navcatalog/...)
- Downloads EPUBs directly to the SD card root
Note
The server URL should be typed to include https:// if the server
requires it - HTTP→HTTPS redirects may cause SSL errors on ESP32.

## Additional Context

* I also changed the home titles to use uppercase for each word and
added a setting to change the size of the side margins

---------

Co-authored-by: Dave Allie <dave@daveallie.com>
This commit is contained in:
Justin Mitchell
2026-01-07 03:58:37 -05:00
committed by GitHub
parent afe9672156
commit b792b792bf
22 changed files with 2287 additions and 40 deletions

View File

@@ -0,0 +1,61 @@
#pragma once
#include <OpdsParser.h>
#include <freertos/FreeRTOS.h>
#include <freertos/semphr.h>
#include <freertos/task.h>
#include <functional>
#include <string>
#include <vector>
#include "../Activity.h"
/**
* Activity for browsing and downloading books from an OPDS server.
* Supports navigation through catalog hierarchy and downloading EPUBs.
*/
class OpdsBookBrowserActivity final : public Activity {
public:
enum class BrowserState {
CHECK_WIFI, // Checking WiFi connection
LOADING, // Fetching OPDS feed
BROWSING, // Displaying entries (navigation or books)
DOWNLOADING, // Downloading selected EPUB
ERROR // Error state with message
};
explicit OpdsBookBrowserActivity(GfxRenderer& renderer, MappedInputManager& mappedInput,
const std::function<void()>& onGoHome)
: Activity("OpdsBookBrowser", renderer, mappedInput), onGoHome(onGoHome) {}
void onEnter() override;
void onExit() override;
void loop() override;
private:
TaskHandle_t displayTaskHandle = nullptr;
SemaphoreHandle_t renderingMutex = nullptr;
bool updateRequired = false;
BrowserState state = BrowserState::LOADING;
std::vector<OpdsEntry> entries;
std::vector<std::string> navigationHistory; // Stack of previous feed paths for back navigation
std::string currentPath; // Current feed path being displayed
int selectorIndex = 0;
std::string errorMessage;
std::string statusMessage;
size_t downloadProgress = 0;
size_t downloadTotal = 0;
const std::function<void()> onGoHome;
static void taskTrampoline(void* param);
[[noreturn]] void displayTaskLoop();
void render() const;
void checkAndConnectWifi();
void fetchFeed(const std::string& path);
void navigateToEntry(const OpdsEntry& entry);
void navigateBack();
void downloadBook(const OpdsEntry& book);
};