Пользователь
0,0
рейтинг
29 января 2012 в 14:23

Администрирование → Перевод выделенного текста с любого языка на русский

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

Я хочу рассказать, как получить перевод выделенного текста в виде оповещения рабочего стола.


У многих десктопных «словарей» есть функция для перевода выделения, которая как раз и предназначена для того, чтобы «не лазить в словарь», но почему-то у меня всегда были с ней проблемы: не переводит, когда нужно; переводит, когда не нужно и т.д.

Наверняка, многие из вас видели различные скрипты для использования google translate из консоли, но я считаю этот способ неудобным в большинстве случаев, не смотря на то, что предпочитаю CLI.

Я подумал, что неплохо было бы иметь возможность быстро переводить выделенный текст или слово и видеть результат, в виде оповещения рабочего стола.
Остаётся только совместить google translate cli + selections + notifications.

Решение


Очень простой интерфейс для отправки уведомлений из консоли предоставляет утилита notify-send, которую можно найти в пакете libnotify-bin. Пример:
notify-send 'title' 'message'
Даст следующий результат


Для получения текущего выделения в X Window System используется утилита xsel.
xsel -o
Выведет текущий selection в стандартный поток вывода.

Шаг 1
Устанавливаем необходимые пакеты:
sudo apt-get install libnotify-bin xsel
Я уверен, что каждый знает, как устанавливать пакеты в своей системе, поэтому не привожу примеры.

Шаг 2
Создаём файл с именем seltr и копируем в него следующие 2 строки:

#!/usr/bin/env bash
notify-send -u critical "$(xsel -o)" "$(wget -U "Mozilla/5.0" -qO - "http://translate.google.com/translate_a/t?client=t&text=$(xsel -o | sed "s/[\"'<>]//g")&sl=auto&tl=ru" | sed 's/\[\[\[\"//' | cut -d \" -f 1)"

Параметр -u critical нужен для того, чтобы оповещение могло перекрывать любые окна.

Параметры запроса google translate:
text=$(xsel -o | sed "s/[\"']//g") → исходный текст — текущий selection с вырезанными ' и ".
sl=auto → автоопределение исходного языка.
tl=ru → язык результата — русский.

Шаг 3
Делаем этот файл исполняемым и перемещаем его в /usr/bin/:
sudo chmod 777 ./seltr && sudo mv ./seltr /usr/bin/

Шаг 4
Теперь остаётся назначить комбинацию клавиш на команду seltr(мой выбор — alt+5). Для этого можно воспользоваться стандартными сердствами, которые предоставляет ваша рабочая среда, либо использовать xbindkeys.

Как это работает


  • Выделяем какой-нибудь иностранный текст(на любом языке), в любом окне.
  • Нажимаем alt+5.
  • Получаем перевод.

Немного скриншотов


Английский

Немецкий

Французский

Украинский

Китайский


Плюсы и минусы


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

- Не работает без подключения к интернету.
- Нет возможности выделить текст перевода.
*Проверенно в Unity, GNOME2, Xfce4, KDE4.
Гуменюк Егор @boo1ean
карма
39,0
рейтинг 0,0
Реклама помогает поддерживать и развивать наши сервисы

Подробнее
Реклама

Самое читаемое Администрирование

Комментарии (87)

  • 0
    Эм… Wellcome?
    • +2
      Исправил.
      Засиделся я вчера допоздна просто)
  • +3
    Так вот чего мне не хватало! Спасибо, очень удобная вещь!
  • +4
    Работает! :)
    Спасибо, пригодится

    image
  • 0
    А как оно с гуглопереводчиком связывается? Translate API вроде платный же сейчас?
    • +8
      В скрипте не видно? Тупо представляется браузером.
      • 0
        Упс, точно, спасибо.
        • +1
          Еще можно воспользоваться альтернативными переводчиками. Все равно высокого качества не достичь.
          Microsoft с ее колоссальными прибылями не скоро апи прикроет.
    • –8
      … wget -U «Mozilla/5.0»…
      Автор хачерит.
  • 0
    Ещё два минуса (вторая вообще ко всем таким программам, что перепробовал):
    — нет возможности (не описана?) забиндить просто на события выделения мышью только в некоторых прогах
    — нет возможности настроить размер шрифта.

    Объясню юз-кейс: часто читаю книги и статьи с экрана, лёжа на диване и пользуясь беспроводной мышью для листания и т. п. Естественно шрифт/масштаб ставлю покрупнее чем когда сижу за компом, но вот большинство переводчиков/словарей выводят фиксированным шрифтом и их всплывающие окна с переводом даже не реагируют на увеличение шрифта их основного окна.
  • +1
    Чаще всего переводить приходится текст в браузере, для браузера есть уже специальные расширения, где можно переведенный текст выделить и пр. Ну если вне браузера что-то нужно что-то глянуть, то такой скриптик может и понадобится конечно.
    • +2
      Ну мне, например, чаще PDF приходится читать. С английским нет проблем, а вот остальные…
    • +1
      Вот так, тупо в лоб, должно работать:
      echo >> ~/notes.txt && echo >> ~/notes.txt && date >> ~/notes.txt && xsel -o >> ~/notes.txt && echo >> ~/notes.txt && notify-send "Эаметка добавлена" "$(xsel -o)"
    • 0
      Сорри, не вам…
  • НЛО прилетело и опубликовало эту надпись здесь
    • НЛО прилетело и опубликовало эту надпись здесь
      • +1
        Не исполнил, а не заэкранировал :) Используйте &lt; вместо <
        • НЛО прилетело и опубликовало эту надпись здесь
          • +2
            Кнопка code это обычный html тег, специального поведение у него не предусмотрено.
  • +2
    Очередное «спасибо» автору, а я сижу теперь и пилю скрипт для использования в качестве общесистемных заметок. Чтобы по хоткею выделенный текст добавлялся в специальный файлик, по типу «добавить в заметки» в Опере.
    • +2
      О! Меня такая же мысль посетила.
      Дату, время, да текст. Скрипт простой выйдет. Доберусь до дома — сделаю.
    • +4
      Вот, писал вам, промахнулся: habrahabr.ru/blogs/linux/137215/#comment_4569017
  • 0
    У меня в Debian testing c Xfce4 notify-send не заработал :-( ничего не показывает. Покопаюсь в логах…
    • 0
      Странно, именно Xfce я проверял на дебиане.
    • 0
      notification daemon запущен?
      • 0
        не было. Установил xfce4-notifyd — он такой минималистический, что даже затухать по таймауту не умеет. Думаю, менять-ли его на notification-daemon или ну его :-)
  • 0
    Google Translator для краснопанды как-то привычнее. Не особо люблю, когда в уведомлениях что-то всплывает лишнее.
  • 0
    Для возможности копирования перевода можно использовать:

    zenity --info --title=«Титл» --text=«текст»
    или загонять перевод сразу в буфер
    • 0
      использовать например для работы с буфером xclip
      • 0
        Это понятно, но просто не хочется всякий раз при переводе слова затирать буфер, ведь там может лежать что-то нужное. Если бы это было критически необходимо, я бы лучше сделал 2 команды на разные shortcut-ы:
        1 — без записи в буфер.
        2 — с записью.
        • 0
          можно и так, а можно и первый вариант мною предложенный (изменить тип оповещения)
        • 0
          можно так же вести лог переводов…
          • 0
            Кстати, у меня были идеи по этому поводу, даже хотел мониторить этот «лог» через conky.
            • 0
              ну записать не проблема:
              echo «text» >> filename
              потом парсить файл и выводить в коньки
              • 0
                сделать в скрипте вывод и в коньках примерно следующее:
                ${execi 3600 /путь/до/скрипта/наш_скрипт.sh}
              • 0
                Ну, всё дело в том, что я понял, что мне это не нужно)
                • +1
                  Хорошо что поняли до того как сделали))) не потеряли время)
    • +1
      Версия с копированием в буфер перевода:
      #!/usr/bin/env bashtext="$(xsel -o)"
      translate="$(wget -U "Mozilla/5.0" -qO - "http://translate.google.com/translate_a/t?client=t&text=$(xsel -o | sed "s/[\"'<>]//g")&sl=auto&tl=ru" | sed 's/\[\[\[\"//' | cut -d \" -f 1)"
      echo $translate | xclip -selection clipboard # Копировать перевод в буфер
      notify-send -u critical $text $translate
      • +1
        Съело энтер:
        #!/usr/bin/env bash
        text="$(xsel -o)"
        ...
      • +1
        сори, так переводит только первое слово. Выкладываю рабочую версию
  • +1
    великолепно! спасибо.
  • 0
    оффтоп, но может кто знает утилиту, аналогичную xsel, но способную достать не только текст, но и картинки/ссылки/другие объекты из выделения?
  • 0
    Было бы еще хорошо направление перевода определять по текущей раскладке. Например при английской раскладке — переводить текст на английский, при русской — на русский соответственно и т.д.
  • 0
    Подобное использую под Win translateclient.com/ru/
  • +1
    Супер, спасибо большое!
  • +4
    вдохновившись идеей (мерси за оную кстати, крайне полезная) и необходимостью поисследовать Питон (пардон если код, эмм, неоптимален и излишен), сваял быстрое дополнение для вывода более подробного перевода.

    Запуск выглядит так:

    notify-send -u critical "$(xsel -o)" "$(python /path/to/tran.py "$(xsel -o | sed "s/[\"'<>]//g")")"


    a сам скрипт /path/to/tran.py вот так:

    import httplib, urllib, argparse, re
    
    def argparser():
        parser = argparse.ArgumentParser(description='Instant Translator')
        parser.add_argument('phrase', metavar='p', type=str,
                            help='phrase to translate')
        args = parser.parse_args()
        return args.phrase
    
    def retrieve(host, path):
        request = httplib.HTTPConnection(host)
        request.request("GET", path, "", {'User-Agent' : 'Mozilla/5.0'})
        response = request.getresponse()
        if response.status > 200:
            return '[["{}"],"ERROR"]'.format(response.reason)
        return response.read()
    
    def parse_item(item, depth = 0):
        if type(item) is str:
            if len(item) == 0:
                return ''
            return "{}{}\n".format("\t" * depth, item)
        result = ''
        for sub_item in item:
            result += parse_item(sub_item, depth + 1)
        return result
    
    phrase = argparser()
    host = 'translate.google.com'
    URL = 'translate_a/t?client=t&sl=auto&tl=ru&' + urllib.urlencode({'text' : phrase})
    
    response = re.sub(',{2,}', ',', retrieve(host, "/" + URL))
    try:
        translated = eval(response)
        result = ''
        for item in translated:
            if type(item) is str:
                result = "Translation: {} > ru\n\n{}".format(item, result)
                break
            result += parse_item(item, -1)
        print result
    except RuntimeError as ex:
        print "Something went wrong ({}): {}".format(response, ex)
    


    результат примерно таков:

    image
    • 0
      Я до питона еще не добрался, так что подсказывайте :)
      ImportError: No module named argparse
      • 0
        argparse, похоже, довольно новый класс — но он там «чисто для понта» — начало можно переписать через простые аргуметны комстроки, как

        import httplib, urllib, re, sys
        
        def argparser():
            return sys.argv[1]
        
        def retrieve(host, path):
            request = httplib.HTTPConnection(host)
        ...
        

        • 0
          Сделал так (что было закомментил):

          Traceback (most recent call last):
          File "/home/ploop/tran.py", line 23, in response = re.sub(',{2,}', ',', retrieve(host, "/" + URL))
          File "/usr/lib/python2.6/re.py", line 151, in sub
          return _compile(pattern, 0).sub(repl, string, count)
          TypeError: expected string or buffer
          No summary specified.
          • 0
            в 2.6 как-то format не так работает — переписал с конкатенацией, запустилось на Питоне 2.6.6 (и даже, если переделать ловлю ексепшна в конце как
            except RuntimeError:
                print "Something went wrong ({})".format(response)

            на 2.4

            попробуйте плиз:

            import httplib, urllib, re, sys
            
            def argparser():
                return sys.argv[1]
            
            def retrieve(host, path):
                request = httplib.HTTPConnection(host)
                request.request("GET", path, "", {'User-Agent' : 'Mozilla/5.0'})
                response = request.getresponse()
                if response.status > 200:
                    return '[["{}"],"ERROR"]'.format(response.reason)
                return response.read()
            
            def parse_item(item, depth = 0):
                if type(item) is str:
                    if len(item) == 0:
                        return ''
                    return ("\t" * depth) + item + "\n"
                result = ''
                for sub_item in item:
                    result += parse_item(sub_item, depth + 1)
                return result
            
            phrase = argparser()
            host = 'translate.google.com'
            URL = 'translate_a/t?client=t&sl=auto&tl=ru&' + urllib.urlencode({'text' : phrase})
            
            response = re.sub(',{2,}', ',', retrieve(host, "/" + URL))
            try:
                translated = eval(response)
                result = ''
                for item in translated:
                    if type(item) is str:
                        result = "Translation: " + item + " > ru\n\n" + result
                        break
                    result += parse_item(item, -1)
                print result
            except RuntimeError as ex:
                print "Something went wrong ({}): {}".format(response, ex)
            • 0
              Во, это нормально! Спасибо!

              image
    • 0
      запуск слизнуло — там всё как в оригинальном решении, notify-send -u critical "$(xsel -o)" "$(python /home/halien/devel/my/python/tran.py "$(xsel -o | sed «s/[\»'<>]//g")")"
  • 0
    Для консольного перевода в Linux есть программа dict.
    • 0
      плюс гуглоперевода в том что он переводит и фразы (как — это другой вопрос =)
      • 0
        Да как бы не переводил, но смысл понять можно, особенно когда с китайского переводишь :)
  • 0
    Stardict отлично переводит выделенные слова по нажатию клавиши Win, давно пользуюсь — всё работает
  • +1
    Для CentoOS5 rpm пакет xsel не найден ((
    пришлось собрать (i386) t.co/Gr2OKXeI, (src.rpm) t.co/W0B8asbY
  • 0
    Идея не плоха, и реализовать не сложно, но, может быть, Вы не пробовали GoldenDict? (не рекламы ради)
    Сам пробовал разные подобные словари, но у многих есть свои «особенности», остановился на этом варианте, так как работает нормально, словари неплохи (поддерживает много форматов), по нажатию нужной клавиши показывает перевод.
  • +2
    > sudo chmod 777 ./seltr
    Страсти какие а
    > sudo chmod +x ./seltr
    не судьба?
    • 0
      > sudo chmod +x ./seltr

      Не на всех системах отработает одинаково ;)
      Лучше написать chmod a+x ./seltr
  • 0
    В качестве альтернативы описанному методу — GoldenDict по хоткею выдает всплывающее окно с переводом. В нем отсутствуют указанные минусы.
    Правда, его нужно предварительно настроить (как минимум, добавить необходимые словари). Зато к нему можно подключать множество форматов словарей (в том числе от Lingvo, и в том числе многие онлайновые). Имхо, лучший словарь из существующих под Linux — удобный, функциональный и стабильный.
    • 0
      Сорри, вкладка со статьей долгое время была открыта и комментария выше (через один от моего) не видел.
    • 0
      Шрифт у этого всплывающего окна дюже мелкий :(
      • +2
        В основном окне «Ctrl»+«+» несколько раз (либо в меню «View — Zoom — Zoom in», либо соответствующие значки на панели) — и проблемы больше нет ;)
        • 0
          Хм, пробовал буквально неделю назад, когда в очередной раз выбирал переводчик — не работало. И сейчас как-то не сразу сработало. Только когда последний раз решил проверить, чтобы точно написать, что это было ожидаемым поведением, но оно не реализовано.
  • 0
    Спасибо за метод, на lxde под ubutu работает
  • +1
    Подскажите, какой шрифт используется в оповещениях, внезапно очень нравится.
    • 0
      мне кажется что эта ссылка поможет ответить на ваш вопрос — font.ubuntu.com/
  • 0
    Текст можно скопировать из уведомления?
    • 0
      В ubuntu — нет. При наведении мышью уведомление размазывается и становится прозрачным, чтобы за ним был доступен интерфейс.
      Обратите внимание на мой скриншот на несколько постов выше — приходится намеренно выделять область больше, чтобы не размазалось, ближе мышь не подведёшь, а делать полный скриншот экрана и редактировать лень.
  • 0
    Ubuntu + GNOME Shell, полёт нормальный. Спасибо!
  • НЛО прилетело и опубликовало эту надпись здесь
  • НЛО прилетело и опубликовало эту надпись здесь
    • +1
      "… возможность перевода целого предложения.." — в этом-то и преимущество.
  • 0
    Если сделать два подряд перевода, то вторая нотификация ждет пока закроется первая. Как то можно сделать, что бы они не ждали а выводились подряд, несколькими штуками?
  • 0
    Прикрутил, спасибо! Вот только интересно: если излишне часто пользоваться, Гугл не забанит? :)
  • 0
    В LibreOffice не удается получить выделенную фразу.
    text="$(xsel -o)"
    Xsel возвращает только первое слово или обрывки фраз. Кто-то знает как решить проблему?
  • +2
    Здравствуйте друзья, вашему вниманию представляю код на руби, формирующий файл словаря, чтобы повторять переводимые слова перед сном. Код также кеширует все запросы в гугл (это к вопросу а не забанит ли гугл). Также имеется установщик.
    github.com/newmen/gnome_google_translator
    Может быть, кому-нибудь ещё понадобятся эти «навороты»… ;)
    • +1
      Задумка интересная с повторением :) А насчёт самой программы — в сторону gconftool-2 не смотрели? по-моему проще и логичнее через неё работать, чем xml писать и gnome перезапускать :)

  • 0
    Признаться, к сожалению так и не нашёл порядочной документации, в которой рассказывалось бы о том, как таки правильно создавать все эти директории и файлы. В официальной документации говорится (http://projects.gnome.org/gconf/), что всё должно быть так то и так-то, но с Gnome3, оно как-то не совсем так. Поэтому я пошёл по пути наименьшего сопротивления.
    Но вообще, спасибо за проявленный интерес. Может быть когда-нибудь я дорасту до gconftool-2. (=
    • 0
      Криво постанул, немного не туда. Прошу прощения.
  • +1
    Модифицировал скрипт, теперь он умеет:
    — конвертировать не только выделенный текст но и последнее набранное слово (по триггеру Ctrl+Shift_Left);
    — при переключении раскладки автоматом переключает язык ввода (укажите свою комбинацию клавиш в последней строке);
    Тригеры клавиш переписал на xdotool — работает более шустро и стабильно.
    Сам скрипт.
    • 0
      И еще — криво работает со скайпом, как исправить не знаю.
  • 0
    уже не работает :(
    • 0
      Так гугл разве денег не хочет за API переводчика?
      В принципе в исходном скрипте легко меняется на API переводчика Яндекса.
    • +1
      работает тока URL изменился

      #!/usr/bin/env bash
      notify-send -u critical "$(xsel -o)" "$(wget -U "Mozilla/5.0" -qO - "https://translate.google.com/translate_a/single?client=t&sl=auto&tl=ru&hl=ru&dt=bd&dt=ex&dt=ld&dt=md&dt=qc&dt=rw&dt=rm&dt=ss&dt=t&dt=at&ie=UTF-8&oe=UTF-8&otf=2&srcrom=1&ssel=0&tsel=0&kc=3&tk=519592|450115&q=$(xsel -o | sed "s/[\"'<>]//g")&sl=auto&tl=ru" | sed 's/\[\[\[\"//' | cut -d \" -f 1)"
      
      • +1
        И продолжение :)
        habrahabr.ru/post/256063

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