Автоматический переводчик выделенного текста в Ubuntu

Результат перевода

Результат перевода

Здравствуйте! Началось всё с того, что я узнал о утилитке xsel, которая с опцией -o выводит содержимое мышиного буфера обмена (ну тот самый, который «выделил — нажал среднюю кнопку мыши») в STDOUT. Немедленно возникло жгучее желание использовать это знание во благо. Немного поразмыслив я неожиданно понял, что нащупал решение давней проблемы, возникающей при чтении англоязычных статей. Я не могу похвастаться высоким уровнем знания языка, но рабочие задачи заставляют читать англоязычную документацию, что заметно подтянуло уровень. Однако, часто встречаются слова ради которых приходится лезть в переводчик. И это не очень удобно. Как можно заметить на скриншоте, проблему я успешно решил, а в этой статье расскажу об этом подробнее.

Постановка задачи

Первым делом я изучил выдачу поисковиков по этому вопросу. Наткнулся на статью о всплывающих уведомлениях на help.ubuntu.ru. В качестве примера использования там как раз предлагали написать скрипт-переводчик. Я уже почти расслабился, но тамошний скрипт обладал рядом недостатков:

  • самый главный: его писал не я
  • перевод только в одну сторону ввиду использования грязного приёма с парсингом ответа страницы переводчика
  • скрипт не работает: гугл сделал платным доступ к API переводчика и все старые лазейки с бесплатным переводом были прикрыты

Таким образом, задача свелась к поиску бесплатного API для переводов. И я быстро нашёл его: API Яндекс.Переводчика. В бесплатной версии API позволяет переводить до 10 миллионов символов в месяц и не более 1 миллиона символов в сутки. Такого лимита вполне достаточно для моих задач.

Погнали же уже!

Погнали! Пишем на python скрипт, принимающий в качестве параметра строку текста и возвращающий нам перевод этой строки. Причём я решил проапгрейдить немного изначальную идею и добавил автоматическое определение языка исходной строки. Логика работы такая: если на вход передана строка на русском, то переводим её на английский. Если на входе строка на любом другом языке, переводим на русский. Для этого потребовалось делать лишний запрос к API, но при моём сценарии использования это не отражается на быстродействии и не приводит к исчерпанию лимита бесплатного API. Итак, установим необходимые пакеты:

apt-get install xsel notify-osd

после чего создадим файл и назовём его, к примеру, yatranslate.py:

#!/usr/bin/python3.4

#!/usr/bin/python3.4

import urllib.request
import urllib.parse
import json
import codecs
import sys

APIKEY='trnsl.1.1.20151211T093839Z.8d3588d6cfec6343.3c4423c7f871b1263a5eaf3d3660226649fd53db'
try:
	TEXT = urllib.parse.quote(sys.argv[1])
except IndexError:
	print("Нет текста")
	sys.exit(0)

#Detect language
reader = codecs.getreader("utf-8")
try:
	response = urllib.request.urlopen('https://translate.yandex.net/api/v1.5/tr.json/detect?key=%s&text="%s"' % (APIKEY, TEXT))
except urllib.error.HTTPError:
	print("Запрос не удался")
	sys.exit(0)

obj = json.load(reader(response))

LANG=obj['lang']

if LANG == 'ru':
	#Если текст на русском, то переводим на английский
	LANG = 'en'
elif LANG == '':
	print("Язык не определён")
	sys.exit(0)
else:
	LANG='ru'

#Translate
try:
        response = urllib.request.urlopen('https://translate.yandex.net/api/v1.5/tr.json/translate?&format=plain&option=1&key=%s&text=%s&lang=%s' % (APIKEY, TEXT, LANG))
except urllib.error.HTTPError:
        print("Запрос не удался")
        sys.exit(0)

obj = json.load(reader(response))
print("%s~%s" % (obj['lang'],obj['text'][0]))

И не забыть сделать его исполняемым:

chmod +x yatranslate.py

Результатом работы скрипта будет строка вида: en-ru~тест. Символ «~» нужен для того, что бы легко отделить направление перевода от результата перевода и красиво оформить вывод во всплывающем уведомлении. Тильда выбрана потому, что редко встречается в текстах. Можно использовать любой удобный символ.

Итак, скрипт есть. Но пока я не сильно ушёл от перевода с помощью переводчика в браузере. Самое время создать второй файлик и назвать его, скажем, yatranslate_notify.sh:

#!/bin/bash

text=`xsel -o`

if [ "$text" == "" ]; then
	exit 0
fi

translated=`~/Dropbox/Scripts/yatranslate/yatranslate.py "$text"`

lang="`echo $translated | cut -d "~" -f1`"
text="`echo $translated | cut -d "~" -f2`"

notify-send "$lang" "$text"

Он тоже должен быть исполняемым:

chmod +x yatranslate_notify.sh

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

Всплывающее уведомление с результатом перевода

Всплывающее уведомление с результатом перевода

Но никакой магии пока не случилось. Что-бы случилась магия, нужно привязать вызов нашего скрипта yatranslate_notify.sh на сочетание клавиш. Я для себя выбрал Alt+T (T от Translator). Для этого необходимо зайти в настройки системы в раздел клавиатура, выбрать там вкладку «сочетание клавиш» и нажать «+» в нижней части окна. В появившемся окне нужно ввести произвольное название для нового сочетания клавиш и полный путь до скрипта yatranslate_notify.sh в поле «команда». После добавления новой комбинации нажать на надпись «выключено» и нажать на клавиатуре желаемое сочетание клавиш. Причём, для работы ускорителя в любой раскладке, необходимо создать столько комбинаций, сколько раскладок вы используете. Сочетание клавиш, разумеется, нужно тоже нажимать в каждой раскладке по очереди.

translator3

Ну и на этом всё. Переводите на здоровье!