Hatred's Log Place

DON'T PANIC!

May 23, 2010 - 2 minute read - Comments -

DokuWiki и web-закладки

Случайно наткнулся на плагин dokubookmark, ставится в два движения, настраиваются неймспейсы… Но тороплюсь.

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

Как их потом искать? В шаблоне по-умолчанию сразу ставится тег Bookmark, я рекомендую его не убирать, потом по этому тегу просматривать свои закладки. Помимо этого: * по назначенным тегам, если озаботились этим * поиском по сайту

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

javascript:Q=document.selection?document.selection.createRange().text:document.getSelection();void(window.open('http://SITE/wiki/doku.php?do=dokubookmark&te='+encodeURIComponent(Q)+'&ur='+encodeURIComponent(location.href)+'&ti='+encodeURIComponent(document.title),'dokuwikiadd','scrollbars=yes,resizable=yes,toolbars=yes,width=680,height=520,left=210,top=150,status=yes'));

Только исправьте адрес и путь на сайте на свои.

Все, пробуйте :)

UPD: Поддержка кирилицы

Из коробки пока не работает нормально с кирилицей (решение ниже, оно же отправлено разработчику)

Вы можете заметить, что для экранирования передаваемой строки используется escape(), так что кодировку строки-источника мы определить никак не сможем. Есть другие вызовы, которые так же экранируют строку, но в кодировке UTF-8, не зависимо от настроек сайта, это: * encodeURI() * encodeURIComponent() Различия между ними можно посмотреть в этой статье (и о escape() так же): http://habrahabr.ru/blogs/webdev/17640/, после чего выберите ту, которая по вкусу.

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

htmlentities($some_text_var)

на

htmlentities($some_text_var, ENT_COMPAT, "UTF-8")

Дело в том, что у htmlentities(), согласно документации, кодировка по умолчанию ISO-8859-1, за подробностями в документацию (умный форматировщик кода у меня тут, даже ссылки сразу на первоисточники поставил, пользуйтесь).

UPD2: Все, эти пляски не нужны, автор обновил версию, за что ему большое спасибо :)

May 22, 2010 - 1 minute read - Comments -

DokuWiki, blog и include плагины

Коротко: include плагин некорректно закрывает <div> если задана опция отображать только первую секцию, в результате может поехать… Ну сами догадайтесь.

Исправление, подразумевается, что мы в директории plugins: 1. открыть include/helper.php 2. найти там функцию _get_firstsec(&$ins, $page) 3. найти в ней строкуphp$ins[] = array('section_close'); 4. заменить на: php$ins[] = array('section_close', array()); 5. очистить кеш 6. радоваться :)

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

http://img153.imageshack.us/img153/1839/screenshoot201005221900.png

Так после:

http://img232.imageshack.us/img232/1196/screenshoot201005222034.png

UPD: написал письмо разработчикам, отреагировали быстро, в git уже есть изменения :)

May 21, 2010 - 1 minute read - Comments -

YouTube и HTML5

На правах реминдера.

http://www.youtube.com/html5

позволяет включить для видео тег

<video>

и забыть о необходимости флеша. Работает сразу в chrome/chromium, для Firefox есть расширение которое заменяет тег на

<embed>

и после этого нормально работает.

May 13, 2010 - 6 minute read - Comments - linux

Резервное копирование при помощи rsync+ssh

Статей на эту тему много, к примеру: * http://wiki.archlinux.org/index.php/Rsync * http://www.scrounge.org/linux/rsync.html * http://main.linuxfocus.org/Russian/March2004/article326.shtml

Но нигде не нашел внятного объяснения как сохранять права доступа, группу и владельца, особенно, если удаленный сервер (backup-сервер) работает не от пользователя root.

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

Настройка backup-сервера

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

Далее, создаем пользователя под которым будут храниться резервные копии, пусть это будет backup: adduser backup

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

После чего, в его домашнем каталоге создаем подкаталоги lock и files: mkdir lock file

Затем создаем там же, в домашнем каталоге, файл rsyncd.conf с примерно таким содержимым:

# малость системной информации, подробнее 'man rsyncd.conf'
use chroot = no
max connections = 4
syslog facility = local5
pid file = /home/backup/lock/rsyncd.pid
lock file = /home/backup/lock/rsyncd.lock

[backup]
    comment = Backup area
    # хранить информацию о правах, владельце и группе в цифровом виде, если не нужно - поставьте no
    numeric ids = yes
    # эта опция позволяет хранить информацию о правах, владельце, группе в xattr, об этом далее
    fake super = yes
    # путь к корню, где будут храниться копии
    path = /home/backup/files
    # по умолчанию, все модули - read only, нам же нужно писать
    read only = no

Комментарии по тексту, думаю остальное избыточно.

Теперь ремарка… об этих самых xattr: Я столкнулся с тем, что при попытке записи, выдавалось сообщение об ошибке, и эти самые атрибуты не писались, гугл ответа не дал. Поставил пакет, зовется attr, который нужен для управления расширенными атрибутами файлов. Вдумчивое чтение ‘man 5 attr’ дало следующее: > Currently, support for extended attributes is implemented on Linux by > the ext2, ext3, ext4, XFS, JFS and reiserfs filesystems.

А, как следствие, вдумчивое чтение ‘man mount’ дало информацию о параметре монтирования user_xattr. У меня файловая система ext4, там этот атрибут по-умолчанию выключен, для сохранения информации о владельце/группе нужно его включить. Поэтому в /etc/fstab для нужной файловой системы после defaults добавил user_xattr, получилось примерно следующее: UUID=780ae01a-6fe2-416f-baa2-0d700cd9574f /home ext4 defaults,user_xattr 0 1

По сути, это все, что относится к серверной настройке, после потребуется только создания своего индивидуального подкаталога для каждого резервируемого хоста внутри ‘files’, я рекомендую создавать эти каталоги по имени хоста (вывода команды hostname). Пока создадим там каталог host1

Резервируемый хост

Тут нужно набросать скриптик и несколько конфигурационных файлов прописать его в cron для регулярного выполнения: * backup.sh - сам скрипт, понимает 3 аргумента: * backup - выполняет резервирование * list - показывает содержимое бекапа на сервере * restore <что> <куда> - восстанавливает данные из резервной копии * backup.conf - конфиг, что бы можно было оперативно размножить по разным хостам * backup.list - список файлов и директорий подлежащих резервированию * backup.exclude - список паттернов для исключения из резервирования (man rsync) * backup.include - писок исключений (отменяет некоторые паттерны в exclude, смотреть man rsync) * backupcron - небольщой скрипт для выполнения планировщиком, я его положил в /etc/cron.hourly/, добавив префик zz, что бы выполнялся последним. * hook.d/ - директория со скриптами, которые выполняется перед выполнением резервирования

Итак, сами скрипты. * backup.sh``` #!/bin/bash

#

Скрипт для инкрементного бекапа при помощи rsync+ssh

с сохранением прав/владельца файла в расширенных

атрибутов (требуется монтирование файловой системы на

которую будет производится резервирование с опцией user_xattr)

#

Version: 20100512.1

#

«THE BEER-WARE LICENSE» (Revision 42):

hatred@inbox.ru wrote this file. As long as you retain

this notice you can do whatever you want with this stuff.

If we meet some day, and you think this stuff is worth it,

you can buy me a beer in return. Alexander ‘hatred’ Drozdoff

#

source backup.conf

[ -z “$host” ] && host=hostname

exclude=backup.exclude include=backup.include backups=backup.list

DAY=$(env LANG=C date +“%F_%H”)

do_hooks() { for pkg in hook.d/* do [ -x $pkg ] && ./$pkg done }

do_backup() { is_incr_exists=$(ssh $ssh_user@$host “stat files/$dest/incr/$DAY > /dev/null 2>&1 && echo yes || echo no”) if [ “$is_incr_exists” == “yes” ]; then ssh $ssh_user@$host rm -rf files/$dest/incr/$DAY fi

do_hooks

rsync -av -R <br/>
    -e "ssh -l $ssh_user" <br/>
    --fake-super <br/>
    --delete <br/>
    --delete-excluded <br/>
    --inplace <br/>
    --backup <br/>
    --backup-dir=/$dest/incr/$DAY <br/>
    --exclude-from=$exclude <br/>
    --include-from=$include <br/>
    $(cat $backups) <br/>
    $host::backup/$dest/full/

}

do_list() { rsync -v -e “ssh -l $ssh_user” $host::backup/$dest/$1 }

do_restore() { rsync -av -e “ssh -l $ssh_user” –super –safe-links $host::backup/$dest/$1 $2 }

do_help() { cat << EOF Use: $0 [SRC] [DEST] EOF }

action=$1 shift

case $action in backup) do_backup ;; list) do_list $@ ;; restore) do_restore $@ ;; *) do_help ;; esac

  * **backup.conf**```
# пользователь на бекап сервере, под которым хранятся резервные копии (того что мы создавали)
ssh_user=backup

# IP или HOST backup-сервера
host=backup.server

# Имя поддиректории в files на backup-сервере для хранения данных конкретного хоста
dest=host
  • backup.list, просто список директорий и файлов, главное, если хотите сохранять саму директорию, а не его содержимое, не ставьте в конце “/”, т.е. вместо “/etc/” пишите “/etc”. примерное содержимое: /etc /home /root /var/backup

  • backup.exclude, список паттернов (man rsync). Обратите внимание, испключается последний элемент, т.е. /var/cache/*/* сохранит директории/файлы в /var/cache/, но исключит их содержимое . примерный список *~ *.back /sys /dev /tmp /proc

  • backup.include, у меня пустой, позволяет делать отдельные исключения к exclude, т.е. для примера выше, если вписать /proc/cpuinfo, то cpuinfo будет сохраняться.

  • backup_cron, правится под ваши нужды, у меня примерно такой:``` #!/bin/bash

cd /home/backup/backup/ ./backup.sh backup > log/backup-$(date +%H).log 2>&1

Все, осталось под пользователем root создать ssh-ключи и передать их на backup-сервер:

ssh-keygen # (тут главное не ставьте парольную фразу, или заводите ssh-agent, но это другая история) ssh-copy-id -i ~/.ssh/id_rsa backup@backup.server # спросит пароль пользователя backup, передаст ключ

По сути всё. Что в результате имеем: на сервере в каталоге host1/full хранится полная копия всех файлов на момент последнего запуска скрипта, передаются только измененные файлы, в каталоге host1/incr/YYYY-MM-DD_HH хранится копия перезаписываемого файла (т.е. если файл изменился, перед тем как он запишется в full, он оттуда сохраняется в incr/YYYY-MM-DD_HH, реализуя таким образом схему инкрементного бекапа).

Восстанавливать примерно так:

mkdir restore ./backup.sh restore full/ restore/ ./backup.sh restore incr/2010-05-10_14/ restore/ ```

Восстановит в т.ч. и атрибуты и владельца/группу, естественно восстановление нужно делать от пользователя root.

Скрипты я оформил, положил вместе со всеми остальными в git, получить можно: git clone http://hatred.homelinux.net/git/scripts.git

в каталоге backup, там же посмотрите скрипт hook.d/pacman.sh, сохраняющем список пакетов перед резервированием.

Источники информации в системе

  • man rsync
  • man rsyncd.conf
  • man attr
  • man 5 attr
  • man mount

May 10, 2010 - 3 minute read - Comments -

Xorg 1.8

Поставил из любопытства, в частности поглядеть на новые средства конфигурации для Input устройств - теперь HAL не используется, а используется, в Linux (кстати, а как на других *nix?), UDEV.

Сразу, для олдовых мужиков, которые издревле конфигурировали иксы через /etc/X11/XFree86.conf или /etc/X11/xorg.conf, тут практически ничего не изменилось: * появилась возможность “дробить конфигурацию”, ложить в отдельных файликах в /etc/X11/xorg.conf.d * именно для Input-устройств появилась новая конфигурационная секция (что бы все драйверы не грузились, только нужное) - InputClass о которой можно так же почитать в man xorg.conf (там обратите внимание на новые директивы, которые помогают определять устройство, всякие Match*)

Теперь, как узнать различную информацию которую можно подсунуть этим самым Match*? Тут рекомендуют обратиться к udevadm, но отчего-то у меня она оказалась мало-информативна. Воспользовался логикой: UDEV берет информацию из SYSFS, при помощи правил в /etc/udev/rules.d добавляет/модифицирует свою, но основную можно глянуть и самому в SYSFS. Для этого идем в /sys/class/input делаем ls и смотрим сколько у нас тут всякого! По крайней мере у меня на EeePC:

$ ls
event0   event11  event4  event7  input0   input11  input4  input7  mice
event1   event2   event5  event8  input1   input2   input5  input8  mouse0
event10  event3   event6  event9  input10  input3   input6  input9  mouse1

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

$ cat /sys/class/input/event10/device/name 
ETPS/2 Elantech Touchpad

Там и другие файлы, другая информация есть, смотрите что нужно.

Из остальных: event1 оказался клавиатурой, там же оказались и ACPI кнопки типа Power Button (event5, event6 - почему только два?), Sleep Button (event4), встроенная usb веб-камера (event8), PC Speaker (event11). Унификация, фигли :)

Ну и вот мои конфиги: * Для тачпада: /etc/X11/xorg.conf.d/09-elantech.conf``` Section “InputClass” Identifier “touchpad catchall”
# Как я получил имя продукта, описано выше MatchProduct “ETPS/2 Elantech Touchpad”

    Option  "SHMConfig"              "on"
    Option  "MaxSpeed"               "1.00"
    Option  "MinSpeed"               "0.75"
    Option  "Emulate3Buttons"        "on"
    Option  "VertTwoFingerScroll"    "1"
    Option  "HorizTwoFingerScroll"   "1"
    Option  "TapButton1"             "1"
    Option  "TapButton2"             "2"
    Option  "TapButton3"             "3"
    Option  "LockedDrags"            "11"

    Driver "synaptics"

EndSection

  * Для переключения раскладки клавиатуры: **/etc/X11/xorg.conf.d/09-keymap.conf**```
# Мои общесистемные настройки переключения клавиатуры для Xorg 1.8
Section "InputClass"
        Identifier "evdev keyboard catchall"
        MatchIsKeyboard "on"

        Option "XkbModel"    "evdev"
        Option "XkbRules"    "base"
        Option "XkbLayout"   "us,ru"
        Option "XkbVariant"  ",winkeys"
        Option "XkbOptions"  "grp:lwin_toggle,grp_led:scroll,compose:ralt,terminate:ctrl_alt_bksp"
EndSection

Немного более детально можно почитать: * у камрада Muhas: http://muhas.ru/?p=133 (вообще рекомендую его блог, особенно любителям тайловых WM и хаков с dmenu :simple_smile: * по вышеуказанной ссылке на англоязычную конфу ArchLinux: http://bbs.archlinux.org/viewtopic.php?pid=753773#p753773 * или тут, но как-то наворочено: http://bbs.archlinux.org/viewtopic.php?pid=683104 * по поводу UDEV и как для него писать правила: http://www.reactivated.net/writing_udev_rules.html * малость в арчевики: http://wiki.archlinux.org/index.php/Xorg#xorg.conf.d_.28Xorg_1.8.29 * man xorg.conf

PS на правах хинта, а то постоянно вылетает из головы: получить базовый xorg.conf: X -configure или Xorg -configure

May 10, 2010 - 1 minute read - Comments - projects programming

Crowns 0.4.0

Выпустил версию 0.4.0 из основных изменений: * добавлена поддержка подложки (фоновой картинки), для реализации отображения синнузий * поддержка импорта из текстовых файлов данных с возрастом, плюс реализована совместимость со старыми форматами * оптимизация отрисовки проекций крон: реализована отрисовка кривыми Безье * экспорт построений в SVG

Как обычно версия для Windows отстроена путем кросс-компиляции, требуется тестирование.

Полный список изменений: ChangeLog

Скачать: Download

Apr 26, 2010 - 6 minute read - Comments - туризм

Нет, мы не эльфы...

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

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

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

Дальше подъем, поднялись по боку трассы до верху, снег тут плотный, влажный. Наверху трассы несколько сместили тропу, сейчас проще подняться до самого конца подъемника и за ним чуть спуститься, высмотреть метки на деревьях краской и топать по тропе. Предварительно спустились вниз к домикам, запаслись водой, на всякий случай. Я надел бахилы.

Тропа пока хорошая, достаточно прочная, но временами таки проваливались по самый пояс. Ненароком вспомнилась сцена из фильма “Властелин колец”, когда герои передвигались по снегу - все проваливались, а эльф бежал по снегу, тогда и родилась присказка которой сопровождалось каждое проваливание: эх, все таки мы не эльфы :)

По тропе вышли на хребет, подниматься было тяжко, решено сделать привал. Находим, как грачи, проталину, Настя быстро собирает “порох” на растопку, я пока подыскивают полешки, что бы удобно сложить костер - вскипятить чаю. Пока собираю, поддтаскиваю, она разводит огонь. Перекусываем, пьем чай, тратим около 40-60 минут, но душевно. Формируем программу-максимум и несколько вариантов программ-минимумов.

Программа максимум: * Дойти до вершины, насладиться видом, спуститься, сделать чаю в термос, сделать чаю на привал, дойти и успеть на электричку

Программы минимумы: * Дойти до вершины, быстро спуститься, успеть на электричку. Чай не делаем. * Не дойти до вершины, топать до часа Ч, поворачивать назад, делать чай, успевать на электричку * Не дойти до вершины, топать до часа Ч, поворачиваться назад, не делать чай, успевать на электричку * Предыдущее с неуспеванием на электричку :simple_smile:

Выполнили, забегая вперед, программу-максимум :)

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

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

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

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

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

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

За время похода и поездки в электричке пришел к выводу, что болтологию нужно рассматривать с точки зрения релятивисткой механики: расстрояния проходятся быстрее за разговором. Правда пока затрудняюсь сейчас ответить, что именно происходить: сокращение расстояния или убыстрение тока времени. Нужно, однако, садиться за научный труд :laughing: Хотя иногда трудно говорить при ходьбе, да и дышать больше ртом приходится, что бывает чревато.

Кроме того, заметил, что рюкзак нужно иметь всегда с поясным ремнем (пошел со своим спортивно-городским), потому как, даже не очень тяжелый рюкзак, который давит только на плечи, значительно утомляет спину, а с ремнем можно часть нагрузки перенести на поясницу, тем самым повысив комфорт в движении.

Ну все, до новых встреч и новых знакомст в лесу, если всопмню что интересного - допишу.

UPD:

Фото, которые сделала Надя

А это стихи, которые она написала пока обратно ехали в электричке:

№1 Когда не на пару и не на работу Встается легко в без пятнадцати пять, И адреналин прогоняет дремоту Когда начинаешь ботинки искать… Но завтрак сготовлен и собран рюкзак, Созрел в голове план коварный похода, Нельзя упустить электричку никак И вдаль повела нас тропа от порога. Нас лес повстречает прохладой весенней, Прибавив для вкусу дорожную грязь. И после цепочка из этих мгновений Нас в каменных джунглях согреет опять. Дорога к вершине – в капризах из наста, И снег норовит заползти в башмаки Еще б потеплей - и нужны будут ласты, Но в них не удобно по лесу ползти… Нас мало по малу пускает Фалаза, И небо к нам ближе стало чуть-чуть Становиться жить разноцветнее сразу, И рядом маячит Вселенская Суть!

№2 Как-то раз на выходные Мы ударились в бега. Взяли тапки запасные, Взяли в термосе чайка. Без потерей мы добрались, На вершине - солнца свет. Мы б от счастья разорались, Но там был уже дуэт! Саша с Настей не орали, И не прыгали везде, Ну, мы их зауважали, Расспросили: че, да где. Они стрелку нам забили, На хребте да у костра Там все вместе чай попили, Но дорога нас ждала. Электрон не за горами Пешкодрапом – два часа. Восхищались небесами, Говорили про леса… По пути нас провожали Два дворняги – другана, Колбасы когда им дали Обещали ждать всегда. Вобщем мы в больших надеждах На совместный вновь поход, Может, на вершинах снежных, Может и наоборот!

Apr 17, 2010 - 3 minute read - Comments - туризм

Из весны в зиму и обратно

Сегодня ходили на водопад на ключе Левый Горбатый (один из “шкотовских водопадов”) в составе трех человек: Я, Юс, Лиза (хотя должно было быть 7 мордолиц), планировали на два дня но так сложилось, что обратились в однин. Но по порядку.

Для начала, на сайте Зеленого есть описание маршрутов на Шкотовское плато, от себя внесу небольшие коррективы как добираться туда, и выбираться от туда, описание для безлошадных :)

Для начала добираемся до Шкотово, сделать это можно на первой электричке, что идет из Владивостока до Тихоокеанской, отправляется в 6.21. Прибывает она примерно в 8.10-8.15, почти сразу есть автобус до Сергеевки, можно сесть до него, или в 9.05 есть автобус 564 (???) Уссурийск-Партизанск (уточните в кассе), если будет задержка.

На автобус садимся, берем билеты до села Центрального, но объясняем водителю, что не на повороте выходим, а чуть дальше “фазенды” (это определение услышал сегодня от водителя, говорит: тут выходят люди, которе потом напрямую в Центральное идут пешком, с поворота слишком круто), где выезд на лесовозную дорогу (географически находится точно севернее самого Центрального). В прошлом году водитель был злой, особо объяснений слушать не стал, сегодня почти как карета остановилась :) и всего 50 руб с человека, даже за багаж не взял - тут видать как повезет, но вообще, спасибо мужику :)

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

Ладно, теперь о впечатлениях.

Собрали в Шкотово, сели на автобус 9.05, доехали, шел мокрый снежок, приехав на поворот в вступив на лесовозную дорогу впечатлились просто страшной кашей из глины, на счастье нам, чуть подмерзшей, так что прошли без особых проишествий.

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

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

Ещё как пришли, все несколько мокрые - снег не сухой же, Юрка переоделся в сухое, я по старинной привычке - нет (лучше двигаться и не мерзнуть или развести костер), сидим, получился такой диалог:

Ю: тебе нормально, не мерзнешь?

Я: неа, нормально

Ю: как так, я в сухом и у меня жира больше!

Я: ну дык, зато у меня - качественней! :laughing:

Вот так, настоящие мужики всегда найдутся чем помериться :)

Обратно выдвинулись примерное в 15 часов. И вот стали замечать, обратный процесс со негом и температурой: ближе к дороге снега вообще не стало, зато дорога превратилась в наглядную демонстрацию весенней распутицы на Руси, а место въезда на грунтовку в сплошное глиняное болото - еле прошли.

Как вышли, в кустах на противоположной стороне дороги, разбили пикничок, почистили обувь, пока подъехал знакомый и добросил до Шкотово. Там, пока ждали, подъехали велосипедисты, что ехали с нами на первой электричке, оказалось с одним, Сашей, уже познакомились, буквально неделю назад - они с нашим общим знакомым ехали на сплав под Партизанск, в общем - Земля квадратная :) Они оказались из турклуба Гринтур, катались до Стеклянухи, там сплавлялись, тоже поделились впечатленями. В общем, доехали вместе в приятной компании, ведь турист туристу, друг, брат и лишняя банка тушенки :laughing:

Apr 5, 2010 - 1 minute read - Comments - linux

OpenSource #058

В этом выпуске вторая часть моей статьи по схемотехнике в Linux: “Схемотехника в Linux с помощью gEDA. Часть 2: pcb”

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

PS выпуск первоапрельский, но вредительства нет :)

Apr 4, 2010 - 1 minute read - Comments - programming

Интересная нотация switch/case в gcc

Относится к расширениям gcc, не претендует на переносимость, но все же: в gcc у case можно указывать диапазоны значений:

case LOWVAL ... HIVAL:

Например:

switch(var) 
{
     case 0 ... 2:
        /* какой-то код */
        break;
     case 3 ... 5:
        /* какой-то другой код */
        break;
     default:
        /* что делаем, когда ничего не помогает */
}

этот код эквивалентен такому:

switch(var) 
{
     case 0:
     case 1:
     case 2:
        /* какой-то код */
        break;
     case 3:
     case 4:
     case 5:
        /* какой-то другой код */
        break;
     default:
        /* что делаем, когда ничего не помогает */
}

ЗЫ про одно полезное расширение gcc я уже писал: 0b00100100

Apr 3, 2010 - 3 minute read - Comments - programming

Qt Creator и Generic Projects

Или: можно ли использовать Qt Creator не для Qt? Если коротко - можно.

Почему он? Потому что оказалось, что он достаточно функционален в мелочах, в частности индексирования кода и автодополнения. Крайне удобен в применении его Locator (что вызывается по стандартному сочетанию клавиш Ctrl+K), применение Локатора вообще сводит использование мыши в Qt Creator к минимуму (что удивительно для среды ориентированной на тулкит Qt4 и создание, в основном, графических приложений). Да, правда обвыкнутся по началу нужно, но потом… Если плагин (http://gitorious.org/creator-plugins), который добавляет функционал по автоматическому созданию реализации функции/метода по его прототипу, так же Я, до того, как узнал про этот плагин, делал свой патч, со схожим функционалом. В общем, все что нужно для удобной работы с проектом (навигация, дополнения, подсветка синтаксиса, отстройка, отладка и т.п.) здесь есть.

Осталось понять, как это добро использовать. Вопросов нет, когда речь идет о родных средствах, типа .pro файла и qmake, а вот при использовании с не qmake/cmake проектами, можно воспользоваться Generic Project, который используют вашу систему сборки, не вмешиваясь в неё. Подробности всегда можно посмотреть на официальном сайте: http://doc.qt.nokia.com/qtcreator-snapshot/creator-project-generic.html

Собственно по ссылке выше и рассказано все, что нужно знать. Тезисно: 1. используется ваша система сборки, порядок шагов по сборке можно задать в свойствах проекта, по умолчанию, это выполнение команды make all, соответственно там можно задать любую нужную последовательность, которая соответствует вашей системе сборки. 2. аналогично задаются шаги по очистке проекта. 3. аналогично задается цель для запуска. 4. аналогично задаются зависимости между проектами (они должны быть открыты). 5. при создании указывается директорий вашего проекта, по умолчанию просканируется дерево и добавятся все *.c, *.cpp, *.cc, *.h, *.hpp файлы (как сказано - все известные типы). 6. после создания проекта и сохранения настроек на диске будет создано несколько файлов: * project_name.files - тут список файлов входящих в проект, обычно исходники, в помощь парсеру, можно править вручную, обновляются автоматически, при добавлении файла в проект из самого Creator’а * project_name.includes - тут список include директорий, в помощь парсеру, можно править вручную * project_name.config - заявляется как обычный C файл, в котором можно записывать ваши макроопределения:#define VERSION "0.0.1" и т.п. * project_name.creator - собственно сам файл проекта, его открывать в Creator’е для загрузки проекта, сейчас никаких настроек больше не содержит. * в процессе работы появится файл project_name.creator.user в котором будут сохранены ваши параметры сборки, очистки проекта, информация о запускаемых модулях.

Теперь как это можно использовать? Покажу на примере своего небольшого Makefile:

PROJECT_NAME=empty-test
EXE = $(PROJECT_NAME)

CC = gcc
CXX = g++

CFLAGS   += -include $(PROJECT_NAME).config
CXXFLAGS += -include $(PROJECT_NAME).config

BIN_DIR = bin

SRC_CPP = ${shell cat $(PROJECT_NAME).files | grep '.cpp$$'}
SRC_C   = ${shell cat $(PROJECT_NAME).files | grep '.c$$'}

OBJ := $(SRC_CPP:.cpp=.o)
OBJ += $(SRC_C:.c=.o)

.PHONY : all clean

all: $(OBJ)
	$(CXX) -o $(BIN_DIR)/$(EXE) $(LDFLAGS) $(OBJ)

%.o : %.cpp
	$(CXX) -c $(LDFLAGS) $(CFLAGS) $(CXXFLAGS) $< -o $@

%.o : %.c
	$(CC) -c $(LDFLAGS) $(CFLAGS) $< -o $@

clean:
	rm -f $(OBJ) $(BIN_DIR)/$(EXE)

Что тут делается, во первых - автоматически получается список файлов проекта из project_name.files, далее, компилятором автоматически подключается project_name.config, и все объявленные там макросы будут доступны внутри кода.

Естественно тут нет и намека на множественные цели, но проект можно разбивать на подпроекты, их зависимости друг от друга задавать в Creator’е, а самих объединять в рабочие области (workspace). В общем и целом - ограничено все только вашей фантазией, и, по сути, данные действия превращают Qt Creator в продвинутый редактор кода, с базовыми функциями управления проектами, чего часто бывает достаточно.

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