В одном из своих постов, посвященных работе с Synapse я рассматривал отправку нескольких документов одним POST-ом. В качестве примера работы я взял часть Google Docs API, а именно — загрузку документа на сервер. Сегодня я решил немного продолжить тему работы с этим API и рассказать о том, как получить список всех документов на сервере.
Теория
Для того, чтобы получить список всех документов на сервере необходимо:
1. Авторизоваться. Для нашего приложения используется интерфейс ClientLogin, реализацию которого в Delphi Вы можете скачать здесь (компонент GoogleLogin).
2. Отправить GET на URL: https://docs.google.com/feeds/default/private/full включив в заголовки версию протокола (на данный момент — 3.0.) и маркер Auth, полученный в результате авторизации.
3. Разобрать элементы entry полученного XML-документа.
4. Вывести список пользователю.
Реализуем этот простой алгоритм — допишем, рассмотренное в посте приложение (ссылка на скачивание). Загружайте исходники приложения, открывайте проект в Delphi и приступим.
Практика
Первым делом, определимся какую именно информацию нам необходимо хранить. Пусть это будет следующая информация о документе:
1. Название
2. ID ресурса — используется, если необходимо обновить контент документа или скачать его и т.д.
3. Даты создания, обновления и последнего просмотра
4. Etag документа — как и ID используется при обновлении контента документа.
Для работы с XML воспользуемся NativeXML, а для работы с HTTP протоколом, как обычно, Synapse. Поэтому подключаем в uses главного модуля программы модули NativeXML.pas и httpsend.pas.
Для хранения информации о документе будем использовать следующий тип данных:
type TDocInfo = class private FTitle : string; FResourceID: string; FEtag: string; FPublish: TDateTime; FUpdated : TDateTime; FLastViewed : TDateTime; procedure SetEtag(const Value: string); procedure SetLastViewed(const Value: TDateTime); procedure SetPublish(const Value: TDateTime); procedure SetResourceID(const Value: string); procedure SetTitle(const Value: string); procedure SetUpdated(const Value: TDateTime); function ToDate(const Str:string):TDateTime; public constructor Create(aXML: TXMLNode); property Title : string read FTitle write SetTitle; property ResourceID: string read FResourceID write SetResourceID; property Etag: string read FEtag write SetEtag; property Publish: TDateTime read FPublish write SetPublish; property Updated : TDateTime read FUpdated write SetUpdated; property LastViewed : TDateTime read FLastViewed write SetLastViewed; end;
Чтобы не забивать пост излишним описанием методов, скажу следующее — копируете этот код в главный модуль программы устанавливаете курсор в любое место описания типа данных и жмете Ctrl+Shift+C — получите готовые методы Set… для записи полей, точно такие же как и у меня в готовой программе. Остается только дописать конструктор и метод ToDate. Начнем со второго. Метод ToDate переводит дату вида 2010-06-06T13:42:56.887Z в TDateTime.
function TDocInfo.ToDate(const Str: string): TDateTime; var FormatSet: TFormatSettings; begin GetLocaleFormatSettings(LOCALE_SYSTEM_DEFAULT, FormatSet); with FormatSet do begin DateSeparator := '-'; TimeSeparator := ':'; ShortDateFormat := 'yyyymmdd'; ShortTimeFormat := 'hhmmss'; Result := StrToDateTime(Str, FormatSet); end; end;
В конструкторе напишем следующее:
constructor TDocInfo.Create(aXML: TXMLNode); begin inherited Create; if aXML=nil then Exit; FTitle:=aXML.NodeByName('title').ValueAsUnicodeString; FResourceID:=aXML.NodeByName('gd:resourceId').ValueAsUnicodeString; FPublish:=ToDate(aXML.NodeByName('published').ValueAsUnicodeString); FUpdated:=ToDate(aXML.NodeByName('updated').ValueAsUnicodeString); FLastViewed:=ToDate(aXML.NodeByName('gd:lastViewed').ValueAsUnicodeString); FEtag:=aXML.AttributeByName['gd:etag']; end;
То есть, если определен узел XML, содержащий данные о документа, то сразу заполним все поля класса. Для хранения информации о всех документах можно воспользоваться, например списком TList:
type TDocList = TList;
В последствии можно будет легко дописать необходимые методы чтения/записи и т.д. А мы пока приступим к тестированию нашей программы.
Добавим на главную форму компонент TMemo для вывода информации и TButton для выполнения запроса. Обработчик OnClick кнопки напишем следующий:
procedure TForm6.Button4Click(Sender: TObject); var HTTP: THTTPSend; Doc: TNativeXML; DocList: TDocList; List:TXmlNodeList; i:integer; begin try HTTP:=THTTPSend.Create; //вставляем заголовки авторизации HTTP.Headers.Add('GData-Version: 3.0'); HTTP.Headers.Add('Authorization: GoogleLogin auth='+Edit3.Text);//всавляем Auth if HTTP.HTTPMethod('GET','http://docs.google.com/feeds/default/private/full') then begin Doc:=TNativeXml.Create; Doc.LoadFromStream(HTTP.Document); DocList:=TDocList.Create; List:=TXmlNodeList.Create; Doc.Root.NodesByName('entry',List); for I := 0 to List.Count - 1 do begin DocList.Add(TDocInfo.Create(List[i])); Memo1.Lines.Add(DateTimeToStr(TDocInfo(DocList[i]).Publish)+' '+ TDocInfo(DocList[i]).Title+' '+ TDocInfo(DocList[i]).Etag); end; end else Memo1.Lines.Add(HTTP.ResultString); finally FreeAndNil(Doc); FreeAndNil(List); FreeAndNil(DocList); FreeAndNil(HTTP) end; end;
Запустите приложение, авторизуйтесь и проверьте, что список документов исправно загружается. В приведенном выше примере работы со списком документов мы упустили один момент — не определили какой тип у документа (текстовый, презентация, таблица и т.д.). Сделать это можно легко — достаточно проанализировать узлы category scheme в XML-документе, но эту часть я оставлю на домашнее задание.
Книжная полка
Описание: Рассмотрены практические вопросы по разработке клиент-серверных приложений в среде Delphi 7 и Delphi 2005 с использованием СУБД MS SQL Server 2000, InterBase и Firebird. Приведена информация о теории построения реляционных баз данных и языке SQL. Освещены вопросы эксплуатации и администрирования СУБД.
|
||
Название: О чем не пишут в книгах по Delphi
Описание: Рассмотрены малоосвещенные вопросы программирования в Delphi. Описаны методы интеграции VCL и API. Показаны внутренние механизмы VCL и приведены примеры вмешательства в эти механизмы. Рассмотрено использование сокетов в Delphi: различные режимы их работы, особенности для протоколов TCP и UDP и др.
|
Вялікае дзякуй!