Отправка голосовых сообщений ВКонтакте с помощью VK API

Всем, кто работал с VK API, давно известно, что доступ к любой работе с аудиозаписями ВКонтакте был закрыт 16 декабря 2016 года, а информация о голосовых сообщениях вообще отсутствует в документации.

imageНа примере моего пустого сообщества-песочницы

Так как же это делается?

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

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

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

https://api.vk.com/method/docs.getUploadServer?access_token=ACCESS_TOKEN&type=audio_message&v=5.63

Основной момент здесь: параметр type=audio_message.

В ответ мы должны получить следующий JSON:

{   "response":              {                "upload_url":"https://..."              } } 

Как правильно загрузить файл на сервер ВКонтакте

Если отправлять файл не в формате multipart/form-data, ничего не выйдет.
В формате mp3 загрузить аудио тоже не получится, лучше всего использовать ogg, хотя можно и поэкспериментировать.

Можно использовать код отсюда, чтобы загрузить файл в нужном формате (пример указан на Java, аналоги для себя, я думаю, можно найти в интернете):

Используем экземпляр класса MultipartUtility, в нём ничего менять не нужно:

StringBuilder response_sb = new StringBuilder(); try {     MultipartUtility multipart = new MultipartUtility("адрес_сервера_для_загрузки", "UTF-8");      multipart.addFilePart("путь_до_файла_с_голосовым_сообщением");      List<String> response = multipart.finish();      for (String line : response) {        response_sb.append(line);     } } catch (IOException e) {     e.printStackTrace(); }

Всё, аудиосообщение загружено. Ответ от сервера в случае удачи будет похожим на это:

{    "file":"62802565|0|0|805131|многосимволов|ogg|9943|file.ogg|многосимволов|многосимволов||||многосимволов=" } 

Сохраняем документ на сервере

Здесь также важно подметить: если вы сохраните документ не у пользователя, то при отправке он будет выглядеть как документ, а не как голосовое сообщение. Либо же вы отправите просто пустое сообщение.

Делаем следующий запрос:

https://api.vk.com/method/docs.save?file=полученный_ранее_file&access_token=ACCESS_TOKEN&v=5.63

Это была последняя стадия. Получаем ответ:

{     "response": [                     {                         "id": 000000000,                         "owner_id": 000000000                         ...  и ещё куча параметров, которые нам сейчас не нужны                     }                 ] }

Вот и всё. Можно отправлять сообщения обычным способом, в attachments указав ссылку doc(owner_id)_(id), используя owner_id и id, полученные выше.

P.S. Обычный пользователь не может отправить сообщение, содержащее что-то кроме записи голоса. А через API это делается очень легко. Раньше это работало и в комментариях/обсуждениях и так далее, но сейчас, видимо, лавочку прикрыли, как и загрузку голосовых сообщений сообществами.


Я не являюсь автором «расследования» по поиску способа отправки аудиосообщений через API, я лишь собрал всю информацию в кучу и постарался красиво оформить. Заметил на просторах интернета много вопросов по этому поводу.

Данная статья написана для тех, кто работал с ВКонтакте API, и описывать неинтересные вещи я не стал, стараясь писать лишь по делу. Если решусь, напишу еще пару статеек о том, как написать бота на Java с использованием LongPoll-сервера VK (для личных страниц) и с использованием Callback API и web-сервлетов (для сообществ).

За предоставленные материалы и помощь благодарность Станиславу Куделко.
ссылка на оригинал статьи https://habrahabr.ru/post/327280/

UIKit + Viper или MVC здорового человека

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

Введение

Начитавшись туториолов о Viper я начал пробовать создать на нем новый проект. В итоге мой Viper выглядел примерно так:

image
Рядом с каждым блоком подписан базовый класс. Стрелками обозначены ссылки между объектами (пунктиром — weak).

Данная схема не решает крайне важную проблему. Каким образом располагать модули в UINavigationController? Из-за того, что стек навигации необходимо добавлять наследников класса UIViewController.

  • придется в router протягивать view через presenter и явно указывать, что это UIViewController
  • после добавления view в UINavagationController, у view счетчик сильных связей увеличится до 2-х. В последствии придется вручную убирать из памяти viper модуль.

В таком подходе очевидна некоторая несовместимость Viper и UIKit.

Как подружить Viper и UIKit

В первую очередь необходимо понять, как перейти от Apple MVC к Viper. MVC достаточно легко раскладывается на view, presenter и interactor. Но у viper появляется еще дополнительный слой — router. И на этом моменте я предлагаю альтернативную точку зрения(во всяком случае на просторах интернета я ничего подобного не видел).

image

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

В ней сказано:

Presenter/Презентатор

Presenter — это PONSO, который в основном состоит из логики, чтобы управлять UI. Он собирает входные данные от взаимодействия с пользователем, таким образом, он может отправлять запросы Interactor’у. Presenter также получает результаты Interactor’а и преобразовывать результаты в состояние, которое является наиболее эффективным для отображения на View.

Entity никогда не передаются из Interactor’а к Presenter’у. Вместо этого простые структуры данных, у которых нет поведения, передаются из Interactor’а к Presenter’у. Это препятствует любой ‘реальной работе’ в Presenter’е. Presenter может только подготовить данные для отображения на View.

Если в качестве presenter взять не PONSO, а UIViewController, что изменится? Да presenter начнет отвечать за отображение модуля, но только под капотом UIKit. Все методы жизненного цикла, можно расценивать по такому же принципу, как события от кнопок view. То есть view сообщает presenter, что случился viewdidload и с этим можно что-то сделать. Вся логика отрисовки осталась на view.

Теперь давайте рассмотрим router(в статье изображен, как wireframe. Я обычно разделяю на router и moduleManager)

Wireframe/Каркас

Маршрутизация обрабатывает навигацию от одного экрана к другому, как определено в wireframes, созданных проектировщиком взаимодействия. Wireframe объект несет ответственность за маршрутизацию. Wireframe объект владеет объектами UIWindow, UINavigationController, и т.д. Он ответственен за создание Interactor, Presenter и View/ViewController и за настройки ViewController. Так как Presenter содержит логику, чтобы реагировать на ввод данных пользователем, Presenter знает, когда перейти на другой экран. Wireframe знает, как это сделать. Итак, Presenter — это пользователь Wireframa.

Встает вопрос. Почему router не может сам являться UINavigationController? Зачем нам еще велосипед, когда в UIKit есть свои роутеры — это UINavigationController и сочувствующие. В подобных классах уже заложена основная логика.

Что решает такой подход?

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

В качестве примера я создал небольшой демо проект. Надеюсь на объективную дискуссию.
ссылка на оригинал статьи https://habrahabr.ru/post/327262/

Открываем доступ к видеозаписям HighLoad++ за последние пять лет

image

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

Более терабайта записей и 500 видеороликов! Это всё, под катом только реклама 🙂

Перейти в канал YouTube!

Это не все наши материалы. Многие из роликов мы расшифровываем и делаем из них обучающий онлайн-курс по разработке высоконагруженных систем HighLoad.Guide — это цепочка специально подобранных писем, статей, материалов, видео. Уже сейчас в нашем учебнике более 40 уникальных материалов. Подключайтесь!

А сейчас мы готовим две конференции, интересные разработчикам сложных проектов:

  • Профессиональная конференция серверных разработчиков Backend Conf
  • Обучающая конференция разработчиков высоконагруженных систем HighLoad++ Junior

5 и 6 июня, Москва, Сколково в рамках фестиваля "Российские интернет-технологии".

ссылка на оригинал статьи https://habrahabr.ru/post/327276/

Разработка ускоренной главной страницы BBC News

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

Это был апрель 2016. Сейчас, спустя год, мы готовы начать поэтапный переход на новую главную страницу. Начиная с небольшого процента пользователей из Великобритании, мы постепенно переведем всех на новую главную страницу в течении нескольких недель. Если же вам нетерпится увидеть её прежде чем переход будет завершен, она доступна по адресу www.bbc.co.uk/news/0

Быстрые факты о новой главной странице

  • Она более легкая и быстрая, чем предыдущая:
  • Сайт доступен через HTTPS и в ближайшем будущем мы планируем перенаправлять на него весь незащищенный трафик.
  • Страница основана на React компонентах, которые стилизованы нашим CSS фреймворком Grandstand.
  • Каждый компонент это горизонтальный «ломтик» страницы, который собирает свои данные. Это облегчает для нас использование «ломтиков» на любой странице.
  • Все компоненты React рендерятся с помощью нашего React-component-as-an-API-endpoint сервиса и соединяются в страницу page-assembly-as-a-service сервисом.
  • React используется только на сервере. Мы не загружаем его на стороне браузера.
  • Команда разработчиков состоит из пяти разработчиков и одного тестировщика, но мы также сотрудничаем с более чем 60 разработчиками и тестировщиками со всего BBC.

Что дальше?

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

Улучшение производительности

Несмотря на то что мы уже существенно улучшили её производительность, все еще много работы только предстоит сделать:

  • Первая значимая отрисовка все еще длинная. Мы можем улучшить её загружая основной CSS раньше.
  • Мы все еще отправляем слишком много байт пользователю. Большая часть из этого — инлайн стили, которые используются только в IE8 (Обновление: Мы уже отправили pull request чтобы удалить треть этих стилей).
  • Пересчет стилей и макетов идет слишком долго на маломощных устройствах. Это все еще требует изучения.
  • Мы основательно связаны «белой панелью BBC», расположенной вверху страницы. Эта панель содержит компоненты из других частей BBC: поиск, уведомления и BBC ID. Все эти компоненты загружают свой блокирующий CSS и Javascript перед ресурсами главной страницы. Хотя это навряд изменится в ближайшем будущем, мы надеемся поработать с командами которые разрабатывают эти компоненты чтобы уменьшить их влияние на производительность.

Усовершенствование дизайна

Чтобы запустить главную страницу быстрее, мы пошли на многие компромисы с UX и редакторской командами по поводу дизайна страницы. После того как мы закончим с внедрением, мы будем улучшать визуальную часть блока историй (промо) чтобы выделить истории корреспондентов и избранные частицы. Текущий дизайн выглядит так:

image

Ниже одно из предложений как мы можем показывать другие типы промо:

image

React в браузере

На раннем этапе мы решили что React в браузере будет излишним для страницы на которой в основном статичные тексты и изображения. Влияние на произодительность от объединения такого количества Javascipt’а и выполнения его в браузере также непозволительно высокое. Даже используя рендеринг на стороне сервера, эмулируемые мобильные устройства тратили на выполнение скриптов и прорисовку почти в 4 раза больше времени когда React был запущен на странице.

image

Без React на странице

image

Влияние React в браузере

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

  • Использование Preact вместо React.
  • Конвертация наших компонентов в stateless functional components где это возможно, чтобы уменьшить их размер.
  • Использовать умное разделение кода чтобы иметь возможность подгружать второстепенный код по запросу.

Источник перевода
ссылка на оригинал статьи https://habrahabr.ru/post/327274/

«Криптография в блокчейнах»: о хеш-функциях, ключах и цифровых подписях

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

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


/ изображение BTC Keychain CC

Хеш-функции

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

Хеш-функции имеются практически в любом языке программирования. Например, они используются для реализации хеш-таблиц и множеств (HashMap/HashSet в Java, dict и set в Python, Map, Set и объекты в JavaScript и так далее). Отдельная категория хеш-функций — криптографические хеш-функции. К ним предъявляются существенно более строгие требования, чем к функциям, обычно используемым в хеш-таблицах. Поэтому и применяются они в более «серьезных» случаях, например для хранения паролей. Криптографические хеш-функции вырабатываются и тщательно проверяются исследователями по всему миру.

Поэкспериментировать с хеш-функциями можно, написав простую программу на Python:

import hashlib def hash_hex(message):     return hashlib.sha256(message.encode()).hexdigest()

Функция hash_hex() рассчитывает представление хеша в шестнадцатеричной записи для строки. В приведенном примере используется функция SHA-256 — та же, что и в биткойне.

Хорошая хеш-функция обеспечивает защиту от коллизий (невозможно получить два одинаковых хеша при разных начальных данных) и обладает так называемым эффектом лавины, когда малейшее изменение входных данных значительно преобразует выходное значение. Эффект лавины в хеш-функции SHA-256 выглядит следующим образом:

>>> hash_hex('Blockchain') '625da44e4eaf58d61cf048d168aa6f5e492dea166d8bb54ec06c30de07db57e1' >>> hash_hex('blockchain') 'ef7797e13d3a75526946a3bcf00daec9fc9c9c4d51ddc7cc5df888f74dd434d1' >>> hash_hex('Bl0ckchain') '511429398e2213603f4e5dd3fff1f989447c52162b0e0a28fe049288359220fc'

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

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

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

import hashlib      def merkle_root(lst):     # Биткойн использует для склеивания хешей два прогона SHA-256 и изменение      # порядка байтов. Зачем, не до конца понятно.     sha256d = lambda x: hashlib.sha256(hashlib.sha256(x).digest()).digest()     hash_pair = lambda x, y: sha256d(x[::-1] + y[::-1])[::-1]      if len(lst) == 1: return lst[0]          # Дублирование элементов в дереве приводит к интересной уязвимости -     # получается, что различные списки транзакций могут иметь один и тот же хеш.     # По этой причине в биткойне даже есть специальный комментарий,     # предостерегающий разработчиков новых криптовалют:     # https://github.com/bitcoin/bitcoin/blob/master/src/consensus/merkle.cpp#L9     if len(lst) % 2 == 1:         lst.append(lst[-1])     return merkle_root([ hash_pair(x, y)          for x, y in zip(*[iter(lst)] * 2) ]) 

Хеш-деревья имеют много применений помимо блокчейнов. Они используются в файловых системах для проверки целостности файлов, распределенных БД для быстрой синхронизации копий и в управлении ключами для надежного журналирования выдачи сертификатов. Git использует обобщение хеш-деревьев — направленные ациклические графы на основе хешей. В блокчейне использование хеш-деревьев продиктовано соображениями производительности, так как они делают возможным существование «легких клиентов», которые обрабатывают лишь малую часть транзакций из блокчейна.

Цифровые подписи

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

Существует множество различных схем криптографии с открытым ключом. Две самые популярные из них — это схемы на основе разложения на множители (RSA) и схемы на основе эллиптических кривых. Последние более популярны в блокчейнах из-за меньшего размера ключей и подписей. Например, в биткойне используется стандарт эллиптической криптографии ECDSA вместе с эллиптической кривой secp256k1. В ней закрытый ключ имеет длину 32 байта, открытый — 33 байта, а подпись — около 70 байт.

Общая идея подписей с открытым ключом выглядит следующим образом. Предположим, что Алиса хочет перевести Бобу один биткойн. Для этого она формирует транзакцию, где записывает, откуда его следует брать (указание на предыдущую транзакцию, в которой Алиса получила биткойн от кого-то еще) и кому отправить (открытый ключ Боба). Алиса знает открытый ключ Боба из сторонних источников — Боб может послать его Алисе через мессенджер или даже опубликовать его на сайте.

Затем Алиса подписывает транзакцию, используя свой секретный ключ. Любой узел в биткойн-сети может проверить, что транзакция подписана определенным открытым ключом (аутентификация), с которым до выполнения транзакции был ассоциирован один биткойн (авторизация). Если эти условия выполнены, то переведенный биткойн начинает ассоциироваться с открытым ключом Боба.

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

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


P.S. В наших следующих постах мы планируем затронуть такие моменты, как смарт-контракты и алгоритмы консенсуса, а также поговорить о том, что будет означать распространение квантовых компьютеров для блокчейна.
ссылка на оригинал статьи https://habrahabr.ru/post/327272/