Как мы разрабатывали «Спецкор» — супер-кастомное мобильное приложение для гражданских репортеров

083d86bee15e388f615ce345023ae751.pngС удовольствием представляем хабрасообществу мобильное приложение для гражданских журналистов «Спецкор», с помощью которого можно снимать фото- и видеорепортажи и продвигать их под эгидой «Комсомолки». Главный создатель — ИД «Комсомольская правда», IT-приспешники и разработчики — мы, компания EastBanc Technologies. Проект анонсирован «Комсомолкой» в конце апреля 2014 года, тогда же запущены первые конкурсы. Мы же со своей стороны решили поделиться техническими деталями реализации приложения. На наш взгляд, это будет интересным для читателей, потому что редко в одном проекте возникает столько нетривиальных технологических и бизнес-задач одновременно.«Спецкор» относится к многоплатформенным клиент-серверным приложениям с административным интерфейсом. Клиентская часть реализована на мобильных платформах iOS и Android и содержит следующий функционал:

создание фото- и видеорепортажей; участие в заданиях; просмотр общей ленты репортажей; получение push-уведомлений, настройка типов получаемых уведомлений; возможность поделиться контентом в своих аккаунтах в социальных сетях. Серверная часть состоит из следующих частей: административный интерфейс; API для мобильных приложений; сервис для обработки медиа-контента и публикации контента в социальные сети; сервис для отправки push-уведомлений. Бизнес-цель проекта — создание управляемой сети гражданских репортеров с помощью приложения, которое позволит эффективно взаимодействовать журналистам и редакции «Комсомолки». Для достижения этой цели необходимо было дать возможность таргетировать и сегментировать информацию по рубрикам и темам, а пользователей — по регионам России.Изначально были сформулированы следующие требования к серверной части:

возможность масштабирования; определение геолокации пользователя; обработка фото- и видеоконтента; интеграция с популярными социальными сетями. Дополнительные технические требования: MongoDB OpenShift Private Cloud Python и TurboGears 2 для реализации функционала серверной части Twitter Bootstrap для административного интерфейса. Как приложение работаетРазделы административного интерфейса: список соцсетей, добавление и блокировка соцсети; список городов, добавление города, просмотр информации о городе; список шрифтов, добавление и удаление шрифтов. Возможно добавление кастомного шрифта в формате TTF; список скинов (тем оформления репортажа), добавление и редактирование скина; список рубрик, добавление рубрики. Рубрика является набором скинов с дополнительными свойствами, содержащими название рубрики; список связанных хештегов для публикации в социальные сети; список заданий, добавление задания. Задание похоже на рубрику, но может быть назначено на определенные даты, города и даже на отдельных пользователей; для заданий рассылаются push-уведомления; список новостей, добавление новостей. Новости содержат текстовую и графическую информацию и могут быть привязаны к городам и пользователям; лента репортажей — инструмент для модерации и назначения наград пользователям. Также может использоваться для удаления репортажей. Для каждого репортажа отображаются ссылки на публикации в социальных сетях; список пользователей — здесь отображаются все пользователи приложения. Со страницы пользователя можно перейти на ленту его репортажей, назначить награду. Можно назначить пользователю новость или задание, и ему будет отправлено push-уведомление. Если пользователь уже публиковал контент в социальные сети, то будут показаны ссылки на его профили в этих сетях. Также пользователя можно блокировать; список менеджеров, добавление менеджера. Создание аккаунтов для сотрудников «Комсомолки», отвечающих за контент и работу с пользователями в определенном регионе. Права менеджерам назначаются таким образом, что они могут создавать задания и новости только для заданного набора городов. Также менеджеры отвечают за модерацию контента. c1406891af869cea715f9b4af9c3a2cc.pngПроцесс с точки зрения «Комсомольской правды» Сотрудники КП, которые отвечают за работу приложения «Спецкор», называются менеджерами. Каждый менеджер отвечает за определенный географический регион.Основные обязанности менеджеров «Комсомолки» — это создание контента для мобильного приложения. Через административную панель менеджеры добавляют задания и рубрики, наполняют их скинами. Для кастомизации скинов они могут добавлять различные шрифты.Когда в рубрике или задании есть хотя бы один скин, она становится доступна в мобильном приложении, и пользователи создают свои репортажи с использованием существующих скинов.Репортажи отправляются на сервер, обрабатываются и попадают в ленту, доступную менеджеру. В зависимости от задания или рубрики, которые могут быть привязаны к определенному региону, а также от географических координат репортажа для рубрик, не имеющих географических ограничений, репортаж попадет на проверку к тому менеджеру, который отвечает за соответствующий регион.

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

Информация о награде приходит автору репортажа в виде новости, а также в виде push-уведомления, если соответствующий тип уведомления включен в настройках мобильного приложения.

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

Одной из интересных задач в создании административного интерфейса для менеджеров «Комсомолки» была реализация возможности создания и редактирования скина. Для этого наши коллеги разработали полнофункциональный WYSIWYG-редактор: все изменения в свойствах сразу отображаются на странице редактирования в виде превью скина. С помощью Javascript и CSS скин отображается в точности так, как будет выглядеть на мобильных устройствах.

8e142db56b881677b5c78e79f01da05f.png

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

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

Пример Администратор, отвечающий за Сибирский Федеральный округ, создает одно задание для Новосибирска, Красноярска, Омска и Томска. Например, заснять видеоролик о том, как через эти города несут олимпийский огонь. Для каждого города указывается временной интервал, когда это задание будет актуально.421890bd59c3028e4a9b5d954e3aa9b9.png

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

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

После обработки репортаж отображается в «Моей ленте» репортажей, если же репортаж прошел модерацию и был одобрен — он становится доступен в общей ленте.

Вот так примерно выглядят процессы, которые текут «за кадром». Обратимся к подробностям реализации.

Архитектура серверной части 49e8c8fc5a358dafff6bce14807949be.pngКак организовано хранение информации Вся информация с мобильных устройств хранится в базе данных MongoDB. Основные задачи, для которых был критичен выбор СУБД в нашем проекте — это: выбор пользователей по регионам; выбор репортажей по регионам; выбор заданий/рубрик по регионам; хранение большого количества бинарных данных; масштабирование; скорость. В MongoDB реализована работа с геоиндексами, и это существенно упростило реализацию работы с геоданными в нашем приложении.Одной из возможностей реализации кластерной конфигурации MongoDB является репликация. Это позволяет распределить нагрузку между несколькими копиями БД (удовлетворение требования на масштабируемость).

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

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

административный интерфейс; API для мобильных приложений; сервис для обработки медиа-контента и публикации контента в социальные сети; сервис для отправки push-уведомлений. Сервисы обработки медиа-контента и отправки push-уведомлений — это процессы, которые находят в базе данные для обработки и выполняют ее. Когда при увеличении нагрузки OpenShift поднимает дополнительные инстансы сервера, то увеличивается количество сервисов, и они могут пытаться обработать одну и ту же информацию. Используя атомарную операцию в MongoDB findAndModify процесс устанавливает специальный статус обрабатываемому контенту, тем самым запрещает его использование другими процессами.Установка приложения в OpenShift происходит по команде push в удаленный репозиторий Git, где создано приложение. OpenShift поддерживает хуки, например, есть хук вызываемый при установке приложения. Мы используем этот хук, чтобы база данных не проходила первичную инициализацию при каждом апдейте приложения.

API и геолокация Поскольку задания и рубрики в приложении часто могут быть ограничены георафическими регионами, важно понимать местоположение пользователя для определения его прав доступа, а также для отправки уведомлений. Для определения координат пользователя приложение запрашивает права на доступ к данным геолокации и, в случае получения разрешения от пользователя, получает координаты и отправляет их на сервер. В случае же если пользователь запретил приложению получать информацию о геолокации от операционной системы смартфона, и приложение не может отправить данные на сервер, координаты определяются посредством использования geoip-сервисов. По запросам приложения определяется примерное положение пользователя по месту регистрации его провайдера.Для определения местоположения юзера, который запретил в настройках геолокацию, мы использовали 2 сервиса:

MaxMind Geolite — локальная база соотношений IP-адресов и их географического местоположения (есть проблемы с точностью в РФ и СНГ): ip-api.com — онлайн-сервис, который определяет местоположение с более высокой точностью. Есть серьезное ограничение на кол-во запросов, поэтому используется кэширование информации. Сервис обработки медиа-контента Сервис обработки медиа-контента является процессом, который исполняется независимо от остальных частей. Основные задачи этого процесса — выбор из БД контента с определенным статусом, процессинг и сохранение обработанных данных обратно в БД. Процессинг медиа-контента состоит из двух частей: обработка видео и обработка фото.Как реализована обработка видео Обработка видео осуществляется при помощи сторонней программы avconv (дальнейшее развитие приложения ffmpeg).Репортажное видео может состоять из нескольких кусков. Снимается оно по принципу Vine/Instagram: пока вы держите палец на экране, съемка идет, как только отпускаете — прерывается. Монтировать куски прямо на девайсе — очень ресурсоемкий процесс, поэтому окончательный монтаж у нас происходит на сервере.

7103781a06c53cccb76a6fef4a1e4e2f.pngbca183324e0b58c130ef7d5f1f016226.pngf90e74ec722633e8e4b5647d76f5bfdb.png

7ccc21c0950ef3a907e10a559367f31d.png44b37cad49434af585d2bf36657c77bd.png7c4af13a0d70856ce0bdbc77b1694693.png

6e0e9af4c8ff3eea1369b73b014f6d84.pngce60aa23786f5755b9256c04fe224bcb.png

Видео можно снимать с двух камер — фронтальной и тыловой, можно переключаться между ними в процессе съемки. Разрешения видео, снятого на различные смартфоны, отличаются. Однако при публикации мы создаем ролики 640×640. Общий процесс обработки видео включает следующие шаги:

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

54cbcd4beec0ef2444a935d6463bb072.png0111fba2766c1897020f731a88114607.png

Как реализована обработка изображений С обработкой фото все проще: изображения обрабатываются с помощью библиотеки Pillow.Мобильное приложение отправляет на сервер оригинальную фотографию, а также информацию о репортаже. В целом шаги обработки фото-репортажа аналогичны обработке видео.Как реализована загрузка в соцсети В приложении реализована поддержка загрузки репортажей в основные социальные сети: ВКонтакте, Одноклассники, Twitter, Facebook, Instagram, YouTube.6faedc3c9b9e8a90c561b64a713910f6.png

Загрузка репортажей в соцсети пользователя Если пользователь решил поделиться своим репортажем в социальных сетях, ему нужно выбрать в приложении, в какой сети он хочет расшарить репортаж. Далее процесс будет таким: Пользователь авторизуется в выбранной социальной сети. У пользователя запрашивается разрешение на доступ к профилю и публикацию в его ленту от имени приложения «Спецкор». Если пользователь разрешает, то мобильное приложение получает Access Token и высылает его на сервер Сервер запрашивает по токену профиль пользователя и сохраняет в базе некоторые данные о пользователе: имя, фамилию и ссылку на аватар. После того как пользователь залил на сервер свой репортаж и медиа-контент репортажа был обработан, запускается непосредственно процесс загрузки репортажа в соцсети. Если это видеорепортаж, то он может быть загружен в сети Вконтакте, Facebook, YouTube. Если пользователь выбрал одну из этих соцсетей, а также выбрал Twitter или Одноклассники, то в видео-хостинговые соцсети будет залито видео, а в Twitter/Одноклассники будет загружена ссылка на видео. Для фоторепортажа доступны все сети, кроме YouTube.Загрузка репортажей в соцсети заказчика Помимо публикации репортажа в пользовательские аккаунты социальных сетей, репортаж будет загружен в приватные Twitter- и YouTube-аккаунты заказчика. Для этого были созданы отдельные приложения в социальных сетях. Для загрузки в Twitter пользовательская авторизация не нужна (токены, при помощи которых делаются публикации, не имеют срока давности). А для загрузки в YouTube нужна первичная авторизация пользователя (ее мы сделали в админке приложения), в процессе которой сервер получает от YouTube 2 ключа: access_token и refresh_token. Access Token — ключ, который используется для загрузки видео в YouTube и действует определенный период времени. Refresh Token нужен для того чтобы генерировать новый Access Token, когда потребуется.Refresh Token не имеет срока давности и может устареть только тогда, когда пользователь заберет права на публикацию у этого приложения. Еще один нюанс, связанный с YouTube: количество загруженных через API видео ограничено, всего 2000 роликов. Поэтому на сервере ведется счетчик публикации и организована возможность добавлять несколько YouTube-аккаунтов. Для публикации видео сервер будет выбирать аккаунт, в котором опубликовано меньше всего роликов.

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

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

Сервис для отправки пуш-уведомлений Так как наше приложение выпущено на iOS и Android, мы поддерживаем и Apple Push Notification Service и Google Cloud Messaging.Стандартная практика такова: сначала приложение запрашивает у мобильного девайса идентификатор возможности показывать push-уведомления. В это время сама операционная система спрашивает у пользователя, хочет ли он принимать их.

c45c19d78df8261b1d8d12f06ed2cf6c.png

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

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

о новых репортажах в общей ленте, о новостях и заданиях, о наградах, присвоенных пользователю. Итог Скажем честно: это был захватывающий опыт разработки продукта, грандиозного не только с технической точки зрения, но базирующегося на глобальной идее — создать огромную сеть гражданских журналистов по всей стране, вывести гражданскую журналистику на профессиональный уровень, предоставив им ресурсы для продвижения силами самого популярного издания России.Приложение запущено в работу. Например, за «Ночь в музее» гражданские репортеры уже получили гонорары. Если вы живете в столице, то прямо сейчас можете побороться за славу и деньги, создав интересные репортажи на тему «Жара в Москве», а новосибирцам «Комсомолка» дает шанс стать богатыми и знаменитыми, отправившись на фотоохоту в городской зоопарк (земляки, поспешите, снимки белого медвежонка Шилки — беспроигрышный вариант!).

Качайте «Спецкор» в Google Play и AppStore.

© Habrahabr.ru