# Image Server A FastAPI-based image server that serves files from directories or ZIP archives using hashed paths for secure, randomized access. The server provides a beautiful full-screen image viewing experience with navigation controls and optional auto-advance features. ## Features - **Secure File Access**: Files are accessed via SHA-256 hashes of their paths (with salt) rather than direct file paths - **Multiple Sources**: Supports serving from directories, individual ZIP files, or glob patterns (e.g., `*.zip`) - **Beautiful UI**: Full-screen responsive image viewer with keyboard navigation - **Navigation Controls**: - Previous/Next buttons (clickable chevrons or arrow keys) - Random access mode - Ordered sequential access with configurable delay - Play/pause toggle for auto-advance - **Keyboard Shortcuts**: - Left/Right Arrow or H/L: Navigate previous/next - Space: Toggle play/pause - +/= or J: Increase slide delay - - or K: Decrease slide delay - O: Toggle between ordered and random modes - **MIME Type Detection**: Automatically sets correct content types for served files - **Health Check Endpoint**: Monitor server status and indexed file count ## Installation ### Prerequisites - Python 3.13 or higher - UV package manager (recommended) or pip ### Using UV (Recommended) ```bash # Clone the repository git clone cd image_server # Install dependencies uv sync # Activate virtual environment source .venv/bin/activate ``` ### Using pip ```bash pip install fastapi uvicorn ``` ## Usage ### Basic Usage ```bash # Serve files from a directory python main.py /path/to/your/images # Serve files from a ZIP archive python main.py /path/to/archive.zip # Serve files matching a glob pattern python main.py "path/to/images/*.zip" ``` ### Server Options ```bash python main.py [SOURCE] [OPTIONS] Arguments: SOURCE Path to directory, ZIP archive, or glob pattern (e.g., *.zip, path/to/zips/*.zip) Options: --host TEXT Host to bind to (default: 0.0.0.0) --port INTEGER Port to bind to (default: 8000) --salt TEXT Salt for hashing file paths (default: random) -h, --help Show help message and exit ``` ### Examples ```bash # Start server on default port 8000 python main.py ./photos # Start server on custom host and port python main.py ./photos --host 127.0.0.1 --port 3000 # Start server with custom salt for consistent hashing python main.py ./photos --salt mysecretkey123 # Start server serving from ZIP files python main.py ./archives/*.zip ``` ## API Endpoints ### File Access - `GET /api/{file_hash}/data` - Retrieve file data by hash - Returns: File content with appropriate Content-Type header - Response: StreamingResponse of the file data ### Navigation Pages - `GET /{file_hash}` - View file with navigation controls - Displays image with previous/next navigation - `GET /{order}/{delay}/{file_hash}` - View file with auto-refresh - order: "next" (sequential) or "random" - delay: Seconds before auto-advancing - file_hash: Starting file hash ### Special Endpoints - `GET /` - Redirect to a random file - `GET /{order}/{delay}` - Redirect to random file with order/delay settings - `GET /api/health` - Health check endpoint - Returns: JSON with status and file count ## How It Works ### File Indexing When started, the server indexes all files from the provided source(s): - For directories: Walks the directory tree and indexes all files - For ZIP archives: Indexes all files within the archive - For glob patterns: Processes each matching file Each file is assigned a unique SHA-256 hash based on: - File path (relative to source or within ZIP) - Salt value (random or user-provided) ### Security - Direct file path access is prevented - Files can only be accessed via their cryptographic hashes - Salt prevents hash prediction attacks - No filesystem traversal vulnerabilities ### User Interface The server serves a single-page application (`frontend.html`) that provides: - Full-screen image display - Click-to-navigate on image - Chevron buttons for previous/next navigation - Play/pause button for auto-advance control - Responsive design that works on mobile and desktop ## Development ### Running in Development Mode ```bash # With auto-reload for development uvicorn main:app --reload --host 0.0.0.0 --port 8000 ``` ### Code Structure - `main.py` - Contains all server logic, routing, and file indexing - `frontend.html` - HTML template for the user interface - `FileIndexer` - Base class for indexing files from directories - `ZipFileIndexer` - Extension for indexing files from ZIP archives - Global `file_mapping` dictionary - Maps hashes to file paths/filenames ### Adding New Features 1. **New Indexer Types**: Create a class inheriting from `FileIndexer` and override the `_index()` method 2. **New Routes**: Add functions decorated with appropriate HTTP method decorators (`@app.get`, etc.) 3. **UI Changes**: Modify `frontend.html` template and update template substitution in `_render_page()` ## Dependencies - **FastAPI** - Modern web framework for building APIs - **Uvicorn** - ASGI server for running the application - **Python Standard Library** - hashlib, mimetypes, secrets, zipfile, etc. ## License This project is licensed under the MIT License - see the LICENSE file for details. ## Contributing 1. Fork the repository 2. Create a feature branch 3. Commit your changes 4. Push to the branch 5. Open a pull request Please ensure your code follows the existing style and includes appropriate tests.