Русский
Русский
English
Статистика
Реклама

Opera

Пишем расширение-читалку для Habr

12.02.2021 08:05:33 | Автор: admin

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

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

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

Автор туториалаАвтор туториала

Шаг 1. Определим состав расширения

Наше расширение будет состоять из нескольких частей:

  • манифест-файл manifest.json с описанием самого расширения, указанием его основных разрешений, прописыванием путей к иконкам, фоновым скриптами т.д.;

  • HTML-страница popup.html и CSS-файл style.css для popup-формы, на которой будет расположена панель управления воспроизведением аудио;

  • фоновый JavaScript-файл content.js, который будет обращаться к странице с открытым постом и воспроизводить её текстовое содержимое;

  • JavaScript-файл popup.js для popup-формы, с помощью которого фоновому скрипту будут передаваться команды пользователя, заданные через popup-форму;

  • иконки расширения 3 размеров: 128x128, 48x48, 16x16 пикселей.

В итоге получаем примерно такую структуру:

Структура проектаСтруктура проекта

Шаг 2. Подготавливаем манифест-файл

С помощью манифеста мы:

  • сообщаем о том, что мы сделали за расширение;

  • указываем, где хранятся его иконки;

  • запрашиваем доступы к вкладкам;

  • сообщаем о том, что будем выполнять фоновые скрипты;

  • указываем, какой popup мы будем использовать.

Здесь также присутствует разрешение на использование localStorage, если вы захотите менять и сохранять настройки без модификации кода. Пример расширения с применением настроек есть у меня на GitHub.

Содержимое manifest.json
{  "manifest_version": 2,  "name": "Habr Reader",  "description": "Расширение позволяет воспроизводить текст на странице со статьей на Хабре с возможностью изменения языка и скорости воспроизведения",  "version": "1.01",  "developer": {    "name": "Enji Rouz",    "url": "https://github.com/EnjiRouz/Habr-Reader-Extension"  },  "icons": {    "16": "res/icon16.png",    "48": "res/icon48.png",    "128": "res/icon128.png"  },  "permissions": [    "storage",    "http://*/*",    "https://*/*",    "tabs",    "contextMenus"  ],  "background": {    "scripts": ["js/content.js"],    "persistent": true  },  "browser_action": {    "default_icon": "res/icon128.png",    "default_popup": "popup.html",    "icon_128": "res/icon128.png"  },  "content_scripts": [{    "matches": ["<all_urls>"],    "js": ["js/content.js"]  }],  "content_security_policy": "script-src 'self' 'unsafe-eval'; object-src 'self';"}

Шаг 3. Делаем popup-форму для управления воспроизведением

С помощью данной формы мы будем ненапрямую:

  • запускать проигрывание синтезированной речи;

  • ставить воспроизведение на паузу;

  • полностью останавливать воспроизведение;

  • менять скорость воспроизведения;

  • менять язык речи с русского на английский, и наоборот.

Для этого нам потребуется сделать в popup.html несколько кнопок для управления воспроизведением, поле для ввода скорости и переключатель для языков. К странице мы привяжем файл стилей style.css, а также скрипт popup.js, который мы будем запускать после того, как форма полностью загрузится. Для этого добавим после его определения ключевое слово defer.

Содержимое popup.html
<!DOCTYPE html> <html lang="en"> <head>     <meta charset="UTF-8">     <link rel="stylesheet" href="css/style.css" type="text/css"/>     <script type="text/javascript" src="js/popup.js" defer></script>     <title>Habr Reader</title> </head> <body> <div class="tool-bar">     <ul>         <li>             <button id="play-button"></button>         </li>         <li>             <button id="pause-button"></button>         </li>         <li>             <button id="stop-button"></button>         </li>         <li>             <label for="speed">Speed</label>             <input type="number" name="speed" id="speed" placeholder="1" value="1" min="0.5" max="2.0"                    step="0.1">         </li>             <li>             <label><input type="radio" name="speech-language" value="ru-RU" id="ru" checked>ru-RU</label>         </li>         <li>             <label><input type="radio" name="speech-language" value="en-US" id="en">en-US</label>         </li>     </ul> </div> </body> </html>
Содержимое style.css
body{    width:180px;    height:60px;    font-family: arial, serif;    font-size: 12px;}.tool-bar{    display: block;    width: 180px;    height: 60px;    line-height: 30px;    background-color: #242424;}.tool-bar ul{    list-style-type: none;    margin: 0;    padding: 0;}.tool-bar ul li{    display: inline-block;    margin: 0;    padding: 0;}button{    background: none;    color: inherit;    border: none;    padding: 0;    font: inherit;    cursor: pointer;    outline: inherit;}.tool-bar ul li button, label{    padding: 0 4px;    text-decoration: none;    color: #FFFFFF;}.tool-bar ul li button:hover{    text-decoration: underline;}input {    width:30px;    padding: 6px 0 4px 10px;    border: 1px solid #9e9e9e;    background: #242424;    border-radius: 4px;    color: #FFFFFF;}

Итоговый вид нашей popup-формы довольно прост и лаконичен. Здесь продемонстрировано, как форма будет отображаться при нажатии на иконку расширения:

Раскрытая popup-форма расширенияРаскрытая popup-форма расширения

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

Упаковку самого расширения мы рассмотрим в конце.

Шаг 4. Передаём управление фоновому скрипту из popup-формы

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

Для этого на каждое событие мы добавим обращение к активной вкладке текущего окна, в котором передадим сообщение. В нём мы укажем следующее:

  • название команды, которую нужно выполнить, например, todo: "play", чтобы сообщить, что мы хотим начать либо продолжить воспроизведение;

  • значения переменных, которые нужны будут для выполнения этой команды, например, newSpeed: speed.value, lang: language,где мы передадим новое значение скорости и языка.

Содержимое popup.js
// определение кнопокconst playButton = document.getElementById("play-button");const pauseButton = document.getElementById("pause-button");const stopButton = document.getElementById("stop-button");// определение полей вводаconst speed = document.getElementById("speed");// назначение действий на соответствующие кнопки/поляif(playButton)    playButton.addEventListener("click", play);if(pauseButton)    pauseButton.addEventListener("click", pause);if(stopButton)    stopButton.addEventListener("click", stop);if(speed)    speed.addEventListener("input", changeSpeed);// применение настроек на странице происходит при помощи их передачи в сообщении,// предназначенном для background скриптаfunction play(){    // определение выбранного языка воспроизведения    let language = document.querySelector('input[name="speech-language"]:checked').value;    chrome.tabs.query({active: true, currentWindow: true}, function (tabs) {        chrome.tabs.sendMessage(tabs[0].id, {todo: "play", newSpeed: speed.value, lang: language});    });}function pause(){    chrome.tabs.query({active: true, currentWindow: true}, function (tabs) {        chrome.tabs.sendMessage(tabs[0].id, {todo: "pause"});    });}function stop(){    chrome.tabs.query({active: true, currentWindow: true}, function (tabs) {        chrome.tabs.sendMessage(tabs[0].id, {todo: "stop"});    });}function changeSpeed(){    chrome.tabs.query({active: true, currentWindow: true}, function (tabs) {        chrome.tabs.sendMessage(tabs[0].id, {todo: "changeSpeed", newSpeed: speed.value});    });}

Шаг 5. Пишем фоновый скрипт для синтеза речи

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

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

Вот, что будет происходить в нашем фоновом скрипте:

  1. При загрузке страницы, содержащей элемент с ID "post-content-body", скрипт будет рекурсивно складывать содержимое текстовых элементов внутри родительского, чтобы сформировать текст для будущего синтеза (это гораздо проще, чем запрашивать разрешение на использование Habr API, но стоит учитывать, что однажды этот ID может поменяться);

  2. По окончании обхода элементов будет выдано сообщение о том, что пост готов к прочтению (но вы можете вместо этого модифицировать код так, чтобы воспроизведение аудио начиналось сразу после подготовки текста);

  3. Далее ожидается действие пользователя через popup-форму. Как только фоновый скрипт получит сообщение от popup-формы с командой и/или значением переменных, то он инициализирует переменные внутри себя и запустит соответствующие функции, например, найдёт голос для нужного языка, а затем начнёт синтез речи в случае нажатия на кнопку воспроизведения.

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

Далее вы можете модифицировать код на своё усмотрение.

Содержимое content.js
// создание средства синтеза речи и получение списка голосовconst synthesis = window.speechSynthesis;const voices = synthesis.getVoices();const utterance = new SpeechSynthesisUtterance();// текущий символ, который синтезируется в данный момент времениlet currentCharacter;// назначение события на момент, когда речь перестанет проигрыватьсяutterance.addEventListener("end", () => {    currentCharacter = null;});// получение символа, который синтезируется в данный моментutterance.addEventListener("boundary", event => {    currentCharacter = event.charIndex;});// переменные: язык речи, скорость проигрывания аудио, воспроизводимый текстlet speechLanguage = "ru-RU";let playerSpeed = 1;let textToPlay = "Открой статью, а потом уже нажимай сюда";/** * Рекурсивно прибавляет текстовое содержимое дочерних элементов для формирования текста поста * @param elementForSearchingIn - родительский элемент, в котором будет осуществляться поиск текстовых нодов */function joinTextNodes(elementForSearchingIn) {    if (elementForSearchingIn.hasChildNodes()) {        elementForSearchingIn.childNodes.forEach(function (node) {            joinTextNodes(node)        });    } else if (elementForSearchingIn.nodeType === Text.TEXT_NODE) {        textToPlay += " " + elementForSearchingIn.textContent;    }}/** * Поиск голоса для заданного языка речи * @param lang - заданный язык речи * @returns {null|SpeechSynthesisVoice} */function findVoice(lang) {    for (let i = 0; i < voices.length; i++) {        if (voices[i].lang === lang)            return voices[i];    }    return null;}/** * Проигрывание синтезированного высказывания */function playTextToSpeech() {    // если проигрывание речи было поставлено на паузу - происходит продолжение проигрывания    if (synthesis.paused && synthesis.speaking)        return synthesis.resume();    if (synthesis.speaking) return;    // определение параметров синтезируемой речи    utterance.text = textToPlay;    utterance.rate = playerSpeed || 1;    utterance.lang = speechLanguage;    utterance.voice = findVoice(utterance.lang);    // проигрывание речи    synthesis.speak(utterance);}/** * Установка проигрывания синтезированной речи на паузу */function pauseTextToSpeech() {    if (synthesis.speaking)        synthesis.pause();}/** * Остановка (прекращение) проигрывания синтезированной речи */function stopTextToSpeech() {    synthesis.resume();    synthesis.cancel();}/** * Изменение скорости речи в режиме реального времени */function changeSpeed() {    if (synthesis.paused && synthesis.speaking) return;    if (currentCharacter === null) return;    stopTextToSpeech();    playTextToSpeech(utterance.text.substring(currentCharacter));}/** * Осуществление взаимодействия pop-up формы с background скриптом при помощи отправки-получения сообщений * в активной вкладке с передачей в них необходимых для работы параметров. * Переданные параметры перезаписывают предыдущие настройки */chrome.runtime.onMessage.addListener(function (request, sender, sendResponse) {    switch (request.todo) {        case "play":            playerSpeed = request.newSpeed;            speechLanguage = request.lang;            playTextToSpeech();            break;        case "changeSpeed":            playerSpeed = request.newSpeed;            changeSpeed();            break;        case "pause":            pauseTextToSpeech();            break;        case "stop":            stopTextToSpeech();            break;    }    sendResponse({        response: "Message received"    });});// подготовка текста поста к чтениюwindow.onload = function () {    let contentBody = document.getElementById("post-content-body");    if (contentBody) {        textToPlay = "";        joinTextNodes(contentBody);        alert("Текст поста готов к чтению")    }};

Шаг 6. Упаковка и установка расширения

Я опишу упаковку и установку для Opera и Chrome. В других браузерах процесс, скорее всего, будет аналогичным, поскольку основные действия мы будем делать через стандартный раздел браузера "Расширения".

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

  • Opera Меню Расширения Расширения включить Режим Разработчика Упаковка расширения

  • Google Chrome Дополнительные инструменты Расширения включить Режим Разработчика Упаковка расширения

На выходе вы получите crx-файл расширения, который, по факту, представляет собой архив с запакованным проектом.

Расширение можно установить через раздел "Расширения" двумя путями:

  • если модификация не требуется - для ряда браузеров достаточно перетащить подготовленный crx-файл из папки с проектом в окно с открытым разделом расширений и нажать на "Установить";

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

Заключение

На этом мой небольшой туториал подошёл к концу.

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

Кстати, мой хороший товарищ сделал на основе моего проекта расширение для того, чтобы оставлять для себя комментарии к объявлениям на Avito. Кому интересно - код и релиз вы найдёте на его GitHub.

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

Спасибо за внимание! До новых встреч!

Подробнее..

Открытые клиенты Hola VPN и Opera VPN

01.05.2021 04:09:42 | Автор: admin

Предлагаю вашему вниманию два простых решения для случаев, когда нужен прокси:

  • Недоступность сетевого ресурса по разным причинам.

  • Гео-ограничения.

  • Потребность спрятать трафик от интернет-провайдера и/или исключить возможность его вмешательства в трафик.

hola-proxy

https://github.com/Snawoot/hola-proxy/

hola-proxy - это клиент для прокси-серверов Hola, который использует то же API для получения доступа к ним, что и браузерное расширение Hola VPN. Соединение с прокси-серверами защищено TLS. Приложению не требуется ни установка, ни права администратора для работы. Имеется в наличии кое-какая устойчивость к попыткам блокировок самих VPN-сервисов. В частности, в отличии от оригинального расширения, приложение успешно работает в Египте.

Отличия приложения от браузерного расширения Hola VPN:

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

  • Убраны почти все ограничения бесплатного доступа.

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

  • Есть возможность использования резидентных IP-адресов в US для того чтобы, например, смотреть американский Netflix, Hulu и другие видео-сервисы с гео-ограничениями, требующими IP-адрес, относящийся к провайдерам потребительского доступа к интернету.

  • Улучшенная устойчивость к блокировкам по сравнению с расширением (у нативного клиента чуть больше возможностей).

  • Открытый исходный код.

  • Запускается на большом ассортименте ОС и аппаратных платформ.

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

Порядок использования:

  1. Скачать отсюда, выбрав исполняемый файл для своей платформы.

  2. Запустить. Станет доступен обычный HTTP-прокси на локальном порте 8080.

  3. Настроить браузер и/или другое ПО на использование HTTP прокси-сервера по адресу 127.0.0.1:8080. Для браузера ради удобства крайне рекомендую использовать расширение SwitchyOmega (Chrome, Firefox).

Примечания:

Если требуются особые настройки (страна, тип прокси), то можно создать ярлык, указав дополнительные параметры командной строки через пробел после имени файла. Справка по параметрам: https://github.com/Snawoot/hola-proxy/#list-of-arguments

Запускать приложение в фоне в Windows можно с помощью "планировщика заданий", назначив старт приложению после запуска системы, либо просто добавив в автозагрузку, если окно терминала в фоне не мешает.

opera-proxy

https://github.com/Snawoot/opera-proxy/

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

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

Порядок использования:

  1. Скачать отсюда, выбрав исполняемый файл для своей платформы.

  2. Запустить. Станет доступен обычный HTTP-прокси на локальном порте 18080.

  3. Настроить браузер и/или другое ПО на использование HTTP-прокси-сервера по адресу 127.0.0.1:18080. Для браузера ради удобства крайне рекомендую использовать расширение SwitchyOmega (Chrome, Firefox).

Примечания:

Обратите внимание, что opera-proxy по умолчанию использует порт 18080, в то время как hola-proxy - 8080.

Справка по параметрам командной строки для выбора региона и других настроек: https://github.com/Snawoot/opera-proxy/#list-of-arguments

Пара слов об Android

Оба приложения работают на Android, не требуя рута. Запустить их можно с помощью любого удобного шелла (приложения-терминала). Я бы порекомендовал Qute, так как оно поддерживает автозапуск и создание ярлыков для скриптов. Для запуска нужно положить бинарь куда-то, где его можно было бы сделать исполняемым. В случае с Qute это /data/data/files/com.ddm.qute

После этого сделать бинарный файл прокси-клиента исполняемым: chmod +x /data/data/files/com.ddm.qute/*-proxy* и запустить его командой или скриптом: /data/data/files/com.ddm.qute/*-proxy*

Перенаправить весь трафик через прокси удобнее всего будет с помощью AdGuard для Android. В его настройках можно установить адрес прокси, куда нужно перенаправить трафик. Важно не забыть добавить в исключения AdGuard само приложение-шелл (в моём примере Qute). В противном случае исходящие соединения прокси будут зацикливаться в сам прокси.

Заслуживают упоминания

  • transocks - демон, который позволяет перенаправлять произвольные TCP-соединения на роутере в SOCKS- или HTTP-прокси.

  • moproxy - аналог предыдущего пункта.

  • Мой прошлый пост о некоторых преимуществах прокси по сравнению с VPN.

Пожалуй, это всё. А наверху на картинке, кстати, муравьед. Вроде бы.

Подробнее..

Opera станет китайской компания из Поднебесной получит основной пакет акций

27.10.2020 18:15:50 | Автор: admin

Новым акционером, владеющим контрольным пакетом акций Opera, станет компания Hong Kong Kunlun, дочерняя организация Beijing Kunlun Tech Co., Ltd. Китайцы намерены выкупить 8,47% акций Opera. Общая стоимость сделки составит $80,145 млн. После ее окончания китайская компания будет владеть 53,88% акций Opera Software.

Photo сredit: adsider.com
В итоге Opera войдет в консолидированную финансовую отчетность Beijing Kunlun Tech Co., Ltd.

Известным веб-браузером Opera владеет норвежская Opera Norway AS с 25-тилетней историей. Компания-разработчик ПО специализируется на веб-браузерах и финансовых технологиях. Общая пользовательская база составляет 360 млн активных пользователей ежемесячно. Ее акции котируются на бирже Nasdaq с 2018 года как OPRA. Согласно годовому отчету Opera Software, операционная прибыль компании за 2019 год составила $208 млн. Выручка Opera Software от доли поиска 41,3%, а за счет рекламы 33,1%.

Стоимость акций Opera с начала 2020 года
Beijing Kunlun Tech Co., Ltd. занимается предоставлением интегрированных дополнительных услуг в интернете, также это крупнейший разработчик веб-игр в Китае. Операционная прибыль Kunlun Tech за 2019 год составила $3,688 млрд. Основатель компании 43-х летний Чжоу Яхуи (Zhou Yahui). На посту генерального директора находился до 2020 года. Сейчас занимает пост председателя и одного из руководителей Opera.

Kunlun Tech стремится стать международной компанией, специализирующейся на интернет-платформах. Сделка станет главной вехой в ее истории. Kunlun Tech желает обладать активами Opera с 2016 года. Ранее сделку в размере $1,2 млрд заблокировал американский регулятор. Тогда китайцам разрешили приобрести только долю компании за $600 млн. Однако она включала права на бренд и браузерный бизнес для мобильных устройств и компьютеров.

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

Подробнее..

Категории

Последние комментарии

  • Имя: Макс
    24.08.2022 | 11:28
    Я разраб в IT компании, работаю на арбитражную команду. Мы работаем с приламы и сайтами, при работе замечаются постоянные баны и лаги. Пацаны посоветовали сервис по анализу исходного кода,https://app Подробнее..
  • Имя: 9055410337
    20.08.2022 | 17:41
    поможем пишите в телеграм Подробнее..
  • Имя: sabbat
    17.08.2022 | 20:42
    Охренеть.. это просто шикарная статья, феноменально круто. Большое спасибо за разбор! Надеюсь как-нибудь с тобой связаться для обсуждений чего-либо) Подробнее..
  • Имя: Мария
    09.08.2022 | 14:44
    Добрый день. Если обладаете такой информацией, то подскажите, пожалуйста, где можно найти много-много материала по Yggdrasil и его уязвимостях для написания диплома? Благодарю. Подробнее..
© 2006-2024, personeltest.ru