#!/usr/bin/env php
<?php
error_reporting(0);
ini_set('memory_limit', '-1');
$base = 'http://';
$mac = '00:1A:79:30:6F:DD';
$out_file = 'epg.xml';
function curl_req($url, $headers = [], $cookies = '', $timeout = 15) {
$ch = curl_init($url);
if ($headers) curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
if ($cookies) curl_setopt($ch, CURLOPT_COOKIE, $cookies);
curl_setopt_array($ch, [
CURLOPT_RETURNTRANSFER => true,
CURLOPT_FOLLOWLOCATION => true,
CURLOPT_TIMEOUT => $timeout,
CURLOPT_CONNECTTIMEOUT => 6,
CURLOPT_SSL_VERIFYHOST => 0,
CURLOPT_SSL_VERIFYPEER => 0
]);
$res = curl_exec($ch);
$code = curl_getinfo($ch, CURLINFO_HTTP_CODE);
curl_close($ch);
return [$res, $code];
}
function extract_token($body) {
$j = json_decode($body, true);
if (isset($j['js']['token'])) return $j['js']['token'];
if (preg_match('/"token"\s*:\s*"([^"]+)"/', $body, $m)) return $m[1];
return null;
}
function mag_headers($token = null) {
$h = [
"User-Agent: Mozilla/5.0 (QtEmbedded; U; Linux; C) AppleWebKit/533.3 (KHTML, like Gecko) MAG254 stbapp ver: 2 rev: 250 Safari/533.3",
"X-User-Agent: Model: MAG254; Link: Ethernet",
"Accept: application/json, text/javascript, */*; q=0.01",
"X-Requested-With: XMLHttpRequest",
"Connection: Keep-Alive",
"Cache-Control: no-store, no-cache, must-revalidate"
];
if ($token) $h[] = "Authorization: Bearer $token";
return $h;
}
echo "Portal: $base\n";
echo "MAC: $mac\n";
$cookies = "mac=$mac; stb_lang=en; timezone=Europe/Berlin";
$handshake_urls = [
"$base/portal.php?action=handshake&type=stb&token=&JsHttpRequest=1-xml",
"$base/portal.php?type=stb&action=handshake&token=&JsHttpRequest=1-xml",
"$base/stalker_portal/c/portal.php?action=handshake&type=stb&token=&JsHttpRequest=1-xml"
];
$token = null;
foreach ($handshake_urls as $url) {
list($body, $code) = curl_req($url, array_merge(mag_headers(), ["Authorization: MAC $mac"]), $cookies);
if ($code == 200 && $body) {
$token = extract_token($body);
if ($token) break;
}
}
if (!$token) {
echo "Handshake failed\n";
exit;
}
$hdr = mag_headers($token);
$epg_data = [];
$epg_urls = [
"$base/load.php?type=epg&action=get_simple_data_table&JsHttpRequest=1-xml",
"$base/portal.php?type=epg&action=get_simple_data_table&JsHttpRequest=1-xml",
"$base/portal.php?type=itv&action=get_epg_info&period=72&JsHttpRequest=1-xml"
];
foreach ($epg_urls as $url) {
list($body, $code) = curl_req($url, $hdr, $cookies, 25);
if ($code == 200 && $body) {
$j = json_decode($body, true);
if (isset($j['js']['data'])) {
$epg_data = $j['js']['data'];
break;
}
}
}
if (empty($epg_data)) {
$chan_url = "$base/portal.php?type=itv&action=get_all_channels&JsHttpRequest=1-xml";
list($chan_body, $chan_code) = curl_req($chan_url, $hdr, $cookies, 25);
if ($chan_code == 200 && $chan_body) {
$c = json_decode($chan_body, true);
if (isset($c['js']['data'])) {
$channels = $c['js']['data'];
foreach ($channels as $ch) {
if (!isset($ch['id'])) continue;
$cid = $ch['id'];
$url = "$base/portal.php?type=itv&action=get_short_epg&ch_id=$cid&JsHttpRequest=1-xml";
list($b, $cc) = curl_req($url, $hdr, $cookies, 10);
if ($cc == 200 && $b) {
$d = json_decode($b, true);
if (isset($d['js']['data'])) $epg_data[$cid] = $d['js']['data'];
}
}
}
}
}
if (empty($epg_data)) {
echo "No EPG data found\n";
exit;
}
$xml = new DOMDocument('1.0', 'UTF-8');
$xml->formatOutput = true;
$tv = $xml->createElement('tv');
$tv->setAttribute('generator-info-name', 'MAG-EPG');
$xml->appendChild($tv);
foreach (array_keys($epg_data) as $cid) {
$c = $xml->createElement('channel');
$c->setAttribute('id', $cid);
$dn = $xml->createElement('display-name', $cid);
$c->appendChild($dn);
$tv->appendChild($c);
}
foreach ($epg_data as $cid => $programs) {
if (!is_array($programs)) continue;
foreach ($programs as $p) {
$start = gmdate('YmdHis O', intval($p['start_timestamp']));
$stop = gmdate('YmdHis O', intval($p['stop_timestamp']));
$prog = $xml->createElement('programme');
$prog->setAttribute('start', $start);
$prog->setAttribute('stop', $stop);
$prog->setAttribute('channel', $cid);
$t = $xml->createElement('title', $p['name'] ?? '');
$prog->appendChild($t);
if (!empty($p['descr'])) {
$d = $xml->createElement('desc', $p['descr']);
$prog->appendChild($d);
}
$tv->appendChild($prog);
}
}
$xml->save($out_file);
echo "EPG saved to $out_file\n";