Skip to content

Instantly share code, notes, and snippets.

@sabberworm
Last active December 31, 2023 00:05
Show Gist options
  • Save sabberworm/1034051 to your computer and use it in GitHub Desktop.
Save sabberworm/1034051 to your computer and use it in GitHub Desktop.
Maloney
cache
error.log
FROM php:8.2.14-apache
RUN mkdir /var/www/html/cache && chown www-data /var/www/html/cache
VOLUME /var/www/html/cache
RUN chown www-data /var/www/html/cache
COPY index.php /var/www/html/
<?php
date_default_timezone_set('Europe/Zurich');
setlocale(LC_TIME, 'de_CH');
header("Content-Type: application/rss+xml;charset=utf-8");
define('MALONEY_MAX_ENTRIES', isset($_REQUEST['max']) ? (int)$_REQUEST['max'] : 10); //Maximum number of episodes to load into the feed
define('CACHE_DIR', __DIR__ . '/cache');
if(!file_exists(CACHE_DIR)) {
mkdir(CACHE_DIR);
}
function getCached($sUrl) {
$sKey = hash('sha256', $sUrl);
$sFile = CACHE_DIR . "/$sKey";
if(file_exists($sFile)) {
return file_get_contents($sFile);
}
$cCurl = curl_init($sUrl);
curl_setopt($cCurl, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($cCurl, CURLOPT_ENCODING, "gzip");
$sResult = curl_exec($cCurl);
if($sResult === false) {
error_log("Request to $sUrl failed, " . curl_error($cCurl));
curl_close($cCurl);
return null;
}
curl_close($cCurl);
file_put_contents($sFile, $sResult);
return $sResult;
}
function addSimpleAttribute($oDocument, $oChannel, $sAttributeName, $sAttributeValue, $sNamespace = null) {
if($sNamespace === 'http://www.itunes.com/dtds/podcast-1.0.dtd') {
$sAttributeName = "itunes:$sAttributeName";
}
$oAttribute = $oDocument->createElement($sAttributeName);
if ($sAttributeValue) {
$oAttribute->appendChild($oDocument->createTextNode($sAttributeValue));
}
$oChannel->appendChild($oAttribute);
return $oAttribute;
}
$sBaseUrl = 'http://www.srf.ch';
$sItunesNs = 'http://www.itunes.com/dtds/podcast-1.0.dtd';
$aResult = null;
$iOffset = 0;
$aDoneIds = array();
$iCount = 0;
if(!is_dir('./cache')) {
mkdir('./cache');
}
$oDocument = new DOMDocument();
$oRoot = $oDocument->createElement("rss");
$oRoot->setAttribute('version', "2.0");
$oRoot->setAttribute('xmlns:itunes', $sItunesNs);
$oDocument->appendChild($oRoot);
$oChannel = $oDocument->createElement("channel");
addSimpleAttribute($oDocument, $oChannel, 'title', "Philip Maloney");
addSimpleAttribute($oDocument, $oChannel, 'description', "Die haarsträubenden Fälle des Philip Maloney. Der Meisterdetektiv ermittelt immer sonntags von 11 bis 12 Uhr.");
addSimpleAttribute($oDocument, $oChannel, 'link', "$sBaseUrl/audio/maloney");
addSimpleAttribute($oDocument, $oChannel, 'language', "de");
addSimpleAttribute($oDocument, $oChannel, 'ttl', "15");
addSimpleAttribute($oDocument, $oChannel, 'author', "Radio SRF 3", $sItunesNs);
addSimpleAttribute($oDocument, $oChannel, 'subtitle', "Philip Maloney", $sItunesNs);
addSimpleAttribute($oDocument, $oChannel, 'summary', "Die haarsträubenden Fälle des Philip Maloney. Der Meisterdetektiv ermittelt immer sonntags von 11 bis 12 Uhr.", $sItunesNs);
$oRoot->appendChild($oChannel);
$bHasImage = false;
while($iCount < MALONEY_MAX_ENTRIES && ($aResult === null || (isset($aResult[1]) && count($aResult[1]) > 0))) {
$aResult = json_decode(file_get_contents("$sBaseUrl/audio/episodes/10000183/10/$iOffset"));
$sListing = $aResult->content;
preg_match_all("/\/popupaudioplayer\?id=([0-9a-f\-]+)\"/i", $sListing, $aResult, PREG_OFFSET_CAPTURE);
foreach($aResult[1] as $aEpisodeInfo) {
$sEpisodeId = $aEpisodeInfo[0];
$iEpisodeLinkStart = strpos($sListing, '<a href="', $aEpisodeInfo[1]) + strlen('<a href="');
$iEpisodeLinkEnd = strpos($sListing, '"', $iEpisodeLinkStart);
$sEpisodeLink = $sBaseUrl . substr($sListing, $iEpisodeLinkStart, $iEpisodeLinkEnd - $iEpisodeLinkStart);
if(isset($aDoneIds[$sEpisodeId])) {
continue;
}
$aDoneIds[$sEpisodeId] = true;
if($iCount >= MALONEY_MAX_ENTRIES) {
break 2;
}
$iCount++;
$sEpisodeUrl = "https://il.srgssr.ch/integrationlayer/2.0/mediaComposition/byUrn/urn:srf:audio:$sEpisodeId.json?onlyChapters=false&vector=portalplay";
$sEpisode = getCached($sEpisodeUrl);
if(!$sEpisode) {
continue;
}
$oEpisode = json_decode($sEpisode, false);
$oMetadata = $oEpisode->chapterList[0];
// error_log(print_r($oEpisode)); die();
$oPublished = DateTime::createFromFormat(DateTime::ATOM, $oMetadata->date);
$sSubtitle = $oMetadata->lead;
$sDescription = $sSubtitle . "\n\n" . $oMetadata->description;
$sEpisodeDownloadUrl = $oMetadata->resourceList[0]->url;
$oItem = $oDocument->createElement('item');
addSimpleAttribute($oDocument, $oItem, 'title', $oMetadata->title);
addSimpleAttribute($oDocument, $oItem, 'link', $sEpisodeLink);
addSimpleAttribute($oDocument, $oItem, 'description', $sDescription);
addSimpleAttribute($oDocument, $oItem, 'subtitle', $sSubtitle, $sItunesNs);
$oEnclosure = addSimpleAttribute($oDocument, $oItem, 'enclosure', null);
$oEnclosure->setAttribute('url', $sEpisodeDownloadUrl);
$oEnclosure->setAttribute('type', 'audio/mpeg');
$oImage = addSimpleAttribute($oDocument, $oItem, 'image', null, $sItunesNs);
$oImage->setAttribute('href', $oEpisode->episode->imageUrl);
if(!$bHasImage) {
$bHasImage = true;
$oChannelImage = addSimpleAttribute($oDocument, $oChannel, 'image', null);
addSimpleAttribute($oDocument, $oChannelImage, 'url', $oEpisode->episode->imageUrl);
addSimpleAttribute($oDocument, $oChannelImage, 'link', "$sBaseUrl/sendungen/maloney");
addSimpleAttribute($oDocument, $oChannelImage, 'title', $oEpisode->episode->imageTitle);
$oChannelImageITunes = addSimpleAttribute($oDocument, $oChannel, 'image', null, $sItunesNs);
$oChannelImageITunes->setAttribute('href', $oEpisode->episode->imageUrl);
}
$oGuid = addSimpleAttribute($oDocument, $oItem, 'guid', $sEpisodeId);
$oGuid->setAttribute('isPermaLink', 'false');
addSimpleAttribute($oDocument, $oItem, 'pubDate', $oPublished->format(DateTime::RFC2822));
addSimpleAttribute($oDocument, $oItem, 'author', 'Radio SRF 3', $sItunesNs);
$oChannel->appendChild($oItem);
}
$iOffset += 10;
}
$oDocument->formatOutput = true;
print @$oDocument->saveXML();
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment