<?php | |
//Convert JSONfeed to RSS in a single function as a drop-in to make adding JSONfeed | |
//support to an aggregator easier | |
function convert_jsonfeed_to_rss($content = NULL, $max = NULL) | |
{ | |
//Test if the content is actual JSON | |
json_decode($content); | |
if( json_last_error() !== JSON_ERROR_NONE) return FALSE; | |
//Now, is it valid JSONFeed? | |
$jsonFeed = json_decode($content, TRUE); | |
if (!isset($jsonFeed['version'])) return FALSE; | |
if (!isset($jsonFeed['title'])) return FALSE; | |
if (!isset($jsonFeed['items'])) return FALSE; | |
//Decode the feed to a PHP array | |
$jf = json_decode($content, TRUE); | |
//Get the latest item publish date to use as the channel pubDate | |
$latestDate = 0; | |
foreach ($jf['items'] as $item) { | |
if (strtotime($item['date_published']) > $latestDate) $latestDate = strtotime($item['date_published']); | |
} | |
$lastBuildDate = date(DATE_RSS, $latestDate); | |
//Create the RSS feed | |
$xmlFeed = new SimpleXMLElement('<?xml version="1.0" encoding="UTF-8"?><rss version="2.0"></rss>'); | |
$xmlFeed->addChild("channel"); | |
//Required elements | |
$xmlFeed->channel->addChild("title", $jf['title']); | |
$xmlFeed->channel->addChild("pubDate", $lastBuildDate); | |
$xmlFeed->channel->addChild("lastBuildDate", $lastBuildDate); | |
//Optional elements | |
if (isset($jf['description'])) $xmlFeed->channel->description = $jf['description']; | |
if (isset($jf['home_page_url'])) $xmlFeed->channel->link = $jf['home_page_url']; | |
//Items | |
foreach ($jf['items'] as $item) { | |
$newItem = $xmlFeed->channel->addChild('item'); | |
//Standard stuff | |
if (isset($item['id'])) $newItem->addChild('guid', $item['id']); | |
if (isset($item['title'])) $newItem->addChild('title', $item['title']); | |
if (isset($item['content_text'])) $newItem->addChild('description', $item['content_text']); | |
if (isset($item['content_html'])) $newItem->addChild('description', $item['content_html']); | |
if (isset($item['date_published'])) $newItem->addChild('pubDate', $item['date_published']); | |
if (isset($item['url'])) $newItem->addChild('link', $item['url']); | |
//Enclosures? | |
if(isset($item['attachments'])) { | |
foreach($item['attachments'] as $attachment) { | |
$enclosure = $newItem->addChild('enclosure'); | |
$enclosure['url'] = $attachment['url']; | |
$enclosure['type'] = $attachment['mime_type']; | |
$enclosure['length'] = $attachment['size_in_bytes']; | |
} | |
} | |
} | |
//Make the output pretty | |
$dom = new DOMDocument("1.0"); | |
$dom->preserveWhiteSpace = false; | |
$dom->formatOutput = true; | |
$dom->loadXML($xmlFeed->asXML()); | |
return $dom->saveXML(); | |
} | |
$content = @file_get_contents("http://timetable.manton.org/feed.json"); | |
echo convert_jsonfeed_to_rss($content)."\n"; |
Oups... I'm having issues with the JSON from https://occitania.social/api/v1/timelines/public?local=true&only_media=false : produces null RSS. Any idea?
@aalcaine whilst that URL returns valid JSON data, it is not a valid JSON Feed (which is what this script expects to be given).
that URL returns valid JSON data, it is not a valid JSON Feed
Thank you @gingerbeardman :-( Let's see if Mastodon fixes that...
@aalcaine doubtful. Their API is designed to produce JSON data, not JSON Feeds.
They provid per-user RSS already, but not for the public timeline. Anyway, I think a public timeline would be too busy to make sense as an RSS feed.
If you still want to do it, a solution for you is to write some code to convert/wrap the Mastodon JSON data into a feed, and then you will be able to use this script. Good luck.
Thanks for this! Just used it to gain access to a JSON feed in my FreshRSS installation.