Эффект черного ящика

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

use XML::Simple;
my $xs = XML::Simple->new();
my $ref = $xs->XMLin(‘test.xml’);

Однако даже такой простой кусок кода в разных системах реагировал по-разному на один и тот же исходный файл. Если в исходном файле XML встречались символы в кодировке utf8, скрипт мог свалиться на этапе разбора файла.

Выяснилось, что модуль XML::Simple сам по себе не занимается разбором XML, и парсинг происходит с помощью других доступных модулей. Если в системе установлен XML::SAX, то именно он будет использоваться по умолчанию, в противном случае для разбора будет применяться XML::Parser.

С XML::SAX тоже не все просто, он для разбора использует либо XML::SAX::PurePerl (что медленно и не всегда корректно работает), либо XML::SAX::Expat или XML::SAX::ExpatXS (если они установлены).

Так вот, чтобы XML::Simple смог корректно разобрать XML файл со строками в кодировке UTF-8, надо установить XML::SAX::Expat или XML::SAX::ExpatXS. Это совершенно не очевидно, и об этом можно забыть при переносе скриптов с сервера на сервер.

Апгрейд MySQL и переписывание запросов

Официальный логотип Mysql

Технически апгрейд базы MySQL несложен, но могут возникнуть не очевидные подводные камни. Например, если MySQL был 4-й версии, а после upgrade версия стала выше 5.0.11, то могут возникнуть проблемы с работой запросов, использующих LEFT JOIN.

Начиная с версии MySQL 5.0.12 запросы с JOIN обрабатываются по стандарту SQL:2003, поэтому такие запросы к базе придется переписать. Вот пример:

CREATE TABLE IF NOT EXISTS `t1` (
`id` int(10) unsigned NOT NULL auto_increment,
`type` enum('a','b') default NULL,
PRIMARY KEY (`id`),
KEY `type` (`type`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8;
INSERT INTO `t1` VALUES (1, 'a'), (2, 'a'), (3, 'b'), (4, 'a'), (5, 'b');

CREATE TABLE IF NOT EXISTS `t2` (
`t1_id` int(10) unsigned default NULL,
KEY `t1_id` (`t1_id`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8;
INSERT INTO `t2` VALUES (1), (1), (1), (2), (2);

CREATE TABLE IF NOT EXISTS `t3` (
`t1_id` int(10) unsigned default NULL,
KEY `t1_id` (`t1_id`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8;
INSERT INTO `t3` VALUES (1), (1), (2), (2), (3);

#Test 1
select t1.id
from t1, t2
left join t3 on t1.id = t3.t1_id and t1.type = 'a'
where t1.id = t2.t1_id
group by t1.id
#1054 - Unknown column 't1.id' in 'on clause'

#Test 2, swap the order of the conditions in "on"
select t1.id
from t1, t2
left join t3 on t1.type = 'a' and t1.id = t3.t1_id
where t1.id = t2.t1_id
group by t1.id
#1054 - Unknown column 't1.type' in 'on clause'

В MySQL 4.x запрос работает без ошибок, начиная с версии 5.0.12 запрос ругается на синтаксис. Если в эти запросы добавить скобок, все заработает:

select t1.id
from (t1, t2)
left join (t3) on (t1.id = t3.t1_id and t1.type = 'a')
where t1.id = t2.t1_id
group by t1.id

select t1.id
from (t1, t2)
left join (t3) on (t1.type = 'a' and t1.id = t3.t1_id)
where t1.id = t2.t1_id
group by t1.id

gedit: необходимый инструмент разработки

gedit logo

Любому программисту нужен удобный текстовый редактор, желательно настраиваемый под себя и с кучей функций. Раньше я пользовался в основном Kate, когда сидел под KDE; но сейчас времена изменились, и я открыл для себя gedit в GNOME.

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

Однако, я привык к другим горячим клавишам в других редакторах. В gedit отсутствует возможность их переназначить, но как оказалось, их можно поменять средствами GNOME. Например, плагин Отступ строк (Text Ident) по умолчанию работает на комбинациях клавиш Ctrl+T и Ctrl+Shift+T; но если для смены раскладки клавиатуры используется Ctrl+Shift, то вторая комбинация клавиш просто не будет работать. Поменять их можно, если залезть в настройки гнома (Центр управления -> Внешний вид, закладка Интерфейс, поставить галку Редактируемые ускорители меню или “Interface” -> “Editable menu shortcut keys” для англоязычной версии).

Включение режима редактирования горячих клавиш в gnome

После включения этой опции можно навести курсор мыши на интересующий пункт меню и нажать желаемые комбинации клавиш – все поменяется.

Еще одна неочевидная вещь, некоторые параметры gedit можно поменять только редактированием параметров gnome. Например, по умолчанию gedit в меню Файл будет показывать последние 4 открытых файла, что маловато. Если же запустить gconf-editor и отредактировать параметр gedit2->ui->recents, то можно задать их столько, сколько надо:

Включение режима редактирования горячих клавиш в gnome

ИМХО это один из самых удобных редакторов для разработчика

Как экспортировать данные в формате ZIP из php-скрипта

Все просто, можно использовать класс zipfile, который использует phpMyAdmin.
Выглядит это примерно так:


require_once("zip.lib.php");
$zip = new zipfile();
$zip->addFile($some_text, 'file.txt');
$handle = fopen("file.zip","w");
fwrite($handle,$zip->file());
fclose($handle);
?>

Все, в текущей директории файл file.txt будет упакован в file.zip. Код будет работать и в php4, и в php5. В php должна быть включена поддержка zlib.

Прикручиваем Paypal для оплаты

Одной из самых популярных платежных систем в буржунете является Paypal. Поэтому желающие прикрутить ее к своему сайту для оплаты товаров и услуг встречается очень часто на любом фрилансерском сайте, например, на RentACoder. Но так, как россиянам Paypal разрешает иметь только send only аккаунты, у нас эта платежная система не прижилась.

Сделать кнопку «Buy now» совсем не сложно, это простейшая форма вот такого вида:













Когда пользователь произведет оплату, он будет перенаправлен на URL, указанный в параметре return. После этого Пейпал сам отправит уведомление о поступившем платеже на notify_url, только эти данные подлежат тщательной проверке, поскольку любому злоумышленнику не составит особого труда сформировать POST-запрос на notify_url. Поэтому полученные данные надо перезапросить у paypal еще раз, добавив к запросу параметр cmd со значением _notify-validate. И если paypal подтвердит совершенный платеж, транзакцию можно считать завершенной.

Для сторонних разработчиков Paypal предусмотрел специальный сервис Paypal Sandbox, который позволяет тестировать весь процесс приема платежей, с одним небольшим ограничением. В paypal sandbox не работает IPN (Instant Payment Notification), когда уведомление о платеже отправляется на notify_url. Для отладки скриптов по обработке IPN в песочнице сделали отдельный инструмент Instant Payment Notification (IPN) simulator.

Парсинг поисковых систем

Yahoo! Logo

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

Однако, есть и дружелюбные поисковики, которые вполне официально разрешают себя парсить. Всего лишь надо зарегистрировать аккаунт на Yahoo, получить app id key и настроить свой парсер, благо API под него доступно там же на самых популярных языках программирования.

Никаких пауз между запросами, никакой подделки юзерагента или сбрасывания cookie делать не надо, все работает быстро и надежно. Выдачу можно забирать в XML, что значительно упрощает парсинг. Однако не стоит забывать, что в термсах Yahoo прописаны ограничения: не более 5000 запросов с одного IP. Как видите, ничто не запрещает использовать все доступные IP адреса для получения желаемого результата.

Особенности работы с RentACoder

Rent A Coder

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

Чтобы рядом с вашими бидами в системе засиял заветный значок Top Coder, надо выполнить следующие условия:

  • Надо выполнить не менее трех проектов на RentACoder
  • Набрать не менее 5000 очков
  • Иметь средний рейтинг не ниже 9 баллов
  • Не иметь ни одной плохо оцененной работы (рейтинг ниже 4 баллов)
  • После выполнения каждой работы заказчик и кодер имеют возможность оценить друг друга по десятибальной шкале, и этот рейтинг очень важен. Он влияет на расчет количества очков в общем зачете кодеров.

    Количество набранных очков рассчитывается по следующей схеме. Берется сумма законченного проекта и умножается на рейтинг. Т.е. 5000 очков можно получить выполнив проекты на сумму $500 с рейтингом 10, или выполнив проекты на сумму $1000 с рейтингом 5.

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

    Например, если заказчик выставил Bid Request и не выбрал ни одного кодера для его выполнения, то карма у заказчика портится. В общем, понятно почему, он же отнял драгоценное время многих кодеров на то, чтобы прочитать его запрос, и дать свой бид. Этот показатель называется Non-action Ratio, на него тоже стоит обращать внимание прежде, чем браться за bid request.

    Еще одна важная деталь. Очень часто заказчик сомневается в квалификации кодера, если он с ним ни разу не работал. Поэтому зачастую он просит демо-версию программы/скрипта/сервиса. Чтобы наглядно показать заказчику, что может ваш скрипт, вам понадобится свой хостинг. Shared хостинг сразу отпадает, поскольку хостер вас может вежливо попросить съехать, если ваш скрипт будет мешать другим клиентам. Dedicated server для демо целей слишком дорог, его лучше использовать под готовые серьезные проекты. Вам будет достаточно VDS от FirstVDS.ru, поскольку ничего другого сопостовимого по соотношению цена/качество вы не найдете.

    См. также по теме: RentACoder: удаленная работа для программиста

    RentACoder: удаленная работа для программиста

    Rent A Coder

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

    Обязательное условие — приличное владение английским языком, поскольку большинство заказчиков англоязычные. Регистрируемся здесь как кодер, настраиваем свое резюме, предпочтения, опыт работы и обязательно подписываемся на RSS сообщения с новыми бидами.

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

    Hello,

    We currently have a functioning school management website. We need a coder who will take all static text on the website and make it to be loaded from the database. We have a page in admin where we have ‘pages’, we need this to be extended to include all text on the entire website. Additionally, it should be possible to add new pages and they appear in a top menu.

    Further, there are two tiny changes we also need:

    1. We have a comment text field. It should be made bigger using CSS
    2. The list of ‘events’ displays on the frontpage. Currently about 10 are displayed. We need this list expanded to show 40

    Заказчик выбирает ценовую категорию для проекта (например, Project Type: Very Small Business Project: under $100(USD)) и может выставить максимальный приемлемый для себя бид (в данном случае Max Accepted Bid: $60.00 (USD)).

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

    Как правило, другие подробности работы заказчик описывает кодеру после того, как кодер принял бид. Заказчик переводит деньги в пользу RentACoder (escrow), и они после выполнения работы и принятия ее заказчиком, переходят в пользу кодера (за вычетом комиссии системы).

    Есть несколько тонкостей в работе. Если кодер в течение 24 часов после принятия бида заказчиком понимает, что по какой-то причине не сможет справиться с задачей, он обязан уведомить заказчика об этом и подать заявку на отказ от задачи. Это так называемый grace period, в течение которого кодер может безболезненно для себя и для заказчика отказаться от работы, не получив негативного рейтинга. Заказчику при этом возвращаются все переведенные в пользу RentACoder деньги.

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

    Если же закачик или кодер чем-то недовольны, все споры решаются независимым арбитражом.

    Комиссия системы составляет 15%, но не менее 3 USD. Выплаты производятся по тому графику, который выбирает кодер (устанавливается минимальная сумма для выплаты (например, $100), и выбирается график выплат — в начале следующего месяца либо по окончании двухнедельного срока).

    Выплаты производятся 4-мя способами:

  • перевод на банковский счет (этот способ годится и для россиян)
  • перевод Western Union
  • выплаты на карту Payoneer Prepaid Mastercard (если ее нет, они ее сделают и вышлют)
  • выплаты в Paypal (для граждан бывшего СССР этот способ оплаты не подойдет)
  • Система очень удобная, довольно много соотечественников уже работает с ней. Категории задач встречаются самые разные, от настройки серверов до разработки крупных порталов, от перевода статей на другие языки до SEO-задач.

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

    В общем, регистрируйтесь и пробуйте, наверняка сервис понравится и вам.

    Про Goolge AJAX API

    Google AJAX API

    Недавно открыл для себя Goolge AJAX API. Оказалось очень полезной штукой; например, можно легко и красиво построить список последних записей блога (смотрим в левый верхний угол), или встроить в страничку переводчик с поддержкой кучи языков. Еще большие чудеса можно вытворять с поиском в Google, в том числе и с поиском по картинкам. Но самое главное, что использование этого API практически не нагружает сервер, поскольку оно все построено на Javascript, выполняется на стороне клиента, а серверная часть скрипта выполняется где-то в Google. Это идеальное средство для украшательства страниц на не очень мощных и недорогих VDS.

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

    Золотое правило админа

    Типичный Одмин
    Если кто-то еще не знает, это правило звучит так:

    Работает – не трожь!

    Теперь собственно сама история. Когда-то у меня стояла OpenSUSE 10.3, в которой был Perl 5.8.8. С выходом OpenSUSE 11 я решил сделать апгрейд, который на первый взгляд прошел удачно. Все было хорошо, пока я не попробовал запустить несколько своих ботов.

    Выяснилось, что в 11-й версии Perl проапгрейдился до версии 5.8.10, и основные модули по работе тоже подвергались апгрейду. Все товарищи, кто прямо или косвенно пользовался модулем HTTP::Message скорее всего в логах увидили нечто подобное:

    HTTP::Message content not bytes

    и после этого долго ломали голову над своим кодом. А на самом деле бага в коде была на стороне мантайнера HTTP::Message, версия libwww-perl-5.810 оказалась глючной до безобразия. И самое интересное, эта версия оказалась в дистрибутиве OpenSUSE 11, поэтому совсем безболезненно апгрейд не прошел.

    Да, эта проблема решается апгрейдом libwww-perl до более свежей версии, что собственно я и сделал. Сейчас это libwww-perl-5.814, и пока багов в ней не заметил.

    Вот и думай после этого, а нужен ли был апгрейд, если он принес столько геморроя?