Пара советов как привести изначально унылый внешний вид OpenOffice и Java-приложений к стилю программ на Gtk:



OpenOffice.org

Создаем файл /etc/profile.d/openoffice.sh со следующим содержанием:

#
# /etc/profile.d/openoffice.sh

export SAL_USE_VCLPLUGIN=gtk
export OOO_FORCE_DESKTOP=gnome
Теперь достаточно перелогиниться в системе, необходимые настройки подхватятся.

Java

Создаем файл /etc/profile.d/gtkjava.sh со следующим содержанием:
#
# /etc/profile.d/gtkjava.sh
export _JAVA_OPTIONS=" -Dswing.defaultlaf=com.sun.java.swing.plaf.gtk.GTKLookAndFeel \
-Dawt.useSystemAAFontSettings=on"
Также перелогинимся.

Пошаговое мини-howto, описывающее как расшарить сканер между linux-системами по аналогии с сетевым принтером.
Предполагаем, что локально сканер на сервере настроен и работает (см. sane).
Теперь нужно выполнить следующие действия:

На сервере:
1) Ставим демон saned (входит в состав разных пакетов, в зависимости от дистрибутива, наример sane-utils или sane-server).
2) В /etc/sane.d/saned.conf добавляем ip клиента(ов) (см. примеры в том же файле).
3) Создаем файл /etc/xinetd.d/saned (для автоматического запуска сервера сканирования сетевым демоном xinetd) вида:

service sane-port
{
disable = no
socket_type = stream
protocol = tcp
user = scanner
wait = no
server = /usr/sbin/saned
}
(здесь предполагается, что в системе присутствует пользователь "scanner" с правами на доступ к сканеру. конечно можно задать пользователя, от имени которого будет запускаться демон saned, по желанию. root строго не рекомендуется)
4) Выполняем команду (чтобы xinetd подхватил созданный нами файл):
$ sudo /etc/init.d/xinetd reload

На клиенте:
5) В /etc/sane.d/net.conf добавляем строку с ip сервера.
6) Пускаем xsane, сканируем, радуемся.

Что такое dwm...

...можно прочитать например здесь (динамический фреймовый оконный менеджер и т.п.).
Заинтересовавшимся про настройку можно (и нужно) почитать здесь.

Я же опишу свои самые первые шаги по освоению dwm, а именно его установку.
Первоначальные действия по распаковке (я ставил в домашнюю директорию) и сборке:

# Будем ставить в домашнюю директорию, в скрытый каталог .dwm
mkdir .dwm
cd ./.dwm/
# Распаковываем
tar -zxf /<PATH_TO_DWM>/dwm-<VER>.tar.gz
# Складываем файлы из архива сюда же в ~/.dwm
mv ./dwm-*/* ./
rmdir ./dwm-*/
# Первоначальные настройки в config.h =)
vim ./config.h
# Компилим
make

PATH_TO_DWM - путь к архиву, VER - версия в имени файла. Архив с новой версией можно взять на сайте dwm.

Если вдруг компиляция валится с ошибкой вида:
/usr/include/X11/Xlib.h: В функции 'XSetOMValues'
/usr/include/X11/Xlib.h:3573: ошибка: expected declaration specifiers before '_X_SENTINEL'

...ситуацию поможет исправить добавление данного ключа к переменной CFLAGS в файле config.mk (именно в Xfuncproto.h лежат нужные для сборки макросы):
-include /usr/include/X11/Xfuncproto.h
Далее создадим простенький скрипт запуска (скрипт взят из README из поставки dwm):
~/.dwm$ echo '    while true
do
echo `date` `uptime | sed 's/.*,//'`
sleep 1
done | ~/.dwm/dwm' > DWM
~/.dwm$ chmod +x ./DWM

Теперь о двух способах, которыми я организовал запуск dwm в двух различных системах (AltLinux Desktop 4 и Ubuntu 8.10):


Первый способ

В AltLinux я просто произвел первоначальные настройки по аналогии с альтовским спеком, а именно создал файл /etc/X11/wmsession.d/23dwm со следующем содержанием:

NAME=DWM
DESC=Light and fast window manager
EXEC=/home/USER/.dwm/DWM
SCRIPT:
exec /home/USER/.dwm/DWM

, где USER, конечно, - имя вашего пользователя (как часть пути в домашний каталог).


Второй способ

Как я ставил на Ubuntu.
Поставил пакет из репозитория и увидел, что в убунте путь к бинарику dwm из коробки задается с помощью системы альтернатив (подробней об альтернативах здесь):
~/.dwm$ ls -l /usr/bin/dwm
lrwxrwxrwx 1 root root 21 2008-06-05 17:07 /usr/bin/dwm -> /etc/alternatives/dwm
~/.dwm$ ls -l /etc/alternatives/dwm
lrwxrwxrwx 1 root root 20 2008-11-26 11:37 /etc/alternatives/dwm -> /usr/bin/dwm.default

Так что легко можно добавить свой бинарик dwm в качестве альтернативы с сохранением системного:
~/.dwm$ sudo update-alternatives --install /usr/bin/dwm dwm /home/<USER>/.dwm/DWM 23

Смотрим что вышло:
~/.dwm$ update-alternatives --display dwm
состояние dwm: auto.
ссылка сейчас указывает на /usr/bin/dwm.default
приоритет /usr/bin/dwm.default: 100
приоритет /usr/bin/dwm.web: 50
приоритет /home/<USER>/.dwm/DWM: 23
Текущая `лучшая' версия: /usr/bin/dwm.default.

И выставим свой бинарик dwm по умолчанию:
~/.dwm$ sudo update-alternatives --set dwm /home/<USER>/.dwm/DWM
Используется `/home/<USER>/.dwm/DWM' для предоставления `dwm'.

Всё, теперь наш dwm готов к запуску (его можно выбрать в том же gdm в меню выбора сеанса).

После обновления с AltLinux Desktop 4.0 до 4.1 приказал долго жить bootsplash.

Как выяснилось новая тема design-bootsplash-desktop не поддерживает установленное у меня разрешение фреймбуфера (1280x1024), о чём на данный момент висит соответствующая бага.

Вот мои действия по лечению проблемы:

1) Смотрим доступные разрешения:


$ ls /etc/bootsplash/themes/desktop/config/bootsplash-*.cfg
/etc/bootsplash/themes/desktop/config/bootsplash-640x480.cfg
/etc/bootsplash/themes/desktop/config/bootsplash-800x600.cfg

2) Выбираем то, что побольше - 800x600.
Пропишем загрузчику соответствующее разрешение. Для lilo - строчка "vga=0x314" в файле /etc/lilo.conf. Не забудем там же прописать ядру параметр "splash=silent".

3) И уходим в ребут...
4) Проверим разрешение фреймбуфера с помощью утилиты fbresolution:

# fbresolution
800x600

5) Выставим тему desktop в файле /etc/sysconfig/bootsplash:

THEME="desktop"

6) Перегенерим initrd (initial ramdisk) с помощью mkinitrd:

# cd /boot/
# mv initrd-`uname -r`.img initrd-`uname -r`.img.bak
# /sbin/mkinitrd --verbose initrd-`uname -r`.img `uname -r`

mkinitrd представляет из себя скрипт, который, кроме всего прочего, прописывает bootsplash из текущей темы (берёт её из /etc/sysconfig/bootsplash) для текущего разрешение фреймбуфера (разрешение берется из вывода утилиты fbresolution).

Результат:

Опишу как настроить мышь Apple MightyMouse на примере AltLinux Desktop 4.1 (в том числе горизонтальный скроллинг).


В первую очередь добавим udev-правило в каталоге /etc/udev/rules.d/. Cледует добавлять в файл, стоящий по алфавиту раньше правил по умолчанию 50-udev-default.rules. Само правило:

#For mightymouse

KERNEL=="mouse*|mice|event*", SYSFS{idVendor}=="05ac", SYSFS{idProduct}=="0304", NAME="input/%k", MODE="0640", SYMLINK="input/mightymouse"


После перезагрузки проверим доступна ли мышь по новой ссылке с помощью утилиты evtest:
# evtest /dev/input/mightymouse

Теперь пропишем мышь в /etc/X11/xorg.conf:

Section "InputDevice"

Identifier "mightymouse"

Driver "evdev"

Option "SendCoreEvents"

Option "Device" "/dev/input/mightymouse"

Option "Name" "Primax Electronics Apple Optical USB Mouse"

Option "HWHEELRelativeAxisButtons" "7 6"

Option "Buttons" "9"

EndSection


После перезагрузки иксов:
# /etc/init.d/dm restart
практически всё должно работать, в т.ч. горизонтальный скроллинг (например в GIMP'е). Для решения проблем горизонтального скроллинга в Firefox см. по ссылке.

И в заключение - полный список соответствий всех кнопок. Например button8 (левая боковая кнопка на мыши) в Firefox забиндина на действие "Назад".

Кратко о том, как перевести WxWidgets-приложение. На примере fityk-0.8.6.
Это ни в коем случае не how-to по gettext и WxWidgets, а просто ориентир куда копать за дальнейшими знаниями.

1) Скачиваем архив, распаковываем, переходим в распакованный каталог.
Следующими пунктами выполним минимальные (см. здесь и здесь) действия по подготовке кода к переводу .
2) $ vim ./src/wxgui/app.h
В конце класса FApp добавляем строку:

wxLocale ss_locale;

3) $ vim ./src/wxgui/app.cpp
В начале FApp::OnInit(void) добавляем строки:
if(ss_locale.Init())
ss_locale.AddCatalog(wxT("fityk.mo"));

Для примера будем просто грузить fityk.mo, который в следующих шагах сформируем.

4) $ vim ./src/wxgui/frame.cpp
Помечаем в файле строки, подлежащие переводу, для чего нужно заменить wxT() на макрос _() (см. доки WxWidgets)
Для примера:
Было:
append_mi(help_menu, ID_H_CONTACT, GET_BMP(bug16), wxT("&Report a Problem"),
Стало:
append_mi(help_menu, ID_H_CONTACT, GET_BMP(bug16), _("&Report a Problem"),
5) Собираем строки, подлежащие переводу в .po-файл (подробней см. по ссылке). Xgettext ищет вхождения _() в текстах и формирует .po-шаблон:
xgettext -C -n -k_ -o fityk.po ./src/wxgui/*.cpp
6) Непосредственно переводим .po-файл, например с помощью редактора poedit:
poedit ./fityk.po


7) Форимируем итоговый .mo-файл с переводами строк:
msgfmt -o fityk.mo fityk.po
8) Собираем и запускаем fityk
./configure
make
sudo make install
fityk

Lftp - отличный консольный ftp-клиент (и в каком-то смысле http-) в синтаксисе команд ориентированный на bash (а оттого и интуитивно понятный unix-пользователям).

Чтобы начать работу есть смыcл прочитать статью на citkit.ru.
Развернутый туториал на английском языке можно найти здесь.

А теперь несколько советов разной степени полезности:

1) В lftp реализована кроме всего прочего и поддержка закладок.
Закладки храняться в простом текстовом виде в файле ~/.lftp/bookmarks.
Подерживается импорт закладок из сторонних приложений
(см. `ls /usr/share/lftp/import-*`)

Добавить текущую директорию в закладки можно командой:

> bookmark add <имя_закладки>

Закладки доступны с помощью автодополнения по клавише TAB при открытии (open) нового адреса. (просто наберите open и нажмите клавишу TAB, чтобы увидеть все сохраненные закладки)

Посмотреть адреса всех закладок можно командой:
> bookmark list

2) Команды pwd и cd осуществляют действия на удаленном сервере и имеют свои "локальные" аналоги lpwd и lcd.
Команда ls же такого аналога не имеет. Поэтому приходится смотреть содержимое локальной директории с помощью вызова команды оболочки shell: !ls .
Исправить ситуацию и создать команду lls поможет простенький alias в конфиге (~/.lftp/rc):
alias lls !ls --color

При этом работают и опции командной строки вроде:
> lls -la
3) Для получения приглашения командной строки lftp нужного формата и цвета (что может иногда быть удобно) добавляем для примера в конфиг такую строку:
set prompt "\[\e[1;30m\](\[\e[0;34m\]_\[\e[1m\]|\[\e[37m\]\[\e[35m\]_) \[\e[34m\]\u\[\e[0;34m\]\@\[\e[1m\]\h\[\e[1;30m\]:\[\e[1;34m\]\w\[\e[1;30m\]>\[\e[0m\] "

Подробнее о настройке цветов и формате приглашения см. статью на opennet и man lftp.

4) Чтобы увидеть например баннер сервера и другие подробности следует поднять debug-level до 3 следующей командой:
> debug 3
> open <имя_сервера>
Подробнее о debug-level см. /usr/share/doc/lftp/README.debug-levels.

5) Команды rm, put и get сами по себе маски не поддерживают, но имеют "m*" аналоги: mrm, mget и mput с поддержкой масок (wildcards)

6) Чтобы запоминать последний адрес в закладке "last" следует добавить в конфиг следующую строку:
set at-exit "bookmark add last"

Теперь всегда можно открыть последний посещенный в предыдущую lftp-сессию адрес командой:
> open last
7) Прямое пробрасывание ссылок из firefox можно реализовать с помощью расширения flashgot. Хотя в связке с firefox наверно лучше использовать специализированный менеджер закачек (вроде wget или d4x), а не ftp-клиент.

8) В поставке lftp идёт также lftpget - скрипт для стягивания одиночного файла (сам бинарик lftp в качестве аргумента принимает исключительно URL директории).

9) Если есть проблемы при отображении кириллических имен файлов на фтп есть смысл добавить в конфиг строку:
set ftp:charset cp1251

Подробней о таких возможностях как планировщик, история команд в стиле csh, слоты (что-то вроде параллельных сессий) можно прочесть в упоминавшимся выше туториале.

И получившийся в результате конфиг:
# Локальный ls
alias lls !ls --color
# Приглашение
set prompt "\[\e[1;30m\](\[\e[0;34m\]_\[\e[1m\]|\[\e[37m\]\[\e[35m\]_) \[\e[34m\]\u\[\e[0;34m\]\@\[\e[1m\]\h\[\e[1;30m\]:\[\e[1;34m\]\w\[\e[1;30m\]>\[\e[0m\] "
# Запоминать в закладке "last" последний адрес
set at-exit "bookmark add last"
# Кодировка сервера
set ftp:charset cp1251

Шпаргалка по созданию снимков экрана:

# Скрин активного окна (по клику), либо выделенного курсором участка экрана
import out.png
# Скрин с задержкой по времени в 3 секунды
import -pause 3 out.png
# Захватить окно с обрамлением wm
import -frame out.png
# Захватить весь экран (нужно, тем не менее, именно выделить курсором произвольный участок экрана)
import -screen out.png
# Содержимое ("скриншот") виртуальной консоли (зд. двенадцатой)
sudo cat /dev/vcs12
# Тот же вывод, но форматированный под ширину в 80 символов
sudo fold -w 80 /dev/vcs12

Ссылки на маны:
man import (1)
man vcs (4)

"Хозяюшке на заметку": автоматически откадрировать отсканированные изображения, удалив темные области по краям, можно простой командой (выполнять в директории с изображениями):

for file in $(ls); do mogrify -fuzz 75% -trim $file; echo $file'        [DONE]' ; done

Было:

Стало:

Оптимальный эффект достигается подбором чувствительности ("fuzz") в процентах.
Конечно, не забудьте сделать backup директории, т.к. mogrify в отличие от convert переписывает исходные файлы (для подробностей см. сайт ImageMagick).

Опишу как быстро настроить передачу файлов с телефона/на телефон по bluetooth в linux.
Способ будет ориентирован на то, что вы подключаете свой bluetooth-адаптер нечасто и только когда есть необходимость работы с телефоном: все службы и графическая утилита будут запускаться автоматически при подключении адаптера.

Я пошел по пути наименьшего сопротивления и установил пакет kdebluetooth со всеми необходимыми зависимостями (в т.ч. пакет bluez-utils - основное linux-решение для такого рода задач).

Теперь подключаем наш bluetooth usb-адаптер и смотрим вывод dmesg и lsusb для того, чтобы убедится, что ОС его благополучно определила.

Дальше создадим файл /usr/local/bin/ssbt (start-stop bluetooth) со следующем содержанием:


#!/bin/sh
USER=some_user
export DISPLAY=:0.0

ps aux | grep kbtobexclient > /dev/null 2>&1
if [ $? == 0 ]; then
echo "Already running!"
exit 1;
fi

/etc/init.d/bluetooth start
su - $USER -c "kbluetoothd"

su - $USER -c "kbtobexclient"

/etc/init.d/bluetooth stop
killall kbluetoothd


Не забудем сделать его исполняемым и заменить "some_user" на имя своего пользователя.
Этот скрипт будет поднимать всю необходимую систему bluetooth и запускать графическую утилиту для передачи файлов kbtobexclient.
После работы же в kbtobexclient и закрытия программы скрипт будет самостоятельно гасить все ранее запущенные им службы.

Теперь для автоматизации организуем автозапуск этого скрипта при каждом включении usb-адаптера в наш ПК.
Для этого добавим udev-правило (коротко: значения product и vendor взяты из вывода lsusb, для подробных разъяснений см. ссылки раз и два) в один из файлов /etc/udev/rules.d/ (лучше для таких целей создать собственный файл с названием, стоящим по алфавиту выше остальных). Собственно текст правила:

# For bluetooth
BUS=="usb", SYSFS{idVendor}=="0a12", SYSFS{idProduct}=="0001", RUN+="/usr/local/bin/ssbt"

Готово: теперь с помощью kbtobexclient можно будет слать файлы на телефон, а демон kbluetoothd будет автоматически принимать файлы.

Ситуация для примера такая: есть два сервера за шлюзом.
Правила ip-tables настроены так, что 22 порт просто пробрасывается на первый сервер, соединения же на 3500-й порт шлюза пробрасываются на 22-й порт второго сервера.
В результате по одному ip-адресу доступны 2 ssh-сервера на разных портах.
И теперь при попытке подсоединиться ко второму возникает конфликт ключей, т.к. ключ второго сервера не совпадает с сохраненным в файле known_hosts ключем первого сервера.
ssh разрывает соединение, предотвращая (по её мнению) подмену ip-адреса ssh-сервера:


@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
@ WARNING: REMOTE HOST IDENTIFICATION HAS CHANGED! @
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
IT IS POSSIBLE THAT SOMEONE IS DOING SOMETHING NASTY!


Можно конечно совсем отключить проверку ключей, но это является не самым безопасным решением.
Альтернативное же решение (может опять же не лучшее, но первое пришедшее мне в голову после беглого прочтения манов ssh) - создать для каждого из двух серверов свой файл для хранения ключей.

Для этого создаем конфиг (~/.ssh/config) следующего содержания:


Host remote1

    Hostname 192.168.1.1

    Port 22

    UserKnownHostsFile remote_file1



Host remote2

    Hostname 192.168.1.1

    Port 3500

    UserKnownHostsFile remote_file2



Где remote_fileX - полные пути к альтернативным файлам known_hosts (логично дать им названия, содержащие имя сервера, а также положить их в ~/.ssh/)

Можно также добавить имена пользователей для серверов с помощью добавления (после имен соответствующих серверов) в конфиг строк вида:

User имя_пользователя

Это позволит не вводить имена каждый раз при обращении к серверам.

Всё, теперь оба наших сервера доступны с помощью следующих простых команд:

$ ssh remote1
$ ssh remote2

В одном из своих предыдущих постов я отписывал как вставлять произвольный текст (тот же программный код со спецсимволами) в сообщения на Blogger.
Теперь же случайно наткнулся на куда более удобный и функциональный способ: с помощью всем известного редактора GVim, который позволяет в один клик (пункт меню "Сделать HTML с подсветкой") не только создать html, но и сохранить выбранную ранее в редакторе подсветку синтаксиса.
Думаю будет полезно не только пользователям Vim, тем более, что изучать редактор для использования этой функции вовсе не обязательно.

В подтвержедие моих слов скриншот:

... И пример вставленного текста (следует вставлять код окруженный в сгенерированном html-файле тегом "body"):


#include <stdio.h>

int main()
{
    int i;
    i = 1;
    return 0;
}

LiarLiar - простенький детектор лжи под Linux.

Описание из спека AltLinux:

Инструмент для определения состояния человека по голосу. Иногда используется, как звуковой детектор лжи (например, для определения волнения человека по его голосу, позволяющее определить искренность его состояния).

Voice stress analysis tool. Sometimes used as an audio lie detector (ie. used for detecting stress in a person's voice to allow for the determination of truthfulnessin a statement)


Работа LiarLiar.

Конечно, это не инструмент дознавателей ЦРУ, а всего лишь игрушка (по крайне мере со стандартным simple-плагином) и качество анализа оставляет желать лучшего (особенно на не особо качественных аудиозаписях), тем не менее довольно забавно испытать её на разных аудиофайлах.

Вот пример "лжи":

А вот "правды":

На последнем скриншоте также видно окно настроек.
Программа, к сожалению, давно не поддерживается авторами, поэтому сборка её сопряжена с некоторыми трудностями, а именно...

Сборка LiarLiar.

LiarLiar требует для сборки старый gstreamer-0.6.
Придется собрать его и плагины к нему.
Чтобы не нанести вреда системе (не переписать например новый gstreamer старым) есть смысл создать каталог /opt/liar, наделить его правами записи для вашего пользователя и все последующие операции (включая make install) проводить от непривилегированного пользователя.

1) Gstreamer-0.6

Тянем gstreamer-0.6.5 и устанавливаем.
Замечу, что с gcc-2.95 и gcc-4.1 он у меня не собрался, поэтому я собирал с помощью gcc-3.4:

~/gstreamer-0.6.5$ export CC=/usr/bin/gcc-3.4
~/gstreamer-0.6.5$ export CXX=/usr/bin/gcc-3.4
~/gstreamer-0.6.5$ ./configure --prefix=/opt/liar/ --disable-docs-build
~/gstreamer-0.6.5$ make
~/gstreamer-0.6.5$ make install

Если при сборке возникает ошибка вида:

gsttrashstack.h: In function 'gst_mem_chunk_alloc':
gsttrashstack.h:103: error: PIC register 'ebx' clobbered in 'asm'

Можно жестко отключить оптимизацию, заменив строку 54 ("#if defined/...") в файле ./gst/gsttrashstack.h на строку с false-условием
"#if 0" .

2) LiarLiar

Тянем liarliar-0.5.2.
Открываем новую консоль (или сбрасываем ранее установленные переменные окружения компилятора). Компилим liar:

~/liarliar-0.5.2$ export PKG_CONFIG_PATH=/opt/liar/lib/pkgconfig/:/usr/lib/pkgconfig/
~/liarliar-0.5.2$ ./configure --prefix=/opt/liar/
~/liarliar-0.5.2$ make

Теперь если возникнет ошибка вида:

simple.cpp: In member function 'virtual void simple::on_activate(const std::vector<double, std::allocator<double> >*, unsigned int)':
simple.cpp:23: warning: converting to 'int' from 'double'
simple.cpp:55: error: 'fabs' was not declared in this scope
simple.cpp:55: error: 'pow' was not declared in this scope
simple.cpp:88: error: 'pow' was not declared in this scope
make[1]: *** [simple.lo] Ошибка 1

То следует в начало файла ./plugins/simple.cpp добавить строку:

#include <math.h>

И продолжить установку:

~/liarliar-0.5.2$ make
~/liarliar-0.5.2$ mkdir -p ~/.liarliar/plugins/
~/liarliar-0.5.2$ cp ./plugins/.libs/* ~/.liarliar/plugins/
~/liarliar-0.5.2$ make install

Liar уже можно запустить, но без плагинов gstreamer'а работать пока он не будет =)


Небольшое лирическое отступление. LiarLiar следует собирать с библиотекой sigc++-1.2, devel-пакеты sigc++-2.0 устанавливать не надо! Если всё же вы захотите (или придется из-за особенностей дистрибутива) собрать с sigc++-2.0, то могут быть проблемы с include'ами (придется подключать файлы вручную), а так же придется в исходниках liar заменить все вызовы SigC::slot на sigc::mem_fun.

3) Плагины Gstreamer

Перед сборкой обязательно установите devel-пакеты libmad и libid3tag, они понадобятся для нужного нам плагина.
Качаем gst-plugins-0.6.5 и ставим:

~/gst-plugins-0.6.5$ export PKG_CONFIG_PATH=/opt/liar/lib/pkgconfig/:/usr/lib/pkgconfig/
~/gst-plugins-0.6.5$ export CC=/usr/bin/gcc-3.4
~/gst-plugins-0.6.5$ export CXX=/usr/bin/gcc-3.4
~/gst-plugins-0.6.5$ ./configure --prefix=/opt/liar/ --disable-ffmpeg --disable-v4l --disable-v4l2 --disable-cdrom --disable-vcd
~/gst-plugins-0.6.5$ make
~/gst-plugins-0.6.5$ make install
~/gst-plugins-0.6.5$ /opt/liar/bin/gst-register

Всё, можно запускать ($ /opt/liar/bin/liarliar)!

Готовую сборку под Ubuntu 7.10 можно скачать отсюда или отсюда.

Ещё где-то с год назад встала задача выбрать файловый менеджер для слабой машины не в ущерб функциональности. Перепробовав несколько файловых менеджеров, я в результате остановил свой выбор на старой версии ROX-Filer ещё на gtk-1 из проекта Rox. ROX-Filer работал действительно бодро (во многом благодаря устаревшей библиотеке gtk-1) при малых объемах оперативной памяти и не слишком быстром жестком диске. При этом на том же железе тяжелые файловые менеджеры на GTK-2, а тем более на kdelibs, безбожно тормозили. Удобство же программ вроде XPlore или Worker оставляли желать лучшего.


Вот лишь некоторые из достоинств ROX-Filer (сраведливые и для современных версий на GTK-2, которыми я и сейчас с удовольствием пользуюсь):

1) Быстрый. GTK2-версия не исключение.
2) Компактность. Меню, адресная строка, строка ввода shell-команд и т.п. отображаются только когда это нужно.

3) Адресная строка с автодополнением по tab.
4) Горячие клавиши, в т.ч. можно назначить клавиши без модификаторов (я использую комбинации приближенные к vim: "y" для копирования, "d" для удаления, ":" для вызова строки ввода команд shell и т.п.)
5) Различные режимы показа файлов: список/стандартный, возможность отображения различной дополнительной информации о файлах, превью для изображений.
6) Назначения ассоциаций приложений по типам файлов, а так же дополнительное общее меню "отправить в" общее для всех типов файлов (зд. удобно например повесить скрипт архивирования).
7) Возможность вешать закладки просто на нажатия цифровых клавиш клавиатуры [0-9] (установка производится так же просто комбинациями Ctrl+[0-9]).
8) Монтирование/размонтирование сменных накопителей.
9) Выбор файлов по условию. Весьма интересная функция, для примера скриншот с подсказкой по условиям:

10) Полноценная поддержка drag-and-drop.
11) Автоматическая адаптация размера окна под содержимое.

В новой версии ещё больше вкусностей, например режим отображения только файлов, удовлетворяющих шаблону.
Выкладываю также архив с адаптированными мною пиктограммами Tango для gtk1-версии ROX-Filer (о том что такое shar-архив см. здесь):



#!/bin/sh
# This is a shell archive (produced by GNU sharutils 4.6.3).
# To extract the files from this archive, save it to some FILE, remove
# everything before the `#!/bin/sh' line above, then type `sh FILE'.
#
lock_dir=_sh10989
#
# Existing files will *not* be overwritten, unless `-c' is specified.
#
# This shar contains:
# length mode name
# ------ ---------- ------------------------------------------
# 2045 -rw-r--r-- Tango_pixmaps/hidden.xpm
# 3394 -rw-r--r-- Tango_pixmaps/up.xpm
# 3431 -rw-r--r-- Tango_pixmaps/details.xpm
# 4116 -rw-r--r-- Tango_pixmaps/zoom.xpm
# 2854 -rw-r--r-- Tango_pixmaps/refresh.xpm
# 3780 -rw-r--r-- Tango_pixmaps/help.xpm
# 3044 -rw-r--r-- Tango_pixmaps/home.xpm
#
MD5SUM=${MD5SUM-md5sum}
f=`${MD5SUM} --version | egrep '^md5sum .*(core|text)utils'`
test -n "${f}" && md5check=true || md5check=false
${md5check} || \
echo 'Note: not verifying md5sums. Consider installing GNU coreutils.'
save_IFS="${IFS}"
IFS="${IFS}:"
gettext_dir=FAILED
locale_dir=FAILED
first_param="$1"
for dir in $PATH
do
if test "$gettext_dir" = FAILED && test -f $dir/gettext \
&& ($dir/gettext --version >/dev/null 2>&1)
then
case `$dir/gettext --version 2>&1 | sed 1q` in
*GNU*) gettext_dir=$dir ;;
esac
fi
if test "$locale_dir" = FAILED && test -f $dir/shar \
&& ($dir/shar --print-text-domain-dir >/dev/null 2>&1)
then
locale_dir=`$dir/shar --print-text-domain-dir`
fi
done
IFS="$save_IFS"
if test "$locale_dir" = FAILED || test "$gettext_dir" = FAILED
then
echo=echo
else
TEXTDOMAINDIR=$locale_dir
export TEXTDOMAINDIR
TEXTDOMAIN=sharutils
export TEXTDOMAIN
echo="$gettext_dir/gettext -s"
fi
if (echo "testing\c"; echo 1,2,3) | grep c >/dev/null
then if (echo -n test; echo 1,2,3) | grep n >/dev/null
then shar_n= shar_c='
'
else shar_n=-n shar_c= ; fi
else shar_n= shar_c='\c' ; fi
f=shar-touch.$$
st1=200112312359.59
st2=123123592001.59
st2tr=123123592001.5 # old SysV 14-char limit
st3=1231235901

if touch -am -t ${st1} ${f} >/dev/null 2>&1 && \
test ! -f ${st1} && test -f ${f}; then
shar_touch='touch -am -t $1$2$3$4$5$6.$7 "$8"'

elif touch -am ${st2} ${f} >/dev/null 2>&1 && \
test ! -f ${st2} && test ! -f ${st2tr} && test -f ${f}; then
shar_touch='touch -am $3$4$5$6$1$2.$7 "$8"'

elif touch -am ${st3} ${f} >/dev/null 2>&1 && \
test ! -f ${st3} && test -f ${f}; then
shar_touch='touch -am $3$4$5$6$2 "$8"'

else
shar_touch=:
echo
${echo} 'WARNING: not restoring timestamps. Consider getting and'
${echo} 'installing GNU `touch'\'', distributed in GNU coreutils...'
echo
fi
rm -f ${st1} ${st2} ${st2tr} ${st3} ${f}
#
if test ! -d ${lock_dir}
then : ; else ${echo} 'lock directory '${lock_dir}' exists'
exit 1
fi
if mkdir ${lock_dir}
then ${echo} 'x - created lock directory `'${lock_dir}\''.'
else ${echo} 'x - failed to create lock directory `'${lock_dir}\''.'
exit 1
fi
# ============= Tango_pixmaps/hidden.xpm ==============
if test ! -d 'Tango_pixmaps'; then
mkdir 'Tango_pixmaps'
if test $? -eq 0
then ${echo} 'x - created directory `Tango_pixmaps'\''.'
else ${echo} 'x - failed to create directory `Tango_pixmaps'\''.'
exit 1
fi
fi
if test -f 'Tango_pixmaps/hidden.xpm' && test "$first_param" != -c; then
${echo} 'x -SKIPPING Tango_pixmaps/hidden.xpm (file already exists)'
else
${echo} 'x - extracting Tango_pixmaps/hidden.xpm (gzipped)'
sed 's/^X//' << 'SHAR_EOF' | uudecode &&
begin 600 _sh10989/gzi
M'XL(`)C/V44"`Y64[5.B4!3&/Z]_!65FF6\@(&0Y@$"OVGOM#)--*:54]B*E
MI?6W+^=PN%YW9W=F[_&#/YY[GO-<!$LYX>=A4\B54L/P.NQWA$[O^E7(";U^
MM^L/KL;/C]ZEL"E,4HN2+$0?31/$Q7QJ4?C1$5I/`Q^^%Z/O:4W33$T!7`.T
M)*MBE0$-0*<:E0J8!G1Q`2X!ZJXIZC9@!C=7H`"7$>4(9<`<HA)=0-PD57%P
M;H%4PAJBFF"=4(UCY)F*F"4K<EZE&'(<8X$-0O6;;4;G"5G1`2\95@';[/B(
M)4**L4*9U=CJBJFX>1W0+MNBC7=R`V^L:5F6#N@!FJ9IF1K@%ZJ*I5H8<HI6
M&A2@2,Y:["PQ1+6"J$>%*%,O95:8%:)*2)NKK!=3:9BY$I4$J*-J00&6:;/I
MF(#7S`I[;]@@Q`YSQLU=1#/I]1$;4("WB':"=Z3:,?:HEP;U*949IPJH-RK`
M>T(GQ@>&#N`CHI-L'N!Y95NQ\;8_L0/BH&>6&0>]4"\YOU)(*PXY9(B;0T07
M"O"-,M,!W]GQT6K$G#'D&-^R,A3@!U/1ZA-5,5%-AOAJ6W&OX\9J`[!1;H@6
M]MJ(8D-JH.I0KQCWNG'FQ'F+CD!SMW%SQ95<?#9V$.7H`MZZ740%"G`/48T0
MWY1]AJ@VR2HJP!:BE#@?L%08XS!)%<<XHKER//>8(3J?$-*@4W*F06?D+,7G
M/<>_OJJF:VAU@:A$%S"&\)>5:,7?%J>M&>FY92PQK6AD,LNYS4*M7BOD:X5L
M=M4H,BV=6?C.UR?&I=$NE>HKA6R:TW*U^M7ZAA>MK_5INU[GM96)**$4B96I
MW.:UDJ)6/4_3=<WSRM7K*:])-YVNY_G^[9WGZ7JWQVMJKQ]U!/</CYXW\/4N
MKST]ZQY;@:_S6E>_FVDOP>N<-@QF6GA_RVMO[Z.9-OX(>&T8<-IG^#+7QVNF
M->(U/P@;B60[[FB^;VOL;._L[NWO-EL'A[QFZ,$H=%K-H^.3H].S<?@P^XW^
?_&W7N&?B?/Z1N."?EW\]2_^M?=52OP`)<*N`_0<``%K-
`
end
SHAR_EOF
${echo} 'x -gunzipping file Tango_pixmaps/hidden.xpm' &&
gzip -d < ${lock_dir}/gzi > 'Tango_pixmaps/hidden.xpm' &&
(set 20 07 02 19 19 26 00 'Tango_pixmaps/hidden.xpm'; eval "$shar_touch") &&
chmod 0644 'Tango_pixmaps/hidden.xpm'
if test $? -ne 0
then ${echo} 'restore of Tango_pixmaps/hidden.xpm failed'
fi
if ${md5check}
then (
${MD5SUM} -c >/dev/null 2>&1 || ${echo} 'Tango_pixmaps/hidden.xpm: MD5 check failed'
) << SHAR_EOF
6ae6da1b48fd6a2b8b6c5251a82ab2d2 Tango_pixmaps/hidden.xpm
SHAR_EOF
else
test `LC_ALL=C wc -c < 'Tango_pixmaps/hidden.xpm'` -ne 2045 && \
${echo} 'restoration warning: size of Tango_pixmaps/hidden.xpm is not 2045'
fi
fi
# ============= Tango_pixmaps/up.xpm ==============
if test ! -d 'Tango_pixmaps'; then
mkdir 'Tango_pixmaps'
if test $? -eq 0
then ${echo} 'x - created directory `Tango_pixmaps'\''.'
else ${echo} 'x - failed to create directory `Tango_pixmaps'\''.'
exit 1
fi
fi
if test -f 'Tango_pixmaps/up.xpm' && test "$first_param" != -c; then
${echo} 'x -SKIPPING Tango_pixmaps/up.xpm (file already exists)'
else
${echo} 'x - extracting Tango_pixmaps/up.xpm (gzipped)'
sed 's/^X//' << 'SHAR_EOF' | uudecode &&
begin 600 _sh10989/gzi
M'XL(``G0V44"`]6665,6.Q"&KP^_HA%99`F3R622`:'(,N.^+Z@4("+N"RJN
M++_=3+^3HJQS/,*E?'P73W5Z>3N=KF]^FA[<O$;3\R.?]K;V7F[3]HNMCS1-
MGW<WO^V^75NG)=H?.5-6E/ZEDE2>F1TY0_3/-EU__VZG!]'#F`JF+E3/,\=<
M];S"K+7U)3N/98[@L_F\AO\X<^6ME+;G">8F!&UTS]-@EYC]E_)Y)4W/<V!M
M@BQZ7LS^RM0]+S.;TG7*]3S+7'<N*HX_B?-UD'7L^1SB5<877<^CJ+=-^IJ>
MCX;SOC.<;Y_9:M]HKF\=>IT;]&R`ZZ:5LN=YU--X5;'^*?BWWM?<OTWDB\86
M[+\`>_!US?6>1_XJE#77LP8]RM4EQSM$OM8I&7H^`#>ND-P/":Z:6+0]EXBO
MO-6L1X%+7VK.5Z$>G^]+@UV^[WHXGRZ(ZS',K@S.<#\MZ@LN*-;?@&MG2]97
M@*73)=NW4%]PI>3[>I+K;7$?V[B?KO'HSU/DC[[5;-]!?VMG*K8_R_4/]3Z'
MO7*RXGI?H-X8I>5Z7\)NO*RX'Z^.YX7]7X.]"R6??P.VSI<\CV^S'HO^OT/]
MRDG,SWNP=$7!YW>'^4AVOH\/N%\=5,WZ/P[Q&Z?8_Q.X:BK%_GO,7D?=L-[/
MZ$=Z()K[^27/FZZ8OV9]6OF>OX&5KZ#O.^*W7I5<_X]\'P[SZ\#&V8+K\YD-
M](6L9W@O,<^CQ7MM\_NT>,\=[-ZV)9^_`+;683XN0I^/QO%]7`)WT3N>S\O@
M-C'/YQ5PC`'GKT)?]![ZK^5^!.R#Z]"KO9*<_\:@UQ<%Z[^9]7?@6Y@7%[7E
M>+?!3526\]T!VS1/S'?!1?"&X]\;YC==#\_K_>/WQ?U?S>]+@1\<[P/6^Y`Y
M%+%UW+]'P_L+LF+[XV'?>5^R/A*LK_`UYDN`I;?@&7"9>27;#7B,V8786.QO
M,>S#!O6,,X>RE;B/"69K0GIBO+\1+ST8R7J6Q-#OB'T]!S:^&_;WP*'`O"UG
M_\$^BWJZ&"S?]R3R5VW:@+R_F4W:_XKG9Q3^35H_'.\([(.1K&<?G.91<KSU
M;*]AWV#V1>PLUS^/?'5;.;[/*>2K@L3\;L*_"P%Z%V"7L9#8W["G\42^-<27
M;8'XAT,]J3_<_X.LOX5^"7:A0GUECM<@G@*WP2-_E?49V/60+^NIH4>G_F%_
MY_XZR_5:<'I?Z'>3^]&"BWP^@NF4?W^GCZ"94_NLT!B=/97/.$VDWV9+I_"9
MHT5:IEF:I',G]!FE(]JG==J@>9JBS1/X"%J@\[1&AW1`Z1<B*:K^X*.I)D.6
M&BIHBY[0-CVE'7KV/SZ"GM,+>DFOZ#6]H;?TCM[3+GV@C[]T\%>?3[1'G^D+
M?:5O])U^D"-/@2*UU/W&YP)=I$MTF:[05;I&U^E&^MRD6W2;[M!=NO<?/O=I
ME3\/Z"$]HL>I4"%FQ(H8$V<%+/JW?5NE<3$AIL62F!.+8EG,)H\_]7J5)L6Y
MY#$JCL2^6!<;)_*9%U,I_KK8%`OBO%@[H<^A.!!2E$*)2N@3^=3"""N:='HM
6?8L3^?S[\Q?M@\/%D9]ZFQJ)0@T``%@[
`
end
SHAR_EOF
${echo} 'x -gunzipping file Tango_pixmaps/up.xpm' &&
gzip -d < ${lock_dir}/gzi > 'Tango_pixmaps/up.xpm' &&
(set 20 07 02 19 19 27 53 'Tango_pixmaps/up.xpm'; eval "$shar_touch") &&
chmod 0644 'Tango_pixmaps/up.xpm'
if test $? -ne 0
then ${echo} 'restore of Tango_pixmaps/up.xpm failed'
fi
if ${md5check}
then (
${MD5SUM} -c >/dev/null 2>&1 || ${echo} 'Tango_pixmaps/up.xpm: MD5 check failed'
) << SHAR_EOF
b42c16fed762365493ce92826e6cb5b3 Tango_pixmaps/up.xpm
SHAR_EOF
else
test `LC_ALL=C wc -c < 'Tango_pixmaps/up.xpm'` -ne 3394 && \
${echo} 'restoration warning: size of Tango_pixmaps/up.xpm is not 3394'
fi
fi
# ============= Tango_pixmaps/details.xpm ==============
if test -f 'Tango_pixmaps/details.xpm' && test "$first_param" != -c; then
${echo} 'x -SKIPPING Tango_pixmaps/details.xpm (file already exists)'
else
${echo} 'x - extracting Tango_pixmaps/details.xpm (gzipped)'
sed 's/^X//' << 'SHAR_EOF' | uudecode &&
begin 600 _sh10989/gzi
M'XL(`.?.V44"`\V665<421"%GX=?$2S-TC1)559E+6R'6MW8!%24`]@LVBB;
M@(JR_'8S;E0U#'"<F:>Q+@WG.YDW(S,R*IKQ)JTMS5-SO.?LO'V^OT,[G?8I
M-6EW[[R]?W"V=7%RN+Y!TW39TZ=]LC^NYY'N:_7T$?VU0PO'1WL,BJ&_+$NC
M'>;1FGWAV2Z[)7-_=[[P`#@N$QVGS`UP%$5)9)@'P7F:&^,Q-\4?%)G&_&GA
MM#1!PCPFG)5A#/_D[7C(/".<E([&>*O>CWV8AX3CTL0X[(AP41H/Z_?6G,0Y
M\\VM'WQ9C\<QYF_4\;7G,V^""YUG/GA<QL,BS#%_&)QX0:PSYBW)1^'G#LX_
M(>,ZB.3\4W4\*^;U^OQ6S-=U?"OFJ_K\5LRN<,1BUM5^6,Q>-Q\)\N$+YZ7Q
MX3=U_##$>8*:HQ#[#6_G(S\1.$NS*`3'DH\D]4W`[`CGF1N@?MK"4>H:K+\M
M]9('O@;OU.OGDO]=J1?#8MX3CEG,'\"ISV+^*.,>B[DCZSDLYOTJ'HOYD\S/
M\TS\GZO]%E&(>`=UOCT?^3RL]^=[B']4WX\G^3ONYC<"G\A]EWXA]_U%UL]L
M`:,^3ZOXB?9QGV<R;FQ^$/]<_+FM%]S75\FWRV+^)N?!P_R]JC<6\X7DQV,Q
M_Y#YFL7\4\8UBSD1OYNX$?*1RG[L]B/48U:]KZ6.$3\7=HLBQ7T7PCZ+N93U
M'%O_V-^3ZGQ);G`?3ZOUD\Q'/I[)_HQ-`/+WO,ZG%?.+.KX5\YRP83'/"WLL
MY@5AS6)>K/;+8EZ2^'CAF%\*XV%>KNO!BGE%.&4QKU;USF)^5>>_>E]>@X,B
M<#36?R/W&1K707[6A&WYROV^%=9^)N/OQ!^93*/^WDM^LL0-T`](H7XT"_U;
MV&6A?X/1/A!_5KA@H7_+?)^%_@TN8A;ZMW#$0O\&FS+P':S7!(>VN[L8G[YE
MW,^8L!-F+NY[$AQDH7&0SQEA$Q0.\M>2]=/`$1Z2^`$+_5M5WR]^B/5Z97X1
M>`[NXT8X-+GD[U+8F$1X`QP%42K]9U/.CPM&_Q:.6.C?PB$+_5LX8*%_R_Y"
M%OJWL&&A?ZOJ_;%"_U9U/Y)ZNZK'38[]NZI;C]B/%L:%H7\+>RST;V'-0O^6
M^\U9Z-_@-+7EBOV%->?"D7!2<RSK.2ST;UE/L]"_5=4O[8/^+?=1)*Y\/])_
M?/XLCZ)1FK6_^^]X!JCQ&PW:?[&F:8PF:>:.IT&MWVB(1JB7;NB2-FCSGF><
MAFF+)NS?%DW1.EW3%;FDR2.?C'4%%%)TSS-,,3G4IFW:H5W:HP_TD3JT3Y_H
M,QW0(1W1L9WY=\\)?:%3.J-S&^$K?:/O=&%=/^@G)9121CD5#SPE/;&.I_2,
MGML=O:`YFJ<%6J0E>DG+M$*K#SROZ#6]H35Z2^_HO1TEQ<\H-*OZU8!JJ/N>
M0=54TVI,3:H9U5+S]B2L)6B%V#'TP#.B>M4-=*DVU")MJG$U;+5E/PTUH:;4
M^@//(EVK*\BUC@[.H-5J%6%*><I_X.E7KCW#'/$9.F34DOTL6U]@/:&='ZGX
M$<\"/HYRK,>Q'@>>R'HB>-J/>F[5Z8ISL&SS_)BGL#.+?U3C7];U76VK/^T]
0_9\\UY,]OP!'#51(9PT``-J/
`
end
SHAR_EOF
${echo} 'x -gunzipping file Tango_pixmaps/details.xpm' &&
gzip -d < ${lock_dir}/gzi > 'Tango_pixmaps/details.xpm' &&
(set 20 07 02 19 19 23 03 'Tango_pixmaps/details.xpm'; eval "$shar_touch") &&
chmod 0644 'Tango_pixmaps/details.xpm'
if test $? -ne 0
then ${echo} 'restore of Tango_pixmaps/details.xpm failed'
fi
if ${md5check}
then (
${MD5SUM} -c >/dev/null 2>&1 || ${echo} 'Tango_pixmaps/details.xpm: MD5 check failed'
) << SHAR_EOF
ae95b3d91f27ee707c09876971f6a392 Tango_pixmaps/details.xpm
SHAR_EOF
else
test `LC_ALL=C wc -c < 'Tango_pixmaps/details.xpm'` -ne 3431 && \
${echo} 'restoration warning: size of Tango_pixmaps/details.xpm is not 3431'
fi
fi
# ============= Tango_pixmaps/zoom.xpm ==============
if test -f 'Tango_pixmaps/zoom.xpm' && test "$first_param" != -c; then
${echo} 'x -SKIPPING Tango_pixmaps/zoom.xpm (file already exists)'
else
${echo} 'x - extracting Tango_pixmaps/zoom.xpm (gzipped)'
sed 's/^X//' << 'SHAR_EOF' | uudecode &&
begin 600 _sh10989/gzi
M'XL(`"30V44"`Z56:5/56!#]//R*5O:MR4ORDEP0RMS<Q(5%%'<*$)`=!`$7
M-G_[].V3\*84<)QY+56>ZGW-'1NBM_.S-#36=7*Z>KJS3NO;J\<T1.>'AP<K
MWX\.%I=HDBZZ[H<QR;]6FE!X?Z3K/M%?ZS1W^&G#`_:@VZ3&F+;'PXJS(BLS
MX_'##LX][@9V607<`VPRFR4>]RJN].=Q'W#IR>,AX*`*2N5/0C\7#ZG'HXI5
M7.4G%!>ID-J?`DZ$--X1R.O/X_X.=AX/`CNAPN-[':S\'\@_,&&F\5PH3L,T
M2A0O`0=I*U'Y9<5)F0:)]7BLD8\A/Z`XKVPKUWA6%+N6"UW@\7AC+X3\`^1C
MBZ+0>BY"/G?6:;Q7P+%+G/;CLK'7!FX!IRYSJA_"7BZD_`CQNJ1"O#'X4NY"
MZ]U6;*5]5NN;0+Z2?-5_VHE'];-Z7G)3M#PVR*=E#/H1`*=Y6&A^JW5]3%5H
M/=9J^R8K8H_78<_E91%Y_!'^M$$>;]3VFWYL-O'DR'<+\V/S%/ZW._Y4?@?Y
M&F=*C7\7_8]*6ZG_/=BK2E/I<NRC'DGA2N4?P%[4Q/^IGG_QI_$>0M\V]3E"
M?E8JKO7_#/]M3QX?8SZB/,[5WPEPFF>YUO\4]2CS"O7YTLE'Y^]K,P\5YOD;
M\HDE'XWG.["5#5-[9\"A&%1[Y]!OEV&E\YC7\RH+KOJVZ:>#OP)\9W/,I^O$
MK_TO8;\0TOPKY&^D`NK_4:=?6H_'X"<FL-J?)[7](BFU'D\A;\H8\4W#?B#]
MT?AF.OU3/`OYP-7[/H?Z13;&?#Q#/K&QF/=Y]*^51\CG>>U/*//X12<?K>\"
M^)G?`(]?-O4I,0^OT-_`1:7:?PWYL.G/F^M\<._>`KLRK;1^[^K]+2/D^Q[S
M5Q0E^O$!V+H`]HG5OS5QKO:9Z_Z&J-^PXLIYTOL-OO6D]YLQ[Y[T?L->D@?H
M=Z_BW!81^'V,>^N24NLSQ'5^#O8F%<NQJK`OHY"7>X?X)X`CF3BM]Q3\%1*_
MXA'&/37UO>H'EG'`_@PBG]R3WN]./HI_`.>>]'XKEJ^9-5JO)?B//>G]5IPE
M>8+^CP'+_J&?`YW\<;^17RP71.LQSG6_6\CO`?AID9?:OT7P,\E7_5T!RWU&
MO2Z1GZQ[KK@%_T;NJ>(0\D9(ZQV!'V=)IOV-48_4D]YOY&\\Z?VN^R7?2_6?
M0K\T0:;]S;C^?I@2]QOYQK;"]R9`/I'<`\UG%;B4_JK_-:[O1=NIO?6ZOC+_
MN-]-/0K@C69>#.QM(O]4+H3>PRW,0YJ:5._%-NS+N<+W<P?V3)$COEW(2W\+
MM;<'?B'[H?;VH1_:$O('C7QF%7_B^AX73O,YQ+Q$IFT4']7SD:69VON,>#.)
M5^,[!C^3%XOR3[A^/[3P?CA%OE;V4?OQ!?S$1O#W%?%DLF^XW^"G<J]POZ'?
M=@7FYZR>%[FG.@_G?/V]UO[GB*<M\:J\A?TX35+U5T`_D0R4[\"7#TZJ]DJN
MWU\6[[D*]BM/>K\;^PGR?0Q[81(G6O\G7+\O2KPOGM;]%U+Y:;Y^'ZJ_&;Y^
MSVG\L\V^NT3]SW7RT?B?\?7W5/7GZWT5BYK/\X9OX?\%U^\IB_U>0#T33WC\
M_MGO_^DP#=?TD+JO_P_JOD6GAWJI[T;J%:W;=89NI+Y;=29OT1F]0P=^)GZB
M*1KYK9_1?U"_T"#=^P,_/^B"EFB9QFC@7^6S0N/T@!;IBBZI12%%=_J)Q4.;
M$DHI(T,!K=(:K=-'\7=7/B.T09NT1=NT0[NT1_MT0)_HD(YNT1FESW1,)W1*
M7^@K?:/O=$;GE).E@MPM.OU44D6/Z#$]H:<T33/R-TMS](SFZ;EP;M(9I!<2
M^0*]I%?TFM[06WI'[^F##.-+8EZ^H0;#7-)#X71S#_=R'[^F(9[D49[@*1[A
M0^KG7W4&^1[_X`M>XF4>XP%>X7%^P(M\Q9?<XI"C&W1BT6ASPBEGO$J&`U[E
M-5[GCX(V>)-OZD\S^UN\S3LBM\M[O,\'++7F0S[BS[_X&1:M'CIF3_U\PJ?\
MA;^*YC?^SF=\SCE;+OBNW2[8<<D5=_,C?BR23_@I3_,,S_+=]V".GXG'>;7]
<7*1?\,)O=7[^S:K&?[P[5Q-=?P.8U>>W%!```/@I
`
end
SHAR_EOF
${echo} 'x -gunzipping file Tango_pixmaps/zoom.xpm' &&
gzip -d < ${lock_dir}/gzi > 'Tango_pixmaps/zoom.xpm' &&
(set 20 07 02 19 19 28 20 'Tango_pixmaps/zoom.xpm'; eval "$shar_touch") &&
chmod 0644 'Tango_pixmaps/zoom.xpm'
if test $? -ne 0
then ${echo} 'restore of Tango_pixmaps/zoom.xpm failed'
fi
if ${md5check}
then (
${MD5SUM} -c >/dev/null 2>&1 || ${echo} 'Tango_pixmaps/zoom.xpm: MD5 check failed'
) << SHAR_EOF
7de7f3590a322af1f74ddc27e1049398 Tango_pixmaps/zoom.xpm
SHAR_EOF
else
test `LC_ALL=C wc -c < 'Tango_pixmaps/zoom.xpm'` -ne 4116 && \
${echo} 'restoration warning: size of Tango_pixmaps/zoom.xpm is not 4116'
fi
fi
# ============= Tango_pixmaps/refresh.xpm ==============
if test -f 'Tango_pixmaps/refresh.xpm' && test "$first_param" != -c; then
${echo} 'x -SKIPPING Tango_pixmaps/refresh.xpm (file already exists)'
else
${echo} 'x - extracting Tango_pixmaps/refresh.xpm (gzipped)'
sed 's/^X//' << 'SHAR_EOF' | uudecode &&
begin 600 _sh10989/gzi
M'XL(`/#/V44"`\V5:5?4.AC'7U\^Q5]P!2Q)NJ01\4R2=L2%51"4@X@(@K()
MJ"CB9S=]GM3A>D`O+SS>=C@SO^;9ES(RB,7I"0R.]!T>K1YMK6%M<_4`@SA8
MWSA8/]Q<.=[?65K&&$[Z^E6&\#$:JG^XKQ_X9PV3>[OK#20-#*25-B)O>(C9
MZT)D#7>8G<Z9!UKYDN6O,M?:,E_KZ1-?)RYR*Y5K>)"X]+[,*9@Q8M.M;$'R
MMXFMJ85.&QYMSXNB;/@>L_`VUPT/LWUGLY3BN]'ZUZ)H^!9Q+DHC;<-7V+_S
M5>8;_L;^TEH69.^$N:HS3?K+O7/B%\0ZQ,/YC#";2BG1\$WFRE>J;GB%XTTK
MF9/^'>;<EP7%>Y?CRTJG9,-+Q)DMA23Y4[:7.942?V5Y8U)%]9,L+T,_*!_%
MK'574OU2KH^W*>MGG(^HRH+BS]E^[7U*\@7+9\Z);L.:_=4N%57#)9];ERKJ
MEXGY><7]$^R_+E-)]E?;^*R@^K]B]J64IN&U=GY*0?5_'?,/\5.\ZVR_]);[
MO\'^2Y=)JN\;CJ^PA2![F['?S0`UO,7RRN:*\GO+_:^<+:A^[WKS3?ZVF:U.
M>=YWV%Y9>D7V=EF_ZU5.]=GC<V4\UW\_YF\LVWO/\JDK<^KO0:RGR135X[#U
M'_?M*/;;ZHSB_<`L;)52?3]R/H75BNKQ*<ZCK7F?CMMZ=]G_9_;G3=R_+W$^
M79Y1O6S,SW0E^7<<KW6&\_-LK]05]Z-JSUU.^=;<'^6ZO!_=MO^&Y>_'>H5S
MBF^<Y;5/"YJG!\Q%8++WL.V?$Y3?(S[/O"PHWL>QWJ7C^9J(_3="4KR3+"^]
MX/V:XG-KI:3^3;?[HW@>9MI^9US_6:ZO,)KK]:07/_5OKO572^+Y.(^FR_UY
M&M\OKN+Z++!\:BK>G\6VGWE*\_N,Y;6+[[/G\7T0Y.G\94^>\D-"K*W-2#Y)
MXO[%]]=0$N<IX_YWDAA?Q?L_P.<A/<X7E[S^GDZ"(70P@*OA^[_H7,/U\-]P
M#+<QBGL8QHW?ZMS"%7S#"9;Q`B.XB17<P=W@\V*=)9SB*R044F3(44"CA(&X
M4&<5K[`6GW7P&NO8P!ML8@MO\>X"G>V0]=EK![O8PWZXW^/@`IW#GYYW<(0/
MI/,1GW[*B76.SZG.9WPA'0MWKD[OVOYQ>U2DLX?ZS-/M<WO:01?W,1[N!WA(
M6N-T/\+CZ.^\V>E@`I.8(GF^IP)/_XCP_'F;P2R>8"YJS(7?L^'9[V9T!O-X
MBH6@L1"^Y\]H_&JN9["(9W@>_E[^2^/7NQ!JE"0)DIE+[<]0TDF&DLONW$#R
2?]KM/Z1S.MKW'9H@C8<F"P``
`
end
SHAR_EOF
${echo} 'x -gunzipping file Tango_pixmaps/refresh.xpm' &&
gzip -d < ${lock_dir}/gzi > 'Tango_pixmaps/refresh.xpm' &&
(set 20 07 02 19 19 27 28 'Tango_pixmaps/refresh.xpm'; eval "$shar_touch") &&
chmod 0644 'Tango_pixmaps/refresh.xpm'
if test $? -ne 0
then ${echo} 'restore of Tango_pixmaps/refresh.xpm failed'
fi
if ${md5check}
then (
${MD5SUM} -c >/dev/null 2>&1 || ${echo} 'Tango_pixmaps/refresh.xpm: MD5 check failed'
) << SHAR_EOF
b689b71208c3c7ea405024cce5304d22 Tango_pixmaps/refresh.xpm
SHAR_EOF
else
test `LC_ALL=C wc -c < 'Tango_pixmaps/refresh.xpm'` -ne 2854 && \
${echo} 'restoration warning: size of Tango_pixmaps/refresh.xpm is not 2854'
fi
fi
# ============= Tango_pixmaps/help.xpm ==============
if test -f 'Tango_pixmaps/help.xpm' && test "$first_param" != -c; then
${echo} 'x -SKIPPING Tango_pixmaps/help.xpm (file already exists)'
else
${echo} 'x - extracting Tango_pixmaps/help.xpm (gzipped)'
sed 's/^X//' << 'SHAR_EOF' | uudecode &&
begin 600 _sh10989/gzi
M'XL(`#[0V44"`[669U,<.1"&/Q^_HC%+AF;R:$B%TCCG;`HP+-$F+!F;\-M/
MTRVQV,!=^:IN15'UE/1*;[>ZM3LQ`I]>/8>1B9[#H^6CK3:T-Y</8`0VU[8[
M2V>=G?D%F('SG@=)!NXOSG-('HSU/`#XJPTO]G;7&L`&^I15MHP;'B46NM*B
M:GB.N!`BJW3#?<2Y*J5,&VXQ2\=9P_W,95G*J.$!8B-,4A*/$->QK639\`RS
MK`LM&QXGML+FO-\4L<Y,K.G\6?:;Z<H0CQ'+7!E#^PTR%\HR#S.7CD7#O8%K
MYBMF$?B<N#*J-)2L!>*R%%I0O(OLSY@LHG@FF"L3,P]YMFE%^5OB^$RM:]IO
M,K"I*=YIYJK..;YYUF<VX?@OV9_5J:X;OF!_N8J98Y[7.C6T7\+[:5ME-)_Z
M_4Q=%0UG?KZ6EOSE77]T7L&<6:LHWI+UD8TD^1-\GG'G4;P5^RF=`]5PQ/-I
ME2@Z;YE9B532_(KW*R))Y[?]?0BIJ/Y6>3\I<YTWO!;8W4##Z^POM4K2_AO,
MA;7L;]/[-5)0/K:X_@IC--WO-SZOTC'7QW?>OW`1D7[;UX,0DO*WP_/N@A7Q
M;EAOM6EX+\Q;3?GHA'@32>?O=^,AOP?<'Z;4DNKA,/1';2C^(V9C:D7Y.>9Z
MESKA^SCA?C!&6LK/:3<>6G_&G+@*(?X1_&EE&_[)[+I/4_S2ZT4N*1YU'2_'
MHWT_"<7W8]A?:5-+^;#LQQK%?FJ_GQ*:SGO(\]KYI7P\"O6BN%X>^WZ3D:9\
M/.GFE^[C*;]'624*FG\6^C-**+[GW)])Z0JTX1<^GS:KR>_+KC^Z_U?!7\7U
M^]K78UE+FG\3^BMB_V^[]4KS[_R\K/G^WS,KF6GJGP^AGBM%^W\,]1!S/7SB
M>*(FX0U_[OHAOU]"_+Z?OC(+*;A^`:_S1>L1^?T35M'YH^CCE1SO'*^OP_WW
M!9:*_+=8'U>E(C_]Z.NAX'H80-\/I23]"'H_4E/^9]#7@\_W.%[7)YT_Q?HD
MCPNJMUEB6R<5W]\8K]=1Q._G8'<_XF'T_5-P__02JR3T[Q5SK;6E]>=!G[)^
M@3DUM:5Z6N3S:J.9)YA+IR"_0\R122SE<XGW=^W*^T\&5LS3S"+P/',5^)+C
MUXE-Z;P+WC\)\<;,RE4LQ9,0.S.:W\N46"3"<OUDS)$P_'[FW?7DOV!V%\;?
MKR6S<A=&\X)9"\5<,9N@C\)^?O]EYCJ<O\+GQZ)F?VWOK_+?#ZO,:>"UKE_2
MKQ,741E7]%YL\+RL"D7]O<GYR]V@^][R^6X&O=\^O\V@]]O[J1)^K[<YG['[
MOB3]#OKWU'WH_6:VS:#W.YR?L=\.^[.EJ6A^/\2K^/?.`=^GZT]%ZP^9E8JX
MOXX"Q\S'_OX#G_A^DI;UI^C?+UE1_&?$>5ZFE>(?:W_VZ6H01F$.^J!US^B_
MI1EPOQUG8!RF8!;&W!AT8QAZ:5RY<0X+L`@3OVB&8`DF81KFX1(N[ABQTR1.
M=5.30@8Y%%""H#451+`,*]"&U7LU:[`.&[`)6_#-K?@.V[#C_N_"'G1@_Q[-
M`1S"$1S#"9RZ%6?P`WZ"=,H.*-#W:%I@P$(-#TDCX9%S]=B=)>&)<]AHGL(S
M>/Z;Y@6\A%=>\QK>P%MX!^_A@_/WD32?[M%\]IH.?'$9^.H\;KN+0[Q?,XI!
M@SB'?;@"+>S'`1RY5S.#X]>:G^ZD'1?)S?N9PED<PU\U@S<T%S",VL6^`@/X
M;YI>#)K;=7"W9A2O_E!SC@NXB!,XA$LX>6-,TYC'2Z>X^$T38X(I9IAC@24*
MK##"95S!-J[B&JYCZU8OM&`#-W'KSO$-N8-N:[[C-N[\,G:OQQ[>I>F'#N[C
H`1[2.+HQCMTXP=,[O`&<80O^>=S6_)<WY'_67$[U_`W!OIP.Q`X``.F'
`
end
SHAR_EOF
${echo} 'x -gunzipping file Tango_pixmaps/help.xpm' &&
gzip -d < ${lock_dir}/gzi > 'Tango_pixmaps/help.xpm' &&
(set 20 07 02 19 19 28 46 'Tango_pixmaps/help.xpm'; eval "$shar_touch") &&
chmod 0644 'Tango_pixmaps/help.xpm'
if test $? -ne 0
then ${echo} 'restore of Tango_pixmaps/help.xpm failed'
fi
if ${md5check}
then (
${MD5SUM} -c >/dev/null 2>&1 || ${echo} 'Tango_pixmaps/help.xpm: MD5 check failed'
) << SHAR_EOF
b002347e0d3193e03938949465314fcd Tango_pixmaps/help.xpm
SHAR_EOF
else
test `LC_ALL=C wc -c < 'Tango_pixmaps/help.xpm'` -ne 3780 && \
${echo} 'restoration warning: size of Tango_pixmaps/help.xpm is not 3780'
fi
fi
# ============= Tango_pixmaps/home.xpm ==============
if test -f 'Tango_pixmaps/home.xpm' && test "$first_param" != -c; then
${echo} 'x -SKIPPING Tango_pixmaps/home.xpm (file already exists)'
else
${echo} 'x - extracting Tango_pixmaps/home.xpm (gzipped)'
sed 's/^X//' << 'SHAR_EOF' | uudecode &&
begin 600 _sh10989/gzi
M'XL(`+W/V44"`ZV6:U?42!"&/R^_HKC+##1))DEWBW!(YN(51$5$.8@(*"@W
M`1%%_.U6O=6!169V#WLVK_GP3/=;55WI;IFLT?+"'-4F^XY/UD]V-FAC>_V(
M:K1]L+>U=G:XM[)*TW3>-Y"DQ/_BR%,R,-XW0/37!LT?[&\)&('!(HWX$:Z#
M.ZG-;"8\"VYG#=_PPH/*26(3*SRDW$SS-!<>5G^<-M.F\(ARE,59+%Q33C)^
MA*?5'R5Y`O^$CC>R,BN%IZKY[:PM/`.V)<<OA,?!SF5%YH1'P:UV%6\LQ./R
M4N%^L/=92^/_4G_J,H?FG.MXR4+\57`S<H4#O]7XS2K^9.A7WLRQWCL5\R.\
MIO%:W,^&\%W-U_&1:PG?`Y>.$Z+^%<V7L-"O"QTO6.C_3QU/B[C`>%S5DR7H
M9U*MER7<T._;<"V']:9:3Z>(//J9:?P."YR'_K%0GU7&(^R4K4C8:SV>/Q?R
M1QJ?&Q9A/>N:W_J.A_]]J(>%?F]HO$(DO*G[H1`);RE[D?`'92L2_AC6WXI:
MV+_;X7LF28+^[&B^N%KO)^6$\V/\L_J=2'A7X^<BX3WE5"2\K]P0"1^$\R`=
M$S[4>"57A'Y_`?-FMQGF'^G^M=99K.]8.;?>HC\GREEU_KY6G%O4<QJ^KTCX
MF^;'(WRF\]LNLLC_7;GC8HO]^4/[$[E$\Q7A?(N$RZMZ,+^I[+UO(E\KU.]=
M$]^O7=7G='XGG%>1\'V-CPTE_*`Z;[E#_Q\J9\[J^7L4^BD2?GP5'^MYHOWL
MN+S$]Y\#IX7-"ZQ_7N<G[$!_GX;[2"2\$.XKD?`SS9\[Y["^Y\J%<SGZ\4+9
M.V>QOQ;#?242?JGY8NMT/4O@1IIG!?;+*W#>MF&]R^$^%`F_UGBE2/B-YK.<
M$?YWX7YSWF)]9.#W(MS?X#(N&R7V1]V$^Z2I]\>L"?='66*]@\J>-RC&AXS>
M_R+<W^!V1X3[VX3\A4,_:N;R?D`]TR:<IT3/\X2Y/-_HYQ0XSWC[@F?`7C84
M\HTK.V;4/ZKL?:$\=L7XWOVZ?B?2_\QN]_3V&-;M/(;J+',+CSIZN;IYQ#$+
MQV!7UTV/.(9H.'BZN?[TB&.$_VZHHP=U_J/AINNZ1V9-T!1FS=`X>/2&Z^\>
MF3'&DAG]](O.:16_O?W#=>61T4FZ@]$UNDOW:(4NZ"=^CZ^YKGL2C#0HI8QR
MEB5'GB*X>GGD]W5Z3QNT"6VQ/M!'N'IYMFF'/M%GVN69HEW:8^W3`5RF:P\.
MZ<NE),,1'=,)OU_IM&L/B.=]X_>,OM,/UBX55%*3/2UJ4X='NGON\_L`>L@U
M/:+'](0]<S1/3WMZ%OA]QGI.+]BQ2"]IB3U+](J6>WI>\_N&]8[K6^0%&E,W
MLV;0#)EAT\NSR>^(4=5XPTV;B2#;,\\R39D9,VY&S9@YY8Y<J;]GGG_6O]\'
3_^4.^9\]%U-]OP'YYZ,MY`L``"#;
`
end
SHAR_EOF
${echo} 'x -gunzipping file Tango_pixmaps/home.xpm' &&
gzip -d < ${lock_dir}/gzi > 'Tango_pixmaps/home.xpm' &&
(set 20 07 02 19 19 26 37 'Tango_pixmaps/home.xpm'; eval "$shar_touch") &&
chmod 0644 'Tango_pixmaps/home.xpm'
if test $? -ne 0
then ${echo} 'restore of Tango_pixmaps/home.xpm failed'
fi
if ${md5check}
then (
${MD5SUM} -c >/dev/null 2>&1 || ${echo} 'Tango_pixmaps/home.xpm: MD5 check failed'
) << SHAR_EOF
4d11478aebe0f54ddd950e3a1f5863a9 Tango_pixmaps/home.xpm
SHAR_EOF
else
test `LC_ALL=C wc -c < 'Tango_pixmaps/home.xpm'` -ne 3044 && \
${echo} 'restoration warning: size of Tango_pixmaps/home.xpm is not 3044'
fi
fi
if rm -fr ${lock_dir}
then ${echo} 'x - removed lock directory `'${lock_dir}\''.'
else ${echo} 'x - failed to remove lock directory `'${lock_dir}\''.'
exit 1
fi
exit 0

GUI-конвертер pspvc конечно отлично подходит для создания одного-двух фильмов для PSP, удобен быстрым интуитивным доступом к настройкам и возможностью точно сгенерировать превью, однако удобным быть перестаёт в случае необходимости конвертирования целого набора видеофайлов.

В связи с этим выкладываю скрипт для пакетного конвертирования сразу нескольких видеофайлов для просмотра на PSP под Linux с gentoo-wiki с моими небольшими доработками, а именно:

1) Добавлен мини-конфиг: можно прописать путь к перекодированным файлам, задержку при создании превью и путь к ffmpeg (я, как видите,
использую не стандартный ffmpeg, а оный из поставки pspvc)

2) Проблема в том, что если вы перекодировали файл, переместили его на psp, а затем перекодировали ещё один,
имя нового файла так же будет M4V10001.MP4, потому что скрипт конечно не знает о существовании файла с таким же именем на psp
(и, конечно, никто кроме вас об этом не знает).
Я предлагаю решение: каждый раз при запуске скрипта вбивать некое значение (постфикс), которое будет прибавляться к цифровой части имени файла.
Это особенно удобно если вы например кодируете сериал: первый сезон с постфиксом 101, второй 201 и т.п. для получения говорящих имён файлов.
По умолчанию файлы по прежнему начинают именоваться с M4V10001.MP4, так что если не предвидиться конфликтов имён, вместо ввода постфикса можно просто нажать enter.

Собственно листинг:



#!/bin/bash
#script name: make_psp_movie.sh
# Converter for batch video encoding for PSP in Linux.
# http://damnsmallblog.blogspot.com
# Originally: http://gentoo-wiki.com/HOWTO_PSP#Converting_all_your_videofiles_at_once

### CONFIG -->

# Prefix for 100MNV01 dir (originally "/tmp/`echo $LOGNAME`/pspmovies/MP_ROOT/")
prefix="/home/`echo $LOGNAME`"

# Preview pic time position in seconds (originally 5)
ss=10

# Path to ffmpeg binary (originally ffmeg)
ffmpeg=/opt/psp/pspvc/share/pspvc/bin/ffmpeg

### CONFIG <--


if [ $# == 0 ]
then
echo "Use: make_psp_movie video1 video2 video3 ..."
fi

# First file's name postfix - number from 1 to 9999 (originally "1" - file name M4V10001.MP4) -->
output="10000"
postfix=0

until (("1" <= "$postfix" && "$postfix" <= "9999"))
do
echo -n "Enter first file's name postfix (from 1 to 9999): "
read postfix

if [ "$postfix" == "" ]
then
postfix=1
fi
done

let "output += $postfix"
# First file's name postfix - number from 1 to 9999 (originally "1" - file name M4V10001.MP4) <--

# target dir
target="$prefix/100MNV01"
mkdir -p "$target"

for m in "$@"
do
echo "-------------------"
echo "Start converting $m"
echo "-------------------"
#output="10001"
while [ -f "$target/M4V${output}.MP4" ]
do
let "output += 1"
done
#generate video
#If "-r 29.97" does NOT work try "-r 14.985"
$ffmpeg -i "$m" -f psp -r 29.97 -b 768k -ar 24000 -ab 64k -s 320x240 "${target}/M4V${output}.MP4"
#generate thumbnail
$ffmpeg -y -i "$m" -f image2 -ss $ss -vframes 1 -s 160x120 -an "${target}/M4V${output}.THM"
#list the files that were just generated
ls -l "${target}/M4V${output}.MP4" "${target}/M4V${output}.THM"
done
echo
echo "---------------------------------------------------------------------------"
echo "You will find any newly generated PSP videos in:"
echo " ${target}"
echo
echo "Please copy them to your PSP's 'MP_ROOT/100MNV01/' folder."
echo
echo "Note: if that folder doesn't already exist, just create the folders first."
echo "---------------------------------------------------------------------------"


По долгу службы встала необходимость создать презентацию для последующего показа под windows.

Итак, как сделать презентацию, гарантированно работающую на любой современной win32-машине (а именно создать exe-файл с презентацией, запускающийся даже на "голой" винде):

1) Делаем презентацию в OOO и экспортируем в sfw.
2) Качаем standalone-флэшплеер с сайта adobe. Я брал конкретно вот этот архив: flash_player_update3_mx2004_win.zip
3) В архиве, кроме всего прочего, присутствует файл SAFlashPlayer.exe - это и есть standalone-флэшплеер.
4) Запускаем его в wine и открываем свою swf-презентацию (File->Open).
5) Сохраняем в exe-файл (File->Create projector).
6) Проверяем полученный файл в том же wine.

Итак, есть задача автоматического создания xml-файла с программой передач (EPG, он же Electronic Program Guide) на российские каналы для последующего использования в софтине типа MMS или Freevo, либо для просмотра например в gshowtv.
Стандартное (но, увы не всегда качественное) для таких случаев linux-решение - набор утилит xmltv. Скрипт поддержки русских каналов можно взять здесь.

Я же предлагаю альтернативное решение - TVxb.
На сайте можно найти не только наборы каналов для разных стран, но и наборы для различных тв-провайдеров (из российиских, кроме пакета со стандартными метровыми и дециметровыми каналами, есть также ini-файлы для Stream-ТВ, Космос-ТВ и НТВ+).

На сайте есть zip-архив предназначенный для linux-пользователей, однако к сожелению это лишь удобно упакованные win32-бинарики, которые придется пускать под неэмулятором wine (ну спасибо и на том: хоть такое минимальное, но всё же внимание к линуксоидам).
После скачивания архива программу естественно необходимо установить и настроить:


# Распаковываем например в /opt/
sudo unzip -d /opt/ TVxb-1.0108-Linux\ distribution.zip
# Переходим в директорию с программой
cd /opt/TVxb/
# Делаем доступными для записи директории с изменяющимися файлами
sudo chmod a+w -R ./cache/ ./ini/ ./log/ ./xml/
# Создаем скрипт запуска...
sudo echo '#!/bin/sh' > /usr/local/bin/TVxb ; sudo echo 'wine /opt/TVxb/bin/TVxb.exe' >> /usr/local/bin/TVxb
# ...и делаем его исполняемым
sudo chmod +x /usr/local/bin/TVxb

Далее скачиваем ini-файл нужного нам набора программ отсюда и кладем его вместо файла TVxb.ini, например:

cp ./TVxb_Russia_Main_Channels.ini /opt/TVxb/ini/TVxb.ini

При необходимости можно скомбинировать несколько наборов и удалить ненужные каналы редактируя ini-файл.

Теперь запускаем TVxb для обновления и ждём загрузки программы передач:


Полученный xml-файл (/opt/TVxb/xml/xmltv.xml) можно просмотреть например программой GShowTV (gshowtv):

Расскажу о двух фичах, которые можно реализовать на роутере с прошивкой DD-WRT на примере роутера Linksys WRT54GL.

1) Файловая система JFFS.

На роутере можно без труда организовать небольшое энергонезависимое хранилище файлов.
Для этого в веб-интерфейсе включаем поддержку jffs (по туториолу из официального вики dd-wrt):

1. Откройте вкладку "Administration".
2. Перейдите к секции "JFFS2 Support".
3. Кликаем "Enable JFFS".
4. Затем жмём "Save".
5. Ждём несколько секунд и жмём "Apply".
6. Опять ждём. Идём обратно к опции "Enable JFFS", кликаем "Clean JFFS".
7. Не кликая "Save", жмём вместо этого "Apply".

Теперь если мы приконнектимся к роутеру по ssh команда "df -h" расскажет нам о наличие новой файловой системы, смонтированной в катаалоге /jffs/, и её размере (размер очень сильно зависит от типа вашей прошивки, для получения хоть сколько-нибудь полезного свободного пространства для jffs рекомендуется установить mini-версию dd-wrt).

2) Индикация активности wifi по лампе на корпусе роутера.

Теперь используем возможности jffs - разместим на ней скрипт (с того же вики dd-wrt), который заставляет гореть лампу янтарным светом при подключенных wifi-клиентах и мигать белым при трансфере данных через WLAN.

Для установки скрипта:
1. Коннектимся по ssh.
2. Переходим в каталог /jffs/ и создаем директорию bin:
# cd /jffs/
# mkdir ./bin

3. Как видно /jffs/bin уже прописан в переменной поиска команд PATH:
# echo $PATH
/bin:/usr/bin:/sbin:/usr/sbin:/jffs/sbin:/jffs/bin:/jffs/usr/sbin:/jffs/usr/bin

4. Создаем файл скрипта (# vi ./wlan.sh) со следующим содержанием:


#!/bin/sh
I=`nvram get wl0_ifname`

while sleep 1; do
if [ "`wl assoclist`" != "" ]; then
XFER=`ifconfig $I|grep bytes`
if [ "$XFER" != "$PXFER" ]; then
LED='gpio disable 3 ; gpio disable 2'
PXFER=$XFER
else
LED='gpio disable 3 ; gpio enable 2'
fi
else
LED='gpio enable 3 ; gpio enable 2'
fi

if [ "$LED" != "$PLED" ]; then
eval $LED
PLED=$LED
fi
done

5. Делаем скрипт исполняемым:
# chmod +x ./wlan.sh

Готово!
Скрипт теперь можно запускать командой wlan.sh или прописать в автозагрузку.

Я думаю многим знакома проблема с вставкой сколько-либо сложного текста в свой блог на blogger.com или в форму на каком-либо другом сайте с поддержкой синтаксиса html в сообщениях.

Когда, например, простой фрагмент вставленного кода отображается не как нужно:



#include <gtk/gtkwidget.h>


, а примерно так:

#include


Сегодня совершенно случайно наткнулся на sed-скрипт на небезызвестном сайте http://www.w3.org/ который эту проблему успешно лечит, а именно:


#! /bin/sed -f
# Generate HTML for plain text from plain text
s/&/\&amp;/g
s/</\&lt;/g
1i\
<PRE>
$a\
</PRE>



Так же там можно найти несколько других вариаций скриптов (в т.ч. под альтернативные ОС вроде MacOSX и win32), занимающихся тем же самым (конвертированием простого текста в html, который в браузере отображается как первоначальный текст).

Бывает необходимо приложить к сообщению небольшой бинарный файл там, где такой встроенной возможности нет (хотя бы как здесь, на blogger.com).

Один из вариантов - архиватор Shar из комплекта GNU Sharutils.
Для дополнительного сжатия файлов с помощью gzip архиватор следует запускать командой вроде:
shar -z {каталог или файл для архивирования} > ./archive.shar
В итоге получится файл archive.shar, являющийся по сути скриптом, который достаточно просто запустить для распаковки и получения исходных данных.

Содержание файла чисто текстовое, поэтому его содержание можно смело вставлять в сообщения, e-mail или др. средства текстовой связи. Если сайт попытается найти и обработать html-синтаксис в тексте shar-скрипта, побив его тем самым (как это делает тот же blogger), необходимо сначала сконвертить shar-текст скриптом txt2html.

Расплатой за удобство служит необходимость наличия sharutils на принимающей стороне (что в общем-то справедливо и в случае использования любого другого архиватора), а так же gzip, если использовалось дополнительное сжатие (опция -z).

Для примера прикладываю скрипт-архив со вложенными директориями, тестовым и бинарным (png-изображение) файлами.





#!/bin/sh
# This is a shell archive (produced by GNU sharutils 4.4).
# To extract the files from this archive, save it to some FILE, remove
# everything before the `!/bin/sh' line above, then type `sh FILE'.
#
#
# Existing files will *not* be overwritten unless `-c' is specified.
#
# This shar contains:
# length mode name
# ------ ---------- ------------------------------------------
# 10 -rw-r--r-- TEST/test.txt
# 0 -rw-r--r-- TEST/empty
# 0 -rw-r--r-- TEST/test_dir/2nd_empty
# 781 -rw-r--r-- TEST/gnuplot.png
#
save_IFS="${IFS}"
IFS="${IFS}:"
gettext_dir=FAILED
locale_dir=FAILED
first_param="$1"
for dir in $PATH
do
if test "$gettext_dir" = FAILED && test -f $dir/gettext \
&& ($dir/gettext --version >/dev/null 2>&1)
then
case `$dir/gettext --version 2>&1 | sed 1q` in
*GNU*) gettext_dir=$dir ;;
esac
fi
if test "$locale_dir" = FAILED && test -f $dir/shar \
&& ($dir/shar --print-text-domain-dir >/dev/null 2>&1)
then
locale_dir=`$dir/shar --print-text-domain-dir`
fi
done
IFS="$save_IFS"
if test "$locale_dir" = FAILED || test "$gettext_dir" = FAILED
then
echo=echo
else
TEXTDOMAINDIR=$locale_dir
export TEXTDOMAINDIR
TEXTDOMAIN=sharutils
export TEXTDOMAIN
echo="$gettext_dir/gettext -s"
fi
if (echo "testing\c"; echo 1,2,3) | grep c >/dev/null; then
if (echo -n testing; echo 1,2,3) | sed s/-n/xn/ | grep xn >/dev/null; then
shar_n= shar_c='
'
else
shar_n=-n shar_c=
fi
else
shar_n= shar_c='\c'
fi
if touch -am -t 200112312359.59 $$.touch >/dev/null 2>&1 && test ! -f 200112312359.59 && test -f $$.touch; then
shar_touch='touch -am -t $1$2$3$4$5$6.$7 "$8"'
elif touch -am 123123592001.59 $$.touch >/dev/null 2>&1 && test ! -f 123123592001.59 && test ! -f 123123592001.5 && test -f $$.touch; then
shar_touch='touch -am $3$4$5$6$1$2.$7 "$8"'
elif touch -am 1231235901 $$.touch >/dev/null 2>&1 && test ! -f 1231235901 && test -f $$.touch; then
shar_touch='touch -am $3$4$5$6$2 "$8"'
else
shar_touch=:
echo
$echo 'WARNING: not restoring timestamps. Consider getting and'
$echo "installing GNU \`touch', distributed in GNU File Utilities..."
echo
fi
rm -f 200112312359.59 123123592001.59 123123592001.5 1231235901 $$.touch
#
$echo $shar_n 'x -' 'lock directory' "\`_sh09789': "$shar_c
if mkdir _sh09789; then
$echo 'created'
else
$echo 'failed to create'
exit 1
fi
# ============= TEST/test.txt ==============
if test ! -d 'TEST'; then
$echo $echo_n 'x -' 'TEST: '$echo_c
if mkdir 'TEST'; then $echo 'created'; else $echo 'failed to create'; fi
fi
if test -f 'TEST/test.txt' && test "$first_param" != -c; then
$echo 'x -' SKIPPING 'TEST/test.txt' '(file already exists)'
else
$echo 'x -' extracting 'TEST/test.txt' '(gzipped)'
sed 's/^X//' << 'SHAR_EOF' | uudecode &&
begin 600 _sh09789/gzi
>'XL(`)A8T4<"`RO.STU5*$FM*.$"`+SF+!D*````
`
end
SHAR_EOF
$echo 'gunzipping file' 'TEST/test.txt' &&
gzip -d < _sh09789/gzi > 'TEST/test.txt' &&
(set 20 08 03 07 18 00 40 'TEST/test.txt'; eval "$shar_touch") &&
chmod 0644 'TEST/test.txt' ||
$echo 'restore of' 'TEST/test.txt' 'failed'
if ( md5sum --help </dev/null 2>&1 | grep 'sage: md5sum \[' ) >/dev/null 2>&1 \
&& ( md5sum --version </dev/null 2>&1 | grep -v 'textutils 1.12' ) >/dev/null; then
md5sum -c << SHAR_EOF >/dev/null 2>&1 \
|| $echo 'TEST/test.txt:' 'MD5 check failed'
4d93d51945b88325c213640ef59fc50b TEST/test.txt
SHAR_EOF
else
shar_count="`LC_ALL=C wc -c < 'TEST/test.txt'`"
test 10 -eq "$shar_count" ||
$echo 'TEST/test.txt:' 'original size' '10,' 'current size' "$shar_count!"
fi
fi
# ============= TEST/empty ==============
if test ! -d 'TEST'; then
$echo $echo_n 'x -' 'TEST: '$echo_c
if mkdir 'TEST'; then $echo 'created'; else $echo 'failed to create'; fi
fi
if test -f 'TEST/empty' && test "$first_param" != -c; then
$echo 'x -' SKIPPING 'TEST/empty' '(file already exists)'
else
$echo 'x -' extracting 'TEST/empty' '(empty)'
> 'TEST/empty' &&
(set 20 08 03 07 18 00 28 'TEST/empty'; eval "$shar_touch") &&
chmod 0644 'TEST/empty' ||
$echo 'restore of' 'TEST/empty' 'failed'
if ( md5sum --help </dev/null 2>&1 | grep 'sage: md5sum \[' ) >/dev/null 2>&1 \
&& ( md5sum --version </dev/null 2>&1 | grep -v 'textutils 1.12' ) >/dev/null; then
md5sum -c << SHAR_EOF >/dev/null 2>&1 \
|| $echo 'TEST/empty:' 'MD5 check failed'
d41d8cd98f00b204e9800998ecf8427e TEST/empty
SHAR_EOF
else
shar_count="`LC_ALL=C wc -c < 'TEST/empty'`"
test 0 -eq "$shar_count" ||
$echo 'TEST/empty:' 'original size' '0,' 'current size' "$shar_count!"
fi
fi
# ============= TEST/test_dir/2nd_empty ==============
if test ! -d 'TEST/test_dir'; then
$echo $echo_n 'x -' 'TEST/test_dir: '$echo_c
if mkdir 'TEST/test_dir'; then $echo 'created'; else $echo 'failed to create'; fi
fi
if test -f 'TEST/test_dir/2nd_empty' && test "$first_param" != -c; then
$echo 'x -' SKIPPING 'TEST/test_dir/2nd_empty' '(file already exists)'
else
$echo 'x -' extracting 'TEST/test_dir/2nd_empty' '(empty)'
> 'TEST/test_dir/2nd_empty' &&
(set 20 08 03 07 18 00 28 'TEST/test_dir/2nd_empty'; eval "$shar_touch") &&
chmod 0644 'TEST/test_dir/2nd_empty' ||
$echo 'restore of' 'TEST/test_dir/2nd_empty' 'failed'
if ( md5sum --help </dev/null 2>&1 | grep 'sage: md5sum \[' ) >/dev/null 2>&1 \
&& ( md5sum --version </dev/null 2>&1 | grep -v 'textutils 1.12' ) >/dev/null; then
md5sum -c << SHAR_EOF >/dev/null 2>&1 \
|| $echo 'TEST/test_dir/2nd_empty:' 'MD5 check failed'
d41d8cd98f00b204e9800998ecf8427e TEST/test_dir/2nd_empty
SHAR_EOF
else
shar_count="`LC_ALL=C wc -c < 'TEST/test_dir/2nd_empty'`"
test 0 -eq "$shar_count" ||
$echo 'TEST/test_dir/2nd_empty:' 'original size' '0,' 'current size' "$shar_count!"
fi
fi
# ============= TEST/gnuplot.png ==============
if test -f 'TEST/gnuplot.png' && test "$first_param" != -c; then
$echo 'x -' SKIPPING 'TEST/gnuplot.png' '(file already exists)'
else
$echo 'x -' extracting 'TEST/gnuplot.png' '(gzipped)'
sed 's/^X//' << 'SHAR_EOF' | uudecode &&
begin 600 _sh09789/gzi
M'XL(`/;86CP"`P$-`_+\B5!.1PT*&@H````-24A$4@```"`````@"`,```!$
MI(K&```!(%!,5$4\/#I+-C53(R-60D-5555J8%]B8F%\:FIZ>GJ!7UZ*;&RU
M4U*U5UBB:&>J;6RK<W*R<W2R>GN\=7.[=WB]?W_%>WO(>GK;<7':?WZW?X"Z
M@'^&AH:0D)"=G)RGEYBDF9FJEI>U@H*Y@X.]CY&YD(Z[DY2MJZRXN+C!AX;$
MC8W)C8W%DY+,EI;.G)S4AH;6BXK5FYK+GZ#5G:#-IZ;+J*;2I*;:HJ';K:W:
ML:_5O;[;L[/<O+SRBHG\G)WGIJ3BJ*?JHZ/HJ*CCL*_@MK?FNKOKM+3LO;WP
MHJ#UL;#RNKK_OK[$Q,3+P<'EP<'JRLOPR,C]P\/_R\KST]']TM/]W-O\W^'_
MX-__X^/_Z.;_[>W_[_'_\.__]?3_]_G_^/?^_?UX6LLN```!J$E$051XVG72
M"4_",!0'\'IBO!`#\<!A.-0L,C5JHH@B48P':B8K8[/OO7W_;V';;3(&:]*D
M77][:?\M"]*-B*_O[#H43=DT@*>NY]:(L@"**@!\W0%F`&ARDLT<90`<-7V2
M&^G8-!L`MU1QZIS#3("B<`?R7^+;&<`O@CH`^9L]+=@W3`+'"C^`L^6I$2N*
M"8&7/U$<HLA#X%,2P'X\)]-5!V5G;K("PKZ(@5?3X-5.`K@:Q%,2!0VZ=I2I
M7O?W8%RLR17HY%M+?=F693_)/6^TCE?DR"CW/UM'C=9GG]4;N;E#PS"8[`<+
MF_E*>5&.5I8-H[(ZWS@TF(IVO$?[!E(G8L&P.3XHO+\D`#6X`F`.Z7]?54BD
M0MP,-.#_;^EZ,`'<.DB`S@7%!:Q!,E9T32!YF[\6#Y-`[]1+`A(6EP#AN1V!
MD3EQ+[)B3\@*V.Z%89*;!D[>4P\&]WP-L"K2[Z_TH$%!`_R^@13`CWL-7M[5
M,X5>FRA5P5ECX>Y_D0AJ(K4>!'Z)Q0$%-*I-K0<PT$!&[`/4W6!&8]$EO7GV
G+60#Y.>E1S$3_`&C4U;\WYN)V0````!)14Y$KD)@@NW>I6\-`P``
`
end
SHAR_EOF
$echo 'gunzipping file' 'TEST/gnuplot.png' &&
gzip -d < _sh09789/gzi > 'TEST/gnuplot.png' &&
(set 20 02 02 01 21 05 42 'TEST/gnuplot.png'; eval "$shar_touch") &&
chmod 0644 'TEST/gnuplot.png' ||
$echo 'restore of' 'TEST/gnuplot.png' 'failed'
if ( md5sum --help </dev/null 2>&1 | grep 'sage: md5sum \[' ) >/dev/null 2>&1 \
&& ( md5sum --version </dev/null 2>&1 | grep -v 'textutils 1.12' ) >/dev/null; then
md5sum -c << SHAR_EOF >/dev/null 2>&1 \
|| $echo 'TEST/gnuplot.png:' 'MD5 check failed'
afe5ff1db943f6bfad21b568e79047e9 TEST/gnuplot.png
SHAR_EOF
else
shar_count="`LC_ALL=C wc -c < 'TEST/gnuplot.png'`"
test 781 -eq "$shar_count" ||
$echo 'TEST/gnuplot.png:' 'original size' '781,' 'current size' "$shar_count!"
fi
fi
$echo $shar_n 'x -' 'lock directory' "\`_sh09789': " $shar_c
if rm -fr _sh09789; then
$echo 'removed'
else
$echo 'failed to remove'
fi
exit 0




 

Copyright © 2007 DamnSmallBlog. Content is licensed under Creative Commons Attribution-Noncommercial.

Design: GeckoandFly and Blogcrowds.