Program Director
AI-powered TV channel programmer for Tunarr written in Go.
Overview
Program Director generates themed channel programming in Tunarr by:
- Syncing media metadata from Radarr and Sonarr to local database
- Using similarity scoring and LLM (Ollama) to intelligently select content matching themes
- Applying generated playlists to Tunarr channels with cooldown tracking
Features
- AI-Powered Selection: Uses Ollama LLM for intelligent media curation
- Theme-Based Playlists: Configure themes with genres, keywords, and scheduling
- Database-Backed: SQLite or PostgreSQL for media caching and cooldown tracking
- Radarr/Sonarr Integration: Syncs and caches media metadata locally
- Trakt.tv Integration: Explore trending content and media metadata
- Tunarr Channels: Updates channel programming with curated content
- Cooldown Management: Prevents media from being replayed too frequently
- HTTP API Server: RESTful API with health checks and Prometheus metrics
- Cron Scheduler: Automated playlist generation on configurable schedules
- Kubernetes Ready: Comprehensive Helm charts for production deployment
- CLI & Server Modes: Run one-off generations or as a scheduled service
Installation
Using Go
go install github.com/geekxflood/program-director@latest
Using Docker
docker pull ghcr.io/geekxflood/program-director:latest
Building from source
git clone https://github.com/geekxflood/program-director.git
cd program-director
go build -o program-director .
Configuration
Environment Variables
| Variable |
Description |
Required |
RADARR_API_KEY |
Radarr API key |
Yes |
SONARR_API_KEY |
Sonarr API key |
Yes |
RADARR_URL |
Radarr API URL |
No |
SONARR_URL |
Sonarr API URL |
No |
TUNARR_URL |
Tunarr API URL |
No |
TRAKT_CLIENT_ID |
Trakt.tv client ID (optional) |
No |
TRAKT_CLIENT_SECRET |
Trakt.tv client secret (optional) |
No |
OLLAMA_URL |
Ollama API URL |
No |
OLLAMA_MODEL |
Ollama model name (default: dolphin-llama3:8b) |
No |
DB_DRIVER |
Database driver (postgres/sqlite) |
No |
POSTGRES_HOST |
PostgreSQL host |
No |
POSTGRES_PORT |
PostgreSQL port |
No |
POSTGRES_DATABASE |
PostgreSQL database name |
No |
POSTGRES_USER |
PostgreSQL user |
No |
POSTGRES_PASSWORD |
PostgreSQL password |
No |
Config File
Copy configs/config.example.yaml to config.yaml and customize:
database:
driver: "sqlite" # or "postgres"
sqlite:
path: "./data/program-director.db"
radarr:
url: "http://localhost:7878"
# api_key from RADARR_API_KEY env var
sonarr:
url: "http://localhost:8989"
# api_key from SONARR_API_KEY env var
tunarr:
url: "http://localhost:8000"
ollama:
url: "http://localhost:11434"
model: "dolphin-llama3:8b"
temperature: 0.7
num_ctx: 8192
cooldown:
movie_days: 30
series_days: 14
anime_days: 14
themes:
- name: "sci-fi-night"
description: "Science fiction themed evening"
channel_id: "your-tunarr-channel-id"
schedule: "0 20 * * *" # 8 PM daily (cron format)
media_types:
- "movie"
- "series"
genres:
- "Science Fiction"
keywords:
- "space"
- "future"
min_rating: 6.0
max_items: 10
duration: 300 # minutes
Usage
CLI Commands
# Sync media metadata from Radarr/Sonarr
program-director sync
program-director sync --movies # Sync only movies
program-director sync --series --cleanup # Sync TV shows and cleanup removed media
# Scan media library (display stats)
program-director scan
program-director scan --detailed # Show detailed statistics with top genres
# Generate playlist for a specific theme
program-director generate --theme sci-fi-night
program-director generate --theme sci-fi-night --dry-run # Preview without applying
# Generate playlists for all themes
program-director generate --all-themes
# Run as HTTP server
program-director serve
program-director serve --port 9000 # Custom port
program-director serve --enable-scheduler # With automated scheduling
program-director serve --schedule "0 */6 * * *" # Custom schedule (every 6 hours)
# Trakt.tv commands
program-director trakt trending --movies # Show trending movies
program-director trakt popular --shows # Show popular TV shows
program-director trakt search --query "Inception" # Search for media
# Show version
program-director version
# Enable debug logging
program-director --debug sync
program-director --json serve # JSON formatted logs
Docker Usage
docker run --rm \
-e RADARR_API_KEY=your-key \
-e SONARR_API_KEY=your-key \
-e OLLAMA_URL=http://ollama:11434 \
-e TUNARR_URL=http://tunarr:8000 \
-e RADARR_URL=http://radarr:7878 \
-e SONARR_URL=http://sonarr:8989 \
-v /path/to/config.yaml:/app/config/config.yaml \
-v /path/to/data:/app/data \
ghcr.io/geekxflood/program-director:latest \
generate --all-themes
Docker Compose Example
version: '3.8'
services:
program-director:
image: ghcr.io/geekxflood/program-director:latest
environment:
- RADARR_API_KEY=${RADARR_API_KEY}
- SONARR_API_KEY=${SONARR_API_KEY}
volumes:
- ./config.yaml:/app/config/config.yaml
- ./data:/app/data
command: serve
HTTP API Server
When running in server mode, Program Director provides a RESTful API:
# Start the HTTP server
program-director serve --port 8080
# Available endpoints:
# GET /health - Health check
# GET /ready - Readiness check (database connectivity)
# GET /metrics - Prometheus metrics
# GET /api/v1/media - List media items
# POST /api/v1/media/sync - Trigger media sync
# GET /api/v1/themes - List configured themes
# POST /api/v1/generate - Generate all playlists
# POST /api/v1/generate/:id - Generate specific theme
# GET /api/v1/history - View play history
# GET /api/v1/cooldowns - View active cooldowns
# POST /api/v1/webhooks - Webhook endpoint
Kubernetes Deployment
Deploy Program Director to Kubernetes using Helm:
# Install with default values
helm install program-director ./charts/program-director
# Install with custom values
helm install program-director ./charts/program-director \
--set config.radarr.apiKey=your-key \
--set config.sonarr.apiKey=your-key \
--values custom-values.yaml
# Using production values
helm install program-director ./charts/program-director \
--values charts/program-director/values-production.yaml
For ArgoCD GitOps deployment, apply the ApplicationSet:
kubectl apply -f argocd/applicationset.yaml
See charts/program-director/README.md for complete Helm documentation.
Architecture
┌─────────────┐ ┌────────────────────────────┐ ┌─────────────┐
│ Radarr │────▶│ Program Director (Go) │────▶│ Tunarr │
│ (Movies) │ │ │ │ (Channels) │
└─────────────┘ │ ┌──────────────────────┐ │ └─────────────┘
│ │ Media Sync Service │ │
┌─────────────┐ │ └──────────────────────┘ │
│ Sonarr │────▶│ ▼ │
│ (TV/Anime) │ │ ┌──────────────────────┐ │
└─────────────┘ │ │ Database (SQLite/PG) │ │
│ └──────────────────────┘ │
┌─────────────┐ │ ▼ │
│ Ollama │◀────│ ┌──────────────────────┐ │
│ (LLM AI) │ │ │ Playlist Generator │ │
└─────────────┘ │ │ + Similarity Scorer │ │
│ └──────────────────────┘ │
│ ▼ │
│ ┌──────────────────────┐ │
│ │ Cooldown Manager │ │
│ └──────────────────────┘ │
└────────────────────────────┘
Key Components
- Media Sync: Periodically fetches media metadata from Radarr/Sonarr
- Database: Caches media and tracks playback history/cooldowns
- Similarity Scorer: Ranks media by genre, keyword, and rating matching
- LLM Integration: Uses Ollama for intelligent content selection
- Playlist Generator: Builds themed lineups respecting cooldowns
- Cooldown Manager: Prevents repetitive content across channels
Development
Setup
# Clone repository
git clone https://github.com/geekxflood/program-director.git
cd program-director
# Install dependencies
go mod download
# Build
go build -o program-director .
# Run locally
./program-director --help
Testing
# Run all tests
go test ./...
# With coverage
go test -cover ./...
# Verbose output
go test -v ./...
Code Quality
# Format code
go fmt ./...
# Lint
golangci-lint run
# Vet
go vet ./...
License
MIT License - see LICENSE for details.
Workflow
- Initial Sync: Run
program-director sync to populate the database with your media
- Configure Themes: Edit
config.yaml with your Tunarr channel IDs and theme definitions
- Generate Playlists: Run
program-director generate --all-themes to create programming
- Schedule Updates: Use
program-director serve to run as a service with automatic scheduling
- Monitor: Check logs and database for playlist history and cooldown tracking
- Tunarr - IPTV server for custom channels
- Radarr - Movie management
- Sonarr - TV show management
- Ollama - Local LLM runtime