Виджет для Android на JavaScript за 15 минут на примере Хабра-Кармы

    Сразу говорю, кармавиджет — вовсе не основная цель статьи. В этой статье я хочу представить широкой общественности способ быстрого создания информационных виджетов для Android на JavaScript всего лишь на примере кармы и рейтинга хабра. Виджет будет смотреться примерно так:



    Виджет будет представлять собой плагин для программы AnyBalance (Android), основная идея которой — собрать общую базу способов извлечения балансов и прочих параметров из личных кабинетов различных провайдеров, например, балансов на сотовых телефонах, интернет провайдерах и т.д. Эти плагины (будем их дальше называть «провайдерами») пишутся на JavaScript и имеют открытый исходный код. Сейчас база AnyBalance содержит около 80 провайдеров, но постоянно расширяется. И хабрахабр там будет не лишним :)

    Итак, чтобы извлечь нужные настройки со страницы Хабрацентра, например, моего, нужно посмотреть, как они там лежат. Мы видим:
        <div class="karma">
            <div class="label">карма</div>
            <div class="score">
             
                   
                 
                <div class="num">3,0</div>
                 
                   
            </div>
            <div class="votes" >3 голоса</div>
        </div>
        <div class="rating">
            <div class="label">рейтинг</div>
            <div class="num">1,5</div>
        </div>
    


    Поскольку мы вооружены регулярными выражениями, то извлечь нужные данные труда не составит. Таким образом, осталось понять, как AnyBalance нам может в этом помочь.

    AnyBalance предоставляет API, в котором предусмотрено взаимодействие плагина с программой. AnyBalance говорит плагину — получи данные, вызывая его функцию main(), и передавая ему настройки пользователя, а он запрашивает страницы из интернета (поддерживаются методы GET и POST), извлекает из них данные и возвращает их программе. Для извлечения хабракармы нам понадобится GET запрос Хабрацентра им. заданного пользователя (AnyBalance.requestGet) и передача извлеченных значений программе (AnyBalance.setResult).

    Сама AnyBalance делает всё остальное, то есть показывает эту информацию на виджетах, запрашивает обновление данных по расписанию, строит графики и ведет статистику. С её помощью можно мониторинг всех используемых в семье счетов загнать в мобильный телефон.

    Итак, код для извлечения кармы и прочих параметров будет выглядеть следующим образом:
    var replaceFloat = [/\s+/g, '', /,/g, '.'];
    
    function main(){
        //Получаем настройки пользователя
        var prefs = AnyBalance.getPreferences();
    
        //Получаем Хабрацентр
        var html = AnyBalance.requestGet("http://habrahabr.ru/users/" + prefs.login);
    
        //Проверяем, не случилась ли ошибка
        var error = getParam(html, null, null, /(страница не найдена \(404\))/i);
        if(error)
            throw AnyBalance.Error("Хабрапользователь " + prefs.login + " не найден. Проверьте имя!");
    
        var result = {success: true};
    
        //Извлекаем данные
        //getParam определена тут же, и представляет собой функцию, позволяющей в одну строчку 
        //извлечь из передаваемой строки подстроку, согласно регулярному выражению, сделать в нем требуемые замены и преобразовать к заданному типу.
        getParam(html, result, 'karma', /<div class="score"[^>]*>[\s\S]*?<div class="num"[^>]*>(-?\d[\d\s\.,]*)/i, replaceFloat, parseFloat);
        getParam(html, result, 'rating', /<div class="rating"[^>]*>[\s\S]*?<div class="num"[^>]*>(-?\d[\d\s\.,]*)/i, replaceFloat, parseFloat);
        getParam(html, result, 'votes', /<div class="votes"[^>]*>(-?\d[\d\s\.,]*)/i, replaceFloat, parseFloat);
        result.__tariff = prefs.login;
        
        //Возвращаем данные программе
        AnyBalance.setResult(result);
    }
    
    


    Всё довольно прямолинейно. Чтобы не перегружать читателя излишними техническими деталями, не буду приводить исходник функции getParam, но её всегда можно посмотреть в репозитории.

    Итак, сам код простой и короткий. Осталось сделать пару декоративных вещей. А именно
    • манифест, в котором будут прописаны названия и типы извлекаемых провайдером данных, название провайдера, версия и другая метаинформация.
    • настройки, которые необходимо сделать для корректной работы провайдера. Нам же надо задать имя пользователя.
    • иконка — для красоты.


    Манифест представляет собой xml файл. Для описываемого провайдера он будет выглядеть так:
    <?xml version="1.0" encoding="utf-8"?>
    <provider>
      <id version="1">ab-social-habrahabr</id>
      <name>Habrahabr</name>
      <description>
        Получает информацию о карме, количество голосов и рейтинг с сайта http://habrahabr для заданного пользователя
      </description>
      <author>Dmitry Kochin <dco@mail.ru></author>
      <files>
        <!-- файлы, входящие в состав провайдера -->
        <icon>icon.png</icon>
        <preferences>preferences.xml</preferences>
        <js>main.js</js>
      </files>
      <counters>
        <!-- данные (счетчики), извлекаемые провайдером -->
        <counter id="karma" name="Карма"/>
        <counter id="rating" name="Рейтинг"/>
        <counter id="votes" name="Голоса"/>
      </counters>
      <keywords>
        хабрахабр, хабр, habr
      </keywords>
      <type>
        social
      </type>
    </provider>
    


    Настройки — тоже xml файл, ссылка на него (и другие файлы провайдера) присутствует в манифесте. Настройки тесно перекликаются с Preferences в Android, но имеют упрощения. Для кармавиджета нужна только одна настройка:
    <?xml version="1.0" encoding="utf-8"?>
    <PreferenceScreen>
        <EditTextPreference 
            title="Хабрапользователь" 
            positiveButtonText="ОК" 
            summary="|Имя хабрапользователя|{@s}" 
            dialogTitle="Хабрапользователь" 
            negativeButtonText="Отмена" 
            dialogMessage="Введите имя хабрапользователя, информацию по которому вы хотите узнать."
            key="login">
        </EditTextPreference>
    </PreferenceScreen>
    


    И, наконец, иконка :) Ну в качестве иконки можно взять прямо лого хабра (если, конечно, владельцы ресурса не против).

    Всё. Теперь каждый владелец устройства на базе Android может постоянно мониторить свою карму, а также множество других параметров, для которых уже написаны провайдеры, на экране телефона. Полный исходный код провайдера, конечно же, доступен в репозитории.

    Написание провайдера, отладка и вырезание иконки у меня заняло ровно 15 минут (засекал). Конечно, я скопировал уже существующий провайдер и просто исправил некоторые места, но ведь это может сделать каждый :) Так что время считаю справедливым.

    В данной статье, в силу её краткости, не слишком подробно описана техническая сторона написания провайдера, но все, кому интересно, могут посмотреть вики на googlecode. Кроме того, для написания провайдера необязательно использовать телефон на Android, есть локальный отладчик провайдеров, представляющий собой расширение Google Chrome и позволяющий даже пошаговую отладку.

    В окончании статьи призываю читателей стать писателями :) И расширить базу провайдеров, если ваш интернет провайдер, сотовый оператор, погодный сайт, банк-клиент ещё не присутствует в общем списке.
    AdBlock похитил этот баннер, но баннеры не зубы — отрастут

    Подробнее
    Реклама

    Комментарии 21

      +11
      >>Поскольку мы вооружены регулярными выражениями, то извлечь нужные данные труда не составит.
      и вы туда же...
        +1
        Для тех, кому претит, есть поддержка JQuery. Можно пользоваться в полной мере.
          +1
          Вот, собственно, пример законопослушного парсинга html с помощью jQuery: code.google.com/p/any-balance-providers/source/browse/trunk/ab-cell-bwc/main.js (сам писал). Так что все отличники могут всё сделать правильно.
          +7
          Что-то я не пойму, вы парсите страницу пользователя? О_о Чем API не устроил?
            +1
            Это пример. Можно парсить страницу пользователя, можно разбирать xml и html (поддерживается jQuery). Но большинство личных кабинетов не предоставляют xml API. И кстати, API хабра не показывает количество голосов, а парсинг HTML показывает (если я правильно понял).

            А основной смысл не в том, как именно лучше сделать кармавиджет, а что это вообще возможно минимальными усилиями. За 10 минут можно переписать на использование xml.
              +2
              И, кстати, обработка хмл гораздо проще. Вот тут подробно про неё написано: code.google.com/p/any-balance-providers/wiki/TutorialXML
                0
                Она реализуется через jQuery (о чем красноречиво говорит добавление его в манифест).
              –4
              Я когда читаю такие статьи, думаю — это ж как надо дрочить на карму.
                +11
                А когда я читаю такие комментарии, думаю — это ж как надо читать статью, в которой в первой же строчке написано «Сразу говорю, кармавиджет — вовсе не основная цель статьи», а потом говорить «достали кармодрочеры».
                +5
                Надеюсь, что кроме слова «карма» в моей статье можно заметить ещё что-нибудь. Вообще-то я именно на этот скрытый междустрочный смысл, затмеваемый губительным влиянием слова «карма», и делал упор. Виджет кармы всего лишь один из более 80 примеров и был написан сегодня за 15 минут для иллюстрации статьи.
                  0
                  И расширить базу провайдеров если… банк-клиент ещё не присутствует в общем списке

                  Многие банк-клиенты используют двухшаговую авторизацию. Для них такой способ не пойдет, как я понимаю.
                    0
                    Да, разумеется. Кроме того, этот способ не подходит и в случае капчи. Но в довольно большом количестве случаев он подходит.
                      +1
                      Кстати, часто второй шаг — это СМС с кодом, которая приходит на тот же самый телефон, где стоит приложение. Так что, думаю, теретически вариант реализуемый.
                        0
                        ещё чуть-чуть докрутить — и отличный вирус получится!
                    +2
                    Вот был топик: habrahabr.ru/post/134272/
                      0
                      Хорошо что такой виджет пишется за 15 минут, но сама программа не каежтся досаточно доработанной, она неудобна в использовании (напрмер, что мешает перенести подключение аккаунтов в саму программу — может быть и сущесвуют какие-то ограничения, но скачивать файлдики с google.code и подключать их не слишком удобно), ну и первый же опробваный аккаунт (beeline интрнет) ничего не показал (виджет остался пустым, лишь с иконкой Билайна).
                        –1
                        Ну там же есть возможность установки провайдера из каталога. Прямо из программы, не надо лезть ни на какой гугл код. По поводу билайн интернет — поскольку у меня нет возможности проверить провайдер на всех тарифных планах сразу, возможно, на некоторых есть ошибки. В этих случаях либо вы сами можете предложить изменения, либо я могу для вас исправить провайдер, если вы можете представить мне временный доступ в ваш личный кабинет.
                        0
                        Приложение понравилось. Есть правда один немного неприятный момент: приложение плодит аж шесть виджетов типа «AnyBalance AxB» с различным размером виджета. Есть возможность объединить их в один, а размер виджета определять в его же настройках? Просто выглядит немного мусорно.
                          0
                          И в догонку: изменить настройки виджета после добавления его на экран не представляется возможным (кнопка «Edit» недоступна). Приходится удалять виджет и добавлять его по-новой.
                            0
                            Там просто маленькая кнопочка, по ней не всегда с первого раза удаётся попасть. Но она работает, никто не жаловался ещё.
                            0
                            Да, в настройках программы можно запретить размеры, которые вам не нужны. А если лаунчер у вас поддерживает изменение размера виджетов после их создания, то можно вообще только первый виджет оставить.

                          Только полноправные пользователи могут оставлять комментарии. Войдите, пожалуйста.

                          Самое читаемое