2012-02-14

Snaked и GTK NumPad

Я уже жаловался на то что в GTK'шных приложениях хреново работает NumPad (в режиме курсора), это касалось навигации и выделения с использованием регистровых Ctrl и Shift, а так же использования буфера обмена, т.е. комбинации Ctrl+Insert, Shift+Insert и Shift+Delete не работали. Это препятствовало полноценному использованию GTK'шных приложения где требуется маломальская работа с текстом. В чём конкретно проблема не знаю, у Qt-приложений всё нормально, у GTK'шного Geany всё тоже отлично работает, видимо тут грешить надо на виджет GtkTextView и на то что он работает с Insert и Delete, но забивает на KP_Insert и KP_Delete.

Но проблема как-то решилась со временем, правда я уже напрочь отучился использовать приложения заточенные на GtkTextView (GtkSourceView основан на этом же виджете и наследует косяк), т.е. всякие редакторы, в IM это как бы не сильно беспокоит, например.

Ну вот и до Snaked дошла очередь :-). Редактор всем хорош, вот только построен он на паршивом (это моё официальное мнение) GtkSourceView, а значит использует все косяки этого виджета и не даёт мне работать с хоткеями как я этого хочу. Ещё недостаток, это заметное притормаживание, даже очень заметное после Geany. Тормозами я не занимался пока, а вот описанная ситуация с NumPad'ом решается таким плагином:
import gtk


author = 'bw<bw@handsdriver.net>'
name = 'M$ Keypad Copy/Paste'
desc = '<ctrl>KP_Insert + <shift>KP_Insert + <shift>KP_Delete'


def init(injector):
injector.bind('editor-active', 'copy', None, copy).to('<ctrl>KP_Insert')
injector.bind('editor-active', 'cut', None, cut).to('<shift>KP_Delete')
injector.bind('editor-active', 'paste', None, paste).to('<shift>KP_Insert')


def copy(editor):
clipboard = editor.view.get_clipboard(gtk.gdk.SELECTION_CLIPBOARD)
editor.buffer.copy_clipboard(clipboard)


def cut(editor):
clipboard = editor.view.get_clipboard(gtk.gdk.SELECTION_CLIPBOARD)
editor.buffer.cut_clipboard(clipboard, True)


def paste(editor):
clipboard = editor.view.get_clipboard(gtk.gdk.SELECTION_CLIPBOARD)
editor.buffer.paste_clipboard(clipboard, None, True)
Собственно чем приглянулся Snaked. Тем что написан на родном для меня языке Python. Плагинизация, хотя тут ничем меня удивить не получилось. Маленькой, но наиважнейшей для меня фичей, это поддерживание сессиий: может быть запущено несколько экземпляров редактора с разными сессиями и при открытии очередного файла, ключиком можно указать в каком экземпляре он будет открыт (если грубо) и т.п. Запоминает файлы в сессии и не удаляет их оттуда пока ты сам это не сделаешь, а вот Geany сбрасывает, когда открываешь для редактирования файл при том что редактор не был загружен до этого. Да и просто интересными внутренностями, есть чему поучиться, а то и позаимствовать ;-).

2010-12-02

ICQ в Empathy

Продолжаю переходить на Gnome'овские приложения. Блажь такая, любопытно как оно там всё интегрированно. Приложения под Gnome и GTK+ постепенно растут, становятся более юзабельны, вот недавно сменил текстовый редактор, прежде это был KWrite, сейчас Geany. Хотя на такой шаг меня скорее подтолкнули изменения в KWrite, а также новые косяки. Но Geany меня полностью устраивает, а особенно его практически мгновенная загрузка (в отличии от KWrite/Kate). Что касается настройки Geany, в частности подсветки кода, то она не реализована в GUI, нужно править конфиги, что меня нисколько не беспокоит.
Отвлёкся я что-то :-).
Сейчас пробую Empathy, до этого пользовался qutIM, а ещё раньше Pidgin. Pidgin в принципе всем устраивал, но я не смог (да и не стал пробовать) побороть такое явление, как разрыв связи ICQ, а точнее упорное не желание её автоматически восстановить. Приходилось время от времени раскрывать окно клиента и смотреть что там с ICQ и в случае чего жать кнопку, а ещё чаще через пункт меню и кнопку несколько раз. qutIM работал хорошо, правда это зависит от того на какой срез кода ты попадёшь (собирал сорцы из их репы) qutIM на Qt4, если что работает. Вообще нет какой-то веской причины менять клиент в очередной раз, просто, что бы "родное", что бы GTK+, что бы Gnome, только из-за этого, ну и конечно же -- посмотреть.

С Jabber у Empathy проблем не возникло, а вот с ICQ пришлось полазить по интернетам. Для аськи вам потребуется:

1. Установить пакет telepathy-haze (это в Debian)
2. Загрузить клиент и создать учётную запись ICQ. Если вдруг она заработала, тогда зачем вы читаете эту белиберду :-) ?
3. $ mc-tool update `mc-tool list | grep icq` bool:use-ssl=false bool:use-clientlogin=false

Возможно понадобится также сменить сервер на login.icq.com, тут не уверен, но у меня именно такой. А по умолчанию используется login.messaging.aol.com.
Рецепт в сети всё нашёл, но уже после того как разобрался сам. Так как Empathy+Haze использует purple-реализации протоколов, значит Pidgin также не должен работать с ICQ, если это не косяк в Empathy или Telepathy Haze (посмотрел логи, вроде как не в них). Попробовал, не работает. Стал копаться в настройках учётки (а в Pidgin эти настройки куда как богаче) и методом проб и ошибок установил, что SSL и Client Login должны быть отключены.

p.s. В новых версиях изменения (haze 0.5, purple 2.10), use-ssl больше нет, так что для отключения SSL используем параметр string:encryption=no_encryption, иначе получаем сообщение: mc-tool update: Protocol 'icq' does not have parameter 'use-ssl'.

2010-10-22

Дружим pickle и __slots__

Баян, наверное, но я вот только сегодня столкнулся с такой проблемой и её решения в рунете не нашёл.
Делаем раз:
class Foo(object):
__slots__ = ['foo']
Делаем два:
import pickle
pickle.dumps(Foo()) # низя
И получаем ошибку: TypeError: a class that defines __slots__ without defining __getstate__ cannot be pickled.
Оказывается, всё до неприличия просто. По умолчанию, при сериализации, используется старинный протокол (номер ноль, pickle.dumps(Foo(), 0)), и вот он как раз и не может разрулить наши __slots__. В данной ситуации стоит использовать более продвинутый протокол (сейчас это номер 2, более старым версиям такой объект не по зубам):
import pickle
pickle.dumps(Foo(), -1) # годится
pickle.dumps(Foo(), 2) # тоже

p.s. Пытался сериализовать объекты Genshi.

2010-09-24

Калибруем APC Smart-UPS 750 (apcupsd)

Обычная проблема, новые аккумуляторы, индикатор заряда (даже полный, 5 делений) мерцает/мигает. Все в один голос — калибруй (утиль apctest), не думай. Но ведь любопытно, что подобное поведение ИБП означает, всё просто (хотя не просто было ответ найти), мерцающая шкала заряда (та что справа) говорит о том, что по глубочайшему убеждению агрегата расчётное время работы от батарей слишком мало, ну или на что-то там не хватит. Вы сталкивались с таким, но только когда оставалось одно-два деления (это скажем ~10% заряда).
Что меня смутило в момент калибровки, так это что к этому мерцанию прибавлялся короткий прерывистый, разрывающий душу, сигнал, и при этом калибрующая софтина не указывала уменьшение заряда, даже по прошествии многих минут (да и на самой железке индикатор оставался полным, т.е. все 5 делений горели).
$ sudo /etc/init.d/apcupsd stop
Stopping UPS power management: apcupsd.
$ sudo apctest


2010-09-24 04:26:54 apctest 3.14.8 (16 January 2010) debian
Checking configuration ...
Attached to driver: usb
sharenet.type = DISABLE
cable.type = USB_CABLE

You are using a USB cable type, so I'm entering USB test mode
mode.type = USB_UPS
Setting up the port ...
Hello, this is the apcupsd Cable Test program.
This part of apctest is for testing USB UPSes.

Getting UPS capabilities...SUCCESS

Please select the function you want to perform.

1) Test kill UPS power
2) Perform self-test
3) Read last self-test result
4) View/Change battery date
5) View manufacturing date
6) View/Change alarm behavior
7) View/Change sensitivity
8) View/Change low transfer voltage
9) View/Change high transfer voltage
10) Perform battery calibration
11) Test alarm
12) View/Change self-test interval
Q) Quit

Select function number:
Нервы не выдержали и я прервал процесс.
Select function number: 10

This test instructs the UPS to perform a battery calibration
operation and reports the result when the process completes.
The battery level must be at 100% and the load must be at least
10% to begin this test.

Battery level is 100% -- OK
Load level is 26% -- OK
Clearing previous self test result...CLEARED

The battery calibration should automatically end
when the battery level drops below about 25%.
This process can take minutes or hours, depending on
the size of your UPS and the load attached.

Initiating battery calibration...INITIATED

Waiting for calibration to complete...
To abort the calibration, press ENTER.

Battery level: 100%...............................................
..................................................................
..........
Но сегодня, набравшись как следует абсента, отключив монитор от UPS (что бы уменьшить нагрузку, тогда индикатор заряда переставал мерцать, так как уже времени автономной работы на что-то важное по мнению пепелаца хватало) решил добить эту калибровку.
Battery level: 91%..
Battery level: 79%
Battery level: 76%.
Battery level: 64%...
Battery level: 51%....
Battery level: 40%..
Battery level: 30%
CALIBRATION COMPLETED
Result of last self test: PASSED
Аллилуйя, братья и сестры.
Как вы заметили, после 100% идёт куча точек. Интерпретируйте каждую точку как 15 секунд времени, т.е. UPS и софтина терзали меня минут двадцать во время этой самой калибровки, убеждая вашего покорного слугу, что заряд всё ещё 100%. Но спустя нцать времени, железяка оживилась, индикатор заряда стал сомневаться в своей правоте и скакал между 2-4 делениями, да и apctest стала ему подыгрывать.
Короче, всё закончилось хорошо. Сейчас всё пучком и монитор работает через ИБП как и должно быть.

2008-12-27

Да будет сканер, в Linux

Несколько месяцев назад я занялся порочной практикой - самостоятельной сборкой ядер Linux. Процесс сам по себе не такой уж и сложный, но я, как человек разумный, решил переделать конфигурацию на свой лад, т.е. убрать всё лишнее, всё что не используется на моей домашней (по совместительству рабочей) машине. Тут и начались проблемы, перестало работать то одно устройство, то другое. Приходилось анализировать исходный конфиг (.config, хватило ума не удалять его, как и предыдущее рабочее ядро) со своим.
Вчера потребовался сканер (USB, Epson Perfection 2480 Photo). Боялся что ничего не заработает на моей сборке ядра и, разумеется, так и получилось. Перезагрузил старое ("оригинальное", из коробки Debian Etch, 2.6.18) ядро, всё нормально. Начал искать в чем причина.
$ sane-find-scanner
found USB scanner (vendor=0x04b8, product=0x0121) at libusb:003:002
Т.е. сканер есть, но его нет:
$ scanimage -L
device `v4l:/dev/video0' is a Noname BT878 video (AVerMedia TVPhone virtual device
То же самое, но под root:
$ sudo scanimage -L
Password:
device `v4l:/dev/video0' is a Noname BT878 video (AVerMedia TVPhone virtual device
device `snapscan:libusb:003:002' is a EPSON EPSON Scanner1 flatbed scanner

Вся закавыка заключается в том, что в своей компиляции я убрал устаревшую (DEPRECATED) опцию USB_DEVICE_CLASS. Если посмотреть описание этой опции, а еще ветку libsane udev rules for 2.6.22 в рассылке sane-devel, то становится ясно в чем дело и как поступить. Идем в /etc/udev/rules.d/z60_libsane.rules (в вашей системе, z60_libsane.rules может иметь другой префикс, не z60_). В начале этого файла должны быть строки:
ACTION!="add", GOTO="libsane_rules_end"                                                                                 
ENV{DEVTYPE}=="usb_device", GOTO="libsane_create_usb_dev"
SUBSYSTEM=="usb_device", GOTO="libsane_rules_begin"
SUBSYSTEM!="usb_device", GOTO="libsane_rules_end"

# Kernel >= 2.6.22 jumps here
LABEL="libsane_create_usb_dev"

# For Linux >= 2.6.22 without CONFIG_USB_DEVICE_CLASS=y
# If the following rule does not exist on your system yet, uncomment it
# ENV{DEVTYPE}=="usb_device", NAME="bus/usb/$env{BUSNUM}/$env{DEVNUM}", MODE="0664", OWNER="root", GROUP="root"

# Kernel < 2.6.22 jumps here
LABEL="libsane_rules_begin"
Нас интересует строка "If the following rule does not exist on your system yet, uncomment it". Как определить, что такого правила в системе еще нет. Во первых, сканер у нас под обычным пользователем всё еще не работает :-). Во вторых, анализируем выход такой команды:
$ grep -ir 'env{devtype}=="usb_device"' /etc/udev/rules.d/
/etc/udev/rules.d/z60_libsane.rules:ENV{DEVTYPE}=="usb_device", GOTO="libsane_create_usb_dev"
/etc/udev/rules.d/z60_libsane.rules:# ENV{DEVTYPE}=="usb_device", NAME="bus/usb/$env{BUSNUM}/$env{DEVNUM}", MODE="0664", OWNER="root", GROUP="root"
/etc/udev/rules.d/z60_libsane-extras.rules:ENV{DEVTYPE}=="usb_device", GOTO="libsane_extras_create_usb_dev"
/etc/udev/rules.d/z60_libsane-extras.rules:# ENV{DEVTYPE}=="usb_device", NAME="bus/usb/$env{BUSNUM}/$env{DEVNUM}", MODE="0664", OWNER="root", GROUP="root"
Очевидно, что такого правила нигде больше нет. Снимаем коментарий с известной строки, перезагружаем систему и радуемся, радуемся я сказал :-). У меня всё заработало:
$ scanimage -L
device `v4l:/dev/video0' is a Noname BT878 video (AVerMedia TVPhone virtual device
device `snapscan:libusb:003:002' is a EPSON EPSON Scanner1 flatbed scanner