User:Plrk/Watchlist RSS feed in PHP (with diff links)

From Meta, a Wikimedia project coordination wiki

The MediaWiki API now provides a somewhat easy way to get an RSS feed of your watchlist, see my other script. However, it this not include diff links - which is why I hacked together the following. Like the other script, it connects to the MediaWiki API and logs in, but instead of fetching the watchlist feed it fetches a serialized version of the watchlist and then creates it's own RSS feed.

Installation[edit]

Copy this code into a .php file on your PHP-running web server, after editing your username/password/preferred wiki accordingly. Point your feed aggregator to the PHP script. That's it!

The code[edit]

<?
////////////////////////////////////////////////////////////
// CONFIGURATION ///////////////////////////////////////////
////////////////////////////////////////////////////////////

// Variable you should edit
$mediawiki_url = "http://en.wikipedia.org/"; // the wiki you want to fetch from. do not forget the trailing slash. any mediawiki installation will work!
$credentials = array();
$credentials['lgname'] = ""; // your username
$credentials['lgpassword'] = ""; // your password

// Variables you should not edit
$login_url = "w/api.php?format=php&action=login";
$watchlist_url = "w/api.php?action=query&list=watchlist&format=php&wlallrev=yes&wllimit=10&wlprop=ids|title|user|comment|timestamp|sizes";

////////////////////////////////////////////////////////////
// LOGIN ///////////////////////////////////////////////////
////////////////////////////////////////////////////////////
$ch = curl_init(); // initializing curl, creating a curl resource
curl_setopt($ch, CURLOPT_URL, $mediawiki_url . $login_url); // set URL
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1); // we want the transfer to return a string
curl_setopt($ch, CURLOPT_POST, TRUE); // we are going to post something
curl_setopt($ch, CURLOPT_POSTFIELDS, $credentials); // we are going to post the array "credentials"
$output = curl_exec($ch); // $output now contains the output string
curl_close($ch); // we close curl resource to free up system resources

// if everything has been done right, $output now contains a serialized array with the
// information we need when we post the request for the watchlist.
$cookie = unserialize($output); // unserialize the output

////////////////////////////////////////////////////////////
// WATCHLIST ///////////////////////////////////////////////
////////////////////////////////////////////////////////////
$wl = curl_init(); // initializing curl, creating a curl resource
curl_setopt($wl, CURLOPT_URL, $mediawiki_url . $watchlist_url); // set URL
curl_setopt($wl, CURLOPT_COOKIE,	$cookie['login']['cookieprefix'] . "UserName=" . $cookie['login']['lgusername'] . "; " .
	$cookie['login']['cookieprefix'] . "UserID=" . $cookie['login']['lguserid'] . "; " .
	$cookie['login']['cookieprefix'] . "Token=" . $cookie['login']['lgtoken'] . "; " .
	$cookie['login']['cookieprefix'] . "_session=" . $cookie['login']['sessionid']); // set the cookies to be used in the request
curl_setopt($wl, CURLOPT_RETURNTRANSFER, 1); // we want the transfer to return a string
$output = curl_exec($wl); // $output now contains the output string
curl_close($wl); // we close curl resource to free up system resources

// if everything worked, $output now contains a serialized array with the watchlist!
$watchlist = unserialize($output); // unserialize the output

////////////////////////////////////////////////////////////
// OUTPUT //////////////////////////////////////////////////
////////////////////////////////////////////////////////////
header("Content-Type: application/xml");
echo "<?xml version=\"1.0\" encoding=\"iso-8859-1\"?>
<rdf:RDF xmlns:rdf=\"http://www.w3.org/1999/02/22-rdf-syntax-ns#\" xmlns=\"http://purl.org/rss/1.0/\" xmlns:dc=\"http://purl.org/dc/elements/1.1/\">
<channel rdf:about=\"http://www.yakujo.se/news/\">
	<title>" . $credentials['lgname'] . "s watchlist from " . $mediawiki_url . "</title>
	<link>" . $mediawiki_url . "wiki/Special:Watchlist</link>
	<description>The last edited pages on " . $credentials['lgname'] . "s watchlist.</description>
	
	<items>
		<rdf:Seq>
";
foreach($watchlist['query']['watchlist'] as $row){
	echo "<rdf:li resource=\"" . $row['revid'] . "\" />\n";
}
echo "
		</rdf:Seq>

	</items>
</channel>
";
$revisions = array();
foreach($watchlist['query']['watchlist'] as $row){
	if(strtolower($row['user']) == strtolower($credentials['lgname'])){
		if($row['revid'] > $revisions[utf8_decode($row['title'])]){
			$revisions[utf8_decode($row['title'])] = $row['revid'];
		}
	}
}

foreach($watchlist['query']['watchlist'] as $row){
	if((isset($revisions[utf8_decode($row['title'])]) && $row['revid'] >= $revisions[utf8_decode($row['title'])]) || !isset($revisions[utf8_decode($row['title'])])){
echo "	<item rdf:about=\"" . $row['revid'] . "\">\n";
echo "		<title>" . utf8_decode($row['title']) . "</title>\n";
echo "		<link>" . $mediawiki_url . "w/index.php?diff=prev&oldid=" . $row['revid'] . "</link>\n";
echo "		<dc:creator>" . $row['user'] . "</dc:creator>\n";
echo "		<dc:date>" . $row['timestamp'] . "</dc:date>\n";

echo "		<description>\n";
				$desc = "			Edit of <a href=\"" . $mediawiki_url . "wiki/" . str_replace(" ", "_", utf8_decode($row['title'])) . "\">" . utf8_decode($row['title']) . "</a>, by <a href=\"" . $mediawiki_url . "wiki/User:" . urlencode(str_replace(" ", "_", $row['user'])) . "\">" . $row['user'] . "</a> at " . $row['timestamp'] . " (<a href=\"" . $mediawiki_url . "w/index.php?diff=prev&oldid=" . $row['revid'] . "\">" . (intval($row['newlen']) - intval($row['oldlen'])) . "</a>)";
				if(strlen($row['comment']) > 0){
					$desc .= "<br /><br /><i>" . utf8_decode($row['comment']) . "</i>";
				}
				$desc .= "\n";
	echo htmlspecialchars($desc);
echo "		</description>\n";
echo "	</item>\n";
	}
}
echo "</rdf:RDF>\n";
?>