Hatred's Log Place

DON'T PANIC!

Mar 24, 2012 - 4 minute read - linux

sdict - небольшой скрипт-оболочка для StarDict (qstardict и sdcv)

Могу напугать некоторых, но в стародавние времена со словарями (имеется в виду - удобные программы-оболочки и сами словари) в Linux было, мягко сказать, не густо. В то время я настроил у себя дома словарный сервер dict|dictd (боле подробно на английском: dict ), сначала просто на локальном хосте, потом, когда появилось ещё парочку компьютеров и достаточно дешёвый доступ в интернет сервер стал использоваться и на них, а так же с работы.

Удобным было почти всё:

  • приятная консольная программка dict - для быстрых запросов
  • возможность настроить словарную базу только в одном месте, а на остальных компьютерах указать только адрес сервера
  • прекрасная графическая программка kdict, которая, запускаясь, проверяла буфер обмена и если там что-то было - переводила его (программа проверяла запущенные копии, запускалась в одном экземпляре)

Время шло, начались появляться и недостатки:

  • много времени стало проводиться за нетбуком, да ещё в отстутствии интернета, иногда нужно было что-то быстро перевести
  • доступность домашнего сервера была явно не на высоте - и свет вырубали и связь рвалась
  • программа kdict со своими удобными свойствами канула в лету (уже и не знаю - вообще она существует, но переводить из буфера обмена она как-то перестала)

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

  • stardict - написана на Gtk+, каноническая версия
  • qstardict - оболочка на Qt4, по своими возможностям оказалась очень похожа на полюбившийся мне kdict, в частности возможности перевода содержимого буфера обмена, стоит ли говорить, что мой выбор остановился на ней? Плюс программа успешно управляется путём посылки DBus уведомлений, что и будет позже мной использовано.
  • sdcv - консольная программа для запроса перевода, по сути аналог dict

Теперь подробнее остановлюсь на qstardict, особенно на работе на переводе содержимого буфера обмена.

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

Мне показался такой вариант не очень удобным. Но не беда - благо программа может управляться по DBus, в частности, для показа этого самого всплывающего окна с переводом. Тут же вспоминаем про удобную программу xclip для работы с буфером обмена из состава Xorg, примешиваем немножно универсальности для работы из X11 или из консоли и получаем такой скрипт:

#!/bin/sh


check_prog()
{
  local res
  prog=`which $1 2> /dev/null`
  res=$?
  if [ $res -ne 0 ]; then
    echo "Can't found program: " $1
    echo "Try to install it via your package manager"
    exit 1
  fi

  echo $prog
}


check_process()
{
  pidof "$1" > /dev/null 2>&1
}


sdict_x11()
{
  local res
  qstardict=`check_prog qstardict`
  qdbus=`check_prog qdbus`
  
  check_process "$qstardict"
  res=$?
  if [ $res -ne 0 ]; then
    # for begin - start qstardict
    "$qstardict" > /dev/null 2>&1 &
    sleep 2
  fi

  "$qdbus" org.qstardict.dbus /qstardict org.qstardict.dbus.showPopup "$@"
  "$qdbus" org.qstardict.dbus /qstardict org.qstardict.dbus.showTranslation "$@"
}


sdict_console()
{
  sdcv=`check_prog sdcv`
  $sdcv -n "$@"
}

# force no X11 version
no_x11="false"
if [ "$1" = "--no-x11" ]; then
  no_x11="true"
  shift
fi

# take word from commad line or from buffer
TRANSLATE=$@
if [ -z "$1" ]; then
  xclip=`check_prog xclip`
  TRANSLATE="`$xclip -o`"
fi

# run translation
if [ -z "$DISPLAY" -o "$no_x11" = "true" ]; then
  sdict_console "$TRANSLATE"
  exit $?
else
  sdict_x11 "$TRANSLATE"
  exit $?
fi

Как она работает?

Просто:

  • при запуске проверяет, что установлена переменная DISPLAY и начинает работать с qstardict
  • если переменная DISPLAY не задана, или первым аргументов в командной строке стоит --no-x11, то работа начинается с консольной версией sdcv
  • если в качестве аргументов sdict передаются какие-то слова - пытается их перевести
  • если список аргументов пуст - пытается получить содержимое буфера обмена при помощи xclip и перевести его
  • перед посылкой сообщения по DBus, проверяет, что qstardict запущен, если нет - то запускает его, ждёт 2 секунды и пытается вызвать его для перевода (тут может быть скрыт подводный камень: у нас на работе есть терминальный сервер на Linux, и графических сессий там может быть много, соответственно у каждого пользователя может быть запущена своя версия qstardict, тут проверка запущенности qstardict может отработать некорретно - исправляется легко, но для себя пока не вижу необходимости, поэтому просто информирую)
  • перед запросом команд xclip, qdbus, qstardict, sdcv производится проверка наличия их в пути поиска переменной окружения $PATH, если не находится - программа выдаёт сообщение об их отсутствии на стандартный вывод и завершает свою работу со статусом 1. Обычно эти программы есть почти в каждом дистрибутиве Linux в одноимённом пакете, в случае ArchLinux:

^ Команда ^ Пакет ^ Команда для устрановки ^ Примечание ^ | xclip | xclip | pacman -S xclip | | | qdbus | qt | pacman -S qt | поставится как зависимость при установке qstardict | | qstardict | qstardict | pacman -S qstardict | | | sdcv | sdcv | pacman -S sdcv | |

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

Пользуйтесь :)