Monday, March 31, 2008

пока варятся пельмени... IE & Protoload, attachEvent, addClassName &

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

в результате нескольких попыток выяснилось что убивает его protoload, который я вызывал startWaiting на ячейке таблицы (td). ну ладно, обиделся, повесил крутилку на document.body, что решило первую проблему.

далее я решил навешивать onchange событие на select. все вроде хорошо, но немножко с замарочками

if(window.addEventListener){ // Mozilla, Netscape, Firefox
select.addEventListener('change', myFunction, false);
} else { // IE
select.attachEvent('onchange', myFunction);
}

а именно в том что мало того что событие аттачится по-разному, так еще и называется или change или onchange

ну и когда это заработало я узнал что в IE не срабатывает добавление стиля через setAttribute('style', 'width:50%;');
в то время как работает setAttribute('id', 'myid'); а добавление стиля работает в операфоксе.
решается это просто через прототайповский addClassName (а ф-ция addClass не прототайповская а из другого пакета dom extension)
но т.к. она не родная то код

var label = document.createElement('div');
label.innerHTML = "abc" ;

label.addClassName("myCssClass");

label.setAttribute('id', 'labelID');
$('parentDiv').appendChild(label);

работать не будет) надо писать

var label = document.createElement('div');
label.innerHTML = "abc" ;

label.setAttribute('id', 'labelID');
$('parentDiv').appendChild(label);

$('labelID').addClassName("myCssClass");

ps. да, сам знаю что бред, но капельку полезного вытянуть можно =)

Friday, March 28, 2008

блоггер фдесятке

http://blogs.yandex.ru/services/
все больше натыкаюсь на блоги на блоггере, причем если в жж я обычно вижу нормальных живых людей или фотоблоги или путешествия то тут всякая нечисть: программеры, админы, линуксоиды...

(слово-паразит забавненько)

только сегодня задумался что терабайт всего 1024 гигабайта.
не все из тех кто родились в один год со сной в своей сознательной жизни застали винчестеры меньше 10 гигабайт. а дальше пошло-поехало... после 4гб у меня сразу появились 120, у друзей по 200 - 500, а терабайт как-то упоминался только про что-то огромное, отдаленное от жизни. сейчас терабайт дома это вполне нормально, куда катится мир)))

Thursday, March 27, 2008

Декоративная обфускация PERL-кода


Или этот верблюд - эмблема PERL (это пример "визуального" japh, для корректного просмотра
которого, предварительно выставь в настройках консоли "разрешение" 120x48 символов, а вот
шрифт лучше выбери поменьше):


---------------------------------[ Spatial Japh by liverpole ]------------------------------


#!/usr/bin/perl -w

sub j(\$){($
P,$V)= @_;while($$P=~s:^
([()])::x){ $V+=('('eq$1)?-32:31
}$V+=ord( substr( $$P,0,1,""))-74} sub a{
my($I,$K,$ J,$L)=@_ ;$I=int($I*$M/$Z);$K=int(
$K*$M/$Z);$J=int($J*$M /$Z);$L=int($L*$M/$Z); $G=$
J-$I;$F=$L-$K;$E=(abs($ G)>=abs($F))?$G:$F;($E<0) and($
I,$K)=($J,$L);$E||=.01 ;for($i=0;$i<=abs$E;$i++ ){ $D->{$K
+int($i*$F/$E) }->{$I+int($i*$G/$E)}=1}}sub p{$D={};$
Z=$z||.01;map{ $H=$_;$I=$N=j$H;$K=$O=j$H;while($H){$q=ord
substr($H,0,1,"" );if(42==$q){$J=j$H;$L=j$H}else{$q-=43;$L =$q
%9;$J=($q-$L)/9;$L=$q-9*$J-4;$J-=4}$J+=$I;$L+=$K;a($I,$K,$J,$ L);
($I,$K)=($J,$L)}a($I,$K,$N,$O)}@_;my$T;map{$y=$_;map{ $T.=$D->{$y}
->{$_}?$\:' '}(-59..59);$T.="\n"}(-23..23);print"\e[H$T"}$w= eval{
require Win32::Console::ANSI};$b=$w?'1;7;':'';($j,$u,$s,$t,$a,$n,$o
,$h,$c,$k,$p,$e,$r,$l,$C)=split/}/,'Tw*JSK8IAg*PJ[*J@wR}*JR]*QJ[*J'.
'BA*JQK8I*JC}KUz]BAIJT]*QJ[R?-R[e]\RI'.'}Tn*JQ]wRAI*JDnR8QAU}wT8KT'.
']n*JEI*EJR*QJ]*JR*DJ@IQ[}*JSe*JD[n]*JPe*'.'JBI/KI}T8@?PcdnfgVCBRcP'.
'?ABKV]]}*JWe*JD[n]*JPe*JC?8B*JE};Vq*OJQ/IP['.'wQ}*JWeOe{n*EERk8;'.
'J*JC}/U*OJd[OI@*BJ*JXn*J>w]U}CWq*OJc8KJ?O[e]U/T*QJP?}*JSe*JCnTe'.
'QIAKJR}*JV]wRAI*J?}T]*RJcJI[\]3;U]Uq*PM[wV]W]WCT*DM*SJ'. 'ZP[Z'.
'PZa[\]UKVgogK9K*QJ[\]n[RI@*EH@IddR[Q[]T]T]T3o[dk*JE'. '[Z\U'.
'{T]*JPKTKK]*OJ[QIO[PIQIO[[gUKU\k*JE+J+J5R5AI*EJ00'. 'BCB*'.
'DMKKJIR[Q+*EJ0*EK';sub h{$\ = qw(% & @ x)[int rand
4];map{printf "\e[$b;%dm",int(rand 6)+101-60* ($w
||0);system( "cls")if$w ;($A,$S)= ($_[1], $
_[0]);($M, @,)= split '}';for( $z=256
;$z>0; $z -=$S){$S*= $A;p @,} sleep$_
[2];while ($_[3]&&($ z+=$ S) <=256){
p@,}}("". "32}7D$j" ."}AG". "$u}OG"
."$s}WG" ."$t","" ."24}(" ."IJ$a"
."}1G$n" ."}CO$o" ."}GG$t" ."}QC"
."$h}" ."^G$e" ."})IG" ."$r",
"32}?" ."H$p}FG$e}QG$r". "}ZC"
."$l", "28}(LC" ."" ."".
"$h}:" ."J$a}EG". "$c"
."}M" ."C$k}ZG". "$e"
."}" ."dG$r","18" ."}("
."D;" ."$C" )}{h(16 ,1,1,0
);h(8, .98,0,0 );h(16 ,1,1,1)
;h(8.0 ,0.98,0, 1); redo}###
#written 060204 by
#liverpole @@@@@@@
#@@@@@@@@@@@


---------------------------------------------------------------------------------[ eof ]----


------------------------------[ japh из ключевых слов PERL ]--------------------------------


not exp log srand xor s qq qx xor
s x x length uc ord and print chr
ord for qw q join use sub tied qx
xor eval xor print qq q q xor int
eval lc q m cos and print chr ord
for qw y abs ne open tied hex exp
ref y m xor scalar srand print qq
q q xor int eval lc qq y sqrt cos
and print chr ord for qw x printf
each return local x y or print qq
s s and eval q s undef or oct xor
time xor ref print chr int ord lc
foreach qw y hex alarm chdir kill
exec return y s gt sin sort split


---------------------------------------------------------------------------------[ eof ]----

Tuesday, March 25, 2008

перфекционизм в .htaccess

около 6 часов я мучал этот .htaccess. основная его цель - отдавать существующий файл в папке files (кроме папок files/textpage) напрямую от сервера а не через пхп-скрипт



# url images/... is equal to url files/...
RewriteRule ^images/(.*)$ files/$1 [L]

# NOT textpages - existing -- all existing files except connected to textpages (just return the file)
RewriteCond %{REQUEST_FILENAME}%{PATH_INFO} -f
RewriteCond %{REQUEST_URI} !/files/textpage
RewriteRule .* - [L]

# NOT textpages - NON - existing (RESIZE) -- all existing files except connected to textpages (just return the file)
RewriteCond %{REQUEST_URI} !/files/textpage
RewriteRule ^files/([^/\d]*)(\d*)/(\d+)x(\d+)/([^/]*)?$
go.php?_action=resize&_dir=$1&_id=$2&_file=$5&_height=$3&_width=$4 [L,QSA]

# textpages - existing -- files connected to textpages (need to check before returning file)
RewriteCond %{REQUEST_FILENAME}%{PATH_INFO} -f
RewriteCond %{REQUEST_URI} /files/textpage
RewriteRule ^files/textpage(\d+)/(.*)?$
go.php?_action=textpage&_id=$1&_file=$2 [L,QSA]

# textpages - NON - existing (RESIZE) -- files connected to textpages (need to check before returning file)
RewriteRule ^files/textpage(\d+)/(\d+)x(\d+)/([^/]*)?$
go.php?_action=resizetextpage&_id=$1&_file=$4&_height=$2&_width=$3 [L,QSA]



хотя именно в этой ситуации при той нагрузке которая пойдет на этот проект можно было смело писать


RewriteRule ^(files|images)/(.*)?$ go.php?_file=$2 [L,QSA]


а потом уже скриптом решать что делать дальше.

да, мой htaccess делает больше чем выполняет свою основную цель. он:
1) переписывает все обращения к папке images на папку files (папка images не существует, но для удовлетворения перфекционизма src картинки идет в images). (но второй вариант это тоже делает)
2) в случае если файл не существует и лежит в папке files/(\d+)x(\d+)/ он отправляет на метод ресайза
3) отдельные методы отдачи файла для файлов в папке /files/textpages (существующих и идущих на ресайз)
4) выбирает из строки запроса переменные (это не надо длать скриптом).
но если 2 и 3 пункт очень просто реализовать в скрипте, то 4 пункт легко парировать тем что вот такая строчка тоже выбирает абсолютно все что нужно


RewriteRule ^(files|images)/([^/\d]+)(\d*)/((\d+)x(\d+)/)*(.*)?$
go.php?_dir=$2&_id=$3&_file=$7&_height=$5&_width=$6 [L,QSA]


p.s. любитесь с живыми людьми =)

Friday, March 21, 2008

sql IF syntax

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

order_date training_title event_title title
2008-03-20 20:04:51 NULL NULL
2008-02-20 19:38:16 aaaaa NULL aaaaa
2008-03-20 19:42:17 aaaaa NULL aaaaa
2008-03-20 19:19:19 asdasd NULL asdasd
2008-03-20 20:04:41 asdasd NULL asdasd
2008-03-20 20:06:41 NULL efefefe's "dinner" efefefe's "dinner"
2008-03-20 20:34:21 NULL efefefe's "dinner" efefefe's "dinner"
2008-03-20 20:06:50 NULL wwwww wwwww

ситуация есть либо один тайтл, либо дугой, надо отсортировать по возрастанию тайтла вообще.
первая мысль -- конкатенация строк, но и concat() и || и + выдавали в результате только null.
сделал я используя IF:

select order_date, training_title, event_title,
IF(training_title is not null, training_title, IF(event_title is not null, event_title,'')) as title
from orders
order by title

IF(<условие>, <если да>, <если нет>)


p.s. я на самом деле второй пост всех обманываю, таблица ордерс не так хороша как кажется, на самом деле в базу уходит запрос:

SELECT `orders`.`order_id`,`orders`.`order_status`,`orders`.`order_training_id`,
`orders`.`order_event_id`,`orders`.`order_user_id`,`orders`.`order_date`,
`orders`.`order_fio`,`orders`.`order_phone`,`orders`.`order_email`,
`orders`.`order_company`,`orders`.`order_comment`,`orders`.`order_admin_comment`,
`orders`.`order_admin_comment_for_user` ,
`trainings`.`training_id`, `trainings`.`training_title`,
`events`.`event_id`, `events`.`event_title`, `events`.`event_date_start`,
`users`.`user_id`, `users`.`user_login`
FROM ( (
`orders`
LEFT JOIN `trainings` ON `orders`.`order_training_id` = `trainings`.`training_id`
) LEFT JOIN `events` ON `orders`.`order_event_id` = `events`.`event_id`
) LEFT JOIN `users` ON `orders`.`order_user_id` = `users`.`user_id`
ORDER BY
IF(`trainings`.`training_title` IS NOT NULL, `trainings`.`training_title`,
IF(`events`.`event_title` IS NOT NULL, `events`.`event_title`,'')
) ASC,
`orders`.`order_date` ASC
LIMIT 20 OFFSET 0

это без where. мне это не нравится по трем причинам:
1) join по 4 таблицам
2) двойной if в ордербае
3) немного длинноватое where

WHERE (`trainings`.`training_title` LIKE '%title%' OR `events`.`event_title` LIKE '%title%')
AND (`orders`.`order_fio` LIKE '%name%') AND (`orders`.`order_email` LIKE '%mail%')
AND (`orders`.`order_status` = 0)
AND (`orders`.`order_event_id` != 0)
AND (`orders`.`order_date` >= '2008-02-20 00:00:00')
AND (`orders`.`order_date` <= '2008-03-20 23:59:59')
AND (`events`.`event_date_start` IS NULL OR `events`.`event_date_start` >= '2008-04-01')
AND (`events`.`event_date_start` IS NULL OR `events`.`event_date_start` <= '2008-04-29')
AND ( `trainings`.`training_id` IS NOT NULL OR `events`.`event_id` IS NOT NULL )

у меня есть серьезные опасения что когда в каждой таблице будет по несколько сотен записей этот запрос "откажется со мной сотрудничать".

ничего полезного (order by + null + mysql)

у нас есть таблица из 2 колонок. в одной хранится дата, во второй некое число либо null. требуется вывести все записи в определенном порядке: вначале все записи у которых training_id = null сортируя при этом их по дате, затем все записи у который training_id не null, при этом сортирую их НЕ по training_id а по дате

если просто написать

select order_date, training_id from orders
order by training_id, order_date

order_date
training_id
2008-03-20 20:04:51 NULL
2008-03-20 20:06:50 NULL
2008-03-20 20:34:21 NULL
2008-03-20 19:19:19 4
2008-03-20 20:04:41 4
2008-02-20 19:38:16 6
2008-03-20 19:42:17 6

мы получим все сортированное по training_id а внутри групп с одиноковым training_id по дате. это не совсем то что нам надо. где training_id = null все хорошо, а где не равно дата идет не по возрастанию

если же написать

select order_date, training_id from orders
order by (training_id is null) DESC, order_date

т.е. мы как бы создаем новую булевую колонку: (training_id is null).

order_date training_id
2008-03-20 20:04:51 NULL
2008-03-20 20:06:50 NULL
2008-03-20 20:34:21 NULL
2008-02-20 19:38:16 6
2008-03-20 19:19:19 4
2008-03-20 19:42:17 6
2008-03-20 20:04:41 4

все как и требовалось, есть две группы внутри которых сортировка идет по дате =)

p.s. про мускуль
в постгресе и в оракле есть order by column nulls first ну или nulls last а в мускуле нету) можно написать вот так:

SELECT * , nickname IS NULL AS isnull
FROM people
ORDER BY isnull ASC, nickname ASC

собственно, из этого примера и следует мое решение)
источник: mysql order by .. nulls first|last

Thursday, March 13, 2008

ну да, забыл добавить что раньше не знал про существование MS Visual Studio Express (бесплатной VS)
никто не трогал ее, какие у нее отличия от других версий?

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

Moonlight and vodka, takes me away...

Microsoft will be delivering Silverlight Media Codecs for Linux, and Novell will be building a 100% compatible Silverlight runtime implementation called "Moonlight".
если одним словом то: Silverlight_2.0_будет_также_поддерживать_Linux =)