2010/08/02

Базовая авторизация, винды, пых и соломинка, или Немного программерского трипа из ничего

...Волна и камень,
Стихи и проза, лед и пламень
Не столь различны меж собой.
(c) Наше почти что всё

Базовая авторизация сцуко хитрая. Вот казалось бы, принципы и технологии отработаны не один десяток лет, ан нет, и тут не без прикола.
Всем известен такой (или примерно такой) код:

if ( isset($_SERVER['PHP_AUTH_USER']) && isset($_SERVER['PHP_AUTH_PW']) )
{
//здесь работаем
} else {
//здесь авторизуем
header('WWW-Authenticate: Basic realm="pedo mellon a minno"');
header('HTTP/1.1 401 Unauthorized');
print 'bad idea';
die;
}
и как он должен работать, тоже все представляют: появляется окошечко с надписью, туда вбиваем логин\пароль, жмём ентер, опач выставляет заголовки $_SERVER['PHP_AUTH_USER'] && $_SERVER['PHP_AUTH_PW'], мы их ловим в коде, всё ништяк.
Не тут-то было.

Пункт "а"; то бишь "о" - Опера.
Опера - как конфета, как старая карамелька: сверху красивая, внутри пустая. С ней много и очень много приколов. К примеру, пара: Опера не отправляет заголовки авторизации и вышеприведённый код сразу переходит на строку print 'bad idea'; Точнее будет сказать, не отправляет с первого раза - жмём F5 и ВНЕЗАПНО получаем авторизованного юзера.
Вторая забавность даже не в том, что "дебагер"-дом-инспектор (ну, как файрбаг в фф) работает через сторонний сервер (да-да, о_О нет коннекта - нет инспекта), а в том, как он визуально организован. Можно перемещаться стрелочками, но нельзя стрелочками же раскрыть ветку; также не работают комбинации Ctrl+Arrow, Ctrl+PgUp\PgDn, Ctrl +\-... Короче, сумрачный оперный проектировщик интерфейсов навесил тоггле-коллапсинг на Enter. Поувольнял бы.

Пункт "х"; Хромой и клоны, возвращаемся к авторизации.
Не буду долго томить, скажу сразу. Заголовок header('HTTP/1.1 401 Unauthorized'); хрому не указ. Не то чтоб совсем... Но как-то неадекватно он себя ведёт: не каждый раз изволит показать модальное окно, отслеживая по каким-то своим хитрым алгоритмам активность юзера и отправляя заголовки минуя ввод логина.
Не верите - проверяйте сами. До меня это дошло за много, много часов.

А глубинах этого сурового трипа поджидала внутренняя малая игра: "переставь мускуль на винде" ;)
Началась она с того, что php5.3 не увидел mysql5.1. Одинаковый mysql_connect('localhost','login','password'); на пыхе 5.2 (оставил-таки себе ;) коннектит, а на 5.3 даёт
Warning: mysql_connect(): [2002] Попытка установить соединение была безуспешной, т.к. от другого компьютера за требуемое время не получен нужный отклик, или было разорвано уже установленное соединение из-за неверного отклика уже подключенного компьютера
и вылетает по таймауту в 30 секунд. Вот здесь скорость отъезда крыши начала приближаться к световой и воображаемые друзья начали казаться не такими уж и воображаемыми. Пока они сейшенили, я решил немного вздремнуть.

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

Секретный секрет заключался в том, что пых5.3 не резолвит localhost. Ибо в замечательной системе Windows Vista в известном файле hosts строка localhost 127.0.0.1 закоменчена. Ну вы поняли. Спасибо Безумному доктору http://drcreazy.com/art/8


Ах да, зачем мне всё это было надо? После беседы с Коджи я так восхитился ;) их движком, что решил написать своё поделие. Ещё один кусок набора веб-инструментов называется "Web Mysql Console". Смотреть здесь http://code.google.com/p/angry/source/browse/#svn/tags/WebMysqlConsole

Такой вот получился трип вместо нескольких часов простого кода

2010/05/20

твитер такой твитер

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

во-вторых, была подмечена одна хитрая методика и другая подтверждена. вариант а) няшка, №следуй, №следуй, няшка, реф, твит, няшка, твит, реф, твит, сиськи, твите.ру х5, няшка, твит, нувыпонели?.. ПРОФИТ!!1111
вариант б) больше похож на какой-то эксперимент: твитится провокационная фраза с персональным тегом в надежде на ретвит, вероятно; потом очень просто отыскать и подфоловить всех по списку - потенциальные живые люди.
социнженерия инэкшн, хуле. пользуйтесь, дарю =;)

в третьих, наш дорогой ЧПУ завёл себе виртуала, который однозначно робот, у него вся выдача состоит из блоготопа йандыкса. что интересно: без первичного фоловинга семь фоловеров, из которых пять - знакомые авки, а двое - тысяник и 30-титысячник - отлипли сами. две седьмых = 28.6% - примерно так я себе и представлял долю человеческого населения этих ваших интернетов.

у меня пока всё... оставайтесь с нами

#twitterday! RT pls :)

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

upd 21/05 14:45 только что видел линк на этот пост в ленте виртуала, которая чуть менее, чем полностью... ну вы помните

2010/05/16

Жизнь и приключения ЧПУ в картинках

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


Первая прекрасная картинка показывает, что число фоловеров и число френдов (взаимных фоловеров) неуклонно и стабильно растёт. "Скачок" был сделан ручным фоловингом - полчаса нажимал кнопу.

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

Третья и четвёртая картинка - абсолютное суточное число фоловеров и директов, соответственно. Странно, что они имеют разный вид, потому что каждого нового фоловера робот фоловит в ответ и отсылает ему приветственный дм. Выяснять лень, будем считать это глюком.

Из представлено материала делаем простые выводы:
  • роботы фоловинга работают стабильно
  • большинству твипла абсолютно пофигу, кто их фоловит
  • твипл в массе не читает ленту
  • количество нечеловеческих тви-аккаунтов over9000
  • относительное количества разума в интернетах неуклонно сокращается
  • в протоплазме можно обнаружить роботов, овощи, смошников и хомячков.
Let's PANIC?!!!11111

ps: К.О. заявляет, что @altosz, который первый отретвитил про этот пост, тоже пользуется ботами и зафоловил ЧПУ примерно до 50-го твита. так-то!

2010/05/12

Установка Disqus на блогспот

  1. регистрируемся сразу с сайтом или другой вариант http://disqus.com/profile/
  2. все самые вкусные опции типа Akismet и FB через API-key (взял ВП-кей у ЧПУ)
  3. знакомое по установке AddThis предложение отредактировать шаблоны; но услужливый дискас предлагает всё сам заапдейтить и пропатчить
  4. варнинг! не забываем переключить радиобатон на Use Disqus Comments on all blog entries. Any existing comments can be imported in чтобы подключились старые каменты
  5. на следующей странице цапаем пропатчаный шаблон и копипастим на блогспот
  6. внимание ещё раз! дискас предупреждает, чтобы в блогспоте галочка "расширенные параметры шаблона для виджетов" была установлена! (она справа над текстареа)
  7. и попробуем сразу импортнуть каменты...
  8. Keep comments on Disqus synced with Blogger, кажется, включает обратную синхронизацию дискаса в блогер, но у меня не включилась сразу
  9. смотрим, что получилось
  10. ничего не получилось, приостановлено на обед
  11. Viola! мы сделали это! Ничего сложного, просто не надо слушать вредных советов =;) со сторонних сайтов, не надо изменять настройки комментариев, как советует Blogohelp.
Теперь у меня появилась уютненькая формочка для каментов :)

2010/05/08

Человеко-Подобный Уникум

Однажды - мне всегда нравились такие начала: "однажды...", хоть и было это с неделю назад - ранней майской ночью под щебетание зануды-соловья мне подумалось, что интернет стал настолько хитроввёрнутой штукой, что отличить анонимуса от %юзернейм% стало практически невозможно.

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

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

ИД ЧПУ пока не скажу =;)
Разве только тем, кто чем поможет. Помощь нужна, по большей части, в плане информации по автоматизации процессов: есть сервисы репостинга бложиков или самому велосипедить скрипт, как лучше настроить интеграцию соцсервисов и тому подобные штуки; и с фотошопом, конечно - надо бы некоторое количество непротиворечивых фоточек класса "я и моя кошка на фоне ковра" только без кошки и без ковра.

Жизнь и творчество HAL ;) будут освещаться здесь и в твитере по тегу #XGE. RT plz!

зы: со вчерашнего поста можно пользоваться кнопой под текстом для массшаринга

2010/05/07

Про социальные кнопки

Все делают вид, что интернеты социализируются, становятся ближе к людям, так сказать, и придумывают разного рода кнопочки, штучечки, ИДешечки... Так вот и у этого бложека объявился второй и, надеюсь, постоянный читатель из твитора @zkonstantin. Который и попенял мне, что мол, жаль нет ружья красивой кнопки "затвитить". Так вот, теперь такая кнопа есть! (см. внизу поста)

Из всех рассмотренных вариантов я выбрал AddThis только потому, что у них есть подробная инструкция "как поставить кнопу на ваш уютненький" с картинками; смотреть здесь http://www.addthis.com/help/blogger. А кто посоветует дефолтные варианты, тому спасибо.

В общем, мы к вам ближе, оставайтесь с нами =;)

зы: чем на самом деле занимаются интернеты, мы вам пока не скажем ;)
а себя называем на "вы" исключительно от мании величия

2010/04/18

Немного о ботах и репах дебиана

Мы строили-строили и наконец построили! :) (Ц)все знают

Вштырилось мне как-то написать твиттер-бота для игры "Мафия". И я его написал, почти. А потом ещё одного...
Как всем известно, программист - существо ленивое, так и мне стало лень копипастить пачку свич-кейсов из одного бота в другого. Пришлось рефакторить (переписывать, да), выделять сущности, строить модель... И получился класс Bot, который реагирует на поток строковых команд. Так как он вызывает колбеки с параметрами, то оказалось, что его можно использовать как роутер, или интерпретатор, или как вам фантазия подскажет ;)

В качестве небольшой хаутушки кусок кода из погодного бота @WeaTwi
$bot = new WeaTwiBot($config['username'],$config['password']);

$bot->addBatch(
array(
Bot::COMMAND => '~!info|!help|!about~i'
,Bot::ACTION => array($bot,'updateStatus')
,Bot::PARAMETER => array('%s %s',
'~^(@[a-z0-9_]+):~i'=>1,
$bot->URL_INFO
)
,Bot::LAST => 1
)
);
$bot->addBatch(
array(
Bot::COMMAND => '~.+~'
,Bot::ACTION => array($bot,'getWeather')
,Bot::PARAMETER => array('~^@[a-z0-9_]+:(.+)~i'=>0)
,Bot::LAST => 1
)
);

$s = array();
foreach ($bot->getLastMentions() as $m)
$s[] = '@'.$m->user->screen_name.':'.preg_replace('~@'.$config['username'].'~i','',$m->text);

$bot->setQueue($s);
$bot->run();
die;
Вот так и живём =:)

Ах да, про дебиан и пхп. Оказывается, в репах дебиана нет такого вкусного php5.3! Как подсказывает гугл и http://www.openkazan.info/node/3515 обновиться можно из http://packages.dotdeb.org
$ nano /etc/apt/sources.list
...
deb http://packages.dotdeb.org stable all
deb-src http://packages.dotdeb.org stable all
#
deb http://php53.dotdeb.org stable all
deb-src http://php53.dotdeb.org stable all
...
$ apt-get update
$ apt-get install php5
, о чём продвинутый юзер и так знает

Оставайтесь с нами, фоловьте ботов ;)
А кто предложит лучший алгоритм для мафиозного бота, тому плюшка

ps: чем бы таким код нормально отформатировать?..

2010/03/03

Twitter и его OAuth

Все, кто ещё не уверен, что OAuth придумали безумные люди, посмотрите на процесс авторизации

Это из самого полного мана http://oauth.net/core/1.0/#anchor9

Вспомнив успех Zend для OpenID, снова обратился к нему. На этом месте должна была быть некая бодрая шутка, но её не будет, так как слова закончились через несколько часов попыток извлечь пользу. Заглянув на http://framework.zend.com/manual/1.10/en/zend.oauth.html можете сами убедиться в полной бесполезности зенда в вопросах хитрой авторизации в твиттере через OAuth. Короче, оно тупо не работает.

Когда ничего не помогает, можно уже наконец читать инструкцию. Загуглив тему, Вы точно так же не обнаружите того, чего не обнаружил я: нормальных хавтушек системы "как установить эту хрень?!"
Зато гугл доставил собственный ман http://code.google.com/intl/ru/apis/accounts/docs/OAuth.html. Блеснул слабый луч надежды.
Но блестел он не долго. Почему? Потому что надо понимать, как именно работает OAuth. Это не "пара логин\пароль". Аутентификация происходит после получения авторизационных ключей, после обмена на них ключей доступа, которые можно получить после предоставления уникальной идентификационной пары. Кто хочет окончательно запутаться, сверху есть замечательная картинка.

Теперь ещё раз и вдумчиво. Немного терминологии:

  • application - приложение, втч веб-ресурс, которое пользуется услугами провайдера
  • provider - сервер авторизации
  • consumer - потребитель услуги, юзер, которого приложение авторизует через провайдера
  • tokens - пары ключ\секретный ключ, гугл зовёт их маркерами
Процесс кажется поначалу весьма простым. Запутанным, но не особенно сложным: ключи запроса, ключи доступа, сигнатура, доступ, оппа! Берём простейший класс-обёртку cURL, за полчаса ваяем шедевр и обламываемся на ответе: "Failed to validate oauth signature and token". Что это? Ищем ключевое слово сигнатура и обламываемся ешё раз: сигнатура вычисляется по RSA-SHA1, но из чего - науке неизвестно; по другим источникам она составляется перекомпоновкой из пары токенов доступа, но их тоже надо ещё получить, а у нас ключи запроса не принимаются. Короче, это тоже тупиковая ветвь.

Решаем обратиться к первоисточникам, то бишь мануалу самого твиттера. Это мрак. Родной ман твиттера ещё хуже мана жКвери. Если захотите почитать, то польза начинается отсюда http://apiwiki.twitter.com/Twitter-API-Documentation. Всё, что находится по ссылкам, ещё менее информативно, чем ман зенда.

К слову, http://hueniverse.com/oauth/, куда сходятся большинство отсылок по OAuth, вполне соответсвует своему названию.

Ситуацию выручил программер нерусской национальности Абрахам, но почему-то Вильямс, с рассказом о том, как это работает https://docs.google.com/View?docID=dcf2dzzs_2339fzbfsf4

Перевожу и дополняю:

  1. Надеюсь, вы уже зарегистрировали своё приложение? здесь https://twitter.com/oauth_clients
  2. получите оригинальные идентификаторы и выучите их наизусть $consumer_key, $consumer_secret
  3. далее выполняем первичную авторизацию приложения на провайдере $to = new TwitterOAuth($consumer_key, $consumer_secret);
  4. и получаем ключи запроса $token = $to->getRequestToken();
  5. токены реквеста нужно указывать в адресе авторизации $request_link = $to->getAuthorizeURL($token);
  6. и выполнить пересылку по этому адресу header('Location: '.$request_link); die;
  7. у твиттера существует два типа авторизации oauth/authorize и oauth/authenticate; кому важно, разберётся сам
  8. в тви-интерфейсе юзер приложения выполняет хитрые действия по нажиманию кнопок пальцами
  9. и если вы всё сделали правильно, то твиттер должен прислать токены доступа, как большим
  10. но этого не происходит, потому что тви не прост: если в пункте 0 вы не указали адрес обратного вызова, то тви считает приложение десктопным и сам переключает режим, и в пункте 8 пересылку не делает, а показывает пин-код; адрес колбека, удивительно, можно указать\переназначить в запросе токенов реквеста, п.3.
  11. получаем ключи доступа $tok = $to->getAccessToken($_GET["oauth_verifier"]);
  12. ой, какая неприятность, у нас новый объект, и он сбивает весь процесс!
    Внимание! объект из п.2 необходимо сохранить! для пхп проще воспользоваться сессиями
  13. всё. ключи доступа получены и можно что-нибудь спросить у твиттера, например: $to->OAuthRequest('https://twitter.com/account/verify_credentials.xml', 'GET', $token)); ах да, у Абрахама в этом месте ошибка в параметрах
  14. пытливый читатель попросит добавки в виде описания процесса для десктопных. пожалуйста: пин-код из п.9 нужно использовать как oauth_verifier из п.10
  15. voila!
У меня работает. Можно продолжать монетизировать твиттер :)
На прощание ссылка для базовой авторизации - красиво выглядит класс http://github.com/jdp/twitterlibphp
зы: внимательный читатель заметил, что твиттер не требует обязательного указания сигнатуры ;)

upd: когда гугл включил статистику для блогспота, я был весьма удивлён огромной для такого скромного бложика посещаемостью этой статьи...
читатель! не стесняйся благодарить автора переводом любой суммы в йандекс-кошелёк 410011133049553 :) (https://money.yandex.ru/shop.xml?scid=1269)

2010/02/13

OpenID, Zend И все-все-все

Внимание! позавчера вышла распрекрасная версия зенда 1.10.1, о чём нам сообщает доверенный источник в лице http://zend-framework.ru/zend-framework-1-10-1-release/
Рекомендую означенный блог к ознакомлению, масса информации для нубов в зенде; многого вы не найдёте в официальной документации.
Забавность произошла у меня с зендом. Есть у них такое место, как Developer Zone http://devzone.zend.com/. Резонно было бы ожидать, что статья http://devzone.zend.com/article/3581 "Getting Started with OpenID and PHP" содержит инфу про Zend_OpenID... А вот и нет! В статье описывается работа с библиотекой The PHP OpenID Library, by JanRain Inc.
Так-то!
Искренне ваш,
и.о. К.О.

зы: в упомянутом блоге описан баг зенд-оид и гугла и хак к нему http://zend-framework.ru/google-zend_openid/ Надеюсь, в новой версии баг исправили, надо глянуть.
Также не забываем про первую в РФ конфу ЗФ; предварительная регистрация http://www.zfconf.ru/pre-registration.php ; твитор @zfconf

2010/02/07

PHP и циклический битовый сдвиг

Возник на канале вопрос про циклический сдвиг в пхп... В качестве послеобеденного фана набросал концепт; надеюсь, кому-нибудь пригодится. Заметьте, функция для любой разрядности, хотя принимает и возвращает только десятичные.


function
circular_shift($what,$direction='<<',$steps=1,$wordlength=32)
{
$bits = base_convert((string)(int)$what,10,2);

for (
$i=0; $i < $steps; $i++)
{
$length = strlen($bits);

if (
'<<'==$direction)
{
if (
$length == $wordlength && '1' == $bits[0] )
// overflow
$bits = substr($bits,1).'1';
else
$bits = $bits.'0';
}
elseif (
'>>'==$direction)
{
if (
$length < $wordlength )
// shortage
$bits = $bits.'0';
else
$bits = $bits[$length-1].substr($bits,0,$length-1);
}
else
die(
'WTF?!');
}
return (int)
base_convert($bits,2,10);
}

print
circular_shift(8) ;


зы: Другие типы сдвигов делаются аналогично. Развивая тему, можно даже связать сдвиги с колбеками и завернуть в класс.

Успехов

2009/12/27

Попадаются ж такие удивительные личности

Например http://www.itdumka.com.ua/index.php?cmd=showcatnodes&cat=1&page=1 блоговодец пишет откровеннейшею чушь о работе с PHP, занимается велосипедированием Smarty и всячески доставляет лулзов.
Но между тем, собирает большие коллекции паттернов и качественно их классифицирует http://www.itdumka.com.ua/index.php?cmd=shownode&node=11 Чувствую где-то подвох.
Ознакомьтесь с коллекцией, интересный сборник.
зы: в хидере картинка с надписью "мысли не обязаны умирать в голове"

2009/12/19

Не могу молчать!

DirectoryIndex, ну вы понимаете, в Apache, в частности, в .htaccess при наличии в списке index.php запрашивает сначала его, даже если он в списке последний!
У меня не осталось цензурных слов, чтоб выразить своё возмущение этим фактом!
Опасайся НЁХ!
upd: это как-то связано с чьими-то кешами

И ещё в RewriteCond нельзя использовать %1 - подстановку подвыражения из самих условий. sad but true

___

зы: немножко пользы для гуи-архов Паттерны меню от Азы Раскина, Usability.by можно почитывать

2009/12/16

йаСМИ в логах

Скучное краткое содержание чата онлайн-трансляции конференции, секция "Кадровый рынок в СМИ"

[14:37] http://twitter.com/media_magnit: блин у меня нет звука
[14:37] http://twitter.com/media_magnit: о есть!!
[14:37] http://twitter.com/media_magnit: в зале 5 человек и те без палева решили смыца
[14:38] http://twitter.com/media_magnit: блин я уже это видела кажеца
[14:40] http://twitter.com/media_magnit: кажется даже на Риве была эта презента
[14:40] rabotyahoff.mp: Чел на в первом ряду пиво потягивает )))
[14:41] http://twitter.com/media_magnit: да точно
[14:41] http://twitter.com/media_magnit: я уже видела эту презенту
[14:41] http://twitter.com/media_magnit: на РИфе и на РИве
[14:46] http://twitter.com/media_magnit: может в других залах интереснее...
[14:46] http://twitter.com/media_magnit: почему только этот показывают
[14:48] Гость 266: а кто сейчас говорит?
[14:48] Гость 266: HH.ru?
[14:48] Гость 266: а, суперджоб
[14:56] Гость 286: A so vtorogo zala net translyacii?
[14:56] Гость 266: нету
[14:56] Гость 266: хотя там сейчас самый сок
[14:58] AlterEgo: а можно второй зал как-нибудь все же транслировать сейчас?
[14:58] Фурашов Евгений: Офигительная секция! 27 минут! Снимаю шляпу... Итоговая конференция онлайн - СМИ ! ПОЗОР
[14:58] AlterEgo: кризис в отрасли
[14:59] AlterEgo: так что за 7 минут всё и было сказано. зп в онлайн-сми так себе
[14:59] AlterEgo: 7=27
[15:01] Администрация COMDI: Дамы и Господа, сессия номер 3 завершена. Трое докладчиков не приехали. Продолжение в 16-30.
[15:02] Гость 286: chto dalshe? zhdem sled sekciyu v 16.30?
[15:02] Фурашов Евгений: Зарплаты нормальные. Платить не за что. Вот Синодов делает в одно рыло свое СМИ - ему много пусть будет денег.
[15:05] Фурашов Евгений: Я вот такую штуку "трое докладчиков не приехали" - с трудом представляю на конференции, скажем , врачей. А у нас, болтолологов , да еще и из Инета - пожалуйста!
[15:05] Фурашов Евгений отключился
[15:07] Гость 266: мда
[15:08] Гость 296: жесть какая-то, зал пустой. пришли две тетки, поболтали так, что их и не слышно и все. за 20 минут завершили 3-ю секцию. а те, кто должны были приехать, сидят
[15:08] Гость 296: видимо дома и греются

2009/12/09

ubuntu и macos

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

зы: хотел сборку выложить, да хостинг глючит %( такой хороший хостинг - и не работает; админу написал. пойду на другой ВДС, ээх

2009/11/30

Разное, текущее

Немного ссылок и радостных вестей

Визуальные программирование сайтов чудесно =:)
Вот мне не нужен суперкреативный портал... В связи с чем берём YAML буилдер на основе фреймворка YAML, разумеется, и за пять минут накидываем схемку. Или 20 минут рассматриваем примеры самого ямла в поисках чего-нибудь поизящнее.
Затем сливаем свежий ИксЕдит, которому, оказывается, необходим гуглогирс... но миленькая сафари нас быстро выручила. Пять минут впиливания ИксЕдита в шаблон от Ямла и можно приступать.
Немного мороки с накручиванием аяксового функционала на шаблон, и готова главная (и единственная) страничка для Pronto cms::etc.

Хотя она и не готова, потому что перед этим я писал аяксовый подгрузчик модулей прямо в шаблон. Таким образом, получается отличнейший крышесрывный шаблонизатор на основе привычного верстальщикам HTML, без всяких тупых вставок на других языках, включая псевдоязыки. Причём, ха, это должно работать без предкомпиляции.
Ну, как вам? ;)
Про модули подробней буду писать завтра в процессе тестирования подгрузчика.

Пока меня не сожрали Ъ-верстальщики за неприкрытую рекламу css-фреймворков, я напоминаю, что не портал верстаем. И немножко им бальзама на куда-нибудь: вышел свежий http://code.google.com/p/zen-coding/, кто не в курсе - подробности с картинками здесь (и все твитеры, и прочие координаты)

Не прощаюсь

2009/10/31

Как написать фреймворк за два часа, часть 1, про Сущности и Хранилища

Наше тело получает жизнь из пустоты. Существование там, где ничего нет, составляет смысл слов: "Форма есть пустота". Слова же: "Пустота есть форма" свидетельствуют о том, что пустота содержит в себе вещи. Не следует полагать, что пустота и вещи суть различны.
Сегодня решил написать не про модули, а про сущности и хранилища; просили.
Вспомним договорённости.
Подумаем про хранилища. Напишем:
interface CRUD
{
public function & create();
public function & read($criteria);
public function update();
public function delete($criteria);
}
почему так? рассказываю дальше:
abstract class StorageEngine implements CRUD
{
protected $__entity;
function __construct($what)
{ $this->__entity = $what; }

function __destruct()
{ $this->update(); }

// здесь ещё раз список методов, т.к. конкретную реализацию оставим для неабстрактных классов
}
ясно? или не полностью?
Возврат значений по ссылке обеспечивает обратную связь сущности (ещё не объявленной) с хранилищем, которое деструктором закрывает сущность, сохраняет её на физическом уровне.
Методы обеспечивают элементарный доступ к сущностям, сложенным в хранилище.
create обеспечивает динамическое создание копии сущности (пока только в памяти времени исполнения)
read читает коллекции сущностей из физического хранилища
update сохраняет коллекцию обратно
delete удаляет быстро и беспощадно
$criteria - признак выборки, XPath

Понимаете ведь, что это только здесь всё так красиво :) Внутри там конкретный аксессор к конкретному хранилищу и много других радостей. К которому можно подключить доп. драйвер и простенький шаблонизатор SQL для совсем уж чудных запросов. Для наших задач вполне хватает $accessor->query('SELECT _read(:criteria)', $array('citeria'=>$criteria));
Как кому-то уже понятно, в качестве драйвера используется PDO::PG, а сами выборки переложены на могучие плечи субд, на пользовательские функции. (Конкретнно чтение, выборку по критерию правильнее было бы оформить через VIEW, но я пошёл по пути унификации. И ещё: в процессе написания функций я обнаружил, что постгрес поддерживает перегрузку функций - функции с одним именем, но разным набором параметров)


Про сущности же подумаем так:
interface XML
{
function asXML();
function XPath();
}
Это два метода, которые нам необходимы. Первый для преобразования объекта к читабельному виду, второй для удобной работы. Да-да, XPath гораздо удобней, чем in_array(). Освоение множеств XML и преобразований требует некоторого мозга, но особого труда не составляет, будем работать с нормальными технологиями.
Кто использовал XML с PHP, конечно же, уже узнал этот интерфейс :) Да, это SimpleXML. Не будем изобретать сущности, извините за тавтологию, воспользуемся имеющейся.
class Entity extends SimpleXMLElement implements XML
{
// здесь меня ожидало несколько весьма занятных ээ... особенностей реализации языка. например, нельзя переопределить конструктор. пришлось изобретать конструкцию загрузки сущностей из схем и других источников, типа такой

static function load($source)
{
if (isXML($source)) $xml = $source;
if (is_file($source)) $xml = file_get_contents($source);
return new self($xml);
}
}
Со статическими методами тоже получилось интересно, почти неделю парился, уже думал, что пхп не поддерживает их перегрузку. Оказалось ещё хитрее ;) До ветки 5.3 self указывает не на текущий класс, а на класс, в котором был написан. То есть наследовать от Entity можно только с переопределением загрузчика. Но в принципе, особой нужды в этом нет, SimpleXML дал нам Entity::getName(), который выдаст имя корневого элемента (здесь необходимо вспомнить правила оформления XML;)

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

Вопросы?

зы: ах да, пример
$sth = new EntityStorage( Entity::load('scheme.xml') );
$sth->create();
или
$data_collection = & $sth->read('user/profile[name="USERNAME"]');
foreach ($data_collection as $user)
{
print $user->id;
print $user->profile->name;
}
$user->profile->name = 'LASTUSER';
$sth->update();

и замечание напоследок: нет, это не ORM, здесь отсутствует преобразование из плоской формы в объектную. На Observer похоже, но отсутствует подписка на изменения. Как назвать, не особенно важно, оно работает =%)

2009/10/20

OpenID + php

Очень хорошо написано здесь http://www.oneid.ru/info/openid-php/ про библиотеку http://openidenabled.com/php-openid/ самая большая с обширной документацией. Много кода, требует cURL и матэкстеншн GMP

Но есть и альтернативные решения вроде http://www.phpclasses.org/browse/package/3290.html

upd: php-openid поддерживает и pgsql тоже =:)

upd2:

Не стал писать новую заметку, но увиденное слегка шокировало

файл примера из библиотеки:
// For OpenID 1, send a redirect. For OpenID 2, use a Javascript
// form to send a POST request to the server.

и оно действительно делает
$form_html = $auth_request->htmlMarkup(getTrustRoot(), getReturnTo(),false, array('id' => $form_id));
 
// otherwise, render the HTML.
print $form_html;

бред какой-то. мощнейшая библиотека, и столько хлама. надо переписывать, срочно.

там ещё и втф встречается типа
function & fn($param){ ... return new someClass($param) }

зы: документация уг, либо я её неправильно читаю. кста, если кому-нить захочется почитать доки, надо начать с класса Auth_OpenID_AuthRequest, а потом перейти к Auth_OpenID_Consumer. Auth_OpenID включить, разумеется, забыли; он находится в файле OpenID.php

2009/10/14

Как написать фреймворк за два часа, часть 0

Вы понимаете, что про два часа - выражение фигуральное; но всё же не лишено смысла. Именно написать фреймворк, т.е. сделать конечную реализацию, займёт существенно больше двух часов. Время реализации можно сократить предварительным планированием. Хороший план - половина работы ;)

Сейчас мы позанимаемся образцово-показательным проектированием и планированием. Да и вообще, делать что-либо без идеи и цели не имеет никакого смысла, пустая трата времени. Итак, приступим.

Определим цели. Во фреймворке необходимо обеспечить:
  • доступность понимания структуры и кода, чтобы начинающий программист мог его освоить
  • некоторый уровень технологий, чтоб джыдаю было не скучно
  • не изобретать велосипедов
  • зы: совсем забыл! заложить в архитектуру максимально возможный уровень расширяемости и не заниматься преждевременной оптимизацией
Осмотревшись, мы находим PHP - достаточно распространённый скриптовый язык с очень (ОЧЕНЬ!) низким уровнем вхождения. В принципе, это проблема пхп, из-за которой он получил дурную славу. Попробуем вернуть языку его достоинство.
Внутренним (и внешним) единым форматом передачи данных примем XML. Что может быть проще и технологичней?
И в случаях затруднений будем руководствоваться принципом KISS Keep It Simple, Stupid - Не тупи, будь проще.
Маленькое лирическое отсутпление. Во время работы в %COMPANYNAME% в среде программистов был изобретён принцип JMS Just Make Simple - Просто сделай проще. От часто прозносимых фраз: "Давай сделаем это проще", "Я знаю как проще". Стали ли они продолжать линейку JMS CMS, я не в курсе.
Продолжаем. Пишем мы фреймфорк для веба, то бишь, чтоб делать сайты. Сайт, в конечном итоге, это текст, причём, текст структурированный. Понятию тега разметки практически идеально соответсвует понятие блока. Да и визуальное оформление обычно составлено из вложенных блоков.
Введём основное понятие фреймворка: модуль - основная и единственная структурная единица фреймворка. Хотя, на самом деле,)) модуль может быть и исполняемым кодом, и шаблоном, и чем-нибудь ещё.
Введём соглашение: каждый модуль обязан возвращать XML. Всегда. Пусть пару строк, но возвращать (как будет видно дальше, мы немного отсутпим от правила, самую малость). Обратно, всё, что не является модулем, не обязано возвращать XML и всё, что не возвращает XML, не является модулем.

Вспомним хитрое слово ReST, которое, в принципе, ничего конкретного не представляет, или, наоборот, представляет слишком многое. Это и технология, и способ, и принципы, и идея; остановимся на слове RESTful подход. Для нас это будет означать Человеко-Понятный Урл + принцип передачи параметров (формирования запросов) в модули + структурированность иерархии модулей, аналогичную URL.

Принцип работы сайтов, по большому счёту, заключается в получении данных, их сохранении и визуальном оформлении.
Основной единицей информации назначаем сущность - Entity. Сущность подготавливается по описанию. Это второй объект, который мы напишем. Первым будет, конечно, хранилище (Storage) сущностей. Хранилище должно реализовывать интерфейс CRUD Create Read Update Delete. Элементарно.
Введём второе соглашение: каждый объект, работающий с данными, принимает и\или возвращает объект типа "сущность".

Тут были упомянуты формы, хорошо бы объектик для работы с формочками по принципу принял-завалидировал-отдал, но об этом в следующей части.

Хм, теперь под выбранную идеологию подберём инструментарий. Это будет:
  • уже упомянутый PHP в связке с Apache. Тип связи с веб-сервером и сам веб-сервер могут быть любыми, это пока не принципиально, но Apache + mod_php весьма распространены, будем ориентироваться на такой тип.
  • т.к. XML клиенту (пользователю) не интересен, подключим XSLT и нагрузим преобразованиями клиента (браузер) - проверено, работает
  • добавим к этому грамотный CSS и какой-нибудь javascript framework: не мудрствуя долго, остановим выбор на jQuery
  • выбор физического воплощения хранилища представил некоторую проблему. Основное требование: нативное хранилище объектов. Но объектно-ориентированные базы весьма нетривиальны и не удовлетворяют требованию простоты фреймворка.
    Ещё одно лирическое отступление. В процессе поиска наткнулся на одно интересное решение: база не имеет собственного клиента, доступ через http RESTful или через API, возвращает xml или json, обращаться можно хоть из javascript. Оригинальное решение и достаточно старое. Но я не поставил вовремя закладку, а название забыл! %( Но в этот фреймворк тоже не подходит в виду излишней оригинальности.

    Остановился на PostgreSQL с дополнением для XML, кстати, прекрасно работает.
    Не забываем переложить бизнес-логику на базу, это её прямое назначение.

Итак, что мы насобирали:
RESTful + modulability (гхм)
XML
Entity-Storage-CRUD
PostgreSQL
PHP
Apache
XSLT+CSS+jQuery

Всё!
Энжой :)

За два часа вроде бы уложился

зы: тру пхп-кодер спросит: где же шаблонизатор? а вот php и есть шаблонизатор, если кто не в курсе

2009/10/09

Программисты, моноширинные шрифты и виндовс

Да, программеру без равномерных фонтов никуда. А какие фонты в винде, ну вы помните, да?
На этот курьер я смотрю лет десять, наверное. Надоело. Бесповоротно.

Было выяснено, что тру-джыдаи давно используют нормальные шрифты, как то: Terminus и Consolas; затем, в процессе сёрфинга, к ним добавились Liberation, Bitstream Vera, и вспомнился Monaco. Выгуглено было страниц под сотню и выяснено, что:
  • Consolas свободно сливается с сайта производителя. Но представляет собой Clear-Type шрифт, что мне не подходит технически: на ЖК с невысоким разрешением клеартайп размазывается между пикселями. Но кому глаз не режет - в принципе, хвалят.
  • Туда же, кстати, ушёл Bitstream Vera, который вроде бы и есть в поставке висты, но можно слить с гнома.
  • Monaco ищется достаточно легко, шрифт старый, известный. Но не нашёл русских букв.
  • Terminus я искал долго. В смысле, чтоб с кириллицей. Так и не нашёл. Без кирилицы - "первая ссылка в гугле". Если у кого вдруг есть terminus-cyr.ttf, пришлите, пожалуйста на почту.
  • В процессе поисков были обнаржуны залежи полезного, но буржуинского http://stackoverflow.com/questions/4689/recommended-fonts-for-programming, http://www.codeproject.com/KB/work/FontSurvey.aspx, http://damieng.com/blog/2007/11/14/droid-sans-mono-great-coding-font. А также поставлен растровый фонт из этой ветки. Первая удача! он заработал. Мне понравилось
  • И Liberation - это шрифт от RedHat. Можно взять с официального сайта. Было ли это ошибкой, но сначала я слил и поставил файл с самым большим номером версии, но шрифт в списке не показался. И я пошёл искать всё прочее, о чём выше. А потом я слил файл с самым коротким названием ;) и заработал Liberation Mono, остальные из пакета почему-то отказались.
Вот так мы поменяли шрифты =:)

Не прощаюсь

2009/10/07

Юзабилити не существует

текст готовился на хабр, но в связи с известно какими причинами не может быть там даже сохранён

Среди свитков, висящих на стене у господина Наосигэ, был свиток со словами: "К важным делам следует относиться легко".


Как я написал в каком-то каменте, меня не перестают удивлять люди, занимающиеся как бы "юзабилити". Хабрапипл вполне представляет, чем чреваты подобные хабразаявления.
Казалось бы, толпы народов съезжаются, устраивают конференции, изводят тонны макулатуры и человеко-лет. На что? А ни на что. Сейчас в очередной раз посмотрим, как получать деньги из воздуха.

Ведь и правда, нельзя делать подобные заявления голословно, нето %юзернейм% негодуэ оппоненты сильно расстраиваются.
Университетов мы кончали, распишем всё по трафарету.

Начнём с названия. Юзабилити - us-ability use-ability - хмм... возможность использования? в приниципе, это бинарное состояние: можно пользоваться \ нельзя пользоваться. Но километры копий не даром же сломаны?

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

Включив немного мозга и обратившись к источникам интернетам, мы узнаем, что юзабилити... м-м - как бы это по-мягче сформулировать - ничем не является.

Оно не является научной дисциплиной по причине отсутствия аксиоматического аппарата, объекта исследования и подхода изучения - это почти основные элементы, отличающие (характеризующие) науку от прочих сфер человеческой жизнедеятельности. (Не лезем в философию и проблему демаркации, ок?)
Но оно и не является сферой человеской деятельности! Так-то!
Словцо это обозначает всего лишь определение понятия в подразделе эргономики - микроэргономике. ("обозначает определение понятия" это я красиво загнул ;) вообщем, вы поняли, да?)

...the extent to which a product can be used by specified users to achieve specified goals with effectiveness, efficiency and satisfaction in a specified context of use.

Э-э! посвятить всего себя изучению одного понятия - задача, достойная философа. Ещё раз к месту слово "докторская". Но я подозреваю малое количество мизантропов-отшельников среди этих удивительных людей.

Увидев этот свиток, мастер Иттэй добавил: "К несущественным делам следует относиться серьёзно".


Пойдём с другой стороны, попытаемся сформулировать род занятий "юзабелист" через перечисление (грязный антинаучный хак). Занятие представляет собой попытку предсказать реакцию (удовлетворённость) и поведение (продуктивность) определённых групп людей при попытке взаимодействия (эффективность) с продуктом.
Вот для чего сотни мегабайт букв, озаряет нас внезапная догадка! Юзабелист подобен древнему врачу, практически вслепую ведущего команду инженеров, проектировщиков, маркетологов, художников и рабочих сцены к светлому приятию конечным пользователем светлых идей, воплощённых в качественном продукте.

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

Попробуем дать хоть какое-то научное обоснование.

По моему скромному мнению, человеческими деяниями управляют два фактора. Точнее, даже один. Инстинкты. Не будем опускаться до полной павловщины, это сильное такое допущение, но остановимся, как на одном из самых понятных.
Так вот, люди всё делают либо по привычке, либо по глупости. По привычке выполняются знакомые операции, уже повторенные несколько раз: свет вкл\выкл, зубная щётка на полке слева, крестик справа сверху, ссылка - синяя и\или подчёркнутая, центр-клик = опен ин нью таб, поиск где-то рядом, в меню можно выбирать, между абзацами обычно отступ два\полтора интервала, колбаса хороша в салате. Это не только приобретённые инстинкты, но и врождённые, типа частоты дыхания, изменения состояния от воздействия определённых цветовых сочетаний, инстинкт слежения [взглядом], моргание, зевание.

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

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

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


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


Успехов и до новых встреч.

Юзабилити не существует! =;)