← На главную

Мини заметки – выпуск 10

Темы выпуска: сборка Pastexen из исходников, процедурное представление данных в Haskell, автоматическая загрузка картинок на radikal.ru, установка Adobe Air под Ubuntu x64 и не только. Предыдущие выпуски: девятый, восьмой, седьмой, шестой.

1. Собираем Pastexen под Linux и FreeBSD

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

Сборка и установка в Linux:

sudo aptitude install g++ libqt4-dev

Из ветки sid:

sudo aptitude install libqxt-dev

Далее:

git clone git://github.com/bakwc/Pastexen.git cd Pastexen make sudo checkinstall

Установка и сборка во FreeBSD:

sudo portmaster -d devel/qt4 devel/qmake4 ln -s /usr/local/bin/qmake-qt4 /usr/local/bin/qmake wget http://dev.libqxt.org/libqxt/get/v0.6.2.tar.gz \ -O libqxt-0.6.2.tar.gz tar -xvzf libqxt-0.6.2.tar.gz cd libqxt-libqxt-dadc327c2a6a

Заменяем в configure /bin/bash на /usr/bin/env bash, после чего говорим:

./configure gmake sudo gmake install

Затем собираем Pastexen по аналогии с тем, как это делается в Linux, только вместо make используем gmake.

2. Скрипт-уведомлялка о разрядке батареи

После того, как однажды мой Toshiba Portege Z930-DKS вырубился, даже на намекнув на то, что его батарея разряжается, я набросал вот такой скрипт:

#!/usr/bin/env perl use strict; use warnings; my $warnings = 0; while(1) { my $acpi_info = `acpi -b`; if($acpi_info =~ /, (\d+)%, (\S+) remaining/) { my $percent = $1; my $time = $2; if($percent < 100 && $warnings <= 0) { show_warning($percent, $time); $warnings = 1; } elsif($percent < 50 && $warnings <= 1) { show_warning($percent, $time); $warnings = 2; } elsif($percent < 25 && $warnings <= 2) { show_warning($percent, $time); $warnings = 3; } elsif($percent < 10 && $warnings <= 3) { show_warning($percent, $time); $warnings = 4; } } else { $warnings = 0; } sleep 60; } sub show_warning { my ($percent, $time) = @_; my $msg = "Battery discharging, $percent\%, $time remaining"; $msg =~ s/'/\'/g; system("zenity --notification --text='$msg' --window-icon=warning ⏎ --timeout=1 &"); }

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

3. Установка Adobe Air под Ubuntu 12.10 x64

Не спрашивайте, зачем мне это понадобилось.

wget http://dl.dropbox.com/u/19923518/eaxme/2013/getlibs-all.deb sudo dpkg -i getlibs-all.deb sudo aptitude install libhal-storage1 libgnome-keyring0 lib32nss-mdns sudo getlibs -l libhal-storage.so.1 sudo getlibs -l libgnome-keyring.so.0.2.0

На вопрос об установке 100500 библиотек для i386 отвечаем утвердительно.

Затем говорим:

sudo ln -s /usr/lib/i386-linux-gnu/libgnome-keyring.so.0 \ /usr/lib/libgnome-keyring.so.0 wget airdownload.adobe.com/air/lin/download/2.6/AdobeAIRInstaller.bin chmod u+x AdobeAIRInstaller.bin sudo ./AdobeAIRInstaller.bin

Сами приложения устанавливаются через /usr/bin/Adobe\ AIR\ Application\ Installer. А вот так: /opt/Prog/bin/Prog запускаются установленные приложения. На самом деле, как мне кажется, куда более простой и правильный способ использования Adobe Air в Ubuntu – это поставить винду под VirtualBox.

4. Простой способ сделать port forwarding

На CPAN для этого есть специальный скрипт:

sudo cpanm tcpforward tcpforward -l localhost:1080 -c eax.me:80

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

5. Скрипт для прогрева кэша WordPress

В плагине WP-SuperCache есть кнопка для прогрева кэша, но она аффектит только посты. В отличие от следующего скрипта:

#!/usr/bin/env perl use strict; use warnings; use LWP::UserAgent; my $home_url = shift; die "Usage: $0 http://example.ru\n" unless $home_url && $home_url =~ m{^http://.*[^/]$}i; my $ua = LWP::UserAgent->new( max_redirect => 0, agent => 'update-cache.pl' ); my @queue = ('/'); my %from; my %errors; my $parsed_urls = 0; my $total_urls = 1; while(@queue) { my $url = shift @queue; $parsed_urls++; print "[$parsed_urls/$total_urls] $url... "; my $res = $ua->get($home_url.$url); if($res->is_success) { my $content = $res->decoded_content; my $urls_count = '0'; while($content =~ m#href=['"]$home_url(/[\w/-]+)['\"]#gio) { if(defined $from{$1}) { push @{$from{$1}}, $url if @{$from{$1}} < 16; next; } else { push @queue, $1; $from{$1} = [$url]; } $urls_count++; $total_urls++; } print "OK, $urls_count new url(s)\n"; } else { print "ERROR: ".$res->status_line."\n"; $errors{$url} = $res->status_line; } } if(keys %errors) { print "--- ERRORS ---\n"; while (my ($url, $err) = each %errors) { print join("\n", @{$from{$url}})." => $url: $err\n"; } }

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

6. Как подписаться на Google-группу, не имея Google-аккаунта

Нужно отправить письмо на [название группы]+subscribe@googlegroups.com, дождаться ответа и следовать дальнейшим инструкциям. Например, чтобы подписаться на группу erlang-russian, нужно отправить электронное письмо на erlang-russian+subscribe@googlegroups.com. А чтобы отписаться, соответственно, на erlang-russian+unsubscribe@googlegroups.com.

7. Процедурное представление данных

Этот прием я нашел в SICP:

makePair a b = (\p -> p a b) getFst x = x (\a b -> a) getSnd x = x (\a b -> b)

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

8. Ошибка «no db_java-5.1 in java.library.path»

Эта ошибка означает, что Java не может найти библиотеки libdb-5.1.so и libdb_java-5.1.so. Проблема решается следующим образом:

sudo ln -s /usr/lib/x86_64-linux-gnu/libdb-5.1.so \ /usr/lib/libdb-5.1.so sudo ln -s /usr/lib/x86_64-linux-gnu/libdb_java-5.1.so \ /usr/lib/libdb_java-5.1.so

Теперь все должно работать!

9. Очень простой content filter для WordPress

Добавляем в functions.php следующий код:

function the_content_filter($content) { $content = preg_replace('#http://eax\\.me/files/#', ⏎ 'http://dl.dropbox.com/u/19923518/eaxme/files/', $content); return $content; } add_filter('the_content', 'the_content_filter');

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

10. Скрипт для загрузки картинок на radikal.ru

Как бы пополняю свою коллекцию аплоадеров на разные хостинги картинок:

#!/usr/bin/env perl # radikal-uplaod.pl v 0.1 # (c) Alexandr Alexeev 2013 | http://eax.me/ use strict; use warnings; use LWP::UserAgent; use HTTP::Cookies; my $file = $ARGV[0] or die "Usage: $0 <fname>\n"; my $ua = LWP::UserAgent->new(agent => 'radikal-upload.pl'); my $cookies = HTTP::Cookies->new(); $ua->cookie_jar($cookies); my $res = $ua->post( 'http://www.radikal.ru/action.aspx', [ upload => 'yes', GEO_POINT_ID => '', URLF => '', M => '640', JQ => '85', IM => '7', VM => '180', R => '0', V => '', X => '', FS => '', F => [$file], ], Content_Type => 'form-data', ); if($res->is_success && $res->decoded_content =~ m'<a href="(http://\w+\d\.radikal\.ru/⏎ [^"]+)" target="_blank">') { print "[+] OK\n"; print "Image:\t$1\n"; my ($sid) = $cookies->as_string =~ m!(SID=[0-9a-f]+)!; my ($del_url) = $res->decoded_content =~ m!(action\.aspx\?⏎ id=[0-9a-f]+&delete=yes)!; print "Delete:\twget --header='Cookie: $sid' ⏎ 'http://www.radikal.ru/$del_url' -O /dev/null\n"; } else { print "[-] Failed\n"; }

Аналогичный скрипт для ImageShack вы найдете в 7-м выпуске мини-заметок.

Дополнение: Мини-заметки – выпуск 11