Skip to content

P2Chill/kometizarr

Repository files navigation

Kometizarr

Automated rating overlays and collection management for Plex - Simple, fast, and powerful.

Kometizarr automatically adds gorgeous multi-source rating badges to your Plex movie and TV show posters. No more messy YAML configs, no database risks, just clean Python that works.

Kometizarr Demo

✨ Features

🎯 Multi-Source Rating Overlays

  • 4 independent rating badges — TMDB, IMDb, RT Critic, RT Audience
  • Independent positioning — Place each badge separately anywhere on the poster
  • Visual alignment guides — Live grid overlay for precise badge placement
  • 11 font options — DejaVu Sans/Serif/Mono in Bold, Regular, and Italic variants
  • Per-badge customization — Font, color, opacity, size, and logo scale per badge
  • Live preview — Render 3 real posters from your library before committing
  • Backward compatible — Legacy unified badge still supported

🎨 Beautiful Design

  • Dynamic RT logos: Fresh tomato/rotten splat for critic scores, fresh/spilled popcorn for audience scores
  • Smart sizing: Logos scale proportionally, popcorn icons enlarged for visibility
  • Perfect alignment: All ratings and logos line up beautifully
  • 50% opacity background: Semi-transparent black rounded rectangle
  • Color-coded text: Gold ratings, white symbols (/10, %)
  • Drop shadows: Crisp text on any poster background

⚙️ Set-and-Forget Automation (NEW in v1.2.0)

  • Two independent cron schedules — Normal run (new items only) + Force run (refresh all ratings)
  • Human-readable scheduling — Daily, Weekly, Every hour with a time picker — no cron syntax needed
  • Plex Webhook — Automatically process the exact item added, the moment it's added
  • Webhook queue — Bulk imports (10 items at once) handled cleanly, no dropped events
  • Multi-library selection — Checkboxes for cron and webhook — pick any combination of libraries
  • Settings tab — All automation configured from the Web UI, persisted across restarts

📊 Dashboard

  • Multi-library processing — Select any combination of libraries and process them in one click
  • Real-time progress — WebSocket updates with live success/failure/skipped counts
  • Library stats — Total items and processed count per library
  • Stop button — Graceful abort mid-run

📦 Smart Collection Management

  • Decade collections: Automatically organize by era
  • Keyword collections: DC Universe, Zombies, Time Travel, etc.
  • Studio collections: Marvel, Disney, Warner Bros
  • Custom collections: Define your own criteria
  • Dry-run mode: Preview before applying
  • Safe operations: No database modifications, uses official Plex API

🚀 Fast & Safe

  • Atomic operations: Each poster processed independently
  • Automatic backups: Original posters saved before modification
  • Easy restoration: One-click restore from the Web UI or CLI
  • Rate limited: Respects API limits (TMDB, MDBList)
  • Resume support: Skip already-processed items

🖼️ Screenshots

Dashboard

Library selection, stats, badge positioning with drag-and-drop, and processing options — all in one view.

Dashboard

Live Processing

Real-time progress with WebSocket updates — success, failure, skipped, and remaining counts.

Processing

Scheduled Processing & Webhook

Two independent cron schedules plus Plex webhook — fully set-and-forget automation.

Settings

Collection Management

Create decade, keyword, and studio collections with presets or custom keywords.

Collections

4-Badge Rating Overlay

Each rating source (TMDB, IMDb, RT Critic, RT Audience) positioned independently with custom styling, dynamic RT logos, and per-badge font/color/size options.

12 Monkeys

🚀 Quick Start

📦 Pre-built Docker Images Available:

  • Docker Hub: p2chill/kometizarr-backend:latest & p2chill/kometizarr-frontend:latest
  • GitHub Container Registry: ghcr.io/p2chill/kometizarr-backend:latest & ghcr.io/p2chill/kometizarr-frontend:latest

No build required — just pull and run! ⚡

Method 1: Web UI (Recommended) 🌐

The easiest way to use Kometizarr is with the Web UI — a beautiful dashboard with live progress tracking and full automation!

Option A: Direct Pull (No Clone Required) ⚡

Download docker-compose.example.yml, fill in your values, and rename it to docker-compose.yml. Or create it manually:

services:
  backend:
    image: ghcr.io/p2chill/kometizarr-backend:latest
    container_name: kometizarr-backend
    ports:
      - "8000:8000"
    volumes:
      - ./data/backups:/backups  # Poster backups (PERSISTENT)
      - ./data/appdata:/app/kometizarr/data  # Settings (cron, webhook config)
    environment:
      - PLEX_URL=http://YOUR_PLEX_IP:32400
      - PLEX_TOKEN=YOUR_PLEX_TOKEN
      - TMDB_API_KEY=YOUR_TMDB_KEY
      - OMDB_API_KEY=YOUR_OMDB_KEY  # Optional
      - MDBLIST_API_KEY=YOUR_MDBLIST_KEY
    restart: unless-stopped
    networks:
      - kometizarr

  frontend:
    image: ghcr.io/p2chill/kometizarr-frontend:latest
    container_name: kometizarr-frontend
    ports:
      - "3001:80"
    depends_on:
      - backend
    restart: unless-stopped
    networks:
      - kometizarr

networks:
  kometizarr:
    driver: bridge

Then run:

docker compose up -d

Open http://localhost:3001 — done in 5 seconds! 🎉

Alternative registries:

  • Docker Hub: Replace ghcr.io/p2chill/ with p2chill/
  • Version pinning: Replace :latest with :v1.2.1 for stable releases

Option B: Clone Repository (For Development)

git clone https://github.com/P2Chill/kometizarr.git
cd kometizarr
cp .env.example .env
# Edit .env with your Plex credentials and API keys
docker compose up -d
📄 View docker-compose.yml
services:
  backend:
    build: ./web/backend
    container_name: kometizarr-backend
    ports:
      - "8000:8000"
    volumes:
      - ./:/app/kometizarr  # Mount entire project
      - ./web/backend:/app/backend  # Mount backend source for hot-reload (no rebuild needed)
      - ./data/backups:/backups  # Poster backups (PERSISTENT - survives reboots)
    environment:
      - PLEX_URL=${PLEX_URL:-http://192.168.1.20:32400}
      - PLEX_TOKEN=${PLEX_TOKEN}
      - TMDB_API_KEY=${TMDB_API_KEY}
      - OMDB_API_KEY=${OMDB_API_KEY}
      - MDBLIST_API_KEY=${MDBLIST_API_KEY}
    restart: unless-stopped
    networks:
      - kometizarr

  frontend:
    build: ./web/frontend
    container_name: kometizarr-frontend
    ports:
      - "3001:80"
    depends_on:
      - backend
    restart: unless-stopped
    networks:
      - kometizarr

networks:
  kometizarr:
    driver: bridge

Then open http://localhost:3001 in your browser! 🎉

Features:

  • 📊 Visual dashboard with library stats and multi-library processing
  • ⚡ Real-time progress with WebSocket updates (auto-reconnect on disconnection)
  • 🎯 One-click processing with live progress tracking
  • 📈 Live success/failure/skipped counts
  • 🎨 Rating source filtering (choose TMDB, IMDb, RT Critic, RT Audience)
  • 🔄 Browser refresh resilience (resumes monitoring active operations)
  • ⏱️ 10-second countdown on completion with skip option
  • 🛑 Cancel/stop button to abort processing mid-run
  • ⚙️ Settings tab — cron scheduling, webhook, library maintenance

Setting Up Automation (v1.2.0)

After starting the stack, open the Settings tab in the Web UI:

  1. Scheduled Processing — Enable either or both cron jobs, pick Daily/Weekly/Hourly and a time, select which libraries to include (none = all). Save.
  2. Plex Webhook — Copy the webhook URL into Plex → Settings → Webhooks. Enable and optionally scope to specific libraries.

That's it — Kometizarr will keep your ratings fresh automatically.

Method 2: CLI/Python Script

For advanced users or automation:

Prerequisites:

Installation:

git clone https://github.com/P2Chill/kometizarr.git
cd kometizarr
pip install -r requirements.txt

Configuration

  1. Copy example config:
cp config.example.json config.json
  1. Edit config.json with your details:
{
  "plex": {
    "url": "http://YOUR_PLEX_IP:32400",
    "token": "YOUR_PLEX_TOKEN",
    "library": "Movies"
  },
  "apis": {
    "tmdb": {
      "api_key": "YOUR_TMDB_KEY"
    },
    "omdb": {
      "api_key": "YOUR_OMDB_KEY",
      "enabled": true
    },
    "mdblist": {
      "api_key": "YOUR_MDBLIST_KEY"
    }
  },
  "rating_overlay": {
    "enabled": true,
    "badge": {
      "position": "northwest",
      "style": "default"
    }
  }
}

How to get your Plex token: https://support.plex.tv/articles/204059436-finding-an-authentication-token-x-plex-token/

Usage

Process entire movie library:

from src.rating_overlay.plex_poster_manager import PlexPosterManager
import json

with open('config.json') as f:
    config = json.load(f)

manager = PlexPosterManager(
    plex_url=config['plex']['url'],
    plex_token=config['plex']['token'],
    library_name='Movies',
    tmdb_api_key=config['apis']['tmdb']['api_key'],
    omdb_api_key=config['apis']['omdb']['api_key'],
    mdblist_api_key=config['apis']['mdblist']['api_key'],
    backup_dir='./data/kometizarr_backups'
)

# Process all movies (skips already processed)
manager.process_library(position='northwest', force=False)

Process single movie:

movie = plex.library.section('Movies').get('The Dark Knight')
manager.process_movie(movie, position='northwest')

Restore original posters:

# Restore single movie
manager.restore_movie('The Dark Knight')

# Restore entire library
manager.restore_library()

TV Shows: Same API, just use library_name='TV Shows' — works identically!

📊 Performance

Tested on 2,363 movie library:

  • Processing speed: ~0.5–4 movies/second depending on your CPU
  • Total time: ~35–55 minutes for full library
  • API limits: Respects TMDB (40 req/10s) and MDBList limits
  • Memory usage: Minimal (processes one at a time)

Rate limiting:

  • 0.3s delay between movies (default)
  • Adjustable in process_library(rate_limit=0.3)

🎯 Why Kometizarr?

Kometizarr is designed to be a lightweight, focused alternative for rating overlays:

  • Simple Configuration: Single JSON config file, no complex YAML hierarchy
  • Fast Processing: Direct API calls with efficient rate limiting
  • Safe Operations: Official Plex API, automatic backups, atomic operations
  • Flexible Workflows: Easy restoration, dry-run mode, skip processed items
  • Beautiful Design: Multi-source ratings (TMDB, IMDb, RT), dynamic RT logos that change based on score
  • Modern Stack: Clean Python code with optional Web UI (React + FastAPI)
  • Plex-First Ratings: Extracts ratings from Plex metadata before hitting external APIs (97%+ success rate)
  • True Automation: Cron scheduling + Plex webhook — fully set-and-forget

📁 Project Structure

kometizarr/
├── src/
│   ├── rating_overlay/
│   │   ├── multi_rating_badge.py    # Badge generation with dynamic logos
│   │   ├── rating_fetcher.py        # TMDB, OMDb, MDBList API calls
│   │   ├── plex_poster_manager.py   # Orchestration and Plex integration
│   │   ├── backup_manager.py        # Original poster backups
│   │   └── overlay_composer.py      # Poster compositing
│   ├── collection_manager/          # Smart collection management
│   └── utils/
│       └── logger.py                # Clean progress tracking
├── web/
│   ├── backend/                     # FastAPI backend with WebSocket
│   │   ├── main.py                  # API endpoints, cron scheduler, webhook
│   │   ├── Dockerfile
│   │   └── requirements.txt
│   ├── frontend/                    # React frontend
│   │   ├── src/
│   │   │   ├── components/          # Dashboard, Settings, ProcessingProgress
│   │   │   ├── App.jsx
│   │   │   └── main.jsx
│   │   ├── Dockerfile
│   │   ├── nginx.conf
│   │   └── package.json
│   └── README.md                    # Web UI documentation
├── assets/
│   └── logos/                       # RT tomato/popcorn logos
├── examples/                        # Example scripts
├── docker-compose.yml               # Docker Compose configuration
├── .env.example                     # Environment variables template
├── config.example.json              # CLI configuration example
└── README.md

🎨 Customization

Badge Position

# Options: 'northwest', 'northeast', 'southwest', 'southeast'
manager.process_library(position='northwest')

Badge Styling

The badge automatically:

  • Scales to 45% of poster width
  • Uses semi-transparent black background (50% opacity)
  • Left-aligns all logos
  • Displays gold ratings with white symbols
  • Adjusts logo sizes (popcorn icons 1.2–1.3x larger for visibility)

Adding Custom Logos

Place PNG files in assets/logos/:

  • tmdb.png — TMDB logo
  • imdb.png — IMDb logo
  • rt_fresh.png — Fresh tomato (critic ≥60%)
  • rt_rotten.png — Rotten splat (critic <60%)
  • rt_audience_fresh.png — Fresh popcorn (audience ≥60%)
  • rt_audience_rotten.png — Spilled popcorn (audience <60%)

Logos should have transparent backgrounds (PNG with alpha channel).

🔧 Advanced Features

Process TV Shows

manager = PlexPosterManager(
    plex_url=config['plex']['url'],
    plex_token=config['plex']['token'],
    library_name='TV Shows',  # Change to TV library
    ...
)
manager.process_library()

Force Reprocessing

# Reprocess all items, even if already done
manager.process_library(force=True)

Limit Processing

# Test on first 10 movies
manager.process_library(limit=10)

Custom Backup Directory

# IMPORTANT: Use a persistent location, NOT /tmp!
manager = PlexPosterManager(
    ...,
    backup_dir='/home/user/kometizarr/backups'  # Or any persistent path
)

🛡️ Safety Features

Automatic Backups

  • Original posters saved to backup_dir/LibraryName/MovieTitle/
  • Web UI/Docker: Backups stored in ./data/backups/ (persistent across reboots)
  • CLI: Default is /tmp/kometizarr_backups⚠️ WARNING: This gets cleared on reboot! Use a persistent location for production
  • Metadata stored (TMDB ID, IMDb ID, ratings)
  • Overlay version also saved for reference

Restoration

  • Restore from backed up originals via Web UI or CLI
  • Safe to run multiple times
  • No data loss

Dry-Run Mode

manager = PlexPosterManager(..., dry_run=True)
manager.process_library()  # Preview without applying

📈 Roadmap

Completed ✅

  • Multi-source rating badges (TMDB, IMDb, RT Critic, RT Audience)
  • Dynamic RT logo system
  • Batch processing for movies and TV shows
  • Automatic backups and restoration
  • Beautiful overlay design with proper alignment
  • Rate limiting and API safety
  • Collection management (decades, studios, keywords, genres)
  • Web UI — React dashboard with FastAPI backend
  • Real-time progress — WebSocket updates for live tracking
  • Docker deployment — Docker Compose support
  • Smart library detection — Auto-detect movie vs TV show libraries
  • Network/Studio presets — 13 streaming services + 12 movie studios
  • Collection visibility controls — Hide collections from library view
  • Cancel/Stop Button — Gracefully abort running processing
  • Rating source filtering — Choose which rating sources to display per run
  • Browser reconnection — Resume monitoring after page refresh
  • WebSocket auto-reconnect — Resilient real-time updates
  • 4-Badge Independent Positioning (v1.1.1) — Each badge placed and styled separately
  • Visual alignment guides — Live grid overlay for precise placement
  • 11 font choices — DejaVu Sans/Serif/Mono in Bold/Regular/Italic
  • Live poster preview (v1.2.0) — Render real posters before committing
  • Font & logo size sliders (v1.2.0) — Fine-tune badge scale visually
  • Scheduled processing (v1.2.0) — Two independent cron jobs (normal + force reprocess)
  • Plex Webhook (v1.2.0) — Process new items automatically the moment they're added
  • Multi-library selection (v1.2.0) — Checkbox selection for cron, webhook, and dashboard
  • Settings tab (v1.2.0) — Full automation config in the Web UI, persisted across restarts
  • Webhook/cron badge fix (v1.2.1) — Webhook and cron now use the badge style & positions configured in the UI (defaults to 4-corner layout on first run)

Planned 🚧

  • Per-episode ratings for TV shows — Season/episode level overlay support
  • unRAID Community Applications — Official unRAID template for one-click installation
  • Multi-server support — Add/remove Plex servers from Web UI

🤝 Contributing

Contributions welcome! Please:

  1. Open an issue first to discuss changes
  2. Follow existing code style
  3. Add tests for new features
  4. Update documentation

📄 License

MIT License — See LICENSE file for details.

🙏 Acknowledgments

  • Posterizarr — Original overlay inspiration
  • Kometa — Collection management patterns
  • PlexAPI — Excellent Python Plex library
  • MDBList — RT ratings API
  • TMDB — Movie database and ratings

💬 Support


Made with ❤️ for the Plex community