2011-12-13 12:29:05 +01:00
|
|
|
<?php
|
|
|
|
|
|
|
|
// By Alphalogic (aka Flo Solcher) alpha@alphalogic.org
|
|
|
|
|
|
|
|
|
|
|
|
if (IN_serendipity !== true) {
|
|
|
|
die ("Don't hack!");
|
|
|
|
}
|
|
|
|
|
|
|
|
// Probe for a language include with constants. Still include defines later on, if some constants were missing
|
|
|
|
$probelang = dirname(__FILE__) . '/' . $serendipity['charset'] . 'lang_' . $serendipity['lang'] . '.inc.php';
|
|
|
|
if (file_exists($probelang)) {
|
|
|
|
include $probelang;
|
|
|
|
}
|
|
|
|
|
|
|
|
include_once dirname(__FILE__) . '/lang_en.inc.php';
|
|
|
|
|
|
|
|
class s9y_audioscrobbler_XMLParser {
|
|
|
|
function parseXML($xml_content, $forced_encoding = null) {
|
|
|
|
$xml_parser = xml_parser_create();
|
|
|
|
xml_parser_set_option ($xml_parser, XML_OPTION_TARGET_ENCODING, 'UTF-8');
|
|
|
|
xml_parser_set_option ($xml_parser, XML_OPTION_CASE_FOLDING, 1);
|
|
|
|
xml_parser_set_option ($xml_parser, XML_OPTION_SKIP_WHITE, 0);
|
|
|
|
$utf8_content = serendipity_utf8_encode($xml_content);
|
|
|
|
xml_parse_into_struct($xml_parser, $utf8_content, $xml_array);
|
|
|
|
xml_parser_free($xml_parser);
|
|
|
|
return $xml_array;
|
|
|
|
}
|
2016-09-22 16:03:33 +02:00
|
|
|
|
2011-12-13 12:29:05 +01:00
|
|
|
function getXMLArray($file, $forced_encoding = null) {
|
2016-09-22 16:03:33 +02:00
|
|
|
if (function_exists('serendipity_request_url')) {
|
|
|
|
$data = serendipity_request_url($file);
|
|
|
|
if (empty($data)) return false;
|
|
|
|
} else {
|
|
|
|
require_once (defined('S9Y_PEAR_PATH') ? S9Y_PEAR_PATH : S9Y_INCLUDE_PATH . 'bundled-libs/') . 'HTTP/Request.php';
|
|
|
|
$req = new HTTP_Request($file);
|
|
|
|
if (PEAR::isError($req->sendRequest()) || $req->getResponseCode() != '200') {
|
|
|
|
if ( ini_get( "allow_url_fopen")) {
|
|
|
|
$data = file_get_contents($file);
|
|
|
|
} else {
|
|
|
|
$data = "";
|
|
|
|
}
|
2011-12-13 12:29:05 +01:00
|
|
|
} else {
|
2016-09-22 16:03:33 +02:00
|
|
|
$data = $req->getResponseBody();
|
2011-12-13 12:29:05 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
if (trim($data)== '') return false;
|
|
|
|
return $this->parseXML($data, $forced_encoding);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
class serendipity_plugin_audioscrobbler extends serendipity_plugin {
|
|
|
|
|
|
|
|
var $title = PLUGIN_AUDIOSCROBBLER_TITLE;
|
|
|
|
var $scrobbler_error = array();
|
|
|
|
var $songs = array();
|
|
|
|
var $scrobblercache;
|
|
|
|
var $number;
|
|
|
|
var $username;
|
|
|
|
var $cachetime;
|
|
|
|
var $utcdifference;
|
|
|
|
var $read_scrobbler_feed = false;
|
|
|
|
var $scrobblerlastupdate;
|
|
|
|
|
|
|
|
function introspect(&$propbag) {
|
|
|
|
$this->title = $this->get_config('sidebartitle', $this->title);
|
|
|
|
|
|
|
|
$propbag->add('name', PLUGIN_AUDIOSCROBBLER_TITLE);
|
|
|
|
$propbag->add('description', PLUGIN_AUDIOSCROBBLER_TITLE_BLAHBLAH);
|
|
|
|
$propbag->add('stackable', true);
|
|
|
|
$propbag->add('author', 'Flo Solcher');
|
2016-09-22 16:03:33 +02:00
|
|
|
$propbag->add('version', '1.25.2');
|
2011-12-13 12:29:05 +01:00
|
|
|
$propbag->add('requirements', array(
|
|
|
|
'serendipity' => '0.8',
|
|
|
|
'smarty' => '2.6.7',
|
|
|
|
'php' => '4.1.0'
|
|
|
|
));
|
|
|
|
$propbag->add('groups', array('FRONTEND_EXTERNAL_SERVICES'));
|
|
|
|
$propbag->add('configuration', array( 'number',
|
|
|
|
'sidebartitle',
|
|
|
|
'username',
|
|
|
|
'songlink',
|
|
|
|
'artistlink',
|
|
|
|
'newwindow',
|
|
|
|
'cachetime',
|
|
|
|
'dateformat',
|
|
|
|
'utcdifference',
|
|
|
|
'spacer',
|
|
|
|
'profiletitle',
|
|
|
|
'formatstring',
|
|
|
|
'formatstring_block',
|
|
|
|
'lastupdate',
|
|
|
|
'forced',
|
|
|
|
'stack'
|
|
|
|
));
|
|
|
|
}
|
|
|
|
|
|
|
|
function introspect_config_item($name, &$propbag) {
|
|
|
|
switch($name) {
|
|
|
|
|
|
|
|
case 'lastupdate': case 'forced':
|
|
|
|
$propbag->add('type', 'hidden');
|
|
|
|
$propbag->add('default', 0);
|
|
|
|
break;
|
|
|
|
|
|
|
|
case 'number':
|
|
|
|
$propbag->add('type', 'string');
|
|
|
|
$propbag->add('name', PLUGIN_AUDIOSCROBBLER_NUMBER);
|
|
|
|
$propbag->add('description', PLUGIN_AUDIOSCROBBLER_NUMBER_BLAHBLAH);
|
|
|
|
$propbag->add('default', '0');
|
|
|
|
break;
|
|
|
|
|
|
|
|
case 'sidebartitle':
|
|
|
|
$propbag->add('type', 'string');
|
|
|
|
$propbag->add('name', TITLE);
|
|
|
|
$propbag->add('description', TITLE_FOR_NUGGET);
|
|
|
|
$propbag->add('default', '');
|
|
|
|
break;
|
|
|
|
|
|
|
|
case 'username':
|
|
|
|
$propbag->add('type', 'string');
|
|
|
|
$propbag->add('name', PLUGIN_AUDIOSCROBBLER_USERNAME);
|
|
|
|
$propbag->add('description', PLUGIN_AUDIOSCROBBLER_USERNAME_BLAHBLAH);
|
|
|
|
$propbag->add('default', '');
|
|
|
|
break;
|
|
|
|
|
|
|
|
case 'stack':
|
|
|
|
$propbag->add('type', 'boolean');
|
|
|
|
$propbag->add('name', PLUGIN_AUDIOSCROBBLER_STACK);
|
|
|
|
$propbag->add('description', PLUGIN_AUDIOSCROBBLER_STACK_BLAHBLAH);
|
|
|
|
$propbag->add('default', true);
|
|
|
|
break;
|
|
|
|
|
|
|
|
case 'songlink':
|
|
|
|
$propbag->add('type', 'boolean');
|
|
|
|
$propbag->add('name', PLUGIN_AUDIOSCROBBLER_SONGLINK);
|
|
|
|
$propbag->add('description', PLUGIN_AUDIOSCROBBLER_SONGLINK_BLAHBLAH);
|
|
|
|
$propbag->add('default', '1');
|
|
|
|
break;
|
|
|
|
|
|
|
|
case 'artistlink':
|
|
|
|
$propbag->add('type', 'select');
|
|
|
|
$propbag->add('select_values', array('0' => PLUGIN_AUDIOSCROBBLER_ARTISTLINK_NONE,
|
|
|
|
'1' => PLUGIN_AUDIOSCROBBLER_ARTISTLINK_SCROBBLER,
|
|
|
|
'2' => PLUGIN_AUDIOSCROBBLER_ARTISTLINK_MUSICBRAINZ_ELSE_NONE,
|
|
|
|
'3' => PLUGIN_AUDIOSCROBBLER_ARTISTLINK_MUSICBRAINZ_ELSE_SCROBBLER
|
|
|
|
));
|
|
|
|
$propbag->add('name', PLUGIN_AUDIOSCROBBLER_ARTISTLINK);
|
|
|
|
$propbag->add('description', PLUGIN_AUDIOSCROBBLER_ARTISTLINK_BLAHBLAH);
|
|
|
|
$propbag->add('default', '4');
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
|
|
case 'newwindow':
|
|
|
|
$propbag->add('type', 'boolean');
|
|
|
|
$propbag->add('name', PLUGIN_AUDIOSCROBBLER_NEWWINDOW);
|
|
|
|
$propbag->add('description', PLUGIN_AUDIOSCROBBLER_NEWWINDOW_BLAHBLAH);
|
|
|
|
$propbag->add('default', false);
|
|
|
|
break;
|
|
|
|
|
|
|
|
case 'cachetime':
|
|
|
|
$propbag->add('type', 'string');
|
|
|
|
$propbag->add('name', PLUGIN_AUDIOSCROBBLER_CACHETIME);
|
|
|
|
$propbag->add('description', PLUGIN_AUDIOSCROBBLER_CACHETIME_BLAHBLAH);
|
|
|
|
$propbag->add('default', 30);
|
|
|
|
break;
|
|
|
|
|
|
|
|
case 'dateformat':
|
|
|
|
$propbag->add('type', 'string');
|
|
|
|
$propbag->add('name', PLUGIN_AUDIOSCROBBLER_DATEFORMAT);
|
|
|
|
$propbag->add('description', PLUGIN_AUDIOSCROBBLER_DATEFORMAT_BLAHBLAH);
|
|
|
|
$propbag->add('default', "%e. %B %Y, %H:%M");
|
|
|
|
break;
|
|
|
|
|
|
|
|
case 'utcdifference':
|
|
|
|
$propbag->add('type', 'string');
|
|
|
|
$propbag->add('name', PLUGIN_AUDIOSCROBBLER_UTCDIFFERENCE);
|
|
|
|
$propbag->add('description', PLUGIN_AUDIOSCROBBLER_UTCDIFFERENCE_BLAHBLAH);
|
|
|
|
$propbag->add('default', "0");
|
|
|
|
break;
|
|
|
|
|
|
|
|
case 'spacer':
|
|
|
|
$propbag->add('type', 'string');
|
|
|
|
$propbag->add('name', PLUGIN_AUDIOSCROBBLER_SPACER);
|
|
|
|
$propbag->add('description', PLUGIN_AUDIOSCROBBLER_SPACER_BLAHBLAH);
|
|
|
|
$propbag->add('default', '<br />');
|
|
|
|
break;
|
|
|
|
|
|
|
|
case 'profiletitle':
|
|
|
|
$propbag->add('type', 'string');
|
|
|
|
$propbag->add('name', PLUGIN_AUDIOSCROBBLER_PROFILETITLE);
|
|
|
|
$propbag->add('description', PLUGIN_AUDIOSCROBBLER_PROFILETITLE_BLAHBLAH);
|
|
|
|
$propbag->add('default', '%USER%');
|
|
|
|
break;
|
|
|
|
|
|
|
|
case 'formatstring':
|
|
|
|
$propbag->add('type', 'text');
|
|
|
|
$propbag->add('name', PLUGIN_AUDIOSCROBBLER_FORMATSTRING);
|
|
|
|
$propbag->add('description', PLUGIN_AUDIOSCROBBLER_FORMATSTRING_BLAHBLAH);
|
|
|
|
$propbag->add('default', 'Song: %SONG%<br />Artist: %ARTIST%<br /><div class="serendipitySideBarDate">%DATE%</div>');
|
|
|
|
break;
|
|
|
|
|
|
|
|
case 'formatstring_block':
|
|
|
|
$propbag->add('type', 'text');
|
|
|
|
$propbag->add('name', PLUGIN_AUDIOSCROBBLER_FORMATSTRING_BLOCK);
|
|
|
|
$propbag->add('description', PLUGIN_AUDIOSCROBBLER_FORMATSTRING_BLOCK_BLAHBLAH);
|
|
|
|
$propbag->add('default', '<div style="text-align: center;">%PROFILE%</div><br />%ENTRIES%<br /><div style="text-align: center;">%LASTUPDATE%</div>');
|
|
|
|
break;
|
|
|
|
|
|
|
|
default:
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
//renders the date for output
|
|
|
|
function renderScrobblerDate($date) {
|
|
|
|
$stamp = $date + intval($this->utcdifference) * 60 * 60;
|
2014-11-25 01:15:57 +01:00
|
|
|
return (function_exists('serendipity_specialchars') ? serendipity_specialchars(serendipity_formatTime($this->get_config('dateformat'), $stamp, true)) : htmlspecialchars(serendipity_formatTime($this->get_config('dateformat'), $stamp, true), ENT_COMPAT, LANG_CHARSET));
|
2011-12-13 12:29:05 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
//sets the timestamp of the last update try
|
|
|
|
function setLastUpdateTry() {
|
|
|
|
$stamp = time();
|
|
|
|
$this->set_config('lastupdate', $stamp);
|
|
|
|
$this->scrobblerlastupdate = $stamp;
|
|
|
|
}
|
|
|
|
|
|
|
|
//reads the songs from the audioscrobbler rdf feed
|
|
|
|
function getSongsFromScrobbler($force = false) {
|
|
|
|
if (!file_exists($this->scrobblercache) || filesize($this->scrobblercache) == 0 || $this->scrobblerlastupdate < (time() - $this->cachetime) || $force) {
|
|
|
|
$this->read_scrobbler_feed = true;
|
|
|
|
if ($this->get_config('forced') == 1 && $force) {
|
|
|
|
echo '<!-- second force attempt -->'."\n";
|
|
|
|
return false;
|
|
|
|
} elseif ($this->get_config('forced') == 0 && $force) {
|
|
|
|
$this->set_config('forced', 1);
|
|
|
|
echo '<!-- setting force attempt -->'."\n";
|
|
|
|
}
|
|
|
|
$this->setLastUpdateTry();
|
|
|
|
echo '<!-- fetching scrobbler feed -->'."\n";
|
|
|
|
$objXml = new s9y_audioscrobbler_XMLParser();
|
|
|
|
$array = $objXml->getXMLArray('http://ws.audioscrobbler.com/1.0/user/'.$this->username.'/recenttracks.xml');
|
|
|
|
if ($array && is_array($array)) {
|
|
|
|
$songs = array();
|
|
|
|
$counter = 0;
|
|
|
|
//$start = false;
|
|
|
|
$start = true;
|
|
|
|
foreach ($array as $xml) {
|
|
|
|
if ($xml['tag'] == 'TRACK' && $xml['type'] == 'close') {
|
|
|
|
$counter++;
|
|
|
|
} elseif ($xml['tag'] == 'RECENTTRACKS' && $xml['type'] == 'close') {
|
|
|
|
$start = true;
|
|
|
|
}
|
|
|
|
if ($start) {
|
|
|
|
if ($xml['tag'] == 'LINK' && $xml['type'] == 'complete') {
|
|
|
|
$songs[$counter]['link'] = $this->reencode($xml['value']);
|
|
|
|
}
|
|
|
|
elseif ($xml['tag'] == 'NAME' && $xml['type'] == 'complete')
|
|
|
|
{
|
|
|
|
$songs[$counter]['songtitle'] = $this->reencode($xml['value']);
|
|
|
|
}
|
|
|
|
elseif ($xml['tag'] == 'DATE' && $xml['type'] == 'complete')
|
|
|
|
{
|
|
|
|
$songs[$counter]['date'] = $this->reencode($xml['attributes']['UTS']);
|
|
|
|
}
|
|
|
|
elseif ($xml['tag'] == 'URL' && $xml['type'] == 'complete')
|
|
|
|
{
|
|
|
|
$songs[$counter]['songlink'] = trim($this->reencode($xml['value']));
|
|
|
|
|
|
|
|
}
|
|
|
|
elseif ($xml['tag'] == 'ARTIST' && $xml['type'] == 'complete')
|
|
|
|
{
|
|
|
|
$songs[$counter]['artisttitle'] = $this->reencode($xml['value']);
|
|
|
|
|
|
|
|
}
|
|
|
|
/*
|
|
|
|
} elseif ($xml['tag'] == 'DESCRIPTION' && $xml['type'] == 'complete') {
|
|
|
|
$songs[$counter]['description'] = reencode($xml['value']);
|
|
|
|
} elseif ($xml['tag'] == 'DC:DATE' && $xml['type'] == 'complete') {
|
|
|
|
$songs[$counter]['date'] = reencode($xml['value']);
|
|
|
|
} elseif ($xml['tag'] == 'DC:TITLE' && $xml['type'] == 'complete' && $state == 0) {
|
|
|
|
$songs[$counter]['songtitle'] = reencode($xml['value']);
|
|
|
|
$state++;
|
|
|
|
} elseif ($xml['tag'] == 'MM:ARTIST' && $xml['type'] == 'open' && is_array($xml['attributes'])) {
|
|
|
|
$songs[$counter]['artistlink'] = reencode($xml['attributes']['RDF:ABOUT']);
|
|
|
|
} elseif ($xml['tag'] == 'DC:TITLE' && $xml['type'] == 'complete' && $state == 1) {
|
|
|
|
$songs[$counter]['artisttitle'] = reencode($xml['value']);
|
|
|
|
$state++;
|
|
|
|
} elseif ($xml['tag'] == 'DC:TITLE' && $xml['type'] == 'complete' && $state == 2) {
|
|
|
|
$songs[$counter]['albumtitle'] = reencode($xml['value']);
|
|
|
|
$state = 0;
|
|
|
|
}
|
|
|
|
*/
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
if (is_array($songs) && count($songs) > 0) {
|
|
|
|
if (count($songs) < intval($this->get_config('number'))) {
|
|
|
|
$songs = $this->stackerScrobbler($songs);
|
|
|
|
} elseif (count($songs) > intval($this->get_config('number'))) {
|
|
|
|
$songs = $this->deStackerScrobbler($songs);
|
|
|
|
}
|
|
|
|
if (!$force) {
|
|
|
|
$this->set_config('forced', 0);
|
|
|
|
}
|
|
|
|
$this->writeScrobblerCache($songs);
|
|
|
|
return true;
|
|
|
|
} elseif ($force) {
|
|
|
|
return false;
|
|
|
|
} elseif (!file_exists($this->scrobblercache)) {
|
|
|
|
$this->scrobbler_error[] = PLUGIN_AUDIOSCROBBLER_FEED_OFFLINE;
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// Reencodes UTF-8 to blog encoding
|
|
|
|
function reencode($string) {
|
|
|
|
if (LANG_CHARSET != 'UTF-8') {
|
|
|
|
return utf8_decode($string);
|
|
|
|
}
|
|
|
|
return $string;
|
|
|
|
}
|
|
|
|
|
|
|
|
//destacks the songs so that always the $this->number songs are in the songarray
|
|
|
|
function deStackerScrobbler($songs) {
|
|
|
|
while (count($songs) != $this->number) array_pop($songs);
|
|
|
|
return $songs;
|
|
|
|
}
|
|
|
|
|
|
|
|
//stacks the songs so that always the $this->number songs are in the songarray
|
|
|
|
function stackerScrobbler($songs) {
|
|
|
|
if (!serendipity_db_bool($this->get_config('stack'))) {
|
|
|
|
return $songs;
|
|
|
|
}
|
|
|
|
|
|
|
|
$this->readScrobblerCache(true);
|
|
|
|
if ($oldsongs = $this->songs) {
|
|
|
|
$diff = $this->number - count($songs);
|
|
|
|
$lastsongs = array();
|
|
|
|
foreach ($oldsongs as $oldsong) {
|
|
|
|
$addsong = true;
|
|
|
|
foreach ($songs as $song) {
|
|
|
|
if ($song['date'] == $oldsong['date']) {
|
|
|
|
$addsong = false;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if ($addsong) $lastsongs[] = $song;
|
|
|
|
}
|
|
|
|
$i = 0;
|
|
|
|
foreach(array_reverse($lastsongs) as $lastsong) {
|
|
|
|
$songs[] = $lastsong;
|
|
|
|
$i++;
|
|
|
|
if (($diff - $i) == 0) {
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return $songs;
|
|
|
|
} else {
|
|
|
|
return $songs;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
//encodes a scrobbler song array
|
|
|
|
function encodeScrobblerArray($song_array) {
|
|
|
|
if (function_exists('gzcompress')) {
|
|
|
|
return gzcompress(serialize($song_array));
|
|
|
|
} else {
|
|
|
|
return serialize($song_array);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
//decodes a scrobbler song array
|
|
|
|
function decodeScrobblerArray($encoded_songs) {
|
|
|
|
if (function_exists('gzcompress')) {
|
|
|
|
return unserialize(gzuncompress($encoded_songs));
|
|
|
|
} else {
|
|
|
|
return unserialize($encoded_songs);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
//writes the s9y cache sets $this->scrobbler_error on failure
|
|
|
|
function writeScrobblerCache($songs) {
|
|
|
|
//check if the $this->songs and $songs are equal
|
|
|
|
if (is_array ($this->songs)) {
|
|
|
|
$equal = true;
|
|
|
|
if (is_array($this->songs))
|
|
|
|
foreach ($songs as $key => $song) {
|
|
|
|
foreach ($song as $tag => $value) {
|
|
|
|
if ($this->songs[$key][$tag] != $value) $equal = false;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if ($equal) {
|
|
|
|
echo '<!-- cache is equal -->'."\n";
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
$fp = @fopen($this->scrobblercache, 'w');
|
|
|
|
if ($fp) {
|
|
|
|
fwrite($fp, $this->encodeScrobblerArray($songs));
|
|
|
|
fclose($fp);
|
|
|
|
$this ->songs = $songs;
|
|
|
|
echo '<!-- cache written -->'."\n";
|
|
|
|
} else {
|
|
|
|
$this->scrobbler_error[] = PLUGIN_AUDIOSCROBBLER_COULD_NOT_WRITE;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
//reads from the s9y cache sets $this->songs on success , $this->scrobbler_error on failure
|
|
|
|
function readScrobblerCache($no_error = false) {
|
|
|
|
//don't do things twice ;)
|
|
|
|
if (is_array($this->songs) && @count($this->songs) > 0) {
|
|
|
|
return $this->songs;
|
|
|
|
} else {
|
|
|
|
$songs = @file_get_contents($this->scrobblercache);
|
|
|
|
if (trim($songs) == '' || !@is_array($this->decodeScrobblerArray($songs))) {
|
|
|
|
//create a new cache if possible
|
|
|
|
//the scobbler feed was not read yet->read it
|
|
|
|
if (!$this->read_scrobbler_feed) {
|
|
|
|
echo '<!-- bad cache trying to create a new one -->'."\n";
|
|
|
|
$this->getSongsFromScrobbler();
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
//if the feed is not readable and this is no stack call add an error
|
|
|
|
if (!$no_error) {
|
|
|
|
$this ->scrobbler_error[] = PLUGIN_AUDIOSCROBBLER_COULD_NOT_READ;
|
|
|
|
}
|
|
|
|
$this ->songs = false;
|
|
|
|
} else {
|
|
|
|
//if the cache doesnt match $this->number try to stack it with a force read
|
|
|
|
if (!($this->read_scrobbler_feed) && count($this->decodeScrobblerArray($songs)) < $this->number) {
|
|
|
|
echo '<!-- force read for stack -->'."\n";
|
|
|
|
//if the songlist is offline or this is the second force attempt - return the cache
|
|
|
|
if (!$this->getSongsFromScrobbler(true)) {
|
|
|
|
$this->songs = $this->decodeScrobblerArray($songs);
|
|
|
|
}
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
//destack the cache - *needed?*
|
|
|
|
if (count($this->decodeScrobblerArray($songs)) > $this->number) {
|
|
|
|
echo '<!-- destacking cache -->'."\n";
|
|
|
|
$songs = $this->deStackerScrobbler($this->decodeScrobblerArray($songs));
|
|
|
|
$this->writeScrobblerCache($songs);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
//return an O.K. cache
|
|
|
|
echo '<!-- cache read -->'."\n";
|
|
|
|
$this ->songs = $this->decodeScrobblerArray($songs);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
//renders the output
|
|
|
|
function renderScrobblerOutput() {
|
|
|
|
$formatstring = $this->get_config('formatstring');
|
|
|
|
$formatstring_block = $this->get_config('formatstring_block');
|
|
|
|
$artistlink = $this->get_config('artistlink');
|
|
|
|
$songlink = $this->get_config('songlink');
|
|
|
|
$spacer = $this->get_config('spacer');
|
|
|
|
$profiletitle = $this->get_config('profiletitle');
|
|
|
|
$this -> getSongsFromScrobbler();
|
|
|
|
$this -> readScrobblerCache();
|
|
|
|
|
|
|
|
if ($this->get_config('newwindow')) {
|
|
|
|
$onlick = ' onclick="window.open(this.href);"';
|
|
|
|
}
|
|
|
|
|
|
|
|
if (!$this->songs) {
|
|
|
|
echo '<span style="font-weight: bold;">'.PLUGIN_AUDIOSCROBBLER_ERROR.':</span><br /><ul><li>'.join('</li><li>', $this->scrobbler_error).'</li></ul>';
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
$content = array();
|
|
|
|
$i = 0;
|
|
|
|
foreach ($this->songs as $key => $value) {
|
|
|
|
$value['songtitle'] = utf8_decode($value['songtitle']);
|
|
|
|
$value['artisttitle'] = utf8_decode($value['artisttitle']);
|
|
|
|
$value['songtitle'] = utf8_decode($value['songtitle']);
|
|
|
|
$add = '';
|
|
|
|
if ($songlink) {
|
|
|
|
if (is_string(strstr($value['link'], '&mode'))) {
|
|
|
|
//fix ampersand entity
|
2014-11-25 01:15:57 +01:00
|
|
|
$song = '<a href="'.str_replace('&mode', '&mode', $value['link']). '"'.$onclick.'>'.(function_exists('serendipity_specialchars') ? serendipity_specialchars($value['songtitle'], ENT_QUOTES) : htmlspecialchars($value['songtitle'], ENT_QUOTES| ENT_COMPAT, LANG_CHARSET)).'</a>'."\n";
|
2011-12-13 12:29:05 +01:00
|
|
|
} elseif (is_string(strstr($value['link'], '&mode'))) {
|
|
|
|
//link is ok
|
2014-11-25 01:15:57 +01:00
|
|
|
$song = '<a href="'.$value['link']. '"'.$onclick.'>'.(function_exists('serendipity_specialchars') ? serendipity_specialchars($value['songtitle'], ENT_QUOTES) : htmlspecialchars($value['songtitle'], ENT_QUOTES| ENT_COMPAT, LANG_CHARSET)).'</a>'."\n";
|
2011-12-13 12:29:05 +01:00
|
|
|
} else {
|
|
|
|
//encode it
|
2014-11-25 01:15:57 +01:00
|
|
|
$song = '<a href="http://www.audioscrobbler.com/music/'.urlencode(utf8_encode($value['artisttitle'])). '/_/'.urlencode(utf8_encode($value['songtitle'])).'"'.$onclick.'>'.(function_exists('serendipity_specialchars') ? serendipity_specialchars($value['songtitle'], ENT_QUOTES) : htmlspecialchars($value['songtitle'], ENT_QUOTES| ENT_COMPAT, LANG_CHARSET)).'</a>'."\n";
|
2011-12-13 12:29:05 +01:00
|
|
|
}
|
|
|
|
} else {
|
2014-11-25 01:15:57 +01:00
|
|
|
$song = (function_exists('serendipity_specialchars') ? serendipity_specialchars($value['songtitle'], ENT_QUOTES) : htmlspecialchars($value['songtitle'], ENT_QUOTES| ENT_COMPAT, LANG_CHARSET));
|
2011-12-13 12:29:05 +01:00
|
|
|
}
|
|
|
|
if ($artistlink == 0) {
|
2014-11-25 01:15:57 +01:00
|
|
|
$artist = (function_exists('serendipity_specialchars') ? serendipity_specialchars($value['artisttitle'], ENT_QUOTES) : htmlspecialchars($value['artisttitle'], ENT_QUOTES| ENT_COMPAT, LANG_CHARSET));
|
2011-12-13 12:29:05 +01:00
|
|
|
} elseif ($artistlink == 1) {
|
2014-11-25 01:15:57 +01:00
|
|
|
$artist = '<a href="http://www.audioscrobbler.com/music/'.urlencode(utf8_encode($value['artisttitle'])).'"'.$onclick.'>'.(function_exists('serendipity_specialchars') ? serendipity_specialchars($value['artisttitle'], ENT_QUOTES) : htmlspecialchars($value['artisttitle'], ENT_QUOTES| ENT_COMPAT, LANG_CHARSET)).'</a>'."\n";
|
2011-12-13 12:29:05 +01:00
|
|
|
} elseif ($artistlink == 2) {
|
|
|
|
if ($value['artisttitle'] != '' || $value['artistlink'] != 'http://mm.musicbrainz.org/artist/') {
|
2014-11-25 01:15:57 +01:00
|
|
|
$artist = '<a href="' . $value['artistlink'] . '"'.$onclick.'>'.(function_exists('serendipity_specialchars') ? serendipity_specialchars($value['artisttitle'], ENT_QUOTES) : htmlspecialchars($value['artisttitle'], ENT_QUOTES| ENT_COMPAT, LANG_CHARSET)).'</a>'."\n";
|
2011-12-13 12:29:05 +01:00
|
|
|
} else {
|
2014-11-25 01:15:57 +01:00
|
|
|
$artist = (function_exists('serendipity_specialchars') ? serendipity_specialchars($value['artisttitle'], ENT_QUOTES) : htmlspecialchars($value['artisttitle'], ENT_QUOTES| ENT_COMPAT, LANG_CHARSET));
|
2011-12-13 12:29:05 +01:00
|
|
|
}
|
|
|
|
} else {
|
|
|
|
if (trim($value['artistlink']) != 'http://mm.musicbrainz.org/artist/' && trim($value['artistlink']) != '') {
|
2014-11-25 01:15:57 +01:00
|
|
|
$artist = '<a href="' . $value['artistlink'] . '"'.$onclick.'>'.(function_exists('serendipity_specialchars') ? serendipity_specialchars($value['artisttitle'], ENT_QUOTES) : htmlspecialchars($value['artisttitle'], ENT_QUOTES| ENT_COMPAT, LANG_CHARSET)).'</a>'."\n";
|
2011-12-13 12:29:05 +01:00
|
|
|
} else {
|
2014-11-25 01:15:57 +01:00
|
|
|
$artist = '<a href="http://www.audioscrobbler.com/music/'.urlencode(utf8_encode($value['artisttitle'])).'"'.$onclick.'>'.(function_exists('serendipity_specialchars') ? serendipity_specialchars($value['artisttitle'], ENT_QUOTES) : htmlspecialchars($value['artisttitle'], ENT_QUOTES| ENT_COMPAT, LANG_CHARSET)).'</a>'."\n";
|
2011-12-13 12:29:05 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
$replacements = array('%ARTIST%' => $artist, '%SONG%' => $song, '%DATE%' => $this->renderScrobblerDate($value['date'], $dateformat));
|
|
|
|
$add = str_replace(array_keys($replacements), array_values($replacements), $formatstring);
|
|
|
|
$content[] = $add;
|
|
|
|
$i++;
|
|
|
|
if ($i == $this->number) {
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
$entries = join($spacer, $content);
|
|
|
|
$output = str_replace('%ENTRIES%', $entries, $formatstring_block);
|
|
|
|
$profiletitle = str_replace('%USER%', $this->username, $profiletitle);
|
2014-11-25 01:15:57 +01:00
|
|
|
$output = str_replace('%PROFILE%', '<a href="http://www.audioscrobbler.com/user/'.urlencode(utf8_encode($this->username)).'"'.$onclick.'>'.(function_exists('serendipity_specialchars') ? serendipity_specialchars($profiletitle, ENT_QUOTES) : htmlspecialchars($profiletitle, ENT_QUOTES| ENT_COMPAT, LANG_CHARSET)).'</a>', $output);
|
2014-11-26 10:40:03 +01:00
|
|
|
$lstime = serendipity_formatTime($this->get_config('dateformat'), filemtime($this->scrobblercache), true);
|
|
|
|
$output = str_replace('%LASTUPDATE%',
|
|
|
|
(function_exists('serendipity_specialchars')
|
|
|
|
? serendipity_specialchars($lstime)
|
|
|
|
: htmlspecialchars($lstime, ENT_COMPAT, LANG_CHARSET)
|
|
|
|
),
|
|
|
|
$output
|
|
|
|
);
|
2011-12-13 12:29:05 +01:00
|
|
|
$output = str_replace('audioscrobbler.com', 'last.fm', $output);
|
|
|
|
return $output;
|
|
|
|
}
|
|
|
|
|
|
|
|
//checks and formats the settings
|
|
|
|
function doConfig() {
|
|
|
|
global $serendipity;
|
|
|
|
$this->number = (intval($this->get_config('number')) == 0) ? 1 : intval($this->get_config('number'));
|
|
|
|
$this->username = trim($this->get_config('username'));
|
|
|
|
$this->cachetime = (intval($this->get_config('cachetime')) == 0) ? 300 : ($this->get_config('cachetime') * 60);
|
|
|
|
$this->scrobblercache = $serendipity['serendipityPath'] . 'templates_c/audioscrobbler_cache_' . preg_replace('@[^a-z0-9]*@i', '', $this->username) . '.dat';
|
|
|
|
$this->utcdifference = intval($this->get_config('utcdifference'));
|
|
|
|
$this->scrobblerlastupdate = intval($this->get_config('lastupdate'));
|
|
|
|
}
|
|
|
|
|
|
|
|
function generate_content(&$title) {
|
|
|
|
$sidebartitle = $title = $this->get_config('sidebartitle', $this->title);
|
|
|
|
$this->doConfig();
|
|
|
|
echo "\n".$this->renderScrobblerOutput()."\n";
|
|
|
|
}
|
|
|
|
}
|
|
|
|
?>
|