Sync reading position from Moon Reader app to Bookhive atproto records
atproto bookhive ereader moonreader
3
fork

Configure Feed

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

at main 99 lines 3.2 kB view raw view rendered
1<img src="icon.png" alt="spacebee" width="160" align="right"> 2 3# spacebee 4 5Sync [Moon+ Reader](https://www.moondownload.com) reading position to your Atmosphere account and share your progress on [bookhive.buzz](bookhive.buzz). 6 7It also serves a simple web page showing your reading status: 8<img src="sshot_spacebee.png"> 9 10> 🚨 *This is vibecoded, I don't know much Python but it works 👍️* 11 12## How to use 13Spacebee pretends to be WebDAV but reads and writes from your Atmosphere account. In the Moon Reader app, go to `Options->Sync with WebDAV` and point it to spacebee: 14 15<img src="sshot_moonreader.webp"> 16 17### Running locally 18 19```sh 20cp .env.example .env 21uv sync --extra dev 22uv run uvicorn spacebee.main:app --reload --port 8080 23``` 24 25Point a test device at `http://<wherever>:8080/` as the WebDAV target. 26 27### Docker 28 29Copy compose file, fill in a `.env`, run: 30 31```sh 32curl -O https://raw.githubusercontent.com/oakbrad/spacebee/main/docker-compose.yml 33curl -O https://raw.githubusercontent.com/oakbrad/spacebee/main/.env.example 34mv .env.example .env # then edit with your creds 35docker compose up -d 36``` 37 38By default it listens on `127.0.0.1:8080`. 39 40### Configuration 41 42Copy `.env.example` to `.env` and fill in: 43 44| Var | Purpose | 45| --- | --- | 46| `BSKY_HANDLE` | The handle spacebee writes records as | 47| `BSKY_APP_PASSWORD` | An app password for that handle | 48| `DAV_USER` / `DAV_PASSWORD` | Basic-auth credentials Moon+ Reader will send | 49| `PASSTHROUGH_ROOT` | Local-disk scratch dir for non-`.po` paths | 50| `PDS` | *Optional.* If unset, resolved from the handle. | 51 52## How it works 53 54```mermaid 55graph LR 56 MR[Moon+ Reader] -->|"WebDAV: PROPFIND / GET / PUT"| SB[spacebee] 57 SB -->|"buzz.bookhive.book"| PDS[ATProto PDS] 58``` 59 60- `PROPFIND /Books/.Moon+/Cache/` synthesizes a directory listing from your 61 `buzz.bookhive.book` records that have a `bookProgress.moonReader.file` 62 field. 63- `GET /Books/.Moon+/Cache/{file}.po` returns the stored position string 64 verbatim (preserves Moon+ Reader's internal chapter/offset encoding). 65- `PUT /Books/.Moon+/Cache/{file}.po` parses the `.po` body, finds the 66 matching bookhive record (or catalog-searches and creates one), and 67 updates `bookProgress.{percent,currentChapter,moonReader}` on your PDS. 68 69Non-position WebDAV paths (`Books/.Moon+/Settings/`, backups, etc.) fall through to a local-disk scratch area rooted at `$PASSTHROUGH_ROOT`. 70 71spacebee also serves a small read-only HTML dashboard at `/` that renders 72your bookhive records (currently-reading, finished, etc.). The dashboard and 73cover-image blob proxy at `/blob/{cid}` are public; all WebDAV endpoints are 74gated by HTTP Basic. 75 76### Record 77 78```json 79{ 80 "$type": "buzz.bookhive.book", 81 "bookProgress": { 82 "percent": 11, 83 "updatedAt": "2026-04-17T10:01:24.000Z", 84 "moonReader": { 85 "file": "The Necromancers House - Buehlman Christopher.epub.po", 86 "position": "1703297605115*21@0#4826:11.1%", 87 "syncedAt": "2026-04-17T10:01:24.000Z" 88 }, 89 "currentChapter": 22 90 } 91} 92``` 93 94 95## Related 96 97- [bookhive.buzz](https://bookhive.buzz) — the AT Protocol book tracker whose records spacebee 98 reads and writes. 99- [Moon+ Reader](https://www.moondownload.com/) - Android eReader app