Czech TV EPG Grabber for XMLTV format with multi-source support
Project description
Czech TV EPG Grabber
Electronic Program Guide (EPG) data grabber in XMLTV format from (not only) Czech television sources. The library supports multiple EPG sources, including Centrum.cz and Blesk.cz, is easily extensible by new EPG sources, and provides both programmatic and command-line interfaces with enhanced programme details including images, cast information, and detailed descriptions.
Features
- 🎯 Multi-source support - Extensible architecture for multiple EPG sources (Centrum.cz, Blesk.cz)
- 📺 XMLTV format - Industry-standard EPG format compatible with Plex, Kodi, and other media centers
- 🖼️ Enhanced programme data - Programme images, cast information, detailed descriptions
- 🏷️ Channel logos - Exact logo URLs from EPG sources with category mapping
- 🇨🇿 Czech language support - Full UTF-8 encoding with proper Czech character handling
- ⚙️ Flexible configuration - Config file or constructor-based configuration
- 🔍 Programme queries - Query specific channel programming by time
- 📅 Multi-day support - Generate EPG data for multiple days ahead
- 🖥️ CLI interface - Command-line tool for easy automation
- 🐍 Python API - Clean programmatic interface for integration
Installation
From PyPI (when published)
pip install epg-grabber
From Source
git clone https://github.com/robco/czech-tv-epg-grabber.git
cd czech-tv-epg-grabber
pip install -e .
Quick Start
Command Line Usage
# Install from source
pip install -e .
# List full usage help
epg-grabber --help
# Generate EPG from default source (Centrum.cz)
epg-grabber
# Generate EPG from Blesk.cz with enhanced details
epg-grabber --source blesk_cz --output enhanced_epg.xml
Python API Usage
from czech_tv_epg import CzechTVEPGGenerator
# Basic usage
generator = CzechTVEPGGenerator()
output_file, stats = generator.generate_epg()
# Get current programme with details
current = generator.get_current_programme("1")
print(f"Now playing: {current['programme']['title']}")
Available EPG sources
| Source | Base URL | Features | API Type |
|---|---|---|---|
| centrum_cz | https://tvprogram.centrum.cz | Channel logos, basic programme info | REST GET |
| blesk_cz | https://tvprogram.blesk.cz | Enhanced details, images, cast, categories | REST POST/GET |
Usage
Command Line Interface
# List full usage help
epg-grabber --help
# List available EPG sources
epg-grabber --list-sources
# List channels with categories
epg-grabber --source blesk_cz --list-channels
# Get current programme with enhanced details
epg-grabber --source blesk_cz --current 62
# Get programme at specific time
epg-grabber --at-time 1 "2025-05-24 20:00"
# Generate EPG with programme images and cast info
epg-grabber --source blesk_cz --output enhanced_epg.xml --days 7
# Generate EPG but hide processing progress bar
epg-grabber --source blesk_cz --output enhanced_epg.xml --days 7 --silent
Python API
from epg_grabber import CzechTVEPGGenerator
from datetime import datetime
# Use Blesk.cz for enhanced programme details
generator = CzechTVEPGGenerator(
source_type="blesk_cz",
base_url="https://tvprogram.blesk.cz"
)
# Get programmes with images and cast info
tips = generator.get_programme_tips_with_images(
date=datetime.now(),
time_from="20:00:00",
time_to="23:59:59"
)
for tip in tips:
print(f"{tip['title']} - {tip['content_type']}")
print(f"Image: {tip['image_url']}")
# Get detailed cast and description
details = generator.get_programme_details(tip['id'])
if details:
print(f"Cast: {[actor['name'] for actor in details['actors'][:3]]}")
Configuration
Using Configuration Files
Centrum.cz config.json
{
"source": {
"type": "centrum_cz",
"base_url": "https://tvprogram.centrum.cz/api"
},
"epg": {
"days_ahead": 5,
"timezone": "+0200"
},
"output": {
"path": "./epg_output",
"filename": "tvguide.xml"
}
}
Blesk.cz config.json
{
"source": {
"type": "blesk_cz",
"base_url": "https://tvprogram.blesk.cz"
},
"epg": {
"days_ahead": 7,
"timezone": "+0200"
},
"output": {
"filename": "enhanced_epg.xml"
}
}
Constructor based configuration
generator = CzechTVEPGGenerator(
source_type="blesk_cz",
base_url="https://tvprogram.blesk.cz",
days_ahead=7,
channels=["62", "63", "64"],
output_filename="my_epg.xml"
)
Using Constructor Parameters
from epg_grabber import CzechTVEPGGenerator
generator = CzechTVEPGGenerator(
source_type="centrum_cz",
base_url="https://tvprogram.centrum.cz/api",
output_path="./epg_files",
output_filename="my_epg.xml",
days_ahead=7,
channels=,
log_level="DEBUG"
)
Enhanced XMLTV Output
The generated XMLTV includes:
- Programme images as tags
- Cast information in sections
- Content types as sub-titles (Film, Seriál, etc.)
- Enhanced descriptions from detailed API calls
- Episode information when available
<programme start="20250526200000 +0200" stop="20250526213000 +0200" channel="ch_62">
<title lang="cs">Hrabě Monte Christo (3/4)</title>
<sub-title lang="cs">Seriál</sub-title>
<desc lang="cs">Jeden z nejkrásnějších příběhů všech dob...</desc>
<icon src="https://ms2.ostium.cz/instance/tv-program/jm9Vdzuj/h230w170t.jpg"/>
<credits>
<actor>Jacques Weber</actor>
<actor>Carla Romanelli</actor>
</credits>
</programme>
Usage examples
Grab EPG and store as XMLTV file
# Generate enhanced EPG for Plex
epg-grabber --source blesk_cz --output /path/to/plex/tvguide.xml --days 7
Grab EPG and show progress
epg-grabber --days 6
Fetching 6 days of programmes: 100%|███████| 864/864 [00:28<00:00, 30.45items/s]
Creating XMLTV programmes: 1%| | 163/25008 [00:29<1:15:13, 5.50items/s]
Automated updates
# Daily EPG updates via cron
0 6 * * * /usr/local/bin/epg-grabber --source blesk_cz --output /var/epg/tvguide.xml --days 7
Development
Adding new EPG sources
from epg_grabber.base import EPGSource, Channel, Programme
from epg_grabber.sources import EPGSourceFactory
class MyEPGSource(EPGSource):
def fetch_channels(self):
# Implement channel fetching
pass
def fetch_programmes(self, date, channel_ids):
# Implement programme fetching
pass
def get_channel_logo_url(self, channel_id):
# Implement logo URL generation
pass
# Register the new source
EPGSourceFactory.register_source('mysource', MyEPGSource)
Error handling
from epg_grabber import CzechTVEPGGenerator
from epg_grabber.exceptions import EPGError, ConfigError, APIError
try:
generator = CzechTVEPGGenerator(source_type="blesk_cz")
result = generator.get_current_programme("62")
except ConfigError as e:
print(f"Configuration error: {e}")
except APIError as e:
print(f"API error: {e}")
except EPGError as e:
print(f"EPG error: {e}")
Testing
Running Tests
# Install development dependencies
pip install -e ".[dev]"
# Run all tests
pytest
# Run tests with coverage
pytest --cov=epg_grabber --cov-report=term-missing
# Run specific test file
pytest tests/test_base.py -v
# Run tests with coverage report
pytest --cov=epg_grabber --cov-report=html
Release Notes
2.1.0, 28-May-2025 -- Progress bar shown when used "--show-progress" param 2.0.1, 28-May-2025 -- Versions handling update 2.0.0, 27-May-2025 -- blesk.cz as EPG source added with rich programme's data available (incl. programme's poster and description) 1.0.0, 25-May-2025 -- Initial release, centrum.cz EPG source
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file epg_grabber-2.1.0.tar.gz.
File metadata
- Download URL: epg_grabber-2.1.0.tar.gz
- Upload date:
- Size: 45.5 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.7
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
e1de3f53c497642368841051da1da439ebb1fa379fe8fe72c42afd6a88f5540c
|
|
| MD5 |
d5d3b3c428e8c78b08ac9345ffacd7e9
|
|
| BLAKE2b-256 |
aff76e22789db93a5147421b4f5319396430614718309031f204ece749a1a8f0
|
Provenance
The following attestation bundles were made for epg_grabber-2.1.0.tar.gz:
Publisher:
python-publish.yml on robco/czech-tv-epg-grabber
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
epg_grabber-2.1.0.tar.gz -
Subject digest:
e1de3f53c497642368841051da1da439ebb1fa379fe8fe72c42afd6a88f5540c - Sigstore transparency entry: 708543823
- Sigstore integration time:
-
Permalink:
robco/czech-tv-epg-grabber@44cca45b61aee0678dc250e2e2440c106352ed6b -
Branch / Tag:
refs/heads/main - Owner: https://github.com/robco
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
python-publish.yml@44cca45b61aee0678dc250e2e2440c106352ed6b -
Trigger Event:
workflow_dispatch
-
Statement type:
File details
Details for the file epg_grabber-2.1.0-py3-none-any.whl.
File metadata
- Download URL: epg_grabber-2.1.0-py3-none-any.whl
- Upload date:
- Size: 57.1 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.7
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
7c9ea70e7353b81aabbe0d994d79c0c2bc42af545ce9f7e263f8fb8da03dcdfe
|
|
| MD5 |
19df7b281b045b558d2882f47683b3b2
|
|
| BLAKE2b-256 |
e46d9efa7a532b6766140a1c496be37133c71b3cf9ff9e5881f8d265c281d801
|
Provenance
The following attestation bundles were made for epg_grabber-2.1.0-py3-none-any.whl:
Publisher:
python-publish.yml on robco/czech-tv-epg-grabber
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
epg_grabber-2.1.0-py3-none-any.whl -
Subject digest:
7c9ea70e7353b81aabbe0d994d79c0c2bc42af545ce9f7e263f8fb8da03dcdfe - Sigstore transparency entry: 708543827
- Sigstore integration time:
-
Permalink:
robco/czech-tv-epg-grabber@44cca45b61aee0678dc250e2e2440c106352ed6b -
Branch / Tag:
refs/heads/main - Owner: https://github.com/robco
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
python-publish.yml@44cca45b61aee0678dc250e2e2440c106352ed6b -
Trigger Event:
workflow_dispatch
-
Statement type: