Files
image-drop/README.md

136 lines
4.8 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# File Drop Uploader
A tiny web app for collecting files and media and saving them to the local filesystem.
Admin users log in to create public invite links; invite links are always public-by-URL. A public uploader page is optional and enabled by default.
Forked from "Immich Drop Uploader": https://github.com/Nasogaa/immich-drop
![File Drop Uploader Dark Mode UI](./screenshot.png)
## Features
- **Local Saving:** All uploaded files are saved to the local filesystem.
- **Invite Links:** Create public-by-URL links for uploads; one-time or multi-use.
- **Manage Links:** Search/sort, enable/disable, delete, edit name/expiry.
- **Passwords (optional):** Protect invites with a password gate.
- **Albums:** Upload into a specific folder (auto-create supported). Preserves client-side folder structure on upload.
- **Duplicate Prevention:** Local SHA1 cache prevents re-uploading the same file.
- **Telegram Notifications (optional):** Get notified via Telegram when upload batches are complete.
- **Progress Queue:** WebSocket updates; see upload progress in real-time.
- **Chunked Uploads (optional):** Large-file support with configurable chunk size.
- **Mobile + Dark Mode:** Responsive UI, safe-area padding, persistent theme.
## Quick start
Clone the repo.
Copy `.env.example` to `.env` and edit.
### docker-compose.yml
```yaml
services:
file-drop:
build: .
container_name: file-drop
restart: unless-stopped
ports:
- "8080:8080"
env_file:
- .env
volumes:
- ./data:/file_drop/data
- /mnt/example/file-drop:/file_drop/data/uploads
healthcheck:
test: ["CMD-SHELL", "python - <<'PY'\nimport urllib.request,sys\ntry:\n urllib.request.urlopen('http://localhost:8080/').read(); sys.exit(0)\nexcept Exception:\n sys.exit(1)\nPY"]
interval: 30s
timeout: 5s
retries: 3
start_period: 10s
```
```bash
$ sudo docker compose up --build -d
```
### Chunked Uploads
- Chunked uploads are enabled by default. Uses setting `CHUNKED_UPLOADS_ENABLED=true`.
- Configure chunk size with `CHUNK_SIZE_MB` (default: `50`). The client only uses chunked mode for files larger than this.
- Intended to bypass upstream proxy limits (e.g., 100MB) while preserving duplicate checks, EXIF timestamps, album add, and peritem progress via WebSocket.
## Developtment
### Architecture
- **Frontend:** static HTML/JS (Tailwind). Drag & drop or "Choose files", queue UI with progress and status chips.
- **Backend:** FastAPI + Uvicorn.
- Saves uploaded files to the local filesystem.
- Computes SHA1 and checks a local SQLite cache (`state.db`) to prevent duplicates.
- WebSocket `/ws` pushes peritem progress to the current browser session only.
- **Persistence:** A local SQLite database (`state.db`) prevents reuploads across sessions. Uploaded files are stored in `/data/uploads`.
### Requirements
- **Python** 3.11
### Local dev quickstart
Run with live reload:
```bash
python main.py
```
The backend contains docstrings so you can generate docs later if desired.
### Dev Configuration (.env)
```ini
# Server (dev only)
HOST=0.0.0.0
PORT=8080
# Public uploader page (optional) — disabled by default
PUBLIC_UPLOAD_PAGE_ENABLED=TRUE
# Local dedupe cache (SQLite)
STATE_DB=./data/state.db
# Telegram Bot for notifications (optional)
#TELEGRAM_BOT_API_KEY=
#TELEGRAM_BOT_OWNER_ID=
# Base URL for generating absolute invite links (recommended for production)
# e.g., PUBLIC_BASE_URL=https://photos.example.com
#PUBLIC_BASE_URL=
# Session and security
SESSION_SECRET=SET-A-STRONG-RANDOM-VALUE
LOG_LEVEL=DEBUG
# Chunked uploads (optional)
CHUNKED_UPLOADS_ENABLED=true
CHUNK_SIZE_MB=95
```
You can keep a checkedin `/.env.example` with the keys above for onboarding.
### How it works
1. **Queue** Files selected in the browser are queued; each gets a client-side ID.
2. **De-dupe (local)** Server computes **SHA1** and checks `state.db`. If seen, marks as **duplicate**.
3. **Save** The file is saved to the local filesystem under `./data/uploads`.
4. **Album** If an album is specified via an invite link, or a folder name is provided on the public page, the file is saved into a corresponding subdirectory. Client-side folder structure is also preserved.
5. **Progress** Backend streams progress via WebSocket to the same session.
6. **Privacy** The UI shows only the current session's items. It does not provide a way to browse saved files.
### Security notes
- The menu and invite creation are behind login. Logout clears the session.
- Invite links are public by URL; share only with intended recipients.
- The default uploader page at `/` is disabled unless `PUBLIC_UPLOAD_PAGE_ENABLED=true`.
- No browsing of uploaded media; only ephemeral session state is shown.
- Run behind HTTPS with a reverse proxy and restrict CORS to your domain(s).