уважаемые посетители блога, если Вам понравилась, то, пожалуйста, помогите автору с лечением. Подробности тут.

Иногда требуется одним POST-запросом отправить на сервер несколько разных по составу и содержанию документов. К примеру, такие действия требуются, когда Вы загружаете на сервер Google какой-либо документ, который должен содержать какую-либо мета-информацию (язык на которой необходимо перевести документ, сведения об авторе и т.д.). В этом случае ваш запрос должен одновременно содержать информацию двух типов: XML с мета-данными и данные отправляемого файла. Как это сделать рассмотрим на примере Google Documents List API.

GoogleLogin API помечен как depricated и не может больше использоваться при разработки приложений, использующих Google API. Для авторизации пользователя необходимо использовать протокол OAuth 2.0 о котором можно узнать здесь

Этот API больше не используется в Google. Актуальный API — Google Drive

Для работы нам понадобится компонент GoogleLogin, последнюю рабочую версию которого Вы можете скачать здесь и, собственно, сама библиотека Synapse. Для обработки XML воспользуемся возможностями NativeXML.
Итак, пишем маленькое приложение, которое загружает на сервер Google документ и в качестве мета-информации отправляет название документа. Размещаем на главной форме компонент GoogleLogin и несколько дополнительных компонентов как показано на рисунке:

Главная форма приложения

и пишем приложение по частям.

1. Авторизация в сервисе «Документы Google»

На данный момент, используя компонент GoogleLogin узнать о результате авторизации можно только через его событие OnAutorization. Поэтому на событие OnClick кнопки «Логин» пишем:

procedure TForm6.Button1Click(Sender: TObject);
begin
  with GoogleLogin1 do
    begin
      Email:=Edit1.Text;
      Password:=Edit2.Text;
      Service:=writely;//идентификатор сервиса гуглодоков
      AccountType:=atHOSTED_OR_GOOGLE;
      Login();
    end;
end;

А в обработчики события компонента проверяем результат (без обработки каптчи):

procedure TForm6.GoogleLogin1Autorization(const LoginResult: TLoginResult;
  Result: TResultRec);
begin
  if LoginResult=lrOk then
    Edit3.Text:=Result.Auth
  else
   Edit3.Text:=Result.LoginStr;
Button2.Enabled:=LoginResult=lrOk;
Button3.Enabled:=LoginResult=lrOk;
end;

После того, как авторизация получена можно отправлять документ на сервер.

2. Формирование запроса и его отправка

Вначале напишем код, который будет составлять XML-документ. Документ должен быть следующего содержания:

<code>
<!--?xml version='1.0' encoding='UTF-8'?-->
 
</code>

Так как изменяться в документе будет всего одна строка — содержимое тега Title, то я просто сохранил этот документ в файл xml.txt и буду этот файл при необходимости изменять. В итоге для составления правильного XML-содержимого запроса сделать необходимо не так уж и много:

var
  Form6: TForm6;
  XMLStream: TMemoryStream;;
...
procedure TForm6.FormCreate(Sender: TObject);
begin
  XMLStream:=TMemoryStream.Create;
end;
 
function TForm6.GetXML(const DocTitle: string): string;
begin
  var XMLDoc: TNativeXML;
begin
  XMLStream.Clear;//очистили поток
  XMLDoc:=TNativeXML.Create;
  XMLDoc.LoadFromFile(ExtractFilePath(Application.ExeName)+'xml.txt');
  XMLDoc.Root.NodeByName('title').ValueAsString:=Edit5.Text;//замненили название документа
  XMLDoc.SaveToStream(XMLStream);//сохранили данные в поток
FreeAndNil(XMLDoc);
end;
 
procedure TForm6.FormDestroy(Sender: TObject);
begin
  FreeAndNil(XMLStream)
end;

Теперь составляем запрос и осуществляем отправку запроса. Для этого подключаем в uses модуль httpsend:

procedure TForm6.Button3Click(Sender: TObject);
Const
  CR = #$0d;
  LF = #$0a;
  CRLF = CR + LF;
var HTTP: THTTPSend;
    S:AnsiString;
    FS: TFileStream;
begin
  //получили XML
  GetXML(Edit5.Text);
 
  HTTP:=THTTPSend.Create;
  //вставляем заголовки авторизации
  HTTP.Headers.Add('GData-Version: 3.0');
  HTTP.Headers.Add('Authorization: GoogleLogin auth='+Edit3.Text);
  //определяем тип данных
  HTTP.MimeType:='multipart/related; boundary=END_OF_PART';
  HTTP.Headers.Add('Slug: '+EncodeURLElement(ExtractFileName(Edit4.Text)));
  {составляем тело запроса}
  S:='--END_OF_PART'+CRLF;
  //MIME-тип первой части документа
  S:=S+'Content-Type: application/atom+xml'+CRLF+CRLF;
  HTTP.Document.Write(PAnsiChar(S)^, Length(S));//записали строку
  //пишем в Document содержимое XML
  XMLStream.Position:=0;
  HTTP.Document.CopyFrom(XMLStream,XMLStream.Size);
  S:=CRLF+CRLF+'--END_OF_PART'+CRLF;//первая часть документа закончена
 
  {вторая часть - документ *.doc}
  S:=S+'Content-Type: application/msword'+CRLF+CRLF;
  HTTP.Document.Write(PAnsiChar(S)^, Length(S));//записали строку
  {записываем doc-файл}
  FS:=TFileStream.Create(Edit4.Text,fmOpenRead);
  FS.Position:=0;
  HTTP.Document.CopyFrom(FS,FS.Size);
  FreeAndNil(FS);
  {завершаем тело запроса}
  s := CRLF + '--END_OF_PART--' + CRLF;
  HTTP.Document.Write(PAnsiChar(S)^, Length(S));//завершили тело документа
 
  //Отправляем запрос
  if HTTP.HTTPMethod('POST','http://docs.google.com/feeds/default/private/full') then
    ShowMessage(HTTP.ResultString);
end;

В этой процедуре мы загружаем в Document (TMemoryStream) данный из двух потоков, разделяя каждую часть специальным разделителем, который, кстати сказать, может быть не только такой как показано в примере. Если отправка завершилась успешно, то в результате выполнения процедуры мы получим сообщение с текстом «201 Created» — документ успешно отправлен и создан на сервере Google.

Книжная полка

Описание: Рассмотрены практические вопросы по разработке клиент-серверных приложений в среде Delphi 7 и Delphi 2005 с использованием СУБД MS SQL Server 2000, InterBase и Firebird. Приведена информация о теории построения реляционных баз данных и языке SQL. Освещены вопросы эксплуатации и администрирования СУБД.
купить книгу delphi на ЛитРес
Описание: Рассмотрены малоосвещенные вопросы программирования в Delphi. Описаны методы интеграции VCL и API. Показаны внутренние механизмы VCL и приведены примеры вмешательства в эти механизмы. Рассмотрено использование сокетов в Delphi: различные режимы их работы, особенности для протоколов TCP и UDP и др.
купить книгу delphi на ЛитРес
0 0 голоса
Рейтинг статьи
уважаемые посетители блога, если Вам понравилась, то, пожалуйста, помогите автору с лечением. Подробности тут.
Подписаться
Уведомить о
8 Комментарий
Межтекстовые Отзывы
Посмотреть все комментарии
Pavel
Pavel
26/08/2010 02:29

А нету ли у Вас примера как отправить файл на определенный сайт (FTP наверное). То есть указать хост, пароль, логин, порт… В примерах, идущими вместе с Synapse так и не разобрался. С получением файла проблем нет, а вот с отправкой, пока не понятно.

Денис
Денис
11/04/2012 17:07

Привет. Я установил компонент для логинирования в Google Dock, но после помещения его на форму и дальнейшей компиляции получаю ошибку:
[DCC Fatal Error] main.pas(7): F1026 File not found: ‘uGoogleLogin.dcu’
Что можете сказать по этому поводу?
Спасибо.

Денис
Денис
11/04/2012 18:27

Благодарю за оперативность :)
 

Тарас
Тарас
13/12/2014 17:56

В гугл все-равно не удается залогиниться с этого приложения — «Не удалось распознать имя пользователя или пароль, использованные в запросе на вход». С-ма безопасности гугла блокирует возможность логина с неизвестных ему приложений. Причем у меня даже после отключения этой проверки, все-равно прога не логинится в гугл