Инструменты пользователя

Инструменты сайта



// О PDF-просмотрщиках

Немного о наболевшем.

В PDF, обычно, распространяется документация.

В документации, обычно, есть перекрёстные ссылки.

По ссылкам неплохо иметь возможность переходить.

До сего момента речь шла, практически, о 100% доступных читалок для PDF.

А вот теперь, перейдя по ссылке, неплохо бы иметь возможность вернуться назад, к той точке, откуда мы пришли.

Внезапно, но это, казалось бы простое требование просто фантастически прореживает стройные ряды просмотрщиков!

После длительных поисков и переборов остался такой набор:

  • Кроссплатформенные
    • Как это не парадоксально, но это PDF.js иными словами - Firefox. И он, пожалуй, единственный.
  • Linux
    • Тут тоже нет разнообразия, единственный представитель, который умеет эту простую фичу - KDEшный Okular. Evince и производные что-то пытаются делать, но работают очень странно. Другие не умеют вовсе.
  • Windows
    • Кто сказал - Acrobat Reader? Нет! Он не умеет. Из опробованных мной, с неперегруженным интерфейсом, только два варианта: STDUViewer и Sumatra PDF. Первый подглючивает временами, остановился на втором (на работе). Foxit Reader тоже, вроде, умеет, но его новомодный интерфейс мне непонятен и неприятен.

UPD: Сегодня появилась статья на Хабре, где человек соединил Qt, QWebEngineView и PDF.js, вот репозиторий на GitHub:

Про годность или негодность сего поделия напишу чуть позже.

// GeoCrop 1.0

Я подумал и решил, что функционала и стабильности достаточно для релиза версии 1.0.

Так что да будет так: https://github.com/h4tr3d/geocrop/releases/tag/v1.0

// GeoCrop и популярные привязки

Если у вас на входе привязанный GeoTIFF, то проблем нет никаких, но если у вас просто растр (.png, .jpeg, .gif) и привязка для него, то есть нюансы. Вообще, GeoCrop умеет работать с любыми данными, с которыми умеет общаться GDAL. Но в в некоторых случаях не всё получается гладко, так, например, только сегодня он научился читать файл проекции для world-привязок (пара .prj+.pgw).

На просторах интернета можно встретить различные описания привязок, самые популярные:

  • Ozi Explorer
  • World files21)
  • Global Mapper

рассмотрим более подробно.

Ozi Explorer

GDAL не умеет только шифрованные OZFX, а так привязанная карта представляет собой пару .map+растр, где растр - это, обычно, .gif, .jpg или .png, реже - .bmp. При наличии такой привязки geocrop можно вызвать без дополнительных приготовлений:

geocrop -f VRT -s 50k K-53-026-A.map K-53-026-A.vrt

Обратите внимание, что передаётся map файл, а не растр.

World files

Т.к. сама привязка состоит из двух файлов (.prj+.pgw), то не так просто сказать, что и откуда читать. Согласно документации .pgw, .pngw или .wld файл22) подтягивается автоматически, если на входе карта в PNG (про другие форматы - ниже), а вот .prj файл нужно читать самому. Для этого в последней версии GeoCrop сделана небольшая эвристика:

  • Если растр содержит пустую проекцию, то производится попытка прочитать проекцию (формат WKT или PROJ.4) из файла с таким же именем, но расширением .prj и .prf.
  • Либо файл проекции можно жестко задать при помощи новой опции -p srs_def

Т.е. при наличии привязки в виде world files GeoCrop так же можно вызвать без дополнительных приготовлений так:

geocrop -f VRT -s 50k K-53-026-A.png K-53-026-A.vrt

если файл проекции находится в K-53-026-A.prj или K-53-026-A.prf, или так:

geocrop -f VRT -s 50k -p K-53-026-A.wkt K-53-026-A.png K-53-026-A.vrt

Обратите внимание, что в обоих случаях в качестве входного источника передаётся сам растр, а не его привязка.

Если у вас растры отличные от PNG:

  • BMP - привязка ищется в .bpw, .bmpw или .wld.
  • GIF - привязка ищется в .gfw, .gifw или .wld.
  • TIFF - если это GeoTIFF со встроенной привязкой, то она и используется, если это просто растр, то привязка ищется в .tfw, .tifw/.tiffw или .wld, а так же в MapInfo .tab файле.
  • JPEG - привязка ищется в .jgw, .jpgw/.jpegw или .wld, а так же MapInfo .tab файле.

Полный и актуальный список всегда можно посмотреть тут: http://www.gdal.org/formats_list.html

Global Mapper

В данный момент GDAL не поддерживает данный формат, а значит не поддерживает и GeoCrop. Ищите способ как сконвертировать его во что-то удобочитаемое.

Вообще .gmw файлы достаточно простые для разбора, так что, возможно, появится у меня и их поддержка. Тем более, что для тех же карт GGC там сразу зашита информация об обрезке (только странно, что они сразу не сделали рамку прозрачной).

// Новый режим в GeoCrop

Теперь в GeoCrop появился новый режим: генерация полигона для обрезки рамки в формате CSV+WKT. Вывод на stdout, так что можно сохранить в любой удобный файл из скрипта, после чего использовать как аргумент для -cutline у gdalwarp в какой-то более сложной команде. Вызова gdalwarp при этом не происходит.

Активируется режим опцией -g (от [g]enerate). Указывать выходной файл при этом не нужно - он будет проигнорирован.

Так же, теперь появилась возможность указывать файл с описанием проекции: -p srs_file. Сама проекция должна быть в формате WKT или PROJ.4. Эта опция перезаписывает определение проекции в текущем файле. Полезна для преобразования файлов с привязками в виде world-файлов. Более того, если проекция в файле пустая, а опция не указана то произведётся попытка прочитать её автоматически из файла с таким же именем, но с расширением .prj или .prf (какой первый попадётся). Так что популярные карты ГГЦ с такими привязками теперь можно конвертировать так же просто, как и с привязками Ozi Explorer.

Чуть раньше реализована функциональность по передаче дополнительных параметров gdalwarp. Для этого нужно завершить опции приложения двойным минусом , опции после него будут переданы gdalwarp как есть без изменений:

geocrop -f VRT -s 200k K-53-07.map K-53-07.vrt -- -overwrite

опция -overwrite будет передана gdalwarp. Помимо этого, теперь можно переопределить и сам исполняемый файл gdalwarp - опция -w GDALWARP.

Кроме того изменился формат опций, стало возможным указывать выходной формат (опция -f FMT, как следствие, образовались такие возможности: Быстро и ненавязчиво готовим карту для открытия в QMapShack) или только обрезать рамку, не делая кроп (опция -n).

// MinGW GCC 5 в Trusty

Сделал PPA, куда положил MinGW GCC 5: https://launchpad.net/~adrozdoff/+archive/ubuntu/mingw

Версия GCC на момент написания поста: 5.3.0. Сборка зависит от репозитория https://launchpad.net/~ubuntu-toolchain-r/+archive/ubuntu/test/+packages (если надумаете собирать сами).

Краткие характеристики сборки:

  • Модель потоков: только posix (требуется libwinpthreads), т.к. позволяет использовать все возможности C++11/C++14. Если будет спрос на win32, то нужно только добавить одну строчку и чуть подкорректировать альтернативы (т.е. сборка поддерживает, просто выключил win32).
  • Обработка исключений: sjlj для win32 и seh для win64
  • Сборка для Win32 и Win64

Добавление репозитория:

  sudo apt-add-repository ppa:adrozdoff/mingw

Установка:

  sudo apt-get install gcc-5-mingw-w64 g++-5-mingw-w64

Компилятор с суффиксом -5, что бы не конфликтовать с тем, что распространяется вместе с Ubuntu/Mint.

В этом же репозитории планирую выкладывать сборки библиотек.

// Android SDK/NDK в Linux Mint

Просто последовательность действий - на память (брать из PPA не хотелось). Как качать NDK, SDK и Android Studio я расписывать не буду. Распаковку всего этого добра произвёл в ~/Android. Имена директорий привёл к виду (или переименованием или созданием необходимых симлинков):

  • android-sdk
  • android-ndk
  • android-studio

По сути, этот рецепт подходит для любого дистрибутива, в большинстве случаев будет отличаться только первый пункт.

Итак…

Необходимое

  1. Ставим OpenJDK: sudo apt-get install openjdk-7-jdk libswt-cairo-gtk-3-jni libswt-cairo-gtk-3-jni ant
  2. В ~/.profile или ~/.bashrc_profile прописываем:
    export ANDROID_HOME=$HOME/Android/android-sdk
    export ANDROID_NDK=$HOME/Android/android-ndk
    # For compability
    export NDK_HOME=$ANDROID_NDK
    export ANDROID_SWT=/usr/share/java
    export PATH=$PATH:$ANDROID_HOME/tools:$ANDROID_HOME/platform-tools:$ANDROID_NDK:$HOME/Android/android-studio/bin
    export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:$ANDROID_HOME/tools/lib
  3. Переходим в ~/Android/android-studio/bin и выполняем:
    ln -s studio.sh android-studio
  4. Добавляем следующие параметры в studio.vmoptions и studio64.vmoptions (предварительно сделайте резервные копии, пригодятся при обновлениях):
    -Dswing.aatext=true
  5. На этом шаге можно перелогиниться, вызвать android и поставить платформы, утилиты, потом запустить Android Studio и сделать необходимые настройки.

Опциональное

Ярлыки в меню

FIXME относительные пути к иконкам не воспринимаются, поэтому иконки не отображаются, только текст.

  1. Создаём файл: ~/.local/share/applications/android-sdk.desktop со следующим содержимым:
    [Desktop Entry]
    Encoding=UTF-8
    Name=Android SDK
    Comment=Android Sofware Development Kit
    Exec=android
    Icon=~/Android/android-sdk/tools/apps/SdkController/res/drawable-xhdpi/ic_launcher.png
    Terminal=false
    Type=Application
    Categories=IDE;Development;

    Если иконка не будет отображаться, замените на полный путь.

  2. Извлекаем иконку Android Studio:
    unzip -o lib/resources.jar artwork/icon_AS_128.png

    Вызываем команду из корня android-studio

  3. Создаём файл: ~/.local/share/applications/android-studio.desktop:
    [Desktop Entry]
    Version=1.0
    Type=Application
    Name=Android Studio
    Exec=android-studio %f
    Icon=~/Android/android-studio/artwork/icon_AS_128.png
    Comment=Develop with pleasure!
    Categories=Development;IDE;
    Terminal=false
    StartupNotify=true
    StartupWMClass=jetbrains-android-studio
    MimeType=application/x-extension-iml;

Автодополнение BASH

Автодополнение для команд android, adb, emulator, fastboot и repo.

  1. Идём в ~/Android
  2. Забираем последнюю версию скрипта (предполагаю, что git уже установлен):
    git clone https://github.com/mbrubeck/android-completion.git
  3. Создаём файл ~/.bash_completion и помещаем в него:
    . $HOME/Android/android-completion/android
    . $HOME/Android/android-completion/repo
  4. Перелогиниваемся

// LyX в Linux Mint и русский

Что бы в LyX начали сходу работать русский нужно поставить пакеты: texlive-lang-cyrillic и cm-super. Точнее даже не так: набивать тексты вы сможете сразу, а вот генерировать PDF - только после установки пакетов.

// Firefox и быстрый поиск

Все - не все, но многие знают, что в Firefox, Google Chrome и, вроде, Опере можно в свойствах закладки указать т.н. ключевое слово (keyword), набрав которое в адресной строке браузера и нажав Ввод перейдёшь по ссылке, на которую указывает данная закладка.

Удобно? Кому как. Но! У этого функционала есть ещё одно одно применение.

Дело в том, что в самом адресе закладки можно указать подстановочную последовательность (плейсхолдер, placeholder, уж не знаю как более корректно перевести это слово на русский язык) %s. На это место будет подставлен весь текст который будет введён после ключевого слова.

На пальцах. Допустим, у нас есть закладка, у которой ключевое слово g, тогда, если в адресной строке введём:

g ябеда-корябеда солёный огурец

то вместо %s будет подставлено: «ябеда-корябеда солёный огурец»

Теперь чуете? Правильно! Мы можем вызывать какие-то URL с параметрами. Это общий случай, я же, в основном, использую это для поиска. К примеру, у меня такой набор (жирным выделены названия закладок):

Да, в самом Firefox можно ключевые слова задать для существующих поисковых систем (в Search bar), но вручную там нельзя добавить произвольную (задав только URL для поиска), только установкой соответствующего расширения, которого может не оказаться. Плюс метод работает во многих браузерах, так что импортировав закладки, получите и работающий поиск, к которому привыкли.

В luakit это сделано прямо и ровно через технологию Search Engine. Пример можно посмотреть прямо в коробке в файле globals.lua (или тут).

// ps2pdf и отрицательное смещение сверху

Если при преобразовании PS в PDF на выходе наблюдается отрицательное смещение (как бы часть листа срезана) сверху, то стоит попробовать явно задать формат страницы при преобразовании:

ps2pdf -sPAPERSIZE=a4 input.ps output.pdf

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

// Две утилиты для работы с картами: ozi2map и geocrop

На выходных готовил растровую карту для похода на Кодар, с последующей конвертацией оной в JNX.

Самые неинтересные и скучные моменты в этом деле была обрезка рамки. А кроме того, печаль, по причине того, что есть карты с привязками OZI, но нет нормального конвертера для них.

В результате, подумал и написал за выходные две программы: ozi2map и geocrop

ozi2map

Данная утилита более не актуальна. Версия GDAL (>=1.10), входящая во все популярные дистрибутивы, уже умеет сама обрабатывать такие MAP файлы.

Первая, как можно понять из названия, предназначена для конвертации карты с привязкой OZI (сама карта в JPEG или GIF или другом распространённом растровом формате, который поддерживает OZI, но не OZFX/OZFX2/OZFX3, для них преобразования можно сделать средствами самого gdal (в прошлых статьях писал про это)).

Для чтения точек привязки и параметров проекции используется функция из недр GDAL: GDALReadOziMapFile(…), что, в отличии от питоновского ozi2geotiff.py, даёт корректные параметры проекции. Далее, не стал особо заморачиваться и подсовывая нужные параметры gdal_translate/gdalwarp вызываю их через system().

Я вообще не стал лезть в разбор map файла, поэтому файла растра автоматически не определяется и его нужно указывать самому:

./ozi2map O-50-103.map O-50-103.jpg
./ozi2map O-50-103.map O-50-103.jpg O-50-103.tif

Если имя выходного файла не задано, имя будет сформировано из имени растра с заменой расширения на .tif.

Всё, пользоваться программой должно быть проще простого. Найти исходники (GPLv2) можно тут:
https://git.gitorious.org/h4tr3d-utils/ozi2map.git

Собирать просто:

make

Полученный бинарник можно запускать от куда угодно.

geocrop

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

Т.е. по сути, программе на вход нужен только масштаб листа (в виде 1M, 500k, 200k, 100k, 50k, 25k, 10k, 5k, 2k) и сам лист карты в формате, поддерживаемом GDAL с корректной привязкой.

Когда расчёты по привязке будут выполнены, вызывается gdalwarp через system(). Полигон для обрезки формируется в координатах листа (не в точках растра), для всех листов, кроме 1M, это 4х угольник (на будущее будет более качественно сделано, но и текущего результата хватит в 99.99% случаев).

Пользоваться программой не сложнее чем ozi2map:

./geocrop -s 100k O-50-103.tif O-50-103-crop.tif

Первым аргументом - стилизованное обозначение масштаба:

  • 1M - 1:1 000 000 (это масштаб используется, если мнемоника не распознана)
  • 500k - 1:500 000 («пятикилометровка»)
  • 200k - 1:200 000 («двухкилометровка»)
  • 100k - 1:100 000 («километровка»)
  • 50k - 1:50 000 («полукилометровка» или «пятисотметровка»)
  • 25k - 1:25 000 («двухсотпятидесятиметровка»)
  • 10k - 1:10 000 («стометровка», пока не реализовано)
  • 5k - 1:5000 («пятидесятиметровка», пока не реализовано)
  • 2k - 2:2000 («двадцатиметровка», пока не реализовано)

Если этот параметр пропущен, используется масштаб 100k.

Вторым аргрументом - входной файл, поддерживаемый GDAL.

Третий аргумент - выходной, кропнутый файл. По умолчанию - GeoTiff, но можно переопределить опцией «-f FORMAT», где FORMAT - любой поддерживаемый GDAL.

Если хотите обрезанные карты потом склеивать при помощи gdal_merge.py, и получить вразумительные результат, входной файл должен быть в цветовой палитре RGB, узнать это можно при помощи утилиты gdalinfo, если в выводе есть такое:

Band 1 Block=4096x1 Type=Byte, ColorInterp=Red
Band 2 Block=4096x1 Type=Byte, ColorInterp=Green
Band 3 Block=4096x1 Type=Byte, ColorInterp=Blue

значит всё хорошо, если нет (выводится палитра из 255 цветов), то палитра индексированная, нужно преобразовать в RGB при помощи утилиты pct2rgb.py из комплекта GDAL.

Собирать просто:

mkdir build
cd build
cmake ..
make

Если на стадии cmake будут какие-то проблемы, стоит поставить dev-пакеты для GDAL и PROJ.4

Исходники можно взять тут (GPLv2):
https://github.com/h4tr3d/geocrop

// luakit: проблема со скролингом по PgUp/PgDown

Проблема странная, проявляется не сразу: вроде при запуске всё отлично работает, потом бац, перестаёт, при этом выводится сообщение слудющего содержания:

Error: in bind call: /home/user/.config/luakit/webview.lua:341: attempt to perform arithmetic on local 'p' (a nil value)

Решение проблемы нашёл тут: https://github.com/mason-larobina/luakit/issues/68, нормальный рабочий вариант получается этот: https://github.com/mason-larobina/luakit/issues/68#issuecomment-5528890

// Однооконный Dia

Достаточно запустить:

dia --integrated

теперь вполне можно пользоваться.

Ну и чуть ярости: ну какого чёрта не вынести это в настройки!?

// Ищем замену OziExplorer на Linux

Решил таки переопубликовать свою статью в OpenSource (http://osa.samag.ru/info/OpenSource068.zip) и у себя в блоге. В журнале статья называется: «QLandKarte GT как замена OziExplorer в GNU/Linux», здесь же публикую под оригинальным.

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

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

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

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

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

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

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

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

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

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

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

sdict.sh
#!/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 на горячую клавишу, когда надо, выделяю слово и жму её - смотрю перевод во всплывающем окошке.

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

// Клавитурные сокращения в vimdiff

ctrl+w ctrl+w Переключиться на другое окно.
ctrl+w Up/Down/Left/Right Переключиться на другое окно.
do Получить изменения из другого окна в текущее.
dp Вставить изменения из текущего окна в другое.
]c Перейти к следующему изменению.
[c Перейти к предыдущему изменению.
:diffupdate diff update
:syntax off выключить подсветку синтаксиса
zo раскрыть свернутый кусок текста
zc свернуть кусок текста

// Amp, a layer3 player

Накатило, решил найти исходники этой программки. Что делает? Да просто берёт и играет mp3 файл. Чем знаменита? :) А тем, что это мой первый проигрыватель mp3 на Linux, который попался мне случайно на купленном диске во Владивостоке, во времена, когда у меня не было интернета и в своём городе-посёлке я был единственным пингвиноводом.

Source1 (на этом сайте) | Source2 | Где найдено

Никаких внешних зависимостей, исходники на чистом Си, в распакованном виде - 290Кб.

PS при сборке на современных системах нужно будет применить такой патч:

guicontrol.c.diff
--- /home/hatred/download/tmp/mp3/amp-0.7.6/guicontrol.c	1997-08-23 22:30:51.000000000 +1100
+++ guicontrol.c	2012-01-17 09:57:49.518208850 +1100
@@ -375,7 +375,8 @@
 	break;	
       case GETHDR_SYN: warn("oops, we're out of sync.\n");
 	break;
-      default: 
+      default:
+        ;
       }
       break;
     }

по сути, после default:, поставить точку с запятой :-)

// Qt Creator & doxygen

Сегодня пролетело в рассылке:

Hi,

Qt Creator master has recently got a feature, which has been requested a
few times, for Doxygen blocks generation. If you type /** or /*! and
press enter/return before a declaration, you'll get something like:
/*!
 *
 * \param data
 * \param options
 * \return
 */
QString generate(const Data &data, const Options &options);


You can also opt whether or not you want an additional \brief command
and leading asterisks for comment continuation (when breaking lines).
The options are in Text Editor→Completion→Documentation Comments.

Notice that the style is identified from the comment beginning. If you
start it with /*! then the Qt style is used. Otherwise, the Java style
with the @ prefix for the commands is picked.

Cheers,
Leandro

Проверил - работает, удобно :)

// Новый GTK+ и падение Opera

После очередного обновления, заметил, что Опера перестала стартовать. При запуске из терминала, вываливает следующее:

$ opera

(opera:13093): Gtk-CRITICAL **: IA__gtk_widget_unrealize: assertion `GTK_IS_WIDGET (widget)' failed

(opera:13093): Gtk-CRITICAL **: IA__gtk_widget_is_toplevel: assertion `GTK_IS_WIDGET (widget)' failed
opera [crash logging]: CRASH!!
/usr/lib/opera/opera got signal SIGSEGV at address B6B26E77

Log was created here:
/var/tmp/crash20111110210615.txt
Убито

Для столкнувшихся с этой же проблемой в ArchLinux:

// QLandkarteGT: Экспорт всей карты в растр, а не только видимой области

В QLandkarteGT есть удобная вещь - экспорт видимой области карты со всеми отображаемыми точками, треками, измерениями и т.п. в растровый (PNG) файл.

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

Патч подкатом.

// Поломанная привязка карт в QLandkarteGT

Сегодня столкнулся с тем, что привязывая карту в QLandkarteGT, получаю такую ошибку:

/usr/bin/gdal_translate -a_srs +proj=merc +a=6378245.0000 +b=6356863.0188 +towgs84=24,-123,-94,-0.02,0.25,0.13,1.1,0 +units=m  +no_defs -gcp 108 182 inf inf -gcp 3310 189 inf inf -gcp 3308 3126 inf inf -gcp 93 3119 inf inf -gcp 1704 1657 inf inf /home/hatred/maps/1/src/K-53-26-view-raw.tiff /tmp/qt_temp.B12852
Input file size is 3402, 3428
0...10...20...30...40...50...60...70...80...90...100 - done.

/usr/bin/gdalwarp -order 1 -r cubic -dstnodata "255" /tmp/qt_temp.B12852 /tmp/qt_temp.u12852

ERROR 1: Attempt to create -2147483648x-2147483648 dataset is illegal,sizes must be larger than zero.
Creating output file that is -2147483648P x -2147483648L.

Неудачно!

Сначала было подумал, что поломано в SVN версии, однако, в релизной 1.2.4 ситуация точно такая же.

Сразу и сходу смутили параметры inf в опции -gcp. Так что решил поглядеть в коде, благо собираю из SVN и он у меня всегда под рукой.

Немного времени, расстановка логов, анализ привели к тому что обнаружилось двойное преобразование координат в функции

bool GPS_Math_Str_To_LongLat(const QString& str, float& lon, float& lat, const QString& srcproj, const QString& tarproj)

в файле GeoMath.cpp

Первое преобразование было в блоке кода:

if(GPS_Math_Str_To_Deg(str, lon, lat,true))
 {
   if(pjTar)
   {
       u = lon * DEG_TO_RAD;
       v = lat * DEG_TO_RAD;
        pj_transform(pjSrc,pjTar,1,0,&u,&v,0);
   }   
 }
 else

а второе преобразование в следующем блоке кода:

if(pjTar && pjSrc)
 {
   pj_transform(pjSrc,pjTar,1,0,&u,&v,0);
 }

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

Сменил первый блок на такой:

if(GPS_Math_Str_To_Deg(str, lon, lat,true))
 {
    u = lon * DEG_TO_RAD;
    v = lat * DEG_TO_RAD;
 }
 else

пересобрал и всё заработало отлично и замечательно.

UPD: а теперь всё то же самое, но в виде патча:

qlandkartegt-map-referencing-fix.diff
Index: src/GeoMath.cpp
===================================================================
--- src/GeoMath.cpp	(revision 3010)
+++ src/GeoMath.cpp	(working copy)
@@ -392,12 +392,8 @@
 
     if(GPS_Math_Str_To_Deg(str, lon, lat,true))
     {
-        if(pjTar)
-        {
-            u = lon * DEG_TO_RAD;
-            v = lat * DEG_TO_RAD;
-            pj_transform(pjSrc,pjTar,1,0,&u,&v,0);
-        }
+        u = lon * DEG_TO_RAD;
+        v = lat * DEG_TO_RAD;
     }
     else
     {

PS автору письмо отправлено

// Готовим растровую карту для навигатора Garmin GPSMap 62s

UPD 2013-11-16: обновил список программ, добавил информацию об автоматической обрезке рамок, добавил информацию о создании многослойного JNX. Убрал текст помеченный как удалённый. За остальными подробностями - в историю изменения страницы. Вики всё же :)

Задача: сделать растровую карту для навигатора Garmin GPSMap 62s.

Инструменты:

  • GDAL 1.8.0. С версии 1.10.0 научился конвертировать привязки OZI Explorer в виде .map + растр (.png, .gif и т.п.) в geotiff, рекоменду обновляться.
  • map2jnx 1.7.8. В последних версиях QLandkarteGT идёт в комплекте + уже с моими патчами для задания различного scale-factor для разных слоёв. Скачёк версии с 0.2.4 до 1.7 (или даже 1.6) случился как раз из-за включения в состав QLandkarteGT.
    • QLandkarteGT задепрекейчена в пользу новой программы от автора - QMapShack
    • Соответственно map2jnx теперь можно разжиться тут
  • QLandKarteGT или QMapShack - нужны для просмотра.
  • NEW: geocrop
  • NEW: ozi2map, опционально, если у вас GDAL младше 1.10.x и есть куча растров привязанных в OZI Explorer (.gif, .png, .jpg и т.д.)

Исходные карты в формате OZFX3 (Ozi Explorer) с готовой привязкой. Если нет привязанных карт, можно почитать тут как это сделать самому. Теперь можно брать любые озиковские привязки (кроме OZFX2 и новых шифрованных OZFX3), но только если у вас версия gdal больше 1.10.0, иначе можно воспользоваться утилитой ozi2map.

// OZFX в GeoTIFF

NOTE: Данный способ конвертации подходит только для карт старого, некриптованного формата OZFX3 и не подходит для карт формата OZFX, OZFX2 и для нового зашифрованного OZFX3.

Оказывается сию процедуру в Linux можно сделать при помощи утилиты gdal_translate из библиотеки GDAL:

gdal_translate -of GTiff 200k--n57-01_ozf.map 200k--n57-01.tiff

Получается нормальный валидный tiff. Проблема, что геоданные о привязке не всегда перевариваются другими программами, хотя и сохраняются, вот, к примеру, фрагмент вывода gdalinfo:

Coordinate System is `'
GCP Projection = 
PROJCS["unnamed",
    GEOGCS["Pulkovo 1942",
        DATUM["Pulkovo_1942",
            SPHEROID["Krassowsky 1940",6378245,298.2999999999998,
                AUTHORITY["EPSG","7024"]],
            AUTHORITY["EPSG","6284"]],
        PRIMEM["Greenwich",0],
        UNIT["degree",0.0174532925199433],
        AUTHORITY["EPSG","4284"]],
    PROJECTION["Transverse_Mercator"],
    PARAMETER["latitude_of_origin",0],
    PARAMETER["central_meridian",159],
    PARAMETER["scale_factor",1],
    PARAMETER["false_easting",500000],
    PARAMETER["false_northing",0],
    UNIT["metre",1,
        AUTHORITY["EPSG","9001"]]]
GCP[  0]: Id=1, Info=
          (110,92) -> (312850.595383564,6212735.20674275,0)
GCP[  1]: Id=2, Info=
          (1325,93) -> (344034.004166507,6211493.42884751,0)
GCP[  2]: Id=3, Info=
          (2544,89) -> (375221.866305868,6210477.54231118,0)
GCP[  3]: Id=4, Info=
          (100,1538) -> (311242.069242769,6175640.4309,0)
GCP[  4]: Id=5, Info=
          (1326,1542) -> (342693.733518233,6174392.90643577,0)
GCP[  5]: Id=6, Info=
          (2557,1535) -> (374149.759678358,6173372.32291538,0)
GCP[  6]: Id=7, Info=
          (91,2985) -> (309639.985652898,6138547.1302834,0)
GCP[  7]: Id=8, Info=
          (1328,2989) -> (341358.837088592,6137294.02823664,0)
GCP[  8]: Id=9, Info=
          (2568,2983) -> (373081.95597641,6136268.88603608,0)

Задел на будущие думы.

UPDATE 2013-11-18: в статье Готовим растровую карту для навигатора Garmin GPSMap 62s рассматривается вариант конвертации с исправлением ошибки в формате геоданных.

// Image Ruler 0.98.1

Выпустил версию 0.98.1 программы Image Ruler для измерения на растровых изображениях.

Изменений минимум:

  • Добавлен вывод суммирующей длинны при измерении ломанной линией (столкнулся с расчётом маршрута по карте)
  • В win32 сборку добавлены плагины графических форматов: теперь из коробки открываются jpeg/gif и иже с ними, иначе работал только png.

// MountTray

Написал небольшую программу для подключения, отключения сменных дисков в Linux, использует udisks для монтирования (в планах сделать бакенд и для простых mount/unmount через sudo, класс для использования которого уже написан, для полных минималистов), udev для детекта новых дисков и изъятия существующих (опять таки, готов и бакед для использования inotify, можно будет альтернативно прикрутить его, кстати, а на други unix системах как с inotify?) и в минимальном плане DBus для возможности получать сообщения: а вдруг кто-то там снаружи примонтировал/отмонтировал диск.

Пожелания - мне на мыло

Проект разместил на Gitorius: http://gitorious.org/h4tr3d-utils/pages/MountTray
Новый адрес: https://github.com/h4tr3d/mount-tray, проект не разрабатывается уже несколько лет.

// FlashBlock в Opera

Полезная ссылка: http://my.opera.com/Lex1/blog/flashblock-for-opera-9/

даны различные рецепты, в том числе очень удобный для Opera 10.5+: просто включить опцию EnableOnDemandPlugin, для чего нужно открыть настройки: opera:config#UserPrefs|EnableOnDemandPlugin, опция автоматически добавится, и можно её включить. Да, это будет работать для любых плагинов.

// OpenSource #068

А в нем и моя очередная статья «QLandKarte GT как замена OziExplorer в GNU/Linux» (название откорректировано редактором, но не суть). Рассматривается вопрос использования данных, подготовленных для использования в OziExplorer (или созданных ими), коих на просторах интернетов премножество, в среде Linux, на примере QLandKarte GT.

Скачать: http://osa.samag.ru/get/OpenSource068.zip

// Psi+ - редактирование контактов в ростере

Столкнулся с проблемой - никоим образом не получалось отредактировать контакт в ростере, хотя горячая клавиша была назначена. В конференции psi-dev@conference.jabber.ru подсказали, посмотреть, а не залочен-ли ростер, оказалось - залочен, исправлять:

  • Настройки → Дополнительно
  • далее находим опцию: options.ui.contactlist.lockdown-roster и ставим в true

Всё!

// DigiKam 1.3.0

Несколько версий назад поломали они там поворот JPEG'ов, хотя как поломали, переход на новую версию libjpeg был, вот малость API и несогласовалось. И вот, матерясь на версию 1.2 во вторник, подготавливая фото к выкладыванию, сегодня накатываю обновления системы и вижу версию 1.3.0, первым делом опробовал - РАБОТАЕТ :) Сейчас ещё нужно покумекать, как там дела обстоят с PicasaWeb и логинами отличными от вида ИМЯ@gmail.com (ведь мыло то может быть любое).

UPD: Да и экспорт в PicasaWeb с логинами отличными от ИМЯ@gmail.com тоже заработал, ну чтож, вкусно :)

// epssplit & jpeg2ps

Про эти утилиты писал года три назад в статье: Резка большеформатных изображений на листы формата А4 для последующего склеивания

Сейчас дошли руки приготовить пакеты для AUR: epssplit, jpeg2ps, так что, в ArchLinux с установкой стало проще :)

По поводу преобразование растра в PS/EPS можно почитать в статье Евгения Балдина в «Linux Format»: LaTeX. Часть 4: Графика

// Вышел OpenSource #057

А в нем и первая часть моей статьи по основам схемотехники в Linux: «Схемотехника в Linux с помощью gEDA. Часть 1: gschem»

Скачать выпуск: http://osa.samag.ru/get/OpenSource057.zip

// Пара исправлений для FBReader

С давних пор пользуюсь для чтения электронных книг замечательной программкой FBReader. Особо мне нравилось то, что он мог на основе параметров пользователя оформлять книги, которые находятся в простом TXT файле.

Например, люди, которые делают OCR могут использовать следующие способы для выделения абзацев:

  • длинные строки, новый абзац с новой строки - такое правда встречается редко
  • в начале обзаца строка имеет отступ а 1-2-3 и т.д. пробелов или табуляций
  • абзацы разделены пустой строкой

Второй и третий случай - наиболее частые, а сам текст обычно выравнен на 80 символов, что бы можно было читать в DOS-терминале

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

Второй вариант, разделение глав, тут обычный случай: по окончании главы 2 и более пустые строки, после заголовка одна пустая строка - самый частый случай. Программа на основе таких данных может строить оглавление и осуществлять быстрый переход, что является достаточно удобным функционалом.

Конечно, данные критерии не покрывают абсолютно все случаи, но большинство - это точно.

Теперь о проблеме: в какой-то момент поломалось форматирование TXT файлов, с разделением абзацев по отступу первой строки, проявлялось так:
Отступ имела первая строка азбаца, после чего азцаз закрывался и вторая строка абзаца так же печаталась с новой строки с отступом, и это очень сильно резало глаза.

Сегодня дошли руки покопаться в исходниках, благодаря ну очень внятной структуре, разобраться много времени не заняло, да и исправления можно сказать косметические, вот патч:

--- ./fbreader/src/formats/txt/TxtBookReader.cpp.orig	2010-01-26 01:33:14.083167173 +1000
+++ ./fbreader/src/formats/txt/TxtBookReader.cpp	2010-01-26 01:38:19.350635588 +1000
@@ -27,7 +27,8 @@
 
 void TxtBookReader::internalEndParagraph() {
 	if (!myLastLineIsEmpty) {
-		myLineFeedCounter = 0;
+		myLineFeedCounter = -1; /* Fixed by Hatred: zero value was break LINE INDENT formater -
+		                           second line print with indent like new paragraf */
 	}
 	myLastLineIsEmpty = true;
 	endParagraph();
@@ -76,7 +77,9 @@
 		((myFormat.breakType() & PlainTextFormat::BREAK_PARAGRAPH_AT_EMPTY_LINE) && (myLineFeedCounter > 0));
 
 	if (myFormat.createContentsTable()) {
-		if (!myInsideContentsParagraph && (myLineFeedCounter == myFormat.emptyLinesBeforeNewSection() + 1)) {
+	    /* Fixed by Hatred: remove '+ 1' for emptyLinesBeforeNewSection, it looks like very strange
+	       when we should point count of empty string decrised by 1 in settings dialog */
+		if (!myInsideContentsParagraph && (myLineFeedCounter == myFormat.emptyLinesBeforeNewSection())) {
 			myInsideContentsParagraph = true;
 			internalEndParagraph();
 			insertEndOfSectionParagraph();

Или альтернативная ссылка: http://codepad.org/GO5GIN7Y

Сейчас попробуем запостить разработчикам.

UPD: собственно: http://groups.google.com/group/fbreader/browse_thread/thread/a0f77eb79add8571?hl=en

// Немного про распознавание текста (OCR) в Linux

Наверное самое слабое место для Linux систем. Хотя проектов достаточно много, например gocr, tesseract или ocrad, но многие из них до сих пор не вышли из зачаточного состояния, требуют для более-менее удовлетворительной работы длительное обучение, и даже после оного достаточно отвратительно распознают текст.

Небольшой перелом в положительном направлении стало открытие исходных кодов программы распознавания текстов cuneiform, но проект развивается достаточно медленно, и пока плохо распознает табличные тексты.

Но, несмотря на это, в настоящее время - это лучшая программа для распознавания под Linux.

На данный момент существует несколько способов её использования:

  1. из командной строки, доступна из коробки
  2. программа cuneiform-qt, довольно убога на данный момент
  3. программа yagf - достаточно удобна, хотя ещё и не достаточно функциональна, может работать сразу со сканером при помощи xsane
  4. веб интерфейс - CuneWebForm, ссылки тут:

Куниформ работает и потихоньку эту свою работу делает, надеюсь будет развитие.

// Текстовый редактор Medit

Про этот редактор я уже упоминал. Мне кажется у меня это будет не последний рассказ про расширения к редактору, поэтому сделаю краткое ревью ему самому, дабы потом можно было ссылаться.

Требования

Как-то я озадачился выбором текстового редактора, который бы было одинаково комфортно использовать как для редактирования кода и разработки, так и для быстрого открытия и редактирования обычных текстов. При этом что бы он был простым для простых вещей, и расширяемым для сложных. Таком образом выработался набор требований:

  1. т.к. нужно редактировать код, нужна подсветка синтаксиса, должна быть возможность создавать свои схемы подсветки
  2. автоотступ, как при вводе кода, так и при обычном текстовом редактировании
  3. отображение номеров строк, мне привычно - отдельной колонкой
  4. многооконный интерфейс образованный вкладками
  5. отступ блока кода и обратный отступ
  6. фолдинг - сокрытие блока кода
  7. поддержка кодировки текста
  8. поддержка поля вывода для внешних команд
  9. собственно вызов внешних команд
  10. боковые панели для быстрой навигации по дереву каталогов и открытия файлов (удобно работать в проекте)
  11. расширяемость - простые средства добавления нового функционала, без написания кода.

Знакомимся - MEdit

Повторю то, что кратко сказал в первом посте про данный редактор:

MEdit23) замечательный редактор, написанный на Gtk, пока, за малым исключением, удовлетворяет все мои запросы. Корнями уходит графическому интерфейсу GGAP24) для GAP25).

Теперь же давайте рассмотрим его соответствие моим требованиям к хорошему текстовому редактору:

  1. подстветка синтаксиса: есть, описание в xml файлах, можно делать свои схемы
  2. автоотступ: есть
  3. отображение номеров строк: есть
  4. многооконный интерфейс образованный вкладками: есть
  5. отступ блока кода и обратный отступ: есть, в конфигурации по-умолчанию клавишами Tab и Shift+Tab соответственно
  6. фолдинг: нет, но как оказалось, в тех редакторах, что он есть, мною не использовался.
  7. поддержка кодировки текста: есть, но иногда после переключения нужно делать File → Reopen With Codepage…
  8. поддержка поля вывода для внешних команд: есть + поддержка фильтров, но это подробнее позже
  9. собственно вызов внешних команд: есть, через механизм Инструментов (или Тулов, от английского Tools)
  10. боковые панели для быстрой навигации по дереву каталогов и открытия файлов: есть
  11. расширяемость: есть, через механизм плагинов (C или Python), через механизм Инструментов, которых реализован ооооочень удобно.

Про функции редактирования особенно и рассказывать не нужно, расскажу про возможность добавлять функционал посредством инструментов, о которых вы узнали из одной из прошлых статей.

Инструменты

Могут быть доступны через меню Инструменты или через контекстное меню мыши. Настраиваются через Изменить → Параметры далее нужно переходить в раздел Инструменты, там находим две вкладки, для создания инструмента в контекстном меню и в главном меню.

Сами инструменты могут быть описанием программы на встроенном Python, LUA или быть командой оболочки (в большинстве случаев - BASH).

Общие параметры для всех языков, это:

  • Включен - определяет включен инструмент или нет
  • Файлы - задает, в случае открытия какого файла будет доступен данный инструмент (например в зависимости от того файл какого языка мы редактируем). Тут могут быть заданы маски файлов, выражение типа: langs: c++, c, pascal или регулярное выражение типа: regex:\.[ch]$. Пустое значение подразумевает что доступно при редактировании всех документов. На основе этого я сделал свой тул для валидации кода php.
  • Параметры - определяют при каких условиях инструмент будет отрабатывать, представляет собой разделенный запятыми список:
    • need-doc - документ должен быть открыт
    • need-file - инструмент не будет работать для новых, ещё не сохраненных на диск файлов
    • need-save - документ будет сохранен перед выполнением команды
    • need-save-all - все открытые документы будут сохранены перед выполнением команды

Для встроенных языков параметры этим и ограничиваются, все остальное осуществляется программно (типа куда производить вывод сообщений).

Для Типа команды «Команда оболочки» доступны так же следующие параметры:

  • Ввод - что будет посылаться на стандартный ввод команды, скрипт должен уметь принимать стандартный ввод
  • Вывод - куда будет посылаться вывод команд:
    • Ничего - никуда, редактор будет недоступен пока команда не завершится
    • Ничего, асинхронно - никуда, можно сразу продолжать работу с редактором
    • Панель вывода - собственно текст будет выведен в панель вывода, к этому выводу можно определить фильтр, о чем скажу ниже
    • Последние пункты соответственно вставят результаты или в текущую позицию в документе или в новый документ.
  • Фильтр - как будет восприниматься текст в панели вывода. Например, если это сообщения компилятора, можно выделить строки содержащие сообщения об ошибках компиляции, подсветить их красным и сделать возможность перехода на строку с ошибкой по клику мыши. Определено несколько стандартных фильтров:
    • Default - ничего не подствечивает, если строка вывода начинается с имя_файла:номер_строки то по клику по такой строке будет произведена попытка открыть файл и перейти на указанную строку.
    • Остальные специфичны для конкретных применений. Посмотреть их описания можно в /usr/share/moo/filters.xml

Описания языка LUA и Python можно посмотреть в справочном руководстве к редактору, в формате HTML, если он у вас установлен по тем же путям, то можно открыть по этой ссылке: file:///usr/share/doc/medit/help/sect-user-tools.html

Для SHELL скриптов, как самых простых в реализации, рассмотрим переменные окружения к которым можно обращаться:

  • $DOC - имя документа без пути к нему
  • $DOC_DIR - полный путь к документу
  • $DOC_BASE - имя документа без расширения (последнего элемента отделенного точкой)
  • $DOC_EXT - расширение документа
  • $LINE - номер строки в которой стоит курсор
  • $DATA_DIR - директория в которой хранятся настройки medit, бывает удобно, что бы некоторые сценарии сохраняли или читали от туда свои настройки.

Как реализовывать конкретный функционал, уже удел вашей фантазии.

Да! На каждый созданный документ, можно после в Изменить → Настройка горячих клавиш, можно настроить свою клавишу. Оду и ту же клавишу можно назначать на разные инструменты, если они выбираются для разных файлов. Если будет отображаться одновременно два инструмента с одинаковой горячей клавишей, будет выполнен тот, который идет раньше.

Остальное

Тут кратко рассмотрю основные интересности о medit:

  • описание синтаксиса можно сохранять в пользовательскую директорию: ~/.local/share/medit/language-specs
  • свои фильтры можно добавлять в файл ~/.local/share/medit/filters.xml причем нужно писать только сам фильтр, например:
    <filter id="php-syntax-check" name="php-syntax-check">
      <match what="stderr" pattern=".*Parse error:.* in (?P&lt;file&gt;[^:]+) on line (?P&lt;line&gt;\d+)" style="output-error" /
      <match what="stdout" pattern=".*Parse error:.* in (?P&lt;file&gt;[^:]+) on line (?P&lt;line&gt;\d+)" style="output-error" /
    </filter>

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

Собственно пока всё, будет дополняться.

// Как запустить...

Комп загружается, и тут встает задача - на разных этапах загрузки, запускать какие-то свои пользовательские программы. Далее бегло попытаюсь посмотреть, как это работает у меня.

Начальная загрузка

Тут относительно просто, и уже все рассмотрено в интернетах, но пару слов скажу.

После того как ядро загрузилось, оно передает (в общем случае) управление пользовательскому процессу init (обычно /sbin/init), который дальше запускает необходимые скрипты, соотвутствующие разным уровням запуска (знаменитые run-levels26)). Какие скрипты будут запускаться, определяется в файле /etc/inittab, там же определяется какой run-level будет использован для запуска, по умолчанию (его можно передать через команду загрузки ядра), в классической схеме, это - 3. В модных дистрибутивах, это - 5.

Hint: man inittab

Скрипты запуска, указанные в конфиге init, обладают своей логикой, в зависимости от дистрибутива, в большинстве своём, реализуют схему загрузки в стиле SysV (Mandriva (ex. Mandrake), Fedora (ex. RedHat), AltLinux, ASPLinux и им подобные) или BSD-like (типа Slackware, ещё примеров не приведу). Часто схему трудно определить, например в моём любимом ArchLinux: вроде просто набор скриптов в /etc/rc.d, но управляются порядком запуска удобно через /etc/rc.conf.

Обычно скрипты, запускаемые лежат в /etc/rc.d или /etc/init.d, как их запускать в различных ранлевелах, рассказывать не моя задача, хочу сказать, что так или иначе, всегда есть специальный скрипт с именем /etc/rc.local, или /etc/rc.d/local, или /etc/init.d/local или различные вариации на эту тему (интересно для своего дистрибутива - поищите в http://google.com/linux). Этот скрипт нужен, что бы пользователь прописал туда свои команды, которые нужно выполнить при загрузке. В некоторых системах существует скприт rc.local.shutdown, который выполняется при выключении или перезагрузке, поищите его у себя.

Справедливости ради, стоит отметить, что схемой init/SysV/BSD схемы загрузки не ограничиваются, у меня на сервере, допустим, дополнительно используется daemontools для управления автоматическим подключением по pppoe27). Данный механизм относится к асинхронной загрузке + перезапуск сервиса в случае его краха. Кроме того, существуют варианты загрузки с зависимостями (в ArchLinux существуют только базовые средства для определения зависимостей), когда запускаемый процесс определяет, что ему нужно для работы ещё какие-то процессы и автоматически пытается их загрузить. В общем, тут есть что почитать для общего развития, для начала - про свой дистрибутив.

Подытоживая: при начальной загрузке в ArchLinux, пользовательские команды можно прописать в файл /etc/rc.local, команды, выполняемые при выключении/перезагрузки можно прописать в /etc/rc.local.shutdown. Обратите внимание: это файлы можно править только от root'а, и команды из них выполняются только от пользователя root, соответственно, если нужно понизить привилегии, используйте команды:

su - <USER> <COMMAND>

или

sudo -u <USER> <COMMAND>

Вход в систему

Я не буду рассматривать вариант непосредственного запуска в уровень 5 - запуск графической системы. Если случаются какие проблемы, легче их поглядеть для начала в консоли. Но это моя философия.

Итак, вы загрузились, у вас на экране приглашение ввести логин и пароль. Задумываемся, а как сделать так, что бы команды выполнялись после ввода логина и пароля…

Тут немного отвлечемся.

У каждого пользователя или через /etc/passwd или через ldap или ещё какую пень-колоду но задана командная оболочка, в народе - шел28), после успешной проверки имени и пароля, собственно и запускается для пользователя эта его оболочка. В качестве её можно, впринципе, прописать что угодно, есть даже такие команды замечательные: /bin/false или /bin/true, которые можно прописать, и пользователь никогда не войдет в систему (например, ему доступна только почта, удаленно, зачем ему давать локальный файловый доступ?) или rssh - оболочка для ограниченного доступа по ssh, если хотим, что бы пользователь мог заливать себе файлы, но не мог зайти в командный режим (понятно, ога, мне самому не поятно :-D)

В общем, при запуске, оболочка считывает настройки и выполняет команды, например bash:

  • выполняет команды из /etc/profile - общесистемный
  • из /etc/profile цепляется файл /etc/profile.bash - для конкретной оболочки
  • далее цепляются скрипты из /etc/profile.d/*.sh
  • после выполняются файлы в домашней директории пользователя:
    • ~/.bash_profile
    • ~/.bash_login (если не обнаружен предыдущий)
    • ~/.profile (если не обнаружен предыдущий)
    • ~/.bashrc (всегда)

Вышеперечисленные файлы, кроме .bashrc, выполняются только когда оболочка bash запускается как login-shell (с параметром -l), т.е. или сразу после ввода логина и пароля, или когда принудительно запущена как 'bash -l'

.bashrc выполняется каждый раз, когда запускается копия шела, а это происходит, например, когда запускается терминал (xterm, termit, konsole, gnome-terminal и пр.). Удобно сюда запихать вызов команд fortune и celebrat или cowsay наблюдать забавные фортунки и нотификации:

cowsay `date` `uname -a`
echo
celebrat
echo
fortune ru
echo

вот что имеем в итоге:

 ______________________________________ 
/ Fri Oct 30 10:23:42 VLAT 2009 Linux  \
| gaz_eeepc 2.6.31-ARCH #1 SMP PREEMPT |
| Fri Oct 23 11:12:58 CEST 2009 i686   |
| Intel(R) Atom(TM) CPU N270 @ 1.60GHz |
\ GenuineIntel GNU/Linux               /
 -------------------------------------- 
        \   ^__^
         \  (oo)\_______
            (__)\       )\/\
                ||----w |
                ||     ||

Meeting at the LUG tomorrow.
День военной разведки РФ six days from now.

Рyкописи, может быть, и не горят. Зато диски С отлично форматирyются.

Когда login-shell закрывается (набрали exit или logout) выполняются команды из файла ~/.bash_logout

Загружаемся в X-Window

Теперь дошла очередь до загрузки иксов.

И вновь нам нужно что-то как-то запустить. Я опишу свой случай, когда используется такая связка: staybox + openbox.

Для начала базовый функционал, который предоставляет сами иксы:

  1. прописывать системные команды в /etc/X11/xinit/xinitrc
  2. создавать скрипты в /etc/X11/xinit/xinitrc.d
  3. свои персональные команды в ~/.xinitrc

Первые два игнорируются, когда в домашней директории есть файлик ~/.xinitrc, так что, если вы рулите иксами через него, подцепляйте системные из /etc/X11/xinit/xinitrc.d:

source /etc/X11/xinit/xinitrc.d/*

Если команда не отцепляется от терминала, то обязательно ставьте & в конце команды, некоторые команды можно запускать отложенно при помощи такого фокуса:

(sleep 5; command ) &

В конце файла ~/.xinitrc всегда должна стоять команда

exec <ваш оконный менеджер или DE>

без всяких & в конце.

Пример моего файла, некоторые команды закоментированы (исторически сложилось :))

#!/bin/sh
 
#
# ~/.xinitrc
#
# Executed by startx (run your window manager from here)
#
 
# http://www.linux-archive.org/debian-kde/20524-fish-ssh-kioslave-doesnt-work.html
export KDE_FORK_SLAVES=true
 
xhost +127.0.0.1
xhost +localhost
#kdeinit &
#gnome-settings-daemon &
 
#asusosd &
#noteo &
 
xscreensaver -nosplash &
xrdb ~/.Xdefaults
 
#gkrellm &
#osmo &
#xfce4-power-manager
xbindkeys
#wicd-client
#icewmtray &
 
(sleep 5; sbxkb) &
 
#numlockx
#blueman-applet &
 
# regenerate menu
#mmaker -f -t xfterm icewm &
 
#nvidia-settings -a InitialPixmapPlacement=2
 
source /etc/X11/xinit/xinitrc.d/*
#gnome-keyring-daemon -d
 
exec ck-launch-session staybox-session
#exec openbox-session
#icewm-session
# exec icewm
#exec startkde
# exec blackbox
# exec fluxbox
#exec startxfce4
#exec afterstep
#exec xterm
 
 
##################################################################
# For LXDE only
##################################################################
 
# Корректор клавиатурного ввода, индикатор раскладки
#gxneur &
 
# Мыльный нотификатор
#mail-notification &
#gnubiff --systemtray --nogui &
 
#exec startlxde
#exec xterm
 
#exec /usr/share/antico/antico

Всякие менеджеры сессий, которые являются неотъемлемой частью различных DE: KDE, Gnome, XFCE, LXDE и т.п. или используемый мною Staybox для собственного окружения, так же читают .desktop файлы из директорий:

  1. системные, общие для всех пользователей: /etc/xdg/autostart/
  2. пользовательские: ~/.config/autostart/

Кроме того, у Staybox есть файл ~/.config/staybox/autostart в который можно в специальной форме прописывать команды, так если перед именем команды ставить @, то менеджер будет следить за ним, и, если он рухнет - перезапускать.

У меня в этом файле прописано:

@lxpanel
@pcmanfm -d
dbus-launch nm-applet

Staybox после запускает оконный менеджер, по умолчанию это OpenBox. У него тоже свои средства для запуска приложений, это файл: ~/.config/openbox/autostart.sh

Для оконного менеджера IceWM, файлом запуска будет ~/.icewm/startup

Хочется отметить, что в случае использования xdm/gdm/kdm/slim или им подобным графическим менеджерам входа в систему, стадия пользовательского .xinirc пролетает, и там следует отдельно читать как выполнить свои команды, но я данный подход не использую, поэтому особо и не страдаю.

На этом пожалуй все, если у кого есть что дополнить - комменты ждут.

26)
0 - останов; 1(S) - однопользовательский режим; 2 - зарезервирован; 3 - многопользовательский режим; 4 - зарезервирован; 5 - запуск графической системы; 6 - перезагрузка
28)
от слова shell

// Макробиблиотека CyrillicTools для OpenOffice

Юзал давно, недавно опять вспомнил, сходу найти не смог, поэтому оставляю эту заметку.

Библиотека представляет собой набор макросов на OpenOffice Basic для работы с кирилистическим текстом, всякие заявленные «сумма прописью» я не использую, но вот когда открываешь документ в старом формате MS Office 95 (пользователям 1C посвящается), то часто там битая кодировка, помогает преобразить текст конвертация Latin1→Cyrillic.

В документации сказано как установить библиотеку для всех пользователей в системе, но, если нужно по быстрому, то в OpenOffice 3.x и выше можно воспользоваться услугами менеджера расширений:

  • скачать архив библиотеки: http://openoffice.vspu.ac.ru/cyrtools1.3.uno.zip
  • в запущенном OpenOffice выбрать Tools → Extension Manager, нажать Add… и выбрать скачанный вами архив
  • перезапустить OOo и наблюдать новый пункт меню Cyrillic Document

Сайт проекта: http://openoffice.vspu.ac.ru/ Документация проекта: http://openoffice.vspu.ac.ru/doc/

Из дополнительных интересных расширений советую посмотреть LanguageTool29), в некоторых сборках OpenOffice он уже идет в комплекте, проверьте свою.

29)
Домашняя страница: http://www.languagetool.org/

// medit: 'PHP check syntax' tool

Medit30) замечательный редактор, написанный на Gtk, пока, за малым исключением, удовлетворяет все мои запросы. Корнями уходит графическому интерфейсу GGAP31) для GAP32). Будет время, напишу более полную заметку про него, благо, писать есть что.

Но сегодня рассмотрим вопрос создания тула 'PHP syntax check'.

Делаем тул

Первым делом идем в Изменить → Параметры → Инструменты вкладка Панель инструментов и создаем новый инструмент, даем ему имя 'PHP syntax check' и нажимаем Enter. Далее заполняем поля инстумента:

  • Файлы: langs:php
  • Параметры: need-doc или need-save (подробности в документации)
  • Тип команды: команда оболочки
  • Вывод: Панель вывода
  • В окне ввода скрипта пишем:
    php -l $DOC

Все, сохраняем, выходим. Теперь, когда мы будем редактировать php скрипт, у нас в меню Инструменты будет появляться пункт 'PHP syntax check', вывод по которому будет производиться в окно вывода.

Оптимизируемся

Тул работает, но если возникает ошибка, удобно было бы переходить по клику по не в окне вывода в нужное место документа.

Вспоминаем, что при создании инструмента был пункт Фильтр… Они нужны как раз, что бы Medit из потока вывода мог выбрать для себя нужные данные, на основе которых сделать какие-то действия. Только для наших задач фильтра нет. Нет, так создадим!

Идем в ~/.local/share/medit и создаем там файл filters.xml с, примерно, таким содержимым:

<filter id="php-syntax-check" name="php-syntax-check">
  <match what="stderr" pattern=".*Parse error:.* in (?P&lt;file&gt;[^:]+) on line (?P&lt;line&gt;\d+)"/>
  <match what="stdout" pattern=".*Parse error:.* in (?P&lt;file&gt;[^:]+) on line (?P&lt;line&gt;\d+)"/>
</filter>

Описания формата нет, а мои изыски на официальной вики канули в лету, поэтому пока так:

  • ?P<file>33) говорит Medit, что в этой позиции находится имя файла.
  • ?P<line>34) говорит Medit, что в этой позиции идет строка.

Все остальное - обычные регулярные выражения. Более подробные применения фильтров, можно глянуть в /usr/share/moo/filters.xml, особенно пасы с pop/push

Теперь идем обратно в Изменить → Настройки → Инструменты, 'PHP syntax check' и в качестве фильтра выбираем наш 'php-syntax-check' сохраняемся. Теперь если при проверке синтаксиса вылетит ошибка, мы можем перейти на неё, просто щелкнув по строчке с сообщением о ней.

В качестве дополнительного тюнинга, идем Изменить → Настройка горячих клавиш, в списке находим 'PHP syntax check' и задаем горячую клавишу, я задал F9.

Несколько снимков экрана, всё кликабельно:

Настройка инструмента

Настройка горячей клавиши, пример работы на заднем фоне

// NetworkManager

Все или подавляющее большинство дистрибутивов предоставляют средства для конфигурации сетевых подключений. Это удобно делать на стационарном компьютере, но что если у вас ноутбук и приходится работать в разных сетях, да ещё быстро настраивать WIFI, тут должны помочь менеджеры сетевых подключений, для быстрой настройки и ввода в строй.

Это пост-размышление и попытка найти золотую середину.

Итак, исходное: нетбук Asus EeePC 1000H, дистрибутив ArchLinux, из тех менеджеров, что можно найти в стандартных репозитариях: networkmanager, wicd, nuts (в AUR или в чакра-проджект).

Кратко, как они работают: есть демон, запущенный от рута, и есть клиенты, которые запускаются от пользователя и говорят демону как нужно настроить сетевое настроение, продуманность этого взаимодействия залог стабильности и безопасности, но это сейчас не важно.

wicd

Исторически так сложилось, что это был первый мененджер сетевых подключений, который я использовал. Он меня всем устраивал, даже тем, что можно было указать только под одному сетевому интерфейсу для проводной и беспроводной сети. Все, больше ничего лишнего: не VPN, не PPPoE, ни подключения телефона и т.п. Только управление профилями проводных и безпроводных (WIFI) сетей.

Изначально обладал только графическим клиентом - wicd-client, в последних версия обзавелся и консольным - wicd-curses, и все бы было хорошо, если бы не написан на питоне (есть у меня предубеждения к этому языку, считаю его идеальным для обучения хорошему стилю кодирования, но не как не для создания полноценных приложений, по сути, в мире *nix он стал эквивалентом Visual Basic для Windows).

Ладно, мне главное ехать, а не шашечки. Но в какой-то момент времени стали наблюдаться непонятные события - при отключении сетевого подключения (например если просто вынуть кабель) долгие тормоза, при этом от системы никакого отклика. Те же события при подключении, причем, я не могу выловить закономерности (мало-мало грешу на флеш в Firefox, конкретно - всякие ролики типа с Ютуба). Это меня сподвигло на поиск альтернативы.

NetworkManager

Логичной альтернативой стал NetworkManager, разработанный в рамках проекта Gnome. Исследуя его зависимости, оказалось, что сам демон (NetworkManager) от gnome никак не зависит, а вот с клиентами чуть каша (про это позже).

Краткие возможности: написан на Си, что несколько радует, позволяет настраивать сеть по нескольким сетевым интерфейсам, как проводным так и беспроводным, позволяет настраивать соединения по PPPoE, поддерживает настроку VPN (OpenVPN, pptp и ещё что-то), но через допольнительные плагины (которые требуют, для чего-то, установленного network-manager-applet)

Стандартный клиент - gnetwork-manager-applet (вызывается nm-applet), встраивается в системный трей, откуда можно вызвать и конфигуратор, имеет гномовские зависимости: gnome-keyring, policykit-gnome, notification-daemon

Есть клиент для KDE - knetworkmanager, к сожалению есть только в AUR35) и только для KDE3

Для консоли, клиент cnetworkmanager-git или cnetworkmanager, опять таки только в AUR36). Клиент написан на питоне.

В общем, GUI клиента без лишних DE зависимостей пока найти не удалось, так что если кто предложит, написанный только на QT/Gtk, буду благодарен, а пока наблюдаю работа в nm-applet.

nuts

Орешки :) Но пока я его не расколол - в клиенте так и не увидел ни одного профиля. Из минусов программы: жесткая настройка сетевых профилей в конфигурационном файле, но работать может с несколькими интерфейсами. В комплекте графический клиент на QT4 - qnut и консольный - cnut.

Доступен из AUR37) или из репозитариев чакра-проджект38), для отстройки нужен пакет kdemod-openresolv39) и хотя оба пакета в своём названии содержат kdemod, никаких kde зависимостей они не тянут40).

Вообще программа интересная, буду курить, но больше мне про него на данный момент сказать нечего.

// Crowns: версия 0.3.0

Закрыты задачи:

Подспутно некоторая оптимизация по скорости.

Страница для скачивания тут

// Перекодировка тегов MP3

Установите пакет mutagen:

pacman -Sy mutagen

В каталоге с вашей коллекцией mp3 файлов выполните команду:

find -iname '*.mp3' -print0 | xargs -0 mid3iconv -eCP1251 --remove-v1

Команда перекодирует старые теги из кодировки CP1251 в UTF8, запишет тег версии id3v2.4 и удалит теги первой версии.

Минус способа: если коллекция используется совместно с проигрывателями из альтернативной системы, не все они понимают теги формата 2.4. Поведение при этом различное: от игнорирования тега, до ругани на битый файл.

Hint: в mpd после этого нужно перечитать список проигрывания, например так:

mpc update (дождитесь завершения, статус можно смотреть запуская mpc без параметров)
mpc clear
mpc listall | mpc add

Опционально:

mpc rm all
mpc save all

P.S. Попутно обновил страницу интернационализации на ArchWiki

// Тормоза в XFCE

Один из вариантов.

Если такое вдруг началось, особенно при запуске… посмотрите вывод ps auxwww количество запущенных процессов, а потом гляньше на файл сессии ~/.cache/sessions/xfce4-session-HOSTNAME:0 у меня там 50 раз запускался xfdesktop.

Да, смысл имеет только в случае сохранения сессий.

// Полезный софт: ScanTailor

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

Сайт: http://scantailor.sourceforge.net/ ArchLinux AUR: http://aur.archlinux.org/packages.php?ID=25426

// Софт на Qt4

Вот наткнулся случайно: список приложений написанных на Qt4 по английски, но выбрать себе можно. Мне вот понравился браузер Arora, в репозитариях есть arora (extra) и arora-git (community). Но про браузеры ещё будет пост ;)

// Пару заметок о QLandkarteGT

Для начала, вышла версия 0.11.0, сайт программы: http://www.qlandkarte.org/

Что из себя представляет, я уже писал

И несколько заметок:

// Sakura и Termit

На форуме русского сообщества ArchLinux в разделе скриншотов за декабрь 2008 появилась тема, там, на снимке экрана фигурировал эмулятор терминала Sakura, решил попробывать.

Sakura

Терминал зависит только от GTK и компоненты VTE, умеет UTF-8, табы. Есть в community репозитария ArchLinux. После запуска имеет примерно такой вид:

sakura

Все настройки, коих аскетично мало, делаются через контекстное меню:

sakura2

Конечно, горячие клавиши, тут даю на основные операции, что меня интересуют:

  • Ctrl-Shift-t - создать новую вкладку
  • Ctrl-Shift-w - закрыть текущую вкладку
  • Alt-Left/Right - переключение между вкладками влево/вправо

Исходный код программы состоит из одного файла :)

Termit

Изучая сакуру, нашел на её сайте упоминание терминала Termit. Эмулятор терминала так же зависит от GTK и VTE, но ещё требует LUA 5.1. Умеет UTF-8, табы. В репозитариях ArchLinux нету, есть только в AUR. После первого запуска видим такое окно:

termit

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

Сразу после запуска будете неприятно удивлены когда откроете новую вкладку - цвет текста сбросится в черный, а прочитать черным по черному будет проблемно :)

Автор уже знает, а пока что можем сделать сами.

Вот тут делои касается конфигурации. Она происходит скриптом на LUA который помещается в ~/.config/termit/init.lua, пример этого скрипта есть в архиве с исходными кодами, пример надо сказать работающий и функциональный. В случае ArchLinux выполним команды:

mkdir ~/.config/termit
cp /usr/share/doc/termit/init.lua.example ~/.config/termit/init.lua

и немного подредактируем. Главное раскомментируйте параметр defaults.foreground_color и укажите тот что вам нужен, gray в большинстве случаем окажется достаточным.

Перезапускаем termit, наблюдаем что в новых вкладках нормально отображается текст, наблюдаем два новых пункта меню:

  • User menu
  • Encodings

termit2

Последнее позволяет поменять кодировки, особенно актуально мне, когда приходится по ssh заходить то на сервера со старой доброй koi8-r или на новые utf-8. Да luit помогает, но иногда забывается, а перелогиниваться лениво :)

Почитать про LUA API термита можно в доке, что идет с ним: /usr/share/doc/termit/lua_api.txt (путь может отличаться в вашем дистрибутиве)

Горячие клавиши настраиваются через init.lua, по умолчанию такие:

  • Alt-Left - предыдущая вкладка
  • Alt-Right - следующая вкладка
  • Ctrl-t - открыть новую вкладку
  • Ctlr-w - закрыть текущую вкладку
  • Ctrl-Insert - копировать выделенный текст в буффер
  • Shift-Insert - вставить текст из буффера

Выполнение приложений

Ещё иногда нужно выполнить какое-то приложение в терминале, иногда приложение не интерактивное, и терминал быстро схлопывается, так что не рассмотреть результатов. Поэтому обычно команда приобретает вид:

bash -c 'echo test; read'

и пока не нажмешь Enter терминал не закроется

Для sakura командная строка получилась:

sakura -e "bash -c 'echo test; read'"

и ничего не отработало - завершилось ошибкой

У termit строка такая:

termit --execute "bash -c 'echo test; read'"

и всё отработало как нужно!

termit3

Ну… В общем, Termit - мой выбор ;)

Сайты программ

// Замечания по NDB кластеру и NDB-нодам

На уровне замечений, касательно понятий «Node Group» и параметра секции [NDBD DEFAULT] NoOfReplicas в конфиге кластаера config.ini

NoOfReplicas - параметр задающий количество реплик данных. Допустим, его значение 2, тогда получается у нас будет две реплики данных. Теперь дальше, допустим, NDB ноды у нас с номерами 10, 11, 12, 13 и в конфиге они перечислены в этом же порядке, тогда количество Node Group будет:

NodeGroupsCount = NDB_Nodes_Count / NoOfReplicas = 4 / 2 = 2

Номера Node Group будут: 0 и 1 (нумерация с нуля.)

Теперь, как ноды группируются в группы? А просто, по порядку номеров. Т.е. наши ноды 10, 11, 12, 13 при NoOfReplicas = 2, распределятся так:

  • Node Group 0: 10, 11
  • Node Group 1: 12, 13

Если прводить аналогии, то очень похоже на RAID 10: 10+11, 12+13 - работают в зеркалирование, и в сумме (10_11)+(12_13) - в чередовании.

Отсюда ещё одно важно замечание: если ВСЕ ноды одной группы вылетают, целостность данных нарушается, как следствие ВЕСЬ кластер прекращает работу, и, как следствие: для работы (и для запуска) кластера необходимо, что бы было хотя бы по одной живой ноде из группы.

Ещё одно замечание (пока окончательно не проверено), но дополню: по одной живой ноде из группы должны стартовать в промежуток не больше 30 сек. Ещё лучше запускать ноды с параметром -n а потом через менеджмент-панель делать или ALL START или node-id START

И в заключение, если отвалится одна нода из группы, лучше, как можно быстрее получить об этом уведомление на почту или ещё куда. И распределять ноды одной группы так, что бы не получилось «семерых одним ударом».

// Планировщик IO проблемы тормоза системы

С недавнего времени стал замечать что система очень сильно тормозит на дисковых операциях. Например, если нужно создать файл 1.5G (допустим, аллоцирование места под закачку торрента), то на выделении система чуть ли не раком становиться - работать становиться очень некомфортно: мышь почти не работает, отклик от клавиатуры очень долгий. Это при том, что памяти - вагон и маленькая тележка (из 1G оперативы 800 метров на кеши, используется меньше 200M).

Почеса репу, решил поглядеть на планировщики IO:

[root@gaz ~]# dmesg | grep scheduler
io scheduler noop registered
io scheduler anticipatory registered (default)
io scheduler deadline registered
io scheduler cfq registered

Начинаю копаться в памяти, ага, точно, на современных ядрах почти всегда планировщик IO по-умолчанию - cfq. Я, видать, уже эксперементировал, и в строке загрузки Grub:

elevator=as

Поменял на

elevator=cfq

(можно было бы и убрать)

Всё, теперь работа стала значительно более приятна.

Хочу отметить, что:

  • noop - обычный FIFO, подразумевается оптимизация ввода-вывода на уровне блочного устройства.
  • deadline - реализует механизм предельного срока для минимизации задержен IO. В один момент времени одно приложение имеет эксклюзивный доступ к диску. Для пользовательского ПК врядли подойдет, для сервера базы данных - вполне (да и серверов вообще, где с диском работа идет активно)
  • as - упреждающий доступ, говориться, что подходит для медленных и малых дисковых подсистем. Как оказалось у меня, на диске 750G не очень хорошо система себя чувствовала.
  • cfq - полностью справедливая очередь. Очередь ввода/вывода для каждого процесса, пытается разделить всю полосу пропускания между ними.

Если контроллер и диски поддерживают NCQ (SATA диски), стоит попробывать планировщик noop, теоретически производительность должна стать сравнима с cfq, при почти нулевой загрузки CPU. Ставить noop для IDE дисков смысла нет.

Да, планировщик можно поменять «на лету», указав для каждого диска свой:

[root@gaz hda2]# cat /sys/block/sda/queue/scheduler
noop anticipatory deadline [cfq] 
[root@gaz hda2]# echo noop > /sys/block/sda/queue/scheduler
[root@gaz hda2]# cat /sys/block/sda/queue/scheduler
[noop] anticipatory deadline cfq 

Почитать про планировщики можно тут:

// UFRaw 0.14

Недавно вышел сабж. Подробности перепечатывать смысла нет, посмотреть новость можно на LOR

Из вкусного:

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

ЗЫ если на ЛОР не читать комменты, то, можно сказать, даже приличный сайт :)

// Ещё немного про организацию CA (центра сертификации)

Для начала использовал программу TinyCA умеет многое и почти всё что нужно, единственно что не умеет (или я не разобрался как) делать иерархию подписывания, т.е. сертификат cert1 подписан certca, а сертификат cert2 подписан сертификатом cert1… Плюс неожиданно обнаруженная бага, при которой при экспорте сертификата в pkcs#12 для импортирования его в Windows, последний не импортируется.

Написана прога на PyGTK.

Поиски навели на проект XCA. Написан на QT4, при компиляции потребовались небольшие шаманства с файлом lib/x509rev.cpp конкретно потребовалось сделать следующее (в формате diff):

--- x509rev.cpp.orig	2008-10-02 13:19:11.000000000 +1100
+++ x509rev.cpp	2008-10-02 13:41:39.000000000 +1100
@@ -7,16 +7,21 @@
 
 #include "x509rev.h"
 
-#if OPENSSL_VERSION_NUMBER >= 0x00908000L
-#define X509_REVOKED_dup(x5r) \
-	ASN1_dup_of (X509_REVOKED, i2d_X509_REVOKED, d2i_X509_REVOKED, x5r)
+//#if OPENSSL_VERSION_NUMBER >= 0x00908000L
+//#define X509_REVOKED_dup(x5r) \
+//	ASN1_dup_of (X509_REVOKED, i2d_X509_REVOKED, d2i_X509_REVOKED, x5r)
+//
+//#else
+//#define X509_REVOKED_dup(x5r) (X509_REVOKED *)ASN1_dup( \
+//	(int (*)(...))i2d_X509_REVOKED, \
+//	(char *(*)(...))d2i_X509_REVOKED, \
+//	(char *)x5r)
+//#endif
 
-#else
 #define X509_REVOKED_dup(x5r) (X509_REVOKED *)ASN1_dup( \
-	(int (*)(...))i2d_X509_REVOKED, \
-	(char *(*)(...))d2i_X509_REVOKED, \
+	(i2d_of_void *)i2d_X509_REVOKED, \
+	(d2i_of_void *)d2i_X509_REVOKED, \
 	(char *)x5r)
-#endif
 
 x509rev::x509rev()
 {

У кого-то наверное запустится и без этого, ибо чует моё сердце здесь многое зависит от версии компилятора и/или библиотеки OpenSSL.

Ну краткий обзор… Да управление не такое удобное как у TinyCA, хотя, возможно, это дело привычки. Но, как показалось, более функциональное. И при этом умеет иерархию. Старый корневой сертификат и ключ заимпортировал, на основе их делаю подписи. Вся база хранится в зашифрованном виде в единственном файле (база данных, подозреваю, что возможны случаи поломки всего этого дела), но возможен дамп базы, и будут по каталогам разложены сертификаты, реквесты и т.д.

Пока юзаю и разбираюсь. Время покажет.

// Inkscape

Хороший мануальчик по изучению методов работы в Inkscape: Изучение Inkscape — создание эскизов Order of the Stick с помощью Inkscape

Чуть обновил сайдбар.