Delphi programming blog
Источник: http://teran.karelia.pro/articles/item_4436.html
 

myshows.ru API & delphi

Опубликовано 27.08.2010 г. 00:14

В прошлом посте я написал, что хочу попробовать написать одно клиентское web-приложение, для чего мне понадобилось разузнать как вычисляется md5 хэш (: За последние 3 или 4 дня это приложение стало обретать какие то черты.

О чем вообще пойдет речь в данной статье? Есть такой сервис как myshows.ru. Суть сервиса такова: люди, которые смотрят сериалы, могут видеть график выхода новых серий, добавлять в списки своего просмотра новые сериалы, там же публикуются ссылки на торренты, наблюдать рейтинг сериалов среди пользователей, добавлять пользователей в друзья, и видеть какие сериалы смотрят они. В общем если ты смотришь какие либо сериалы, и не знаешь по каким дням или как часто они выходят, этот сервис может тебе помочь. По крайней мере это тот функционал ресурса, который мне интересен. Зачем вобще использовать API ресурса, если можно пользоваться им через браузер? В общем то вопрос возможно в удобстве. Я решил что хочу видеть у себя список новых сериалов и серий к ним, и при клике на сериал, например, отправляться на ресурс куда их обычно скидывают (в моем случае это сервера в локальной сети) ну или не важно куда (: API ресурса весьма прост, все GET запросы обычно состоят из одного/двух параметров. Итак, какие операции я могу выполнить с помощью API?
  1. авторизация на ресурсе
  2. получить список сериалов, которые в твоем списке с их статусами (смотрю/собираюсь посмотреть/перестал смотреть/полностью посмотрел)
  3. пару дней назад появилась возможность получать список просмотренных серий
  4. получить список серий которые уже вышли, но не отмечены у тебя как просмотренные, а также серий которые выйдут в ближайшее время, с датами выхода и названиями
  5. Отметить эпизод (т.е. серию) как просмотренную, или наоборот
  6. пункт "синхронизация всех просмотренных эпизодов" кажется появился только что, и часа полтора назад его не было (: хз что это. но разработчики говорили о множественном отмечании эпизодов, видимо оно и есть.
  7. установка статуса сериала (смотрю/буду смотреть/забил/удалить из списка)
  8. отметка рейтинга сериала
  9. поиск по названию
  10. полная информация о сериале, со списком эпизодов и т.п
Некоторые возможности я попробовал реализовать используя Delphi. Вобще это мое первое приложения работающее с сетью. Работает оно не используя потоков для загрузки информации, так что иногда может подтупливать при задержке ответа сервера (: В состав проекта вошли на настоящий момент всего 4 файла:
  1. главная форма
  2. форма логина
  3. форма настроек
  4. юнит с реализацией классов и типов данных для работы с сервисом.
Выгрузка данных, кстати, проводится в формате JSON (JavaScript Object Notation), так что для работы требуется библиотека SuperObject, ее я увидел так же в первый раз как и формат выгрузки данных :) который впрочем весьма прост, и напоминает аутпут функции serialize в php. Мануал к данной библиотеке весьма ущербен, хотя и показывает основы ее использования. Меня однако весьма удивило отсутствие метода такого, как например, HasParameter() или что нибудь подобное. Первое что можно реализовать это описания различных множеств, описывающих статусы сериала и просмотра эпизодов:
    TSeriesStatus =  (ssRunning, ssCanceledEnded);
    TSeriesWatchedStatus  = ( wsWatching, wsLater, wsCancelled, wsFinished, wsRemove );
    TEpisodeWatchedStatus = (ewsWatched, ewsUnwatched, ewsNext);
Описание эпизода достаточно просто и состоит из следующих элементов (по крайней мере те, что меня заинтересовали): ID эпизода и сериала, номер сезона, номер эпизода в сезоне, дата выхода, название (на английском), статус (просмотрен/не просмотрен/скоро выйдет)
    TEpisode = class(TObject)
        id : integer;
        show_id : integer;
        season  : integer;
        episode_number : integer;
        airDate : TDate;
        title : string;
        status : TEpisodeWatchedStatus;
    end;
Описание сериала выглядит немного более большим и включает в себя следующие вещи (опять же не все , а что мне потребовалось): ID, название рус/англ, статус (завершен или еще идет), мой статус просмотра, количество эпизодов просмотрено/всего, рейтинг пользователей, ссылка на кинопоиск (т.е его id на кинопоиск.ру), также здесь будет храниться список эпизодов для этого сериала.
    TSeries = class (TObject)
      public
        id : integer;
        title : string;
        ru_title : string;
        runtime : integer;
        status : TSeriesStatus;
        watchedStatus : TSeriesWatchedStatus;
        watchedEpisodes : integer;
        totalEpisodes : integer;

        rating : double;
        kinopoiskId : integer;

        episodes   : TList;

        constructor Create();
        destructor Destroy();
    end;
Вообще видимо библиотека SuperObject имеет методы, позволяющие распарсить объект ISuperObject и сформировать на его основе объект TObject (т.е при совпадении названий полей оно их заполнит) и для этого реализован class helper для TObject (что мне не понравилось) с функцими FromJSon & ToJson. Я правда для данных структур написал методы заполнения руками, поскольку определение статусов и т.п было не совсем тривиально (т.е сравнение строк). Описание класса объекта непосредственно работающего с ресурсом весьма просто: получение данных и отправка запросов через TIdHTTP (люди его обычно используют? а то не шарю (: ), чтение приходящих данных в строковый поток, при возникновении ошибки (работы с ресурсом, например, слетела авторизации) после проверки http.responseCode устанавливается значение сообщения об ошибке FErrorMessage (зы: кому то на заметку, видел в каком то блоге, что люди проверяют не responseCode, а строку responseText, на вхождение в него требуемого целочисленного кода возврата); Функции для разбора структур сериалов и эпизодов; Также нам потребуется пара списков для хранения наших сериалов, и результатов поиска. Названия остальных методов класса говорят, кажется, сами за себя.
    TMyShows = class (TObject)
      strict private
        http : TIdHTTP;
        stream : TStringStream;
        fErrorMessage : string;
        function ParseSeries(obj : ISuperObject):TSeries;
        function ParseEpisode(obj : ISuperObject): TEpisode;
      public
        authenticated : boolean;
        series : TList;
        searchResult  : TList;

        constructor Create();
        destructor Destroy();

        function login(user, password  : AnsiString):integer;
        function LoadShows(notifyApplication : boolean = true) : integer;
        function LoadEpisodes() : integer;
        function SearchShows(title:string):integer;
        function getShowInfo(showId:integer):TSeries;
        function checkEpisode(eId : integer; uncheck : boolean = false) : boolean;
        procedure SetSeriesStatus(showId:integer; status: TSeriesWatchedStatus);

        property ErrMsg : string read fErrorMessage;
    end;
при загрузке списка сериалов (или перезагрузке, например, когда мы меняем статус сериала, или добавляем новый сериал в список), приложению (главной форме) отправляется сообщение, обрабатывая которое, форма перерисовывает вывод информации в таблицах. Кто какие, кстати, использует методы для того чтобы уведомить интерфейс, о том что требуется обновление вывода данных? Итак, кажется мне что это не супер интересно и т.п так что напоследок пара скриншотов:
 
Контекстное меню содержит пункт настройки ссылок для сериалов, блок избранных ссылок (отображается для всех сериалов), и блок ссылок для выбранного сериала [на скрине в каждом блоке по одной ссылке]. Данные настройки хранятся в XML файле, работа с которым, в прочем ведется с помощью еще одного класса TLinksConfig который использует интерфейс IXMLDocument (об этом [меню и xml] мб отдельно). Ссылки редактируются в простом окошке:
 
Вторая вкладка содержит информацию о сериях которые не посмотрены, или скоро выйдут.

с фильтрацией по сериалу. На последней вкладке планируется сделать более подробную информацию по сериалу. Плохо что API не предоставляет информацию о ссылках на torrent-файлы, или изображения (лого) сериала. Хотя предоставляет id на kinopoisk.ru где название постера фильма соответствует его ID, так что можно вытащить, но там не все сериалы.

Кто на ресурсе зареган, можете побаловаться (:myshows.v.0.1.alpha.pre Весьма не очень веселая ситуация с прорисовкой компонентов, при включении GlassSheet для формы, бедные TSpeedButton с картинками так и не отображаются. Да и вобще у многих компонентов без включения DubleBuffered косяки с отображением. Элемент TLinkLabel так и не смог поставить на форму чтобы он отображался, прозрачная все время (форма с glass/на ней TTabControl/на нем TPanel а сверху linkLabel) (: кто подскажет как с этим бороться?
Метки:  MyShows API 

Комментарии

Нет комментариев
- Имя
- e-mail*
- Сайт
вы можете использовать теги [i],[b],[code],[quote]
Дополнительно