RSS новости
Играть онлайн в игры денди
 
Каталог / Разное
Ссылка на ленту:

crimsonpoint

мысли вслух

Загружается, подождите...

Gmail лежит

Gmail лежал сегодня несколько часов. Если-бы это был какой-нибудь mail.ru, то говорить было-бы не о чем. Но Гугл старательно продвигает концепцию интернет-офиса, многие специалисты говорят, что будущее именно за такой схемой - компьютер/браузер/онлайн-сервисы. И вот представьте, что перевели вы свою фирму с MSO на Гугловские сервисы а он как сегодня возьми и вырубись в разгар рабочего дня на несколько часов! И хрен что сделаешь.


Расширение фокса для Google Translate

Очередной полезный экстеншн для фаерфокса - Unofficial Google Translate Firefox extension.
Поскольку сайты на аглийском читать мне приходится часто, проблема словаря/перводчика постоянно вылезала. В качестве словаря меня вполне устраивает бесплатный StarDict а в качестве переводчика Google Translate (до этого долго пользовался альтавистовским баблфишем). Но лазить на сайт гугла за переводом каждый раз не очень удобно. Стал искать расширение для фокса. Перепробовал несколько, критерии отбора - удобный и маленький. Встречайте победителя - Unofficial Google Translate Firefox extension. Выделяете нужный текст и щелкаете на нем мышкой с нажатым альтом. Перевод появляется в новом слое (плохо, что слой не таскается мышкой). Направление перевода выбирается в меню по правой кнопте. Размер - 4,4к. Нереально удобно.
Здесь подправленная мною версия - убрал здоровенный футер, который автор (спасибо ему за работу) зачем-то вставлял в слой с переводом.


Продолжение

Собственно, второй скриптик от предыдущего поста, который добавит на страничке поиска русского гуггла ссылку "Искать в Яндексе":
// ==UserScript==
// @name google.ru
// @when Pages Match
// @includes http://www.google.ru/search*
// ==/UserScript==

var link = findbutton('input','type','submit');
var que = document.location.href;
que = que.substr(que.indexOf('q=')+2);
que = que.substr(0,que.indexOf('&'));
insert(after(link), '<a rel="nofollow" onclick="return opnfrm(this)" href="http://yandex.ru/yandsearch?text='+que+'">Search in Yandex</a> ');

function findbutton(tag,attr,val)
{
var b = 0;
var elements = document.getElementsByTagName(tag);
for (var i = 0; i < elements.length; i++) {
if( elements.item(i).getAttribute(attr) == val ) { b = elements.item(i); break; }
}
return b;
}


14:04 29.01.09

Два скрипта для Greasemonkey

Не знаю как вы, а я для поиска в Рунете использую два поисковика - Яндекс и Гугл. Начинаю, обычно, с яндекса, а если на первых страницах нужную информацию найти на удается, то переключаюсь на гугл. Это скриптик для Greasemonkey или Chikenfoot добавляет под строкой поиска Яндекса ссылку "Search in Google" с вашим запросом, просто жмешь ее и всё, не нужно открывать новый таб с гуглом, копировать запрос из яндекса в строку гугла, короче удобно:
// ==UserScript==
// @name yandex
// @when Pages Match
// @includes http://yandex.ru/yandsearch*
// ==/UserScript==
var link = findbutton('a','id','advanced');
var que = document.location.href;
que = que.substr(que.indexOf('text=')+5);
insert(after(link), '<a rel="nofollow" onclick="return opnfrm(this)" href="http://www.google.ru/search?q='+que+'&ie=utf-8&oe=utf-8&aq=t&rls=org.mozilla:en-US:official&client=firefox-a">Search in Google</a> ');

function findbutton(tag,attr,val)
{
var b = 0;
var elements = document.getElementsByTagName(tag);
for (var i = 0; i < elements.length; i++) {
if( elements.item(i).getAttribute(attr) == val ) b = elements.item(i);
}
return b;
}


Вассерман о кризисе

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


Корпоративная почта без настройки почтового сервера

Попросил тут меня знакомый настроить ему в оффисе корпоративную почту на его домене. Те кто с этим сталкивался знают, что это дело не на бутылку пива. Во-первых, нужен лицензионный MTA типа MS Exchange, MDaemon, Cerio Mail Server и т.п. который совсем не дешевый (ставить пиратку в конторе сейчас, значит рисковать). Во-вторых, нужно знать/уметь как этот софт настраивать (а вы знаете что такое SPF, gray listing, RBL, PTR lookup?) иначе или вас завалят спамом или вы будете терять письма. В принципе, софт может быть и бесплатным (Linux, BSD), но настраивать его еще сложнее, так что тоже вариант не простой.
Что-же делать - спросите вы, использовать Гугл Апликейшн - отвечу я. К стати, тех, кто хочет получить интерфейс gmail для почтового ящика на собственном домене это тоже касается.
Далее описываю по шагам как это делал я:


Реальный кризис

Пока у нас про кризис только общие разговоры и передачи по зомбиящику, в европе, похоже, все гораздо хуже. Недавно приехала знакомая из Испании, где жила и работала последние три года. Рассказывает, что там работы нет, мелкие и средние фирмешки закрываются десятками ежедневно, на испанские курорты никто не ездит, недвижимость упала в цене уже на 30 процентов и всеравно ее не покупают. Вобщем, полный алес капут. Ждем у нас того-же, а пока закупаемся солью и спичками.


Chikenfoot - убойный экстеншн для Firefox

Открыл для себя Chikenfoot. Это замечательное расширение позволяет записывать и выполнять в фоксе скрипты, автоматизируя рутинные операции, которые приходится выполнять на некоторых сайтах. Ну и кроме того полная поддержка функционала Greasemonkey и совместимость с гризиманковскими скриптами.
Вот пример простейшего скрипта:
wait(go("google.com"));
enter("crimsonpoint");
click("google search");
Все элементарно: открываем в текущей вкладке гугл, вводим в поле поиска "crimsonpoint" и жмем на кнопку поиск! Чувствуете какой потенциал для автоматизации и хуманоэмуляции!
У меня знакомый играет в текстовую РПГ на одном из российских сайтов. Я ему за пол-часа c помощию chikenfoot бота написал, который автоматом ресурсы копает и скилы прокачивает.
Для сеошников это вообще бомба - автоматизация регистрации, например, или добавления ссылок в каталоги/социалки и т.п. Вобщем, маст хэв однозначный.


модуль ParallelUserAgent

Неожиданно столкнулся с такой проблемой - в perl под виндой не так просто распараллелить выполнение программы, во всяком случае у меня не получилось. Форки работают не стабильно, т.е. тестовые примеры, когда в форке ни чего не делается выполняются нормально, а стоит там, к примеру создать объект lwp и все сразу вылетает. А триды у меня вообще не заработали - мой активстейтовский перл v5.6.1 говорит что не поддерживает Thread.pm. Наверное можно как-то это победить, но хотелось все сделать побыстрее, без курения манов и я полез на cpan и быстро нашел там то, что мне было нужно. Если ваша задача это получение данных из интернет то вам поможет ParallelUserAgent. Там все просто, вот например:
#!/usr/bin/perl
use strict;
use LWP::Parallel::UserAgent;

my $DEBUG=1;
my $ua = new LWP::Parallel::UserAgent;
my $req;
my $res;

$ua->in_order (0); # handle requests in order of registration
$ua->duplicates(0); # ignore duplicates
$ua->timeout (30); # in seconds
$ua->max_req (3); # max number of threads per victim site
$ua->max_hosts (3); # number of threads !!!!!!!
my %url = (
'http://crimsonpoint.blogspot.com/atom.xml'=>'atom.xml',
'http://crimsonpoint.blogspot.com/rss.xml'=>'rss2.xml',
'http://search.cpan.org/'=>'cpan.html'
);

$ua->initialize;
foreach my $i (keys %url) {
$req = new HTTP::Request GET => $i;
print "\tRegistering '".$req->url."'\n" if $DEBUG;
if ( $res = $ua->register ($req) ) {
print $res->error_as_HTML;
last;
}
}

my $entries = $ua->wait();
foreach (keys %$entries) {
$res = $entries->{$_}->response;
my $url = $res->request->url;

print "Answer for $url was \"", $res->code,": ", $res->message,"\"\n" if $DEBUG;

if( $res->is_success ) {
open(OUT, ">".$url{$url}) or die;
print OUT $res->content;
close(OUT);
}
}


16:26 29.10.08

еще доки

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


08:25 27.10.08

экономим трафик - прокси на perl

Для тех, кто выходит в интернет через gprs или просто живет не в Москве или Питере и не имеет дешевой безлимитки, короче для всех, кто вынужден экономить трафик.
До вчерашнего дня я выходил в интернет через связку HandyCache + CProxy. HandyCache - это кэширующий прокси, который к тому-же можно настроить на резку банеров или другого нежелательного контента, мне он экономит около 25 процентов трафика. CProxy - это программа-клиент чешского бесплатного сервиса позволяющего уменьшить трафик за счет сжатия (если вам это ни о чем не говорит, сходите сюда). CProxy эконимит мне еще около 70 процентов от того, что пропускает HandyCache.
Беда только в том, что бесплатные сервисы типа CProxy очень тормозные. Лучший вариант - поднять свой собственный жмущий прокси, например ziproxy. Но поскольку я искал быстрое решение и заморачиваться с компиляцией ziproxy мне не хотелось, я решил поискать тоже-самое на perl. Долго искать не пришлось, на первой-же позиции в гугле оказалось то что надо. Правда, сразу у меня скрипт вылетал с ошибкой, но после небольшой доработки все заработало. Теперь наслаждаюсь скоростью по сравнению с CProxy, даже на тормозном firstvds.ru.
Нужно будет еще установить степень сжатия на максимальную и сделать возможным доступ только с определенного списка IP.
#!/usr/bin/perl -Tw
use strict;
$ENV{PATH} = join ":", qw(/usr/ucb /bin /usr/bin);
$|++;

my $VERSION_ID = q$Id: proxy,v 1.21 1998/xx/xx xx:xx:xx merlyn Exp $;
my $VERSION = (qw$Revision: 1.21 $ )[-1];

## Copyright (c) 1996, 1998 by Randal L. Schwartz
## This program is free software; you can redistribute it
## and/or modify it under the same terms as Perl itself.

### debug management
sub prefix {
my $now = localtime;

join "", map { "[$now] [${$}] $_\n" } split /\n/, join "", @_;
}
$SIG{__WARN__} = sub { warn prefix @_ };
$SIG{__DIE__} = sub { die prefix @_ };
&setup_signals();

### logging flags
my $LOG_PROC = 0; # begin/end of processes
my $LOG_TRAN = 0; # begin/end of each transaction
my $LOG_REQ_HEAD = 0; # detailed header of each request
my $LOG_REQ_BODY = 0; # header and body of each request
my $LOG_RES_HEAD = 0; # detailed header of each response
my $LOG_RES_BODY = 0; # header and body of each response

### configuration
my $HOST = 'localhost';
my $PORT = 8080; # pick next available user-port
my $SLAVE_COUNT = 8; # how many slaves to fork
my $MAX_PER_SLAVE = 20; # how many transactions per slave

### main
warn("running version ", $VERSION);

&main();
exit 0;

### subs
sub main { # return void
use HTTP::Daemon;
my %kids;

my $master = HTTP::Daemon->new(LocalPort => $PORT, LocalAddr => $HOST)
or die "Cannot create master: $!";
warn("master is ", $master->url);
## fork the right number of children
for (1..$SLAVE_COUNT) {
$kids{&fork_a_slave($master)} = "slave";
}
{ # forever:
my $pid = wait;
my $was = delete ($kids{$pid}) || "?unknown?";
warn("child $pid ($was) terminated status $?") if $LOG_PROC;
if ($was eq "slave") { # oops, lost a slave
sleep 1; # don't replace it right away (avoid thrash)
$kids{&fork_a_slave($master)} = "slave";
}
} continue { redo }; # semicolon for cperl-mode
}

sub setup_signals { # return void

setpgrp; # I *am* the leader
$SIG{HUP} = $SIG{INT} = $SIG{TERM} = sub {
my $sig = shift;
$SIG{$sig} = 'IGNORE';
kill $sig, 0; # death to all-comers
die "killed by $sig";
};
}

sub fork_a_slave { # return int (pid)
my $master = shift; # HTTP::Daemon

my $pid;
defined ($pid = fork) or die "Cannot fork: $!";
&child_does($master) unless $pid;
$pid;
}

sub child_does { # return void
my $master = shift; # HTTP::Daemon

my $did = 0; # processed count

warn("child started") if $LOG_PROC;
{
flock($master, 2); # LOCK_EX
warn("child has lock") if $LOG_TRAN;
my $slave = $master->accept or die "accept: $!";
warn("child releasing lock") if $LOG_TRAN;
flock($master, 8); # LOCK_UN
my @start_times = (times, time);
$slave->autoflush(1);
warn("connect from ", $slave->peerhost) if $LOG_TRAN;
&handle_one_connection($slave); # closes $slave at right time
if ($LOG_TRAN) {
my @finish_times = (times, time);
for (@finish_times) {
$_ -= shift @start_times; # crude, but effective
}
warn(sprintf "times: %.2f %.2f %.2f %.2f %d\n", @finish_times);
}

} continue { redo if ++$did < $MAX_PER_SLAVE };
warn("child terminating") if $LOG_PROC;
exit 0;
}

sub handle_one_connection { # return void
use HTTP::Request;
my $handle = shift; # HTTP::Daemon::ClientConn

my $request = $handle->get_request;
defined($request) or die "bad request"; # XXX

my $response = &fetch_request($request);
warn("response: <<<\n", $response->headers_as_string, "\n>>>")
if $LOG_RES_HEAD and not $LOG_RES_BODY;
warn("response: <<<\n", $response->as_string, "\n>>>")
if $LOG_RES_BODY;
$handle->send_response($response);
close $handle;
}

sub fetch_request { # return HTTP::Response
use HTTP::Response;
my $request = shift; # HTTP::Request

## XXXX needs policy here
my $url = $request->url;
warn("processing url is $url") if $LOG_TRAN;
&fetch_validated_request($request);
}

BEGIN { # local static block
my $agent; # LWP::UserAgent

sub fetch_validated_request { # return HTTP::Response
my $request = shift; # HTTP::Request

$agent ||= do {
use LWP::UserAgent;
my $agent = LWP::UserAgent->new;
$agent->agent("Mozilla/5.0");
$agent->env_proxy;
$agent;
};

$request->header('accept-encoding'=>'gzip,deflate');

warn("fetch: <<<\n", $request->headers_as_string, "\n>>>")
if $LOG_REQ_HEAD and not $LOG_REQ_BODY;
warn("fetch: <<<\n", $request->as_string, "\n>>>")
if $LOG_REQ_BODY;

my $response = $agent->simple_request($request);

my $content = $response->content;
if ($response->is_success and
$response->content_type =~ /(text|plain|html|javascript)/ and
not ($response->content_encoding || "") =~ /\S/ and
length($content)>100 and
($request->header("accept-encoding") || "") =~ /gzip/) {
require Compress::Zlib;
my $new_content = Compress::Zlib::memGzip($content);
if (defined $new_content) {
$response->content($new_content);
$response->content_length(length $new_content);
$response->content_encoding("gzip");
warn("gzipping content from ".
(length $content)." to ".
(length $new_content)) if $LOG_TRAN;
}
}

$response;
}
}


17:18 25.10.08

появился релиз FireFox 3.0

На сайте мозиллы официально представлен релиз второй версии mozilla firefox. Но я пожалуй подожду версию 3.1, заодно пока и расширения все под новую версию переделают.
А вот, проверенный временем список расширений, которые у меня установлены:


регулярные выражения в perl

Доки по regexp на русском: хорошая статья по регулярным выражениям в perl с примерами, вторая то-же про регэкспы покороче, как справочник. Все в формате pdf. Для тех, кто не в курсе - в perl всего штук пять функций для работы со строками, между тем это один из самых мощных языков по обработке текста. А все потому, что встроены регулярные выражения. Не просто доступны через библиотечные функции, а встроенны и доведены до совершенства. Пример красоты и мощи - узнал недавно про модификатор "e", который позволяет использовать в качестве подстановки исполняемый код. Вот как можно в тексте заменить каждое третье слово left на right:
$num = 0;
$text =~ s/(left).*?/if((++$num%3)== 0){'right'}else{$1}/igex;
Вот за это я люблю perl.


Функциональное программирование

Попалась тут переводная статья, объясняющая принципы функционального программирования на примере Питона. Всем кто занимается программированием профессионально и нет, и не в курсе что такое FP советую зачитать - Функциональное программирование на языке Python. Статья написана доступно и я думаю будет полезна даже тем кто Питон не использует, как я, например. Не согласен только с двумя вещами:

  1. Автор обидел мой любимый perl, записав его в компанию языков лишенных возможности писать в стиле FP. На самом деле в perl есть все что он описывает в статье, а в рекомендациях по хорошему стилю программирования на perl всячески рекомендуют этим пользоваться, там где уместно. Большинство так и делает - 99 процентов программеров на perl напишут:
    open(IN,"<filename") or die;
    вместо
    unless(open(IN,"<filename")) {  die; }
  2. Помоему, FP использовать нужно только там, где это делает код короче и читабельней. Злоупотреблять им явно не стоит. А то что функциональный подход стоит использовать для уменьшения количества ошибок в программе, это просто бред. Сравните примеры из статьи.
    императивный код:
    xs = (1,2,3,4)
    ys = (10,15,3,22)
    bigmuls = []
    #...прочий код...
    for x in xs:
        for y in ys:
            #...прочий код...
            if x*y > 25:
                bigmuls.append((x,y))
                #...прочий код...
    #...прочий код...
    print bigmuls

    функциональный код:
    bigmuls = lambda xs,ys: filter(lambda (x,y):x*y > 25, combine(xs,ys))
    combine = lambda xs,ys: map(None, xs*len(ys), dupelms(ys,len(xs)))
    dupelms = lambda lst,n: reduce(lambda s,t:s+t, map(lambda l,n=n: [l]*n, lst))
    print bigmuls((1,2,3,4),(10,15,3,22))

    Просто очевидно какой вариант читабельней, проще пишется и проще отлаживается.


купил ноутбук

Всем кто задумался о покупке дешевого ноутбука для серфинга, печати и программирования (не gamedev) рекомендую - HP nx6310 модель EY503ES. Характеристики такие - CPU Intel CM 410 (1,46GHz, 1MB L2 cash, 533MHz FSB), 15.0 XGA (1024x768), RAM 256MB DDR2 533MHz, HDD 60GB 5400rpm, DVD+/-RW, 56K Modem, 802.11b/g, OS Free DOS. Цена в Москве дешевле 700$. Поясняю - новый целик, пишущий DVD, WiFi, приличная матрица и все это дешевле 20 тысяч. Работать за ним очень приятно - не шумит, не греется, раскладка клавиатуры приближена к десктопной, ни где не скрипит, ни чего не болтается. Кроме того это все-таки HP, это вам не Acer и тем более не Rover и iRu. Минус - винды нет, нужно ставить самому, причем оказалось там есть кое-какие тонкости; диска с драйверами тоже нет. Пришлось немножко погуглить, и за вечер я все настроил.
ИМХО лучший по соотношению цена/качество бюджетный ноутбук. Вообще-то покупал я его жене, но похоже работать за ним буду сам :)


пятница, тринадцатое

В прошлую пятницу, тринадцатого числа случилась неприятность. Сам не знаю зачем, я выгрузил фаервол (Outpost 2.0), чего никогда не делаю, потом про это благополучно забыл и вышел в интернет. Через полчаса я заметил что все как-то странно подтормаживает, и на модеме не гаснет лампочка SEND... Короче, за пол-часа в интернете я нацеплял штук 10 троянов и фиг его знает чего они успели за это время у меня стянуть. Вот тут я порадовался, что месяца два назад поставил TrueCrypt и перенес на криптованный диск базу с паролями от почтовых ящиков, аськи, вебмани, хостинга и т.п. А вот Касперский разочаровал - с только-что обновленными базами и высоким уровнем безопасности всех троянов он отловить не смог, остались два, запустившиеся как виндовые сервисы - дочищал за ним руками.
Выводы:

  1. Agnitum Outpost Firewall - вполне надежная стенка, хотя во всех обзорах по надежности стоит где-то в середине списка.
  2. Антивирус Касперского нужно или менять на что-то другое (многие хвалят NOD32), или ставить кроме KAV еще что-то типа Лавасофт Адваре.
  3. Как бы хорошо ваш комп не был защищен, всю приватную информацию нужно обязательно держать в криптованном виде. Здесь лучшее и к тому-же бесплантое решение - TrueCrypt.
  4. в пятницу тринадцатого не пользуйтесь компьютером :)


test

test