28 April 2012

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

Open sourceJavaScript
Сразу говорю, кармавиджет — вовсе не основная цель статьи. В этой статье я хочу представить широкой общественности способ быстрого создания информационных виджетов для 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 и позволяющий даже пошаговую отладку.

В окончании статьи призываю читателей стать писателями :) И расширить базу провайдеров, если ваш интернет провайдер, сотовый оператор, погодный сайт, банк-клиент ещё не присутствует в общем списке.
Tags:виджетандроидбаланс сотовых операторовбаланс
Hubs: Open source JavaScript
+23
10.9k 236
Comments 21
Popular right now
Backend-разработчик (Middle)
to 250,000 ₽ЛатераЗеленоградRemote job
Senior Frontend Engineer
from 160,000 to 220,000 ₽Jamakase TechnologiesRemote job
Javascript разработчик
from 130,000 to 180,000 ₽ArtezioНижний Новгород
Javascript разработчик
from 160,000 to 220,000 ₽ArtezioМосква
JavaScript разработчик
from 150,000 to 200,000 ₽SportrecsМоскваRemote job
Top of the last 24 hours