pagenator

19.10.2009 (1:11 дп) – Filed under: codding,software

simple pages on your cite with your PHP code.

Этот код родился давно и был использован в нескольких фриланс-проектах.
Со временем он изменился и приобрел законченый вид, после которого мне не надо в него более лазить чтобы использовать. На самом деле я стремлюсь все компоненты своего кода довести до такого состояния. Но заказчику такой подход как минимум не понятен, а как максимум не выгоден – ибо скорость выполнения заказа падает. Зато потом, на следующем заказе, она может резко возрасти.

Это предисловие. А содержание такое – я хочу похвастаться своим первым публичным релизом кода. Очень надеюсь он будет полезным хоть кому-нибудь.

Что этот код делает.
Pagenator – это простая библиотека позволяющая за минуту развернуть мини-сайт со страничками и ЧПУ. Ориентирована на програмистов, т.к. это не CMS. Никаких БД или файлов, никаких конфигов. Просто складываете свои PHP файлы в директорию и не забодьтесь о том, как их показать. Вообщем то, что делает Pagenator делал каждый PHP програмист, как пить дать.

Суть.
Сама либа в google code – http://pagenator.googlecode.com/svn/trunk/
Скриншот, исчерпывающи описывающий принцип работы:
Спасибо за внимание. Рад любым отзывам.

Unicode and UTF-8. Рвем волосы на голове.

08.07.2009 (10:24 дп) – Filed under: codding,software

Unicode. Как много в этом слове. Сейчас использовать юникод в вэб приложениях – это уже не просто хороший тон, а стандарт.

Но с юникодом бывает много проблем, т.к. для начала наиболее расспространенные операционные системы используют «снаружи» однобайтовые кодировки и на этапе создания основных языков програмирования поддержка UTF не была заложена. Юникод был предложен как универсальная кодирвка в 1991 году, и в 1993 уже использовалась версия 1.1. Сейчас при слове «юникод» у большенства всплывает в голове аббревиатура UTF-8. Но честно говоря UTF-8 – это не юникод. Чуть более внимательно вчитавшись в определения можно подчеркнуть, что «Юникод» – это стандарт кодирования символов. А UTF-8 – кодировка, реализующая представление Юникода. Основная черта UTF-8 заключаеться в том, что первые 128 символов совпадает с ASCII, что дает обратную совместимость с ПО «не умеющим» юникод.

Всеже «Настоящим» юникодом считается UTF-16BE, UTF-16LE, UTF-32BE, UTF-32LE. Собственно первая версия кодирования юникода была 16-битной, с фиксированной шириной символа. Windows начиная с 2000 внутри себя использует UTF-16LE. В мире *nix принято использовать UTF-8.

И наконец о том, как все это касается нас. Редактирование файлов в нужной кодировке, темпаче если она отличается от системной становится не найтивной. Впрочем всегда решается удачным редактором, или толковым IDE. Для простых целей – это EditPro (win) и JOE (*nix). Тексты – это только пол беды. Оснавная беда – это языки програмирования. Про С/С++ говорить не имеет смысла, т.к. язык достаточно низкого уровня и собственно является основой для всего остального. А все остальное – это как минимум JAVA, Perl, PHP, Python, etc..

О некоторых тонкостях стоит рассказать. От простого к сложному.
JAVA – найтивно поддерживает юникод. JDK 1.5 полностью реализовывает стандарт Unicode 4.0.
PHP – впринципе при работе с UTF-8 не возникает никаких проблем. Пока речь не доходит до регулярных выражений и мультабайтных строчек. Есть несколько библиотек, которые решают возникающие проблемы, не считая iconv конечно. Собственно для поддержки всего рациона кодировок в PHP есть mbstring.
Perl - изначально работает на своей собственной кодировке, т.е. имеет внутренние представление текста. Впринципе при работе с однобайтными кодировками это не заметно, т.к. кодировка определяется автоматически. В остальных случаях её следует указывать для источника данных и для вывода. Тут неплохо об этом написано. Вообщем ясная документация дает все ответы:
http://perldoc.perl.org/functions/open.html
http://perldoc.perl.org/Encode.html.

Пример работы с разными кодировками в Perl:
open(SQLFILE, «<:encoding(UTF-16LE)", $SQL_files{$item})
$current_sql_query =~ s/\x{FEFF}//g; ## срезаем спецсимволы.
$current_sql_query_utf8 = encode(«UTF-8″,$current_sql_query);

Об остальных языках я пожалуй говорить не буду.
На закуску, настоящий юникод: http://www.unicode.org/~scherer/emoji4unicode/snapshot/full.html

Да, есть ещё одна забавная штука – юникод в виндовой консоле.
Ставим PowerShell, в нем помимо иных возможностей можно менять кодировку на лету:
$OutputEncoding = [System.Text.Encoding]::UTF8

Другие материалы:
http://docs.activestate.com/activeperl/5.10/lib/Encode/Unicode.html
http://www.utf8-chartable.de/
http://www.php.net/manual/en/regexp.reference.php
http://www.php.net/manual/en/reference.pcre.pattern.modifiers.php
http://www.mapbender.org/Encoding_UTF8/ISO8859-1#utf8_decode
http://webcollab.sourceforge.net/unicode.html

rapidleech and rapidget.

25.06.2009 (4:08 пп) – Filed under: codding,software

По работе встала передо мной простая по сути, но не самая тривиальная по технике проблема: Массовое скачивание и закачивание файлов на файловые хостинги, при том, чтобы пользователь орудовал только списками этих файлов не более того.
(для гугла: php download script filehosting или php filehosting mass uploader)

Почесав репу я поинтересовался у гугла, кто и как решал такую проблему. Потому что я не первый – это уж точно. И первое, что я нашел – это был rapidget. Второе – это rapidleech.
Как-то более мне приглянулся рапидлич, хотя большой разницы нет. Но она таки есть.
Кто с кого попер код я не стану судить, но оба скрипта выросли из одного начала. Более причесаным выглядит первый, наверное потому что переписывали таки русские.

Далее надо было встроить скрипты в имеющийся код и сделать из них консольные качалки.
Тут начались первые проблемы, т.к. кроме плагинов аплода/даунлода код представляет из себя большую свалку HTML, CSS, JS и PHP соответственно, но разобраться можно.

Разбираться я стал с рапидличером, т.к. он поновей будет и у него хорошее коммунити.
Краткая история такова – вырезать весь ненужный для консоли код из файлоа http.php и other.php. Для даунлода можно почистить audl.php, оставив там лишь обработчик формы.
Для аплода все немного хитрей – надо добавить цикл (если много файлов) в файл upload.php (auul.php можно даже не открывать) и тоже поменять GET переменные на иные нужные. Впринципе в таком сильно обрезаном варианте скрипт можно встраивать.

P.S. Писал немного второпях, такчто извиняюсь за сумбурность.

Radio. SHOUTcast. Retranslation.

20.05.2009 (9:07 дп) – Filed under: codding,software

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

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

На gentoo из портов поставить не удалось – просят скачать с официального сайта (линк выше).
Качаем, ставим:

# cd /opt
# wget http://www.shoutcast.com/downloads/sc1-9-5/shoutcast-1-9-8-*******.tar.gz
# gunzip -c shoutcast-1-9-8-********.tar.gz | tar xf -
# cd shoutcast-1-9-8-*********

там 3 файлика. Конфиг быкапим и настраиваем под ретрансляцию.

Основные параметры:
MaxUsers=32; максимальное количество юзверей онлайн
Password=megasecret; пароль для админки радио
PortBase=8000; Порт вещания. И вэб интерфейса статистики/управления.
LogFile=sc_serv.log; Желательно всетаки видеть что происходит
SrcIP=ANY; IP для подключения к источнику. ANY всегда работает.
DestIP=aaa.bbb.ccc.ddd; IP с которого будет сримится. (на котором виснет сервер)

И наконец самое главное.
RelayPort=8001; Порт, на котором вещает ретранслируемая станция
RelayServer=123.221.232.221; И собственно аддрес ретранслируемого сервера.

Ещё полдесятка параметров не принципиально. Для тривиальной задачи.
Если буду как-то тонко разбираться – расскажу об этом отдельно.

Пускаем сервер:
# ./sc_serv &

Теперь надо сделать красиво и удобно. Создаем поддомен radio.myhost.com
и кладем в него .htaccess со следующим содержанием (если apache конечно):

RewriteEngine On
RewriteBase /
RewriteRule (.*) http://aaa.bbb.ccc.ddd:8000/$1 [QSA,P]

Где aaa.bbb.ccc.ddd наш IP на который подвешан сервер (DestIP).

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

P.S. Сервер приватный. Кому хочется послушать – пишите на почту.

PHP tips

22.04.2009 (10:48 пп) – Filed under: codding

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

Типс о занимаемой мамяти.
В PHP есть вообщем ссылки. И если у вас есть переменная, которая содержит большой объем данных и вы хотите эти данный ещё разок обработать.
(например nl2br($str); и т.д.) – передавайте по ссылке. Просто nl2br(&$str);. Экономия памяти и процессорного времени на копировании данных в функцию и обратно.
(надо будет посчитать в циферках что к чему)

Типс о неровной отдаче.
Когда большой скрипт долго думает – он может отдавать страницу кусками, что выглядит некрасиво. Поэтому такой вывод можно буфферизировать, благо в PHP есть для этого средства. Можно использовать эти два типса вместе. Т.е. буферизировать вывод, сохранив его в переменную, потом проверить например на XSS.
Буферизация смотрится красиво + можно при таком подходе сделать какой-нить «please wait» красивый, или рекламу показать, пока вывод готовится на сервере. (только чтоб таймаут не порвался, ибо данные-то не идут)

Типс о скрытых ошибках.
Никакие ошибки пользователь не должен видеть на вашем сайте.
И для этого не нужно городить нечитаемых ифов и переменных состояния – достаточно просто чуть что выкидывать эксепшн. При том можно написать свой класс эксепшенов, который юудет все логировать. Или логировать через catch(Exception $e) { /* code */ }.
Для пользователя любой лаг может выглядеть например как выкидывание на последнюю посешенную страницу на сайте. Использой везде файринг с «тихим» отловом можно даже защитится от собственных кривых рук.

Спасибо за внимание, надеюсь был ползен.

easy PHP templates

18.03.2009 (4:27 пп) – Filed under: codding

Creating templates for *SQL query output
or other data with many rows and fixed number of columns.

(Русское описание ниже(: )

$arrayForTable = array(    array ('COL1'=>1, 'COL2'=>2),    array ('COL1'=>3, 'COL2'=>4));echo buildFormattedCycledArray($arrayForTable, 'small_table.tmp');function buildFormattedCycledArray($inArray, $template) {    $template = '_templates/'.$template;    if(!file_exists($template) or sizeof($inArray)==0) {        return null;    }    $data = file_get_contents($template);    $keywords = array();    $columns = array();    preg_match_all("/([\d\D\n\r]*)#begin#([\d\D\n\r]*)#end#([\d\D\n\r]*)/i", $data, $keywords);    preg_match_all("/\{(\w+)\}/i", $keywords[2][0], $columns);    $cell_row_templ = $keywords[2][0];    $ret_data = '';    $page_data = '';    $ret_data .= $keywords[1][0];    $arr_counter = 0;    foreach($inArray as $key => $item)  {        $page_data = $cell_row_templ;        $counter = 0;        foreach ($columns[0] as $col) {                        $page_data = str_replace($col, $inArray[$arr_counter][$columns[1][$counter]],$page_data);            $counter ++;                    }                        $ret_data .= $page_data;        $arr_counter ++;    }                    $ret_data .= $keywords[3][0];    return $ret_data;}

And template like this:

<table cellpadding="0" cellspacing="1">#begin#<tr>    <td>{COL1}</td>    <td>{COL2}</td></tr>#end#</table>

Идея очень проста: Регулярное выражение вырезает то, что находится между
#begin# и #end# и повторяет для каждой строчки. Если есть запись вида {COL1} и в строчке есть элемент с ключем COL1 – происходит замена. Все это сваливается в одну большую переменную и отдается. Дальше её мыжно вывести наружу.

Подобным способом можно «ошаблонизировать» весь код. Но реально это не нужно,
ибо большая потеря производительности. В большинстве случаев я не считаю позором
поставить include(‘logic.php’) в начале файла и по ходу в HTML вставлять <?=$datastr;?>. Оно не сильно хуже или неудобней чем какой-нить {DATASTR};

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

Translations in XMLA

11.03.2009 (11:51 дп) – Filed under: codding

MSAS 2003/2005 supports translations for dimensions and measures.
In my task i must set translations for XMLA (OLAP) for PHP client.
(accessing by PHP SOAP through IIS)

If you want to use translations in MDX query you may use properites
like Properties(«LCID1036″), where «LCID1036″ is Locale ID.
Full article about it at sqlblog.com.

Other way is using custom caption in MDX query like this.

WITH member [Measures].[ruClients] as [Measures].[Clients],caption = 'caption'SELECT{[Measures].[ruClients] } ON 0,NON EMPTY [time].[week].children ON 1FROM [payments]

Next you can set location in SOAP request. By using SQL Server Profiler Excel’s XMLA
command can be found. Here exists field 1049.

< PropertyList xmlns="urn:schemas-microsoft-com:xml-analysis">         < Catalog>SomeMSASDatabase         < LocaleIdentifier>1049         < DataSourceInfo/>         < Content>SchemaData         < Format>Tabular       < /PropertyList>

P.S. Sorry for my English :(

not python

05.03.2009 (9:46 дп) – Filed under: codding,trash

Одну из новых поделок я хотел сделать на Python’е.
Но запуск «Hello world!» занял слишком много времени,
жалось и сочуствие к которому пересилила стремления к новым знаниям.
Итого изучения Python’а было отложено до лучших времен.

Приключения начались с Denwer’а, который был бухнут вместе
с модулем для питона (2.5).
Модуль это работает через CGI. Это вообщем не так плохо, т.к. хостеры
не долюбливают mod_python.

Далее начались новые сюрпризы. Питон 3.0 ныне никем не поддерживаемый и даже не
включенный в стабильные ebuild’ы горячо обожаеой gentoo имеет другой синтаксис..
Во первых он полностью юникодный, во вторых print там со скобочками.
(на этом мои знания обновок подходят к концу) 2.6 является переходной версией.

Но вот чтобы прикрутить питон к MySQL есть модуль. Модуль с удовольствием ставится на виндовый Python, 2.4 и 2.5 версии. Для 2.6 есть неофициальный модуль.
У меня не заработал..

На том я порешил, что игра свеч не стоит, и свою поделку я напишу тупо на PHP.
Процесс написания начался со сбора в единую либу кода со всех своих залежей и поделок. Получился генератор форм и запросов.. Но об этом позже.

Opera and syntaxhighlighter

02.03.2009 (1:08 пп) – Filed under: codding,software

I found that opera don’t understand syntaxhighlighter.
Bug on «<» under <pre> tag, managed by syntaxhighlighter.
I’m fix bad posts by replacing «<» with «&rt

deleting duplicates

22.02.2009 (2:05 пп) – Filed under: codding

Deleting dublicate values from any table in SQL Server.
Key value (ID) may be changed.


SET ANSI_NULLS ONGOSET QUOTED_IDENTIFIER ONGOCREATE procedure [dbo].[delete_dublicates_from_table]  @table nvarchar(255)as beginDECLARE @ID bigintDECLARE @COUNT int declare @query nvarchar(max)declare @condamne table ( ids bigint, counts int)set @query = 'SELECT [ID], COUNT([ID]) FROM '+@table+' GROUP BY [ID] HAVING COUNT([ID]) > 1 'insert into @condamne exec sp_executesql @queryDECLARE CUR_DELETE CURSOR FOR select * from @condamneOPEN CUR_DELETE declare @temp_query nvarchar(max)FETCH NEXT FROM CUR_DELETE INTO @ID,@COUNTWHILE @@FETCH_STATUS = 0BEGIN  set @temp_query = (select 'DELETE TOP('+convert(nvarchar(3),@COUNT,120)+'-1) FROM '+@table+' WHERE ID = '+convert(nvarchar(32), @ID)+' ') exec sp_executesql @temp_queryFETCH NEXT FROM CUR_DELETE INTO @ID,@COUNTEND CLOSE CUR_DELETEDEALLOCATE CUR_DELETEend