update readme.md
This commit is contained in:
@@ -1,39 +1,236 @@
|
|||||||
# ImageRepo
|
# ImageRepo
|
||||||
|
|
||||||
This is a personal project that will be used to view store Patreon content from over the years.
|
A self-hosted image and video gallery application designed for organizing and viewing media collections. Originally built for managing Patreon content archives, it features automatic importing, tagging, duplicate detection, and a responsive dark-themed UI.
|
||||||
It is a viewer for images and videos and not any text content that a creator may have posted.
|
|
||||||
|
|
||||||
if for some reason you want to use this repo this is a basic docker-compose.yml to run it:
|
## Features
|
||||||
|
|
||||||
|
- **Gallery View** - Browse images in a paginated grid with thumbnail previews
|
||||||
|
- **Showcase View** - Randomized masonry layout for discovery
|
||||||
|
- **Image Modal** - Full-size viewing with zoom, pan, and keyboard navigation
|
||||||
|
- **Video Support** - Playback for video files with thumbnail generation
|
||||||
|
- **Tagging System** - Organize images with tags (artist, character, series, rating, archive, user-defined)
|
||||||
|
- **Tag Autocomplete** - Quick tag entry with search suggestions
|
||||||
|
- **Automatic Importing** - Scans `/import` directory on schedule or manual trigger
|
||||||
|
- **Archive Extraction** - Supports ZIP, RAR, 7z and other archive formats
|
||||||
|
- **Duplicate Detection** - Perceptual hash (pHash) comparison to skip similar images
|
||||||
|
- **Import Filters** - Skip images by dimensions or transparency percentage
|
||||||
|
- **Bulk Deletion** - Delete images by tag or filter criteria
|
||||||
|
- **Artist Organization** - Auto-tags images based on folder structure
|
||||||
|
- **Dark Theme** - Easy on the eyes for extended browsing
|
||||||
|
|
||||||
|
## Quick Start
|
||||||
|
|
||||||
|
### Docker Compose
|
||||||
|
|
||||||
|
```yaml
|
||||||
|
services:
|
||||||
|
imagerepo:
|
||||||
|
image: git.fabledsword.com/bvandeusen/imagerepo:latest
|
||||||
|
ports:
|
||||||
|
- "5000:5000"
|
||||||
|
volumes:
|
||||||
|
- ./imagerepo/db:/db # SQLite database storage
|
||||||
|
- ./imagerepo/images:/images # Imported images and thumbnails
|
||||||
|
- ./your-media:/import # Source directory to import from
|
||||||
|
environment:
|
||||||
|
- THUMBS_VERBOSE=1
|
||||||
|
- THUMBS_LOG_EVERY=50
|
||||||
|
```
|
||||||
|
|
||||||
|
Then visit `http://localhost:5000` in your browser.
|
||||||
|
|
||||||
|
## Volumes
|
||||||
|
|
||||||
|
| Path | Description |
|
||||||
|
|------|-------------|
|
||||||
|
| `/db` | Database storage (SQLite by default) |
|
||||||
|
| `/images` | Where imported images and thumbnails are stored |
|
||||||
|
| `/import` | Source directory the importer scans for new media |
|
||||||
|
|
||||||
|
## Environment Variables
|
||||||
|
|
||||||
|
### Database Configuration
|
||||||
|
|
||||||
|
By default, ImageRepo uses SQLite. Set `DB_TYPE=postgresql` to use PostgreSQL instead.
|
||||||
|
|
||||||
|
| Variable | Default | Description |
|
||||||
|
|----------|---------|-------------|
|
||||||
|
| `DB_TYPE` | `sqlite` | Database type: `sqlite` or `postgresql` |
|
||||||
|
| `DB_NAME` | `app.db` | Database name (SQLite filename or PostgreSQL database) |
|
||||||
|
| `DB_USER` | `imagerepo` | PostgreSQL username |
|
||||||
|
| `DB_PASS` | `postgres` | PostgreSQL password |
|
||||||
|
| `DB_HOST` | `postgres` | PostgreSQL host |
|
||||||
|
| `DB_PORT` | `5432` | PostgreSQL port |
|
||||||
|
|
||||||
|
### Import Settings
|
||||||
|
|
||||||
|
These can also be configured via the Settings page in the UI.
|
||||||
|
|
||||||
|
| Variable | Default | Description |
|
||||||
|
|----------|---------|-------------|
|
||||||
|
| `IMPORT_MIN_WIDTH` | `0` | Minimum image width in pixels (0 = no minimum) |
|
||||||
|
| `IMPORT_MIN_HEIGHT` | `0` | Minimum image height in pixels (0 = no minimum) |
|
||||||
|
| `IMPORT_SKIP_TRANSPARENT` | `false` | Skip mostly-transparent images (PNG/GIF/WebP) |
|
||||||
|
| `IMPORT_TRANSPARENCY_THRESHOLD` | `0.9` | Transparency % threshold (0.0-1.0) for skipping |
|
||||||
|
| `IMPORT_PHASH_THRESHOLD` | `2` | Duplicate detection sensitivity (0=disabled, 1=strict, 2=normal, 5=loose, 10=very loose) |
|
||||||
|
|
||||||
|
### Thumbnail Generation
|
||||||
|
|
||||||
|
| Variable | Default | Description |
|
||||||
|
|----------|---------|-------------|
|
||||||
|
| `THUMBS_VERBOSE` | `0` | Enable verbose logging (`1`, `true`, or `yes`) |
|
||||||
|
| `THUMBS_LOG_EVERY` | `50` | Log progress every N thumbnails |
|
||||||
|
| `THUMBS_BATCH_SIZE` | `500` | Process thumbnails in batches of N |
|
||||||
|
| `THUMBS_FFMPEG_TIMEOUT` | `60` | Timeout in seconds for video thumbnail extraction |
|
||||||
|
|
||||||
|
### Archive Extraction
|
||||||
|
|
||||||
|
| Variable | Default | Description |
|
||||||
|
|----------|---------|-------------|
|
||||||
|
| `ARCHIVE_TMPDIR` | System temp | Directory for extracting archives |
|
||||||
|
| `ARCHIVE_MIN_FREE_GB` | `0` | Minimum free disk space (GB) required to start extraction (0 = disabled) |
|
||||||
|
| `ARCHIVE_NUM_WIDTH` | `4` | Zero-padding width for archive sequence numbers in tags |
|
||||||
|
|
||||||
|
### Other
|
||||||
|
|
||||||
|
| Variable | Default | Description |
|
||||||
|
|----------|---------|-------------|
|
||||||
|
| `PIL_MAX_IMAGE_PIXELS` | `178956970` | Maximum image size Pillow will process (guards against decompression bombs) |
|
||||||
|
|
||||||
|
## Import Behavior
|
||||||
|
|
||||||
|
The importer runs:
|
||||||
|
- Automatically every 8 hours
|
||||||
|
- Manually via the "Trigger Image Import" button in Settings
|
||||||
|
|
||||||
|
### Folder Structure
|
||||||
|
|
||||||
|
The importer uses the folder structure to auto-tag images:
|
||||||
|
|
||||||
```
|
```
|
||||||
|
/import/
|
||||||
|
├── ArtistName/ # Tagged as "artist:ArtistName"
|
||||||
|
│ ├── image1.png
|
||||||
|
│ ├── image2.jpg
|
||||||
|
│ └── archive.zip # Extracted, contents tagged with "archive:archive"
|
||||||
|
├── AnotherArtist/
|
||||||
|
│ └── subfolder/
|
||||||
|
│ └── image3.png # Still tagged as "artist:AnotherArtist"
|
||||||
|
```
|
||||||
|
|
||||||
|
- Top-level folders become `artist:FolderName` tags
|
||||||
|
- Archives (ZIP, RAR, 7z, etc.) are extracted and their contents tagged with `archive:filename`
|
||||||
|
- Nested subfolders inherit the top-level artist tag
|
||||||
|
|
||||||
|
### Supported Formats
|
||||||
|
|
||||||
|
**Images:** PNG, JPG, JPEG, GIF, WebP, BMP, TIFF
|
||||||
|
**Videos:** MP4, WebM, MKV, AVI, MOV
|
||||||
|
**Archives:** ZIP, RAR, 7z, and others supported by `unar`/`7z`
|
||||||
|
|
||||||
|
## Settings Page
|
||||||
|
|
||||||
|
The Settings page (`/settings`) provides:
|
||||||
|
|
||||||
|
### Admin Actions
|
||||||
|
- **Trigger Image Import** - Manually start an import scan
|
||||||
|
- **Regenerate Thumbnails** - Rebuild all thumbnails
|
||||||
|
- **Reset Image Database** - Clear all image records (files remain on disk)
|
||||||
|
|
||||||
|
### Import Filters
|
||||||
|
Configure filtering rules that apply during import:
|
||||||
|
- Minimum dimensions
|
||||||
|
- Transparency filtering
|
||||||
|
- Duplicate detection sensitivity
|
||||||
|
|
||||||
|
### Delete Images by Tag
|
||||||
|
Bulk delete all images associated with a specific tag (e.g., remove an entire artist's collection).
|
||||||
|
|
||||||
|
### Clean Up Existing Images
|
||||||
|
Scan and selectively delete images that match filter criteria (transparency or dimensions).
|
||||||
|
|
||||||
|
## API Endpoints
|
||||||
|
|
||||||
|
| Endpoint | Method | Description |
|
||||||
|
|----------|--------|-------------|
|
||||||
|
| `/api/random-images` | GET | Get random images for showcase |
|
||||||
|
| `/api/tags/search` | GET | Search tags for autocomplete |
|
||||||
|
| `/api/import-settings` | GET/POST | Read/write import filter settings |
|
||||||
|
| `/api/import-stats` | GET | Get last import statistics |
|
||||||
|
| `/api/filter-scan` | GET | Scan images matching filter criteria |
|
||||||
|
| `/api/filter-delete` | POST | Delete selected images |
|
||||||
|
| `/api/delete-by-tag` | POST | Delete all images with a tag |
|
||||||
|
| `/image/<id>/tags` | GET | List tags for an image |
|
||||||
|
| `/image/<id>/tags/add` | POST | Add a tag to an image |
|
||||||
|
| `/image/<id>/tags/remove` | POST | Remove a tag from an image |
|
||||||
|
|
||||||
|
## Keyboard Shortcuts
|
||||||
|
|
||||||
|
In the image modal:
|
||||||
|
- **Arrow Left/Right** - Previous/Next image
|
||||||
|
- **Escape** - Close modal
|
||||||
|
- **Click image** - Toggle zoom
|
||||||
|
- **Drag** (when zoomed) - Pan around image
|
||||||
|
|
||||||
|
## PostgreSQL Setup
|
||||||
|
|
||||||
|
To use PostgreSQL instead of SQLite:
|
||||||
|
|
||||||
|
```yaml
|
||||||
|
services:
|
||||||
imagerepo:
|
imagerepo:
|
||||||
image: git.fabledsword.com/bvandeusen/imagerepo:latest
|
image: git.fabledsword.com/bvandeusen/imagerepo:latest
|
||||||
ports:
|
ports:
|
||||||
- "5000:5000"
|
- "5000:5000"
|
||||||
environment:
|
environment:
|
||||||
# - DB_TYPE=postgresql
|
- DB_TYPE=postgresql
|
||||||
# - DB_HOST=postgres
|
- DB_HOST=postgres
|
||||||
# - DB_PASS=${IMAGEREPO_PASS}
|
- DB_USER=imagerepo
|
||||||
- THUMBS_VERBOSE=1
|
- DB_PASS=your_secure_password
|
||||||
- THUMBS_LOG_EVERY=1
|
- DB_NAME=imagerepo
|
||||||
- THUMBS_BATCH_SIZE=50
|
|
||||||
volumes:
|
volumes:
|
||||||
- ./imagerepo/db/:/db # SQLite db storage
|
- ./imagerepo/images:/images
|
||||||
- ./imagerepo/images:/images # where the app will store it's imported images
|
- ./your-media:/import
|
||||||
- ./Patreon:/import # where it will import images from
|
depends_on:
|
||||||
|
- postgres
|
||||||
|
|
||||||
|
postgres:
|
||||||
|
image: postgres:15
|
||||||
|
environment:
|
||||||
|
- POSTGRES_USER=imagerepo
|
||||||
|
- POSTGRES_PASSWORD=your_secure_password
|
||||||
|
- POSTGRES_DB=imagerepo
|
||||||
|
volumes:
|
||||||
|
- ./postgres-data:/var/lib/postgresql/data
|
||||||
```
|
```
|
||||||
|
|
||||||
by default the app will use SQLite for it's db but it can be configured with postgres
|
## Development
|
||||||
the defaults for the postgres DB connection are:
|
|
||||||
DB_USER = imagerepo
|
|
||||||
DB_PASS = postgres
|
|
||||||
DB_HOST = postgres
|
|
||||||
DB_PORT = 5432
|
|
||||||
DB_NAME = imagerepo
|
|
||||||
|
|
||||||
the above are also environment variables that can be set in the docker-compose
|
### Local Setup
|
||||||
|
|
||||||
# Imports
|
```bash
|
||||||
the app checks the "/import" directory either when triggered from the settings menu or every 8 hours.
|
# Clone the repository
|
||||||
|
git clone https://git.fabledsword.com/bvandeusen/imagerepo.git
|
||||||
|
cd imagerepo
|
||||||
|
|
||||||
the importer assumes that folders in the root of the import directory indicate the artist the images are from and tags the imports with the directory as a name. I have not tested with images sitting in the root as I don't have my files structured like that.
|
# Create virtual environment
|
||||||
|
python -m venv venv
|
||||||
|
source venv/bin/activate # or `venv\Scripts\activate` on Windows
|
||||||
|
|
||||||
|
# Install dependencies
|
||||||
|
pip install -r requirements.txt
|
||||||
|
|
||||||
|
# Run with Flask dev server
|
||||||
|
flask run
|
||||||
|
```
|
||||||
|
|
||||||
|
### Docker Build
|
||||||
|
|
||||||
|
```bash
|
||||||
|
docker build -t imagerepo .
|
||||||
|
docker run -p 5000:5000 -v ./images:/images -v ./import:/import imagerepo
|
||||||
|
```
|
||||||
|
|
||||||
|
## License
|
||||||
|
|
||||||
|
This is a personal project. Use at your own discretion.
|
||||||
|
|||||||
Reference in New Issue
Block a user