Pulls RSS feeds from the last N hours, extracts full article text, builds one EPUB,
and pushes it to a Crosspoint
(Xteink X4) reader over WiFi via its /upload endpoint.
The Xteink X4 doesn't maintain a persisten WiFi connection (to save battery), so WiFi has to be enabled on the device when you want the EPUB to be published. Newspaper polls for the device to come online and pushes the EPUB once it is detected.
I was inspsired to build this by Jonas and his approach, but went a different direction as I don't use Feedbin and wanted to automate the EPUB -> device publishing.
Note
Make sure to set a static IP address for your Xteink device.
cp config.example.yaml config.yaml # fill in feeds + device host/IPDocker:
make upUses network_mode: host for mDNS/LAN reachability. If unsupported, drop that line
and use the device's IP instead of crosspoint.local.
Non-Docker (systemd):
python3 -m venv venv && ./venv/bin/pip install -r requirements.txt
sudo cp newspaper.service /etc/systemd/system/ # fix paths in the unit first
sudo systemctl enable --now newspaperOn the home screen, click File Transfer > Join a Network > Then connect to a network and stay on the screen
that shows a QR code with the "Open this URL in your browser or scan QR code with your phone"
Now, your Xteink is connected to WiFi and the code will be able to see your device and publish the newspaper EPUB to it.
--config PATH— defaultconfig.yaml--once— check once and exit (for cron instead of a long-running service)--force— ignore cooldown, push if device is online--build-only— build the EPUB tostate/, skip the device (for testing)
python -m src.main --config config.yaml --build-only| Key | Meaning |
|---|---|
feeds |
RSS/Atom feed URLs |
lookback_hours |
Only include posts published within this window |
device.host / port |
Crosspoint web server address |
device.poll_interval_seconds |
How often to check if device is online |
device.cooldown_seconds |
Min time between pushes |
output.state_dir |
Where EPUBs + state live |
extraction.skip_url_contains |
Skip links matching these (e.g. youtube.com) |
extraction.min_content_chars |
Below this, fall back to feed summary |
- No paywall/JS bypass — falls back to feed summary, skips if too short
- No read/unread tracking — same article can repeat across overlapping windows
/uploadhas no auth — trusted home network only

