Metadata-Version: 2.4
Name: SyncTwink
Version: 0.2.0
Summary: A skinny but powerful, self-hosted file sync across your devices over a Tailscale tailnet.
Author: Jake
License: MIT
Keywords: webdav,syncthing,tailscale,file-sync,self-hosted
Requires-Python: >=3.9
Description-Content-Type: text/markdown
License-File: LICENSE
Requires-Dist: WsgiDAV>=4.3.0
Requires-Dist: cheroot>=10.0.0
Requires-Dist: PyYAML>=6.0
Requires-Dist: requests>=2.28
Provides-Extra: dev
Requires-Dist: pytest>=7.0; extra == "dev"
Dynamic: license-file

# SyncTwink

A skinny but powerful, self-hosted file sync across your devices over a [Tailscale](https://tailscale.com) tailnet.

Two always-on servers (e.g. a **Raspberry Pi** and a **Mac Mini**) each expose
the *same* folder over **WebDAV** for iOS Files and other clients, while
**Syncthing** keeps the two copies replicated. Either server can go offline and
your files stay reachable from the other.

```
        Tailnet (WireGuard, end-to-end encrypted)
   ┌──────────────────────────────────────────────────┐
   │                                                    │
┌──┴──────────────┐   Syncthing replication   ┌─────────┴───────┐
│  Raspberry Pi   │ <───────────────────────> │    Mac Mini     │
│  • Tailscale    │                            │  • Tailscale    │
│  • WebDAV :8080 │                            │  • WebDAV :8080 │
│  • Syncthing    │                            │  • Syncthing    │
└──┬──────────────┘                            └─────────┬───────┘
   │                                                     │
   │            WebDAV over Tailscale (HTTP/HTTPS)       │
   └──────────────────────┬──────────────────────────────┘
                          │
            ┌─────────────┴─────────────┐
            │  iPhone / iPad Files app  │  ← connects to whichever
            │  Mac / other devices      │     server is reachable
            └───────────────────────────┘
```

SyncTwink is the glue: a small Python package + CLI you install on **each
server**. It configures the WebDAV service (via [WsgiDAV](https://wsgidav.readthedocs.io/)),
sets up the Syncthing shared folder, and optionally fronts WebDAV with HTTPS
using `tailscale serve`.

## What it does

- **WebDAV server** backed by WsgiDAV + cheroot, serving one folder with
  per-user auth (basic + digest). Works with iOS Files, macOS Finder, and any
  WebDAV client.
- **Syncthing replication** between the two servers, configured for you via
  Syncthing's REST API (adds the folder, pairs peers, enables file versioning).
- **Native services** — installed as a `systemd` unit on Linux or a `launchd`
  agent/daemon on macOS, so WebDAV starts on boot and restarts on failure.
- **Tailscale-aware** — reads your tailnet status to print the right
  connection URLs and can expose WebDAV over HTTPS with a valid MagicDNS cert.

SyncTwink assumes Tailscale is already installed and `tailscale up` has been
run on each machine. It does **not** manage the tailnet itself.

## Quick start (run on *each* server)

```bash
# 1. Install the CLI (pick one)
pipx install SyncTwink
# or from source:
# pipx install git+https://github.com/jchaselubitz/synctwink.git
# pipx install .                  # from a git clone

# 2. Create a config (generates a WebDAV password for you)
sudo synctwink init --user jake --data-dir /srv/synctwink/data

# 3. Find this machine's Syncthing device id (after Syncthing has run once)
synctwink syncthing id
```

Put **each server's** device id into the **other server's** config under
`syncthing.peers`, then on both machines:

```bash
sudo synctwink install     # installs deps, configures Syncthing, starts WebDAV
synctwink status           # health check + connection URLs
```

See [`docs/INSTALL.md`](docs/INSTALL.md) for the full walkthrough and
[`docs/IOS.md`](docs/IOS.md) for connecting the iPhone Files app.

## CLI

| Command | What it does |
| --- | --- |
| `synctwink init` | Write a config file (with a generated password). |
| `synctwink install` | Full setup: deps, Syncthing folder/peers, WebDAV service, HTTPS. |
| `synctwink serve` | Run the WebDAV server in the foreground (used by the service). |
| `synctwink status` | Show Tailscale / WebDAV / Syncthing health + URLs. |
| `synctwink info` | Print client connection details (for iOS Files etc.). |
| `synctwink syncthing id` | Print this node's Syncthing device id. |
| `synctwink syncthing pair <id>` | Add a peer and share the folder with it. |
| `synctwink syncthing configure` | Re-apply folder + peers from config. |
| `synctwink sync` | Wake Syncthing, pull/push now, re-quiet on battery (for laptops). |
| `synctwink pause` / `synctwink resume` | Stop / start peer syncing. |
| `synctwink service restart` | Restart the WebDAV service. |
| `synctwink uninstall` | Remove the WebDAV service and reset `tailscale serve`. |

For an **often-offline laptop** that wants offline files without burning
battery, see [`docs/LAPTOP.md`](docs/LAPTOP.md): join it as a Syncthing peer,
pause on battery, and use `synctwink sync` to pull changes on demand.

## Configuration

A single YAML file. Default location is `/etc/synctwink/config.yaml` (root) or
`~/.config/synctwink/config.yaml`. Override with `--config` or `SYNCTWINK_CONFIG`.
See [`synctwink/templates/config.example.yaml`](synctwink/templates/config.example.yaml).

The config holds plaintext WebDAV passwords and is written `0600`. Because all
traffic rides the encrypted tailnet, HTTP basic auth is safe here.

## Requirements

- Python 3.9+
- Tailscale (installed + `tailscale up` already done)
- Syncthing (auto-installed via `apt`/`dnf`/`pacman`/`brew` if missing)
- A Linux host with `systemd`, or macOS with `launchd`

## Architecture & design notes

See [`docs/ARCHITECTURE.md`](docs/ARCHITECTURE.md).

## License

MIT — see [LICENSE](LICENSE).
