Скопируйте iframe

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

43 кандидата в президенты. 18 выдвиженцев от партий, 25 самовыдвиженцев на пост президента и отсутствие главного политического оппонента Владимира Путина, политика Алексея Навального. Промежуточные итоги набирающей обороты российской политической кампании No1.

ЖИТЕЛИ САНКТ-ПЕТЕРБУРГА

«Если бы вчера допустили Навального, я бы голосовал за него, так как его не допустили, я не знаю, либо я пойду, но теперь мне надо определяться за кого, либо не пойду».

«Было бы интересно, если бы он участвовал, были бы шансы показать Жириновскому, что ему пора уходить, потому что у Навального были шансы стать вторым».

«Тут двоякая ситуация, потому что с одной стороны есть закон, с другой – у всех должны быть равные шансы, не знаю, ну мне не очень нравится Навальный».

Накануне ЦИК России официально отказал Навальному в регистрации кандидатом в президенты. По мнению ЦИК политик не имеет права баллотировать из-за судимости по делу «Кировлеса ». После отказа Центральной избирательной комиссии Навальный призвал своих сторонников бойкотировать мартовские выборы.

«Решение ЦИК о не допуске меня на выборы исключит миллионы людей из этих выборов, исключит миллионы людей из политической системы, потому что не даст им возможность вообще никак участвовать в выборах и ваше решение оно именно об этом», – сказал Алексей Навальный.

В свою очередь телеведущая «Дождя» Ксения Собчак регистрацию получила. Она идет от партии «Гражданская инициатива», которая не имеет мест в Госдуме и поэтому до 7 января должна собрать не менее 100 тысяч подписей в свою поддержку. Собчак уже предложила Навальному быть её доверенным лицом.

«У нас уже 50 штабов по всей России, у меня запланировано большое количество поездок по городам. Уже я ездила, открывала часть штабов и у нас там кипит работа», – сказала Собчак.

Что касается главного кандидата и действующего президента, Владимир Путин даже не приехал на заседание своей инициативной группы. Пресс-секретарь Путина Песков сослался на плотный график президента, он же заявил, что призывы Навального к бойкоту «нужно изучить на соответствие законодательству».

Вместе с тем эксперты не видят возможности для широкого протеста, результаты предрешены, говорит Александр Конфисахор .

«Мы ждем, что кто победит – он победит. Мы представляем, какой результат он получит на этих выборах. То есть диссонанса от ожидаемого и того, что будет в реальности не будет. И поднять людей на протест, когда нет повода и причины протестовать – очень сложно», – сказал доцент кафедры политической психологии СПБГУ Александр Конфисахор .

От коммунистов на выборы в России идет блогер и бизнесмен Павел Грудинин. В партиях ЛДПР и Яблоке решили коней на переправе не менять, от них идут Жириновский и Явлинский. Но несмотря практически на полсотни кандидатов в президенты, у президента Франции, например, уже запланирована встреча с Путиным, которая состоится после объявленных на 18 марта выборов.

Р азочаровавшийся в блогере функционер рассказал о непростой ситуации в штабе.

В штабе блогера Алексея Навального , который продолжает сбор средств на президентскую кампанию, несмотря на запрет ЦИК и разъяснения Конституционного суда, снова неразбериха. Об управленческом кризисе в протестных рядах пишет на своей странице в Facebook недавний функционер ФБК, правозащитник Виталий Серкуанов . Свой уход из команды Навального Серуканов объяснил «необходимостью самоуважения».

По сведениям Виталия Серкуанова, штаб Навального не в состоянии удовлетворить требования жертвователей средств и обнародовать статистику собранных в регионах подписей. Причина активисту очевидна: для выдвижения блогеру не хватает 250 тысяч голосов, но заручиться необходимым количеством сторонников до дедлайна будет непосильной задачей. Cрок, когда ЦИК должны быть представлены документы для регистрации, заканчивается 31 января 2018 года в 18 часов. Именно поэтому, как отмечает Серуканов, команда Навального меняет тактику по принципу Никколо Макиавелли «Цель оправдывает средства». Несанкционированные митинги 24 декабря планируют как жесткий этап перехода от провала кампании к этапу будущего бойкота выборов.

«Волков (глава штаба Навального) не придумал ничего нового, кроме как через море задержаний, арестов и отрицательного резонанса уйти от ответа на вопросы о причинах провала кампании, прежде всего тактических. Вызвать сочувствие масс, отбиться административными арестами, в то время как простые участники получат уголовные сроки», - пишет Серуканов.

Юрист Илья Ремесло , который провел независимое расследование деятельности ФБК, в комментарии ИА «Политика Сегодня» отметил, что количество разочаровавшихся сторонников Навального увеличивается закономерно.

К этой же категории собеседник агентства относит бывших волонтеров Александра Туровского и Дениса Лебедева . Первый пострадал при обыске в штабе блогера, но Навальный не удосужился упомянуть его имя. Похожая история произошла с Лебедевым тремя годами ранее. Ему сломали ногу в одной из поездок по делам ФБК, но в фонде активисту дали понять, что не собираются заниматься его проблемами.

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

«Никакой поддержки на самом деле нет. Это ситуация показывает, что они не могут наладить элементарную работу, потому что эти люди никогда нигде не работали и не зарабатывали деньги честным трудом. Ни Волков, ни Навальный. Поэтому они тянутся друг другу. Если бы у них был необходимый уровень поддержки, то люди бы валили без остановки. Набирали эти подписи, даже если Волков и Навальный были бы совершенно бесталанными, но поскольку и они бесталанные и уровня поддержки нет, то мы получаем то, что получаем», - прокомментировал Ремесло.

​Кампания +1. Собираем 1 000 000 подписей

​На то, чтобы собрать 300 000 подписей, необходимых для выдвижения кандидата на президентских выборах в 2018 году, нам потребовалось 4 месяца. Наша новая цель - миллион, и мы запускаем кампанию «+1».

По законам Российской Федерации для регистрации кандидатом в президенты претендент должен предоставить в Центральную избирательную комиссию 300 000 подтвержденных подписей, собрать которые необходимо в очень короткий срок. На сбор отводится всего 40 дней, а в нашем случае - еще меньше, потому что эти 40 дней приходятся на новогодние праздники. По сути, это еще одно искусственное препятствие, созданное властью. Кроме того, подписи должны быть собраны в 40 регионах страны - не более 7500 от каждого субъекта РФ.


Фото: Евгений Фельдман

Чтобы вовремя подать в ЦИК необходимые 300 000, мы должны знать, что во всех регионах, где будут открыты наши штабы, мы можем рассчитывать на 7500 подписей. И что собраны они будут точно в срок и с полным соблюдением процедуры.

У тех кандидатов, которых Кремль хочет видеть на выборах, и бумагу нарезанную возьмут как подписи, мы такое не раз наблюдали. Наши же подписи будут смотреть под микроскопом

Алексей Навальный


Фото: Евгений Фельдман

Скорее всего, подписи, поданные штабом Навального, ЦИК будет изучать особенно тщательно - поэтому мы должны максимально застраховаться и собрать намного больше, чем предписано протоколом. Мы собираем не только электронные адреса, но и номера телефонов и краткие анкеты всех, кто готов поддержать выдвижение Алексея Навального. Это делается для того, чтобы мы точно знали, в каких регионах есть наши сторонники и сколько их.

Желающих поддержать независимого оппозиционного кандидата вокруг вас - море. Хотя бы из соображений конкуренции на выборах. Даже запутинцы поддерживают конкуренцию, хотят видеть независимых кандидатов в бюллетенях

Алексей Навальный


Следующая наша цель - миллион подписей, которые гарантируют нам необходимые 300 000 в конце года. Для этого мы запускаем кампанию «+1» и призываем всех, кто уже поставил подпись на сайте, убедить зарегистрироваться еще хотя бы одного человека. А лучше двоих или пятерых - и тогда нужный миллион будет достигнут уже к лету.

Сейчас нам очень нужна ваша помощь. Потратьте, пожалуйста, 10-15 минут своего времени и сагитируйте кого-нибудь из своих друзей, родственников или коллег по работе поставить подпись.


Фото: Евгений Фельдман

Напишите нескольким знакомым письмо или сообщение в социальной сети:
«Привет. Я поставил свою подпись за выдвижение Навального кандидатом. Не мог бы ты тоже поставить? Это будет правильно»

Алексей Навальный

Уже подписавшиеся 385 531 человек - страшная сила. Давайте использовать ее с максимальной пользой. Присоединяйтесь к кампании «+1».

Еще это рассказ о том, как при помощи свободного ПО и недорогих комплектующих небольшая команда создала сложную систему сбора подписей в масштабах целой страны. В проекте нет сложных технических решений, но есть множество важных мелочей, которые невозможно предусмотреть на основе типичного опыта IT-разработки.

Для удобства материал разбит на четыре поста, которые лучше читать последовательно.

Это технический материал, но многие вопросы, которые здесь обсуждаются, непонятны без минимального знания современного политического контекста, поэтому он в необходимой мере описан. Если вас по каким-то причинам пугает слово «Навальный» (оно встретится еще несколько раз) или упоминание демократических институтов, просто не читайте этот текст. В комментариях политические вопросы обсуждаться не будут.

Цель кампании

Регистрация Алексея Навального кандидатом в президенты.

Задачи, поставленные перед IT-отделом

(в хронологическом порядке):

Предварительная регистрация всех, кто готов поставить подпись за выдвижение нашего кандидата;
- Обеспечение работы сети штабов по всей России;
- Создание системы для сбора 315 тысяч идеальных подписей.

Исторический и политический контекст

Если у вас нет парламентской партии, то для участия в выборах вам нужно собирать подписи. Это заградительная процедура, которую используют, чтобы не пускать на выборы «несогласованных» кандидатов.

Бесконечные возможности для отказа в регистрации заложены на уровне правил сбора:

  • Сбор подписей жестко ограничен по времени;
  • На брак по закону отводится небольшой процент от необходимого количества подписей, нельзя сдать подписи с хорошим запасом;
  • Невозможно на своей стороне проверить подписи, т. к. данные избирателей должны соответствовать базе ФМС, доступ к которой есть только у государственных органов;
  • Графолог при проверке в ЦИК может забраковать любую подпись и не несет юридической ответственности в случае ошибки;
  • Сама схема проверки предполагает, что будет значительный процент ложных срабатываний (парадокс теоремы Байеса как заградительный барьер на выборах).

Мы уже сталкивались с этим в Новосибирске, когда собирали подписи для участия в выборах в Законодательное собрание.

Для сбора подписей в Новосибирске мы создали систему Жнец , которая была ориентирована на сбор подписей «в поле» и на кубах, управляла маршрутами сборщиков, учитывала все подписные листы и позволяла ранжировать подписи по результатам различных проверок.

Сборщики в Новосибирске принесли более 16 тысяч подписей, из которых мы выбрали и сдали самые лучшие 11 722. Несмотря на жесткий отбор, рабочая группа избирательной комиссии выявила множество «недействительных подписей», а избирательная комиссия отказала кандидатам в регистрации. Подробнее о том, по каким абсурдным причинам подписи признаются недействительными, .

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

Особенности нового сбора подписей

Для сбора подписей за выдвижение кандидата в президенты установлены еще более жесткие условия:

Необходимо сдать не более 315 тысяч подписей;
- Не менее 300 тысяч подписей должны быть признаны действительными;
- От одного региона засчитывается не более 7500 подписей;
- На короткий период сбора (с 27 декабря по 31 января) приходятся продолжительные новогодние праздники, когда многие уезжают в отпуск.

Учитывая предыдущий опыт и новые требования, мы приняли следующие базовые принципы.

Всероссийская сеть штабов

Из-за региональных квот нельзя было вести работу, скажем, в десяти крупнейших городах. 315 тысяч подписей можно было собрать, если охватить не менее 40 городов. В малонаселенных регионах собирать подписи сложнее, поэтому на практике для успешного сбора нужно было открыть штабы в большинстве регионов страны.

Прогноз по количеству подписей на момент успешного завершения сбора показывает, что в крупных городах количество желающих поставить подпись значительно превысило бы региональные квоты. Москва (127 тысяч) и Питер (63 тысяч) не влезли на экран.

Сбор подписей только в штабах

Для сбора по домам нам бы пришлось нанять несколько тысяч сборщиков. Каждый, кто хоть раз работал с платными сборщиками (или, например, студентами-социологами), знает, что не все они одинаково трепетно относятся к процедуре и не все преодолевают соблазн просто «нарисовать» подпись-другую. Небрежное заполнение приводит к большому проценту брака, а «рисование» подписей - настолько распространенная проблема, что в ЦИКе предусмотрена проверка графологом. Даже наличие графолога в штате и показательное оформление нескольких заявлений в полицию не может на 100% избавить штаб от «рисовальщиков» (мы проверяли). К тому же сборщик может дорисовывать подписи не только из злого умысла, но и, наоборот, чтобы «помочь штабу».

Мы знали, что при сборе «в поле» нам обязательно внедрят «токсичных сборщиков », как это было в Новосибирске. Токсичные сборщики намеренно допускают ошибки в данных избирателя (например, подменяют одну цифру в номере паспорта). Их задача - увеличить количество недействительных подписей выше предела, после которого избирком отказывает в регистрации. В Новосибирске потратили много сил, чтобы вычистить токсичные подписи. При сборе по всей стране это сделать невозможно.

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

Многоступенчатая проверка подписей

Идеальные подписи - это математическая абстракция. Настоящий сбор подписей - сложный и тяжёлый процесс. Даже честные и хорошо подготовленные сборщики допускают ошибки, а в условиях нехватки времени, административного давления и провокаций брака будет еще больше.

У нас есть много данных о том, как появляются ошибки. По нашему опыту, в подписных листах, собранных совершенно честным образом, будет около 10% подписей, которые избирком признает недействительными.

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

Скан паспорта для каждой подписи

Без скана вся ответственность за качество подписи лежит на сборщике. Если он случайно или намеренно ошибся в номере паспорта, мы этого никогда не узнаем.

По опыту мы выяснили, что только ошибки переписывания паспортных данных в подписной лист и ошибки ввода данных легко исчерпывают допустимый 5% лимит, даже если подписи собираются в комфортных условиях и добросовестными сборщиками.

Имея скан документа, мы могли провести несколько независимых этапов проверки подписи и внести исправления.

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

Конечно, сканировать паспорт можно было только в штабах, иначе нельзя было обеспечить достаточный уровень безопасности персональных данных.

Синхронизация с электронной базой данных

Все операции с подписями и подписными листами, все статусы и перемещения должны были отражаться в электронной базе данных. Система сбора подписей должна была контролировать все этапы сбора и выявлять ошибки. Только так мы сохранили бы порядок (и душевное равновесие) при работе с сотнями тысяч физических объектов.

Что было сделано в новой версии системы

  • Чтобы нам было где собирать подписи, мы развернули сеть региональных штабов. IT-инфраструктура штабов состоит из нескольких физических серверов, ряда виртуалок, 70 роутеров, 230 камер и 189 укомплектованных рабочих станций. Изнутри системой одновременно пользуются более 250 человек.
  • Чтобы за короткий период сбора успеть привести в штабы несколько сотен тысяч человек, мы заранее начали регистрацию избирателей на сайте 20!8, где они предварительно подтверждали свои данные.
  • Чтобы снизить количество ошибок, мы сделали систему, позволяющую проводить независимые проверки правильности заполнения подписного листа. Система состоит из нескольких веб-приложений и мобильного приложения под две платформы.
  • Чтобы загрузить данные в систему, мы собрали (и частично изготовили) комплект оборудования для сканирования паспортов, продумали схему безопасной передачи персональных данных и внедрили ее во всех штабах.
  • Чтобы форматирование адреса было корректным с точки зрения избиркома, мы подняли поиск по базе ФИАС и вместе с юристами серьезно повозились с ней, чтобы учесть все требования закона.
  • Чтобы (частично) обезопасить штабы и иметь дополнительные аргументы в судах, мы наладили круглосуточную систему видеонаблюдения и записи.
  • Чтобы протестировать инфраструктуру, механику, уточнить данные и подготовить штабы к сбору, мы провели большую процедуру предварительной верификации избирателей, через которую прошло 81 750 человек.
  • Мы разработали внешний вид подписного листа, систему логистики листов в штабах, а также систему физического хранения и быстрого доступа для центрального штаба.

Основные технологии наших веб-приложений

Основной язык бэкенда: Python.
Фронтенд: JavaScript, jQuery, React, D3.js.
Фреймворки: Django (6 шт), aiohttp (1 шт).
Базы данных: PostgreSQL, Redis и другие.
Полнотекстовый поиск: Sphinx.
HTTP-сервер: Nginx, Varnish.
Тестирование: Jenkins, Browserstack, RobotFramework, Locust.
Мониторинг: Zabbix, Elasticsearch, Kibana, Sentry.
Деплой: Ansible и другие инструменты.
Управление конфигурацией сервера: Chef.

Часть первая: сайт «Навальный 20!8»

Нам предстояло привести в штабы несколько сотен тысяч человек в очень ограниченный промежуток времени. Для этого мы начали регистрацию сторонников прямо в день старта кампании. Рекрутинг и регистрация сторонников - одна из основных задач сайта «Навальный 20!8 », поэтому форма регистрации есть почти на каждой странице.

Так как все это нужно не просто ради красивых цифр, нам важно было знать, что зарегистрировавшиеся сторонники - это настоящие люди, а не боты, уметь поддерживать с ними связь и понимать, в каком городе они прописаны (чтобы прогнозировать выполнение квот по регионам). Поэтому регистрация на сайте была довольно сложной и с обязательным подтверждением номера телефона. Чтобы не обманывать себя и других, в потенциальных подписантов мы записывали только людей, которые заполнили анкету целиком и подтвердили свой телефон. Поэтому на главной странице вместо миллиона с лишним (общее количество регистраций) у нас сейчас только 706 513 «будущих подписей».

С точки зрения сайтостроения это довольно рядовой продукт. Сайт сделан на Python + Django + PostgreSQL, используются стандартный ORM и стандартная админка. За полтора года сайт пережил несколько обновлений: добавлялись разделы, менялась работа формы регистрации, менялись тексты и изображения на страницах. Мы старались не усложнять дизайн, чтобы можно было верстать стандартными блоками, благодаря чему некоторые разделы проходили путь от идеи до запуска за три дня.

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

Карта штабов

Единственный сложный интерактивный элемент, который видят посетители, - карта России с отмеченными на ней штабами. Когда количество штабов перевалило за 50, ориентироваться по карте стало сложно из-за близкого расположения маркеров в европейской части страны. Изначально карта задумывалась как чисто декоративный элемент, но внезапно наполнилась функционалом, поэтому для тех, кто уже оценил федеральность кампании и просто хочет найти свой город, мы сделали режим списка.

Карта сделана с использованием прекрасной и многогранной библиотеки d3.js. Писать свой скрипт, а не использовать стандартные Google Maps или Яндекс.Карты мы решили из-за картографической проекции. Есть множество способов сделать развертку эллипсоида Земли на плоскости . В проекции Меркатора объекты сильно растягиваются на северных широтах, а нам нужно больше места в тех районах, где сосредоточены основные крупные города. Кроме того, в проекции Меркатора Россия выглядит довольно странно. Мы выбрали более привычную по учебникам географии коническую проекцию Альберса (Albers-Siberia).


Россия здорового человека (коническая проекция Альберса) и Россия курильщика (проекция Меркатора)

Управление контентом

Редакторский раздел сайта мало чем интересен. Используется обычная админка Django с минимальной кастомизацией. При ограниченных разработческих ресурсах выгоднее научить нескольких пользователей админки пользоваться стандартным инструментом, чем тратить время на создание действительно удобного.

Некоторые решения, упрощающие жизнь редактора, были взяты с других проектов. Например, инструмент для типографирования текстов на клиентской стороне. Наш типограф удобен тем, что легко подключается к любому текстовому или строковому полю ввода. Информация о состоянии автотипографики (вкл./выкл.) хранится в виде непечатного символа в конце строки и никак не зависит от бэкенда.

Для работы со сложным контентом постов и новостей мы используем блочный редактор, который тоже используется на многих других проектах:

Блоки бывают разных типов, на каждом проекте свой набор. Каждый блок содержит контент и может содержать настройки. Данные блоков хранятся в базе в виде json, а разметка внутри текстового блока хранится в формате markdown.

Для отображения блоки преобразуются в нужный формат: HTML для поста, текст для индексирования, RSS или XML для Яндекс.Дзена, JSON для мобильного приложения и так далее. Таким образом мы получаем предсказуемый результат на любом устройстве при достаточно сложном форматировании контента.

Первая версия была основана на коде Sir Trevor . Позже, когда поддерживать спагетти-код Sir Trevor стало тяжело, редактор был переписан на React.

Аналитика

Самое интересное с технической точки зрения происходит в админке сайта. Оттуда мы наблюдали за потоком регистраций.

Первое время аналитика была довольно примитивной: графики количества регистраций разного типа от времени. Но нам хотелось видеть динамику по регионам и отслеживать влияние различных событий на число регистраций. Так появилась Долгожданная аналитика:


На этом экране есть сводная информация за все время жизни сайта, график за определенный период и список событий за этот период. Можно выделить какой-то пик на графике и попробовать понять, какое событие его вызвало. Чаще всего это публикация очередного видео с расследованием на YouTube-канале Навального. Самый большой прирост подписей давали ролики о махинациях региональных чиновников.

График сделан на d3.js, а фильтрация событий по времени и штабу реализована с использованием библиотеки Crossfilter . Это решение позволяет на клиентской стороне без тормозов интерфейса оперировать данными о регистрациях на интервале больше года с шагом 1 час. На данный момент это 12 мегабайт данных (1,3 Мб в gzip).

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

Город и регион

Еще у нас есть огромная таблица, где для каждого региона России прописаны основные показатели подготовки к сбору подписей:

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

Москва - 2,5% ошибок и 579 вариантов написания;
- Санкт-Петербург - 12,6% ошибок и 767 вариантов написания;
- Комсомольск-на-Амуре - более 20% ошибок и сокращений, 75 вариантов.

Неправильная оценка количества сторонников могла привести к неправильному планированию сети штабов и агитационных мероприятий. Пришлось подумать над тем, как пользовательский ввод названия города превратить в стандартное название региона. Не хотелось для такой простой формы использовать механизмы автодополнения по КЛАДРу или ФИАСу. Поэтому мы взяли список из 700 наиболее крупных городов России, добавили список типичных написаний («спб», «н-ск») и сделали нестрогий поиск по ним с ранжированием по расстоянию Левенштейна (это мера разницы между двумя наборами символов).

Каждый город из списка мы отнесли к одной из трех категорий по расстоянию до ближайшего штаба: штаб есть в городе, штаб близко (городская агломерация), штаб далеко. Удаленность от штаба учитывалась при оценке количества людей, которые в нужный момент приедут и поставят подпись. В аналитике мы отдельно считали всех подписантов и «доступных» (подтвердил почту, живет в городе со штабом или рядом).


На этом графике видно, как кампания со временем становилась все более региональной. Доля новых регистраций из Москвы и Санкт-Петербурга уменьшилась с 35% до 15%.

SMS и почта

Еще одной технической сложностью была отправка SMS и писем. Шлюзы не очень хорошо доставляют сообщения, особенно на зарубежные номера. Но мы хотели получить самую чистую и достоверную базу сторонников, поэтому вторая часть формы регистрации требовала подтвердить номер телефона через SMS. Для надежной отправки мы сделали ротацию трех шлюзов: если сообщение не было доставлено, то повторная отправка шла уже через другой шлюз. Кроме того, отдельные шлюзы можно было выключать при сбоях на их стороне. Показатели доставляемости SMS-кодов - один из параметров, за которым велось наблюдение:

По графику видно, что в работе шлюзов дважды случались сбои. Доля доставленных SMS сильно падала 21 февраля и 17-18 апреля из-за сбоев очереди отправки сообщений. А 15 июля мы поменяли верстку формы регистрации, это тоже заметно на графике.

Мы отправляем большое количество писем по базе из более 700 тысяч email-адресов. Кто-то подписан на новости, кто-то должен получить уведомление о событии. Кроме того, каждый адрес нужно подтвердить по правилам 2-opt-in (это когда в первом письме приходит ссылка, на которую нужно нажать, подтверждая подписку на рассылку). В начале кампании мы пользовались сервисом ActiveCampaign, но он дорогой и невероятно тормозной. Когда база перевалила за 300 тысяч контактов, работать стало невозможно. Поэтому мы написали свой CRM / рассылочный сервис, который позволяет по нужным выборкам формировать рассылки и цепочки писем. Для доставки писем сейчас используется Mailgun.

Очереди отложенных задач

Отправка почты или SMS через API сторонних сервисов - операция, занимающая существенное время. Такие операции нужно выполнять асинхронно, чтобы не замедлять пользовательский интерфейс и не положить все приложение под нагрузкой. Изначально все асинхронные задачи работали через Celery с Redis в качестве брокера. Каждое письмо или SMS-сообщение создавало задачу в очереди Celery, после чего свободный воркер эту задачу обрабатывал. Но такой подход оказался ненадежным и слишком ресурсоемким.

Как-то раз нам прилетело больше 10 тысяч регистраций за час (нет, нас не показали по телевизору, это была кампания «+1»). 10 воркеров Celery не могли с этим справиться, пользователи начали замечать значительную задержку при получении SMS и почты.

После этого случая мы отказались от Celery в пользу простейшей очереди на базе PostgreSQL. Задачи из очереди разбирали «демоны» на питоне, по одному на каждый канал доставки сообщений. Раз в 10 секунд демон брал пачку задач из очереди и одним пакетом отправлял данные в рассылочный API. Группировка задач радикально снизила нагрузку на сервер, а использование самодельной очереди предельно упростило отладку и мониторинг.

Celery оказался слишком сложным инструментом для нашей задачи. Ему требуется вдумчивая настройка и мониторинг через внешние утилиты вроде Flower, которая сама потребляет немало ресурсов. На других проектах мы стараемся использовать более простое решение - RQ + Redis.


Сравнение сложности RQ и Celery из статьи про работу с асинхронными задачами.

Процесс разработки

Как устроен процесс создания сайта «Навальный 20!8» с точки зрения разработчиков? Мы не придерживаемся какой-то одной методологии, а используем подходы из разных систем. Например, менеджеры ставят задачи в Trello со структурой, похожей на канбан-доску, а разработчики применяют отдельные практики экстремального программирования.

Примерно половина команды находится в московском офисе, а остальные работают удаленно. Московские сотрудники могут участвовать в летучках кампании, чтобы не работать лучше понимать общую картину, но задачи IT-отдела мы обсуждаем отдельно. Регулярные созвоны позволяют всем синхронизироваться и понимать основное направление работы в каждый момент времени.

Большинство участников проекта работают над ним фуллтайм, но отдельные задачи были сделаны разработчиками, временно привлеченными с других проектов, или даже волонтерами. Например, волонтер Илья практически полностью сделал карту штабов для главной страницы.

Исходный код хранится в git-репозитории на платформе Bitbucket. Для каждой серьезной новой задачи создается отдельная ветка. Мы не поднимаем staging-сервер для каждой ветки, все они сливаются в develop для запуска на едином тестовом сервере. После тестирования разработчик, ответственный за задачу, делает пулл-реквест в мастер. Тимлид смотрит код и, если все хорошо, запускает деплой. Для больших задач разработчики делают подробные описания того, что нужно проверить и что может пойти не так при деплое.


Деплой организован очень просто. У нас есть инструмент, который реагирует на веб-хук из Bitbucket (или на кнопку из своего интерфейса), забирает код из нужной ветки, копирует его на сервер и запускает там скрипт обновления. Скрипт оформлен в Makefile.

При запуске «make update» происходит обновление зависимостей, миграции, постпроцессинг статических файлов и, если все прошло удачно, перезапуск uwsgi-сервера. Миграции мы стараемся делать так, чтобы они не ломали старый код, поэтому в случае ошибок деплоя все продолжает работать.

Разработка началась 18 сентября 2016 года. С тех пор было 1228 коммитов, 200 пулл-реквестов, деплой более 600 раз запускался в продакшн, а в репозитории было 67 веток (большинство из них сейчас закрыты).

Про дизайн

В команде проекта над дизайном постоянно работало всего два человека (арт-директор с функцией продакта и дизайнер), при этом оба активно заняты и в других проектах кампании. Поэтому подход к дизайну был предельно утилитарен.

В дизайне IT-продуктов мы всегда руководствуемся двумя основными принципами:

1) Информация для самого «ленивого» и невовлеченного пользователя должна лежать на самом видном месте (так мы, например, определяли первоначальные места блоков и разделов на сайте);

2) Чем меньше людей будут пользоваться конечным продуктом, тем меньше мы его стараемся декорировать (экономим ресурсы разработки) и тем больше входных усилий можем допустить для каждого пользователя (часто эффективнее обучить несколько человек, чем тратить время на внедрение новых фич, которые сэкономят усилия пользователя или уберегут от ошибки).

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

IT-cистема для сбора подписей - очень сложный, многокомпонентный проект с ограниченными ресурсами, поэтому основная часть работы дизайнеров шла на бумаге, на встречах и в гугл-доках, а не в графическом редакторе (в нашем случае Sketch).

В проекте много сложных схем, которые так и хочется нарисовать, а все найденные с ходу электронные инструменты для рисования схем нас не устраивали. Иногда мы использовали draw.io, но чаще рисовали прямо на бумаге. Самые важные схемы висели на доске проекта. Туда же крепились бумажные «тикеты» с вопросами для обсуждения на встречах.

Из согласованных с юристами бумажных схем и сценариев мы собирали прототипы в marvelapp.com , чтобы лишний раз проверить логику и удостовериться, что ничего не забыто. Только после этого макеты передавались в разработку.

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

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

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

По нашим расчетам, с существующим количеством штабов и при условии непрерывного потока людей у каждого сборщика должно было уходить не больше 6 минут на человека - от «здравствуйте» до завершения процедуры сбора.

Верификация и сбор подписей через IT-систему - это полностью изобретенная нами процедура, поэтому основным методом проверки своих решений мы выбрали тестирование MVP на реальных пользователях системы. Так мы протестировали базовый протокол и первый интерфейс верификации на сотрудниках московского штаба, а потом поехали в три разных города (Санкт-Петербург, Челябинск и Ульяновск), чтобы понаблюдать за реальными пользователями в процессе работы. Для подобных проектов это лучший способ быстро составить список вещей и юзер-кейсов, которые могли забыть или не предусмотреть на этапе проектирования и разработки.

После внесения небольших правок в интерфейс верификация была запущена во всех штабах кампании. В итоге нам удалось сократить время обработки одной анкеты до полутора-двух минут на человека.

Тестирование

Для автоматизированного тестирования использовался RobotFramework. Для покрытия самого критического функционала проекта были написаны приемочные и функциональные тесты, настроен их автоматический запуск. В качестве CI-системы использовался Jenkins.

Важнейшая функция сайта - регистрация пользователей, которая предполагает подтверждение телефона через SMS-код. Для тестирования сообщений с кодами был настроен GSM-модем с тестовой SIM-картой и Asterisk. SMS-код пересылался на почту, откуда он уже был доступен для тестов.

Обнаруженные ошибки добавлялись в Trello в виде задач разработчикам.

Серверная инфраструктура

Сайт «Навальный 20!8» продолжает работать и плавно становится сайтом кампании забастовки избирателей, поэтому информационное эмбарго еще не снято, и рассказ будет коротким. Серверная часть состоит из трех уровней: бэкенд, кэширующие прокси и edge-серверы. Все конфигурации управляются через chef, поэтому сервер с любой ролью может быть быстро поднят на новой виртуалке.

На бэкенде работают база данных и инстансы приложений, каждое приложение на своей виртуалке и со своими ip. Все серверы существуют в нескольких экземплярах, а база реплицируется в режиме master-slave на другую машину.

На прокси-сервере установлен Varnish, который занимается кешированием запросов к определенным адресам и различными url-зависимыми ограничениями. Если бэкенд выходит из строя, сайт может неопределенное время работать с прокси-сервера, сломается только механизм регистрации пользователей.

Edge-серверы занимаются кэшированием статики и ssl-терминацией (дальше трафик идет по VPN-сети). Суть этих серверов - раздать основной объем трафика и защитить остальную инфраструктуру от атак. Это слабые виртуалки с гигабитным каналом в разных дата-центрах. Нагрузка распределяется DNS-балансировкой. Edge-серверы содержат минимум конфигурации и при необходимости легко поднимаются за несколько минут. Максимальный полезный трафик, который был у нас на edge-серверах, - 5 Гбит/с в течение нескольких часов.

Картинки, стили, javascript, json-данные хранятся таким образом, что имя файла включает хеш от содержимого данного файла (например, style.28fa1c7b1761.css), поэтому все эти файлы можно навсегда кэшировать на сервере и в браузере. Основной объем трафика отдается с edge-серверов. Дальше проходят только запросы к контентным страницам, а это примерно в 25 раз меньше данных.

Иногда вместо edge-серверов подключается CloudFlare, но мы стараемся возвращаться к своим серверам, т. к. у CloudFlare не всегда бывает хорошая доступность из России. Отдельные провайдеры, даже самые крупные, регулярно начинают блокировать их ip (следы Роскомнадзора).

Заключение

Собирать подписи в традиционном стиле (без специальной IT-системы, с бумагой, ручкой и таблицами в экселе) - это как лететь на воздушном шарике на Луну: да, если взять достаточно много шариков, даже получится взлететь и скрыться в облаках, но добраться до цели таким способом физически невозможно.

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

В рассказывается про выбор и настройку оборудования штабной сети, разработку собственного сканера документов и организацию видеонаблюдения за помещениями штабов.

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

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

Теги:

  • django
  • навальный
  • дизайн интерфейсов
  • разработка сайта
  • 20!8
Добавить метки

Санкт-Петербург, Марсово поле, 17 декабря 2017 года: за выдвижение Навального кандидатом в президенты РФ в Северной столице проголосовали 1797 человек Фото: Twitter / @teamnavalny

Сбор подписей за выдвижение Алексея Навального в президенты прошел в Санкт-Петербурге, на Марсовом поле. Невзирая на штормовой ветер с Невы, в течение полутора часов около двух тысяч человек, терпеливо отстояв в очередях, проголосовали за оппозиционного политика. По закону достаточно было бы всего 500 подписей, так что норма была перевыполнена почти в четыре раза.

В центре Марсова поля собрались неизменные спутники всех оппозиционных акций в Питере - бодрые нодовцы развернули свои черно-оранжевые полосатые полотнища и включили через усилители патриотические песни. Под грохот «Вставай, страна огромная…» к расставленным по полю столам тянулись сторонники Навального.

Возле самого Вечного огня собирались замерзшие граждане и обсуждали происходящее. Кто-то достал распечатку с предвыборными обещаниями Путина в 2000 году и громко зачитывал пункты об удаленности власти от бизнеса, о свободе прессы… «Он что - забыл, что обещал?» - голос наивной барышни буквально потонул в общем хохоте.

«Почему-то мы тут не видим нотариуса! - удивленно прокомментировал корреспонденту NT события на Марсовом поле Олег Зацепа, член городской избирательной комиссии с правом решающего голоса. - Организаторы утверждают, что он позже проведет свои действия по факту, но это же еще не факт!»

«Нотариус может потом утвердить списки по видео, - разъяснил ситуацию Денис Михайлов, руководитель штаба Навального в Питере. - По закону не требуется, чтобы нотариус присутствовал здесь, он может удостоверить по протокольному видео, которое мы делаем. Регистрационные листы мы тоже заверим у нотариуса и отправим в ЦИК. А чтобы привезти сюда нотариуса - (нужно) полтора миллиона (рублей), у нас нет таких средств».

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

«Мне кажется, если бы Навального хоть на месяц пустили на телевидение, Путину было бы его не догнать. Потому что мы президенту не доверяем!»

«Здесь взрослых очень много, не только молодежь, просто молодые более шустрые, - объяснила свое участие в акции 54-летняя Шахназ. - Ну, придет Путин, еще 6 лет - а что будет после него? Не повезет тому президенту, который придет после него, - все разрушено! У меня дочка учится в колледже, она рассказывает, как их в колледже агитируют против Навального, она говорит - мама, мы все равно все понимаем! Мне кажется, если бы Навального хоть на месяц пустили на телевидение, Путину было бы его не догнать. Потому что мы президенту не доверяем!»

Всех записавшихся организовали в 50 колонн примерно по 40 человек и выстроили перед мемориальным комплексом для подсчета голосов.

«Господа, поднимите карточки, если вы «за» выдвижение Алексея Навального в кандидаты в президенты!» - обратился к собравшимся Михайлов. Над полем взметнулся лес красных листков. «Против» есть?» - на окраине толпы показалась одна красная карточка. «Воздержались?» За Навального проголосовали 1797 человек, позже сообщила Фонтанка.ру.

«Итак, Навальный набрал нужное количество голосов!» - констатировал глава штаба и закрыл собрание. Полиция, которая всю акцию жалась к обочинам Марсова поля, побрела к своим машинам.

Екатеринбург: стукачи против Навального, студенты - за


Екатеринбург, 24 декабря 2017 года Фото: Twitter / @teamnavalny_ekb

Уже за полчаса до начала собрания на площадке около памятника отцам-основателям Екатеринбурга в центре города скопилось довольно много народа. Люди средних лет, пенсионеры, но все больше молодежь втекают в огороженное небольшими заборчиками пространство через полицейский досмотр на входе. «А в этот раз полиции не так много, - замечает один из присутствующих. - В прошлый раз намного больше нагнали, а ведь человек сто всего в митинге участвовали».

Действительно, стражей порядка относительно немного и настроены они вполне дружелюбно. Как и участники собрания. Только один старичок, когда его по ошибке пытаются досмотреть повторно, начинает ругаться, грозить полицейским кулаком и грозно вопрошать: «Что? Лычку новую получить захотел?» Вскоре революционный пыл мужчины гаснет в дружеской атмосфере собрания - многие здесь встретились со знакомыми и друзьями, кто-то пришел с семьей.

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

«У нас в РГППУ старшекурсник составил список всех студентов, которые за Навального, и отнес в деканат. Настоящий 1937-й!»

Люди все прибывают. Поддержать своего кандидата пришли городской депутат-либерал Дмитрий Головин, член общественной наблюдательной комиссии Свердловской области Вячеслав Башков и «серый кардинал» уральской оппозиции, политолог Федор Крашенинников. Волонтеры раздают листы регистрации, в которых нужно указать паспортные данные и поставить подпись, а также мандаты - красные прямоугольники, необходимые для голосования.

Под памятником отцам-основателям старичок рассказывает двум молодым людям поучительную историю, как за два дня до выборов мэра Екатеринбурга он решил не голосовать за Ройзмана, потому что он «все равно не пройдет». И когда «народный кандидат» и борец с наркоторговлей неожиданно для всех победил, пересмотрел свою позицию - и теперь считает, что у Навального тоже есть шанс. В ответ студенты делятся собственной историей: «У нас в РГППУ старшекурсник составил список всех студентов, которые за Навального, и отнес в деканат. Настоящий 1937-й!»

Наконец, листы заполнены, и мандаты розданы. Организаторы на всякий случай принесли не 500, а 1 тыс. карточек для голосования - разобрали все, так что опоздавшим пришлось отказать. На повестке четыре вопроса: считать ли собрание открытым, объявить о создании инициативной группы по выдвижению Навального, выдвинуть ли его кандидатуру, закрыть ли, наконец, собрание?

На вопросы положительно отвечают взмахом красных карточек свыше 950 человек (видимо, часть публики отсеялась из-за холода). Организатор собрания Бармин уже собирается объявить результат, но потом спохватывается: может, кто-то против? Кто воздержался? Таковых нет. Четверо ответили «против» только на последний вопрос - о закрытии собрания.

Через час после официального начала народ начинает расходиться. Замечаний от ЦИКа не прозвучало, мероприятие прошло и завершилось мирно, без стычек и провокаций. Участники собрания ожидают, что их снова пригласят оставить свои паспортные данные и подписи, когда штаб Навального начнет избирательную кампанию.


Владивосток, 24 декабря 2018 года Фото: 2018.navalny.com / Антон Лаврусюк


Пермь, 24 декабря 2018 года Фото: 2018.navalny.com / Валерий Авраменко


Тюмень, 24 декабря 2018 года Фото: 2018.navalny.com / Сергей Сысоев



Челябинск, 24 декабря 2018 года Фото: 2018.navalny.com / Андрей Абрамов


Ростов-на-Дону, 24 декабря 2018 года Фото: 2018.navalny.com / Владислав Кульчицкий


Волгоград, 24 декабря 2018 года Фото: 2018.navalny.com / Алексей Копаев