diff --git a/README.md b/README.md index 4bd9633..ab5539d 100644 --- a/README.md +++ b/README.md @@ -1,18 +1,19 @@ # 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. +A self-hosted web app for uploading files and media and saving them to the filesystem on your server. +Useful for letting people upload vacation photos, etc. just by sending them a link. -Forked from "Immich Drop Uploader": https://github.com/Nasogaa/immich-drop +Admin user can create invite links with optional limits and password protection. A public uploader page is optional and enabled by default. -![File Drop Uploader Dark Mode UI](./screenshot.png) +[View Screenshots](screenshots.md) ## 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. +- **Local Saving:** All uploaded files are saved to the server's local filesystem. +- **Drag and Drop:** Upload multiple files and folders by dragging them onto the page. +- **Invite Links:** Create sharable 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. +- **Passwords (optional):** Protect invite links with a password. - **Albums:** Upload into a specific folder (auto-create supported). Preserves client-side folder structure on upload. - **Duplicate Prevention:** Local SHA‑1 cache prevents re-uploading the same file. - **Telegram Notifications (optional):** Get notified via Telegram when upload batches are complete. @@ -26,7 +27,9 @@ Clone the repo. Copy `.env.example` to `.env` and edit. -### docker-compose.yml +### Docker Compose + +Create `docker-compose.yml` and edit: ```yaml services: @@ -49,10 +52,15 @@ services: start_period: 10s ``` +Start the service: + ```bash $ sudo docker compose up --build -d ``` +Set up nginx / a reverse proxy and point it to the web app. + + ### Chunked Uploads - Chunked uploads are enabled by default. Uses setting `CHUNKED_UPLOADS_ENABLED=true`. @@ -70,11 +78,22 @@ $ sudo docker compose up --build -d - 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`. -### Requirements +### Setup -- **Python** 3.11 +Requires Python 3.11+. -### Local dev quickstart +Create a venv, activate it, and install: + +```text +$ virtualenv -p python3 env +$ source env/bin/activate +(env) $ pip install -r requirements.txt +``` + +```text +(env) $ cp .env.example .env +(env) $ vim .env +``` Run with live reload: @@ -82,54 +101,30 @@ Run with live reload: 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 checked‑in `/.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 **SHA‑1** 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. +1. **Queue** - Files selected in the browser are queued; each gets a client-side ID. +2. **De-dupe (local)** - Server computes **SHA‑1** 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`. +- The public uploader page at `/` is enabled unless disabled with `PUBLIC_UPLOAD_PAGE_ENABLED=false`. - 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). + +## License + +This program is free and open-source software licensed under the MIT License. Please see the `LICENSE` file for details. + +That means you have the right to study, change, and distribute the software and source code to anyone and for any purpose. You deserve these rights. + +## Acknowledgements + +This project was forked from "Immich Drop Uploader" by Simon Adams: https://github.com/Nasogaa/immich-drop + diff --git a/media/admin-page.png b/media/admin-page.png new file mode 100644 index 0000000..0abf756 Binary files /dev/null and b/media/admin-page.png differ diff --git a/media/after-uploading.png b/media/after-uploading.png new file mode 100644 index 0000000..e910bf3 Binary files /dev/null and b/media/after-uploading.png differ diff --git a/media/invite-page.png b/media/invite-page.png new file mode 100644 index 0000000..b8cbad4 Binary files /dev/null and b/media/invite-page.png differ diff --git a/media/public-uploader.png b/media/public-uploader.png new file mode 100644 index 0000000..990a617 Binary files /dev/null and b/media/public-uploader.png differ diff --git a/media/telegram-bot.png b/media/telegram-bot.png new file mode 100644 index 0000000..f3d8de4 Binary files /dev/null and b/media/telegram-bot.png differ diff --git a/screenshot.png b/screenshot.png deleted file mode 100644 index 5ca2250..0000000 Binary files a/screenshot.png and /dev/null differ diff --git a/screenshots.md b/screenshots.md new file mode 100644 index 0000000..ddcbb7a --- /dev/null +++ b/screenshots.md @@ -0,0 +1,21 @@ +# Screenshots + +## Public upload page + +![](media/public-uploader.png) + +## After uploading files + +![](media/after-uploading.png) + +## Admin page + +![](media/admin-page.png) + +## Invite link (with password) + +![](media/invite-page.png) + +## Telegram bot + +![](media/telegram-bot.png)