Яндекс.переводчик для Linux на Python GUI
- среда, 23 октября 2019 г. в 00:49:02
Приветствую хабражителей!
Довольно давно возникла необходимость в мультиязычном онлайн переводчике при закрытом браузере.
Нет, так то я и словарем в "особо тяжелых" случаях пользоваться не брезгую, но иногда приходится читать немаленький текст, и не все слова я знаю, как следствие теряется контекст.
Вначале был translate-shell...
Translate-shell вещь достаточно удобная, особненно, если пишешь, допустим, в Vi/vim. Переключился в соседнюю консоль и переводи.
Ключи простейшие и запоминаются легко.
$ trans -b -e yandex -t en "Простые ключи."
Simple keys.
или
$ echo -e "\nС перенаправлением.\n"|trans -b -e yandex -t en
With redirection.
Но этого как обычно было мало. Захотелось графики.
Работа в SublimeText и Zeal несколько удобней, нежели голая консоль.
Хм… Подумал-подумал, и решил прикрутить переводчик на горячую клавишу.
Выбор пал на gxmessage. Zenity меня не устроил, уж и не помню почему.
Был написан код:
#!/bin/bash
# Name script trans.sh
TEXT=$(xclip -selection primary -o)
TRANS=$(trans -e yandex -hl en -tl ru -b "$TEXT")
if [ "$TRANS" ]; then
gxmessage -geometry 1000x800 -bg "#aaaaaa" -title "Translate" -wrap -center -font "Menlo Regular 24" "$TRANS"
else
gxmessage -geometry 1000x800 -bg "#aaaaaa" -title "Translate" -wrap -center -font "Menlo Regular 24" "Нет связи с сервисом"
fi
И назначен на Ctrl+1. В IceWm это легко. Правим $HOME/.icewm/keys
key "Ctrl+1" $HOME/progs/trans.sh
Некоторое время меня это устраивало. На "контрол+1" с английского, "контрол+2" на английский. Хорошо...
Но тут translate-shell начал давать сбои.
Не знаю, что произошло у разрабов, но меня это совсем огорчило.
Я решил, пора, давно на питоне не писал.
Недолгие поиски в гугл привели меня к Yandex.API, Python и GTK+ 3 в виде модуля gi.
Почему gi, ведь обычно писал на PyQt5? Он на моей машине работает значительно быстрее. Машина не новая, памяти тоже(по современным меркам) не ахти.
Модуль GTK+ 3 для python был для меня вновинку. Целый вечер разбирался с синтаксисом на сайтах раз, два и три.
#!/usr/bin/env python3.6
# -*- coding: utf-8 -*-
import sys
import requests
import gi
gi.require_version('Gtk', '3.0')
from gi.repository import Gtk
from gi.repository import Gdk
from gi.repository import Pango
import warnings
warnings.filterwarnings("ignore")
import os
CURRDIR = os.path.dirname(os.path.abspath(__file__))
ICON = os.path.join(CURRDIR, 'yandex-48.xpm')
headers = {
'User-Agent': ('Mozilla/5.0 (Windows NT 6.0; rv:14.0) Gecko/20100101 '
'Firefox/14.0.1'),
'Accept':
'text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8',
'Accept-Language':
'ru-ru,ru;q=0.8,en-us;q=0.5,en;q=0.3',
'Accept-Encoding':
'gzip, deflate',
'Connection':
'keep-alive',
'DNT':
'1'
}
URLDETECT = "https://translate.yandex.net/api/v1.5/tr.json/detect"
URLTRANS = "https://translate.yandex.net/api/v1.5/tr.json/translate"
KEY = "you-API-key"
def clip():
clipboard = Gtk.Clipboard.get(Gdk.SELECTION_PRIMARY)
clip = clipboard.wait_for_text()
return clip
def detect():
params = {"key": KEY, "text": clip(), "lang": 'ru'}
respdetect = requests.get(URLDETECT, params=params, headers=headers).json()
if 'lang' in respdetect.keys():
respdetect = respdetect
else:
respdetect = {'code': 200, 'lang': 'en'}
langtetect = respdetect["lang"]
if langtetect != 'ru':
langout = langtetect + '-ru'
else:
langout = 'ru-en'
return langout
def translate():
params = {"key": KEY, "text": clip(), "lang": detect()}
response = requests.get(URLTRANS, params=params, headers=headers).json()
if 'text' in response.keys():
response = response
else:
response = {'code': 200, 'lang': 'en-ru', 'text': ['the buffer is empty']
}
output = ''.join(response["text"])
return output
class TextViewWindow(Gtk.Window):
def __init__(self):
Gtk.Window.__init__(self, title=f"Yandex Translator {detect()}")
self.set_default_size(1000, 350)
self.set_position(Gtk.WindowPosition.CENTER_ALWAYS)
self.grid = Gtk.Grid()
self.add(self.grid)
self.create_textview()
self.create_toolbar()
self.key_Esc = Gdk.keyval_from_name("Escape")
self.connect("key-press-event", self._key)
def create_toolbar(self):
toolbar = Gtk.Toolbar()
self.grid.attach(toolbar, 1, 1, 1, 1)
new_button = Gtk.ToolButton.new_from_stock(Gtk.STOCK_CLOSE)
new_button.set_is_important(True)
toolbar.insert(new_button, 0)
new_button.connect("clicked", self.on_button_clicked, self.tag_bold)
new_button.show()
def on_button_clicked(self, widget, tag):
Gtk.main_quit()
def create_textview(self):
scrolledwindow = Gtk.ScrolledWindow()
scrolledwindow.set_hexpand(True)
scrolledwindow.set_vexpand(True)
self.grid.attach(scrolledwindow, 0, 0, 2, 1)
self.textview = Gtk.TextView()
self.textbuffer = self.textview.get_buffer()
self.textbuffer.set_text(f"{translate()}")
scrolledwindow.add(self.textview)
self.textview.set_wrap_mode(Gtk.WrapMode.WORD)
self.tag_bold = self.textbuffer.create_tag("bold",
weight=Pango.Weight.BOLD)
self.textview.modify_font(Pango.FontDescription('Menlo Regular 24'))
def _key(self, widg, event):
if event.keyval == self.key_Esc:
Gtk.main_quit()
win = TextViewWindow()
win.connect("destroy", Gtk.main_quit)
win.set_icon_from_file(ICON)
win.show_all()
Gtk.main()
В итоге имею автопереводчик на горячей клавише.
Всем спасибо за внимание.
Проект полностью на github.
P.S.: Буду рад критике кода.