Многие блоггеры используют в качестве своей блог-платформы всемирно известный livejournal.com, известный у нас как ЖЖ (Живой Журнал). Писать посты в ЖЖ можно не только при помощи стандартного веб-интерфейса ЖЖ, но также используя протокол XML-RPC, при помощи которого на любом языке программирования появляется возможность написать собственный блог-клиент, при помощи которого можно управлять своим ЖЖ. Так например делает биржа статей Liex для автоматического размещения статей на блогах ЖЖ. Каким образом написать свой блог-клиент для ЖЖ на Delphi, пойдет речь в этой статье.
Протокол XML-RPC представляет собой некоторый набор соглашений, при помощи которых программа-клиент может отправлять запросы при помощи
XML и получать ответы также в формате XML. Это в принципе все, что можно сказать о самом протоколе, ничего интересного. А вот реализация обмена данными при помощи
XML-RPC например в
Wordpress отличается от реализации XML-RPC в
ЖЖ или
Joomla. Поэтому реализацию постинга при помощи XML-RPC придется делать под каждую блог-платформу, которая вас интересует. Официальное описание XML-RPC для ЖЖ можно
прочитать здесь.
В этой статье мы приведем класс для работы с ЖЖ через XML-RPC, в котором пока будут реализованы две функции, одна будет выполнять логин в ЖЖ, другая оправлять пост в ЖЖ. Вот исходный текст класса
TLJXmlRpc:
unit ljxmlrpc;
interface
uses Classes, Windows, Dialogs, SysUtils, idHttp;
type
TLJXmlRpc=class
private
FUsername: string;
FPassword: string;
FLogged: boolean;
function PostXML(XML: string): string;
procedure AddLoginInfo(XML: TStringList);
procedure AddVersionInfo(XML: TStringList);
procedure AddDateInfo(XML: TStringList; Date: TDateTime);
public
function Login(AUserName,APassword: string): boolean;
function Post(ASubj,AText: string; ACreated: TDateTime=0): integer;
end;
implementation
procedure TLJXmlRpc.AddLoginInfo(XML: TStringList);
begin
XML.Add('<member><name>username</name>');
XML.Add('<value><string>'+FUsername+'</string></value>');
XML.Add('</member>');
XML.Add('<member><name>password</name>');
XML.Add('<value><string>'+FPassword+'</string></value>');
XML.Add('</member>');
end;
procedure TLJXmlRpc.AddVersionInfo(XML: TStringList);
begin
XML.Add('<member><name>ver</name>');
XML.Add('<value><int>1</int></value>');
XML.Add('</member>');
end;
procedure TLJXmlRpc.AddDateInfo(XML: TStringList; Date: TDateTime);
var y,m,d,h,mi,s,ms: word;
begin
DecodeDate(Date,y,m,d);
DecodeTime(Date,h,mi,s,ms);
XML.Add('<member><name>year</name>');
XML.Add('<value><int>'+IntToStr(y)+'</int></value>');
XML.Add('</member>');
XML.Add('<member><name>mon</name>');
XML.Add('<value><int>'+IntToStr(m)+'</int></value>');
XML.Add('</member>');
XML.Add('<member><name>day</name>');
XML.Add('<value><int>'+IntToStr(d)+'</int></value>');
XML.Add('</member>');
XML.Add('<member><name>hour</name>');
XML.Add('<value><int>'+IntToStr(h)+'</int></value>');
XML.Add('</member>');
XML.Add('<member><name>min</name>');
XML.Add('<value><int>'+IntToStr(s)+'</int></value>');
XML.Add('</member>');
end;
function TLJXmlRpc.PostXML(XML: string): string;
var http: TIdHTTP;
XMLRequest: TStringStream;
begin
http:=TIdHTTP.Create(nil);
XMLRequest:=TStringStream.Create('<?xml version="1.0"?>'+XML,CP_UTF8);
try
XMLRequest.Position:=0;
Result:=http.Post('http://www.livejournal.com/interface/xmlrpc',XMLRequest);
finally
XMLRequest.Free;
http.Free;
end;
end;
function TLJXmlRpc.Login(AUserName,APassword: string): boolean;
var XML: TStringList;
Ret: string;
begin
FUsername:=AUsername;
FPassword:=APassword;
XML:=TStringList.Create;
try
XML.Add('<methodCall>');
XML.Add('<methodName>LJ.XMLRPC.login</methodName>');
XML.Add('<params>');
XML.Add('<param>');
XML.Add('<value><struct>');
AddLoginInfo(XML);
AddVersionInfo(XML);
XML.Add('</struct></value>');
XML.Add('</param>');
XML.Add('</params>');
XML.Add('</methodCall>');
Ret:=PostXML(XML.Text);
if Pos('<methodResponse><fault>',Ret)=0 then FLogged:=true else
begin
FUsername:='';
FPassword:='';
FLogged:=false;
end;
Result:=FLogged;
finally
XML.Free;
end;
end;
function TLJXmlRpc.Post(ASubj,AText: string; ACreated: TDateTime=0): integer;
var XML: TStringList;
Ret: string;
begin
if not FLogged then
raise Exception.Create('Not logged on');
XML:=TStringList.Create;
try
XML.Add('<methodCall>');
XML.Add('<methodName>LJ.XMLRPC.postevent</methodName>');
XML.Add('<params>');
XML.Add('<param>');
XML.Add('<value><struct>');
AddLoginInfo(XML);
AddVersionInfo(XML);
XML.Add('<member><name>event</name>');
XML.Add('<value><string>'+AText+'</string></value>');
XML.Add('</member>');
XML.Add('<member><name>subject</name>');
XML.Add('<value><string>'+ASubj+'</string></value>');
XML.Add('</member>');
XML.Add('<member><name>lineendings</name>');
XML.Add('<value><string>pc</string></value>');
XML.Add('</member>');
if ACreated=0 then AddDateInfo(XML,Now) else AddDateInfo(XML,ACreated);
XML.Add('</struct></value>');
XML.Add('</param>');
XML.Add('</params>');
XML.Add('</methodCall>');
Ret:=PostXML(XML.Text);
finally
XML.Free;
end;
end;
end.
Пример использования класса:
lj: TLJXmlRpc;
...
lj:=TLJXmlRpc.Create;
if lj.Login('mylogin','mypass') then
lj.Post('test subj','this is new post');
В этом классе пока реализованы методы
Login и
Post. Реализация проста и понятна из кода. В классе используется Indy
TIdHTTP и применяется методика для отправки сообщения в
UTF8, которая была описана в статье
Indy TIdHTTP.POST и русские символы в HTML.
Описание реализации других функций, таких как получение списка постов, редактирование и удаление постов будут реализованы в будущем, так что следите за новыми публикациями.
Смотрите также:
Оставьте свой комментарий
Вы должны быть авторизированны, чтобы оставить комментарий.
Большое спасибо за ценное объяснение XML-RPC под Delphi, благодаря вашим наработкам написал клиенты для мультипостинга в сетки своих блогов по протоколу Metaweblog. Хотел уточнить один момент – допустим, перед применением каких-либо функций постинга мы делаем lj:=TLJXmlRpc.Create; Нужно ли делать в конце Free? У меня операции постинга выполняются в цикле, соответственно, на каждом шаге у меня создается все новый и новый TLJXmlRpc, как я понимаю (или я неправ?). В принципе все и так работает, не жалуюсь, но может быть так будет лучше?
попробовал на 7 версии компилируется только если из той же строчки убрать CP_UTF8, как исправить проблему, без єтого я так понимаю будут крякоряблы отсылатся.
Компилировалось в Delphi XE, иными словами в юникодной версии Delphi