23 августа 2015 г.

Skype 4.3 без PulseAudio

Как известно, Microsoft безжалостно выпилила поддержку ALSA из Skype 4.3. А я, в свою очередь, недавно пару вечеров старательно выпиливал этот PulseAudio из openSUSE 13.2, после того, как никакими молотками и "волшебными" русскими словами не смог заставить этот самый PulseAudio видеть порт line-in на старой карте видео-захвата. Кроме того, я попытался снять звук обычной звуковой картой и получил на записи великолепный белый шум, хотя ожидал услышать немного другое.

После "лечения" системы от PulseAudio осталась только одна проблема - неработающий Skype. В интернетах сразу нашел совет использовать эмулятор PulseAudio для ALSA - apulse. Нормальный такой рабочий костыль. Один из вариантов настройки apulse заключается в создании файла ~/.asoundrc. У меня он, например, такого содержания:

pcm.!default {
  type asym
    playback.pcm {
      type plug
      slave.pcm "hw:1,0"
    }
    capture.pcm {
      type plug
      slave.pcm "hw:3,0"
    }
}

Где "hw:1,0" и "hw:3,0" это ALSA-идентификаторы устройств воспроизведения и захвата звука, соответственно. Но такой подход оказался не очень удобным, потому что в компьютере у меня одновременно было 2 устройства воспроизведения и 3 устройства захвата звука. И если ID основного устройства для вывода звука оказывался всегда "hw:1,0", то нужное устройство захвата периодически оказывалось то с ID "hw:3,0", то "hw:2,0". Ну и, понятное дело, чтобы Skype начал получать звук с правильного устройства, надо было поменять его ID в файле .asoundrc и после этого перезапустить Skype через apulse:

apulse skype

Наверное, можно прибить гвоздями все ID к соответствующим звуковым устройствам через UDEV, но как-то мне всегда лень "лазить через Google" в его конфиги. Поэтому предлагаю более простой и универсальный вариант динамической настройки apulse.

Он основывается на том, что указать устройства для apulse можно с помощью установленных переменных окружения APULSE_PLAYBACK_DEVICE и APULSE_CAPTURE_DEVICE. А с помощью программ aplay и arecord можно легко выдернуть циферки, которые присвоены вашим звуковым устройствам.

Например, вот мой вывод команды aplay -l:

**** List of PLAYBACK Hardware Devices ****
card 0: HDMI [HDA Intel HDMI], device 3: HDMI 0 [HDMI 0]
  Subdevices: 1/1
  Subdevice #0: subdevice #0
card 0: HDMI [HDA Intel HDMI], device 7: HDMI 1 [HDMI 1]
  Subdevices: 1/1
  Subdevice #0: subdevice #0
card 0: HDMI [HDA Intel HDMI], device 8: HDMI 2 [HDMI 2]
  Subdevices: 1/1
  Subdevice #0: subdevice #0
card 1: PCH [HDA Intel PCH], device 0: ALC1150 Analog [ALC1150 Analog]
  Subdevices: 1/1
  Subdevice #0: subdevice #0
card 1: PCH [HDA Intel PCH], device 1: ALC1150 Digital [ALC1150 Digital]
  Subdevices: 1/1
  Subdevice #0: subdevice #0

Интересующее меня устройство вывода называется ALC1150 Analog. Команда play -l говорит что ему присвоены идентификаторы card 1 и device 0. Из этих сочетаний в моем случае надо сформировать имя "hw:1,0". В других дистрибутивах имя может строиться немного по-другому, например, "plughw:1,0".

Таким образом, всё что надо сделать это выдернуть циферки, назначенные устройствам воспроизведения и захвата, сформировать для них валидные ALSA-идентификаторы и записать их в соответствующие переменные окружения. Автоматизировать эту процедуру можно добавлением следующих строчек в ваш файл ~/.profile, который будет выполнятся при каждом входе в систему под вашим именем:

PLAY_DEV_NAME="ALC1150 Analog"
REC_DEV_NAME="U0x46d0x804"

PLAY_CARD=`aplay -l |grep "$PLAY_DEV_NAME" | grep -E -o "card +[0-9]+"`
PLAY_DEV=`aplay -l |grep "$PLAY_DEV_NAME" | grep -E -o "device +[0-9]+"`
APULSE_PLAYBACK_DEVICE="hw:${PLAY_CARD##card },${PLAY_DEV##device }"

REC_CARD=`arecord -l |grep "$REC_DEV_NAME" | grep -E -o "card +[0-9]+"`
REC_DEV=`arecord -l |grep "$REC_DEV_NAME" | grep -E -o "device +[0-9]+"`
APULSE_CAPTURE_DEVICE="hw:${REC_CARD##card },${REC_DEV##device }"

export APULSE_PLAYBACK_DEVICE APULSE_CAPTURE_DEVICE

Только нужно поменять значения переменных PLAY_DEV_NAME и REC_DEV_NAME на имена ваших устройств.



29 июня 2015 г.

Eclipse Mars, GTK+ 3, Adwaita и маленький CSS-напильник

С переходом на новый Eclipse Mars, я решил кое-что ещё поменять в своей жизни. Хотя правильнее сказать, что сам Eclipse предложил мне эти изменения, а я не стал сопротивляться. Как известно, Eclipse Mars теперь по умолчанию использует GTK+ версии 3. Для второй версии GTK+ у меня уже много лет стоит тема oxygen-gtk. Страшненькая, да... но уже привычная. Поэтому как-то даже мысли не возникало попробовать поменять её. А тут оказалось, что для GTK+ 3 у меня вообще эта тема не стоит, и используется тема по умолчанию, которая называется Adwaita. И что-то я так поглядел на неё, и в принципе мой глаз посчитал её чуть менее страшной и чуть более секси, чем oxygen-gtk. Осталось только решить несколько бросившихся сразу в глаза проблем.

Проблемы

Проблема 1. Какое-то неадекватно большое значение padding у большинства GUI-элементов.


Проблема 2. Странный tooltip для javadoc с белым шрифтом на чёрном фоне.

 
Проблема 3. Смазанные шрифты после скролинга некоторых окон (Project Explorer, Package Explorer, Outline). Особенно ярко проблема проявляется, если скролить колесом мыши.


Решение

В GTK+ 3 для описания тем больше не используются rc-файлы собственного формата. Теперь для стилизации применяются более понятные CSS-подобные файлы.

Проблемы 1 и 2 решаются созданием файла ~/.config/gtk-3.0/gtk.css со следующим содержанием:
* {
    padding: 1px;
}

GtkToolbar {
    padding: 2px;
}

GtkMenuBar {
    padding: 2px;
}

GtkMenuItem {
    padding: 2px 6px;
}

.tooltip {
    background-color: #CAE1FF;
    color: #333;
    text-shadow: none;
}

Кратко поясню. Сначала устанавливаем padding абсолютно для всех элементов равным 1px. Затем для элементов GtkToolbar, GtkMenuBar и GtkMenuItem делаем отступы чуть более разумными. CSS-класс tooltip вероятно прописан где-то в коде и назначен, как для всплывающего окна javadoc, так и для хинтов различных графических элементов. Свойство text-shadow необходимо, чтобы ликвидировать тень текста хинта, которая становится заметной и неуместной после изменения его фона и цвета текста:


Обратите внимание, что файл ~/.config/gtk-3.0/gtk.css будет действовать и переопределять стили для любой темы GTK+ 3, выбранной пользователем, у которого в домашнем каталоге есть этот файл, а не только для темы Adwaita.

Проблему 3 я решил довольно тупо, сняв флажок с Use mixed fonts and colors for labels в настройках внешнего вида (Window / Preferences / General / Appearance). Мне легче смириться с одноцветным черным лейблом, чем с таким поломанным шрифтом.

Тут я вынужден обновить сообщение и добавить, что после решения проблемы 3 появилась проблема 4 :) которая выглядет, как практически нечитаемый выбранный пункт во всплывающем окне автодополнения.


Эта неприятность также фиксится добавлением некоторых строчек в gtk.css:
GtkTreeView:selected {
    color: #FFF;
    background-color: #4A90D9;
}

Результаты






Ссылки

Тем, кто захочет ещё что-нибудь подкрутить или сделать более тонкую настройку, а не такую кувалдообразную, как у меня, рекомендую сначала заглянуть сюда, и конкретно вот сюда. А ещё здесь интересно.

Когда терпение кончилось

Спустя некоторое время, должен признать, что это далеко не все глюки с UI, которые мне повстречались при использовании GTK+ 3 в Eclipse. И у меня больше нет сил подкручивать эти гайки. Я устал, я ухожу. Теперь перед запуском Eclipse у меня выполняется export SWT_GTK3=0, что заставляет Eclipse использовать GTK+ 2 по старинке.

10 июня 2015 г.

Перенос существующей базы данных Redmine с SQLite на PostgreSQL

Разглагольствовать не буду. Скажу лишь, что попробовал несколько различных способов, кроме ручного исправления дампа SQLite, ибо лень. Самым простым и жизнеспособным оказался метод с использованием программы Taps. Эта чудо-ruby-штука поднимает http-сервер с подключением к базе данных А и позволяет с помощью клиента выполнять обмен данными между этой базой А и какой-либо базой Б, даже если они управляются различными СУБД. Конечно, её возможности не безграничны, но для миграции базы данных Redmine их хватило.

Все ниже описанные действия выполнялись на openSUSE 13.2.

Кратко и по сути

1. Установить через RubyGems программу Taps:
gem install taps
2. Подготовить базу данных PostgreSQL для Redmine:
createuser -U postgres redmine
psql -U postgres
postgres=# ALTER USER redmine WITH PASSWORD 'redmine_password';
postgres=#\q
createdb -U postgres -O redmine redmine
3. Запустить сервер Taps с подключением к новой созданной в PostgreSQL базе для Redmine:
taps.ruby2.1 server postgres://redmine:redmine_password@localhost/redmine taps taps_password
4. Используя клиент Taps, запушить все данные из исходной базы SQLite в PostgreSQL:
taps.ruby2.1 push sqlite:///usr/local/redmine/db/redmine.db.sqlite3 http://taps:taps_password@localhost:5000
5. Не забыть изменить настройки подключения к БД в Redmine (redmine/config/database.yml):
production:
  adapter: postgresql
  database: redmine
  host: localhost
  username: redmine
  password: "redmine_password"
5. Перезапустить Redmine

Грабли

При запуске сервер валится приблизительно с такой портянкой:
/usr/lib/ruby/gems/2.1.0/gems/sinatra-1.0/lib/sinatra/base.rb:298:in `': uninitialized constant Tilt::CompileSite (NameError)
        from /usr/lib/ruby/gems/2.1.0/gems/sinatra-1.0/lib/sinatra/base.rb:297:in `'
        from /usr/lib/ruby/gems/2.1.0/gems/sinatra-1.0/lib/sinatra/base.rb:21:in `'
        from /usr/lib/ruby/2.1.0/rubygems/core_ext/kernel_require.rb:73:in `require'
        from /usr/lib/ruby/2.1.0/rubygems/core_ext/kernel_require.rb:73:in `require'
        from /usr/lib/ruby/gems/2.1.0/gems/taps-0.3.24/lib/taps/server.rb:1:in `'
        from /usr/lib/ruby/2.1.0/rubygems/core_ext/kernel_require.rb:73:in `require'
        from /usr/lib/ruby/2.1.0/rubygems/core_ext/kernel_require.rb:73:in `require'
        from /usr/lib/ruby/gems/2.1.0/gems/taps-0.3.24/lib/taps/cli.rb:61:in `server'
        from /usr/lib/ruby/gems/2.1.0/gems/taps-0.3.24/lib/taps/cli.rb:27:in `run'
        from /usr/lib/ruby/gems/2.1.0/gems/taps-0.3.24/bin/taps:6:in `'
        from /usr/bin/taps.ruby2.1:23:in `load'
        from /usr/bin/taps.ruby2.1:23:in `
'
В этом случае необходимо проверить какие версии библиотеки Tilt у вас установлены:
zypper se -s tilt
Если среди установленных есть Tilt версии 2, то необходимо её снести и поставить 1.4. Как правило, zypper сам ставит версию 1.4 вместо удалённой 2.

Ещё

Уже после публикации этой статьи, я наткнулся ещё на одну чудо-ruby-штуку под названием YamlDb. Жалко, что она сразу мне не попалась, меньше бы времени потратил. И на Хабре давно уже есть статейка.