···2233# spacebee
4455-A WebDAV shim for syncing [Moon+ Reader](https://www.moondownload.com) reading position. Translates
66-the `.po` position files into ATProto reads/writes on your
77-[bookhive.buzz](https://bookhive.buzz) book records.
55+Sync [Moon+ Reader](https://www.moondownload.com) reading position to your Atmosphere account and share your progress on [bookhive.buzz](bookhive.buzz).
8699-```json
1010-{
1111- "$type": "buzz.bookhive.book",
1212- "bookProgress": {
1313- "percent": 11,
1414- "updatedAt": "2026-04-17T10:01:24.000Z",
1515- "moonReader": {
1616- "file": "The Necromancers House - Buehlman Christopher.epub.po",
1717- "position": "1703297605115*21@0#4826:11.1%",
1818- "syncedAt": "2026-04-17T10:01:24.000Z"
1919- },
2020- "currentChapter": 22
2121- }
2222-}
77+It also serves a simple web page showing your reading status:
88+<img src="sshot_spacebee.png">
99+1010+> 🚨 *This is vibecoded, I don't know much Python but it works 👍️*
1111+1212+## How to use
1313+Spacebee 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:
1414+1515+<img src="sshot_moonreader.webp">
1616+1717+### Running locally
1818+1919+```sh
2020+cp .env.example .env
2121+uv sync --extra dev
2222+uv run uvicorn spacebee.main:app --reload --port 8080
2323```
24242525-Also serves a static page showing your reading progress.
2525+Point a test device at `http://<wherever>:8080/` as the WebDAV target.
2626+2727+### Docker
26282727-> 🚨 *This is vibecoded, I don't know what I'm doing but it works 👍️*
2929+Copy compose file, fill in a `.env`, run:
3030+3131+```sh
3232+curl -O https://raw.githubusercontent.com/oakbrad/spacebee/main/docker-compose.yml
3333+curl -O https://raw.githubusercontent.com/oakbrad/spacebee/main/.env.example
3434+mv .env.example .env # then edit with your creds
3535+docker compose up -d
3636+```
3737+3838+By default it listens on `127.0.0.1:8080`.
3939+4040+### Configuration
4141+4242+Copy `.env.example` to `.env` and fill in:
4343+4444+| Var | Purpose |
4545+| --- | --- |
4646+| `BSKY_HANDLE` | The handle spacebee writes records as |
4747+| `BSKY_APP_PASSWORD` | An app password for that handle |
4848+| `DAV_USER` / `DAV_PASSWORD` | Basic-auth credentials Moon+ Reader will send |
4949+| `PASSTHROUGH_ROOT` | Local-disk scratch dir for non-`.po` paths |
5050+| `PDS` | *Optional.* If unset, resolved from the handle. |
28512952## How it works
3053···5073cover-image blob proxy at `/blob/{cid}` are public; all WebDAV endpoints are
5174gated by HTTP Basic.
52755353-## Configuration
7676+### Record
54775555-Copy `.env.example` to `.env` and fill in:
5656-5757-| Var | Purpose |
5858-| --- | --- |
5959-| `BSKY_HANDLE` | The handle spacebee writes records as |
6060-| `BSKY_APP_PASSWORD` | An [app password] for that handle |
6161-| `DAV_USER` / `DAV_PASSWORD` | Basic-auth credentials Moon+ Reader will send |
6262-| `PASSTHROUGH_ROOT` | Local-disk scratch dir for non-`.po` paths |
6363-| `PDS` | *Optional.* If unset, resolved from the handle. |
6464-6565-## Running locally
6666-6767-```sh
6868-cp .env.example .env
6969-uv sync --extra dev
7070-uv run uvicorn spacebee.main:app --reload --port 8080
7878+```json
7979+{
8080+ "$type": "buzz.bookhive.book",
8181+ "bookProgress": {
8282+ "percent": 11,
8383+ "updatedAt": "2026-04-17T10:01:24.000Z",
8484+ "moonReader": {
8585+ "file": "The Necromancers House - Buehlman Christopher.epub.po",
8686+ "position": "1703297605115*21@0#4826:11.1%",
8787+ "syncedAt": "2026-04-17T10:01:24.000Z"
8888+ },
8989+ "currentChapter": 22
9090+ }
9191+}
7192```
72937373-Point a test device at `http://<your-laptop>:8080/` as the WebDAV target.
74947595## Related
7696