Files
Maxx Cherevko bcf4353722 first commit
2026-04-30 08:40:34 +02:00

70 lines
2.5 KiB
Markdown

# Downloads Auto-Uploader
Watches your `~/Downloads` folder and automatically syncs new or changed files to a remote server over SSH/rsync. Runs every 5 minutes as a macOS launchd agent.
## How it works
1. SSHes into the remote host and indexes the destination directory (`find` with sizes)
2. Walks the local scan directory and compares files by size
3. Uploads only what is missing or has a different size, preserving directory structure
4. Logs every action to `uploader_log.txt` and records successful uploads in `.uploader_state.json`
Files are skipped if they:
- Match a skip pattern (hidden files, `.crdownload`, `.part`, `.tmp`, etc.)
- Were modified less than 30 seconds ago (still being written)
- Already exist on the remote with the same size
## Requirements
- macOS (uses launchd)
- `python3` (built-in on macOS, or `brew install python`)
- `rsync` (`brew install rsync` recommended — macOS ships an outdated version)
- SSH key-based access to the remote host (no password prompts)
## Quick start
See [INSTALL.md](INSTALL.md).
## Configuration
Edit `downloads_uploader_config.json`:
| Key | Default | Description |
|-----|---------|-------------|
| `remote_destination` | `filez@10.10.8.1:/mnt/ssd2t/shared/torrent/Downloads/` | `user@host:/path` on the remote |
| `ssh_key_path` | `""` | Path to SSH private key; empty = system default (`~/.ssh/id_rsa`) |
| `ssh_port` | `22` | SSH port |
| `scan_directory` | `""` | Directory to watch; empty = parent of `uploader/` folder |
| `skip_patterns` | see config | Shell glob patterns for files/dirs to ignore |
| `min_file_age_seconds` | `30` | Skip files newer than this (still being downloaded) |
| `timeout_seconds` | `7200` | Per-file rsync timeout (2 hours) |
| `remote_scan_timeout` | `120` | Timeout for the remote `find` command |
| `dry_run` | `false` | Log what would be uploaded without transferring anything |
## Files
```
uploader/
downloads_uploader.py # main sync script
downloads_uploader_install.sh # launchd installer
downloads_uploader_config.json # configuration
.uploader_state.json # upload audit log (auto-created)
uploader_log.txt # application log (auto-created)
uploader_stdout.log # launchd stdout (auto-created)
uploader_stderr.log # launchd stderr (auto-created)
```
## Manual usage
```bash
# Run once right now
./downloads_uploader_install.sh run
# Dry run (no transfers)
# Set "dry_run": true in config, then:
./downloads_uploader_install.sh run
# Check agent status + recent log
./downloads_uploader_install.sh status
```