From: Penny Leach Date: Fri, 29 Jun 2007 23:29:45 +0000 (+1200) Subject: added audioscrobbler plugin X-Git-Url: http://git.mjollnir.org/gw?a=commitdiff_plain;h=5e0d19e8bb5bf89e461c3b8dd7c5f80b1b758202;p=s9y.git added audioscrobbler plugin --- diff --git a/plugins/serendipity_plugin_audioscrobbler/UTF-8/lang_de.inc.php b/plugins/serendipity_plugin_audioscrobbler/UTF-8/lang_de.inc.php new file mode 100644 index 0000000..2931d6c --- /dev/null +++ b/plugins/serendipity_plugin_audioscrobbler/UTF-8/lang_de.inc.php @@ -0,0 +1,32 @@ + diff --git a/plugins/serendipity_plugin_audioscrobbler/UTF-8/lang_ru.inc.php b/plugins/serendipity_plugin_audioscrobbler/UTF-8/lang_ru.inc.php new file mode 100644 index 0000000..d94055d --- /dev/null +++ b/plugins/serendipity_plugin_audioscrobbler/UTF-8/lang_ru.inc.php @@ -0,0 +1,45 @@ + + * EN-Revision: Revision of lang_en.inc.php + */ + +@define('PLUGIN_AUDIOSCROBBLER_TITLE', 'Audioscrobbler'); +@define('PLUGIN_AUDIOSCROBBLER_TITLE_BLAHBLAH', 'Отображает список последних композиций в вашем блоге'); +@define('PLUGIN_AUDIOSCROBBLER_NUMBER', 'Количество композиций'); +@define('PLUGIN_AUDIOSCROBBLER_NUMBER_BLAHBLAH', 'Как много композиций отображать? (Должно быть не меньше 1)'); +@define('PLUGIN_AUDIOSCROBBLER_USERNAME', 'Логин на Audioscrobbler'); +@define('PLUGIN_AUDIOSCROBBLER_USERNAME_BLAHBLAH', 'Введите ваш логин, чтобы плагин мог получить доступ к соотвествующей ленте.'); +@define('PLUGIN_AUDIOSCROBBLER_NEWWINDOW', 'Новое окно'); +@define('PLUGIN_AUDIOSCROBBLER_NEWWINDOW_BLAHBLAH', 'Sollen die Links in einem neuen Fenster ge??ffnet werden (needs Javascript)'); +@define('PLUGIN_AUDIOSCROBBLER_CACHETIME', 'Как часто список должен обновляться'); +@define('PLUGIN_AUDIOSCROBBLER_CACHETIME_BLAHBLAH', 'Содержимое списка кэшируется. Когда превышается некоторый интервал времени, кэш обновляется. (Стандартно: 30 минут, минимум 5 минут)'); +@define('PLUGIN_AUDIOSCROBBLER_FORMATSTRING', 'Форматирование записи'); +@define('PLUGIN_AUDIOSCROBBLER_FORMATSTRING_BLAHBLAH', 'Используйте %ARTIST% для имени исполнитея, %SONG% для имени композиции, %ALBUM% для имени альбома and %DATE% для даты.'); +@define('PLUGIN_AUDIOSCROBBLER_UTCDIFFERENCE', 'Stunden Unterschied zur UTC Zeit'); +@define('PLUGIN_AUDIOSCROBBLER_UTCDIFFERENCE_BLAHBLAH', 'Смещение времени от GMT (Пример: Москва (Россия) = 3)'); +@define('PLUGIN_AUDIOSCROBBLER_FORMATSTRING_BLOCK', 'Форматирование всего блока'); +@define('PLUGIN_AUDIOSCROBBLER_FORMATSTRING_BLOCK_BLAHBLAH', 'Используйте %ENTRIES% для списка композицийt, %PROFILE% для ссылки на профиль, и %LASTUPDATE% для времени последнего кэширования.'); +@define('PLUGIN_AUDIOSCROBBLER_PROFILETITLE', 'Заголовок для ссылки на профиль'); +@define('PLUGIN_AUDIOSCROBBLER_PROFILETITLE_BLAHBLAH', 'Текст для отображения в ссылке на Ваш профиль. (Для использования имени пользователя введите %USER%'); +@define('PLUGIN_AUDIOSCROBBLER_SONGLINK', 'Ссылки на композиции'); +@define('PLUGIN_AUDIOSCROBBLER_SONGLINK_BLAHBLAH', 'Должны ли композиции ссылаться на их страницы на Audioscrobbler?'); +@define('PLUGIN_AUDIOSCROBBLER_ARTISTLINK', 'Ссылки на исполнителей'); +@define('PLUGIN_AUDIOSCROBBLER_ARTISTLINK_BLAHBLAH', 'Ставить ли ссылки на исполнителей? (Выберите вариант)'); +@define('PLUGIN_AUDIOSCROBBLER_ARTISTLINK_NONE', 'Не ставить ссылок'); +@define('PLUGIN_AUDIOSCROBBLER_ARTISTLINK_SCROBBLER', 'Ссыли на страницы исполнителей на Audioscrobbler'); +@define('PLUGIN_AUDIOSCROBBLER_ARTISTLINK_MUSICBRAINZ_ELSE_NONE', 'Ссылки на Musicbrainz, если доступно'); +@define('PLUGIN_AUDIOSCROBBLER_ARTISTLINK_MUSICBRAINZ_ELSE_SCROBBLER', 'Ссылки на Musicbrainz, если не доступно, то на Audioscrobbler'); +@define('PLUGIN_AUDIOSCROBBLER_SPACER', 'Разделитель'); +@define('PLUGIN_AUDIOSCROBBLER_SPACER_BLAHBLAH', 'Что должно быть использовано для разделения композиций в списке?'); +@define('PLUGIN_AUDIOSCROBBLER_COULD_NOT_WRITE', 'Кэш не может быть записан'); +@define('PLUGIN_AUDIOSCROBBLER_COULD_NOT_READ', 'Кэш не может быть прочитан'); +@define('PLUGIN_AUDIOSCROBBLER_FEED_OFFLINE', 'Список композиций не доступен'); +@define('PLUGIN_AUDIOSCROBBLER_STACK', 'Использовать повторение?'); +@define('PLUGIN_AUDIOSCROBBLER_STACK_BLAHBLAH', 'Если количество композиций в списке меньше чем размер списка, Вы можете разрешить эту установку, чтобы последняя композициця была повторена X раз до заполнения списка.'); +@define('PLUGIN_AUDIOSCROBBLER_NUMBER_BLAHBLAH', 'как много композиций отображать? (Стандартно: одну, не может быть меньше 1)'); +@define('PLUGIN_AUDIOSCROBBLER_FORCE_ENCODING', 'Использовать кодировку:'); +@define('PLUGIN_AUDIOSCROBBLER_FORCE_ENCODING_BLAHBLAH', 'Поу молчанию, Serendipity использует UTF-8 при разборе данных. Если это вызывает прооблемы, так как ваш блог не поддерживает UTF-8, введите подходящую кодировку.'); + diff --git a/plugins/serendipity_plugin_audioscrobbler/lang_de.inc.php b/plugins/serendipity_plugin_audioscrobbler/lang_de.inc.php new file mode 100755 index 0000000..85a3f52 --- /dev/null +++ b/plugins/serendipity_plugin_audioscrobbler/lang_de.inc.php @@ -0,0 +1,32 @@ + diff --git a/plugins/serendipity_plugin_audioscrobbler/lang_en.inc.php b/plugins/serendipity_plugin_audioscrobbler/lang_en.inc.php new file mode 100644 index 0000000..2ea5b3a --- /dev/null +++ b/plugins/serendipity_plugin_audioscrobbler/lang_en.inc.php @@ -0,0 +1,46 @@ + + * EN-Revision: Revision of lang_en.inc.php + */ + +@define('PLUGIN_AUDIOSCROBBLER_TITLE', 'Audioscrobbler'); +@define('PLUGIN_AUDIOSCROBBLER_TITLE_BLAHBLAH', 'Shows last played songs in your blog'); +@define('PLUGIN_AUDIOSCROBBLER_NUMBER', 'Number of Songs'); +@define('PLUGIN_AUDIOSCROBBLER_NUMBER_BLAHBLAH', 'How many songs should be displayed? (Standard: one, must be at least 1)'); +@define('PLUGIN_AUDIOSCROBBLER_USERNAME', 'Audioscrobbler Username'); +@define('PLUGIN_AUDIOSCROBBLER_USERNAME_BLAHBLAH', 'Enter your username so that the plugin can access the appropriate feed.'); +@define('PLUGIN_AUDIOSCROBBLER_NEWWINDOW', 'New Window'); +@define('PLUGIN_AUDIOSCROBBLER_NEWWINDOW_BLAHBLAH', 'Sollen die Links in einem neuen Fenster ge??ffnet werden (needs Javascript)'); +@define('PLUGIN_AUDIOSCROBBLER_CACHETIME', 'How often should the list be updated?'); +@define('PLUGIN_AUDIOSCROBBLER_CACHETIME_BLAHBLAH', 'The contents of the Audioscrobbler feed are cached. When this number of minutes expires, it is updated. (Standard: 30 minutes, minimum 5 Minuten)'); +@define('PLUGIN_AUDIOSCROBBLER_FORMATSTRING', 'Entry Formatting'); +@define('PLUGIN_AUDIOSCROBBLER_FORMATSTRING_BLAHBLAH', 'Use %ARTIST% for the Artist, %SONG% for the Song, %ALBUM% for the Album and %DATE% for the Date.'); +@define('PLUGIN_AUDIOSCROBBLER_UTCDIFFERENCE', 'Stunden Unterschied zur UTC Zeit'); +@define('PLUGIN_AUDIOSCROBBLER_UTCDIFFERENCE_BLAHBLAH', 'Time offset from GMT (example: EST (Boston, New York (USA)) = -5)'); +@define('PLUGIN_AUDIOSCROBBLER_FORMATSTRING_BLOCK', 'Formatting for the whole block'); +@define('PLUGIN_AUDIOSCROBBLER_FORMATSTRING_BLOCK_BLAHBLAH', 'Use %ENTRIES% for the songlist, %PROFILE% for a link to your Audioscrobbler Profile, and %LASTUPDATE% for the date and time the feed was last cached.'); +@define('PLUGIN_AUDIOSCROBBLER_PROFILETITLE', 'Title for the Profile Link'); +@define('PLUGIN_AUDIOSCROBBLER_PROFILETITLE_BLAHBLAH', 'Text to display for the optional linke to your Audioscrobbler profile. (To use your username type %USER%'); +@define('PLUGIN_AUDIOSCROBBLER_SONGLINK', 'Link Songs'); +@define('PLUGIN_AUDIOSCROBBLER_SONGLINK_BLAHBLAH', 'Should songs be linked to their Audioscrobbler page?'); +@define('PLUGIN_AUDIOSCROBBLER_ARTISTLINK', 'Link Artists'); +@define('PLUGIN_AUDIOSCROBBLER_ARTISTLINK_BLAHBLAH', 'Should artists be linked? (choose a service)'); +@define('PLUGIN_AUDIOSCROBBLER_ARTISTLINK_NONE', 'no'); +@define('PLUGIN_AUDIOSCROBBLER_ARTISTLINK_SCROBBLER', 'Artist page in Audioscrobbler'); +@define('PLUGIN_AUDIOSCROBBLER_ARTISTLINK_MUSICBRAINZ_ELSE_NONE', 'with Musicbrainz, if available'); +@define('PLUGIN_AUDIOSCROBBLER_ARTISTLINK_MUSICBRAINZ_ELSE_SCROBBLER', 'with Musicbrainz, if Musicbrainz is not available, with Audioscrobbler'); +@define('PLUGIN_AUDIOSCROBBLER_SPACER', 'Separator'); +@define('PLUGIN_AUDIOSCROBBLER_SPACER_BLAHBLAH', 'What should be used to separate entries in the songlist?'); +@define('PLUGIN_AUDIOSCROBBLER_COULD_NOT_WRITE', 'Cache could not be written'); +@define('PLUGIN_AUDIOSCROBBLER_COULD_NOT_READ', 'Cache could not be evaluated'); +@define('PLUGIN_AUDIOSCROBBLER_FEED_OFFLINE', 'Audioscrobbler Songlist offline'); +@define('PLUGIN_AUDIOSCROBBLER_STACK', 'Use stacking?'); +@define('PLUGIN_AUDIOSCROBBLER_STACK_BLAHBLAH', 'If the number of songs in your songlist is smaller than the number of songs you want to have displayed, you can enable this setting so that the last song item will be repeated X times to fill the list.'); +@define('PLUGIN_AUDIOSCROBBLER_NUMBER_BLAHBLAH', 'How many songs should be displayed? (Standard: one, must be at least 1)'); +@define('PLUGIN_AUDIOSCROBBLER_FORCE_ENCODING', 'Force encoding:'); +@define('PLUGIN_AUDIOSCROBBLER_FORCE_ENCODING_BLAHBLAH', 'By default, Serendipity uses UTF-8 to parse the Audioscrobbler data. If this is breaking special characters because your blog is not UTF-8, enter the appropriate encoding here.'); + +?> diff --git a/plugins/serendipity_plugin_audioscrobbler/lang_ru.inc.php b/plugins/serendipity_plugin_audioscrobbler/lang_ru.inc.php new file mode 100644 index 0000000..48c45d4 --- /dev/null +++ b/plugins/serendipity_plugin_audioscrobbler/lang_ru.inc.php @@ -0,0 +1,44 @@ + + * EN-Revision: Revision of lang_en.inc.php + */ + +@define('PLUGIN_AUDIOSCROBBLER_TITLE', 'Audioscrobbler'); +@define('PLUGIN_AUDIOSCROBBLER_TITLE_BLAHBLAH', 'Отображает список последних композиций в вашем блоге'); +@define('PLUGIN_AUDIOSCROBBLER_NUMBER', 'Количество композиций'); +@define('PLUGIN_AUDIOSCROBBLER_NUMBER_BLAHBLAH', 'Как много композиций отображать? (Должно быть не меньше 1)'); +@define('PLUGIN_AUDIOSCROBBLER_USERNAME', 'Логин на Audioscrobbler'); +@define('PLUGIN_AUDIOSCROBBLER_USERNAME_BLAHBLAH', 'Введите ваш логин, чтобы плагин мог получить доступ к соотвествующей ленте.'); +@define('PLUGIN_AUDIOSCROBBLER_NEWWINDOW', 'Новое окно'); +@define('PLUGIN_AUDIOSCROBBLER_NEWWINDOW_BLAHBLAH', 'Sollen die Links in einem neuen Fenster ge??ffnet werden (needs Javascript)'); +@define('PLUGIN_AUDIOSCROBBLER_CACHETIME', 'Как часто список должен обновляться'); +@define('PLUGIN_AUDIOSCROBBLER_CACHETIME_BLAHBLAH', 'Содержимое списка кэшируется. Когда превышается некоторый интервал времени, кэш обновляется. (Стандартно: 30 минут, минимум 5 минут)'); +@define('PLUGIN_AUDIOSCROBBLER_FORMATSTRING', 'Форматирование записи'); +@define('PLUGIN_AUDIOSCROBBLER_FORMATSTRING_BLAHBLAH', 'Используйте %ARTIST% для имени исполнитея, %SONG% для имени композиции, %ALBUM% для имени альбома and %DATE% для даты.'); +@define('PLUGIN_AUDIOSCROBBLER_UTCDIFFERENCE', 'Stunden Unterschied zur UTC Zeit'); +@define('PLUGIN_AUDIOSCROBBLER_UTCDIFFERENCE_BLAHBLAH', 'Смещение времени от GMT (Пример: Москва (Россия) = 3)'); +@define('PLUGIN_AUDIOSCROBBLER_FORMATSTRING_BLOCK', 'Форматирование всего блока'); +@define('PLUGIN_AUDIOSCROBBLER_FORMATSTRING_BLOCK_BLAHBLAH', 'Используйте %ENTRIES% для списка композицийt, %PROFILE% для ссылки на профиль, и %LASTUPDATE% для времени последнего кэширования.'); +@define('PLUGIN_AUDIOSCROBBLER_PROFILETITLE', 'Заголовок для ссылки на профиль'); +@define('PLUGIN_AUDIOSCROBBLER_PROFILETITLE_BLAHBLAH', 'Текст для отображения в ссылке на Ваш профиль. (Для использования имени пользователя введите %USER%'); +@define('PLUGIN_AUDIOSCROBBLER_SONGLINK', 'Ссылки на композиции'); +@define('PLUGIN_AUDIOSCROBBLER_SONGLINK_BLAHBLAH', 'Должны ли композиции ссылаться на их страницы на Audioscrobbler?'); +@define('PLUGIN_AUDIOSCROBBLER_ARTISTLINK', 'Ссылки на исполнителей'); +@define('PLUGIN_AUDIOSCROBBLER_ARTISTLINK_BLAHBLAH', 'Ставить ли ссылки на исполнителей? (Выберите вариант)'); +@define('PLUGIN_AUDIOSCROBBLER_ARTISTLINK_NONE', 'Не ставить ссылок'); +@define('PLUGIN_AUDIOSCROBBLER_ARTISTLINK_SCROBBLER', 'Ссыли на страницы исполнителей на Audioscrobbler'); +@define('PLUGIN_AUDIOSCROBBLER_ARTISTLINK_MUSICBRAINZ_ELSE_NONE', 'Ссылки на Musicbrainz, если доступно'); +@define('PLUGIN_AUDIOSCROBBLER_ARTISTLINK_MUSICBRAINZ_ELSE_SCROBBLER', 'Ссылки на Musicbrainz, если не доступно, то на Audioscrobbler'); +@define('PLUGIN_AUDIOSCROBBLER_SPACER', 'Разделитель'); +@define('PLUGIN_AUDIOSCROBBLER_SPACER_BLAHBLAH', 'Что должно быть использовано для разделения композиций в списке?'); +@define('PLUGIN_AUDIOSCROBBLER_COULD_NOT_WRITE', 'Кэш не может быть записан'); +@define('PLUGIN_AUDIOSCROBBLER_COULD_NOT_READ', 'Кэш не может быть прочитан'); +@define('PLUGIN_AUDIOSCROBBLER_FEED_OFFLINE', 'Список композиций не доступен'); +@define('PLUGIN_AUDIOSCROBBLER_STACK', 'Использовать повторение?'); +@define('PLUGIN_AUDIOSCROBBLER_STACK_BLAHBLAH', 'Если количество композиций в списке меньше чем размер списка, Вы можете разрешить эту установку, чтобы последняя композициця была повторена X раз до заполнения списка.'); +@define('PLUGIN_AUDIOSCROBBLER_NUMBER_BLAHBLAH', 'как много композиций отображать? (Стандартно: одну, не может быть меньше 1)'); +@define('PLUGIN_AUDIOSCROBBLER_FORCE_ENCODING', 'Использовать кодировку:'); +@define('PLUGIN_AUDIOSCROBBLER_FORCE_ENCODING_BLAHBLAH', 'Поу молчанию, Serendipity использует UTF-8 при разборе данных. Если это вызывает прооблемы, так как ваш блог не поддерживает UTF-8, введите подходящую кодировку.'); diff --git a/plugins/serendipity_plugin_audioscrobbler/serendipity_plugin_audioscrobbler.php b/plugins/serendipity_plugin_audioscrobbler/serendipity_plugin_audioscrobbler.php new file mode 100755 index 0000000..ac120eb --- /dev/null +++ b/plugins/serendipity_plugin_audioscrobbler/serendipity_plugin_audioscrobbler.php @@ -0,0 +1,542 @@ +sendRequest()) || $req->getResponseCode() != '200') { + if ( ini_get( "allow_url_fopen")) { + $data = file_get_contents($file); + } else { + $data = ""; + } + } else { + $data = $req->getResponseBody(); + } + 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'); + $propbag->add('version', '1.25'); + $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', '
'); + 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%
Artist: %ARTIST%
%DATE%
'); + 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', '
%PROFILE%

%ENTRIES%
%LASTUPDATE%
'); + break; + + default: + return false; + } + return true; + } + + //renders the date for output + function renderScrobblerDate($date) { + $stamp = $date + intval($this->utcdifference) * 60 * 60; + return htmlspecialchars(serendipity_formatTime($this->get_config('dateformat'), $stamp, true)); + } + + //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 ''."\n"; + return false; + } elseif ($this->get_config('forced') == 0 && $force) { + $this->set_config('forced', 1); + echo ''."\n"; + } + $this->setLastUpdateTry(); + echo ''."\n"; + $objXml = new s9y_audioscrobbler_XMLParser(); + $array = $objXml->getXMLArray('http://ws.audioscrobbler.com/1.0/user/'.$this->username.'/recenttracks.xml'); + error_log('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 ''."\n"; + return; + } + } + $fp = @fopen($this->scrobblercache, 'w'); + if ($fp) { + fwrite($fp, $this->encodeScrobblerArray($songs)); + fclose($fp); + $this ->songs = $songs; + echo ''."\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 ''."\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 ''."\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 ''."\n"; + $songs = $this->deStackerScrobbler($this->decodeScrobblerArray($songs)); + $this->writeScrobblerCache($songs); + return; + } + //return an O.K. cache + echo ''."\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 ''.PLUGIN_AUDIOSCROBBLER_ERROR.':
'; + 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 + $song = ''.htmlspecialchars($value['songtitle'], ENT_QUOTES).''."\n"; + } elseif (is_string(strstr($value['link'], '&mode'))) { + //link is ok + $song = ''.htmlspecialchars($value['songtitle'], ENT_QUOTES).''."\n"; + } else { + //encode it + $song = ''.htmlspecialchars($value['songtitle'], ENT_QUOTES).''."\n"; + } + } else { + $song = htmlspecialchars($value['songtitle'], ENT_QUOTES); + } + if ($artistlink == 0) { + $artist = htmlspecialchars($value['artisttitle'], ENT_QUOTES); + } elseif ($artistlink == 1) { + $artist = ''.htmlspecialchars($value['artisttitle'], ENT_QUOTES).''."\n"; + } elseif ($artistlink == 2) { + if ($value['artisttitle'] != '' || $value['artistlink'] != 'http://mm.musicbrainz.org/artist/') { + $artist = ''.htmlspecialchars($value['artisttitle'], ENT_QUOTES).''."\n"; + } else { + $artist = htmlspecialchars($value['artisttitle'], ENT_QUOTES); + } + } else { + if (trim($value['artistlink']) != 'http://mm.musicbrainz.org/artist/' && trim($value['artistlink']) != '') { + $artist = ''.htmlspecialchars($value['artisttitle'], ENT_QUOTES).''."\n"; + } else { + $artist = ''.htmlspecialchars($value['artisttitle'], ENT_QUOTES).''."\n"; + } + } + $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); + $output = str_replace('%PROFILE%', ''.htmlspecialchars($profiletitle, ENT_QUOTES).'', $output); + $output = str_replace('%LASTUPDATE%', htmlspecialchars(serendipity_formatTime($this->get_config('dateformat'), filemtime($this->scrobblercache), true)), $output); + $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"; + } +} +?>