Интеграция журнала LiveJournal в персональный сайт
1 Вступление
Все большую популярность среди пользователей интернета приобретает ведение
личных онлайновых дневников. Существует множество сайтов, которые позволяют
публиковать свои откровения в интернете легко и непринужденно, без какого-либо
знания специальных языков программирования и разметки гипертекста. Один из таких
сайтов - LiveJournal (www.livejournal.com), интернет-сервис, где каждый желающий
может завести себе личный дневник.
2 Задача
Создать программный комплекс, который позволит интегрировать журнал из
Livejournal в персональный сайт, предусмотреть возможность отображения постов и
комментариев с использованием предустановленного шаблона.
3 Существующие решения
Существует несколько методов решения данной задачи, которые описаны
непосредственно на сайте LiveJournal
(http://www.livejournal.com/developer/embedding.bml?method=all):
1. Самый простой путь встроить ваш журнал в персональный сайт - это вставить
JavaScript в HTML-код страницы. В браузерах, где JavaScript отключен, возможно
отображение ссылки на журнал:
2. Встраивание Livejournal при помощи фреймов. Данный метод будет работать
только в том случае, если браузер поддерживает отображение фрейм-структур:
<center>
<iframe name="livejournal"
src="http://www.livejournal.com/users/username/"
frameborder="0"
scrolling="auto" height="400" width="460">
<a href="http://username.livejournal.com/">View my LiveJournal</a>
</iframe>
</center>
3. Интеграция при помощи CGI-скриптов или PHP. Средствами языка программирования
производится чтение данных с удаленного ресурса и затем последующий вывод в
браузер без обработки информации:
Очевидное преимущество всех существующих решений - простота реализации. Подобная
интеграция займет не более 10 минут с минимальным увеличением скорости загрузки
страницы.
Недостатки: все вышеописанные способы интеграции доступны только для
пользователей с платными экаунтами. В случае же их модификации под бесплатные
журналы на вашей странице появится реклама которую необходимо будет
дополнительно фильтровать. Так же появляется проблема несоответствия дизайна
станицы и встраиваемого журнала. Вывод: ни один из способов внедрения от
Livejournal не предоставляет гибкости в настройках отображения записей и
комментариев журнала.
4 Решение
Суть предлагаемого метода - парсинг записей и комментариев журнала Livejournal и
последующий вывод результатов с использованием предустановленного шаблона.
5 Используемые технологии
PHP, MYSQL, RSS, Sockets
6 Кросс-браузерность
Internet Explorer 5.0,6.0,7.0; FireFox 1.0,2.0; Opera 9.0; Safari 2.0;
7 Входные и выходные параметры
Входные параметры:
$user - имя пользователя Livejournal, журнал которого будет интегрироватся в
персональный сайт;
$postCount - количество записей, отображаемых на странице;
Выходные параметры:
Структура данных, содержащая в себе записи и комментарии журнала Livejournal.
Фрагмент HTML-кода, отображающий записи и комментарии журнала Livejournal с
использованием предустановленного шаблона.
8 Реализация
Для начала нам необходимо получить ленту записей (постов) пользователя. К
счастью Livejournal выдает по RSS-каналу всю необходимую информацию о дневнике и
последних 25 записях. Ниже приведен фрагмент RSS-потока одного из журналов
Поскольку одним из самых распространенных языков написания скриптов в сети
является PHP, мы воспользуемся именно этим интерпретатором для интегрирования
дневника в сайт.
Широко распространенных способов обработки XML-документов существует два -
Event-based APIs и Document Object Model (DOM) APIs. В PHP стандартная поддержка
XML организована с помощью Event-based API (основана на событиях).
Сперва создадим класс RSSParser, внутри которого будет выполняться вся работа по
разбору XML. После создания класса, получим RSS-данные от сервиса LiveJournal и
инициализируем обработчик XML, который будет использовать для событийной
обработки (Event-based API) класс RSSParser. Код класса RSSParser приведен ниже:
case "LASTBUILDDATE": $this->lastBuildDate .= $data; break;
}
}
}
}
Стоит учитывать, что чаще всего XML-документы хранятся в Unicode кодировке
UTF-8, а в рунете наиболее часто используемой кодировкой является Windows-1251,
т.е. приходится решать проблему перекодировки.
or die("Error parsing RSS data from http://".$this->user.".
livejournal.com/data/rss !");
}
fclose($fp);
xml_parser_free($xml_parser);
$this->posts=$rss_parser->lj;
$this->userPic=$rss_parser->userPic;
$this->lastBuildDate=$rss_parser->lbd;
if ($this->delcuts)
$this->clearLivejournalCuts();
}
Данная функция является одним из методов класса Livejournal. Параметр
$this->postsCount определяет количество записей, которые будут считаны,
$this->maxPostSize - максимальный размер поста в байтах. Как результат
выполнения функции generatePostData() мы получаем двухмерный массив
$this->posts, в котором находятся записи журнала разбитые на элементы:
Заголовок, Дата, Текст, Ссылка на комментарии.
Следующий шаг - получение комментариев для каждой из записей. Все было бы так же
просто, если Livejournal выдавал ленту комментариев по RSS. К сожалению, такой
услуги нет ни для платных, ни для бесплатных экаунтов. Комментарии придется
получать при помощи HTML-парсера.
Существует две системы стилей (http://www.livejournal.com/customize/)
Livejournal при помощи которых происходит отображение журналов - S1 (для
пользователей, знакомых с CSS и HTML) и S2 (для остальных). Кроме того,
существует несколько стилей для просмотра журналов Livejournal
(http://www.livejournal.com/manage/settings/): Horizon, XCalibur, Dystopia,
Lynx. Самым "легким" из них является Lynx. Именно в этом стиле мы будем
считывать страницы с комментариями пользователей. Кроме того, это позволит нам
написать универсальный парсер для всех стилевых отображений журналов.
Метод getSocketData() считывает HTML-данные со страницы с комментариями. Для
того, чтоб использовать стиль Lynx необходимо в конце адресной строки дописать
параметр "?format=light".
//get socket data
function getSocketData($host,$request)
{
if ($fp = fsockopen($host, 80, $errno, $errstr, 5))
{
fputs($fp,$request);
$data="";
while(!feof($fp))
$data.=fgets($fp,2048);
fclose($fp);
}
return ($data);
}
//get livejournal comments
function getLJCommentsSock($ljUser, $commentsId)
{
$commentsPath=$commentsId.".html?format=light";
$host="livejournal.com";
$commonRequest= "Accept: */*"."\r\n".
"Accept-Language: ru"."\r\n".
"User-Agent: Mozilla/4.0 (compatible; MSIE 5.0; Windows NT)"."\r\n".
if ($prevName=="b" && !$this->comments[$j][user] && $parser->iNodeValue!="(")
$this->comments[$j][subj]=$parser->iNodeValue;
};
if ($parser->iNodeName=="img" && $parser->iNodeType == NODE_TYPE_ELEMENT)
{
$attrValues = $parser->iNodeAttributes;
$attrNames = array_keys($attrValues);
$size = count($attrNames);
for ($i = 0; $i < $size; $i++)
{
$name = $attrNames[$i];
if ($name=="src" && strpos($attrValues[$name],"userpic"))
$this->comments[$j][pic]=$attrValues[$name];
}
}
if ($parser->iNodeName=="a" && $parser->iNodeType == NODE_TYPE_ELEMENT)
{
$attrValues = $parser->iNodeAttributes;
$attrNames = array_keys($attrValues);
$size = count($attrNames);
for ($i = 0; $i < $size; $i++)
{
$name = $attrNames[$i];
if ($name=="href" && strpos($attrValues[$name],"replyto"))
{
$this->comments[$j][reply]=$attrValues[$name];
$j++;
$this->comments[$j][text]="";
}
}
}
$prevName=$parser->iNodeName;
};
$this->commentsCount=$j;
}
Как результат выполнения функции parseComments() мы получаем двухмерный массив
$this->comments, в котором находятся комментарии к текущей записи журнала
разбитые на элементы: Имя пользователя, Адрес юзерпика, Заголовок, Дата, Текст,
Ссылка на ответ.
В качестве дополнительных параметров можно установить максимальный размер записи
(var $maxPostSize = 999999) и возможность удаления катов (var $delcuts = true);
9 Пример работы
В качестве примера работы программного комплекса создадим произвольный шаблон
для отображения записей и комментариев журнала Livejournal.