docs: Update README for local file saving and Telegram notifications
Co-authored-by: aider (gemini/gemini-2.5-pro) <aider@aider.chat>
This commit is contained in:
102
README.md
102
README.md
@@ -1,22 +1,22 @@
|
|||||||
# Immich Drop Uploader
|
# File Drop Uploader
|
||||||
|
|
||||||
A tiny web app for collecting photos/videos into your **Immich** server.
|
A tiny web app for collecting photos/videos 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 disabled by default.
|
Admin users log in to create public invite links; invite links are always public-by-URL. A public uploader page is optional and disabled by default.
|
||||||
|
|
||||||

|

|
||||||
|
|
||||||
## Features
|
## Features
|
||||||
|
|
||||||
- **Invite Links:** public-by-URL links for uploads; one-time or multi-use
|
- **Local Saving:** All uploaded files are saved to the local filesystem.
|
||||||
- **Manage Links:** search/sort, enable/disable, delete, edit name/expiry
|
- **Invite Links:** Create public-by-URL links for uploads; one-time or multi-use.
|
||||||
- **Row Actions:** icon-only actions with tooltips (Open, Copy, Details, QR, Save)
|
- **Manage Links:** Search/sort, enable/disable, delete, edit name/expiry.
|
||||||
- **Passwords (optional):** protect invites with a password gate
|
- **Passwords (optional):** Protect invites with a password gate.
|
||||||
- **Albums (optional):** upload into a specific album (auto-create supported)
|
- **Albums:** Upload into a specific folder (auto-create supported). Preserves client-side folder structure on upload.
|
||||||
- **Duplicate Prevention:** local SHA‑1 cache (+ optional Immich bulk-check)
|
- **Duplicate Prevention:** Local SHA‑1 cache prevents re-uploading the same file.
|
||||||
- **Progress Queue:** WebSocket updates; retry failed items
|
- **Telegram Notifications:** Get notified via Telegram when upload batches are complete.
|
||||||
- **Chunked Uploads (optional):** large-file support with configurable chunk size
|
- **Progress Queue:** WebSocket updates; see upload progress in real-time.
|
||||||
- **Privacy-first:** never lists server media; session-local uploads only
|
- **Chunked Uploads (optional):** Large-file support with configurable chunk size.
|
||||||
- **Mobile + Dark Mode:** responsive UI, safe-area padding, persistent theme
|
- **Mobile + Dark Mode:** Responsive UI, safe-area padding, persistent theme.
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
@@ -54,15 +54,14 @@ services:
|
|||||||
# Configure all settings here (no .env required)
|
# Configure all settings here (no .env required)
|
||||||
environment:
|
environment:
|
||||||
|
|
||||||
# Immich connection (must include /api)
|
|
||||||
IMMICH_BASE_URL: https://immich.example.com/api
|
|
||||||
IMMICH_API_KEY: ${IMMICH_API_KEY}
|
|
||||||
|
|
||||||
# Optional behavior
|
# Optional behavior
|
||||||
IMMICH_ALBUM_NAME: dead-drop
|
|
||||||
PUBLIC_UPLOAD_PAGE_ENABLED: "false" # keep disabled by default
|
PUBLIC_UPLOAD_PAGE_ENABLED: "false" # keep disabled by default
|
||||||
PUBLIC_BASE_URL: https://drop.example.com
|
PUBLIC_BASE_URL: https://drop.example.com
|
||||||
|
|
||||||
|
# Telegram Bot for notifications (optional)
|
||||||
|
#TELEGRAM_BOT_API_KEY: "YOUR_BOT_API_KEY"
|
||||||
|
#TELEGRAM_BOT_OWNER_ID: "YOUR_TELEGRAM_USER_ID"
|
||||||
|
|
||||||
# Large files: chunked uploads (bypass 100MB proxy limits)
|
# Large files: chunked uploads (bypass 100MB proxy limits)
|
||||||
CHUNKED_UPLOADS_ENABLED: "false" # enable chunked uploads
|
CHUNKED_UPLOADS_ENABLED: "false" # enable chunked uploads
|
||||||
CHUNK_SIZE_MB: "95" # per-chunk size (MB)
|
CHUNK_SIZE_MB: "95" # per-chunk size (MB)
|
||||||
@@ -98,62 +97,22 @@ docker compose up -d
|
|||||||
```
|
```
|
||||||
---
|
---
|
||||||
|
|
||||||
## What's New
|
|
||||||
|
|
||||||
### v0.5.0 – Manage Links overhaul
|
|
||||||
- In-panel bulk actions footer (Delete/Enable/Disable stay inside the box)
|
|
||||||
- Per-row icon actions with tooltips; Save button lights up only on changes
|
|
||||||
- Per-row QR modal; Details modal close fixed and reliable
|
|
||||||
- Auto-refresh after creating a link; new row is highlighted and scrolled into view
|
|
||||||
- Expiry save fix: stores end-of-day to avoid off-by-one date issues
|
|
||||||
|
|
||||||
Roadmap highlight
|
|
||||||
- We’d like to add a per-user UI and remove reliance on a fixed API key by allowing users to authenticate and provide their own Immich API tokens. This is not in scope for the initial versions but aligns with future direction.
|
|
||||||
- The frontend automatically switches to chunked mode only for files larger than the configured chunk size.
|
|
||||||
|
|
||||||
### 📱 Device‑Flexible HMI (New)
|
|
||||||
- Fully responsive UI with improved spacing and wrapping for small and large screens.
|
|
||||||
- Mobile‑safe file picker and a sticky bottom “Choose files” bar on phones.
|
|
||||||
- Safe‑area padding for devices with notches; refined dark/light theme behavior.
|
|
||||||
- Desktop keeps the dropzone clickable; touch devices avoid accidental double‑open.
|
|
||||||
|
|
||||||
### ♻️ Reliability & Quality of Life (New)
|
|
||||||
- Retry button to re‑attempt any failed upload without re‑selecting the file.
|
|
||||||
- Progress and status updates are more resilient to late/reordered WebSocket events.
|
|
||||||
- Invites can be created without an album, keeping uploads unassigned when preferred.
|
|
||||||
|
|
||||||
### Last 8 Days – Highlights
|
|
||||||
- Added chunked uploads with configurable chunk size.
|
|
||||||
- Added optional passwords for invite links with in‑UI unlock prompt.
|
|
||||||
- Responsive HMI overhaul: mobile‑safe picker, sticky mobile action bar, safe‑area support.
|
|
||||||
- Retry for failed uploads and improved progress handling.
|
|
||||||
- Support for invites with no album association.
|
|
||||||
|
|
||||||
### 🌙 Dark Mode
|
|
||||||
- Automatic or manual toggle; persisted preference
|
|
||||||
|
|
||||||
### 📁 Album Integration
|
|
||||||
- Auto-create + assign album if configured; optional invites without album
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## Chunked Uploads
|
## Chunked Uploads
|
||||||
|
|
||||||
- Enable chunked uploads by setting `CHUNKED_UPLOADS_ENABLED=true`.
|
- Enable chunked uploads by setting `CHUNKED_UPLOADS_ENABLED=true`.
|
||||||
- Configure chunk size with `CHUNK_SIZE_MB` (default: `95`). The client only uses chunked mode for files larger than this.
|
- Configure chunk size with `CHUNK_SIZE_MB` (default: `95`). The client only uses chunked mode for files larger than this.
|
||||||
- Intended to bypass upstream limits (e.g., 100MB) while preserving duplicate checks, EXIF timestamps, album add, and per‑item progress via WebSocket.
|
- Intended to bypass upstream proxy limits (e.g., 100MB) while preserving duplicate checks, EXIF timestamps, album add, and per‑item progress via WebSocket.
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
## Architecture
|
## Architecture
|
||||||
|
|
||||||
- **Frontend:** static HTML/JS (Tailwind). Drag & drop or "Choose files", queue UI with progress and status chips.
|
- **Frontend:** static HTML/JS (Tailwind). Drag & drop or "Choose files", queue UI with progress and status chips.
|
||||||
- **Backend:** FastAPI + Uvicorn.
|
- **Backend:** FastAPI + Uvicorn.
|
||||||
- Proxies uploads to Immich `/assets`
|
- Saves uploaded files to the local filesystem.
|
||||||
- Computes SHA‑1 and checks a local SQLite cache (`state.db`)
|
- Computes SHA‑1 and checks a local SQLite cache (`state.db`) to prevent duplicates.
|
||||||
- Optional Immich de‑dupe via `/assets/bulk-upload-check`
|
- WebSocket `/ws` pushes per‑item progress to the current browser session only.
|
||||||
- WebSocket `/ws` pushes per‑item progress to the current browser session only
|
- **Persistence:** A local SQLite database (`state.db`) prevents re‑uploads across sessions. Uploaded files are stored in `/data/uploads`.
|
||||||
- **Persistence:** local SQLite (`state.db`) prevents re‑uploads across sessions/runs.
|
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
@@ -187,7 +146,6 @@ immich_drop/
|
|||||||
## Requirements
|
## Requirements
|
||||||
|
|
||||||
- **Python** 3.11
|
- **Python** 3.11
|
||||||
- An **Immich** server + **API key**
|
|
||||||
|
|
||||||
---
|
---
|
||||||
# Local dev quickstart
|
# Local dev quickstart
|
||||||
@@ -211,20 +169,16 @@ The backend contains docstrings so you can generate docs later if desired.
|
|||||||
HOST=0.0.0.0
|
HOST=0.0.0.0
|
||||||
PORT=8080
|
PORT=8080
|
||||||
|
|
||||||
# Immich connection (include /api)
|
|
||||||
IMMICH_BASE_URL=http://REPLACE_ME:2283/api
|
|
||||||
IMMICH_API_KEY=ADD-YOUR-API-KEY # needs: asset.upload; for albums also: album.create, album.read, albumAsset.create
|
|
||||||
MAX_CONCURRENT=3
|
|
||||||
|
|
||||||
# Public uploader page (optional) — disabled by default
|
# Public uploader page (optional) — disabled by default
|
||||||
PUBLIC_UPLOAD_PAGE_ENABLED=TRUE
|
PUBLIC_UPLOAD_PAGE_ENABLED=TRUE
|
||||||
|
|
||||||
# Album (optional): auto-add uploads from public uploader to this album (creates if needed)
|
|
||||||
IMMICH_ALBUM_NAME=dead-drop
|
|
||||||
|
|
||||||
# Local dedupe cache (SQLite)
|
# Local dedupe cache (SQLite)
|
||||||
STATE_DB=./data/state.db
|
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)
|
# Base URL for generating absolute invite links (recommended for production)
|
||||||
# e.g., PUBLIC_BASE_URL=https://photos.example.com
|
# e.g., PUBLIC_BASE_URL=https://photos.example.com
|
||||||
#PUBLIC_BASE_URL=
|
#PUBLIC_BASE_URL=
|
||||||
|
|||||||
Reference in New Issue
Block a user