Про статистику FeedBurner я уже упоминал несколько раз в блоге. Первый раз я рассказывал о том, как получить количество подписчиков, второй — про работу со статистикой и даже выложил в доступ небольшой модуль для работы со статистикой. По сути модуль содержит ряд функций для получения тех или иных данных по RSS-каналу.
На этот раз я решил доработать этот модуль и сделать небольшой комопнент, который будет максимально быстро и удобно предоставлять пользователю всю возможную информацию, получаемую программой с помощью Awareness API, ну и, как следствие, немного расширить репозиторий проекта «Google API в Delphi«.
Введение
Вначале немного общих сведений о работе компонента.
Во-первых, т.к. компонент активно работает с XML-документами, то, как и везде в проекте «Google API в Delphi«, компонент использует модуль NativeXML.pas из одноименной библиотеки.
Во-вторых, компонент использует в своей работе потоки — минимум один, максимум — 10. В основном использование потоков было введено для по двум причинам:
1. Максимально полно предоставлять информацию по статистике фида. Дело в том, что никто не запрещает нам в запросах к API использовать в качестве параметра dates интервалы (непрерывные и дескретные) и, таким образом, получить статистику, скажем, за полгода в одном XML-документе. Однако, если в интервале будет допущено ошибка, например, в интервале будет содержаться дата за которую статистика по каналу отсутствует, то мы сразу по всем датам получим ошибку. В компоненте всякий интервал разбивается на отдельные даты и по каждой дате получаем отдельный XML, который затем разбирается и данные поступают в общий список. Таким образом если даже в, не дай бог, в середине интервала попадется «нехорошая» дата — компонент обработает исключение API и продолжит сбор статистики по остальным датам.
2. Обхода неприятной ситуации при работе с API. Ситуация эта касается следующего — когда задается интервал дат сервер не возвращает заголовок Content-Length. И эта ситуация не для меня не только неприятна, но и в целом непонятна. Задаем одну дату — всё в порядке, две — заголовка нет. Пробовал все известные варианты отправки запроса, разные библиотеки (wininet, synapse, ics, indy), просматривал заголовки в FF — нифига. Нету заголовка. А нет заголовка, следовательно, становится неизвестно сколько «на том конце провода» данных. Учитывая, то, что при запросе рефераллов фида XML-документ может иметь довольно внушительный размер, даже для владельцев скоростных безлимитов, сей неприятный момент может вызвать долгие минуты ожидания пока программка «отвиснет». С потоками все проще — интерфейс не замирает, по каждой дате данные приходят достаточно быстро, можно визуализировать процесс закачки и т.д.
Теперь, что касается самого компонента.
Свойства компонента
property APIMethod: TOperation read FAPIMethod write FAPIMethod;
Свойство, определяющее уровень статистики. Определяет метод API, который будет использоваться в потоках. Если проанализировать, то, что выдает нам сервер по трем запросам: GetFeedData, GetItemData и GetResyndicationData, то можно увидеть, что каждый метод по сути делает возможным получение более полной статистики. Например, GetFeedData выдает общие сведения по фиду (количество подписчиков, охват аудитории, количество кликов и т.д.), GetItemData — выдает всё то, что и GetFeedData плюс данные по элементам фида в отдельности, например, заголовок сообщения, количество кликов по заголовку и т.д. И, наконец, GetResyndicationData предоставляет самую полную статистику, которая включает всё, что касается GetFeedData и GetItemData, а также информацию по тому, какие из элементов вашего канала использовались в сторонних фидах (рефералах) и какое количество переходов было с этих каналов.
Соответственно от того, какое значение примет свойство APIMethod (toGetFeedData, toGetItemData, toGetResyndicationData) будет зависеть объем данных, которое компонент получит, а равно и время затраченное на обработку данных и т.д.
property FeedURL: string read FFeedURL write SetFeedURL;
URL канала статистику которого необходимо получить. Например, URL моего канала выглядит так:
http://feeds.feedburner.com/myDelphi
property SilentAPI: boolean read FSilent write FSilent;
«Тихая» обработка исключений API. Всего API предоставляет нам шесть различных сообщений об ошибках запроса (не найден фид, отсутствует URI и т.д.). По большому счёту эти ошибки не приводят к каким-либо нежелательным последствиям в программе — ничего не рушится, не переполняется и т.д. Поэтому, если Вы не хотите, чтобы компонент прерывал свою работу при таких исключениях, а просто пропускал неудачный запрос и продолжал сбор статистики, то установите значение этого свойства в true.
property MaxThreads: byte read FMaxThreads write SetMaxThreads;
Максимальное количество одновременно запущенных потоков. Максимум 10, минимум 1.
property TimeLine : TTimeLine read FTimeLine write SetTimeLIme;
Коллекция, которая используется для задания временных интервалов за которые необходимо получить статистику. Каждый элемент коллекции содержит три свойства:
- RangeType: TRangeType — тип заданного интервала:
- trSingle — одиночная дата. При этом StartDate=EndDate;
- trDescrete — дискретный интервал. Проще говоря, таким образом, в компоненте задаются две даты — StartDate и EndDate
- trContinued — непрерывный интервал. Статистика будет собираться по всему интервалу дат от StartDate до EndDate включительно.
- StartDate: TDate — начальная дата интервала
- EndDate: TDate — конечная дата интервала.
При работе с этим свойством можно не задумываться о том, чтобы временные интервалы не пересекались. Например, если будут заданы такие интервалы:
- от 12.01.2010 до 17.01.2010
- от 12.01.2010 до 22.01.2010
то при сборе статистики компонент составит список не повторяющихся дат и Вы в итоге получите статистику за интервал от 12.01 до 22.01, избежав повторных запросов по пересекающимся датам.
property FeedData:TEntryCollection read FFeedData;
Данные по статистике канала.
События компонента
property OnAPIRequestError:TOnAPIRequestError; TOnAPIRequestError = procedure (const Code:integer; Error: string) of object;
При SilentAPI=true возвращает код ошибки API и её текст, переведенный на язык пользователя (в нашем случае — на русский язык).
property OnProgress:TOnProgress; TOnProgress = procedure(const Date: TDate; ThreadIdx:byte; ProgressCurrent,ProgressMax:int64) of object;
Параметры:
Date: TDate — дата за которую получаются данные;
ThreadIdx:byte — номер потока, который обрабатывает запрос;
ProgressCurrent: int64 — количество принятых байт данных;
ProgressMax:int64 — количество байт, которое необходимо получить.
property OnParseElement: TOnParseElement; TOnParseElement = procedure (Item:TBasicEntry) of object;
Возвращает последний полученный элемент статистики. Удобно использовать для непрерывного вывода данных пользователю при работе компонента.
property OnThreadStart: TOnThreadStart; property OnThreadEnd:TOnThreadEnd; TOnThreadStart = procedure (ThreadIdx:integer; Actives:byte) of object;
Возвращают индекс стартовавшего или закончившего работу потока соответственно, а также общее количество запущенных в данный момент потоков.
property OnDone : TOnDownload; TOnDownload = TNotifyEvent;
Срабатывает после получения всех данных, когда количество запущенных потоков равно нулю и достигнут конец списка дата.
Методы компонента
У компонента всего два метода (помимо конструктора и деструктора).
procedure Start; procedure Stop;
Собственно, названия говорящие — первый метод запускает потоки компонента в работу, второй — может потребоваться для аварийной остановки потоков.
Структура статистики. TBasicEntry
По большому счёту TBasicEntry предоставляет статистику практически в том же виде, что и API — вся статистика делится на три большие коллекции:
верхний уровень TBasicEntry содержит следующие свойства:
property Date: TDate read FDate;
Дата за которую получена статистика.
property Circulation: integer read FCirculation;
Количество подписчиков канала в этот день.
property Hits: integer read FHits;
Количество запросов данных канала.
property Reach: integer read FReach;
Охват аудитории.
property Downloads: integer read FDownloads;
Количество закачек файлов (если таковые имелись в элементах канала).
Второй уровень статистики (свойство FeedItems у TBasicEntry)
Каждый элемент содержит следующие свойства:
property Title: string read FTitle;
Заголовок элемента фида (поста).
property URL: string read FURL;
URL этого элемента.
property ItemViews: integer read FItemViews;
Количество просмотров этого элемента.
property ClickThroughs: integer read FClickThroughs;
Количество просмотров этого элемента пользователями и ботами.
Третий уровень статистики (свойство Referrers у FeedItems).
Предоставляет информацию об использовании элементов фида другими службами, сайтами, блогам и т.д. Каждый элемент содержит следующие свойства:
property URL: string read FURL;
URL на котором использовался элемент вашего канала (URL реферала)
property ItemViews: integer read FItemViews;
Количество просмотров элемента у реферала.
property ClickThroughs: integer read FClickThroughs;
Количество запросов элемента у реферала.
От того, какой значение примет свойство APIMethod у компонента зависит насколько полно будет заполнена коллекция TBasicEntry.
В качестве примера, можно рассмотреть такой обработчик события OnParseElement компонента:
procedure TForm6.ItemChangeEvent(Item: TBasicEntry); var i,j: integer; begin Memo2.Lines.Add('----------'+DateToStr(Item.Date)+'----------'); Memo2.Lines.Add('---------- Circulation: '+IntToStr(Item.Circulation)+'----------'); for i := 0 to Item.FeedItems.Count - 1 do begin Memo2.Lines.Add('Title: '+Item.FeedItems[i].Title); for j:= 0 to Item.FeedItems[i].Referrers.Count - 1 do begin Memo2.Lines.Add(' Referrer: '+Item.FeedItems[i].Referrers[j].URL); Application.ProcessMessages; end; end; end;
Здесь в Memo выводится часть статистики по всем трем уровням:дата, количество подписчиков, заголовок элемента канала и URL реферала.
Если установить у компонента свойство APIMethod как:
APIMethod:=toGetResyndicationData
То после получения статистики Memo2 будет содержать, например, такие данные:
Теперь, не меняя ничего в обработчике события изменяем свойство:
APIMethod:=toGetFeedData
Снова запускаем программу на выполнение и Memo уже будет содержать данные только по верхнему уровню статистики:
Ну и, наконец, для поиска элемента статистики по дате можно использовать метод:
TFeedBurner = class(TComponent) ... FeedData.IndexOf(Date: TDate):integer; ...
Метод IndexOf возвращает индекс элемента в коллекции FeedData по дате, либо, если такой элемент отсутствует -1.
Скачать компонент можно в нашем репозитории на странице закачек.
Книжная полка
Описание: Рассмотрены практические вопросы по разработке клиент-серверных приложений в среде Delphi 7 и Delphi 2005 с использованием СУБД MS SQL Server 2000, InterBase и Firebird. Приведена информация о теории построения реляционных баз данных и языке SQL. Освещены вопросы эксплуатации и администрирования СУБД.
|
||
Название: О чем не пишут в книгах по Delphi
Описание: Рассмотрены малоосвещенные вопросы программирования в Delphi. Описаны методы интеграции VCL и API. Показаны внутренние механизмы VCL и приведены примеры вмешательства в эти механизмы. Рассмотрено использование сокетов в Delphi: различные режимы их работы, особенности для протоколов TCP и UDP и др.
|