Files
tvj-epg/epg/engine.py
T
Lyncoln 8529fca032
Build and Publish TVJ EPG Image / build (push) Successful in 29s
Add health reporting, container probe, and JNN channel support
2026-09-10 10:38:21 -04:00

68 lines
2.5 KiB
Python

"""Fetch each provider feed once and publish selected channels."""
from datetime import datetime, timezone
import sys
from epg.config import load
from epg.health import record
from epg.providers import PROVIDERS
from epg.writers import atomic_write, m3u, xmltv
def run(environ=None):
channels, xml_path, m3u_path = load(environ)
feeds = {}
schedules = {}
report = {'checked_at': datetime.now(timezone.utc).isoformat(),
'success': False, 'providers': {}, 'channels': {}}
errors = []
for channel in channels:
provider = PROVIDERS[channel.provider]
key = (channel.provider, channel.feed_url, channel.tenant)
if key not in feeds:
try:
feeds[key] = provider.fetch(channel.feed_url, channel.tenant)
report['providers'][channel.provider] = {'status': 'healthy'}
except Exception as error:
feeds[key] = error
report['providers'][channel.provider] = {
'status': 'unhealthy', 'error': type(error).__name__}
try:
if isinstance(feeds[key], Exception):
raise feeds[key]
schedules[channel.id] = provider.programmes(feeds[key], channel.channel_id)
report['channels'][channel.id] = {'status': 'healthy'}
except Exception as error:
errors.append(error)
report['channels'][channel.id] = {
'status': 'unhealthy', 'error': type(error).__name__}
if errors:
record(xml_path, report)
raise errors[0]
# Fetch and render everything before replacing any previous output.
try:
xml_content = xmltv(channels, schedules)
playlist = m3u(channels)
atomic_write(xml_path, xml_content)
atomic_write(m3u_path, playlist)
report['success'] = True
except Exception as error:
report['output_error'] = type(error).__name__
raise
finally:
record(xml_path, report)
print(f"[{datetime.now().astimezone().isoformat()}] Wrote {xml_path} and {m3u_path}", flush=True)
for channel in channels:
programmes = schedules[channel.id]
print(f"{channel.name}: {len(programmes)} programmes, through {max(p.stop for p in programmes).isoformat()}", flush=True)
def main():
try:
run()
except Exception as error:
print(f"EPG update failed: {error}", file=sys.stderr, flush=True)
sys.exit(1)
if __name__ == "__main__":
main()