diff --git a/README.md b/README.md index e69de29..4c275e8 100644 --- a/README.md +++ b/README.md @@ -0,0 +1,191 @@ +# 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: Navigate previous/next + - Space: Toggle play/pause + - +/-: Increase/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. \ No newline at end of file