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

Сегодня решил немного перекурить документацию по Google Celendar API и доделать работу с событиями календаря, а именно: добавить методы редактирования и удаления события.

На самом деле, что при редактировании, что при удалении практически любого элемента entry в Google Data используется в целом один и тот же универсальный алгоритм, состоящий из трех шагов:
1. Определить значение атрибута (или узла, или заголовка) e-tag
2. Определить ссылку для редактирования (то есть пройтись по узлам link в фиде и вытащить ту, что содержит атрибут rel=»edit»)
3. Сформировать запрос и отправить его методом PUT (для редактирования) или DELETE (для удаления) записи.
В свое время я не поленился и создал необходимые типы данных для всех возможных элементов в XML календаря, включая некоторые из Google Data API. В итоге, например, узел, который 100% является текстовым описывается так:

type
  TTextTag = class
  private
    FName: string;
    FValue: string;
    FAttributes: TList;
  public
    Constructor Create(const ByNode: IXMLNode);
    procedure ParseXML(Node: IXMLNode);
    function AddToXML(Root: IXMLNode): IXMLNode;
    property Value: string read FValue write FValue;
    property Name: string read FName write FName;
    property Attributes: TListread FAttributes write FAttributes;
  end;

При этом в метод Create передается непосредственно ссылка на узел в документе и все поля класса заполняются данными на этапе создания. Если же на этапе создания узел в документе не определен, то впоследствии можно использовать метод ParseXML для заполнения полей класса. После этого данные можно читать, редактировать. Если узел необходимо вставить в документ, то вызывается метод AddToXML у которого единственный параметр — родительский узел для нового узла.
Может пример класса представлен не совсем удачно, но с помощью этого примера будет разобраться, что я буду делать при работе с событиями Google Celendar. Кстати, начал писать про календарь и вспомнил о настройках Windows 7 — гаджеты, обои для рабочего стола и т.д. Есть там гаджет «Календарь»…Интересно, можно к нему прикрутить Google Celendar? :) Посмотрим потом, когда более-менее разберемся с API, а пока я буду делать следующее — изменять данные в мероприятии. Каждое мероприятие я определяю как класс:

type
  TCelenrarEvent = class
  private
    Fid: string;
    FEtag: string;
    FAuth: string;
    Fpublished: TDateTime;
    Fupdated: TDateTime;
    FTitle: TTextTag;
    FDescription: TTextTag;
    FLinks: TCelendarLinksList; // ссылки события
    [...]
  public
    constructor Create(const ByNode: IXMLNode; aAuth: string);
    property Etag: string read FEtag;
    property PublishedTime: TDateTime read Fpublished;
    property UpdateTime: TDateTime read Fupdated;
    property title: TTextTag read FTitle write FTitle;
  [...]
end;

Соответственно для обновления мероприятия в календаре нам необходимо изменить содержимое полей класса и отправить изменения на сервер. Пишем метод Update:

procedure TCelenrarEvent.Update;
var
  i: integer;
  aDoc: IXMLDocument;
  Root, Node: IXMLNode;
  tmpURL: string;
begin
  aDoc := NewXMLDocument();
  aDoc.Active := true;
  Root := aDoc.AddChild('entry');
//добавляем пространства имен
  for i := 0 to High(clNameSpaces) do
    Root.DeclareNamespace(clNameSpaces[i, 0], clNameSpaces[i, 1]);
//определяем etag  мероприятия
  Root.Attributes['gd:etag'] := FEtag;
  InsertCategory(Root);
  Node := aDoc.CreateElement('id', clNameSpaces[0, 1]);
  Node.Text := Fid;
  aDoc.DocumentElement.ChildNodes.Add(Node);
  //записываем узлы в документ
  FTitle.AddToXML(Root);
  [...]
  if length(GetEditURL) > 0 then //если ссылка на редактирование обнаружена в фиде
    with THTTPSend.Create do
    begin
      Headers.Add('GData-Version: 2');
      Headers.Add('Authorization: GoogleLogin auth=' + FAuth);
      MimeType := 'application/atom+xml';
      Headers.Add('If-Match: ' + FEtag);
      aDoc.SaveToStream(Document);
      HTTPMethod('PUT', GetEditURL);
      if (ResultCode > 200) and (ResultCode < 400) then
      begin
        tmpURL := GetNewLocationURL(Headers);
        Document.Clear;
        aDoc.SaveToStream(Document);
        Headers.Clear;
        MimeType := 'application/atom+xml';
        Headers.Add('GData-Version: 2');
        Headers.Add('Authorization: GoogleLogin auth=' + FAuth);
        Headers.Add('If-Match: ' + FEtag); //не забываем про заголовок!
        HTTPMethod('PUT', tmpURL);
      end;
    end;
end;

Вот примерно так можно описать метод для обновления мероприятия. Теперь можно загрузить весь список мероприятий календаря, выбрать то, которое необходимо изменить, изменить необходимые поля в классе и отправить изменения на сервер, используя метод Update. Соответственно, если изменить метод отправки данных с PUT на DELETE и не отправлять никакие данные в документе, за исключением etag, то можно удалить мероприятие из календаря.
Теперь осталось собрать все, что сделано для Google Celendar API в Delphi и либо соорудить компонент, либо небольшую библиотеку для работы с календарями.

0 0 голоса
Рейтинг статьи
уважаемые посетители блога, если Вам понравилась, то, пожалуйста, помогите автору с лечением. Подробности тут.
Подписаться
Уведомить о
5 Комментарий
Межтекстовые Отзывы
Посмотреть все комментарии
Алексей
Алексей
24/03/2010 16:44

Очень интересно. А можно как то прикрутиться к задачам в календаре?

Алексей (Минск)
Алексей (Минск)
25/03/2010 15:22

Решил все-таки имя изменить :)))
Нет ли идеи у вас создать единный компонент для работы с google& Готов помочь в реализации

Андрей
Андрей
29/04/2011 11:21

А можно ли как-то по API восстановить удаленное событие?
Удалить его получается двумя способами: через отправку DELETE и через изменения eventStatus на «http://schemas.google.com/g/2005#event.canceled». А вот восстановить никак не получается.