From 5823f8fa6225decc00fca22d9b733198f40b5d9d Mon Sep 17 00:00:00 2001 From: NMD Date: Sat, 21 Aug 2010 15:17:41 +0600 Subject: [PATCH 1/9] =?UTF-8?q?=D1=81=D0=BE=D0=B7=D0=B4=D0=B0=D0=BB=20?= =?UTF-8?q?=D1=80=D0=B5=D0=BF=D0=BE=D0=B7=D0=B8=D1=82=D0=B0=D1=80=D0=B8?= =?UTF-8?q?=D0=B9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Demo/blogger_api_demo/ExampleBlogApi.dpr | 14 + Demo/blogger_api_demo/ExampleBlogApi.res | Bin 0 -> 5280 bytes Demo/blogger_api_demo/Unit1.dcu | Bin 0 -> 11840 bytes Demo/blogger_api_demo/Unit1.dfm | 142 ++++ Demo/blogger_api_demo/Unit1.pas | 145 ++++ packages/BloggerApi.pas | 966 ++++++++++++++++++++++ packages/BloggerApi_Pack.res | Bin 0 -> 6336 bytes sourse/BloggerApi.pas | 967 +++++++++++++++++++++++ 8 files changed, 2234 insertions(+) create mode 100644 Demo/blogger_api_demo/ExampleBlogApi.dpr create mode 100644 Demo/blogger_api_demo/ExampleBlogApi.res create mode 100644 Demo/blogger_api_demo/Unit1.dcu create mode 100644 Demo/blogger_api_demo/Unit1.dfm create mode 100644 Demo/blogger_api_demo/Unit1.pas create mode 100644 packages/BloggerApi.pas create mode 100644 packages/BloggerApi_Pack.res create mode 100644 sourse/BloggerApi.pas diff --git a/Demo/blogger_api_demo/ExampleBlogApi.dpr b/Demo/blogger_api_demo/ExampleBlogApi.dpr new file mode 100644 index 0000000..3de5039 --- /dev/null +++ b/Demo/blogger_api_demo/ExampleBlogApi.dpr @@ -0,0 +1,14 @@ +program ExampleBlogApi; + +uses + Forms, + Unit1 in 'Unit1.pas' {Form1}; + +{$R *.res} + +begin + Application.Initialize; + Application.MainFormOnTaskbar := True; + Application.CreateForm(TForm1, Form1); + Application.Run; +end. diff --git a/Demo/blogger_api_demo/ExampleBlogApi.res b/Demo/blogger_api_demo/ExampleBlogApi.res new file mode 100644 index 0000000000000000000000000000000000000000..4ade5707e61635741977619f39c2ecbaadf8f8b0 GIT binary patch literal 5280 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 literal 0 HcmV?d00001 diff --git a/Demo/blogger_api_demo/Unit1.dfm b/Demo/blogger_api_demo/Unit1.dfm new file mode 100644 index 0000000..b600f22 --- /dev/null +++ b/Demo/blogger_api_demo/Unit1.dfm @@ -0,0 +1,142 @@ +object Form1: TForm1 + Left = 0 + Top = 0 + Caption = 'Form1' + ClientHeight = 455 + ClientWidth = 622 + Color = clBtnFace + Font.Charset = DEFAULT_CHARSET + Font.Color = clWindowText + Font.Height = -11 + Font.Name = 'Tahoma' + Font.Style = [] + OldCreateOrder = False + PixelsPerInch = 96 + TextHeight = 13 + object Button1: TButton + Left = 8 + Top = 217 + Width = 201 + Height = 25 + Caption = #1055#1086#1083#1091#1095#1077#1085#1080#1077' '#1082#1083#1102#1095#1072 + TabOrder = 0 + OnClick = Button1Click + end + object Memo1: TMemo + Left = 8 + Top = 8 + Width = 530 + Height = 81 + Lines.Strings = ( + 'Memo1') + TabOrder = 1 + WantTabs = True + end + object ComboBox1: TComboBox + Left = 8 + Top = 190 + Width = 145 + Height = 21 + TabOrder = 2 + Text = 'ComboBox1' + OnChange = ComboBox1Change + end + object Button2: TButton + Left = 8 + Top = 244 + Width = 201 + Height = 25 + Caption = #1057#1086#1079#1076#1072#1085#1080#1077' '#1087#1086#1089#1090#1072 + TabOrder = 3 + OnClick = Button2Click + end + object Memo2: TMemo + Left = 8 + Top = 95 + Width = 185 + Height = 89 + Lines.Strings = ( + 'Memo2') + TabOrder = 4 + end + object Memo3: TMemo + Left = 199 + Top = 95 + Width = 185 + Height = 89 + Lines.Strings = ( + '

Memo2

') + TabOrder = 5 + end + object Button3: TButton + Left = 8 + Top = 271 + Width = 201 + Height = 25 + Caption = #1055#1086#1083#1091#1095#1077#1085#1080#1077' '#1087#1086#1089#1090#1072 + TabOrder = 6 + OnClick = Button3Click + end + object Button4: TButton + Left = 8 + Top = 298 + Width = 201 + Height = 25 + Caption = #1055#1086#1083#1091#1095#1077#1085#1080#1077' '#1087#1086#1089#1090#1072' '#1089' '#1087#1072#1088#1072#1084#1077#1090#1088#1072#1084#1080 + TabOrder = 7 + OnClick = Button4Click + end + object Button5: TButton + Left = 8 + Top = 325 + Width = 201 + Height = 25 + Caption = #1054#1073#1085#1086#1074#1083#1077#1085#1080#1077' '#1087#1086#1089#1090#1072 + TabOrder = 8 + OnClick = Button5Click + end + object Edit1: TEdit + Left = 224 + Top = 327 + Width = 185 + Height = 21 + TabOrder = 9 + Text = 'Edit1' + end + object Button6: TButton + Left = 8 + Top = 353 + Width = 201 + Height = 25 + Caption = 'Button6' + TabOrder = 10 + OnClick = Button6Click + end + object ProgressBar1: TProgressBar + Left = 328 + Top = 244 + Width = 150 + Height = 17 + TabOrder = 11 + end + object Blogger1: TBlogger + AppName = 'MyCompany' + Blogs = <> + OnProgress = Blogger1Progress + OnError = Blogger1Error + Left = 584 + Top = 8 + end + object GoogleLogin1: TGoogleLogin + AppName = + 'Mozilla/5.0 (Windows; U; Windows NT 5.1; ru; rv:1.9.2.6) Gecko/2' + + '0100625 Firefox/3.6.6' + AccountType = atGOOGLE + Email = 'nmdsoft@gmail.com' + Password = 'programmersofta#' + Service = blogger + OnAutorization = GoogleLogin1Autorization + Left = 584 + Top = 56 + end +end diff --git a/Demo/blogger_api_demo/Unit1.pas b/Demo/blogger_api_demo/Unit1.pas new file mode 100644 index 0000000..86a64f1 --- /dev/null +++ b/Demo/blogger_api_demo/Unit1.pas @@ -0,0 +1,145 @@ +unit Unit1; + +interface + +uses + Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms, + Dialogs, StdCtrls, BloggerApi, uGoogleLogin, ComCtrls; + +type + TForm1 = class(TForm) + Blogger1: TBlogger; + Button1: TButton; + Memo1: TMemo; + GoogleLogin1: TGoogleLogin; + ComboBox1: TComboBox; + Button2: TButton; + Memo2: TMemo; + Memo3: TMemo; + Button3: TButton; + Button4: TButton; + Button5: TButton; + Edit1: TEdit; + Button6: TButton; + ProgressBar1: TProgressBar; + procedure Button1Click(Sender: TObject); + procedure GoogleLogin1Autorization(const LoginResult: TLoginResult; Result: TResultRec); + procedure Button2Click(Sender: TObject); + procedure Button3Click(Sender: TObject); + procedure Button4Click(Sender: TObject); + procedure Button5Click(Sender: TObject); + procedure Button6Click(Sender: TObject); + procedure Blogger1Error(E: string); + procedure ComboBox1Change(Sender: TObject); + procedure Blogger1Progress(aCurrentProgress, aMaxProgress: Integer); + private + { Private declarations } + public + { Public declarations } + end; + +var + Form1: TForm1; + +implementation + +{$R *.dfm} + +procedure TForm1.Blogger1Error(E: string); +begin + ShowMessage(e); +end; + +procedure TForm1.Blogger1Progress(aCurrentProgress, aMaxProgress: Integer); +begin + ProgressBar1.Max:=aMaxProgress; + ProgressBar1.Position:=aCurrentProgress; +end; + +procedure TForm1.Button1Click(Sender: TObject); +begin + GoogleLogin1.Login; +end; + +procedure TForm1.Button2Click(Sender: TObject); +var + a:TStringList; +begin + a:=TStringList.Create; + a.Add('dd'); + Memo1.Lines.Text:= Blogger1.PostCreat(Memo2.Text,Memo3.Text ,a,False); + a.Free; +end; + +procedure TForm1.Button3Click(Sender: TObject); +var + aa:TPostCollection; +begin + aa:=TPostCollection.Create(nil); + aa:=Blogger1.RetrievAllPosts; + if aa.Count<1 then + Exit; + Memo1.Lines.Add( IntToStr( aa.Count)); + Memo1.Lines.Add(aa.Items[0].PostId); + Memo1.Lines.Add(DateToStr(aa.Items[0].PostPublished)); + Memo1.Lines.Add(DateToStr(aa.Items[0].PostUpdate)); + Memo1.Lines.Add(aa.Items[0].PostTitle); + Memo1.Lines.Add(aa.Items[0].PostSourse.Text); + Memo1.Lines.Add(aa.Items[0].СategoryPost.Text); + aa.Free; +end; + +procedure TForm1.Button4Click(Sender: TObject); +var + aa:TPostCollection; +begin + aa:=TPostCollection.Create(nil); + aa:=Blogger1.RetrievPostForParams('Wininet','','','','','',1,2); + if aa.Count<1 then + begin + aa.Free; + Exit; + end; + Memo1.Lines.Add( IntToStr( aa.Count)); + Memo1.Lines.Add(aa.Items[0].PostId); + Memo1.Lines.Add(DateToStr(aa.Items[0].PostPublished)); + Memo1.Lines.Add(DateToStr(aa.Items[0].PostUpdate)); + Memo1.Lines.Add(aa.Items[0].PostTitle); + Memo1.Lines.Add(aa.Items[0].PostSourse.Text); + Memo1.Lines.Add(aa.Items[0].СategoryPost.Text); + aa.Free; +end; + +procedure TForm1.Button5Click(Sender: TObject); +var + a:TStringList; +begin + a:=TStringList.Create; + a.Add('Привет'); + Blogger1.PostModify(Edit1.Text,Memo2.Text,Memo3.Text ,a,False); + a.Free; +end; + +procedure TForm1.Button6Click(Sender: TObject); +begin + Blogger1.PostDelete(Edit1.Text); +end; + +procedure TForm1.ComboBox1Change(Sender: TObject); +begin + Blogger1.CurrentBlog:=ComboBox1.ItemIndex; +end; + +procedure TForm1.GoogleLogin1Autorization(const LoginResult: TLoginResult; Result: TResultRec); +var + i:Integer; +begin + Blogger1.Auth:=Result.Auth; + Blogger1.RetrievAllBlogs; + Memo1.Lines:=Blogger1.Blogs.Items[1].СategoryBlog; + + for I := 0 to Blogger1.Blogs.Count - 1 do + ComboBox1.Items.Add(Blogger1.Blogs.Items[i].Title); +end; + +end. diff --git a/packages/BloggerApi.pas b/packages/BloggerApi.pas new file mode 100644 index 0000000..0d670fe --- /dev/null +++ b/packages/BloggerApi.pas @@ -0,0 +1,966 @@ +{*******************************************************} +{ } +{ BloggerApi } +{ } +{ Copyright (C) 2010 NMD } +{ http://nmdsoft.blogspot.com/ } +{*******************************************************} + + +unit BloggerApi; + +interface + +uses + SysUtils, Classes,NativeXml,WinInet; + +//ошибки +resourcestring +rsErrorXmlTag='Нет закрывающего тега. HTHL должен быть валидным'; +rsErrorNotTolken='Нет толкена google для работы с сервисом'; +rsErrorNotSelectBlog='Блог не выбран! Смотри property CurrentBlog'; +rsErrorIdPost='Не указан Id сообщения в блоге'; + +rsErrorGet='Произошла сетевая ошибка при получении данных c сервера'; +rsErrorDelete='Произошла сетевая ошибка при выполнении запроса Delete'; +rsErrorPost='Произошла сетевая ошибка при отправке данных на сервер'; +rsErrorPut='Произошла сетевая ошибка при обновлении данных на сервер'; +const + cnsBlogDefault='http://www.blogger.com/feeds/default/blogs'; + cnsEntry='entry'; + cnsName='name'; + cnsId='id'; + cnsPublished='published'; + cnsUpdated='updated'; + cnsTitle='title'; + cnsCategory='category'; + cntTerm='term'; + cnsXhtml='xhtml'; + cnsXmlns='xmlns'; + cnsType='type'; + cnsText='text'; + cnsContent='content'; + cnsScheme='scheme'; + cnsTerm='term'; + cnsDiv='div'; + cnsAtomUrl='http://www.w3.org/2005/Atom'; + cnsXhtmlUrl='http://www.w3.org/1999/xhtml'; + cnsAtnsUrl='http://www.blogger.com/atom/ns#'; + //http://www.blogger.com/feeds/blogID/posts/default + cnsPostBlogStart='http://www.blogger.com/feeds/'; + cnsPostBlogEnd='/posts/default'; + cnsAppControll='app:control'; + cnsXmlnsApp='xmlns:app'; + cnsXmlnsAppUrl='http://www.w3.org/2007/app'; + cnsAppDraft='app:draft'; + cnsYes='yes'; + cnsVop='/?'; +// cnsPostIdUrl='http://www.blogger.com/feeds/blogID/posts/default/postID'; + +type + //событие для ошибки + TErrorEvent = procedure(aE: string) of object; + //Прогресс выполнения задания + TProgressEvent = procedure(aCurrentProgress,aMaxProgress: Integer) of object; + + TPostItem = class (TCollectionItem) + private + FPostTitle: string; + FPostId: string; + FPostSourse: TStringList; + FСategoryPost:TStringList; + FPostPublished: TDateTime; + FPostUpdate: TDateTime; + procedure SetPostId(const Value: string); + procedure SetPostPublished(const Value: TDateTime); + procedure SetPostSourse(const Value: TStringList); + procedure SetPostTitle(const Value: string); + procedure SetPostUpdate(const Value: TDateTime); + procedure SetСategoryPost(const Value: TStringList); + public + constructor Create(Collection: TCollection);override; + destructor Destroy; override; + published + property PostId:string read FPostId write SetPostId; + property PostTitle:string read FPostTitle write SetPostTitle; + property PostSourse:TStringList read FPostSourse write SetPostSourse; + property СategoryPost:TStringList read FСategoryPost write SetСategoryPost; + property PostPublished:TDateTime read FPostPublished write SetPostPublished; + property PostUpdate:TDateTime read FPostUpdate write SetPostUpdate; + end; + + TPostCollection = class (TCollection) + private + function GetItemBlog(Index: Integer): TPostItem; + procedure SetItemBlog(Index: Integer; Value: TPostItem); + public + constructor Create(AOwner:TComponent); + function Add: TPostItem; + property Items[Index: Integer]: TPostItem read GetItemBlog write SetItemBlog; + function AddEx(aPostTitle,aPostId:string; aPostSourse:TStringList;aPostPublished,aPostUpdate:TDateTime): TPostItem; + end; + + + TBlogItem = class (TCollectionItem) + private + FTitle:string;//заголовок + FBlogId:string;//id блога + FСategoryBlog:TStringList;//ярлыки блога + FPublished:TDateTime;//дата последеней публикации + FUpdate:TDateTime;//дата последнего обновления + procedure SetCategory(const Value: TStringList); + procedure SetPublished(const Value: TDateTime); + procedure SetUpdate(const Value: TDateTime); + procedure SetBlogId(const Value: string); + procedure SetTitle(const Value: string); + + public + constructor Create(Collection: TCollection);override; + destructor Destroy; override; + published + property Title:string read FTitle write SetTitle; + property BlogId:string read FBlogId write SetBlogId; + property СategoryBlog:TStringList read FСategoryBlog write SetCategory; + property Publish:TDateTime read FPublished write SetPublished; + property Update:TDateTime read FUpdate write SetUpdate; + end; + + TBlogCollection = class (TCollection) + private + function GetItemBlog(Index: Integer): TBlogItem; + procedure SetItemBlog(Index: Integer; Value: TBlogItem); + public + constructor Create(AOwner:TComponent); + function Add: TBlogItem; + property Items[Index: Integer]: TBlogItem read GetItemBlog write SetItemBlog; + function AddEx(aName,aTitle,aBlogId: string;aUrl:string;aСategoryBlog:TStringList;aPublished,aUpdate:TDateTime): TBlogItem; + end; + +//класс для работы с блогами на Blogger'e +type + TBlogger = class(TComponent) + private + //для работы с xml + FXMLDoc:TNativeXml; + FAuth:string; + FUrl:string;//ссылка на профиль владельца блога + FAppName:string;//название приложения + FBlogs:TBlogCollection; + FCurrentBlog: Integer;//блог с которым будем непосредственно работать + //для событий + FProgress:TProgressEvent; + FErrorEvent: TErrorEvent;//ошибка + + //вспомогательные для работы с инетом + function GetUrl(url, param, method: string; AUTH:AnsiString;postData: UTF8String): UTF8String; + function DataAvailable(hRequest: pointer; out Size: cardinal): boolean; + function GetScriptName(url, hostname: string): string; + procedure SetFlags(url: string; out Flags_connection, Flags_Request: Cardinal); + function GetHostName(url: string): string; + + function GetIdBlog(aSourse:string):string;//получение id блога + function GetPostId(aSourse:string):string;//получение id поста + + procedure ToError(aError:string);//обработка ошибок + //для пропертей + procedure SetAppName(const Value: string); + procedure SetAuth(const Value: string); + procedure SetBlog(const Value: TBlogCollection); + procedure SetCurrentBlog(const Value: Integer); + + protected + public + procedure RetrievAllBlogs;//получение списка блогов пользователя + function PostCreat(aTitle,aContent:string; aCategory:TStringList;aComment:Boolean):UTF8String;//создание сообщения и отправка в блог + function PostModify(id,aTitle,aContent:string; aCategory:TStringList;aComment:Boolean):UTF8String;//Изменение сообщения и отправка его в блог + function PostDelete(id:string):Boolean;//удаление поста из блога + + function RetrievAllPosts:TPostCollection;//получаем последние 25 постов из блога + //получение статей по заданным параметрам + function RetrievPostForParams(aCategory:string =''; aOrderby:string =''; aPublishedMin:string =''; + aPublishedMax:string =''; aUpdatedMin:string ='';aUpdatedMax:string =''; + aStartIndex:Integer=0; aMaxResults:Integer=0; aAlt : string =''):TPostCollection; + //Возвращает посты из блога по заданным параметрам созданым в ручную + function RetrievPostForTextParams(Parametrs:string):TPostCollection; + constructor Create(AOwner: TComponent);override;//инициализация класса + destructor Destroy; override;//уничтожение + published + property Auth:string read FAuth write SetAuth; + property AppName:string read FAppName write SetAppName; + property CurrentBlog:Integer read FCurrentBlog write SetCurrentBlog default -1; + property Url: string read FUrl; + property Blogs:TBlogCollection read FBlogs write SetBlog; + + //события + property OnProgress:TProgressEvent read FProgress write FProgress;//прогресс выполнения задачи + property OnError:TErrorEvent read FErrorEvent write FErrorEvent;//возникает при ошибке ) + + end; + +procedure Register; + +implementation + +constructor TBlogger.Create(AOwner: TComponent); +begin + inherited; + FBlogs:=TBlogCollection.Create(Self); + FXMLDoc:=TNativeXml.Create; + FAuth:=''; + FAppName:='MyCompany'; + FCurrentBlog:=-1; +end; + +destructor TBlogger.Destroy; +begin + FreeAndNil(FXMLDoc); + FBlogs.Free; + inherited; +end; + +function TBlogger.GetHostName(url : string) : string; +begin + result := ''; + if pos('https://',url) > 0 then + begin + delete(url,1,length('https://')); + SetLength(url,pos('/',url) - 1); + result := url; + end + else + if pos('http://',url) > 0 then + begin + delete(url,1,length('http://')); + SetLength(url,pos('/',url) - 1); + result := url; + end; +end; + +{------------------------------------------------------------------------------- + Функция: TBlogger.GetIdBlog + Автор: NMD + Дата: 2010.08.08 + Входные параметры: aSourse: string строка содержащая id блога + Результат: id блога string +-------------------------------------------------------------------------------} +function TBlogger.GetIdBlog(aSourse: string): string; +var + i:Integer; +begin + Result:=''; + i:=AnsiPos('.blog-',aSourse); + Delete(aSourse,1,i+5); + Result:=aSourse; +end; + +function TBlogger.GetPostId(aSourse: string): string; +var + i:Integer; +begin + Result:=''; + i:=AnsiPos('.post-',aSourse); + Delete(aSourse,1,i+5); + Result:=aSourse; +end; + +function TBlogger.GetScriptName( url,hostname : string) : string; +begin + result := ''; + delete(url,1,pos(hostname,url) + length(hostname)); + result := url; +end; + +procedure TBlogger.SetFlags(url : string; out Flags_connection,Flags_Request : Cardinal); +begin + //Оприделяем на https или http + if pos('https',url) > 0 then + begin + Flags_connection := INTERNET_DEFAULT_HTTPS_PORT; + Flags_Request := INTERNET_FLAG_RELOAD or INTERNET_FLAG_IGNORE_CERT_CN_INVALID or INTERNET_FLAG_NO_CACHE_WRITE or INTERNET_FLAG_SECURE or INTERNET_FLAG_PRAGMA_NOCACHE or INTERNET_FLAG_KEEP_CONNECTION; + end + else + begin + Flags_connection := INTERNET_DEFAULT_HTTP_PORT; + Flags_Request := INTERNET_FLAG_RELOAD or INTERNET_FLAG_IGNORE_CERT_CN_INVALID or INTERNET_FLAG_NO_CACHE_WRITE or INTERNET_FLAG_PRAGMA_NOCACHE or INTERNET_FLAG_KEEP_CONNECTION; + end; +end; + +//обработка ошибок +procedure TBlogger.ToError(aError: string); +begin + if Assigned(FErrorEvent) then + OnError(aError); +end; + +function TBlogger.DataAvailable(hRequest: pointer; out Size : cardinal): boolean; +begin + result := wininet.InternetQueryDataAvailable(hRequest, Size, 0, 0); +end; + +function TBlogger.GetUrl(url : string; param: string; method : string; AUTH:AnsiString; postData:UTF8String) :UTF8String;//Получение страницы по url +var + FHost,FScript : string; + hInternet,hConnect,hRequest : Pointer; + dwBytesRead,I,L : Cardinal; + Flags_connection,Flags_Request : Cardinal; + Flag_HttpSendRequest:LongBool; + header:TStringStream; +begin + result := ''; + fHost := GetHostName(url); + fScript := GetScriptName(url,fHost); + if Param <> '' then + if fScript[Length(fScript)] = '?' then + fScript := fScript + param + else + fScript := fScript + '?' + param; + //Устанавливаем флаги + SetFlags(url,Flags_connection,Flags_Request); + //Инициализируем WinInet + hInternet := InternetOpen(PChar(FAppName),INTERNET_OPEN_TYPE_PRECONFIG,Nil,Nil,0); + if Assigned(hInternet) then + begin + //Открываем сессию + hConnect := InternetConnect(hInternet,PChar(FHost),Flags_connection,nil,nil,INTERNET_SERVICE_HTTP,0,1); + if Assigned(hConnect) then + begin + //Формируем запрос + hRequest := HttpOpenRequest(hConnect,PChar(uppercase(method)),PChar(fScript),HTTP_VERSION,nil,Nil,Flags_Request,1); + if Assigned(hRequest) then + begin + header:=TStringStream.Create; + with Header do + begin + WriteString('Content-Type:application/atom+xml'+SLineBreak); + WriteString('GData-Version:2 '+SLineBreak); + WriteString('Authorization: GoogleLogin auth='+AUTH+SLineBreak+SLineBreak); + end; + //Отправляем запрос + I := 1; + if uppercase(method)='GET' then + begin + Flag_HttpSendRequest:=HttpSendRequest(hRequest,PChar(header.DataString),Length(header.DataString),nil,0); + if not Flag_HttpSendRequest then + ToError(rsErrorGet); + end; + if uppercase(method)='POST' then + begin + Flag_HttpSendRequest:=HttpSendRequest(hRequest,PChar(header.DataString),Length(header.DataString),Pointer(postData),Length(postData)); + if not Flag_HttpSendRequest then + ToError(rsErrorPost); + end; + if uppercase(method)='PUT' then + begin + Flag_HttpSendRequest:=HttpSendRequest(hRequest,PChar(header.DataString),Length(header.DataString),Pointer(postData),Length(postData)); + if not Flag_HttpSendRequest then + ToError(rsErrorPut); + end; + if uppercase(method)='DELETE' then + begin + Flag_HttpSendRequest:=HttpSendRequest(hRequest,PChar(header.DataString),Length(header.DataString),nil,0); + if not Flag_HttpSendRequest then + begin + OnError(rsErrorDelete); + Result:='0' + end + else + begin + Result:='1'; + end; + end; + if Flag_HttpSendRequest and (uppercase(method)<>'DELETE') then + begin + repeat + DataAvailable(hRequest, L);//Получаем кол-во принимаемых данных + if L = 0 then break; + SetLength(result,L + I); + if not (InternetReadFile(hRequest,@result[I],sizeof(L),dwBytesRead)) then //Получаем данные с сервера + begin + OnError(rsErrorGet); + end; + if Assigned(FProgress) then //прогресс + OnProgress(i,L+1); + inc(I,dwBytesRead); + until dwBytesRead = 0; + result[I] := #0; + end; + end; + InternetCloseHandle(hRequest); + end; + InternetCloseHandle(hConnect); + end; + InternetCloseHandle(hInternet); + header.Free; +end; + +{------------------------------------------------------------------------------- + Процедура: TBlogger.RetrievAllBlogs + Автор: NMD + Дата: 2010.08.03 21:13:59 + Входные параметры: Нет + Результат: получение списка блогов пользователя +-------------------------------------------------------------------------------} +procedure TBlogger.RetrievAllBlogs; +var + i,i2:Integer; + Nodes,NodesChild: TXmlNodeList; +begin + FBlogs.Clear;//очистка блогов перед получением нового списка + FXMLDoc.Clear; + FXMLDoc.ReadFromString(GetUrl(cnsBlogDefault,'','get',FAuth,'')); + //проверка на существование коллекции + if not Assigned(FBlogs) then Exit; + try + Nodes:=TXmlNodeList.Create; + FXMLDoc.Root.FindNodes('entry',Nodes); + for i := 0 to Nodes.Count-1 do + begin + FBlogs.Add; + FBlogs.Items[i].BlogId:=GetIdBlog(Nodes.Items[i].NodeByName(cnsId).ValueAsString); + FBlogs.Items[i].Publish:=Nodes.Items[i].NodeByName(cnsPublished).ValueAsDateTime; + FBlogs.Items[i].Update:=Nodes.Items[i].NodeByName(cnsUpdated).ValueAsDateTime; + FBlogs.Items[i].Title:=Nodes.Items[i].NodeByName(cnsTitle).ValueAsString; + NodesChild:=TXmlNodeList.Create; + Nodes.Items[i].FindNodes(cnsCategory,NodesChild); + for i2 := 0 to NodesChild.Count - 1 do + begin + FBlogs.Items[i].СategoryBlog.Add(NodesChild.Items[i2].AttributeByName[cntTerm]); + end; + end; + finally + FreeAndNil(Nodes); + FreeAndNil(NodesChild); + end; +end; + +{------------------------------------------------------------------------------- + Функция: TBlogger.RetrievAllPosts + Автор: NMD + Дата: 2010.08.09 + Входные параметры: Нет + Что делает: получает последние 25 сообщений из блога + Результат: Коллекция TPostCollection содержащая исчерпывающую информацию о сообщении и само сообщение +-------------------------------------------------------------------------------} +function TBlogger.RetrievAllPosts: TPostCollection; +var + Nodes,NodesChild: TXmlNodeList; + i,i2:Integer; +begin + Result:=TPostCollection.Create(nil); + FXMLDoc.Clear; + if FAuth<>'' then + begin//'http://www.blogger.com/feeds/9144819905011498730/posts/default' + if FCurrentBlog>-1 then + FXMLDoc.ReadFromString(GetUrl(cnsPostBlogStart+Blogs.Items[FCurrentBlog].FBlogId+cnsPostBlogEnd,'','get',FAuth,'')) + else + ToError(rsErrorNotSelectBlog); + end + else + ToError(rsErrorNotTolken); + + Nodes:=TXmlNodeList.Create; + FXMLDoc.Root.FindNodes(cnsEntry,Nodes); + for i := 0 to Nodes.Count-1 do + begin + Result.Add; + Result.Items[i].PostId:=GetPostId(Nodes.Items[i].NodeByName(cnsId).ValueAsString); + Result.Items[i].PostTitle:=Nodes.Items[i].NodeByName(cnsTitle).ValueAsString; + Result.Items[i].PostSourse.Add(Nodes.Items[i].NodeByName(cnsContent).ValueAsString); + Result.Items[i].PostPublished:=Nodes.Items[i].NodeByName(cnsPublished).ValueAsDateTime; + Result.Items[i].PostUpdate:=Nodes.Items[i].NodeByName(cnsUpdated).ValueAsDateTime; + NodesChild:=TXmlNodeList.Create; + Nodes.Items[i].FindNodes(cnsCategory,NodesChild); + for i2 := 0 to NodesChild.Count - 1 do + begin + Result.Items[i].СategoryPost.Add(NodesChild.Items[i2].AttributeByName[cntTerm]); + end; + end; +end; + +{------------------------------------------------------------------------------- + Функция: TBlogger.RetrievPostForTextParams + Автор: NMD + Дата: 2010.08.10 21:09:02 + Входные параметры: + Parametrs параметры запроса постов из блога + Что делает: Возвращает посты из блога по заданным параметрам созданым в ручную + Результат: Список постов в коллекции TPostCollection + Необходимо забивать только параметры после знака вопроса + http://www.blogger.com/feeds/9144819905011498730/posts/default?category=Application + то есть category=Application +-------------------------------------------------------------------------------} +function TBlogger.RetrievPostForTextParams(Parametrs:string): TPostCollection; +var + Nodes,NodesChild: TXmlNodeList; + i,i2:Integer; +begin + Result:=TPostCollection.Create(nil); + FXMLDoc.Clear; + if FAuth<>'' then + begin + if FCurrentBlog>-1 then + FXMLDoc.ReadFromString(GetUrl(cnsPostBlogStart+Blogs.Items[FCurrentBlog].FBlogId+cnsPostBlogEnd+parametrs,'','get',FAuth,'')) + else + ToError(rsErrorNotSelectBlog); + end + else + ToError(rsErrorNotTolken); + + Nodes:=TXmlNodeList.Create; + FXMLDoc.Root.FindNodes(cnsEntry,Nodes); + for i := 0 to Nodes.Count-1 do + begin + Result.Add; + Result.Items[i].PostId:=GetPostId(Nodes.Items[i].NodeByName(cnsId).ValueAsString); + Result.Items[i].PostTitle:=Nodes.Items[i].NodeByName(cnsTitle).ValueAsString; + Result.Items[i].PostSourse.Add(Nodes.Items[i].NodeByName(cnsContent).ValueAsString); + Result.Items[i].PostPublished:=Nodes.Items[i].NodeByName(cnsPublished).ValueAsDateTime; + Result.Items[i].PostUpdate:=Nodes.Items[i].NodeByName(cnsUpdated).ValueAsDateTime; + NodesChild:=TXmlNodeList.Create; + Nodes.Items[i].FindNodes(cnsCategory,NodesChild); + for i2 := 0 to NodesChild.Count - 1 do + begin + Result.Items[i].СategoryPost.Add(NodesChild.Items[i2].AttributeByName[cntTerm]); + end; + end; +end; + +{------------------------------------------------------------------------------- + Функция: TBlogger.RetrievPostForParams + Автор: NMD + Дата: 2010.08.10 19:39:25 + Входные параметры: + aAlt atom(default),rss + aCategory Посты определенной категории + aOrderby Задаем порядок постов в котором мы их получим в список постов lastmodified (the default), starttime, or updated. + aPublishedMin Ограничение на дату публикации. Игнорируется если orderby установлен в updated + APublishedMax Ограничение на дату публикации. Игнорируется если orderby установлен в updated + aUpdatedMin Ограничение на дату публикации. Игнорируется если orderby установлен в updated + aUpdatedMax Ограничение на дату публикации. Игнорируется если orderby установлен в updated + aStartIndex Индекс поста который будет получен первым (для докачки постов) + aMaxResults Максимальное кол-во возвращаемых постов + Что делает: Возвращает посты из блога по заданным параметрам + Результат: Список постов в коллекции TPostCollection + Пример + http://www.blogger.com/feeds/9144819905011498730/posts/default?category=Application&max-results=10&start-index=1&published-min=2008-03-16T00:00:00&published-max=2011-03-24T23:59:59 +-------------------------------------------------------------------------------} +function TBlogger.RetrievPostForParams(aCategory:string =''; aOrderby:string =''; aPublishedMin:string =''; + aPublishedMax:string =''; aUpdatedMin:string ='';aUpdatedMax:string =''; + aStartIndex:Integer=0; aMaxResults:Integer=0; aAlt : string =''): TPostCollection; +var + i:Integer; + temp:TStringList; + parametrs:string; +begin + Result:=TPostCollection.Create(nil); + if FAuth='' then + begin + ToError(rsErrorNotTolken); + Exit; + end; + if FCurrentBlog<0 then + begin + ToError(rsErrorNotSelectBlog); + Exit; + end; + parametrs:=''; + temp:=TStringList.Create; + if aAlt<>'' then + temp.Add('alt='+aAlt); + if aCategory<>'' then + temp.Add('category='+aCategory); + if aOrderby<>'' then + temp.Add('orderby='+aOrderby); + if aPublishedMin<>'' then + temp.Add('published-min='+aPublishedMin); + if APublishedMax<>'' then + temp.Add('published-max='+aPublishedMax); + if aUpdatedMin<>'' then + temp.Add('updated-min='+aUpdatedMin); + if aUpdatedMax<>'' then + temp.Add('updated-max='+aUpdatedMax); + if aStartIndex<>0 then + temp.Add('start-index='+IntToStr(aStartIndex)); + if aMaxResults<>0 then + temp.Add('max-results='+IntToStr(aMaxResults)); + for I := 0 to temp.Count - 1 do + begin + if i>0 then + parametrs:=parametrs+'&'+temp.Strings[i] + else + parametrs:=parametrs+temp.Strings[i]; + end; + temp.Free; + Result:=RetrievPostForTextParams(cnsVop+parametrs); +end; + +{------------------------------------------------------------------------------- + Процедура: TBlogger.CreatPost формируем xml будущего сообщения и отправляем его в блог + Автор: NMD + Дата: 2010.08.06 18:37:01 + Входные параметры: + aTitle- заголовок, + aContent-текст сообщения: string; + aCategory-ярлыки сообщения: TStringList; + aComment: Boolean комментарий или нет + Результат: string получаем xml отправленной статьи но уже из блогга или текст ошибки +-------------------------------------------------------------------------------} +function TBlogger.PostCreat(aTitle, aContent: string; aCategory: TStringList; aComment: Boolean):UTF8String; +var + i:Integer; + Node,Node2:TXmlNode; + tempXML :TNativeXml; +begin + Result:=''; + if FAuth='' then + begin + ToError(rsErrorNotTolken); + Exit; + end; + if FCurrentBlog<0 then + begin + ToError(rsErrorNotSelectBlog); + Exit; + end; + + FXMLDoc.Clear; + FXMLDoc.Root.CreateName(FXMLDoc,cnsEntry).AttributeAdd(cnsXmlns,cnsAtomUrl); + { + yes + } + if aComment then + begin + Node:=FXMLDoc.Root.NodeNew(cnsAppControll); + Node.AttributeAdd(cnsXmlnsApp,cnsXmlnsAppUrl); + Node2:=TXmlNode.CreateNameValue(FXMLDoc,cnsAppDraft,cnsYes); + Node.NodeAdd(Node2); + end; + + //Marriage! + with FXMLDoc.Root.NodeNew(cnsTitle)do + begin + AttributeAdd(cnsType,cnsText); + ValueAsString:=aTitle; + end; + // + Node:=FXMLDoc.Root.NodeNew(cnsContent); + Node.AttributeAdd(cnsType,cnsXhtml); + //сам контент единственное он должен быть валидным html + tempXML:=TNativeXml.Create; + try + tempXML.ReadFromString(aContent); + except + ToError(rsErrorXmlTag); + tempXML:=nil; + Exit;//выход + end; + for I := 0 to tempXML.RootNodeList.NodeCount - 1 do + begin + node2:=tempXML.RootNodeList.Nodes[i]; + node.NodeAdd(node2); + end; +{ //
+ Node2:=TXmlNode.CreateName(FXMLDoc,cnsDiv); + Node2.AttributeAdd(cnsXmlns,cnsXhtmlUrl); + Node.NodeAdd(Node2); + Node:=TXmlNode.CreateName(FXMLDoc,'p'); + Node.ValueAsString:=aContent; + Node2.NodeAdd(Node); +} + // + for i := 0 to aCategory.Count - 1 do + with FXMLDoc.Root.NodeNew(cnsCategory) do + begin + AttributeAdd(cnsScheme,cnsAtnsUrl); + AttributeAdd(cnsTerm,sdAnsiToUtf8(aCategory.Strings[i])); + end; + Result:=GetUrl(cnsPostBlogStart+Blogs.Items[FCurrentBlog].FBlogId+cnsPostBlogEnd,'','post',FAuth,FXMLDoc.WriteToString); + tempXML:=nil; +end; + +{------------------------------------------------------------------------------- + Функция: TBlogger.PostModify + Автор: NMD + Дата: 2010.08.10 21:28:47 + Входные параметры: + id сообщения, остальное анологично созданию поста + Что делает: Производит обновление поста в блоге + Результат: xml модифицированного сообщения +-------------------------------------------------------------------------------} +function TBlogger.PostModify(id, aTitle, aContent: string; aCategory: TStringList; aComment: Boolean): UTF8String; +var + i:Integer; + Node,Node2:TXmlNode; + blogId:string; +begin + Result:=''; + if FAuth='' then + begin + ToError(rsErrorNotTolken); + Exit; + end; + if FCurrentBlog<0 then + begin + ToError(rsErrorNotSelectBlog); + Exit; + end; + FXMLDoc.Clear; + FXMLDoc.Root.CreateName(FXMLDoc,cnsEntry).AttributeAdd(cnsXmlns,cnsAtomUrl); + + { + yes + } + if aComment then + begin + Node:=FXMLDoc.Root.NodeNew(cnsAppControll); + Node.AttributeAdd(cnsXmlnsApp,cnsXmlnsAppUrl); + Node2:=TXmlNode.CreateNameValue(FXMLDoc,cnsAppDraft,cnsYes); + Node.NodeAdd(Node2); + end; + // tag:blogger.com,1999:blog-blogID.post-postID + blogId:=IntToStr(FBlogs.Items[FCurrentBlog].id);//id блога + FXMLDoc.Root.NodeNew(cnsId).ValueAsString:='tag:blogger.com,1999:blog-'+blogId+'.post-'+id; + //Marriage! + with FXMLDoc.Root.NodeNew(cnsTitle)do + begin + AttributeAdd(cnsType,cnsText); + ValueAsString:=aTitle; + end; + // + Node:=FXMLDoc.Root.NodeNew(cnsContent); + Node.AttributeAdd(cnsType,cnsXhtml); + //
+ Node2:=TXmlNode.CreateName(FXMLDoc,cnsDiv); + Node2.AttributeAdd(cnsXmlns,cnsXhtmlUrl); + Node.NodeAdd(Node2); + Node:=TXmlNode.CreateName(FXMLDoc,'p'); + Node.ValueAsString:=aContent; + Node2.NodeAdd(Node); + + // + for i := 0 to aCategory.Count - 1 do + with FXMLDoc.Root.NodeNew(cnsCategory) do + begin + AttributeAdd(cnsScheme,cnsAtnsUrl); + AttributeAdd(cnsTerm,sdAnsiToUtf8(aCategory.Strings[i])); + end; + //'http://www.blogger.com/feeds/1897581382578917834/posts/default/5129237316807356045', + Result:=GetUrl(cnsPostBlogStart+Blogs.Items[FCurrentBlog].FBlogId+cnsPostBlogEnd+'/'+id,'','put',FAuth,FXMLDoc.WriteToString); +end; + +{------------------------------------------------------------------------------- + Функция: TBlogger.PostDelete + Автор: NMD + Дата: 2010.08.11 19:24:17 + Входные параметры: + id сообщения которое необходимо удалить + Что делает: удаление поста из блога + Результат: Boolean +-------------------------------------------------------------------------------} +function TBlogger.PostDelete(id: string): Boolean; +begin + if FAuth='' then + begin + ToError(rsErrorNotTolken); + Exit; + end; + if FCurrentBlog<0 then + begin + ToError(rsErrorNotSelectBlog); + Exit; + end; + if id='' then + begin + ToError(rsErrorIdPost); + Exit; + end; + if GetUrl(cnsPostBlogStart+Blogs.Items[FCurrentBlog].FBlogId+cnsPostBlogEnd+'/'+id,'','DELETE',FAuth,'')='1' then + Result:=True + else + Result:=False; +end; + + +procedure TBlogger.SetAppName(const Value: string); +begin + if Value<>'' then + FAppName := Value; +end; + +procedure TBlogger.SetAuth(const Value: string); +begin + if Value<>'' then + begin + FAuth := Value; + end; +end; + +procedure TBlogger.SetBlog(const Value: TBlogCollection); +begin + FBlogs.Assign(Value); +end; + +procedure TBlogger.SetCurrentBlog(const Value: Integer); +begin + FCurrentBlog := Value; +end; + +{BlogCollection} +function TBlogCollection.Add: TBlogItem; +begin + result := TBlogItem(inherited Add); +end; + +function TBlogCollection.AddEx(aName, aTitle,aBlogId: string; aUrl: string; aСategoryBlog: TStringList; aPublished, + aUpdate: TDateTime): TBlogItem; +begin + result := inherited Add as TBlogItem; + Result.FTitle:=aTitle; + Result.FBlogId:=aBlogId; + Result.FСategoryBlog.Assign(aСategoryBlog); + Result.FPublished:=aPublished; + Result.FUpdate:=aUpdate; +end; + +constructor TBlogCollection.Create(AOwner: TComponent); +begin + inherited Create(TBlogItem); +end; + +function TBlogCollection.GetItemBlog(Index: Integer): TBlogItem; +begin + result := TBlogItem(inherited GetItem(Index)); +end; + +procedure TBlogCollection.SetItemBlog(Index: Integer; Value: TBlogItem); +begin + inherited SetItem(Index, Value) +end; + +constructor TBlogItem.Create(Collection: TCollection); +begin + inherited; + FTitle:=''; + FBlogId:=''; + FСategoryBlog:=TStringList.Create;//ярлыки блога + FPublished:=Time;//дата последеней публикации + FUpdate:=Time;//дата последнего обновления +end; + +destructor TBlogItem.Destroy; +begin + FСategoryBlog.Destroy; + inherited; +end; + +procedure TBlogItem.SetCategory(const Value: TStringList); +begin + FСategoryBlog.Assign(Value); +end; + +procedure TBlogItem.SetBlogId(const Value: string); +begin + FBlogId := Value; +end; + +procedure TBlogItem.SetPublished(const Value: TDateTime); +begin + FPublished := Value; +end; + +procedure TBlogItem.SetTitle(const Value: string); +begin + FTitle := Value; +end; + +procedure TBlogItem.SetUpdate(const Value: TDateTime); +begin + FUpdate := Value; +end; + +{ TPostItem } + +constructor TPostItem.Create(Collection: TCollection); +begin + inherited; + FPostSourse:=TStringList.Create; + FСategoryPost:=TStringList.Create; +end; + +destructor TPostItem.Destroy; +begin + FPostSourse.Free; + FСategoryPost.Free; + inherited; +end; + +procedure TPostItem.SetPostId(const Value: string); +begin + FPostId := Value; +end; + +procedure TPostItem.SetPostPublished(const Value: TDateTime); +begin + FPostPublished := Value; +end; + +procedure TPostItem.SetPostSourse(const Value: TStringList); +begin + FPostSourse.Assign(Value); +end; + +procedure TPostItem.SetPostTitle(const Value: string); +begin + FPostTitle := Value; +end; + +procedure TPostItem.SetPostUpdate(const Value: TDateTime); +begin + FPostUpdate:=Value; +end; + +procedure TPostItem.SetСategoryPost(const Value: TStringList); +begin + FСategoryPost.Assign(Value); +end; + +{ TPostCollection } + +function TPostCollection.Add: TPostItem; +begin + result := TPostItem(inherited Add); +end; + +function TPostCollection.AddEx(aPostTitle, aPostId: string; aPostSourse: TStringList; aPostPublished, + aPostUpdate: TDateTime): TPostItem; +begin + result := inherited Add as TPostItem; + Result.FPostTitle:=aPostTitle; + Result.FPostId:=aPostId; + Result.FPostSourse.Assign(aPostSourse); + Result.FPostPublished:=aPostPublished; + Result.FPostUpdate:=aPostUpdate; +end; + +constructor TPostCollection.Create(AOwner: TComponent); +begin + inherited Create(TPostItem); +end; + +function TPostCollection.GetItemBlog(Index: Integer): TPostItem; +begin + result := TPostItem(inherited GetItem(Index)); +end; + +procedure TPostCollection.SetItemBlog(Index: Integer; Value: TPostItem); +begin + inherited SetItem(Index, Value); +end; + +procedure Register; +begin + RegisterComponents('WebDelphi.ru', [TBlogger]); +end; + +end. + diff --git a/packages/BloggerApi_Pack.res b/packages/BloggerApi_Pack.res new file mode 100644 index 0000000000000000000000000000000000000000..654f9b6ede15a4816b3ba0097e14e6ad8d5044ac GIT binary patch literal 6336 zcmeHLJ#Q015PfG{fE1905F(w0C?bTABitZGLVN`wg#_U!1x>IZF%gO57*jxrghYk- z1^EFqNQjn{lyo!{6wrr`^2~d?zO%hPJ9oB^>c$@5?dueBw*YcaB4H%=a^A_WY}4$%lcC z48f-{Df1zCNEFL=rkgn*{P3F}{G_xy;92wkFp%mJG}R@v1%G=Y*moS`-oi86gF<08 zAM6vfkI?Qxdk@d-D1b*ClS#%v#z4kE#y~0zoFwX5s;<)%VeV1CQ+d*4u4>CZsR-jE z^$qnRRc&3>mVMF~%2Qa!slB4M?CPIH#EJ5a64}*1$$W_KVI0Uls-N9QO4|9S&A&KE z^Z5~hilI8D{`_+_#r0EqdWK2c^WRgrhwHeDW$I0y0xz@2O7FT&t2Lhcb`E~E%JZ<0 zL+6aS5V_V{$dw7Sh6>jCtCQslV<^J9iMPmm$(Q^eUwBq!vFpZbx}|9GXf38`em)yR z1uZnOg*s|jgynK@jcy-4*~>n?WCK$ZS4nNyXm4fX(9 zqk19UEn1)Bv5C`Qye*Ea8^01?9bLaQ`ZejU~a0ghNm1AT{v u&Q?!GAZMzvzu&FYty2$4z^|gHUS)NOs^>v@2AOnc3z#u84b0|$=l=l!|55P( literal 0 HcmV?d00001 diff --git a/sourse/BloggerApi.pas b/sourse/BloggerApi.pas new file mode 100644 index 0000000..18b924f --- /dev/null +++ b/sourse/BloggerApi.pas @@ -0,0 +1,967 @@ +{*******************************************************} +{ } +{ BloggerApi } +{ } +{ Copyright (C) 2010 NMD } +{ http://nmdsoft.blogspot.com/ } +{*******************************************************} + + +unit BloggerApi; + +interface + +uses + SysUtils, Classes,NativeXml,WinInet; + +//ошибки +resourcestring +rsErrorXmlTag='Нет закрывающего тега. HTHL должен быть валидным'; +rsErrorNotTolken='Нет толкена google для работы с сервисом'; +rsErrorNotSelectBlog='Блог не выбран! Смотри property CurrentBlog'; +rsErrorIdPost='Не указан Id сообщения в блоге'; + +rsErrorGet='Произошла сетевая ошибка при получении данных c сервера'; +rsErrorDelete='Произошла сетевая ошибка при выполнении запроса Delete'; +rsErrorPost='Произошла сетевая ошибка при отправке данных на сервер'; +rsErrorPut='Произошла сетевая ошибка при обновлении данных на сервер'; +const + cnsBlogDefault='http://www.blogger.com/feeds/default/blogs'; + cnsEntry='entry'; + cnsName='name'; + cnsId='id'; + cnsPublished='published'; + cnsUpdated='updated'; + cnsTitle='title'; + cnsCategory='category'; + cntTerm='term'; + cnsXhtml='xhtml'; + cnsXmlns='xmlns'; + cnsType='type'; + cnsText='text'; + cnsContent='content'; + cnsScheme='scheme'; + cnsTerm='term'; + cnsDiv='div'; + cnsAtomUrl='http://www.w3.org/2005/Atom'; + cnsXhtmlUrl='http://www.w3.org/1999/xhtml'; + cnsAtnsUrl='http://www.blogger.com/atom/ns#'; + //http://www.blogger.com/feeds/blogID/posts/default + cnsPostBlogStart='http://www.blogger.com/feeds/'; + cnsPostBlogEnd='/posts/default'; + cnsAppControll='app:control'; + cnsXmlnsApp='xmlns:app'; + cnsXmlnsAppUrl='http://www.w3.org/2007/app'; + cnsAppDraft='app:draft'; + cnsYes='yes'; + cnsVop='/?'; +// cnsPostIdUrl='http://www.blogger.com/feeds/blogID/posts/default/postID'; + +type + //событие для ошибки + TErrorEvent = procedure(aE: string) of object; + //Прогресс выполнения задания + TProgressEvent = procedure(aCurrentProgress,aMaxProgress: Integer) of object; + + TPostItem = class (TCollectionItem) + private + FPostTitle: string; + FPostId: string; + FPostSourse: TStringList; + FСategoryPost:TStringList; + FPostPublished: TDateTime; + FPostUpdate: TDateTime; + procedure SetPostId(const Value: string); + procedure SetPostPublished(const Value: TDateTime); + procedure SetPostSourse(const Value: TStringList); + procedure SetPostTitle(const Value: string); + procedure SetPostUpdate(const Value: TDateTime); + procedure SetСategoryPost(const Value: TStringList); + public + constructor Create(Collection: TCollection);override; + destructor Destroy; override; + published + property PostId:string read FPostId write SetPostId; + property PostTitle:string read FPostTitle write SetPostTitle; + property PostSourse:TStringList read FPostSourse write SetPostSourse; + property СategoryPost:TStringList read FСategoryPost write SetСategoryPost; + property PostPublished:TDateTime read FPostPublished write SetPostPublished; + property PostUpdate:TDateTime read FPostUpdate write SetPostUpdate; + end; + + TPostCollection = class (TCollection) + private + function GetItemBlog(Index: Integer): TPostItem; + procedure SetItemBlog(Index: Integer; Value: TPostItem); + public + constructor Create(AOwner:TComponent); + function Add: TPostItem; + property Items[Index: Integer]: TPostItem read GetItemBlog write SetItemBlog; + function AddEx(aPostTitle,aPostId:string; aPostSourse:TStringList;aPostPublished,aPostUpdate:TDateTime): TPostItem; + end; + + + TBlogItem = class (TCollectionItem) + private + FTitle:string;//заголовок + FBlogId:string;//id блога + FСategoryBlog:TStringList;//ярлыки блога + FPublished:TDateTime;//дата последеней публикации + FUpdate:TDateTime;//дата последнего обновления + procedure SetCategory(const Value: TStringList); + procedure SetPublished(const Value: TDateTime); + procedure SetUpdate(const Value: TDateTime); + procedure SetBlogId(const Value: string); + procedure SetTitle(const Value: string); + + public + constructor Create(Collection: TCollection);override; + destructor Destroy; override; + published + property Title:string read FTitle write SetTitle; + property BlogId:string read FBlogId write SetBlogId; + property СategoryBlog:TStringList read FСategoryBlog write SetCategory; + property Publish:TDateTime read FPublished write SetPublished; + property Update:TDateTime read FUpdate write SetUpdate; + end; + + TBlogCollection = class (TCollection) + private + function GetItemBlog(Index: Integer): TBlogItem; + procedure SetItemBlog(Index: Integer; Value: TBlogItem); + public + constructor Create(AOwner:TComponent); + function Add: TBlogItem; + property Items[Index: Integer]: TBlogItem read GetItemBlog write SetItemBlog; + function AddEx(aName,aTitle,aBlogId: string;aUrl:string;aСategoryBlog:TStringList;aPublished,aUpdate:TDateTime): TBlogItem; + end; + +//класс для работы с блогами на Blogger'e +type + TBlogger = class(TComponent) + private + //для работы с xml + FXMLDoc:TNativeXml; + FAuth:string; + FUrl:string;//ссылка на профиль владельца блога + FAppName:string;//название приложения + FBlogs:TBlogCollection; + FCurrentBlog: Integer;//блог с которым будем непосредственно работать + //для событий + FProgress:TProgressEvent; + FErrorEvent: TErrorEvent;//ошибка + + //вспомогательные для работы с инетом + function GetUrl(url, param, method: string; AUTH:AnsiString;postData: UTF8String): UTF8String; + function DataAvailable(hRequest: pointer; out Size: cardinal): boolean; + function GetScriptName(url, hostname: string): string; + procedure SetFlags(url: string; out Flags_connection, Flags_Request: Cardinal); + function GetHostName(url: string): string; + + function GetIdBlog(aSourse:string):string;//получение id блога + function GetPostId(aSourse:string):string;//получение id поста + procedure RetrievAllBlogs;//получение списка блогов пользователя + + procedure ToError(aError:string);//обработка ошибок + //для пропертей + procedure SetAppName(const Value: string); + procedure SetAuth(const Value: string); + procedure SetBlog(const Value: TBlogCollection); + procedure SetCurrentBlog(const Value: Integer); + + protected + public + function PostCreat(aTitle,aContent:string; aCategory:TStringList;aComment:Boolean):UTF8String;//создание сообщения и отправка в блог + function PostModify(id,aTitle,aContent:string; aCategory:TStringList;aComment:Boolean):UTF8String;//Изменение сообщения и отправка его в блог + function PostDelete(id:string):Boolean;//удаление поста из блога + + function RetrievAllPosts:TPostCollection;//получаем последние 25 постов из блога + //получение статей по заданным параметрам + function RetrievPostForParams(aCategory:string =''; aOrderby:string =''; aPublishedMin:string =''; + aPublishedMax:string =''; aUpdatedMin:string ='';aUpdatedMax:string =''; + aStartIndex:Integer=0; aMaxResults:Integer=0; aAlt : string =''):TPostCollection; + //Возвращает посты из блога по заданным параметрам созданым в ручную + function RetrievPostForTextParams(Parametrs:string):TPostCollection; + constructor Create(AOwner: TComponent);override;//инициализация класса + destructor Destroy; override;//уничтожение + published + property Auth:string read FAuth write SetAuth; + property AppName:string read FAppName write SetAppName; + property CurrentBlog:Integer read FCurrentBlog write SetCurrentBlog default -1; + property Url: string read FUrl; + property Blogs:TBlogCollection read FBlogs write SetBlog; + + //события + property OnProgress:TProgressEvent read FProgress write FProgress;//прогресс выполнения задачи + property OnError:TErrorEvent read FErrorEvent write FErrorEvent;//возникает при ошибке ) + + end; + +procedure Register; + +implementation + +constructor TBlogger.Create(AOwner: TComponent); +begin + inherited; + FBlogs:=TBlogCollection.Create(Self); + FXMLDoc:=TNativeXml.Create; + FAuth:=''; + FAppName:='MyCompany'; + FCurrentBlog:=-1; +end; + +destructor TBlogger.Destroy; +begin + FreeAndNil(FXMLDoc); + FBlogs.Free; + inherited; +end; + +function TBlogger.GetHostName(url : string) : string; +begin + result := ''; + if pos('https://',url) > 0 then + begin + delete(url,1,length('https://')); + SetLength(url,pos('/',url) - 1); + result := url; + end + else + if pos('http://',url) > 0 then + begin + delete(url,1,length('http://')); + SetLength(url,pos('/',url) - 1); + result := url; + end; +end; + +{------------------------------------------------------------------------------- + Функция: TBlogger.GetIdBlog + Автор: NMD + Дата: 2010.08.08 + Входные параметры: aSourse: string строка содержащая id блога + Результат: id блога string +-------------------------------------------------------------------------------} +function TBlogger.GetIdBlog(aSourse: string): string; +var + i:Integer; +begin + Result:=''; + i:=AnsiPos('.blog-',aSourse); + Delete(aSourse,1,i+5); + Result:=aSourse; +end; + +function TBlogger.GetPostId(aSourse: string): string; +var + i:Integer; +begin + Result:=''; + i:=AnsiPos('.post-',aSourse); + Delete(aSourse,1,i+5); + Result:=aSourse; +end; + +function TBlogger.GetScriptName( url,hostname : string) : string; +begin + result := ''; + delete(url,1,pos(hostname,url) + length(hostname)); + result := url; +end; + +procedure TBlogger.SetFlags(url : string; out Flags_connection,Flags_Request : Cardinal); +begin + //Оприделяем на https или http + if pos('https',url) > 0 then + begin + Flags_connection := INTERNET_DEFAULT_HTTPS_PORT; + Flags_Request := INTERNET_FLAG_RELOAD or INTERNET_FLAG_IGNORE_CERT_CN_INVALID or INTERNET_FLAG_NO_CACHE_WRITE or INTERNET_FLAG_SECURE or INTERNET_FLAG_PRAGMA_NOCACHE or INTERNET_FLAG_KEEP_CONNECTION; + end + else + begin + Flags_connection := INTERNET_DEFAULT_HTTP_PORT; + Flags_Request := INTERNET_FLAG_RELOAD or INTERNET_FLAG_IGNORE_CERT_CN_INVALID or INTERNET_FLAG_NO_CACHE_WRITE or INTERNET_FLAG_PRAGMA_NOCACHE or INTERNET_FLAG_KEEP_CONNECTION; + end; +end; + +//обработка ошибок +procedure TBlogger.ToError(aError: string); +begin + if Assigned(FErrorEvent) then + OnError(aError); +end; + +function TBlogger.DataAvailable(hRequest: pointer; out Size : cardinal): boolean; +begin + result := wininet.InternetQueryDataAvailable(hRequest, Size, 0, 0); +end; + +function TBlogger.GetUrl(url : string; param: string; method : string; AUTH:AnsiString; postData:UTF8String) :UTF8String;//Получение страницы по url +var + FHost,FScript : string; + hInternet,hConnect,hRequest : Pointer; + dwBytesRead,I,L : Cardinal; + Flags_connection,Flags_Request : Cardinal; + Flag_HttpSendRequest:LongBool; + header:TStringStream; +begin + result := ''; + fHost := GetHostName(url); + fScript := GetScriptName(url,fHost); + if Param <> '' then + if fScript[Length(fScript)] = '?' then + fScript := fScript + param + else + fScript := fScript + '?' + param; + //Устанавливаем флаги + SetFlags(url,Flags_connection,Flags_Request); + //Инициализируем WinInet + hInternet := InternetOpen(PChar(FAppName),INTERNET_OPEN_TYPE_PRECONFIG,Nil,Nil,0); + if Assigned(hInternet) then + begin + //Открываем сессию + hConnect := InternetConnect(hInternet,PChar(FHost),Flags_connection,nil,nil,INTERNET_SERVICE_HTTP,0,1); + if Assigned(hConnect) then + begin + //Формируем запрос + hRequest := HttpOpenRequest(hConnect,PChar(uppercase(method)),PChar(fScript),HTTP_VERSION,nil,Nil,Flags_Request,1); + if Assigned(hRequest) then + begin + header:=TStringStream.Create; + with Header do + begin + WriteString('Content-Type:application/atom+xml'+SLineBreak); + WriteString('GData-Version:2 '+SLineBreak); + WriteString('Authorization: GoogleLogin auth='+AUTH+SLineBreak+SLineBreak); + end; + //Отправляем запрос + I := 1; + if uppercase(method)='GET' then + begin + Flag_HttpSendRequest:=HttpSendRequest(hRequest,PChar(header.DataString),Length(header.DataString),nil,0); + if not Flag_HttpSendRequest then + ToError(rsErrorGet); + end; + if uppercase(method)='POST' then + begin + Flag_HttpSendRequest:=HttpSendRequest(hRequest,PChar(header.DataString),Length(header.DataString),Pointer(postData),Length(postData)); + if not Flag_HttpSendRequest then + ToError(rsErrorPost); + end; + if uppercase(method)='PUT' then + begin + Flag_HttpSendRequest:=HttpSendRequest(hRequest,PChar(header.DataString),Length(header.DataString),Pointer(postData),Length(postData)); + if not Flag_HttpSendRequest then + ToError(rsErrorPut); + end; + if uppercase(method)='DELETE' then + begin + Flag_HttpSendRequest:=HttpSendRequest(hRequest,PChar(header.DataString),Length(header.DataString),nil,0); + if not Flag_HttpSendRequest then + begin + OnError(rsErrorDelete); + Result:='0' + end + else + begin + Result:='1'; + end; + end; + if Flag_HttpSendRequest and (uppercase(method)<>'DELETE') then + begin + repeat + DataAvailable(hRequest, L);//Получаем кол-во принимаемых данных + if L = 0 then break; + SetLength(result,L + I); + if not (InternetReadFile(hRequest,@result[I],sizeof(L),dwBytesRead)) then //Получаем данные с сервера + begin + OnError(rsErrorGet); + end; + if Assigned(FProgress) then //прогресс + OnProgress(i,L+1); + inc(I,dwBytesRead); + until dwBytesRead = 0; + result[I] := #0; + end; + end; + InternetCloseHandle(hRequest); + end; + InternetCloseHandle(hConnect); + end; + InternetCloseHandle(hInternet); + header.Free; +end; + +{------------------------------------------------------------------------------- + Процедура: TBlogger.RetrievAllBlogs + Автор: NMD + Дата: 2010.08.03 21:13:59 + Входные параметры: Нет + Результат: получение списка блогов пользователя +-------------------------------------------------------------------------------} +procedure TBlogger.RetrievAllBlogs; +var + i,i2:Integer; + Nodes,NodesChild: TXmlNodeList; +begin + FBlogs.Clear;//очистка блогов перед получением нового списка + FXMLDoc.Clear; + FXMLDoc.ReadFromString(GetUrl(cnsBlogDefault,'','get',FAuth,'')); + //проверка на существование коллекции + if not Assigned(FBlogs) then Exit; + try + Nodes:=TXmlNodeList.Create; + FXMLDoc.Root.FindNodes('entry',Nodes); + for i := 0 to Nodes.Count-1 do + begin + FBlogs.Add; + FBlogs.Items[i].BlogId:=GetIdBlog(Nodes.Items[i].NodeByName(cnsId).ValueAsString); + FBlogs.Items[i].Publish:=Nodes.Items[i].NodeByName(cnsPublished).ValueAsDateTime; + FBlogs.Items[i].Update:=Nodes.Items[i].NodeByName(cnsUpdated).ValueAsDateTime; + FBlogs.Items[i].Title:=Nodes.Items[i].NodeByName(cnsTitle).ValueAsString; + NodesChild:=TXmlNodeList.Create; + Nodes.Items[i].FindNodes(cnsCategory,NodesChild); + for i2 := 0 to NodesChild.Count - 1 do + begin + FBlogs.Items[i].СategoryBlog.Add(NodesChild.Items[i2].AttributeByName[cntTerm]); + end; + end; + finally + FreeAndNil(Nodes); + FreeAndNil(NodesChild); + end; +end; + +{------------------------------------------------------------------------------- + Функция: TBlogger.RetrievAllPosts + Автор: NMD + Дата: 2010.08.09 + Входные параметры: Нет + Что делает: получает последние 25 сообщений из блога + Результат: Коллекция TPostCollection содержащая исчерпывающую информацию о сообщении и само сообщение +-------------------------------------------------------------------------------} +function TBlogger.RetrievAllPosts: TPostCollection; +var + Nodes,NodesChild: TXmlNodeList; + i,i2:Integer; +begin + Result:=TPostCollection.Create(nil); + FXMLDoc.Clear; + if FAuth<>'' then + begin//'http://www.blogger.com/feeds/9144819905011498730/posts/default' + if FCurrentBlog>-1 then + FXMLDoc.ReadFromString(GetUrl(cnsPostBlogStart+Blogs.Items[FCurrentBlog].FBlogId+cnsPostBlogEnd,'','get',FAuth,'')) + else + ToError(rsErrorNotSelectBlog); + end + else + ToError(rsErrorNotTolken); + + Nodes:=TXmlNodeList.Create; + FXMLDoc.Root.FindNodes(cnsEntry,Nodes); + for i := 0 to Nodes.Count-1 do + begin + Result.Add; + Result.Items[i].PostId:=GetPostId(Nodes.Items[i].NodeByName(cnsId).ValueAsString); + Result.Items[i].PostTitle:=Nodes.Items[i].NodeByName(cnsTitle).ValueAsString; + Result.Items[i].PostSourse.Add(Nodes.Items[i].NodeByName(cnsContent).ValueAsString); + Result.Items[i].PostPublished:=Nodes.Items[i].NodeByName(cnsPublished).ValueAsDateTime; + Result.Items[i].PostUpdate:=Nodes.Items[i].NodeByName(cnsUpdated).ValueAsDateTime; + NodesChild:=TXmlNodeList.Create; + Nodes.Items[i].FindNodes(cnsCategory,NodesChild); + for i2 := 0 to NodesChild.Count - 1 do + begin + Result.Items[i].СategoryPost.Add(NodesChild.Items[i2].AttributeByName[cntTerm]); + end; + end; +end; + +{------------------------------------------------------------------------------- + Функция: TBlogger.RetrievPostForTextParams + Автор: NMD + Дата: 2010.08.10 21:09:02 + Входные параметры: + Parametrs параметры запроса постов из блога + Что делает: Возвращает посты из блога по заданным параметрам созданым в ручную + Результат: Список постов в коллекции TPostCollection + Необходимо забивать только параметры после знака вопроса + http://www.blogger.com/feeds/9144819905011498730/posts/default?category=Application + то есть category=Application +-------------------------------------------------------------------------------} +function TBlogger.RetrievPostForTextParams(Parametrs:string): TPostCollection; +var + Nodes,NodesChild: TXmlNodeList; + i,i2:Integer; +begin + Result:=TPostCollection.Create(nil); + FXMLDoc.Clear; + if FAuth<>'' then + begin + if FCurrentBlog>-1 then + FXMLDoc.ReadFromString(GetUrl(cnsPostBlogStart+Blogs.Items[FCurrentBlog].FBlogId+cnsPostBlogEnd+parametrs,'','get',FAuth,'')) + else + ToError(rsErrorNotSelectBlog); + end + else + ToError(rsErrorNotTolken); + + Nodes:=TXmlNodeList.Create; + FXMLDoc.Root.FindNodes(cnsEntry,Nodes); + for i := 0 to Nodes.Count-1 do + begin + Result.Add; + Result.Items[i].PostId:=GetPostId(Nodes.Items[i].NodeByName(cnsId).ValueAsString); + Result.Items[i].PostTitle:=Nodes.Items[i].NodeByName(cnsTitle).ValueAsString; + Result.Items[i].PostSourse.Add(Nodes.Items[i].NodeByName(cnsContent).ValueAsString); + Result.Items[i].PostPublished:=Nodes.Items[i].NodeByName(cnsPublished).ValueAsDateTime; + Result.Items[i].PostUpdate:=Nodes.Items[i].NodeByName(cnsUpdated).ValueAsDateTime; + NodesChild:=TXmlNodeList.Create; + Nodes.Items[i].FindNodes(cnsCategory,NodesChild); + for i2 := 0 to NodesChild.Count - 1 do + begin + Result.Items[i].СategoryPost.Add(NodesChild.Items[i2].AttributeByName[cntTerm]); + end; + end; +end; + +{------------------------------------------------------------------------------- + Функция: TBlogger.RetrievPostForParams + Автор: NMD + Дата: 2010.08.10 19:39:25 + Входные параметры: + aAlt atom(default),rss + aCategory Посты определенной категории + aOrderby Задаем порядок постов в котором мы их получим в список постов lastmodified (the default), starttime, or updated. + aPublishedMin Ограничение на дату публикации. Игнорируется если orderby установлен в updated + APublishedMax Ограничение на дату публикации. Игнорируется если orderby установлен в updated + aUpdatedMin Ограничение на дату публикации. Игнорируется если orderby установлен в updated + aUpdatedMax Ограничение на дату публикации. Игнорируется если orderby установлен в updated + aStartIndex Индекс поста который будет получен первым (для докачки постов) + aMaxResults Максимальное кол-во возвращаемых постов + Что делает: Возвращает посты из блога по заданным параметрам + Результат: Список постов в коллекции TPostCollection + Пример + http://www.blogger.com/feeds/9144819905011498730/posts/default?category=Application&max-results=10&start-index=1&published-min=2008-03-16T00:00:00&published-max=2011-03-24T23:59:59 +-------------------------------------------------------------------------------} +function TBlogger.RetrievPostForParams(aCategory:string =''; aOrderby:string =''; aPublishedMin:string =''; + aPublishedMax:string =''; aUpdatedMin:string ='';aUpdatedMax:string =''; + aStartIndex:Integer=0; aMaxResults:Integer=0; aAlt : string =''): TPostCollection; +var + i:Integer; + temp:TStringList; + parametrs:string; +begin + Result:=TPostCollection.Create(nil); + if FAuth='' then + begin + ToError(rsErrorNotTolken); + Exit; + end; + if FCurrentBlog<0 then + begin + ToError(rsErrorNotSelectBlog); + Exit; + end; + parametrs:=''; + temp:=TStringList.Create; + if aAlt<>'' then + temp.Add('alt='+aAlt); + if aCategory<>'' then + temp.Add('category='+aCategory); + if aOrderby<>'' then + temp.Add('orderby='+aOrderby); + if aPublishedMin<>'' then + temp.Add('published-min='+aPublishedMin); + if APublishedMax<>'' then + temp.Add('published-max='+aPublishedMax); + if aUpdatedMin<>'' then + temp.Add('updated-min='+aUpdatedMin); + if aUpdatedMax<>'' then + temp.Add('updated-max='+aUpdatedMax); + if aStartIndex<>0 then + temp.Add('start-index='+IntToStr(aStartIndex)); + if aMaxResults<>0 then + temp.Add('max-results='+IntToStr(aMaxResults)); + for I := 0 to temp.Count - 1 do + begin + if i>0 then + parametrs:=parametrs+'&'+temp.Strings[i] + else + parametrs:=parametrs+temp.Strings[i]; + end; + temp.Free; + Result:=RetrievPostForTextParams(cnsVop+parametrs); +end; + +{------------------------------------------------------------------------------- + Процедура: TBlogger.CreatPost формируем xml будущего сообщения и отправляем его в блог + Автор: NMD + Дата: 2010.08.06 18:37:01 + Входные параметры: + aTitle- заголовок, + aContent-текст сообщения: string; + aCategory-ярлыки сообщения: TStringList; + aComment: Boolean комментарий или нет + Результат: string получаем xml отправленной статьи но уже из блогга или текст ошибки +-------------------------------------------------------------------------------} +function TBlogger.PostCreat(aTitle, aContent: string; aCategory: TStringList; aComment: Boolean):UTF8String; +var + i:Integer; + Node,Node2:TXmlNode; + tempXML :TNativeXml; +begin + Result:=''; + if FAuth='' then + begin + ToError(rsErrorNotTolken); + Exit; + end; + if FCurrentBlog<0 then + begin + ToError(rsErrorNotSelectBlog); + Exit; + end; + + FXMLDoc.Clear; + FXMLDoc.Root.CreateName(FXMLDoc,cnsEntry).AttributeAdd(cnsXmlns,cnsAtomUrl); + { + yes + } + if aComment then + begin + Node:=FXMLDoc.Root.NodeNew(cnsAppControll); + Node.AttributeAdd(cnsXmlnsApp,cnsXmlnsAppUrl); + Node2:=TXmlNode.CreateNameValue(FXMLDoc,cnsAppDraft,cnsYes); + Node.NodeAdd(Node2); + end; + + //Marriage! + with FXMLDoc.Root.NodeNew(cnsTitle)do + begin + AttributeAdd(cnsType,cnsText); + ValueAsString:=aTitle; + end; + // + Node:=FXMLDoc.Root.NodeNew(cnsContent); + Node.AttributeAdd(cnsType,cnsXhtml); + //сам контент единственное он должен быть валидным html + tempXML:=TNativeXml.Create; + try + tempXML.ReadFromString(aContent); + except + ToError(rsErrorXmlTag); + tempXML:=nil; + Exit;//выход + end; + for I := 0 to tempXML.RootNodeList.NodeCount - 1 do + begin + node2:=tempXML.RootNodeList.Nodes[i]; + node.NodeAdd(node2); + end; +{ //
+ Node2:=TXmlNode.CreateName(FXMLDoc,cnsDiv); + Node2.AttributeAdd(cnsXmlns,cnsXhtmlUrl); + Node.NodeAdd(Node2); + Node:=TXmlNode.CreateName(FXMLDoc,'p'); + Node.ValueAsString:=aContent; + Node2.NodeAdd(Node); +} + // + for i := 0 to aCategory.Count - 1 do + with FXMLDoc.Root.NodeNew(cnsCategory) do + begin + AttributeAdd(cnsScheme,cnsAtnsUrl); + AttributeAdd(cnsTerm,sdAnsiToUtf8(aCategory.Strings[i])); + end; + Result:=GetUrl(cnsPostBlogStart+Blogs.Items[FCurrentBlog].FBlogId+cnsPostBlogEnd,'','post',FAuth,FXMLDoc.WriteToString); + tempXML:=nil; +end; + +{------------------------------------------------------------------------------- + Функция: TBlogger.PostModify + Автор: NMD + Дата: 2010.08.10 21:28:47 + Входные параметры: + id сообщения, остальное анологично созданию поста + Что делает: Производит обновление поста в блоге + Результат: xml модифицированного сообщения +-------------------------------------------------------------------------------} +function TBlogger.PostModify(id, aTitle, aContent: string; aCategory: TStringList; aComment: Boolean): UTF8String; +var + i:Integer; + Node,Node2:TXmlNode; + blogId:string; +begin + Result:=''; + if FAuth='' then + begin + ToError(rsErrorNotTolken); + Exit; + end; + if FCurrentBlog<0 then + begin + ToError(rsErrorNotSelectBlog); + Exit; + end; + FXMLDoc.Clear; + FXMLDoc.Root.CreateName(FXMLDoc,cnsEntry).AttributeAdd(cnsXmlns,cnsAtomUrl); + + { + yes + } + if aComment then + begin + Node:=FXMLDoc.Root.NodeNew(cnsAppControll); + Node.AttributeAdd(cnsXmlnsApp,cnsXmlnsAppUrl); + Node2:=TXmlNode.CreateNameValue(FXMLDoc,cnsAppDraft,cnsYes); + Node.NodeAdd(Node2); + end; + // tag:blogger.com,1999:blog-blogID.post-postID + blogId:=IntToStr(FBlogs.Items[FCurrentBlog].id);//id блога + FXMLDoc.Root.NodeNew(cnsId).ValueAsString:='tag:blogger.com,1999:blog-'+blogId+'.post-'+id; + //Marriage! + with FXMLDoc.Root.NodeNew(cnsTitle)do + begin + AttributeAdd(cnsType,cnsText); + ValueAsString:=aTitle; + end; + // + Node:=FXMLDoc.Root.NodeNew(cnsContent); + Node.AttributeAdd(cnsType,cnsXhtml); + //
+ Node2:=TXmlNode.CreateName(FXMLDoc,cnsDiv); + Node2.AttributeAdd(cnsXmlns,cnsXhtmlUrl); + Node.NodeAdd(Node2); + Node:=TXmlNode.CreateName(FXMLDoc,'p'); + Node.ValueAsString:=aContent; + Node2.NodeAdd(Node); + + // + for i := 0 to aCategory.Count - 1 do + with FXMLDoc.Root.NodeNew(cnsCategory) do + begin + AttributeAdd(cnsScheme,cnsAtnsUrl); + AttributeAdd(cnsTerm,sdAnsiToUtf8(aCategory.Strings[i])); + end; + //'http://www.blogger.com/feeds/1897581382578917834/posts/default/5129237316807356045', + Result:=GetUrl(cnsPostBlogStart+Blogs.Items[FCurrentBlog].FBlogId+cnsPostBlogEnd+'/'+id,'','put',FAuth,FXMLDoc.WriteToString); +end; + +{------------------------------------------------------------------------------- + Функция: TBlogger.PostDelete + Автор: NMD + Дата: 2010.08.11 19:24:17 + Входные параметры: + id сообщения которое необходимо удалить + Что делает: удаление поста из блога + Результат: Boolean +-------------------------------------------------------------------------------} +function TBlogger.PostDelete(id: string): Boolean; +begin + if FAuth='' then + begin + ToError(rsErrorNotTolken); + Exit; + end; + if FCurrentBlog<0 then + begin + ToError(rsErrorNotSelectBlog); + Exit; + end; + if id='' then + begin + ToError(rsErrorIdPost); + Exit; + end; + if GetUrl(cnsPostBlogStart+Blogs.Items[FCurrentBlog].FBlogId+cnsPostBlogEnd+'/'+id,'','DELETE',FAuth,'')='1' then + Result:=True + else + Result:=False; +end; + + +procedure TBlogger.SetAppName(const Value: string); +begin + if Value<>'' then + FAppName := Value; +end; + +procedure TBlogger.SetAuth(const Value: string); +begin + if Value<>'' then + begin + FAuth := Value; + RetrievAllBlogs; + end; +end; + +procedure TBlogger.SetBlog(const Value: TBlogCollection); +begin + FBlogs.Assign(Value); +end; + +procedure TBlogger.SetCurrentBlog(const Value: Integer); +begin + FCurrentBlog := Value; +end; + +{BlogCollection} +function TBlogCollection.Add: TBlogItem; +begin + result := TBlogItem(inherited Add); +end; + +function TBlogCollection.AddEx(aName, aTitle,aBlogId: string; aUrl: string; aСategoryBlog: TStringList; aPublished, + aUpdate: TDateTime): TBlogItem; +begin + result := inherited Add as TBlogItem; + Result.FTitle:=aTitle; + Result.FBlogId:=aBlogId; + Result.FСategoryBlog.Assign(aСategoryBlog); + Result.FPublished:=aPublished; + Result.FUpdate:=aUpdate; +end; + +constructor TBlogCollection.Create(AOwner: TComponent); +begin + inherited Create(TBlogItem); +end; + +function TBlogCollection.GetItemBlog(Index: Integer): TBlogItem; +begin + result := TBlogItem(inherited GetItem(Index)); +end; + +procedure TBlogCollection.SetItemBlog(Index: Integer; Value: TBlogItem); +begin + inherited SetItem(Index, Value) +end; + +constructor TBlogItem.Create(Collection: TCollection); +begin + inherited; + FTitle:=''; + FBlogId:=''; + FСategoryBlog:=TStringList.Create;//ярлыки блога + FPublished:=Time;//дата последеней публикации + FUpdate:=Time;//дата последнего обновления +end; + +destructor TBlogItem.Destroy; +begin + FСategoryBlog.Destroy; + inherited; +end; + +procedure TBlogItem.SetCategory(const Value: TStringList); +begin + FСategoryBlog.Assign(Value); +end; + +procedure TBlogItem.SetBlogId(const Value: string); +begin + FBlogId := Value; +end; + +procedure TBlogItem.SetPublished(const Value: TDateTime); +begin + FPublished := Value; +end; + +procedure TBlogItem.SetTitle(const Value: string); +begin + FTitle := Value; +end; + +procedure TBlogItem.SetUpdate(const Value: TDateTime); +begin + FUpdate := Value; +end; + +{ TPostItem } + +constructor TPostItem.Create(Collection: TCollection); +begin + inherited; + FPostSourse:=TStringList.Create; + FСategoryPost:=TStringList.Create; +end; + +destructor TPostItem.Destroy; +begin + FPostSourse.Free; + FСategoryPost.Free; + inherited; +end; + +procedure TPostItem.SetPostId(const Value: string); +begin + FPostId := Value; +end; + +procedure TPostItem.SetPostPublished(const Value: TDateTime); +begin + FPostPublished := Value; +end; + +procedure TPostItem.SetPostSourse(const Value: TStringList); +begin + FPostSourse.Assign(Value); +end; + +procedure TPostItem.SetPostTitle(const Value: string); +begin + FPostTitle := Value; +end; + +procedure TPostItem.SetPostUpdate(const Value: TDateTime); +begin + FPostUpdate:=Value; +end; + +procedure TPostItem.SetСategoryPost(const Value: TStringList); +begin + FСategoryPost.Assign(Value); +end; + +{ TPostCollection } + +function TPostCollection.Add: TPostItem; +begin + result := TPostItem(inherited Add); +end; + +function TPostCollection.AddEx(aPostTitle, aPostId: string; aPostSourse: TStringList; aPostPublished, + aPostUpdate: TDateTime): TPostItem; +begin + result := inherited Add as TPostItem; + Result.FPostTitle:=aPostTitle; + Result.FPostId:=aPostId; + Result.FPostSourse.Assign(aPostSourse); + Result.FPostPublished:=aPostPublished; + Result.FPostUpdate:=aPostUpdate; +end; + +constructor TPostCollection.Create(AOwner: TComponent); +begin + inherited Create(TPostItem); +end; + +function TPostCollection.GetItemBlog(Index: Integer): TPostItem; +begin + result := TPostItem(inherited GetItem(Index)); +end; + +procedure TPostCollection.SetItemBlog(Index: Integer; Value: TPostItem); +begin + inherited SetItem(Index, Value); +end; + +procedure Register; +begin + RegisterComponents('NMD', [TBlogger]); +end; + +end. + From 5826e84cb29386d7d11c9d502fe9961af2c3fed7 Mon Sep 17 00:00:00 2001 From: NMD Date: Sat, 21 Aug 2010 15:19:18 +0600 Subject: [PATCH 2/9] gdd --- packages/BloggerApi_Pack.dpk | 36 ++++++++++++++++++++++++++++++++++++ 1 file changed, 36 insertions(+) create mode 100644 packages/BloggerApi_Pack.dpk diff --git a/packages/BloggerApi_Pack.dpk b/packages/BloggerApi_Pack.dpk new file mode 100644 index 0000000..6ca7220 --- /dev/null +++ b/packages/BloggerApi_Pack.dpk @@ -0,0 +1,36 @@ +package BloggerApi_Pack; + +{$R *.res} +{$ALIGN 8} +{$ASSERTIONS ON} +{$BOOLEVAL OFF} +{$DEBUGINFO ON} +{$EXTENDEDSYNTAX ON} +{$IMPORTEDDATA ON} +{$IOCHECKS ON} +{$LOCALSYMBOLS ON} +{$LONGSTRINGS ON} +{$OPENSTRINGS ON} +{$OPTIMIZATION ON} +{$OVERFLOWCHECKS OFF} +{$RANGECHECKS OFF} +{$REFERENCEINFO ON} +{$SAFEDIVIDE OFF} +{$STACKFRAMES OFF} +{$TYPEDADDRESS OFF} +{$VARSTRINGCHECKS ON} +{$WRITEABLECONST OFF} +{$MINENUMSIZE 1} +{$IMAGEBASE $400000} +{$IMPLICITBUILD ON} + +requires + rtl, + vcl; + +contains + BloggerApi in 'BloggerApi.pas'; + +end. + + From 42f3608c68ac0faaf7033dff94cc42f82e93c005 Mon Sep 17 00:00:00 2001 From: NMD Date: Sun, 22 Aug 2010 15:06:42 +0600 Subject: [PATCH 3/9] =?UTF-8?q?=D1=83=D0=B4=D0=B0=D0=BB=D0=B8=D0=BB=20?= =?UTF-8?q?=D1=81=D0=B2=D0=BE=D0=B9=20=D0=BF=D0=B0=D1=81=D1=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Demo/blogger_api_demo/Unit1.dfm | 2 -- 1 file changed, 2 deletions(-) diff --git a/Demo/blogger_api_demo/Unit1.dfm b/Demo/blogger_api_demo/Unit1.dfm index b600f22..0155090 100644 --- a/Demo/blogger_api_demo/Unit1.dfm +++ b/Demo/blogger_api_demo/Unit1.dfm @@ -132,8 +132,6 @@ object Form1: TForm1 'Mozilla/5.0 (Windows; U; Windows NT 5.1; ru; rv:1.9.2.6) Gecko/2' + '0100625 Firefox/3.6.6' AccountType = atGOOGLE - Email = 'nmdsoft@gmail.com' - Password = 'programmersofta#' Service = blogger OnAutorization = GoogleLogin1Autorization Left = 584 From e876bde527502518f37f5ccb576c0aac09684b75 Mon Sep 17 00:00:00 2001 From: NMD Date: Wed, 13 Oct 2010 20:57:14 +0600 Subject: [PATCH 4/9] =?UTF-8?q?=D0=A4=D0=BE=D1=80=D0=BC=D0=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Demo/blogger_api_demo/Unit1.dfm | 2 ++ 1 file changed, 2 insertions(+) diff --git a/Demo/blogger_api_demo/Unit1.dfm b/Demo/blogger_api_demo/Unit1.dfm index 0155090..1a55316 100644 --- a/Demo/blogger_api_demo/Unit1.dfm +++ b/Demo/blogger_api_demo/Unit1.dfm @@ -132,6 +132,8 @@ object Form1: TForm1 'Mozilla/5.0 (Windows; U; Windows NT 5.1; ru; rv:1.9.2.6) Gecko/2' + '0100625 Firefox/3.6.6' AccountType = atGOOGLE + Email = 'nmdsoft@gmail.com' + Password = 'dima1234programmer4321' Service = blogger OnAutorization = GoogleLogin1Autorization Left = 584 From 07e04db10613dd22637d204e64deb44a6003eb0d Mon Sep 17 00:00:00 2001 From: NMD Date: Fri, 15 Oct 2010 20:16:49 +0600 Subject: [PATCH 5/9] =?UTF-8?q?=D0=94=D0=BE=D0=B1=D0=B0=D0=B2=D0=B8=D0=BB?= =?UTF-8?q?=20=D0=BA=D0=BE=D0=BB=D0=BB=D0=B5=D0=BA=D1=86=D0=B8=D1=8E=20?= =?UTF-8?q?=D0=94=D0=BB=D1=8F=20=20=D0=BA=D0=BE=D0=BC=D0=BC=D0=B5=D0=BD?= =?UTF-8?q?=D1=82=D0=B0=D1=80=D0=B8=D0=B5=D0=B2?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Demo/blogger_api_demo/Unit1.dfm | 1 - packages/BloggerApi.pas | 128 ++++++++++++++++++++++++++++++++ packages/BloggerApi_Pack.dpk | 1 + 3 files changed, 129 insertions(+), 1 deletion(-) diff --git a/Demo/blogger_api_demo/Unit1.dfm b/Demo/blogger_api_demo/Unit1.dfm index 1a55316..dd638c8 100644 --- a/Demo/blogger_api_demo/Unit1.dfm +++ b/Demo/blogger_api_demo/Unit1.dfm @@ -133,7 +133,6 @@ object Form1: TForm1 '0100625 Firefox/3.6.6' AccountType = atGOOGLE Email = 'nmdsoft@gmail.com' - Password = 'dima1234programmer4321' Service = blogger OnAutorization = GoogleLogin1Autorization Left = 584 diff --git a/packages/BloggerApi.pas b/packages/BloggerApi.pas index 0d670fe..78bb9c9 100644 --- a/packages/BloggerApi.pas +++ b/packages/BloggerApi.pas @@ -63,6 +63,52 @@ interface //Прогресс выполнения задания TProgressEvent = procedure(aCurrentProgress,aMaxProgress: Integer) of object; + //для комментариев + TCommentItem = class (TCollectionItem) + private + FCommentTitle: string; + FCommentId: string; + FCommentSourse: TStringList; + FCommentPublished: TDateTime; + FCommentUpdate: TDateTime; + FAutorName:string; + FAutorURL:string; + FAutorEmail:string; + procedure SetCommentId(const Value: string); + procedure SetCommentPublished(const Value: TDateTime); + procedure SetCommentSourse(const Value: TStringList); + procedure SetCommentTitle(const Value: string); + procedure SetCommentUpdate(const Value: TDateTime); + procedure SetCommentAutorEmail(const Value: string); + procedure SetCommentAutorName(const Value: string); + procedure SetCommentAutorURL(const Value: string); + public + constructor Create(Collection: TCollection);override; + destructor Destroy; override; + published + property CommentId:string read FCommentId write SetCommentId; + property CommentTitle:string read FCommentTitle write SetCommentTitle; + property CommentSourse:TStringList read FCommentSourse write SetCommentSourse; + property CommentPublished:TDateTime read FCommentPublished write SetCommentPublished; + property CommentUpdate:TDateTime read FCommentUpdate write SetCommentUpdate; + property CommentAutorName:string read FAutorName write SetCommentAutorName; + property CommentAutorURL:string read FAutorURL write SetCommentAutorURL; + property CommentAutorEmail:string read FAutorEmail write SetCommentAutorEmail; + end; + + //комментарии + TCommentCollection = class (TCollection) + private + function GetItemComment(Index: Integer): TCommentItem; + procedure SetItemComment(Index: Integer; Value: TCommentItem); + public + constructor Create(AOwner:TComponent); + function Add: TCommentItem; + property Items[Index: Integer]: TCommentItem read GetItemComment write SetItemComment; + function AddEx(aPostTitle,aPostId:string; aPostSourse:TStringList;aPostPublished,aPostUpdate:TDateTime): TCommentItem; + end; + + //для сообщений TPostItem = class (TCollectionItem) private FPostTitle: string; @@ -962,5 +1008,87 @@ procedure Register; RegisterComponents('WebDelphi.ru', [TBlogger]); end; +{ TCommentItem } + +constructor TCommentItem.Create(Collection: TCollection); +begin + inherited; + FCommentSourse:=TStringList.Create; +end; + +destructor TCommentItem.Destroy; +begin + FCommentSourse.Free; + inherited; +end; + +procedure TCommentItem.SetCommentAutorEmail(const Value: string); +begin + FAutorEmail := Value; +end; + +procedure TCommentItem.SetCommentAutorName(const Value: string); +begin + FAutorName := Value; +end; + +procedure TCommentItem.SetCommentAutorURL(const Value: string); +begin + FAutorURL := Value; +end; + +procedure TCommentItem.SetCommentId(const Value: string); +begin + FCommentId:=Value; +end; + +procedure TCommentItem.SetCommentPublished(const Value: TDateTime); +begin + FCommentPublished:=Value; +end; + +procedure TCommentItem.SetCommentSourse(const Value: TStringList); +begin + FCommentSourse.Assign(Value); +end; + +procedure TCommentItem.SetCommentTitle(const Value: string); +begin + FCommentTitle:=Value; +end; + +procedure TCommentItem.SetCommentUpdate(const Value: TDateTime); +begin + FCommentUpdate:=Value; +end; + +{ TCommentCollection } + +function TCommentCollection.Add: TCommentItem; +begin + +end; + +function TCommentCollection.AddEx(aPostTitle, aPostId: string; aPostSourse: TStringList; aPostPublished, + aPostUpdate: TDateTime): TCommentItem; +begin + +end; + +constructor TCommentCollection.Create(AOwner: TComponent); +begin + inherited Create(TCommentItem); +end; + +function TCommentCollection.GetItemComment(Index: Integer): TCommentItem; +begin + result := TCommentItem(inherited GetItem(Index)); +end; + +procedure TCommentCollection.SetItemComment(Index: Integer; Value: TCommentItem); +begin + inherited SetItem(Index, Value); +end; + end. diff --git a/packages/BloggerApi_Pack.dpk b/packages/BloggerApi_Pack.dpk index 6ca7220..1a50319 100644 --- a/packages/BloggerApi_Pack.dpk +++ b/packages/BloggerApi_Pack.dpk @@ -34,3 +34,4 @@ contains end. + From 9a9a218c21335e04db44f4eee6fd0b616d1d6827 Mon Sep 17 00:00:00 2001 From: NMD Date: Fri, 15 Oct 2010 20:59:16 +0600 Subject: [PATCH 6/9] =?UTF-8?q?=D0=A0=D0=B5=D0=B0=D0=BB=D0=B8=D0=B7=D0=B0?= =?UTF-8?q?=D1=86=D0=B8=D1=8F=20=D0=BF=D0=BE=D0=BB=D1=83=D1=87=D0=B5=D0=BD?= =?UTF-8?q?=D0=B8=D1=8F=20=D0=B2=D1=81=D0=B5=D1=85=20=D0=BA=D0=BE=D0=BC?= =?UTF-8?q?=D0=BC=D0=B5=D0=BD=D1=82=D0=B0=D1=80=D0=B8=D0=B5=D0=B2=20=D0=B8?= =?UTF-8?q?=D0=B7=20=D0=B1=D0=BB=D0=BE=D0=B3=D0=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Demo/blogger_api_demo/Unit1.dcu | Bin 11840 -> 12874 bytes Demo/blogger_api_demo/Unit1.dfm | 27 ++++++++-- Demo/blogger_api_demo/Unit1.pas | 21 ++++++++ packages/BloggerApi.pas | 88 +++++++++++++++++++++++++++++--- 4 files changed, 123 insertions(+), 13 deletions(-) diff --git a/Demo/blogger_api_demo/Unit1.dcu b/Demo/blogger_api_demo/Unit1.dcu index 5400df649829122ace5e2726f6824bda105fbf92..2b99492f70e08a4e12dba37e9d806456b9619f35 100644 GIT binary patch delta 4399 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 diff --git a/Demo/blogger_api_demo/Unit1.dfm b/Demo/blogger_api_demo/Unit1.dfm index dd638c8..576e74f 100644 --- a/Demo/blogger_api_demo/Unit1.dfm +++ b/Demo/blogger_api_demo/Unit1.dfm @@ -96,8 +96,8 @@ object Form1: TForm1 OnClick = Button5Click end object Edit1: TEdit - Left = 224 - Top = 327 + Left = 390 + Top = 131 Width = 185 Height = 21 TabOrder = 9 @@ -108,17 +108,34 @@ object Form1: TForm1 Top = 353 Width = 201 Height = 25 - Caption = 'Button6' + Caption = #1059#1076#1072#1083#1077#1085#1080#1077' '#1087#1086#1089#1090#1072 TabOrder = 10 OnClick = Button6Click end object ProgressBar1: TProgressBar - Left = 328 - Top = 244 + Left = 390 + Top = 108 Width = 150 Height = 17 TabOrder = 11 end + object Button7: TButton + Left = 8 + Top = 384 + Width = 201 + Height = 25 + Caption = #1055#1086#1083#1091#1095#1077#1085#1080#1077' '#1074#1089#1077#1093' '#1082#1086#1084#1084#1077#1085#1090#1072#1088#1080#1077#1074 + TabOrder = 12 + OnClick = Button7Click + end + object Edit2: TEdit + Left = 215 + Top = 217 + Width = 161 + Height = 21 + TabOrder = 13 + Text = 'Edit2' + end object Blogger1: TBlogger AppName = 'MyCompany' Blogs = <> diff --git a/Demo/blogger_api_demo/Unit1.pas b/Demo/blogger_api_demo/Unit1.pas index 86a64f1..26a42e1 100644 --- a/Demo/blogger_api_demo/Unit1.pas +++ b/Demo/blogger_api_demo/Unit1.pas @@ -22,6 +22,8 @@ TForm1 = class(TForm) Edit1: TEdit; Button6: TButton; ProgressBar1: TProgressBar; + Button7: TButton; + Edit2: TEdit; procedure Button1Click(Sender: TObject); procedure GoogleLogin1Autorization(const LoginResult: TLoginResult; Result: TResultRec); procedure Button2Click(Sender: TObject); @@ -32,6 +34,7 @@ TForm1 = class(TForm) procedure Blogger1Error(E: string); procedure ComboBox1Change(Sender: TObject); procedure Blogger1Progress(aCurrentProgress, aMaxProgress: Integer); + procedure Button7Click(Sender: TObject); private { Private declarations } public @@ -58,6 +61,7 @@ procedure TForm1.Blogger1Progress(aCurrentProgress, aMaxProgress: Integer); procedure TForm1.Button1Click(Sender: TObject); begin + GoogleLogin1.Password:=Edit2.Text; GoogleLogin1.Login; end; @@ -125,6 +129,23 @@ procedure TForm1.Button6Click(Sender: TObject); Blogger1.PostDelete(Edit1.Text); end; +procedure TForm1.Button7Click(Sender: TObject); +var + a:TCommentCollection; + i:Integer; +begin + a:=TCommentCollection.Create(nil); + a:=Blogger1.RetrievAllComments; + if a.Count<=0 then + begin + a.Free; + Exit; + end; + for I := 0 to a.Count - 1 do + Memo3.Lines.Add(a.Items[i].CommentSourse.Text); + a.Free; +end; + procedure TForm1.ComboBox1Change(Sender: TObject); begin Blogger1.CurrentBlog:=ComboBox1.ItemIndex; diff --git a/packages/BloggerApi.pas b/packages/BloggerApi.pas index 78bb9c9..dbfc128 100644 --- a/packages/BloggerApi.pas +++ b/packages/BloggerApi.pas @@ -56,7 +56,11 @@ interface cnsYes='yes'; cnsVop='/?'; // cnsPostIdUrl='http://www.blogger.com/feeds/blogID/posts/default/postID'; - + cnsAuthor='author';//автор для комментариев + //cnsName имя автора комментария + cnsURl='uri'; + cnsEmail='email'; + cnsCommentsEnd='/comments/default'; type //событие для ошибки TErrorEvent = procedure(aE: string) of object; @@ -105,7 +109,7 @@ TCommentCollection = class (TCollection) constructor Create(AOwner:TComponent); function Add: TCommentItem; property Items[Index: Integer]: TCommentItem read GetItemComment write SetItemComment; - function AddEx(aPostTitle,aPostId:string; aPostSourse:TStringList;aPostPublished,aPostUpdate:TDateTime): TCommentItem; + function AddEx(aCommentTitle,aCommentId:string; aCommentSourse:TStringList;aCommentPublished,aCommentUpdate:TDateTime;aAutorName,aAutorEmail,aAutorURL:string): TCommentItem; end; //для сообщений @@ -206,6 +210,8 @@ TBlogger = class(TComponent) function GetIdBlog(aSourse:string):string;//получение id блога function GetPostId(aSourse:string):string;//получение id поста + function GetCommentId(aSourse:string):string;//получение id комментария + procedure ToError(aError:string);//обработка ошибок //для пропертей @@ -216,7 +222,11 @@ TBlogger = class(TComponent) protected public + constructor Create(AOwner: TComponent);override;//инициализация класса + destructor Destroy; override;//уничтожение + procedure RetrievAllBlogs;//получение списка блогов пользователя + function PostCreat(aTitle,aContent:string; aCategory:TStringList;aComment:Boolean):UTF8String;//создание сообщения и отправка в блог function PostModify(id,aTitle,aContent:string; aCategory:TStringList;aComment:Boolean):UTF8String;//Изменение сообщения и отправка его в блог function PostDelete(id:string):Boolean;//удаление поста из блога @@ -228,8 +238,10 @@ TBlogger = class(TComponent) aStartIndex:Integer=0; aMaxResults:Integer=0; aAlt : string =''):TPostCollection; //Возвращает посты из блога по заданным параметрам созданым в ручную function RetrievPostForTextParams(Parametrs:string):TPostCollection; - constructor Create(AOwner: TComponent);override;//инициализация класса - destructor Destroy; override;//уничтожение + + //Комментарии + function RetrievAllComments:TCommentCollection;//возвращает все комментарии текущего блога + published property Auth:string read FAuth write SetAuth; property AppName:string read FAppName write SetAppName; @@ -264,6 +276,12 @@ destructor TBlogger.Destroy; inherited; end; +//получение id комментария +function TBlogger.GetCommentId(aSourse: string): string; +begin +// +end; + function TBlogger.GetHostName(url : string) : string; begin result := ''; @@ -479,6 +497,52 @@ procedure TBlogger.RetrievAllBlogs; end; end; +//возвращает все комментарии текущего блога +function TBlogger.RetrievAllComments: TCommentCollection; +var + Nodes,NodesChild: TXmlNodeList; + i,i2:Integer; +begin + Result:=TCommentCollection.Create(nil); + FXMLDoc.Clear; + if FAuth<>'' then + begin//'http://www.blogger.com/feeds/9144819905011498730/posts/default' + //http://www.blogger.com/feeds/blogID/comments/default + if FCurrentBlog>-1 then + FXMLDoc.ReadFromString(GetUrl(cnsPostBlogStart+Blogs.Items[FCurrentBlog].FBlogId+cnsCommentsEnd,'','get',FAuth,'')) + else + ToError(rsErrorNotSelectBlog); + end + else + begin + ToError(rsErrorNotTolken); + Exit;////////ИСПРАВИТЬ!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! + end; + + Nodes:=TXmlNodeList.Create; + FXMLDoc.Root.FindNodes(cnsEntry,Nodes);// + for i := 0 to Nodes.Count-1 do + begin + Result.Add; + Result.Items[i].CommentId:=GetCommentId(Nodes.Items[i].NodeByName(cnsId).ValueAsString);//id комментария + Result.Items[i].CommentTitle:=Nodes.Items[i].NodeByName(cnsTitle).ValueAsString;//заголовок + Result.Items[i].CommentSourse.Add(Nodes.Items[i].NodeByName(cnsContent).ValueAsString);//текст комментария + Result.Items[i].CommentPublished:=Nodes.Items[i].NodeByName(cnsPublished).ValueAsDateTime;// дата публикации комментария + Result.Items[i].CommentUpdate:=Nodes.Items[i].NodeByName(cnsUpdated).ValueAsDateTime;// дата обновления комментария +// Result.Items[i].CommentAutorName:=Nodes.Items[i].NodeByName(cnsName).ValueAsString;//имя автора +// Result.Items[i].CommentAutorURL:=Nodes.Items[i].NodeByName(cnsURl).ValueAsString;//профиль автора +// Result.Items[i].CommentAutorEmail:=Nodes.Items[i].NodeByName(cnsEmail).ValueAsString;//адрес электронной почты автора +{ + NodesChild:=TXmlNodeList.Create; + Nodes.Items[i].FindNodes(cnsAuthor,NodesChild); + for i2 := 0 to NodesChild.Count - 1 do + begin + Result.Items[i].СategoryPost.Add(NodesChild.Items[i2].AttributeByName[cntTerm]); + end; +} + end; +end; + {------------------------------------------------------------------------------- Функция: TBlogger.RetrievAllPosts Автор: NMD @@ -1066,13 +1130,21 @@ procedure TCommentItem.SetCommentUpdate(const Value: TDateTime); function TCommentCollection.Add: TCommentItem; begin - + result := TCommentItem(inherited Add); end; -function TCommentCollection.AddEx(aPostTitle, aPostId: string; aPostSourse: TStringList; aPostPublished, - aPostUpdate: TDateTime): TCommentItem; +function TCommentCollection.AddEx(aCommentTitle, aCommentId: string; aCommentSourse: TStringList; aCommentPublished, + aCommentUpdate: TDateTime; aAutorName, aAutorEmail, aAutorURL: string): TCommentItem; begin - + result := inherited Add as TCommentItem; + Result.FCommentTitle:=aCommentTitle; + Result.FCommentId:=aCommentId; + Result.FCommentSourse.Assign(aCommentSourse); + Result.FCommentPublished:=aCommentPublished; + Result.FCommentUpdate:=aCommentUpdate; + Result.FAutorName:=aAutorName; + Result.FAutorEmail:=aAutorEmail; + Result.FAutorURL:=aAutorURL; end; constructor TCommentCollection.Create(AOwner: TComponent); From 3bb00befa9efc2d524297082b347dc68e3e2576c Mon Sep 17 00:00:00 2001 From: NMD Date: Fri, 15 Oct 2010 21:18:16 +0600 Subject: [PATCH 7/9] =?UTF-8?q?=D0=A0=D0=B5=D0=B0=D0=BB=D0=B8=D0=B7=D0=BE?= =?UTF-8?q?=D0=B2=D0=B0=D0=BB=20=D0=BF=D0=BE=D0=BB=D1=83=D1=87=D0=B5=D0=BD?= =?UTF-8?q?=D0=B8=D0=B5=20=D0=B2=D1=81=D0=B5=D1=85=20=D0=BA=D0=BE=D0=BC?= =?UTF-8?q?=D0=BC=D0=B5=D0=BD=D1=82=D0=B0=D1=80=D0=B8=D0=B5=D0=B2=20=D0=B8?= =?UTF-8?q?=D0=B7=20=D0=B1=D0=BB=D0=BE=D0=B3=D0=B0=20=D0=A2=D0=B5=D0=BA?= =?UTF-8?q?=D1=81=D1=82=20=D0=BA=D0=BE=D0=BC=D0=BC=D0=B5=D0=BD=D1=82=D0=B0?= =?UTF-8?q?=D1=80=D0=B8=D1=8F=20=D0=97=D0=B0=D0=B3=D0=BE=D0=BB=D0=BE=D0=B2?= =?UTF-8?q?=D0=BE=D0=BA=20=D0=BA=D0=BE=D0=BC=D0=BC=D0=B5=D0=BD=D1=82=D0=B0?= =?UTF-8?q?=D1=80=D0=B8=D1=8F=20=D0=90=D0=B2=D1=82=D0=BE=D1=80=20=D0=BA?= =?UTF-8?q?=D0=BE=D0=BC=D0=BC=D0=B5=D0=BD=D1=82=D0=B0=D1=80=D0=B8=D1=8F=20?= =?UTF-8?q?=D0=90=D0=B4=D1=80=D0=B5=D1=81=20=D1=81=D0=B0=D0=B9=D1=82=D0=B0?= =?UTF-8?q?=20=D0=B0=D0=B2=D1=82=D0=BE=D1=80=D0=B0=20=D0=90=D0=B4=D1=80?= =?UTF-8?q?=D0=B5=D1=81=20=D1=8D=D0=BB=D0=B5=D0=BA=D1=82=D1=80=D0=BE=D0=BD?= =?UTF-8?q?=D0=BD=D0=BE=D0=B9=20=D0=BF=D0=BE=D1=87=D1=82=D1=8B=20=D0=B0?= =?UTF-8?q?=D0=B2=D1=82=D0=BE=D1=80=D0=B0=20=D0=BA=D0=BE=D0=BC=D0=BC=D0=B5?= =?UTF-8?q?=D0=BD=D1=82=D0=B0=D1=80=D0=B8=D1=8F?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Demo/blogger_api_demo/Unit1.dcu | Bin 12874 -> 12801 bytes Demo/blogger_api_demo/Unit1.pas | 2 +- packages/BloggerApi.pas | 11 +++++------ 3 files changed, 6 insertions(+), 7 deletions(-) diff --git a/Demo/blogger_api_demo/Unit1.dcu b/Demo/blogger_api_demo/Unit1.dcu index 2b99492f70e08a4e12dba37e9d806456b9619f35..8b3265576b12bc07cc85a6a01c3cd5fcbd856794 100644 GIT binary patch delta 318 zcmX?=(wM^K%D^DXXvDzavT`Dq0h8m(jW*^YIuAN*EEHLSQ*+Y97#J*g6xo7P^HNfa zfE*?!1;#`mt;V6imu&+4z6=_3mR3=>U!H)+Nk9bqx!cfF#HNKnr*8()&>9*!Z~U z&2Q9M7#UY?{;08vSzL@Il8K8omPw2?kx7G9$%r+T$&OV?Xz~G_J)%5JGE7n|VoZE2 zEKD;0Y*^Ts_}I86Pt;XqOx(O(cMT&4*I(u-+jcy7v^iJbijmP^@(P1)#u<}M3{UDD xU|{&bFqfH!XDPE2$6V%!e@mIufH(`t&f;0g+{U$%`NY4uK)jUs+GHUk3jlSHUNQgx delta 417 zcmZonIhDfY%D^D%WyHYXx_ly+0h7z}jW*^Yx__BEY%CO6f>U$S(ij*lekig9r{<-k z7Kt%1Ffl1GCIV?S4h6u3s*I_dBX!p>a`F6Sp0aJngGa7Rn|bxE7#X!Ddl+;x_DsHFa8fiu cg26y&DRTwKQsz1TmNG8@(uGWuPa0YP09ST|=>Px# diff --git a/Demo/blogger_api_demo/Unit1.pas b/Demo/blogger_api_demo/Unit1.pas index 26a42e1..f84e579 100644 --- a/Demo/blogger_api_demo/Unit1.pas +++ b/Demo/blogger_api_demo/Unit1.pas @@ -142,7 +142,7 @@ procedure TForm1.Button7Click(Sender: TObject); Exit; end; for I := 0 to a.Count - 1 do - Memo3.Lines.Add(a.Items[i].CommentSourse.Text); + Memo3.Lines.Add(a.Items[i].CommentAutorName); a.Free; end; diff --git a/packages/BloggerApi.pas b/packages/BloggerApi.pas index dbfc128..3f0ab4d 100644 --- a/packages/BloggerApi.pas +++ b/packages/BloggerApi.pas @@ -529,18 +529,17 @@ function TBlogger.RetrievAllComments: TCommentCollection; Result.Items[i].CommentSourse.Add(Nodes.Items[i].NodeByName(cnsContent).ValueAsString);//текст комментария Result.Items[i].CommentPublished:=Nodes.Items[i].NodeByName(cnsPublished).ValueAsDateTime;// дата публикации комментария Result.Items[i].CommentUpdate:=Nodes.Items[i].NodeByName(cnsUpdated).ValueAsDateTime;// дата обновления комментария -// Result.Items[i].CommentAutorName:=Nodes.Items[i].NodeByName(cnsName).ValueAsString;//имя автора -// Result.Items[i].CommentAutorURL:=Nodes.Items[i].NodeByName(cnsURl).ValueAsString;//профиль автора -// Result.Items[i].CommentAutorEmail:=Nodes.Items[i].NodeByName(cnsEmail).ValueAsString;//адрес электронной почты автора -{ + NodesChild:=TXmlNodeList.Create; Nodes.Items[i].FindNodes(cnsAuthor,NodesChild); for i2 := 0 to NodesChild.Count - 1 do begin - Result.Items[i].СategoryPost.Add(NodesChild.Items[i2].AttributeByName[cntTerm]); + Result.Items[i].CommentAutorName:=NodesChild.Items[i2].NodeByName(cnsName).ValueAsString;//имя автора + Result.Items[i].CommentAutorURL:=NodesChild.Items[i2].NodeByName(cnsURl).ValueAsString;//профиль автора + Result.Items[i].CommentAutorEmail:=NodesChild.Items[i2].NodeByName(cnsEmail).ValueAsString;//адрес электронной почты автора end; -} end; +// FreeAndNil(NodesChild); end; {------------------------------------------------------------------------------- From 9d54522717f7bc6167040240f2ad5cdca5cd1d94 Mon Sep 17 00:00:00 2001 From: NMD Date: Fri, 15 Oct 2010 22:08:15 +0600 Subject: [PATCH 8/9] =?UTF-8?q?=D0=90=D0=BD=D0=BE=D0=BD=D0=B8=D0=BC=D0=BD?= =?UTF-8?q?=D1=8B=D0=B5=20=D0=BA=D0=BE=D0=BC=D0=BC=D0=B5=D0=BD=D1=82=D0=B0?= =?UTF-8?q?=D1=82=D0=BE=D1=80=D1=8B=20=D0=B2=20=D0=B1=D0=BB=D0=BE=D0=B3?= =?UTF-8?q?=D0=B5=20=D0=BD=D0=B5=20=D0=B8=D0=BC=D0=B5=D1=8E=D1=82=20Url=20?= =?UTF-8?q?=D1=81=D0=B4=D0=B5=D0=BB=D0=B0=D0=BB=20=D0=BF=D1=80=D0=BE=D0=B2?= =?UTF-8?q?=D0=B5=D1=80=D0=BA=D1=83,=20=D0=B0=20=D1=82=D0=BE=20=D0=B1?= =?UTF-8?q?=D1=8B=D0=BB=D0=B0=20=D0=B2=D0=B5=D1=80=D0=BE=D1=8F=D1=82=D0=BD?= =?UTF-8?q?=D0=BE=D1=81=D1=82=D1=8C=20=D0=B2=D0=BE=D0=B7=D0=BD=D0=B8=D0=BA?= =?UTF-8?q?=D0=BD=D0=BE=D0=B2=D0=B5=D0=BD=D0=B8=D1=8F=20=D0=BE=D1=88=D0=B8?= =?UTF-8?q?=D0=B1=D0=BA=D0=B8=20=D0=BF=D0=BE=20=D1=8D=D1=82=D0=BE=D0=B9=20?= =?UTF-8?q?=D0=BF=D1=80=D0=B8=D1=87=D0=B8=D0=BD=D0=B5!?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Demo/blogger_api_demo/Unit1.dcu | Bin 12801 -> 13957 bytes Demo/blogger_api_demo/Unit1.dfm | 8 ++++---- Demo/blogger_api_demo/Unit1.pas | 12 +++++++++++- packages/BloggerApi.pas | 16 +++++++++++++--- 4 files changed, 28 insertions(+), 8 deletions(-) diff --git a/Demo/blogger_api_demo/Unit1.dcu b/Demo/blogger_api_demo/Unit1.dcu index 8b3265576b12bc07cc85a6a01c3cd5fcbd856794..599c43b2ecc60a2a53e715d607e8dbfaf0911a18 100644 GIT binary patch delta 4556 zcmb7G4@{Kj8Gpa$eZKR(%ZYG>^I*V$$Q29{{&^Y^0{tz zPfM#bOUQiO)79c>?~&$Ga;$*mVTGi3j zCZT=gx3tC6+OeUVEo1DqOw!X-+0&&nzio7wDhS)q+*RJ$Li9{%beMaWb#!cKZC>87 zp{1S92I-8#w?&-Z2yTk&RgA&waZO4>u)$KPWYTU8{?SsT3h`gAQlevuN8+An@m+1k?h%Pov04nOiP>zg-FTAYq6n_Jhfr*TZC8&)>AH#K)z z83RaDJS6RgG^K^45NS#-kxXa95^qo2W7GDH#$C!#@DK4-%6RZv{L{)r(4DZ%s{vy# z4#czcd3PXD@rN$iGaq3&VtNAk%*4{tV|FQ@^Es5Fcq(U3MQ=|}N4o^9`2>6s0o1zY zwhno0E2rasM~=;R4NjuD4TSzTf*LI}#C07N9nVTE$wS!J!9`YE&7BBC4_hF^_7SMv zb6hBo19Yt5z12y;x`zN2gD+d>|HwECcSwAk@VOWqvnC|P&BBW$eueOa;D4+sN@8&C ze48yLLQ-8#Ej_ZN4b-75sD&&$$*ZRMewgbXc8g)W> zu-2A5XI$4^!8TjUoCIC32?lJ5bB1)iE_m4XWB7Xc+aKAUit)OA*Z(Bw>+v*wYI^T9 ztbBaXb+d5Hy|I^`vZkrLroptr_m3!hh{7i2=5yWjZ5iMZ>w@n+U%mLv^MZNJzV~#- z7hfwxa|*hu`^V;O`zM*sLD!AKTfXzt6km0g-*stpJ9r~;+?Vvg`zWw)%Wlf;6H^Vv zcRA$vT^B}=6A-S#ec=cAd4AWq(X&zhx%=|H(TZaIuCt@pqYh{9>k#Fe{jM{k$uom+ zpZR{iGv4n$DVs|6)t&UaPLHmVuGBxZ>OTGbzV)_2_oS~rdC+}*s+X=wUxMyu@w>j& z$KiL4`RcwM-4?B8?1v*>rihJ$?$4%r>AD;Zd3!qK318jq(G$^-C+-)rYO3zWy#5D6 zQ&ZEows7pp)vKEZV>fQ5QTkmcMvcM0Wu|z4{*>?YHSaMtg21Ne&rA*2uoNG|G?s@2 zSbiFsJU(qwBhJe71eTfvsIFcR^nw+C~vHs)b1taTO^OIQtCN|BN%YAJmjUM!;& zd6c4Ch(%bCV?XY>jnN<;F!RZ0$&$cE%5IGYXzPY zcwXS60yhd=FYsxB+XQ|k@TS0*1#S}P9ToVz!0iH02z*80Uj^0 zo)!3efx891DDWkL0|I|5@VdY^1-1%&OW*;4hXl3@>=bxJ;8B5H0(%5LEATG@Hw*l= zz%2r|3cM`vOMy28ekAaiz~f$lX9QjlcuC+@fu9NdmzjDW=9mpx7_y@R8R&;RRAFJn zlt+YwFJsskCJG%G$tjcDae~v_NtV;{(CVWVpk?G)IL>o0f#>27*>}9tqmGRHyJZG0 z0)caB#nF0=RsyX=S_i>w$>c?J`;yUMw@mOybu~a0?*zLgKMIvcRZm#;N{_ziaUiN1 zd9fZxBwNOLX(W0AbtV&;7o)krG8Ca_F#4rIfK7jZ_Ag*YZdH?Fso`YxnA{lhq+eRrf#=nPFx;%jX$1!zBEvNqszqv|@Gd0(Eby znh#cWL6Mq~BvI8Kt7e5gs#rNMpoypALts+Nh*b_nYH5k;0=e=G74fR`Uads+x}cuG zEjF4y#=Z_+*1R@ z$O;J78=?y8S%BN;UKTkNZE9F$<9xCD44Byj6}6KJ%8R9kKTGYU@jnN4wU6pchet`)(z!*a z6zBuK!Vy(&HZjnp0^8pT9?I$TRzWhoimVWWCR_+>XFi)?AMU#bHVecU>I`6jA`=pr zOkGz%Zm1RwxGn&23fL=9%$RjaP=Sv*F#6D=2`pX%0A|&I{;AkB@@Gl(z5|x5feBcu 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 diff --git a/Demo/blogger_api_demo/Unit1.dfm b/Demo/blogger_api_demo/Unit1.dfm index 576e74f..e1f5ecb 100644 --- a/Demo/blogger_api_demo/Unit1.dfm +++ b/Demo/blogger_api_demo/Unit1.dfm @@ -3,7 +3,7 @@ object Form1: TForm1 Top = 0 Caption = 'Form1' ClientHeight = 455 - ClientWidth = 622 + ClientWidth = 903 Color = clBtnFace Font.Charset = DEFAULT_CHARSET Font.Color = clWindowText @@ -62,8 +62,8 @@ object Form1: TForm1 object Memo3: TMemo Left = 199 Top = 95 - Width = 185 - Height = 89 + Width = 696 + Height = 314 Lines.Strings = ( '

Memo2

') TabOrder = 5 @@ -130,7 +130,7 @@ object Form1: TForm1 end object Edit2: TEdit Left = 215 - Top = 217 + Top = 219 Width = 161 Height = 21 TabOrder = 13 diff --git a/Demo/blogger_api_demo/Unit1.pas b/Demo/blogger_api_demo/Unit1.pas index f84e579..4fab0b4 100644 --- a/Demo/blogger_api_demo/Unit1.pas +++ b/Demo/blogger_api_demo/Unit1.pas @@ -142,7 +142,17 @@ procedure TForm1.Button7Click(Sender: TObject); Exit; end; for I := 0 to a.Count - 1 do - Memo3.Lines.Add(a.Items[i].CommentAutorName); + begin + Memo3.Lines.Add('Имя автора: '+a.Items[i].CommentAutorName); + Memo3.Lines.Add('URL: '+a.Items[i].CommentAutorURL); + Memo3.Lines.Add('Email: '+a.Items[i].CommentAutorEmail); + Memo3.Lines.Add('ID Комментария: '+a.Items[i].CommentId); + Memo3.Lines.Add('Заголовок комментария: '+a.Items[i].CommentTitle); + Memo3.Lines.Add('Текст комментария: '+a.Items[i].CommentSourse.Text); + Memo3.Lines.Add('Дата публикации: '+DateToStr( a.Items[i].CommentPublished )); + Memo3.Lines.Add('Дата обновления: '+DateToStr( a.Items[i].CommentPublished )); + + end; a.Free; end; diff --git a/packages/BloggerApi.pas b/packages/BloggerApi.pas index 3f0ab4d..a558463 100644 --- a/packages/BloggerApi.pas +++ b/packages/BloggerApi.pas @@ -61,6 +61,7 @@ interface cnsURl='uri'; cnsEmail='email'; cnsCommentsEnd='/comments/default'; + cnsAnonymous='Anonymous';//анонимный комментатор type //событие для ошибки TErrorEvent = procedure(aE: string) of object; @@ -278,8 +279,13 @@ destructor TBlogger.Destroy; //получение id комментария function TBlogger.GetCommentId(aSourse: string): string; +var + i:Integer; begin -// + Result:=''; + i:=AnsiPos('.blog-',aSourse); + Delete(aSourse,1,i+5); + Result:=aSourse; end; function TBlogger.GetHostName(url : string) : string; @@ -520,6 +526,7 @@ function TBlogger.RetrievAllComments: TCommentCollection; end; Nodes:=TXmlNodeList.Create; + FXMLDoc.Root.FindNodes(cnsEntry,Nodes);// for i := 0 to Nodes.Count-1 do begin @@ -535,11 +542,14 @@ function TBlogger.RetrievAllComments: TCommentCollection; for i2 := 0 to NodesChild.Count - 1 do begin Result.Items[i].CommentAutorName:=NodesChild.Items[i2].NodeByName(cnsName).ValueAsString;//имя автора - Result.Items[i].CommentAutorURL:=NodesChild.Items[i2].NodeByName(cnsURl).ValueAsString;//профиль автора + if NodesChild.Items[i2].NodeByName(cnsName).ValueAsString<>cnsAnonymous then//у анонимных людей нет профиля)) + Result.Items[i].CommentAutorURL:=NodesChild.Items[i2].NodeByName(cnsURl).ValueAsString //профиль автора + else + Result.Items[i].CommentAutorURL:=cnsAnonymous; Result.Items[i].CommentAutorEmail:=NodesChild.Items[i2].NodeByName(cnsEmail).ValueAsString;//адрес электронной почты автора end; + FreeAndNil(NodesChild); end; -// FreeAndNil(NodesChild); end; {------------------------------------------------------------------------------- From b28373659fa3323349630d26924b007dc8dab3b5 Mon Sep 17 00:00:00 2001 From: NMD Date: Sat, 16 Oct 2010 01:03:10 +0600 Subject: [PATCH 9/9] =?UTF-8?q?=D0=98=D1=81=D0=BF=D1=80=D0=B0=D0=B2=D0=B8?= =?UTF-8?q?=D0=BB=20=D0=BE=D0=BF=D0=BE=D0=B2=D0=B5=D1=89=D0=B5=D0=BD=D0=B8?= =?UTF-8?q?=D0=B5=20=D0=BE=D0=B1=20=D0=BE=D1=88=D0=B8=D0=B1=D0=BA=D0=B5!?= =?UTF-8?q?=20=D0=BD=D0=B5=D0=BE=D0=B1=D1=85=D0=BE=D0=B4=D0=B8=D0=BC=D0=BE?= =?UTF-8?q?=20=D0=BF=D0=B5=D1=80=D0=B5=D0=B4=D0=B5=D0=BB=D0=B0=D1=82=D1=8C?= =?UTF-8?q?=20=D0=BE=D0=B1=D1=80=D0=B0=D0=B1=D0=BE=D1=82=D0=BA=D1=83=20?= =?UTF-8?q?=D0=B8=D1=81=D0=BA=D0=BB=D1=8E=D1=87=D0=B8=D1=82=D0=B5=D0=BB?= =?UTF-8?q?=D1=8C=D0=BD=D1=8B=D1=85=20=D1=81=D0=B8=D1=82=D1=83=D0=B0=D1=86?= =?UTF-8?q?=D0=B8=D0=B9=20=D0=B2=20=D0=BA=D0=BE=D0=BC=D0=BF=D0=BE=D0=BD?= =?UTF-8?q?=D0=B5=D0=BD=D1=82=D0=B0=D1=85?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Demo/blogger_api_demo/Unit1.dcu | Bin 13957 -> 14941 bytes Demo/blogger_api_demo/Unit1.dfm | 24 +++++++++++++------- Demo/blogger_api_demo/Unit1.pas | 31 +++++++++++++++++++++----- packages/BloggerApi.pas | 38 +++++++++++++++++++++++++++++++- 4 files changed, 78 insertions(+), 15 deletions(-) diff --git a/Demo/blogger_api_demo/Unit1.dcu b/Demo/blogger_api_demo/Unit1.dcu index 599c43b2ecc60a2a53e715d607e8dbfaf0911a18..3f3b30a66050dbcacb3fd4b93dc5441945006d1c 100644 GIT binary patch delta 5554 zcmb7I4^WiXwZGrF=li&<3oa{CcFU4o3lsuASadhWOT z2^eSk%FMmzp7T5Z@1OmKp{{d%^L&ggY^h|-o6tBq?|}tX35`|Ili0kaqpzf>$G`Qf z360}bnqp1zHm~Um)&zt8?Mpj@cYg9yTewy!IsA;03CWwp+QyF7zW!if=%J7I9Ny2< z%~-M6zb$-heu@9f^S=H;d-~dMba%IR23B;pcWfzI6Xq%F=pvQZ+^c$CAQWxh-Liz_om(p|G+Z(wYFBbTHhV)k`4~Gx)bU;{GHwH zlKX3`Tde78GrUJz-KJWC+5^Fwo({tE!v2&6Eh9i`OS`)awQ`)u zo~z#eP$kRPVuGEFz4FM9&v~4B3MH2r`}YsuIOo~07>Y{k8LJK-PqF7*e)jc#_Uult z$AxPGotx4a^Dvj<+r*f5t97rE#}gP6p0HwdEVv?7>*uJ3ORPm9cT8tGcR?&}QEh); zU-y=hrJWtEk5X3uCGC1)j-lq#)&#b+1%eb1fCBmM@1)dlGAW%5^7}XmYpDwwn(lA@ zuwi~dnjhEZn49M0-~_*)lF15JF34)|-``!C;qJe6cM1PbcV&b3cjq?TU6k%><`%a* z)s`?8vkN;@ZR;*cor7~CexZru_m8vKh;vo?7@U9C3GK2cJer!So>!~G#O zLo{nX{=_xjoXxw=%+c^UuOj(e$Pvoi7j#^?^PV}BnuMa7l(lK5&~QX zpsoybbxVDF4T-ZuhTJ^6O9U4;5u9hBiS%%6?5^#8Oj>662`V(8c%)Jpsh5Bf1JEN$ zv3-!l?m6OzrFfLYp(Tbq?nff&V}w-Q1C&W%oPe5p0Jj8=6W}ud)z?P94kXU}h{Vec zaXdn~)So0^B>^FNk){jGjlu5rU|{RkT7OX5mERz^=^neq(oUJbS7|l?J&vp}Glj(K z4Y8&_?$S?%i{veFd69YcV@Bu|A6Lvf_bPrvA^eLBTSx*^Tp@YDkjD*U517Q8biCsp zJoZ9K+^^$Z_u#Q7N8*Dz-g^(OzaeWLl?r3JLjOGq<@)89__&U5H}E9m9O@@sD&*-3 zJ7Nmqf%LS{q%IjWOe}_p(Ryj+)^&yqop{}`H%HCeYK_h0%{boJ4=dTX7$bJg?d9uCZ(o}Lc9?3Gutb8z)KNoV~bt$P$k4^>RKSY_-C zKU`v~QNmtZBBrovHN4G!Dft6ZNMP|pk#hK-zFej(&}}3T7XwQQk7isBrR%=FSeHwe z$4j|iB}r@p#ox$oPVbG=+i~jFV)EWNJrt)`<20L|HEGvEv_N+d7u<={3TlXye=kns zp9CUYVsjn-i{mUjE&6}SO2V7;%Bh9ylpL&COct!erYR4_smod_ObCzsaaxWMf4Lb3JM+u18zI#=A`0TUq4qrO_mh08TitB5>_3hysBRf7nKz}=%|2%wl#P|8| zLaC((lS!N-rfs^oZI^Rk$Dft?Lr)VQ9(mB2)KfQHFP?f#u)g)fzYhP~gBz5KVM~EC zG&~?TT(^IB_(Y6O(EhO@Vy^w}k{gF7Q2p-xoL_@JWGB3%nrkbAkUW z@QlE>1RfRm8-bq){G-5&0xt`^Vy4>9aV&&fR3HacScIccjERtcmzOe$86zpqA0a&{ zll(~t<)e@1;1sXMCZc{CgEYoyjMK>Dxj4xS(9Mf*g7_pPW30W~ePb8?K3#+*ATWi- zLK;7zVWZ&)(ex`Cr@?IX@p9VU4AgS0Q+$=a`~elT2Xd@UGmw8~IXJT%n^}&}Ec1AU z?nY!-C%MOP?xtd89CI0(L#5V<8T};m#`N>83a-|d8}k``WzaI6iWd0uESAU9RJ(;* zlcCi#Tsf2Qh&G&QGO&9X~Wbz0QiSd@C^=cTkunOFrTwT85OP_B9^ z)#V^Zu~wU^dgrbr*GOZ9^yZh|V$tpNv0sXz!MnclY3I|_Ci?8k%J~Oe4$in-$Hw>~ zIy*)^V?1BoUm7o|8IolNgzEKB{f%s#htlbs>77|mof(feGnGwHZWEN6pUMnS_c~-+ z^=cQSk=UdbdH=y>!Hij~NpU|R>1d9mQD!+YQ`9Reo8)C`KbYAR9j85%P_czBj7Qy0 z?cV_&b%^rIhE+rxNN&|tN~u0OQ!rWm2uv&qHT8~(*$^?Cn;1x9R^a)gTQUxP1uDU! zdBF^JuxlEWK?P(&E>xISg+DERIA%n`!BBUtVplM<)qzQmzw2T6zaJCyfjHT6u z3&Dl*#{}rS0!wvp0G8(9BujU24VaytPGA`hZUUC+;AUV>2TumJ$iXeZvK-tBEXTo9 zf#o`Q8nApi^T0v{4sHilL>C5Fv4dvS}K~coDGLamm%!rI4FY zF|fKk$uFz#bnsGO^^=loST;&%8L(w;$*ySF=HTVP8YU#SYDG4I6~I;`A+e3CZWCKc zzq5*DS2tcF)&s23B|EjDP|mDG&Yes2b(NgA)yO%t?Fejy2!H$tbP{=DxvsEM&QFel zmqgDb!Dq#;H; zMD|8iC`yg+(7rd{I{NlI$4;ETu{FiTje7**n;eGfB)@`6*cSBuV z0w&@qa)?4-xOn->O2{Ppw=S%tpNTp!Xi z*d^yvBXa&tAszGxKNBm9JYKur0)7ZU2Xw`v&lU9o<$#e8zjpnA?&}pf-#jGeTZMX; z6*!_Jzmjtb^`x8v*xd|%Gla8i;&I4wyDw17q`OGvevXch4$>cdPPz0eQap%;n? zZ6R6;p$PZWLT+k+Xb#a1qPax7fNBvD9y2;k(tMKkQZZVDOFzFSQ2}*Bt}p3HU6u1F zg|8#cJ&>qpya#UR;Qz__0Njp|h$M#~RHz@a3D^UIY$nK7CU>0ZGK&2^oTknDJq*fT z@zb>0MX!fkCBidAC2!ZMisX+a%J~wUgk>b0f)ri2P|ml(CP@;1;pchWDd>L*Za%f%p`F8)$9K!d0tY6|evDlu2p=wM87h!jWoK{3SNj*f)*sptql zL(Cb|5O30m>C&QOu~-Kv)**^@fd4gmh^IhwoO=bObc7dZM|fLwf)DJZluq&|wUhi{ z^dx^>JIy~4r@1YW7>cL0u*N%WGFRgXAr2c(xTQ@?YePl*><(DrZ#=!p8MWB5Nf*n zn0wDX=R5!J-uE8oI=kB@)G+4iE@y0L@V>qYQzji9yl)0{SQo5n>GXO!f~(&dyl?*u z)e?QcQsSKGUogKj90-SlPt0l!|J46d`oV6?6gYT*r`hqzf1PNEew5_RX?g3_msX_R ze@}b+iq_Da_7yFwJo7`HjltEcA8QXczm;(Di)gkZ1&_(aQpdwlYx0)JvL>HW+a7LP z%@}*R$(K;w5^QZ>A-Nx#d}4lQ^Q_Krt7Ly_^4Y2gS`i8dI$B7O2TeZvnwx@=Y!k`E ztoAn3Xg4(FCwT6c0le!Od*?Uev2s?V8iF3i&O~~O@+z|Q47^`5cIn$$c@>NA1W#!# zW7AndilOO=2lm#4!|h>mlsa(tJM5{R%8G29A8K8m%2)-FD#*<9rHJzR9tGu&XTbdpw!z5{VY>b_n ztmyD()#(SM*kxj{u7P*QO`s4jv;>x(=Hfib~v6LI+XW@t9 z`Y*fkY8_I)VQigh_5}S9%?qtw)7t4|tOT-EgP}}H&u3X$$gi-`{T`0H8ccOZDp}Ku zP@w4Nn6`_4IkJTm$L?W*GVxBStri+Ewy`ILWhY&SbW3mSY<}L|tXP;ko!MAccH(x+ z7x5kyCsY~RkbqP#0biMb(hzEE_mVg*K;myArrdth(Uh=fF2Pq!)JmsxS$kFc;}UWQ z3HsiI;*m;aq(=z2ZUTBFDNgGmu{K6LO^W+S9I>Er_{@wYlDd-+WgJi@f&Bzn#{oVG z3=uHV1eBU)dMc7Q<0OfbO>sQaa;blT02cufdGL$v=1H##hNWHE6@t^p+1)AaEJ@of zlTAR6BP+~ECUJIL?6JptuWw93FXeGd51n!oPrIqr(a+M7Bf~mgXyS4E(h+;Fj!zwj zPaDAlI_@2Z8^>G559+vY9B!Oi!XuZubcMUdDHx|yI_T5!874l_+;;i{Rw`I^g@CD$ zG_qZ0tqiVO5t1rHx=M|y;xK(QhNIu4+g7=BxXy&*JunWpH1F5(hB)3-Esw_ZBswnZ zlWyF&5!vCFC#UuMISVDd=|Wm}SQvYT8^XVn-~>N7=Hi2Cwy=Cm`jS|J6y>a?MoGPjz55(!ZIDI2duf%ByZExvkOPt2vW(mnYBu$SKZN5>`yeTUh^kjj*I{J)fspUlUKc1|}4a%9Z z_x?0h63csSg~VS6hSwnrH4sGQaOmTjz(j!#flh&Q1YQ#OwZIgCp9xGAm?rRyz-EDi z0viRsEAXhmV*+0gI9uRH0_z2SBJh;Jdj+l(xLn}xLs(pZCArxRNA1#oBy-NJ`=q}12lp(x@h## zutsr}odMgo-MimL% zlgq3;RdGAe$}^N7-9#KphF!^YMwp9dD*M5$ybg&hkEc<)3Y1+LNTw}` z$mL*HWTc=jUZm_Qjn_065@iNm@q#FWM%G8o=`)(MfEv>`(wKfqt)Eg`LS+UaLkY>W zYLym9C9zHM_Eq>dXhWQCv{5o4qxDi3b!$k#BPBtudaM!3QPxw>IXZx!L6!L3>A=R ztBPiqZHz31463jSJh6IIaakY0abV9v1%1=cj9TDR4vhY28v;ww0Dz@xfWXo;P=UGW z*#;~_0~@eRjr_AL4HALnXy5>rtAP_(z6L443N%OsRzzDFSg}TVFc0l_V386HGJ%z9 zkOizPk24i3%GYX;1FU>la?>mND0(i?SDIuir}t=(4{Ulsax*KpYfu2JGAKF!%%d6< z0h`$+xhntH8db{teUhuLifP~hR%Ml3ZS`^uN`O@lMI<}Bb{)ki1y<{lZ2jyG4a$Jc z?w8!0`eXvjfz?|$HDU2YIkRLrFHhIkljYozt z!aSA8H3fPph8E!)e7e$Ia_*TS=cni8pvJd+H!t5HeuGpQq~0L(=-|&@wSXr@<6B?b zH+bOC;UlL`FFa%?_VAJO7neXGRYc5W*hi{cuc?@*@#o(B`12op@CelCLF;&g;%#q` z%nl!@r1A&*YiBnS{0Q+I#QVKK@=Zp_*#2aBxpE>(k9b}U6zSDIe zlO8-%M~`fcA2?elUx54&;j*T~=j$Ms=#h&dJ${QG|7e?Jjup}_)%b@-N#yeU#X4w! zxv&5h8PUgzmH_2IzRq9l)_rY~^Vhv{{&`y>|~0gl1?6VZYI$};%yF%k7lt1f)Ii>+Bs6%ruVmjs0=ojXg<*eL<@*60xCpk z+^`uSX%R`6P$hKxrJL7DRE!aWIj(2*ft=S-_-az^21QS~8&2xrr*iIte;VYRB+rwo z+*CVZ8=XT*3-#P~6P-myCeGIg7h{7Tenzw7Jc=V zy7+qf?~0{!yE>WMMK-r%HqVcxbAN0yjXdrb%;7BL#cCnn5cBe-S**nAat>*6>y9ueYi$J+RZ zG(MsAC$Memo2

') TabOrder = 5 @@ -97,11 +104,10 @@ object Form1: TForm1 end object Edit1: TEdit Left = 390 - Top = 131 + Top = 198 Width = 185 Height = 21 TabOrder = 9 - Text = 'Edit1' end object Button6: TButton Left = 8 @@ -129,8 +135,8 @@ object Form1: TForm1 OnClick = Button7Click end object Edit2: TEdit - Left = 215 - Top = 219 + Left = 390 + Top = 171 Width = 161 Height = 21 TabOrder = 13 @@ -152,6 +158,8 @@ object Form1: TForm1 Email = 'nmdsoft@gmail.com' Service = blogger OnAutorization = GoogleLogin1Autorization + OnAutorizCaptcha = GoogleLogin1AutorizCaptcha + OnError = GoogleLogin1Error Left = 584 Top = 56 end diff --git a/Demo/blogger_api_demo/Unit1.pas b/Demo/blogger_api_demo/Unit1.pas index 4fab0b4..e23a9ae 100644 --- a/Demo/blogger_api_demo/Unit1.pas +++ b/Demo/blogger_api_demo/Unit1.pas @@ -4,7 +4,7 @@ interface uses Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms, - Dialogs, StdCtrls, BloggerApi, uGoogleLogin, ComCtrls; + Dialogs, StdCtrls, BloggerApi, uGoogleLogin, ComCtrls, ExtCtrls; type TForm1 = class(TForm) @@ -24,6 +24,7 @@ TForm1 = class(TForm) ProgressBar1: TProgressBar; Button7: TButton; Edit2: TEdit; + Image1: TImage; procedure Button1Click(Sender: TObject); procedure GoogleLogin1Autorization(const LoginResult: TLoginResult; Result: TResultRec); procedure Button2Click(Sender: TObject); @@ -35,6 +36,8 @@ TForm1 = class(TForm) procedure ComboBox1Change(Sender: TObject); procedure Blogger1Progress(aCurrentProgress, aMaxProgress: Integer); procedure Button7Click(Sender: TObject); + procedure GoogleLogin1Error(const ErrorStr: string); + procedure GoogleLogin1AutorizCaptcha(PicCaptcha: TPicture); private { Private declarations } public @@ -63,6 +66,8 @@ procedure TForm1.Button1Click(Sender: TObject); begin GoogleLogin1.Password:=Edit2.Text; GoogleLogin1.Login; + if Edit1.Text<>'' then + GoogleLogin1.Captcha:=Edit1.Text; end; procedure TForm1.Button2Click(Sender: TObject); @@ -165,12 +170,26 @@ procedure TForm1.GoogleLogin1Autorization(const LoginResult: TLoginResult; Resul var i:Integer; begin - Blogger1.Auth:=Result.Auth; - Blogger1.RetrievAllBlogs; - Memo1.Lines:=Blogger1.Blogs.Items[1].СategoryBlog; + if LoginResult=lrOk then + begin + Blogger1.Auth:=Result.Auth; + Blogger1.RetrievAllBlogs; + if Blogger1.Blogs.Count=0 then + Exit; + Memo1.Lines:=Blogger1.Blogs.Items[1].СategoryBlog; + for I := 0 to Blogger1.Blogs.Count - 1 do + ComboBox1.Items.Add(Blogger1.Blogs.Items[i].Title); + end; +end; - for I := 0 to Blogger1.Blogs.Count - 1 do - ComboBox1.Items.Add(Blogger1.Blogs.Items[i].Title); +procedure TForm1.GoogleLogin1AutorizCaptcha(PicCaptcha: TPicture); +begin + Image1.Picture:=PicCaptcha; +end; + +procedure TForm1.GoogleLogin1Error(const ErrorStr: string); +begin + ShowMessage(ErrorStr); end; end. diff --git a/packages/BloggerApi.pas b/packages/BloggerApi.pas index a558463..035478b 100644 --- a/packages/BloggerApi.pas +++ b/packages/BloggerApi.pas @@ -20,6 +20,7 @@ interface rsErrorNotTolken='Нет толкена google для работы с сервисом'; rsErrorNotSelectBlog='Блог не выбран! Смотри property CurrentBlog'; rsErrorIdPost='Не указан Id сообщения в блоге'; +rsErrorIsEmpty='Данные от сервера не были получены'; rsErrorGet='Произошла сетевая ошибка при получении данных c сервера'; rsErrorDelete='Произошла сетевая ошибка при выполнении запроса Delete'; @@ -478,6 +479,12 @@ procedure TBlogger.RetrievAllBlogs; FBlogs.Clear;//очистка блогов перед получением нового списка FXMLDoc.Clear; FXMLDoc.ReadFromString(GetUrl(cnsBlogDefault,'','get',FAuth,'')); + //проверка на наличие данных + if FXMLDoc.IsEmpty then + begin + ToError(rsErrorIsEmpty); + Exit; + end; //проверка на существование коллекции if not Assigned(FBlogs) then Exit; try @@ -524,9 +531,14 @@ function TBlogger.RetrievAllComments: TCommentCollection; ToError(rsErrorNotTolken); Exit;////////ИСПРАВИТЬ!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! end; + //проверка на наличие данных + if FXMLDoc.IsEmpty then + begin + ToError(rsErrorIsEmpty); + Exit; + end; Nodes:=TXmlNodeList.Create; - FXMLDoc.Root.FindNodes(cnsEntry,Nodes);// for i := 0 to Nodes.Count-1 do begin @@ -572,10 +584,22 @@ function TBlogger.RetrievAllPosts: TPostCollection; if FCurrentBlog>-1 then FXMLDoc.ReadFromString(GetUrl(cnsPostBlogStart+Blogs.Items[FCurrentBlog].FBlogId+cnsPostBlogEnd,'','get',FAuth,'')) else + begin ToError(rsErrorNotSelectBlog); + Exit; + end; end else + begin ToError(rsErrorNotTolken); + Exit; + end; + //проверка на наличие данных + if FXMLDoc.IsEmpty then + begin + ToError(rsErrorIsEmpty); + Exit; + end; Nodes:=TXmlNodeList.Create; FXMLDoc.Root.FindNodes(cnsEntry,Nodes); @@ -620,10 +644,22 @@ function TBlogger.RetrievPostForTextParams(Parametrs:string): TPostCollection; if FCurrentBlog>-1 then FXMLDoc.ReadFromString(GetUrl(cnsPostBlogStart+Blogs.Items[FCurrentBlog].FBlogId+cnsPostBlogEnd+parametrs,'','get',FAuth,'')) else + begin ToError(rsErrorNotSelectBlog); + Exit; + end; end else + begin ToError(rsErrorNotTolken); + Exit; + end; + //проверка на наличие данных + if FXMLDoc.IsEmpty then + begin + ToError(rsErrorIsEmpty); + Exit; + end; Nodes:=TXmlNodeList.Create; FXMLDoc.Root.FindNodes(cnsEntry,Nodes);