Initial commit: TVJ EPG script + Dockerfile
This commit is contained in:
22
Dockerfile
Normal file
22
Dockerfile
Normal file
@@ -0,0 +1,22 @@
|
|||||||
|
# Use slim Python image
|
||||||
|
FROM python:3.11-slim
|
||||||
|
|
||||||
|
# Set working directory
|
||||||
|
WORKDIR /app
|
||||||
|
|
||||||
|
# Copy script
|
||||||
|
COPY tvj_epg.py .
|
||||||
|
|
||||||
|
# Install requests
|
||||||
|
RUN pip install --no-cache-dir requests
|
||||||
|
|
||||||
|
# Default update interval (hours)
|
||||||
|
ENV UPDATE_INTERVAL=6
|
||||||
|
|
||||||
|
# Run the script in a loop, using UPDATE_INTERVAL env variable
|
||||||
|
CMD sh -c 'while true; do \
|
||||||
|
echo "$(date) - Updating TVJ EPG..."; \
|
||||||
|
python tvj_epg.py; \
|
||||||
|
echo "$(date) - Sleeping for ${UPDATE_INTERVAL} hours..."; \
|
||||||
|
sleep $((${UPDATE_INTERVAL}*3600)); \
|
||||||
|
done'
|
||||||
67
tvj_epg.py
Normal file
67
tvj_epg.py
Normal file
@@ -0,0 +1,67 @@
|
|||||||
|
import requests
|
||||||
|
import xml.etree.ElementTree as ET
|
||||||
|
from datetime import datetime, timezone
|
||||||
|
|
||||||
|
# 1SpotMedia API config
|
||||||
|
API_URL = "https://www.1spotmedia.com/index.php/api/epg/get_epg_timeline_by_id"
|
||||||
|
CHANNEL_ID = "66e312890478fd00235244cb"
|
||||||
|
TVG_ID = "TVJ.jm@SD"
|
||||||
|
|
||||||
|
# Output file
|
||||||
|
OUTPUT_FILE = "/app/output/tvj.xml"
|
||||||
|
|
||||||
|
# Record script start time
|
||||||
|
script_run_time = datetime.now(tz=timezone.utc)
|
||||||
|
print(f"[{script_run_time.strftime('%Y-%m-%d %H:%M:%S UTC')}] Script run started.")
|
||||||
|
|
||||||
|
# Fetch EPG data
|
||||||
|
resp = requests.get(API_URL, params={"id": CHANNEL_ID}, headers={"User-Agent": "Mozilla/5.0"})
|
||||||
|
data = resp.json()
|
||||||
|
|
||||||
|
# Determine last update time from API if available
|
||||||
|
if isinstance(data, dict) and "lastUpdate" in data:
|
||||||
|
# API may provide a timestamp in milliseconds
|
||||||
|
api_last_update_ts = data["lastUpdate"]
|
||||||
|
last_update_time = datetime.fromtimestamp(api_last_update_ts / 1000, tz=timezone.utc)
|
||||||
|
elif isinstance(data, list) and len(data) > 0:
|
||||||
|
# Fallback: use the latest program endTime
|
||||||
|
last_update_time = datetime.fromtimestamp(max(p["endTime"] for p in data) / 1000, tz=timezone.utc)
|
||||||
|
else:
|
||||||
|
last_update_time = script_run_time
|
||||||
|
|
||||||
|
# Ensure we have a list of programs
|
||||||
|
if isinstance(data, dict):
|
||||||
|
programs = data.get("data", [])
|
||||||
|
elif isinstance(data, list):
|
||||||
|
programs = data
|
||||||
|
else:
|
||||||
|
programs = []
|
||||||
|
|
||||||
|
# Create XMLTV root
|
||||||
|
tv = ET.Element("tv", attrib={"generator-info-name": "custom-1spotmedia"})
|
||||||
|
|
||||||
|
# Add channel
|
||||||
|
channel = ET.SubElement(tv, "channel", id=TVG_ID)
|
||||||
|
ET.SubElement(channel, "display-name").text = "TVJ SD"
|
||||||
|
|
||||||
|
# Add programs
|
||||||
|
for p in programs:
|
||||||
|
start = datetime.fromtimestamp(p["startTime"] / 1000, tz=timezone.utc)
|
||||||
|
stop = datetime.fromtimestamp(p["endTime"] / 1000, tz=timezone.utc)
|
||||||
|
|
||||||
|
programme = ET.SubElement(tv, "programme",
|
||||||
|
start=start.strftime("%Y%m%d%H%M%S +0000"),
|
||||||
|
stop=stop.strftime("%Y%m%d%H%M%S +0000"),
|
||||||
|
channel=TVG_ID)
|
||||||
|
ET.SubElement(programme, "title").text = p["title"]
|
||||||
|
if "description" in p:
|
||||||
|
ET.SubElement(programme, "desc").text = p["description"]
|
||||||
|
|
||||||
|
# Write XMLTV file
|
||||||
|
tree = ET.ElementTree(tv)
|
||||||
|
tree.write(OUTPUT_FILE, encoding="utf-8", xml_declaration=True)
|
||||||
|
|
||||||
|
# Log completion with timestamps
|
||||||
|
completion_time = datetime.now(tz=timezone.utc)
|
||||||
|
print(f"[{completion_time.strftime('%Y-%m-%d %H:%M:%S UTC')}] XMLTV guide updated successfully: {OUTPUT_FILE}")
|
||||||
|
print(f"Summary: Script run time = {script_run_time.strftime('%Y-%m-%d %H:%M:%S UTC')}, Last guide update from API = {last_update_time.strftime('%Y-%m-%d %H:%M:%S UTC')}")
|
||||||
Reference in New Issue
Block a user