Синхронизация с LiveJournal

Статья была написана для HostInfo.ru.

Думаю, мало кто поспорит, что блоги (в частности, сервис LiveJournal) стабильно обосновались в нашей жизни как (как минимум) довольно удобный способ узнать, что нового происходит в жизни друзей и знакомых. Еще интересно бывает следить за блогами незнакомых, но пишущих интересные статьи людей. Не стоит забывать и сообщества, коих великое множество. Таким образом, довольно приличное количество людей начинают свой день (или, напротив, завершают его) просмотром так называемой «френдленты», в которой к одной колонке сводятся все записи из интересующих журналов. Некоторые даже специально заводят аккаунты, которыми пользуются исключительно для того, чтобы одной страницей читать все новости. И нет-нет да и проскакивает мысль: «А как удобно было бы читать вот тот вот сайт в этой же френдленте». Действительно, есть огромное количество сайтов-блогов, ведущихся по тому же принципу, что и на LiveJournal, но на собственном хостинге. Если у вас подобный блог, почему не сделать синхронизацию, чтобы при изменениях на сайте автоматически изменялось его «зеркало» в LiveJournal?

В принципе, например, если ваш блог построен на CMS WordPress, то можно взять готовый плагин, синхронизирующий записи с сайта с аккаунтом в LiveJournal. Но это типовое решение, и в данной статье мы рассмотрим процесс чуть глубже, на уровне интерфейсов LiveJournal.

Будем считать, что процесс добавления новостей на свой собственный сайт вы наладили, и сосредоточимся на дублировании этих записей непосредственно в «Живой журнал». Собственно, для добавления записи у нас масса возможностей: через SMS, через Jabber, электронную почту. Однако нас интересуют два более гибких интерфейса: Flat- и XML-RPC-протоколы.

Flat Client/Server Protocol Flat Client/Server Protocol представляет собой обработку обычных POST-запросов. Например, страница, содержащая такую форму, может быть использована для добавления сообщений в любой дневник:
 <form accept-charset="UTF-8" method="post" name="postform"
 action="http://www.livejournal.com/interface/flat">
 <input type=hidden name=mode value="postevent">
 <input type=hidden name=user value="username">
 <input type=hidden name=password value="password">
 <input type=hidden name=auth_method value="clear">
 <input type=text name=year value="2007">
 <input type=text name=mon value="05">
 <input type=text name=day value="31">
 <input type=text name=hour value="17">
 <input type=text name=min value="0">
 <input type=text name=subject value="тема"><br /><br />
 <textarea name=event>сообщение</textarea><br /><br />
 <input type=button value="Ok" onclick="postform.submit()"><br />
 </form><br />

Естественно, в поля user и password вписываются логин и пароль журнала, в который, собственно, мы хотим добавить запись. В ответ на эту форму сервер (если данные учетной записи верны) выдаст ответ подобного вида:

 anum
 192
 itemid
 7
 success
 OK
 url
 http://user.livejournal.com/1984.html

Значение success, равное «OK», говорит о том, что сообщение успешно добавлено в журнал. В случае неудачи этот параметр будет равен FAIL. Параметр anum, судя по документации, предназначен для вычисления публичного itemid записи. На самом же деле я так и не встретил ситуации, когда бы этот параметр пригодился. Параметр itemid содержит номер записи в данном дневнике, и его можно, например, запомнить в базе – он может понадобиться для редактирования записи. Последний параметр – url – содержит прямую ссылку на запись.

Вуаля, треть нашей задачи мы осуществили: теперь при добавлении новости на сайт эта же новость без труда дублируется в «ЖЖ». Две оставшиеся трети проблемы решаются следующим образом:

 <form accept-charset="UTF-8" method="post" name="postform"
 action="http://www.livejournal.com/interface/flat">
 <input type=hidden name=mode value="editevent">
 <input type=hidden name=itemid value="7">
 <input type=hidden name=ver value="1">
 <input type=hidden name=user value="username">
 <input type=hidden name=password value="password">
 <input type=hidden name=mode value="editevent">
 <input type=hidden name=auth_method value="clear">
 <input type=text name=year value="2007">
 <input type=text name=mon value="05">
 <input type=text name=day value="31">
 <input type=text name=hour value="17">
 <input type=text name=min value="0">
 <input type=text name=subject value="тема"><br /><br />
 <textarea name=event>сообщение</textarea><br /><br />
 <input type=button value="Ok" onclick="postform.submit()">
 </form> 

Эта форма отличается от первой рассмотренной только второй и третьей строками. Параметр mode мы установили равным editevent и ввели параметр itemid, который содержит номер редактируемой записи в LiveJournal. Причем если поле event будет пустым, сообщение будет стерто.

XML-RPC Interface
Но Flat-интерфейс все-таки не очень удобен. Более гибким и мощным инструментом является XML-RPC-интерфейс. Для реализации работы с этим интерфейсом на PHP я выбрал библиотеку XML-RPC for PHP. Вот пример функции для добавления сообщения в журнал:

 function post_LJ($year,$month,$day,$hour,$minute,$subject,$event) {
 $lj_userid="user";
 $lj_passwd="password";
 
 $client=new xmlrpc_client("/interface/xmlrpc", "www.livejournal.com", 80);
 
 $params = new xmlrpcval( array(
 	 'username' => new xmlrpcval($lj_userid,'string'),
 	 'password' => new xmlrpcval($lj_passwd,'string'),
 	 'ver' => new xmlrpcval('1','string'),
 	 'lineendings' => new xmlrpcval('pc','string'),
 	 'event' => new xmlrpcval($event,'string'),
 	 'subject' => new xmlrpcval($subject,'string'),
 	 'year' => new xmlrpcval($year,'int'),
 	 'mon' => new xmlrpcval($month,'int'),
 	 'day' => new xmlrpcval($day,'int'),
 	 'hour' => new xmlrpcval($hour,'int'),
 	 'min' => new xmlrpcval($minute,'int')),'struct'
 );
 
 $msg = new xmlrpcmsg('LJ.XMLRPC.postevent');
 $msg->addparam($params);
 $client->setDebug(0);
 $result = $client->send($msg);
 if ($result->faultCode() != 0) {
 print "Ошибка: " . $result->faultString();
 } else {
 printf("Сообщение добавлено");
 };
 };

Если рассматривать процедуру вкратце, то мы сначала формируем XML-запрос, а затем отсылаем его серверу на обработку. В ответ мы получаем тоже XML-файл, но уже с результатами. Мы можем получить и распечатать любую запись из дневника:

 function view_LJ($itemid) {
 $lj_userid="user";
 $lj_passwd="password";
 
 $client=new xmlrpc_client("/interface/xmlrpc", "www.livejournal.com", 80);
 
 $params = new xmlrpcval( array(
 	 'username' => new xmlrpcval($lj_userid,'string'),
 	 'password' => new xmlrpcval($lj_passwd,'string'),
 	 'ver' => new xmlrpcval('1','string'),
 	 'lineendings' => new xmlrpcval('pc','string'),
 	 'selecttype' => new xmlrpcval('one','string'),
 	 'itemid' => new xmlrpcval('itemid','string'),
 	 'year' => new xmlrpcval($year,'int'),
 	 'month' => new xmlrpcval($month,'int'),
 	 'day' => new xmlrpcval($day,'int')),'struct'
 );
 
 $msg = new xmlrpcmsg('LJ.XMLRPC.getevents');
 $msg->addparam($params);
 $client->setDebug(0);
 $result = $client->send($msg);
 if ($result->faultCode() != 0) {
 print "Ошибка: ".$result->faultString();
 return;
 };
 
 $v=$result->value();
 $events=$v->structMem('events');
 $event = $events->arrayMem(0);
 $itemid_xml=$event->structMem('itemid');
 $eventtime_xml=$event->structMem('eventtime');
 $subject_xml=$event->structMem('subject');
 $event_xml=$event->structMem('event');
 
 $itemid=$itemid_xml->scalarVal();
 $subject=$subject_xml->scalarVal();
 $eventtime=$eventtime_xml->scalarVal();
 $event=$event_xml->scalarVal();
 
 printf("$eventtime<br /><br />");
 printf("$subject<br /><br />");
 printf("$event<br />");
 
 };

То есть при большом желании можно не хранить записи на сайте, а получать их в момент формирования страницы со своего «ЖЖ»-аккаунта.

Редактирование и удаление записей производится по аналогии с примером, приведенном для Flat-интерфейса:

 function post_LJ($itemid,$year,$month,$day,$hour,$minute,$title,$message) {
 $lj_userid="user";
 $lj_passwd="password";
 
 $client=new xmlrpc_client("/interface/xmlrpc", "www.livejournal.com", 80);
 
 $params = new xmlrpcval( array(
 	 'username' => new xmlrpcval($lj_userid,'string'),
 	 'password' => new xmlrpcval($lj_passwd,'string'),
 	 'ver' => new xmlrpcval('1','string'),
 	 'itemid' => new xmlrpcval($itemid,'int'),
 	 'event' => new xmlrpcval($message,'string'),
 	 'lineendings' => new xmlrpcval('pc','string'),
 	 'subject' => new xmlrpcval($title,'string'),
 	 'year' => new xmlrpcval($year,'int'),
 	 'mon' => new xmlrpcval($month,'int'),
 	 'day' => new xmlrpcval($day,'int'),
 	 'hour' => new xmlrpcval($hour,'int'),
 	 'min' => new xmlrpcval($minute,'int')),'struct'
 );
 
 $msg = new xmlrpcmsg('LJ.XMLRPC.editevent');
 $msg->addparam($params);
 $client->setDebug(0);
 $result = $client->send($msg);
 if ($result->faultCode() != 0) {
 print "Couldn't process request: ".$result->faultString();
 return;
 };
 };

Таким образом можно реализовывать довольно интересные комбинации. Например, вы можете вести дневник на LiveJournal и вкраплять в ленту записей новости своего сайта. Или, напротив, разбавлять новости на главной странице записями из своего «ЖЖ». Также можно не ограничиваться одним аккаунтом, а, допустим, если у вас музыкальная группа, то на странице сайта можно собрать до кучи записи из «ЖЖ»-аккаунтов всех участников. В общем, возможности ограничиваются исключительно вашей фантазией и производительностью сервера.


28 июня 2007

Опубликовано на HostInfo.ru 29 июня 2007.


« вернуться к списку текстов
« комментарии ()


© сайт разработан и поддерживается мной.