FoxBase!
msgbartop
Блог Oracle разработчика
msgbarbottom
foxbase

18.12.2010 Livejournal XML-RPC. Часть 1

Livejournal XML-RPC
Многие блоггеры используют в качестве своей блог-платформы всемирно известный 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
Описание реализации других функций, таких как получение списка постов, редактирование и удаление постов будут реализованы в будущем, так что следите за новыми публикациями. 

www.foxbase.ru



Смотрите также:



Комментарии читателей

  1. |

    Большое спасибо за ценное объяснение XML-RPC под Delphi, благодаря вашим наработкам написал клиенты для мультипостинга в сетки своих блогов по протоколу Metaweblog. Хотел уточнить один момент – допустим, перед применением каких-либо функций постинга мы делаем lj:=TLJXmlRpc.Create; Нужно ли делать в конце Free? У меня операции постинга выполняются в цикле, соответственно, на каждом шаге у меня создается все новый и новый TLJXmlRpc, как я понимаю (или я неправ?). В принципе все и так работает, не жалуюсь, но может быть так будет лучше?

  2. |

    попробовал на 7 версии компилируется только если из той же строчки убрать CP_UTF8, как исправить проблему, без єтого я так понимаю будут крякоряблы отсылатся.

  3. |

    Компилировалось в Delphi XE, иными словами в юникодной версии Delphi



Оставьте свой комментарий

Вы должны быть авторизированны, чтобы оставить комментарий.