Files
image-drop/README.md

4.8 KiB
Raw Blame History

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

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

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
$ 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:

python main.py

The backend contains docstrings so you can generate docs later if desired.

Dev Configuration (.env)

# 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).