Xteink-X4-crosspoint-reader/src/network/HttpDownloader.h
Justin Mitchell b792b792bf
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>
2026-01-07 19:58:37 +11:00

43 lines
1.1 KiB
C++

#pragma once
#include <SDCardManager.h>
#include <functional>
#include <string>
/**
* HTTP client utility for fetching content and downloading files.
* Wraps WiFiClientSecure and HTTPClient for HTTPS requests.
*/
class HttpDownloader {
public:
using ProgressCallback = std::function<void(size_t downloaded, size_t total)>;
enum DownloadError {
OK = 0,
HTTP_ERROR,
FILE_ERROR,
ABORTED,
};
/**
* Fetch text content from a URL.
* @param url The URL to fetch
* @param outContent The fetched content (output)
* @return true if fetch succeeded, false on error
*/
static bool fetchUrl(const std::string& url, std::string& outContent);
/**
* Download a file to the SD card.
* @param url The URL to download
* @param destPath The destination path on SD card
* @param progress Optional progress callback
* @return DownloadError indicating success or failure type
*/
static DownloadError downloadToFile(const std::string& url, const std::string& destPath,
ProgressCallback progress = nullptr);
private:
static constexpr size_t DOWNLOAD_CHUNK_SIZE = 1024;
};