Pull to refresh

Персональный рейтинг депутатов каждому при помощи JavaScript и браузера Chrome

Reading time 6 min
Views 20K

Скоро некоторые из нас пойдут отдавать свои голоса за очередных кандидатов в депутаты. Депутаты являются нашими представителями и им мы предоставляем право принимать некоторые законодательные решения за нас. В данных условиях логично выбирать тех кто делает свой выбор также как и мы.


Голоса депутатов находятся на vote.duma.gov.ru. Нам остаётся проголосовать за важные для нас законопроекты в соответствии со своим видением и получить рейтинг на основе которого и делать выбор на выборах.


Я выбрал наименее затратный путь и написал JavaScript расширение для Chrome. Работа с ним организованна через консоль браузера (Ctrl + Shift + J). Бонусом я протестировал поддержку русского языка в JavaScript без препроцессоров.


Под катом вас ждёт код с комментариями и комментарии к статье.



В папке "vote" три файла "manifest.json", "insert.js", "script.js" в кодировке UTF-8 (без BOM).


Код:


Файл "manifest.json":


{ 
  "manifest_version": 2,
  "name": "Твой кандидат",
  "description": "Расширение для подсчёта персонального рейтинга депутатов на vote.duma.gov.ru",
  "version": "1.0",
  "content_scripts": [
    {
      "matches": [ "http://vote.duma.gov.ru/*" ],
      "js": [ "insert.js" ],
      "run_at": "document_end"
    }
  ],
  "web_accessible_resources": [
    "script.user.js"
  ]
} 

Часть манифеста "web_accessible_resources" даёт доступ странице загружать и использовать перечисленные в ней файлы плагина. "script.js" это основной скрипт в котором вся логика.


Хром не даёт прямого доступа расширениям к переменным страницы. Мы внедряем свой скрипт("script.js") в саму страницу при помощи "insert.js".


Файл "insert.js":


var script   = document.createElement('script');
script.type  = 'text/javascript';
script.src   = chrome.extension.getURL("script.user.js");
script.async = 1;
document.head.appendChild(script);

Файл "script.user.js":


// ==UserScript==
// @name Твой кандидат
// @description Расширение для подсчёта персонального рейтинга депутатов на vote.duma.gov.ru
// @author ivan386
// @license MIT
// @version 1.0
// @run-at document-end
// @include http://vote.duma.gov.ru/*
// ==/UserScript==

javascript:
(function() {
    'use strict';

var вывести = function( текст ){
    console.log( текст );
    document.querySelector( "#текст" ).innerText = текст;
};

var голосовать = function( ваш_голос )
{
    if ( typeof deputiesData !== 'undefined' )
    {
        /* Для хранения рейтинга и остальных данных депутатов используется localStorage */
        var депутаты = JSON.parse( localStorage.getItem( "депутаты" ) || "{}" );

        /* В переменной deputiesData храняться голоса депутатов за текущий закнопроект и другие данные. */
        deputiesData.forEach( function( депутат )
        {
            var ls_депутат = депутаты[ депутат.url ];

            /* Восстанавливаем сохранённый рейтинг или устанавливаем 0 */
            депутат.рейтинг = ( !ls_депутат ) ? 0 : ls_депутат.рейтинг;

            /* Восстанавливаем статистику */
            депутат.статистика = ( !ls_депутат ) ? {} : ( ls_депутат.статистика || {} );

            /* Копируем имя */
            депутат.имя = депутат.sortName;

            /* Сохраняем статистику голосов депутатов на будущее. */
            if ( typeof( депутат.статистика[ депутат.result ] ) === 'undefined' )
                депутат.статистика[ депутат.result ] = 1;
            else 
                депутат.статистика[ депутат.result ] ++;

            депутат.количество = 0;
            for ( var голоса in депутат.статистика )
                депутат.количество += депутат.статистика[голоса];

            /* У каждого депутата есть ссылка с его ID на результаты его голосования. */
            /* Используем её как уникальный идентификатор. */
            депутаты[ депутат.url ] = депутат;

            /* Результат голосования каждого депутата лежит в переменной result */
            /* Соответствия взяты из функции renderer скрипта на странице с результатами голосования на vote.duma.gov.ru. */
            /* Значение -1 соответствует голосу "За" */
            /* Значение 0 соответствует голосу "Воздержался" */
            /* Значение 1 соответствует голосу "Против" */
            /* Значение 2 соответствует голосу "Не голосовал" */

            /* Меняем рейтинг депутата в соответствии с нашим выбором. */
            депутат.рейтинг += ( депутат.result == ваш_голос ) ? 1 : -1;
        } );

        /*Сохраняем рейтинг и другие данные в localStorage */
        localStorage.setItem( "депутаты" , JSON.stringify( депутаты ) );

        вывести( "голос " + ( ваш_голос == -1 ? "За" : "Против" ) + " принят" );
    }
    else 
        вывести( "на странице не найдено результатов голосования депутатов за законопроект" );

};

var за = function()
{
    /* Значение -1 соответствует голосу "За" */
    return голосовать( -1 );
};

var против = function()
{
    /* Значение 1 соответствует голосу "Против" */
    return голосовать( 1 );
};

var по_рейтингу = function( список )
{
    var список_по_рейтингу = [];
    var вывод = [];

    for ( var ключ in список )
        список_по_рейтингу.push( список[ ключ ] );

    список_по_рейтингу.sort( function( первый, второй )
    {
        /* Сортируем в порядке убывания рейтинга */
        return второй.рейтинг - первый.рейтинг;
    } );

    список_по_рейтингу.forEach( function( элемент )
    {
        /* Выводим результаты в консоль */
        вывод.push( элемент.имя + ": " + элемент.рейтинг + ( элемент.количество ? " (" + элемент.количество + ")" : "" ) );
    } );

    return вывод.join( "\n" );
};

var рейтинг_депутатов = function()
{
    var депутаты = JSON.parse( localStorage.getItem( "депутаты" ) || "{}" );

    вывести( по_рейтингу( депутаты ) );
};

var рейтинг_партий = function()
{
    var депутаты = JSON.parse( localStorage.getItem( "депутаты" ) || "{}" );
    var партии = {};

    for ( var идентификатор in депутаты )
    {
        var депутат = депутаты[ идентификатор ];
        var партия = партии[ депутат.factionCode ];
        if ( партия )
        {
            /* Рейтинг партии складывается из рейтинга депутатов. */
            партия.рейтинг += депутат.рейтинг;
            партия.количество ++;
        }
        else
            партии[ депутат.factionCode ] = { имя: депутат.faction , рейтинг: депутат.рейтинг , количество: 1 };
    }

    вывести( по_рейтингу( партии ) );
};

var окно = (typeof unsafeWindow === 'undefined') ? window : unsafeWindow;

document.body.insertBefore( document.createElement( "div" ) , document.body.firstChild ).innerHTML = 'Твой кандидат:\n\
 <button onclick="за()">За</button>\n\
 <button onclick="против()">Против</button>\n\
 <button onclick="рейтинг_партий()">Рейтинг партий</button>\n\
 <button onclick="рейтинг_депутатов()">Рейтинг депутатов</button>\n\
 <div id="текст"></div>';

окно.за = за;
окно.против = против;
окно.рейтинг_депутатов = рейтинг_депутатов;
окно.рейтинг_партий = рейтинг_партий;

if ( typeof( окно.deputiesData ) !== 'undefined' )
    deputiesData = окно.deputiesData;

вывести( "за() - проголосовать за\n\
против() - проголосовать против\n\
рейтинг_депутатов() - выводит текущий рейтинг депутатов в соответствии с вашими голосами\n\
рейтинг_партий() - выводит текущий рейтинг партий в соответствии с вашими голосами\n\
 " );

})();
void(0);

Установка


  1. Копируем папку "vote" с содержимым на локальный диск.
  2. В браузере Chrome открываем "chrome://extensions/" или "Главное Меню > Дополнительные инструменты > Расширения"
  3. Ставим галочку "Режим разработчика"
  4. Нажимаем "Загрузить распакованное расширение..."
  5. Находим и выбираем папку "vote" со скриптами.
  6. Нажимаем ОК.

Использование


Голосуем

  1. Заходим на страницы с голосами депутатов на vote.duma.gov.ru.
    Например: http://vote.duma.gov.ru/vote/95967 (ссылка взята здесь)
  2. Открываем консоль браузера (Ctrl + Shift + J).
    3.1. Если против пишем:


    против()

    3.2. Если за пишем:


    за()

  3. Нажимаем Enter

Получаем рейтинг

  1. Заходим на любую страницу vote.duma.gov.ru.
  2. Открываем консоль браузера (Ctrl + Shift + J) ещё не открыта.
    3.1. Для вывода рейтинга депутатов:


    рейтинг_депутатов()

    3.2. Для вывода рейтинга партий:


    рейтинг_партий()

  3. Нажимаем Enter

Либо можно воспользоваться кнопками вверху страницы.


Результат


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


Пример рейтинга депутатов:


Иванов Иван Иванович: 5
Петров Пётр Петрович: 0
Сидоров Владимир Владимирович: -5

Пример рейтинга партий (в скобках количество депутатов):


Пиастрская: 100 (10)
Фарианская: 0 (1)
АнтиПиастрская: -100 (1)

Все имена и события вымышлены. Совпадения случайны.


Заключение


Надеюсь этот скрипт поможет делать более осознанный выбор своего представителя в законодательной власти. А заодно и покажет пример написания расширения для анализа данных на государственных сайтах .


Об ошибках прошу писать в личные сообщения.


Источники


  1. Создаём своё расширение для Google Chrome
  2. Как запускать расширения Хрома не из магазина WebStore
  3. Учимся писать userscript'ы
  4. Скрипты на GitHub
  5. Система анализа результатов голосований на заседаниях Государственной Думы
Tags:
Hubs:
+30
Comments 54
Comments Comments 54

Articles