mirror of
https://github.com/andwati/ftsync.git
synced 2026-10-18 09:22:53 +00:00
143 lines
3.5 KiB
Markdown
143 lines
3.5 KiB
Markdown
# ftsync
|
|
|
|
A terminal-based FTP sync tool built with Ratatui. Local directory is always
|
|
authoritative — new and modified files are uploaded to the server.
|
|
|
|
---
|
|
|
|
## Requirements
|
|
|
|
- Rust 1.80+ (install via [rustup](https://rustup.rs))
|
|
- OpenSSL development headers (for FTPS/TLS support)
|
|
|
|
```bash
|
|
# Debian / Ubuntu
|
|
sudo apt install libssl-dev pkg-config
|
|
|
|
# Arch
|
|
sudo pacman -S openssl
|
|
|
|
# Fedora
|
|
sudo dnf install openssl-devel
|
|
```
|
|
|
|
---
|
|
|
|
## Build
|
|
|
|
```bash
|
|
cargo build --release
|
|
# Binary: ./target/release/ftsync
|
|
```
|
|
|
|
Optionally install system-wide:
|
|
```bash
|
|
cargo install --path .
|
|
```
|
|
|
|
---
|
|
|
|
## Running
|
|
|
|
### Option A — environment variables (credentials never written to disk)
|
|
|
|
```bash
|
|
FTP_HOST=ftp.example.com \
|
|
FTP_USER=ian \
|
|
FTP_PASS=secret \
|
|
FTP_LOCAL=/home/ian/dist \
|
|
FTP_REMOTE=/public_html \
|
|
./target/release/ftsync
|
|
```
|
|
|
|
Full list of env vars:
|
|
|
|
| Variable | Description | Default |
|
|
|-------------|------------------------------------|---------|
|
|
| `FTP_HOST` | FTP server hostname or IP | — |
|
|
| `FTP_PORT` | FTP port | 21 |
|
|
| `FTP_USER` | FTP username | — |
|
|
| `FTP_PASS` | FTP password | — |
|
|
| `FTP_LOCAL` | Local directory to sync from | — |
|
|
| `FTP_REMOTE`| Remote directory to sync to | — |
|
|
| `FTP_TLS` | Enable FTPS/TLS (`1`/`true`/`yes`) | false |
|
|
|
|
### Option B — interactive config screen
|
|
|
|
Run `ftsync` with no env vars. A config form will appear. Fill in your
|
|
credentials and press **Enter** — they are saved to `~/.ftpsync.conf`.
|
|
|
|
---
|
|
|
|
## Keybindings
|
|
|
|
### Config screen
|
|
|
|
| Key | Action |
|
|
|------------------|-------------------------|
|
|
| `Tab` / `↓` | Next field |
|
|
| `Shift+Tab` / `↑`| Previous field |
|
|
| `Enter` | Save and go to sync |
|
|
| `q` / `Esc` | Quit |
|
|
|
|
### Sync screen
|
|
|
|
| Key | Action |
|
|
|-----|-----------------------------|
|
|
| `s` | Start sync |
|
|
| `d` | Dry run (preview only) |
|
|
| `c` | Back to config |
|
|
| `q` | Quit (or abort active sync) |
|
|
|
|
### Summary screen
|
|
|
|
| Key | Action |
|
|
|-----|-----------------|
|
|
| `s` | Sync again |
|
|
| `c` | Back to config |
|
|
| `q` | Quit |
|
|
|
|
---
|
|
|
|
## Config file
|
|
|
|
Stored at `~/.ftpsync.conf` (TOML). Environment variables always override
|
|
values in this file.
|
|
|
|
```toml
|
|
host = "ftp.example.com"
|
|
port = 21
|
|
user = "ian"
|
|
password = "secret"
|
|
local_dir = "/home/ian/dist"
|
|
remote_dir = "/public_html"
|
|
tls = false
|
|
excludes = [".git", "node_modules", "__pycache__", ".DS_Store", "Thumbs.db"]
|
|
```
|
|
|
|
---
|
|
|
|
## How sync works
|
|
|
|
1. Connects to the FTP server (plain or FTPS).
|
|
2. Recursively lists all files on the remote, recording their sizes.
|
|
3. Walks the local directory tree, skipping excluded patterns.
|
|
4. For each local file: if the remote file exists with the same byte size,
|
|
it is **skipped**. Otherwise it is **uploaded**.
|
|
5. Remote directories are created automatically as needed.
|
|
6. The sync task runs on a Tokio async thread; the Ratatui UI stays
|
|
responsive throughout via an `mpsc` channel.
|
|
|
|
---
|
|
|
|
## Project structure
|
|
|
|
```
|
|
src/
|
|
├── main.rs Terminal setup, Tokio event loop, keyboard handling
|
|
├── app.rs App state machine (screens, fields, sync state)
|
|
├── ftp.rs FTP/FTPS connection and sync engine (suppaftp)
|
|
├── ui.rs All Ratatui widget rendering (3 screens)
|
|
└── config.rs Config loading/saving, env var overlay
|
|
```
|