“Google API в Delphi” Проект, открытый для всех

altНачалось все с того, что одним прекрасным зимним днем у меня напрочь пропали всякие идеи на тему программирования в Delphi. До того момента все как-то шло гладко – всегда находилась интересная мне тема, которую я старался разобрать и поделиться своими решениями и идеями в блоге. Что было делать теперь, когда темы исчерпали себя, а новых нет?

Я решил поинтересоваться у читателей, что было бы им интересно увидеть в блоге. И один из наиболее активных читателей и критиков (в хорошем смысле этого слова) как бы вскользь упомянул о том, что было бы неплохо переложить на Delphi API Яндекс.Спеллера (проверка орфографии). Сказано – сделано. Опубликовал пост на эту тему у себя в блоге. Сам по себе API оказался простым, но именно опубликованный пост, а точнее комментарии читателей к нему, и стали отправной точкой для проекта о котором я и хочу рассказать сегодня – о проекте «Google API в Delphi».

Официальной датой старта проекта можно считать 06.03.2010, когда была зарегистрирована закрытая группа обсуждений в Google, содержащий все исходники, имеющиеся у меня на руках в тот момент. Не могу сказать, что работа в проекте кипела и некуда было складывать новые модули. Скорее всего сказалась моя тогдашняя сумасшедшая занятость на основной работе и если и писал что-то на Delphi, то это было что-то небольшое по объему, чтобы сильно не отвлекаться, но и не расслабляться.

Пример реализации Google API в Delphi

В качестве примера того, что разрабатывается нами в проекте можно продемонстрировать использование API Контактов. В целом работу с API можно представить в виде следующих последовательных шагов:


Аналогичная схема работы присутствует при работе практически с каждым API Google, изменяется только третий шаг – парсинг. На этом шаге используется всегда модуль для GData API, т.к. это основа всех API и без него просто никуда не деться, но изменяются модули для обработки и представления специфичной информации, например, как в нашем случае – специфичной информации по контактам.

Для реализации представленной выше схемы мы используем, разработанный модуль GContacts.pas, в котором определены следующие основные типы данных:

• TContactGroup – группа контактов. Содержит всю служебную информацию по группе, название группы и её тип (системная или определенная пользователем)

• TContact – контакт. Содержит всю информацию, относящуюся к конкретному контакту пользователя.

• TGoogleContact – содержит сведения по всем контактам и группам пользователя, а также свойства и методы для управления контактами. Основной класс для работы с API.
Также в модуле определены все типы данных, позволяющие хранить и обрабатывать информацию по определенным свойствам контакта, например, класс:

TcpRelation = class
private
FValue: string;
FLabel: string;
FRealition:TRelationType;
function GetRelStr(aRel:TRelationType):string;
public
constructor Create(const ByNode: TXMLNode=nil);
procedure Clear;
function IsEmpty:boolean;
procedure ParseXML(const Node: TXmlNode);
function AddToXML(Root: TXmlNode):TXmlNode;
property Realition:TRelationType read FRealition write FRealition;
property Value: string read FValue write FValue;
end;
Определяет такое свойство «Контакт контакта», т.е. сведения о человеке с которым поддерживает связь Контакт пользователя. Используя этот класс можно:

1. Получить имя или email этот человека

2. Определить, кем он приходится для нашего Контакта (брат, сестра, дед и т.д.) – для этого служит свойство Realition.

3. Корректно записать все сведения в XML-документ при отправке контакта на сервер – метод AddToXML.

4. Корректно разобрать XML-узел в документе, который содержит необходимую нам информацию – метод ParseXML.

5. Проверить класс на полноту данных. Если метод IsEmpty возвращает false, то либо в классе не определено какое-то значимое свойство, без которого Google не примет документ, либо класс вообще не содержит сведений.

6. Очистить полностью все поля класса и, тем самым при обновлении контакта удалить эти сведения с сервера.

Аналогичным образом определены и другие вспомогательные классы и типы данных, что избавляет нас от необходимости лишний раз лезть в «сырой» XML-документ и искать что-либо – все делается вызовом одного метода (пример см. ниже) без прямого использования парсинга XML со стороны пользователя в принципе.

Если представить все связи в модуле графически, то получится примерно следующая схема:


Схема, конечно, упрощена, т.к. не показана связь с GData API и т.д., но суть та же – все сводится к использованию одного класса, который предоставит пользователю модуля всё, что требуется в удобном виде.

Используя модуль, в настоящее время можно осуществить следующие операции по работе с Google Contacts API:

1. Получение сведений о контактах в целом, включая удаленные не позднее чем 90 дней назад, либо частично, например, только контакты, добавленные не позднее определенной даты. При этом можно определить размер принимаемого документа, который измеряется количеством записей о контактах в нем, например, «попросить» Google отправлять нам все контакты частями по 5 штук в документе.

2. Парсинг XML-документа. При этом для каждого контакта определяется до 19 различных параметров, начиная от таких распространенных, как Ф.И.О. и, заканчивая такими, как круг общения контакта, адреса, телефоны, явки и т.д.

3. Сохранение и загрузка локальной копии контактов из файла.

4. Группировка контактов по группам.

5. Изменение сведений о контакте и отправка данных в Google.

6. Ведение лога всех операций. Например, можно узнать размеры всех принимаемых документов и адреса откуда эти документы были получены.

Вот пример, как с помощью TGoogleContact можно получить документ, содержащий сведения о контактах:

Contact:=TGoogleContact.Create(self, FAuth, GmailAkk); //создали экземпляр, передав в параметрах ключ Auth и адрес Gmail-почты
Contact.MaximumResults:=10; //получаем по 10 контактов в документе
Contact.StartIndex:=3; //начинаем получение с третьего по номеру контакта
Contact.SortOrder:=TS_None; //оставляем сортировку на усмотрение Гугла
Contact.ShowDeleted:=true; //просим выслать информацию по удаленным контактам
Contact.RetriveContacts; //получаем контакты
Все что от нас требуется после выполнения метода RetriveContacts – это немного терпения пока прибудут все контакты. А чтобы не смотреть на уныло зависшую форму приложения можно определить события TGoogleContact:

TParseElement = (T_Group, T_Contact);
//события компонента
TOnRetriveXML = procedure (const FromURL:string) of object; //срабатывает перед началом закачки
TOnBeginParse = procedure (const What: TParseElement; Total, Number: integer) of object;//срабатывает перед тем как начнется парсинг элемента
TOnEndParse = procedure (const What: TParseElement; Element: TObject) of object;//срабатывает после успешного парсинга XML-элемента
TOnReadData = procedure (const TotalBytes, ReadBytes: int64) of object;//срабатывает каждый раз при получении информации из Сети
К примеру, если определить все события, то можно получить вот такой лог работы программы:


Естественно, никто не запрещает Вам, например на OnReadData заполнять ProgressBar или выполнять иные действия.

Для работы с изображением, которое определено для контакта, в TGoogleContact также имеются свои методы. Например так:

Contact.RetriveContactPhoto(Selected, ‘noimage.jpg’)
Здесь мы попросили загрузить изображение для контакта Selected и, если этот контакт не имеет своего изображения, то показать дефолтное.

На момент написания этой статьи я заканчиваю создание демонстрационного проекта, реализующего всю работы с Контактами в Google с использованием приведенного выше модуля. Думаю, что когда выйдет журнал, проект уже будет полностью готов.

Возвращаясь к началу статьи, а именно к её названию, в заключение хочется сказать, что проект «Google API в Delphi» всегда был, есть и будет бесплатным и открытым для всех желающих. Может быть поэтому я и согласился перевести проект под управление Git, которая, кстати сказать, была разработана в свое время Линусом Торвальдсом. Just For Fun

Понравилась статья? Поделиться с друзьями: