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

27 февраля 2013

Темы выпуска: сборка 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 A 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

Метки: .


Вы можете прислать свой комментарий мне на почту, или воспользоваться комментариями в Telegram-группе.