<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0">
	<channel>
		<title>БетаЛаборатория - внеочередной IT-блог</title>
		<link>http://betalabs.ru</link>
		<description>Записки обычного программиста</description>
		<language>ru-Ru</language>
		<pubDate>Sun, 20 May 2012 21:26:16 +0400</pubDate>
		<lastBuildDate>Sun, 20 May 2012 21:26:16 +0400</lastBuildDate>
		<generator>AbendBlatt Blog Engine</generator>
		
		<item>
			<title>FloatField с запятой в Django Forms - Паллиатив</title>
			<link>http://betalabs.ru/2010-03-14/floatfield_s_zapjatoj_v_django_forms___palliativ/</link>
			<description>&lt;p&gt;Давно собирался сделать возможность вводить Float разделенные не точкой, а запятой, да никак руки не доходили. Но, сегодня все-таки пришлось сделать, поскольку для заказчика это оказалось критично. В принципе, данная задача решена в отдельном бранче Django, однако я предпочел сделать более простое, но менее полное и гибкое решение - создал специальный FormField. Все что он делает - это заменяет в полученных от пользователя данных запятую на точку, после чего передает управления оригинальному FloatField.&lt;/p&gt;
&lt;div class=&quot;highlight&quot; style=&quot;background: #dddddd; overflow: auto;&quot; lang=&quot;python&quot;&gt;
&lt;pre&gt;from django import forms

class FloatFieldWithComma(forms.FloatField):
	def clean(self, value):
		# Проверяем задано ли вообще значение
		if value:
			# Если да - заменяем запятую на точку
			value = value.replace(&quot;,&quot;,  &quot;.&quot;)
		return super(FloatFieldWithComma,  self).clean(value)
&lt;/pre&gt;
&lt;/div&gt;
&lt;p&gt;Соответственно, если вы используете ModelForm, вам надо будет переопределить поля с плавающей точкой&lt;/p&gt;
&lt;div class=&quot;highlight&quot; style=&quot;background: #dddddd; overflow: auto;&quot; lang=&quot;python&quot;&gt;
&lt;pre&gt;# Модель
class MyModel(models.Model):
	name = models.CharField(max_length=150)
	price = models.FloatField()

# Форма для модели. В таком виде форма будет требовать
# чтобы разделитель обязательно был точкой.
class MyModelForm(forms.ModelForm):
	class Meta:
		model = MyModel
# А с переопределенным полем price валидными будут и
# точка и запятая
class MyModelForm(forms.ModelForm):
	price = FloatFieldWithComma()
	class Meta:
		model = MyModel

&lt;/pre&gt;
&lt;/div&gt;
&lt;p&gt;Недостатки этого метода в том, что он, во-первых, не прозрачен для django-admin - чтобы все работало, потребуется переопределять формы всех AdminModel в которых нужен ввод чисел с плавающей точкой. А во-вторых, вывод значения поля будет по прежнему с точкой. На данный момент меня такое решение устраивает, однако я попробую придумать что-то более гибкое.&lt;/p&gt;</description>
			<pubDate>Sun, 14 Mar 2010 13:45:00 +0400</pubDate>
			<guid isPermaLink="false">32</guid>
		</item>
		
		<item>
			<title>Храните деньги в сберегательной кассе</title>
			<link>http://betalabs.ru/2010-03-12/xranite_dengi_v_sberegatelnoj_kasse/</link>
			<description>&lt;p&gt;Есть у меня возле офиса один замечательный банк, по прозванию Финанскредит. Открыл я там на днях себе счет и соорудил карточку - специально для работы с PayPal, поскольку моя основная карта от Альфа-банка там не верифицируется.&lt;/p&gt;
&lt;div class=&quot;notify&quot;&gt;Лирическое отступление. Проблема с картам Альфа-банка, насколько я смог разобраться кроется в совместимости авторизационных методов банка и PayPal. PayPal при попытке авторизовать карту отправляет не все требуемые данные, а именно отсутствует CVV2. Альфа-банк же такую транзакцию не принимает, хотя авторизационную сумму в 1,95USD на счету блокирует на 21 день.&lt;/div&gt;
&lt;p&gt;И все вроде с Финанскредитом складывалось неплохо - открыли счет и выдали карту буквально за 30 минут (выдали бы быстрее, но принтер карт заклинило) и к PayPal карта тоже замечательно прицепилась. Негативные впечатления начались когда я решил подключить интернет-банк. Для начала надо было пойти в банкомат и активировать услугу, использую секретный временный код, на что банкомат выдавал временный пароль. Далее, первый раз авторизация на сайте происходит по номеру карты и полученному от банкомата паролику. А вот дальше, система просит указать любой логин и пароль... из 4(!) цифр(!). Вся безопасность строится на том, что набор пароля производится на виртуальной клавиатуре. Что она из себя представляет - это панель содержащая 10 картинок на которых при каждом обновлении страницы цифры от 0 до 9 отображаются в случайном порядке. При клике на картинку в поле для пароля попадает идентификатор &quot;ячейки&quot; в которой расположена картинка. То есть на сервер отправляется не сам пароль, а лишь 4 номера ячеек на которые кликнул пользователь. И все бы ничего, но... Во-первых, сессии для отображения картинок обновляются только при обновлении всей страницы. То есть, если не обновив страницу запросить с сервера картинку для любой ячейки, мы получим ту же картинку. Номер ячейки на сервер передается просто в виде GET переменной. То есть, даже если учесть что картинки не кэшируются, злоумышленник может просто повторно сгрузить все картинки с цифрами. Во-вторых, на каждую цифру приходится всего два(!) варианта изображения. Это значит что для определения цифры, злоумышленнику даже не потребуется OCR - достаточно просто сравнить полученный файл со всеми 20 возможными. Что же в итоге? Достаточно получить возможность внедрить в браузер произвольный код (фактически без разницы какой - JS, Java или Flash) и злоумышленник знает какие цифры находятся в каждой ячейке, он знает и номер ячеек, которые выбрал пользователь и вуаля - он имеет доступ к нашему интернет-банку. Да, он не может совершать там операции более чем на 500 рублей за раз (для больших требуется код, оправляемый на SMS-номер владельца, если он подключил себе эту услугу). Но вот никаких ограничений на количество таких операций нет, так что...&lt;/p&gt;
&lt;p&gt;Но это все проблема не только этого банка - увы, серьезная безопасность пока не в чести у энтерпрайзеров. И если бы мои негативные впечатления на этом заканчивались, я бы даже не стал писать. Но, самое интересное было впереди.&lt;/p&gt;
&lt;p&gt;Как я уже говорил - в основном эта карта мне нужна для использование с системой PayPal, так что сразу после активации интернет-банка я верифицировал карту и оплатил одну большую покупку. По моим расчетам, после всех конвертаций и комиссий, на счету должно было остаться чуть меньше 1000 рублей - то есть денег было впритык. Но, каково же было мое удивление, когда на следующий день, банкомат известил меня, что у меня задолженность(!) в 2870 рублей. Интересная у банка получалась математика. Первая мысль была о проблемах самого банкомата, вторая - о каких-нибудьт скрытых комиссиях. Чтобы разобраться, я полез в интернет-банк и запросил выписку. В ней по прежнему значилась цифра &quot;-2870 руб.&quot;, однако, по сумме всех транзакций (в том числе и конверсионных) получалось именно так, как я рассчитал - должно было быть чуть меньше тысячи.&lt;/p&gt;
&lt;p&gt;Пришлось распечатывать выписку и топать в банк. Там стало еще веселее - оказалось, что банковская программа вообще моих расходных транзакций не видит, только пополнения, но при этом я все равно в минусе. Обзвонив всех кого можно, менеджеры так и не смогли разобраться в чем дело, и я плюнул и ушел, предупредив что вернусь завтра. В общем, кончилось все тем, что вечером, а вернее почти ночью, мне вернули на счет все чего там не хватало, но никаких разъяснений так и не дали.&lt;/p&gt;
&lt;p&gt;Сколько же людей оказалось вот так обмануто? Специально или случайно происходят такие вещи - это уже вопрос отдельный - в моей ситуации я склоняюсь к тому, что это все-таки какая-то программная ошибка, ибо так неумело не воруют. Тут больше меня интересует, сколько людей таких ошибок не замечает. На самом деле, ведь и я бы мог не заметить, если бы не провел всего одну операцию по карте - через месяц или два, исчезновение 100 евро я бы мог отнести к собственной забывчивости, поскольку много оплачиваю через PayPal, а так же периодически расплачиваюсь картами в магазинах и т.д. А что уж говорить о тех, для кого это вообще не деньги...&lt;/p&gt;
&lt;p&gt;В итоге, могу сказать только одно - со своими деньгами надо быть внимательными, поскольку к чужим в банках зачастую относятся наплевательски.&lt;/p&gt;</description>
			<pubDate>Fri, 12 Mar 2010 12:51:00 +0400</pubDate>
			<guid isPermaLink="false">31</guid>
		</item>
		
		<item>
			<title>Новый WYSIWYG</title>
			<link>http://betalabs.ru/2010-02-26/novyj_wysiwyg/</link>
			<description>&lt;p&gt;Ну вот, переделал django-приложения для работы с WYSIWYG-редакторами. Первоначальная реализация была достаточно кривая, к тому же давала возможность работать только с FCKEditor 2, который уже достаточно устарел. Кроме того, после некоторых оптимизаций работы nginx, она перестала работать =/ Новое приложение уже более корректно, хотя еще тоже не доделано. На данный момент еще не реализована нормальная работа с https, однако это проблема не только данного приложения, но и всей системы в целом.&lt;/p&gt;
&lt;p&gt;От использоваия FCK для себя я отказался в пользу TinyMCE. Но в самом приложении я реализую постепенно поддержку минимум 3-4х различных редакторов, после чего выложу это все в open-source. Увы, пока мне приходится все это делать одному. Сейчас я перешел к более-менее активному поиску помошника по django (нужно по работе), но насколько быстрым и успешным будет этот поиск не знаю. Сначала я очень понадеялся на проект http://djangopeople.net, но увы... Как оказалось большая часть москвичей, да и россиян вообще, именно к джанго отношения не имеют. Не совсем мне понятна их мотивация для регистрации на таком сайте, но судя по всему, просто чтобы дополнительно &quot;засветиться&quot;&amp;nbsp; везде, где могут обитаться потенциальные заказчики. Грустно...&lt;/p&gt;
&lt;p&gt;PS: начинаю морально готовиться к тому, что сотрудников надо будет искать не в нашей стране.&lt;/p&gt;</description>
			<pubDate>Fri, 26 Feb 2010 00:07:00 +0400</pubDate>
			<guid isPermaLink="false">30</guid>
		</item>
		
		<item>
			<title>Упрощенная Система Налогообложения</title>
			<link>http://betalabs.ru/2010-01-07/uproschennaja_sistema_nalogooblozhenija/</link>
			<description>&lt;div&gt;Вот я и добрался до написания статьи относительно налогов. По правде говоря, статья эта коснется только Упрощенной Системы Налогообложения, поскольку с остальными я дела не имел, а заниматься копипастом с юридических сайтов как-то не хочется.&lt;/div&gt;
&lt;div&gt;&amp;nbsp;&lt;/div&gt;
&lt;div&gt;Итак, &lt;strong&gt;что же такое УСН&lt;/strong&gt;, или &amp;quot;Упрощенка&amp;quot;? В 2003 году наше правительство сжалилось над малым бизнесом и пустили в ход новую систему налогообложения, при применении которой, юрлица и ИП оплачивают один налог, вместо нескольких, что сильно облегчает жизнь. Правда, как я и говорил, облегчение это не для всех - для того чтобы иметь возможность применять УСН компания или ИП должны не вылезать за рамки некоторых ограничений:&lt;/div&gt;
&lt;ul&gt;
	&lt;li&gt;Нельзя зарабатывать больше 15`000`000 рублей. Можно было просто написать млн. но нолики живее иллюстрируют цифру =)&lt;/li&gt;
	&lt;li&gt;В компании или у ИП должно быть меньше 100 наемных сотрудников.&lt;/li&gt;
	&lt;li&gt;Нельзя добывать или продавать полезные ископаемые (увы, поиски нефти на дачном участке отменяются)&lt;/li&gt;
	&lt;li&gt;Нельзя производить подакцизные товары (сигареты там, спиртное)&lt;/li&gt;
	&lt;li&gt;Организация не должна иметь представительств и филиалов. Вот это обстоятельство немного печально, поскольку даже маленький бизнес может быть территориально разрознен. Но, поскольку в нашем случае речь идет об ИП, тут печалиться не о чем - у ИП итак не может никаких представительств - только представители по доверенности.&lt;/li&gt;
	&lt;li&gt;Нельзя заниматься игорным бизнесом.&lt;/li&gt;
	&lt;li&gt;Есть еще какие-то ограничения, но я их не помню&lt;/li&gt;
&lt;/ul&gt;
&lt;div&gt;Как видите все ограничения для нас пока совершенно заоблачны (правда, печально, что первое особенно заоблачно), что означает что УСН нам вполне разрешено.&lt;/div&gt;
&lt;div&gt;&amp;nbsp;&lt;/div&gt;
&lt;div&gt;&lt;strong&gt;Что же за единый налог мы должны будем платить?&lt;/strong&gt; У &amp;quot;упрощенки&amp;quot; есть два варианта вычисления налогов. Правда, выбрать надо сразу и поменять форму расчета можно будет не ранее чем через 2 или 3 года - не помню.&lt;/div&gt;
&lt;div&gt;&amp;nbsp;&lt;/div&gt;
&lt;div&gt;Вариант первый: &lt;strong&gt;6% от дохода&lt;/strong&gt; &lt;strong&gt;юридического лица&lt;/strong&gt;. Самый простой для калькуляции способ. Ежеквартально вы считаете сколько денег заработали, вычисляете 6% и относите их в сбербанк, заполнив соответственную квитанцию. Например, за квартал мы получим на наш расчетный счет 300`000 тугриков. Это означает что в налоговую мы отнесем 300`000*0,06=18`000. Не так уж и много, правда? Но это не много в том случае, если все 300 тысяч, или хотя бы большая их часть идет нам в карман. А если мы вынуждены платить за материалы, работу оутсорсерсеров и подрядчиков, аренду, бензин и т.д. Представьте, к нам на счет пришло 300 тысяч из которых 200 мы израсходовали на выполнение заказов. Получается что 18000 от нашей реальной прибыли составят целых 18%, то есть практически пятую часть всех наших доходов... По-моему это многовато. Что же делать в такой ситуации?&lt;/div&gt;
&lt;div&gt;&amp;nbsp;&lt;/div&gt;
&lt;div&gt;Если вы планируете заниматься бизнесом, который требует постоянных расходов на закупку материалов, субподряды и прочее (короче имеет высокие расходные статьи), лучше выбирать второй вариант УСН - &lt;strong&gt;15% от дохода минус расход&lt;/strong&gt;. Как это работает:&lt;/div&gt;
&lt;div&gt;Весь квартал вы собираете документы о расходах относящихся к вашему юрлицу (товарные накладные, счета, договора). При вычислении налогов вы сначала суммируете всю прибыль, потом все расходы. Из суммы прибыли нужно вычесть сумму расходов и от полученной разности взять 15%, что и составит ваш налог.&lt;/div&gt;
&lt;div&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;alert&quot;&gt;ВНИМАНИЮ ИП! Не смотря на то, что вся прибыль считается собственными деньгами физического лица, налоговая не станет принимать в качестве расходных статей все его расходы. То есть чеки из продуктовых магазинов не относятся к расходам влияющим на размер налога. Для подтверждения юридической траты необходимы товарные накладные или прочие документы подтверждающие оплату, оформленные именно на ИП, а не на физическое лицо. Кроме того, даже если вы будете покупать все продукты питания в МЕТРО и нежно хранить товарные накладные, налоговый орган может отказать в их действительности, поскольку существует правило экономической целесообразности. Если по ОКВЭД вы продаете одежду, а налоги пытаетесь списывать документами на килограммы мороженного, то оправдать такие расходы будет крайне затруднительно.&lt;/div&gt;
&lt;div&gt;&amp;nbsp;&lt;/div&gt;
&lt;div&gt;Рассмотрим тот же пример:&lt;/div&gt;
&lt;div&gt;За отчетный период на счет поступило 300 тысяч. При этом по документам у нас получается 200 тысяч расходов. Следовательно,наш налог составит (300000-200000)*0,15=15000. Ну вот, уже на 3000 меньше =) Разумеется все это очень бегло и для определения правильного варианта нужны более тщательные расчеты.&lt;/div&gt;
&lt;div&gt;&amp;nbsp;&lt;/div&gt;
&lt;div&gt;Итак, если вы выбрали вариант налогообложения который вам подходит, то надо просто распечатать &lt;a href=&quot;http://static.betalabs.ru/media/upload/Files/2010/01/06/Заявление_о_переходе_на_УСН.doc&quot; title=&quot;Бланк&quot; target=&quot;_blank&quot;&gt;Заявление о переходе на УСН&lt;/a&gt; (см.  &lt;a href=&quot;http://static.betalabs.ru/media/upload/Files/2010/01/06/Заявление_о_переходе_на_УСН_Обазец.doc&quot; title=&quot;Образец заполнения&quot; target=&quot;_blank&quot;&gt;Образец заполнения заявления о переходе на УСН&lt;/a&gt;) и подать его в налоговую, вместе остальными документами, при регистрации.&lt;/div&gt;
&lt;div class=&quot;notify&quot;&gt;ВАЖНО! При расчете налогов надо быть очень внимательными. Все ваши огрехи за год всплывут разом и могу оказаться очень неприятными. Согласно какому-то там постановлению, все компании работающие на УСН уплачивают налог ежеквартально, а отчетность сдают один раз - до первого апреля следующего за отчетным периодом года. Ну, короче за 2009 год отчетность надо подать до 1 апреля 2010.&lt;/div&gt;</description>
			<pubDate>Thu, 7 Jan 2010 23:05:00 +0400</pubDate>
			<guid isPermaLink="false">22</guid>
		</item>
		
		<item>
			<title>Хэширование имен загружаемых файлов в Django, часть вторая</title>
			<link>http://betalabs.ru/2010-01-06/xeshirovanie_imen_zagruzhaemyx_fajlov_v_django_chast_vtoraja/</link>
			<description>&lt;div&gt;В прошлой реализации хранилища файлов с хэшированием имен файлы были доступны клиентам сайта по хэшированному имени, что не всегда удобно &amp;mdash; файлы, передаваемые клиентам сайта, не имели осмысленных имён. Решая эту проблему, все хранилище было переработано и теперь представляет собой приложение. Кроме того, требуется дополнительно настроить frontend-сервер. Для начала несколько слов о самом принципе работы системы:&lt;/div&gt;
&lt;div style=&quot;text-align: center;&quot;&gt;&amp;nbsp;&lt;a class=&quot;flyout&quot; href=&quot;http://static.betalabs.ru/media/upload/Images/cache/djangosha1storagenginx___display.jpg&quot;&gt;&lt;img width=&quot;150&quot; height=&quot;96&quot; border=&quot;0&quot; alt=&quot;Схема работы Django SHA1Storage: &quot; title=&quot;Схема работы Django SHA1Storage: &quot; src=&quot;http://static.betalabs.ru/media/upload/Images/cache/djangosha1storagenginx___thumbnail.jpg&quot;&gt;&lt;/img&gt;&lt;/a&gt;&lt;/div&gt;
&lt;ul type=&quot;none&quot;&gt;
	&lt;li&gt;1. Клиент запрашивает файл у веб-сервера (frontend, в нашем случае это nginx).&lt;/li&gt;
	&lt;li&gt;2. nginx перенаправляет запрос к Django (backend), согласно параметрам локации (location), которой соответствует URI запрошенного файла.&lt;/li&gt;
	&lt;li&gt;3. Django принимает запрос, обрабатывает URL и возвращает nginx&#39;у ответ с кодом 200, содержащий реальный путь до файла (в заранее заданной локации) в заголовке X-Accel-Redirect, а также тип содержимого файла в заголовке Content-type, основанный на расширении изначального имени файла.&lt;/li&gt;
	&lt;li&gt;4, 5, 6. nginx обрабатывает путь в X-Accel-Redirect и в ответ на исходный запрос (пункт 1) клиента передаёт ему файл из директории, соответствующей локации, если файл найден. Заголовок Content-type, полученный от Django, при этом сохраняется.&lt;/li&gt;
&lt;/ul&gt;
&lt;div&gt;Теперь обо всем по порядку. В первую очередь настроим frontend:&lt;/div&gt;
&lt;div lang=&quot;bash&quot; style=&quot;background: rgb(221, 221, 221) none repeat scroll 0% 0%; overflow: auto; width: 520px; -moz-background-clip: border; -moz-background-origin: padding; -moz-background-inline-policy: continuous;&quot; class=&quot;highlight&quot;&gt;
&lt;pre&gt;
    server {
    listen mysite.ru:80;
    server_name mysite.ru www.mysite.ru;

# Нам совершенно не обязательно проксировать все запросы.
# Поэтому ограничиваемся проверкой запросов вида
# http://mysite.ru/media/upload/some_file.ext

# Передаём изменённый GET-запрос Django. В ответ мы должны получить ответ с
# заголовком X-Accel-Redirect.
    location /media/upload {
        rewrite ^/media/upload/(.*) /nginx/?filename=upload/$1 break;

        fastcgi_pass unix:/path/to/django&#39;s/fcgi.sock;
        include /etc/nginx/fastcgi_params;
    }
 

# Эта локация отражает реальный путь до директории хранилища наших файлов.
# Именно сюда Django будет ссылаться в X-Accel-Redirect.
# Прямой доступ к файлам клиентам сайта запрещён (для этого нужна директива internal).
    location /sha1storage {
        internal;
        alias /path/to/project/media/sha1storage;
    }

# Запрещаем  клиентам сайта прямые запросы к Django в локацию /nginx
    location /nginx {
        internal;
    }
 

# Запрещаем клиентам сайта прямой доступ к файлам хранилища в обход Django
    location /media/sha1storage {
        internal;
    }

# Локация с файлами, доступными для загрузки клиентам сайта не из sha1storage.
# Сюда Django перенаправит запрос посредством X-Accel-Redirect, если не
# найдёт файл в sha1storage.
    location /upload {
       internal;
       alias /home/www/www51/betalabs.ru/media/upload;
    }
}
&lt;/pre&gt;
&lt;/div&gt;
&lt;div&gt;Как это все в итоге работает:&amp;nbsp;nginx получает запрос от клиента. Если путь запрашиваемого файла начинается с /media/upload/, то делается запрос к Django по адресу вида &#39;/nginx/?filename=upload/filename.ext&#39;, с передачей в GET-переменной filename пути до файла, с указанием изначального имени. Обратите внимание, что в запросе к Django обрезается /media/, поскольку Django всегда работает с файлами внутри директории, указанной в MEDIA_ROOT.&lt;/div&gt;
&lt;div&gt;&amp;nbsp;&lt;/div&gt;
&lt;div&gt;Для настройки django нам понадобиться приложение &lt;a target=&quot;_blank&quot; href=&quot;https://code.google.com/p/django-sha1storage/&quot;&gt;SHA1Storage&lt;/a&gt;.&lt;/div&gt;
&lt;div&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;alert&quot;&gt;ВНИМАНИЕ. На данный момент приложение находится в стадии beta-тестирования и имеет некоторые ограничения в настройке, которые, я надеюсь, в ближайшее время будут ликвидированы. Если вы найдете какие-то баги, буду очень благодарен за багрепорт.&lt;/div&gt;
&lt;div&gt;&amp;nbsp;&lt;/div&gt;
&lt;div&gt;Для установки добавляем его в INSTALLED_APPS:&lt;/div&gt;
&lt;div&gt;&amp;nbsp;&lt;/div&gt;
&lt;div lang=&quot;django&quot; class=&quot;highlight&quot; style=&quot;background: rgb(221, 221, 221) none repeat scroll 0% 0%; overflow: auto; width: 520px; -moz-background-clip: border; -moz-background-origin: padding; -moz-background-inline-policy: continuous;&quot;&gt;
&lt;pre&gt;
INSTALLED_APPS = (
    &#39;sha1storage&#39;,
)

# Если хотите использовать это хранилище как основное, можно указать параметр DEFAULT_FILE_STORAGE.
DEFAULT_FILE_STORAGE = &#39;sha1storage.storage.SHA1FilenameFileSystemStorage&#39;&lt;/pre&gt;
&lt;/div&gt;
&lt;div&gt;
&lt;div&gt;&amp;nbsp;&lt;/div&gt;
&lt;div&gt;Если вы хотите использовать хранилище только для отдельных файлов, то к полю файла в модели необходимо добавить свойство storage.&lt;/div&gt;
&lt;div&gt;&amp;nbsp;&lt;/div&gt;
&lt;div&gt;В urls.py необходимо добавить обработку URL обработчика sha1storage:&lt;/div&gt;
&lt;pre&gt;
urlpatterns = patterns(&#39;&#39;,
 (r&#39;nginx/&#39;, &#39;sha1storage.views.get_real_filename&#39;),
);
&lt;/pre&gt;
&lt;/div&gt;
&lt;div&gt;В принципе это все. Теперь при загрузке файла его имя будет хэшироваться, и он будет сохраняться в папку /path/to/project/media/sha1storage/upload_to_mode_field_path/. При этом модели будет передаваться не хэш от имени файла, а само имя. Из дополнительных особенностей: все файлы, кроме стандартной графики, sha1storage возвращает с заголовком Content-Disposition: attachment, в качестве полумеры для закрытия XSS-уязвимостей, пока не реализованы более строгие алгоритмы защиты.&lt;/div&gt;</description>
			<pubDate>Wed, 6 Jan 2010 18:40:00 +0400</pubDate>
			<guid isPermaLink="false">23</guid>
		</item>
		
		<item>
			<title>Регистрируем ИП или первый шаг к своему делу</title>
			<link>http://betalabs.ru/2009-12-27/registriruem_ip_ili_pervyj_shag_k_svoemu_delu/</link>
			<description>&lt;div&gt;Помимо программирования, я планирую писать в блоге и о юридических аспектах своей жизни, поскольку они составляют немалую ее часть. Писать я буду стараться максимально просто, именно в ключе практического применения. Собственно, одна первая статья из этой серии у меня уже есть - это кратенький рассказ-жалоба на &quot;Ваше право&quot;. Я думаю, про то, как вести себя с такого рода &quot;посетителями&quot;, я напишу дополнительно. Сейчас же я хочу поделиться опытом регистрации себя в качестве Индивидуального Предпринимателя. Зачем это нужно? Ну, во-первых, это упрощает взаимодействие с некоторыми клиентами, поскольку при наличии ИП мы можем заключать договора Юрлицо-Юрлицо, а к таким договорам у многих клиентов больше доверия. Во-вторых, это вообще легализует деятельность в качестве оутсорсера. Конечно, можно фрилансить и без всяких ИП, однако, при постоянном извлечении прибыли от оказания услуг, налоговая может трактовать это как незаконное предпринимательство, даже если вы ежегодно подаете декларацию о доходах.&lt;/div&gt;
&lt;div&gt;Строго говоря, решение об открытии ИП - это вопрос сугубо личный, и как-то склонять к этому я не собираюсь, тем более, что переход к официальному предпринимательству накладывает ряд дополнительных обязательств. Поэтому я буду писать не о том, зачем, а о том как это делается.&lt;/div&gt;
&lt;div&gt;Вообще, налоговая история человека начинается с получения им Индивидуального Номера Налогоплательщика - ИНН. Вполне вероятно, что у вас такого документа как раз и нету. В&amp;nbsp;принципе, начать регистрацию можно и без него, но в процессе все равно придется получать. Поэтому я рекомендую, для тех кто пока не встал на учет в налоговом органе, сделать это, как говориться, в первую голову. Благо, процедура совсем простая и безболезненная. Для начала вам надо узнать, где располагается ваше районное отделение налоговой. Лучше всего воспользоваться формой на официальном сайте налоговой - &lt;a href=&quot;http://service.nalog.ru:8080/addrno.do&quot; target=&quot;_blank&quot;&gt;http://service.nalog.ru:8080/addrno.do&lt;/a&gt;.&lt;/div&gt;
&lt;div class=&quot;notify&quot;&gt;ПРЕДУПРЕЖДАЮ. Форма может глючить. Во всяком случае, в Firefox3.5@Ubuntu глючит - после второго шага (выбор региона) сразу выводит реквизиты центрального отделения по всему региону, без уточнения адреса. Побороть глюк можно, нажав кнопку &quot;назад&quot;, а потом сразу &quot;дальше&quot;, хотя в других браузерах, возможно, и нет глюков или есть, но другие. В любом случае, поборов эту форму, вы получите адреса или телефоны, которые нам нужны и для получения ИНН, и для подачи документов на регистрацию.&lt;/div&gt;
&lt;div&gt;ИНН делается за один день - пришли, отдали паспорт, подождали, получили - так что это самая простая из предстоящих нам операций.&lt;/div&gt;
&lt;div&gt;Итак, после получения ИНН можно смело приступать непосредственно к подготовке нашего основного визита в налоговую. Первое, что нам предстоит, так это заполнить заявление по форме p21001. &lt;a title=&quot;Форма P21001: Бланк&quot; href=&quot;http://static.betalabs.ru/media/upload/Files/2009/12/27/p21001.xls&quot;&gt;Вот бланк самого заявления&lt;/a&gt;, и вот&amp;nbsp;&lt;a title=&quot;Образец заполнения&quot; href=&quot;http://static.betalabs.ru/media/upload/Files/2009/12/27/p21001_Образец.xls&quot; target=&quot;_blank&quot;&gt;Образец заполнения&lt;/a&gt;. На последнем листе необходимо указать список видов деятельности, которыми вы собираетесь заниматься - так называемые коды ОКВЭД. Найти справочник в сети не проблема, но лично мне понравился больше всего &lt;a href=&quot;http://getokved.ru/&quot; target=&quot;_blank&quot;&gt;getokved.ru&lt;/a&gt;. Все, что касается околокомпьютерной деятельности, описывается в разделе 72:&lt;/div&gt;
&lt;ul&gt;
&lt;li&gt;72.1 Консультирование по аппаратным средствам вычислительной техники&lt;/li&gt;
&lt;li&gt;72.2 Разработка программного обеспечения и консультирование в этой области&lt;/li&gt;
&lt;li&gt;72.3 Обработка данных&lt;/li&gt;
&lt;li&gt;72.4 Деятельность по созданию и использованию баз данных и информационных ресурсов&lt;/li&gt;
&lt;li&gt;72.5 Техническое обслуживание и ремонт офисных машин и вычислительной техники&lt;/li&gt;
&lt;li&gt;72.6 Прочая деятельность, связанная с использованием вычислительной техники и информационных технологий&lt;/li&gt;
&lt;/ul&gt;
&lt;div&gt;Более подробную расшифровку кодов можете найти все на том же сайте, конкретно &lt;a href=&quot;http://getokved.ru/k3&quot; target=&quot;_blank&quot;&gt;тут&lt;/a&gt;.&lt;/div&gt;
&lt;div&gt;Если вы обратили внимание, в заявлении на всех страницах в правом верхнем углу указывается номер листа. Но на листе с видами деятельности поле с номером пустое, и его нужно заполнить. Все дело в том, что на странице всего 10 полей для кодов, но закон никак не ограничивает вас в количестве видов деятельности. Следовательно, вы можете приложить к заявлению несколько таких листов, соответственно последовательно их нумеруя. Так же стоит обратить внимание, что основным видом деятельности будет считаться код, который указан первым. Если честно, я не знаю зачем вообще выделяется основной вид деятельности, но так или иначе, этот факт стоит учитывать - на всякий случай.&lt;/div&gt;
&lt;div class=&quot;alert&quot;&gt;ВАЖНО! После заполнения всех кодов, не забудьте указать их количество на первой странице заявления.&lt;/div&gt;
&lt;div&gt;Еще нам может пригодиться заявление о переходе на Упрощенную Систему Налогообложения - УСН. О том, что это такое и с чем его едят, я напишу отдельно, в ближайшее же время. Там же и выложу бланк заявления с образцом.&lt;/div&gt;
&lt;div&gt;Кроме этих двух заявлений (или одного, если вы решите не переходить на УСН, что маловероятно), нам понадобится квитанция об оплате госпошлины в размере 400 рублей. Реквизиты для платежа вы можете узнать по телефону или в интернете. Правда, как это ни странно, на сайте налоговой я этих данных не нашел - у них вообще поиск периодически падает с ошибкой &quot;#1040: Too many connections&quot;. Для всех москвичей реквизиты одинаковые, поскольку регистрацию всех ИП, ООО&amp;nbsp;и прочих осуществляет ИФНС №46. Для удобства выкладываю  &lt;a title=&quot;для оплаты госпошлины в размере 400 рублей за регистрацию ИП&quot; href=&quot;http://static.betalabs.ru/media/upload/Files/2009/12/27/квитанция_бланк.doc&quot; target=&quot;_blank&quot;&gt;Бланк квитанции&lt;/a&gt; и  &lt;a title=&quot;для оплаты госпошлины в размере 400 рублей за регистрацию ИП&quot; href=&quot;http://static.betalabs.ru/media/upload/Files/2009/12/27/квитанция_образец.doc&quot; target=&quot;_blank&quot;&gt;Образец заполнения квитанции&lt;/a&gt;, который заполнен реквизитами для москвичей.&lt;/div&gt;
&lt;div class=&quot;alert&quot;&gt;ВНИМАНИЕ! Если вы будете использовать заполненную квитанцию, ОБЯЗАТЕЛЬНО уточните и проверьте реквизиты платежа - они могут измениться в любой момент.&lt;/div&gt;
&lt;div&gt;Итак, теперь можно печатать все наши документы и перемещаться в банк и к нотариусу - в произвольном порядке. Оплачивать квитанцию можно в любом банке, но лучше всего в Сбербанке, потому как в других может быть комиссия за оплату. Нотариус подойдет любой - от него нам требуется заверение нашей подписи на третьей странице нашего заявления.&lt;/div&gt;
&lt;div class=&quot;notify&quot;&gt;КСТАТИ. Расписываться дома на третьей странице строго запрещается - это можно делать только в присутствии нотариуса, иначе не заверит. Вообще, лучше нигде в заявлении не расписываться - нотариус скажет, где и как подписаться.&lt;/div&gt;
&lt;div&gt;Мне такое заверение обошлось в 500 рублей, хотя цифра эта у разных нотариусов может и отличаться. Я особо не парился, и просто сходил к ближайшему.&lt;/div&gt;
&lt;div&gt;Кстати, где-то в процессе всех этих кувырканий, нам надо сделать копию ИНН и паспорта. Из паспорта нам надо два разворота - с основными паспортными данными и с пропиской.&lt;/div&gt;
&lt;div class=&quot;notify&quot;&gt;КСТАТИ. Копию паспорта лучше делать на одном листе, иначе придется сшивать два листа, заклеивать с обратной стороны место скрепления бумажкой, расписываться на ней так, чтобы часть росписи попадала на бумажку, а часть на основной лист и писать &quot;Прошито и пронумеровано 2 листа&quot;. В заявлении за вас это сделает нотариус, а тут придется возиться самостоятельно. Так что уж лучше постараться и сделать оба разворота паспорта на одной бумажке. Лично я просто отсканировал, склеил в GIMP и распечатал.&lt;/div&gt;
&lt;div&gt;Теперь мы имеем полный комплект документов, необходимых для превращения из Человека Разумного в Человека Предприимчивого - паспорт, копию паспорта, копию ИНН, заявление о регистрации, заявление о переходе на УСН (ежели собираемся переходить) и оплаченную квитанцию. Осталось передать эти документы уполномоченным органам и ждать 5 рабочих дней. На самом деле, в законе написано &lt;span style=&quot;text-decoration: underline;&quot;&gt;не более&lt;/span&gt; пяти рабочих дней, однако, согласно какому-то там письму &quot;О&amp;nbsp;не сокращении сроков&quot;, налоговая использует отпущенный срок полностью, якобы для уменьшения количества ошибок при оформлении.&lt;/div&gt;
&lt;div&gt;Подача документов в Москве происходит следующим образом. Первым делом необходимо прибыть по адресу:&amp;nbsp;Москва, Походный проезд, владение 3, корп.1.&amp;nbsp;Как проехать - описывать не буду, думаю, все мы умеем пользоваться гугл-яндекс-картами. По прибытии нам необходимо отыскать корпус 1, подъезд 3. Это уже сложнее, поэтому прилагаю схему &lt;a href=&quot;http://maps.yandex.ru/?um=1JzxT2CdInml5ljsmjH-bD8qJ91DhLIC&amp;l=sat%2Cskl&quot; target=&quot;_blank&quot;&gt;&amp;laquo;ИФНС №46&amp;raquo; на Яндекс.Картах&lt;/a&gt;.&lt;/div&gt;
&lt;div&gt;Нам нужен зал №4 - это который направо (налево зал №3, который нам пригодится позже). В четвертом зале располагаются веселенькие терминалы регистрации в электронной очереди. Если возле них вдруг не обнаруживается приветливый юноша или знойная барышня, придется самостоятельно отыскать кнопку D. Автомат плюнет в нас чеком с циферками DХХХ, вместе с которым мы уютно располагаемся на любезно предоставленных стоячих местах. Сидячие, в принципе, тоже присутствуют, но сомневаюсь, что кто-то нам уступит. Разнообразить томительную очередь можно, наблюдая за движениям электронной очереди, красочно&amp;nbsp; - в двух цветах - иллюстрируемую на множестве табло. Как только очередь соизволит дойти до нас, внимательно запоминаем номер окошка и торопимся в зал №3. Там, отыскав нужный номер, мы встретим ясную приветливую мину... Нежно улыбаемся в ответ и передаем паспорт, чек с номером и пакет документов в руки ответственного работника.&lt;/div&gt;
&lt;div class=&quot;notify&quot;&gt;КСТАТИ. Перед тем как проникать в зал №3, лучше выключить свой мобильный телефон - по правилам в залах ИФНС разговаривать по телефону нельзя. Да и опасно: охранники в третьем зале зверские - ругаются и хамят.&lt;/div&gt;
&lt;div&gt;Пару минут спустя нам вернут паспорт, заставят подписать расписку о вручении, подарят копию этой расписки и, одарив лучезарной улыбкой, отпустят с миром. Теперь можно заглянуть в туалет, перекусить в столовой и отчаливать в родные пенаты. Впереди нас ожидает пять дней релаксации.&lt;/div&gt;
&lt;h3&gt;После дождичка в четверг.&lt;/h3&gt;
&lt;div&gt;По истечении отпущенного налоговикам срока в размере пяти рабочих дней, нам необходимо совершить еще один набег на их логово. Лично я прибыл на место дислокации примерно в 14:30, снова получил плевок от агрегата (на этот раз при нажатии кнопочки M). Номер тут же появился на табло и я проследовал к нужному окну. Индифферентный молодой человек просмотрел мой паспорт, забрал расписку и, взяв три подписи в каком-то акте, выдал мне мои документы - Свидетельство, выписку из ЕГРИП и уведомление о постановке на учет. Вот и все - в общей сложности я пробыл в налоговой три минуты одиннадцать секунд. Вышел я уже преобразившийся в Человека Предприимчивого.&lt;/div&gt;
&lt;div&gt;&amp;nbsp;&lt;/div&gt;
&lt;div&gt;Как видите, процедура достаточно проста и не очень обременительна. Правда, если вы переходите на УСН, еще надо будет появиться в районной налоговой, чтобы получить еще одно уведомление о постановке на учет по упрощенке. Но это придется делать не сразу - по закону налоговая может делать это уведомление в течение месяца. Так что, прежде чем ехать, обязательно позвоните и уточните состояние дел. Еще нам предстоит побывать в пенсионном, открыть счет в банке и начать вести деятельность. И, конечно, бухгалтерия, куда без нее. Обо всем этом я обязательно напишу... постепенно =)&lt;/div&gt;</description>
			<pubDate>Sun, 27 Dec 2009 22:41:00 +0400</pubDate>
			<guid isPermaLink="false">18</guid>
		</item>
		
		<item>
			<title>Яндекс крутит гайки</title>
			<link>http://betalabs.ru/2009-12-27/jandeks_krutit_gajki/</link>
			<description>&lt;div&gt;О том что Яндекс поменял алгоритм знают уже все. Причем шум вокруг нового алгоритма не утихает до сих пор - очень уж сильно изменилась выдача. Много социального контента попало в топ, много коммерческого вылетело. Сам я не СЕО-шник, но хочу поделиться впечатлениями от происходящего не как айтишник, а как владелец интернет-магазина, активно продвигаемого в своем сегменте.&lt;/div&gt;
&lt;div&gt;&amp;nbsp;&lt;/div&gt;
&lt;div&gt;К новому году мы начали готовиться за нескольку месяцев. Набор стандартный - статьи для веса и биржи для скорости. Биржи были запущены примерно в начале-середине октября (как раз незадолго до смены алго), а статьи чуть позднее - ближе к концу октября. Все шло как положено - вылезли мы по основным запросам в топ 3, повесели несколько дней и вот тут-то все и началось.&lt;/div&gt;
&lt;div&gt;Сразу после смены алгоритма мы уехали на вторую страницу по основным запросам и потеряли по 2-3 позиции в низкосастотниках. Причем, это отразилось в основном на &quot;свежих&quot; ключевиках, а старые наши слова практически и не покачнулись. Ссылки у нас были довольно качественные - не с говносайтов, следовательно яндекс увеличил значимость возраста ссылок. Собственно, особенно предпринимать было нечего, так что мы просто тихо наблюдали за развитием событий. Через какое-то время низкочастотники вернулись в норму и чуть-чуть прибавили основные запросы - это доиндексировались статьи. И&amp;nbsp;на этом всякие эвалюции закончились и до топа по основным запросам мы не доползли. =\&lt;/div&gt;
&lt;div&gt;&amp;nbsp;&lt;/div&gt;
&lt;div&gt;Среди СЕОшников сейчас бытует мнение, что Яша специально мутит воду коммерческим сайтам (запускает соцресурсы в топ по явно коммерческим запросам, например), чтобы втянуть больше игроков в Директ. Что ж, вполне реалистично звучит. Мы в директ решили не лезть, поскольку оставшийся трафик с низкочастотников и основных запросов нас пока более-менее удовлетворяет, но вот многие кто вылетел из топа вынуждены теперь тратить деньги на контекстную рекламу.&lt;/div&gt;
&lt;div&gt;&amp;nbsp;&lt;/div&gt;
&lt;div&gt;PS:&amp;nbsp;Тут с неделю назад подал заявку на платную регистрацию в ЯК - все давно собирался. До сих пор не рассмотрели, хотя должны обрабатывать за сутки. В&amp;nbsp;саппорте извиняются и просят подождать. Сдается мне, что многие ломанулись не только в директ, но и в платный каталог, да так что менеджеры не справляются. Так что, если в яндексе хотели заработать на смене алгоритма, им это явно удалось.&lt;/div&gt;</description>
			<pubDate>Sun, 27 Dec 2009 16:48:00 +0400</pubDate>
			<guid isPermaLink="false">21</guid>
		</item>
		
		<item>
			<title>jQuery, :hidden и тэг option</title>
			<link>http://betalabs.ru/2009-12-26/jquery_hidden_i_teg_option/</link>
			<description>&lt;div&gt;В jQuery имеет место одна проблема с псевдоцсс селектором :hidden - в браузерах отличных от FireFox конструкция вида&lt;/div&gt;
&lt;div&gt;&amp;nbsp;&lt;/div&gt;
&lt;div lang=&quot;javascript&quot; style=&quot;background: rgb(221, 221, 221) none repeat scroll 0% 0%; overflow: auto; -moz-background-clip: border; -moz-background-origin: padding; -moz-background-inline-policy: continuous; width: 520px;&quot; class=&quot;highlight&quot;&gt;
&lt;pre&gt;
&amp;lt;script&amp;gt;
$(document).ready(function() {
	$(&amp;quot;*:hidden&amp;quot;).remove();
});
&amp;lt;/script&amp;gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;div&gt;&amp;nbsp;&lt;/div&gt;
&lt;div&gt;удалит не только действительно невидимые объекты, но и все options.&lt;/div&gt;
&lt;div&gt;Проблема кроется в текущей реализации алгоритма определения видимости:&lt;/div&gt;
&lt;div lang=&quot;javascript&quot; class=&quot;highlight&quot; style=&quot;background: rgb(221, 221, 221) none repeat scroll 0% 0%; overflow: auto; width: 520px; -moz-background-clip: border; -moz-background-origin: padding; -moz-background-inline-policy: continuous;&quot;&gt;
&lt;pre&gt;
Sizzle.selectors.filters.hidden = function(elem){
	return elem.offsetWidth === 0 || elem.offsetHeight === 0;
};&lt;/pre&gt;
&lt;/div&gt;
&lt;div&gt;&amp;nbsp;&lt;/div&gt;
&lt;div&gt;Фаерфокс этот момент обрабатывает вполне корректно - в качестве габаритов option он всегда возвращает размеры отрисованного select. А вот остальные браузеры (возможно не все конечно, но основные) сплоховали - всегда возвращают 0, что и приводит jQuery в замешательство.&lt;/div&gt;
&lt;div&gt;&amp;nbsp;&lt;/div&gt;
&lt;div&gt;В принципе есть два варианта решения данной проблемы. Первый сгодится если проблемы возникают только с вашим кодом - тут можно просто изменить конструкцию селектора:&lt;/div&gt;
&lt;div&gt;&amp;nbsp;&lt;/div&gt;
&lt;div lang=&quot;javascript&quot; style=&quot;background: rgb(221, 221, 221) none repeat scroll 0% 0%; overflow: auto; width: 520px; -moz-background-clip: border; -moz-background-origin: padding; -moz-background-inline-policy: continuous;&quot; class=&quot;highlight&quot;&gt;
&lt;pre&gt;
&amp;lt;script&amp;gt;
$(document).ready(function() {
	$(&amp;quot;*:hidden:not(option)&amp;quot;).remove();
});
&amp;lt;/script&amp;gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;div&gt;&amp;nbsp;&lt;/div&gt;
&lt;div&gt;Хуже если эта проблема мешает работе каких-либо плагинов. Решить ее можно &amp;quot;подменив&amp;quot; селектор &amp;quot;:hidden&amp;quot;, что, между прочим, совсем не сложно.&lt;/div&gt;
&lt;div&gt;&amp;nbsp;&lt;/div&gt;
&lt;div lang=&quot;javascript&quot; style=&quot;background: rgb(221, 221, 221) none repeat scroll 0% 0%; overflow: auto; width: 520px; -moz-background-clip: border; -moz-background-origin: padding; -moz-background-inline-policy: continuous;&quot; class=&quot;highlight&quot;&gt;
&lt;pre&gt;
&amp;lt;script&amp;gt;
// Удалять настоящий селектор не за чем.
// Просто переименуем его в :realhidden.
jQuery.expr[&#39;:&#39;].realhidden = jQuery.expr[&#39;:&#39;].hidden;
// А на его место поместим наш собственный, с дополнительной проверкой
jQuery.expr[&#39;:&#39;].hidden = function(elem) {
	// Если обрабатываемый элемент это option возвращаем false
  	if (elem.nodeName == &amp;quot;OPTION&amp;quot;) {
		return false;
  	} else { // Если нет - передаем управление оригинальному селектору :hidden 
 		return jQuery(elem).is(&amp;quot;:realhidden&amp;quot;);
	}
};
$(document).ready(function() {
	// Сработает функция jQuery.forceHidden и все опции останутся на месте
	$(&amp;quot;#test :hidden&amp;quot;).remove(); 	
});

&amp;lt;/script&amp;gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;div&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;notify&quot;&gt;Главное, чтобы замена селектора произошла до выполнения кода скрипта, который будет ее использовать. Скорее всего достаточно того, что он выполняется до события $(document).ready, но в некоторых случаях могут быть варианты - просто будте внимательный.&lt;/div&gt;</description>
			<pubDate>Sat, 26 Dec 2009 05:55:00 +0400</pubDate>
			<guid isPermaLink="false">20</guid>
		</item>
		
		<item>
			<title>Почему я редко пишу в блог</title>
			<link>http://betalabs.ru/2009-12-18/pochemu_ja_redko_pishu_v_blog/</link>
			<description>&lt;div&gt;Есть у меня одна проблема с подбором материала - мне все время кажется, что выбранная мной тема будет не нужна и не интересна. Либо, кто-то это уже точно написал, либо она вообще не достойна опубликования. Из-за этой проблемы прерывались мои неоднократные попытки вести блоги на блогосервисах, и из-за нее же я не публикую, и вообще не описываю, большинство из своих наработок. Причем, я отлично знаю, что в десятках блогов разбирают одни и те же проблемы, разбирают одни и те же решения и все такое прочее. Но сам, почему-то, не могу - только если себя заставлять. А написанное через силу вряд ли вообще будет читабельно. В чем корни моей проблемы я,&amp;nbsp;увы, пока не нашел, однако я стараюсь бороться с ней, потому что понимаю - хоть я и не очень крутой программист, но у меня есть чем поделиться и о чем рассказать. И я буду стараться рассказывать. Я очень надеюсь, что постепенно в этом блоге появятся постоянные читатели, которым будет интересно и полезно. И надеюсь они будут задавать вопросы - мне всегда было легче отвечать на вопросы, чем упреждать их своевременным описанием - вопрос для меня как катализатор.&amp;nbsp;&lt;/div&gt;</description>
			<pubDate>Fri, 18 Dec 2009 04:06:00 +0400</pubDate>
			<guid isPermaLink="false">19</guid>
		</item>
		
		<item>
			<title>jQuery abeInline plugin</title>
			<link>http://betalabs.ru/2009-12-12/jquery_abeinline_plugin/</link>
			<description>&lt;div&gt;Я наконец оформил одну из функцию, которую написал в процессе разработки этого блога, в виде плагина к jQuery. Получился плагин abeInline - средство для inline редактирования контента. Конечно, пока она еще не полная, так сказать beta-версия, но в принципе работоспособная. Сейчас она умеет конвертировать блоки в text input и в textarea, отправлять результат по AJAX и обрабатывать несколько разных блоков как единую форму.&lt;/div&gt;
&lt;div&gt;&amp;nbsp;&lt;/div&gt;
&lt;div&gt;&lt;a href=&quot;/abe-inline/&quot;&gt;Документация&lt;/a&gt; - тоже пока не полная =(&lt;/div&gt;
&lt;div&gt;&lt;a href=&quot;http://plugins.jquery.com/project/abe-inline&quot;&gt;Скачать&lt;/a&gt; - пока выложил только на jQuery, но планирую сделать проект на code.google.com с ропозиторием и багтреком.&lt;/div&gt;
&lt;div&gt;&lt;a href=&quot;/abe-inline/#license&quot;&gt;Лицензия&lt;/a&gt; - библиотека распространяется по Лицензии BSD.&lt;/div&gt;
&lt;div&gt;&amp;nbsp;&lt;/div&gt;
&lt;div&gt;Если честно, это первая библиотека открываемая мной публично. У меня есть одна черта, которая мне очень мешает в вопросе выкладывания своих наработок - мне все время кажется что работа настолько незакончена, что выкладывать ее неприлично. Помимо всего прочего, это распространяется и на запуск личных проектов - многие я не запустил именно потому, что они казались мне не готовыми. Сейчас я усердно борюсь с этими своими ощущениями - в конце концов, полевые испытания всегда самые эффективные. А если что-то в библиотеке не работает - никто же не отменял багтрекинг, патчи и новые версии. Вобщем, теперь я буду стараться выкладывать больше своих наработок - возможно кому-то что-то из них поможет.&lt;/div&gt;</description>
			<pubDate>Sat, 12 Dec 2009 12:01:00 +0400</pubDate>
			<guid isPermaLink="false">17</guid>
		</item>
		
		<item>
			<title>Подсветка синтаксиса, часть четветрая, заключительная</title>
			<link>http://betalabs.ru/2009-12-07/podsvetka_sintaksisa_chast_chetvetraja_zakljuchitelnaja/</link>
			<description>&lt;div&gt;Ну вот , кажется, и походит к концу моя эпопея с подсветкой синтаксиса. В процессе беседы, несколько для меня неожиданной, с Иваном Салагаевым, получил от него несколько разъяснений по его библиотеке и сам покопался в ней поглубже. В итоге, убрал из функции инициализации автоматический поиск блоков для подсветки и открыл функцию highlight для внешнего доступа. Кое-какие недочеты конечно остались, но я думаю разберусь со временем. Ивану огромное спасибо за библиотеку и за помощь.&lt;/div&gt;
&lt;div&gt;&amp;nbsp;&lt;/div&gt;
&lt;div&gt;Еще добавил вывод номеров строк, но он работает независимо от основной библиотеки.&lt;/div&gt;</description>
			<pubDate>Mon, 7 Dec 2009 19:30:00 +0400</pubDate>
			<guid isPermaLink="false">16</guid>
		</item>
		
		<item>
			<title>Подстветка синтаксиса, часть третья</title>
			<link>http://betalabs.ru/2009-12-05/podstvetka_sintaksisa_chast_tretja/</link>
			<description>&lt;div&gt;Задумался о том, что в текущей реализации подсветки кода я могу столкнуться с чрезмерным увеличением количества AJAX-запросов. Учитывая что на одной странице выводится до 20 записей, в каждой из которой может оказаться по несколько блоков кода, это чревато десятками запросов.&lt;/div&gt;
&lt;div&gt;&amp;nbsp;&lt;/div&gt;
&lt;div&gt;В&amp;nbsp;сети я нашел несколько скриптов для подсветки синтаксиса на JavaScript, однако, после нескольких экспериментов, я убедился что они не дают никаких реальных преимуществ. Самым качественным решением, из тех которые я нашел, является библиотека Ивана Салагаева (&lt;a href=&quot;http://softwaremaniacs.org/soft/highlight/&quot;&gt;http://softwaremaniacs.org/soft/highlight/&lt;/a&gt;). Но, во-первых, упакованная библиотека со всеми языками весит 78 Килобайт, а во-вторых, имеет несколько странную реализацию - подсветка осуществляется ТОЛЬКО&amp;nbsp;автоматически, основываясь на анализе кода, то есть нельзя вручную указать какой блок подсвечивать. Скорость его работы я не анализировал, поскольку для меня достаточным для отказа фактором стал именно вес библиотеки.&lt;/div&gt;
&lt;div&gt;&amp;nbsp;&lt;/div&gt;
&lt;div&gt;Поэтому я несколько оптимизировал свою систему. В&amp;nbsp;новой версии все блоки на странице обрабатываются одним AJAX&amp;nbsp;запросом. Для этого сначала генерируется форма, в которую агрегируются все блоки с кодом. Форма создается по правилам Django Formset, для удобства ее обработки на сервере.&lt;/div&gt;
&lt;div&gt;Полученный от сервера ответ разбит на блоки, которые очень легко разбираются и размещаются где положено.&lt;/div&gt;
&lt;div&gt;&amp;nbsp;&lt;/div&gt;
&lt;div&gt;
&lt;div lang=&quot;javascript&quot; style=&quot;background: rgb(221, 221, 221) none repeat scroll 0% 0%; overflow: auto; width: 520px; -moz-background-clip: border; -moz-background-origin: padding; -moz-background-inline-policy: continuous;&quot; class=&quot;highlight&quot;&gt;
&lt;pre&gt;
$(document).ready(function() {
	var form = $(&amp;quot;&amp;lt;form&amp;gt;&amp;quot;); // Создаем форму.
	var i = 0;
	$(&amp;quot;.highlight&amp;quot;).each(function() { //Перебираем все блоки требующие подсветки
		var hObject = $(this);
		hObject.attr(&amp;quot;id&amp;quot;, &amp;quot;highlight-&amp;quot;+i); // Присваиваем блоку уникальный id, чтобы потом найти его.
		// Создаем поле language для формы. Содержит название языка.
		language = $(&amp;quot;&amp;lt;input&amp;gt;&amp;quot;).attr({
			&amp;quot;name&amp;quot; : &amp;quot;form-&amp;quot;+i+&amp;quot;-language&amp;quot;,
			&amp;quot;value&amp;quot; :  hObject.attr(&amp;quot;lang&amp;quot;)? hObject.attr(&amp;quot;lang&amp;quot;) : &amp;quot;text&amp;quot;, // Если аттрибудет lang не задан, код будет возвращен без подсветки.
			&amp;quot;type&amp;quot; : &amp;quot;text&amp;quot;
		});
		// Создаем поле id для формы. Используется для идентификации блока с результатом.
		id = $(&amp;quot;&amp;lt;input&amp;gt;&amp;quot;).attr({
			&amp;quot;name&amp;quot; : &amp;quot;form-&amp;quot;+i+&amp;quot;-id&amp;quot;,
			&amp;quot;value&amp;quot; :  i,
			&amp;quot;type&amp;quot; : &amp;quot;text&amp;quot;
		});
		// Создаем поле code для формы. Содержит код для подсветки.
		code = $(&amp;quot;&amp;lt;textarea&amp;gt;&amp;quot;).attr({
			&amp;quot;name&amp;quot; : &amp;quot;form-&amp;quot;+i+&amp;quot;-code&amp;quot;,
		}).text(hObject.html());
		// Добавляем поля к форме.
		form.append(language);
		form.append(code);
		form.append(id);
		i++;
	});
	// Если есть хотя бы один блок
	if (i) {
		// Создаем поле form-TOTAL_FORMS. Нужен для Django Formset для обработки формы. 
		total = $(&amp;quot;&amp;lt;input&amp;gt;&amp;quot;).attr({
			&amp;quot;name&amp;quot; : &amp;quot;form-TOTAL_FORMS&amp;quot;,
			&amp;quot;type&amp;quot; : &amp;quot;text&amp;quot;,
			&amp;quot;value&amp;quot; : i
		});
		// Создаем поле form-INITIAL_FORMS. Нужен для Django Formset для обработки формы. В нашем случае всегда 0.
		initial  = $(&amp;quot;&amp;lt;input&amp;gt;&amp;quot;).attr({
			&amp;quot;name&amp;quot; : &amp;quot;form-INITIAL_FORMS&amp;quot;,
			&amp;quot;type&amp;quot; : &amp;quot;text&amp;quot;,
			&amp;quot;value&amp;quot; : &amp;quot;0&amp;quot;
		});
		// Добавляем поля к форме.
		form.append(total); 
		form.append(initial);
		// Отправляем запрос 
		$.post(&amp;quot;/tools/highlight/&amp;quot;, form.serialize(), function(response_data) {
			// Перебираем блоки ответа.
			$(response_data).find(&amp;quot;.highlighted&amp;quot;).each(function(){
				// Заменяем исходный блок, на подсвеченный, ореинтируясь на id.
				$(&amp;quot;#highlight-&amp;quot;+$(this).attr(&amp;quot;id&amp;quot;)).replaceWith($(this).html());
			});
		});
	}
});&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;</description>
			<pubDate>Sat, 5 Dec 2009 14:40:00 +0400</pubDate>
			<guid isPermaLink="false">14</guid>
		</item>
		
		<item>
			<title>Планы по ABE</title>
			<link>http://betalabs.ru/2009-12-01/plany_po_abe/</link>
			<description>&lt;div&gt;Решил записать ближайшие планы по развитию AbendBlatt Engine:&lt;/div&gt;
&lt;ul&gt;
	&lt;li&gt;Хочу добавить поддержку переводов для постов. Чтобы один пост можно было писать на разных языках и, при наличии переводов, выводить ссылки вида &amp;quot;Read in English&amp;quot;. Лично я не думаю что сразу начну этим пользоваться, однако это может оказаться полезным в будущем. Естественно, к этому необходимо прикрутить систему автоматического определения языка пользователя и хотя бы возможность выбрать язык по умолчанию.&lt;/li&gt;
	&lt;li&gt;Нужно добавить к постам возможность указания связанных записей. Во-первых это просто удобно, а во-вторых, учитывая что многие темы невольно разделяются на несколько частей, это необходимо для формирования цепочек.&lt;/li&gt;
	&lt;li&gt;Нужно доделать систему оповещений и подписки. Сейчас она функционирует через пень-колоду.&lt;/li&gt;
	&lt;li&gt;Экспорт RSS надо сделать более гибким. В первую очередь надо сделать отдельные ленты для колонок. Кроме того думаю сделать интерфейс для создания собственных сборок - например, если кто-то захочет ленту состоящую из нескольких колонок, но не всего блога.&lt;/li&gt;
	&lt;li&gt;Еще хочу сделать систему формирования выпусков. Под выпуском я подразумеваю некий связный набор постов. Причем с возможностью использования как уже опубликованных материалов, так и черновиков. Основная особенность выпуска в том, что он выводится как одна статья (с постраничным разбиением по контенту) и может быть скачана в видел PDF.&lt;/li&gt;
&lt;/ul&gt;
&lt;div&gt;PS: Ну, и естественно, в приоритетном режиме надо доделывать основные административные интерфейсы. Поскольку сейчас многие операции я проделываю напрямую в базе или через shell django-проекта.&lt;/div&gt;</description>
			<pubDate>Tue, 1 Dec 2009 16:54:00 +0400</pubDate>
			<guid isPermaLink="false">12</guid>
		</item>
		
		<item>
			<title>Подсветка синтаксиса, часть вторая</title>
			<link>http://betalabs.ru/2009-11-27/podsvetka_sintaksisa_chast_vtoraja/</link>
			<description>&lt;div&gt;Как я и думал, встраивание подсвеченного кода в пост в чистом виде оказалось решением скверным. Причем, помимо неудобств при редактиваронии, такой подход вызывает дополнительные проблесмы при экспотре RSS - лишние теги + лишние стили... ничего хорогошего вобщем. =)&lt;/div&gt;
&lt;div&gt;&amp;nbsp;&lt;/div&gt;
&lt;div&gt;В итоге я заменил способ подстветки - теперь это работает так:&lt;/div&gt;
&lt;div&gt;&amp;nbsp;&lt;/div&gt;
&lt;div&gt;В WYSIWYG вставляется контейнер с небработанным кодом, которому присваивается класс highlight и в аттрибуте lang указывается язык для подсветки. По окончании загрузаки страницы, из всех контейнеров класса highlight извлекается их содержимое и AJAX-запросом отправляется на сервер, а полученный результат замещает собой первоначальный контейнер.&lt;/div&gt;
&lt;div&gt;&amp;nbsp;&lt;/div&gt;
&lt;div&gt;Выполнено это пока не очень изящно, однако работает.&lt;/div&gt;
&lt;div&gt;&amp;nbsp;
&lt;div lang=&quot;javascript&quot; style=&quot;background: rgb(221, 221, 221) none repeat scroll 0% 0%; overflow: auto; width: 520px; -moz-background-clip: border; -moz-background-origin: padding; -moz-background-inline-policy: continuous;&quot; class=&quot;highlight&quot;&gt;
&lt;pre&gt;
$(document).ready(function() {
	$(&amp;quot;.highlight&amp;quot;).each(function() {
		var hObject = $(this);
		$.post(&amp;quot;/tools/highlight/&amp;quot;, {
			&amp;quot;language&amp;quot; : hObject.attr(&amp;quot;lang&amp;quot;)? hObject.attr(&amp;quot;lang&amp;quot;) : &amp;quot;text&amp;quot;,
			&amp;quot;code&amp;quot; : hObject.html()
		},
		function(response_data) {
			hObject.replaceWith($(&amp;quot;&amp;lt;div&amp;gt;&amp;quot;).append(response_data));
		});
	})
});&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;</description>
			<pubDate>Fri, 27 Nov 2009 23:03:00 +0400</pubDate>
			<guid isPermaLink="false">10</guid>
		</item>
		
		<item>
			<title>Хэширование имен загружаемых файлов в Django</title>
			<link>http://betalabs.ru/2009-11-26/xeshirovanie_imen_zagruzhaemyx_fajlov_v_django/</link>
			<description>&lt;div&gt;Уже давно я столкнулся в Django с проблемой загрузки файлов, с utf8 символами в названии. При сохранении такого файла django рушилась с руганью на ошибку конвертации ascii строки. Однако тогда разбираться с проблемой я не стал за ненадобностью - мне было проще переименовывать редкие файлы с utf8 именами.&lt;/div&gt;
&lt;div&gt;&amp;nbsp;&lt;/div&gt;
&lt;div&gt;А вот сейчас проблема эта всплыла опять и достаточно остро. За советом как лучше поступать с utf8 в именах файлов я обратился к хорошему сисадмину, который посоветовал мне вообще отказаться от сохранения юникода. Это чревато рисками обхода ограничений директории и получения доступа к исполняемым файлам системы.&lt;/div&gt;
&lt;div&gt;&amp;nbsp;&lt;/div&gt;
&lt;div&gt;&amp;quot;Дело в том, что из-за отсутствия гарантий однообразности восприятия специальных символов в имени файла, одни функции в системе могут счесть имя файла валидным и безопасным, а другие - иначе интерпретировать некоторые символы, в результате чего есть опасность нарваться на &amp;quot;../../../filename&amp;quot; в аргументах системному вызову, со всеми вытекающими.&amp;quot; &amp;copy; Arach&lt;/div&gt;
&lt;div&gt;&amp;nbsp;&lt;/div&gt;
&lt;div&gt;Поэтому, было решено просто хэшировать имена загружаемых файлов. Есть в этом конечно и минус (при скачивании файла несколько не удобно будет его идентифицировать), однако на данном этапе так будет лучше. А уж в процессе подумаю о решении и этой проблемы.&lt;/div&gt;
&lt;div&gt;&amp;nbsp;&lt;/div&gt;
&lt;div&gt;Изменить метод работы с файлами в Django очень просто - достаточно сделать специальный обработчик - подкласс django.core.files.storage.Storage. Мало того, в случае лишь частичной замены методов работы, можно наследовать стандартные дочерние классы.&lt;/div&gt;
&lt;div&gt;&amp;nbsp;&lt;/div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div lang=&quot;python&quot; class=&quot;highlight&quot; style=&quot;background: rgb(221, 221, 221) none repeat scroll 0% 0%; overflow: auto; width: 520px; -moz-background-clip: border; -moz-background-origin: padding; -moz-background-inline-policy: continuous;&quot;&gt;
&lt;pre&gt;
# -*- coding: utf-8 -*-
from django.core.files.storage import FileSystemStorage
from hashlib import sha1

class SHA1FilenameFileSystemStorage(FileSystemStorage):
	def get_valid_name(self, name):
		type=&amp;quot;&amp;quot;
		if name.rfind(&amp;quot;.&amp;quot;):
			type = name[name.rindex(&amp;quot;.&amp;quot;):]
		return str(sha1(name.encode(&amp;quot;UTF-8&amp;quot;)).hexdigest())+type&lt;/pre&gt;
&lt;/div&gt;
&amp;nbsp;&lt;/div&gt;
&lt;div&gt;В данном случае я наследовал стандартный класс хранилища файлов FileSystemStorage, переопределив в нем всего один метод. Метод get_valid_name отвечает за генерацию валидного имени файла ДО проверки доступности такого имени для сохранения. Сначала мы пытаемся отделить расширение файла, если таковое есть, после чего хэшируем входящее имя и прибавляем к нему расширение. Лично я предпочел установить этот обработчик в качестве стандартного в своих приложениях, для чего в settings.py определяется переменная DEFAULT_FILE_STORAGE.&lt;/div&gt;
&lt;div&gt;
&lt;div&gt;&amp;nbsp;&lt;/div&gt;
&lt;div lang=&quot;python&quot; class=&quot;highlight&quot; style=&quot;background: rgb(221, 221, 221) none repeat scroll 0% 0%; overflow: auto; width: 520px; -moz-background-clip: border; -moz-background-origin: padding; -moz-background-inline-policy: continuous;&quot;&gt;
&lt;pre&gt;
import django_useful
DEFAULT_FILE_STORAGE = &#39;django_useful.sha1storage.SHA1FilenameFileSystemStorage&#39;&lt;/pre&gt;
&lt;/div&gt;
&lt;div&gt;Если же надо применить данный обработчик только к определенным файлам, нужно в модели передать путь&amp;nbsp; его в качестве аргумента storage&lt;/div&gt;
&lt;div&gt;&amp;nbsp;&lt;br&gt;&lt;/br&gt;
&lt;div lang=&quot;python&quot; class=&quot;highlight&quot; style=&quot;background: rgb(221, 221, 221) none repeat scroll 0% 0%; overflow: auto; width: 520px; -moz-background-clip: border; -moz-background-origin: padding; -moz-background-inline-policy: continuous;&quot;&gt;
&lt;pre&gt;
from django.db import models
import django_useful

class Car(models.Model):
    photo = models.ImageField(storage=django_useful.sha1storage.SHA1FilenameFileSystemStorage(location=&#39;/media/photos&#39;))&lt;/pre&gt;
&lt;/div&gt;
&lt;div&gt;&amp;nbsp;&lt;/div&gt;
&lt;div&gt;PS:&amp;nbsp;Сегодня добавил в блог подсветку синтаксиса с помощью &lt;a target=&quot;_blank&quot; href=&quot;http://pygments.org&quot;&gt;Pygments&lt;/a&gt;. Реализовал в виде плагина для FCKEditor, но пока не очень изящно - код со стилями и прочей ересью вставляется прямо в пост. Не очень удобно редактировать - фактически приходится заново генерировать код полностью. Думаю что лучше будет заменить это все на вставку некого плейсхолдера, и генерировать код непосредственно перед выводом, с помощью PreView триггера.&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;</description>
			<pubDate>Thu, 26 Nov 2009 04:15:00 +0400</pubDate>
			<guid isPermaLink="false">8</guid>
		</item>
		
		<item>
			<title>Pisa XHTML2PDF и поддержка HTTP AUTH </title>
			<link>http://betalabs.ru/2009-11-21/pisa_xhtml2pdf_i_podderzhka_http_auth/</link>
			<description>&lt;div&gt;В рамках Торговой Системы понадобилось мне сделать генератор этикеток и ценников. Мой старый, генерировавший jpg картинки по строгому шаблону не годится, потому что информация на разхных ценниках разная, сответсвтенно и размеры у них должны быть динамические. Наиболее быстрым и удобным решением, мне показалось генерировать pdf. В&amp;nbsp;процессе размышлений и поиска, была найдена библиотека &lt;a href=&quot;http://www.xhtml2pdf.com/&quot;&gt;Pisa&lt;/a&gt;, конвертирующая html в pdf. Вот это совсем то что нужно. Само собой есть определенные ограничения в верстки, но главное она понимает большую часть html+css.&lt;/div&gt;
&lt;div&gt;&amp;nbsp;&lt;/div&gt;
&lt;div&gt;Все было неплохо, пока не наткнулся на 2 момента. Момент первый - если картинка вставляется в ячейку таблицы, у которой задан конкретный размер, то картинка эта отображается только в том случае, если у нее заданы аттрибуты width и height. То есть встраивать картинки с неопределенным размером в таблицу не получается. Поиски по комьюнити ничего не дали, поэтому полез в исходники. В&amp;nbsp;итоге обнаружилось следующее - в методе определяющем парметры картинки, в случае отсутствия жестко прописаных размеров, основным источником размеров почему-то считался родительский объект. То есть, если у картинки не заданы размеры, то Pisa пытеатся взять эти размеры у контейнера в котором этак картинка лежит. Если размеры родительского контейнера не прописаны в стилях, то все проходит более-менее нормально - Pisa, не получив от родительского объяекта объявления стиля вычисляет размеры картинки исходя из самой кратинки. А вот, если у родительского контйнера в стиля присутствует width или height, то тогда размеры картинки вычисляются именно их этих параметров. Причем делается это без конвертации значений, из-за чего, собсвтенно и существует проблема. Поскольку, в стилях размеры пишутся с указанием единиц измерения (в моем случае ячейка имела ширину 7cm), заначение это строковое. И естественно, умножение его на 96 dpi (именно так происходит &amp;quot;вычисление&amp;quot; размера картинки), естественно дает на выходе 0. Патчить это я не стал - решил ограничиться вычислением размеров картинки при генерации html шаблона, и указанием их в аттрибутах тега &amp;lt;img&amp;gt; - ИМХО, это наиболее верное решение.&lt;/div&gt;
&lt;div&gt;&amp;nbsp;&lt;/div&gt;
&lt;div&gt;А вот вторую проблему без патча решить не удалось. Связана она опять-таки с картинками. Pisa поддерживает два варианта обращения к картинкам - либо по абсолютному пути на сервере (для локальных файлов, естественно), либо по http или https. Однако при этом не была учтена особенность, что урл может быть защищен http-авторизацией. У меня все dev-площадки всегда закрыты от внешнего доступа. Да и некоторые рабочие системы тоже. Поэтому, снова пришлось лезть в исходники, но на этот раз патчить все-таки пришлось. Патч обеспечивает обработку URL&amp;nbsp;вида protocol://userid:passwd@host/path/to/file. То есть перед тем как запросить с сервера host файл /path/to/file система посылает Basic Auth заголовок с логином и паролем для доступа.&lt;/div&gt;
&lt;div&gt;&amp;nbsp;&lt;/div&gt;
&lt;div&gt;Патч сделан для версии XHTML2PDF / pisa 3.0.32&lt;/div&gt;
&lt;div&gt;Скачать: &lt;a href=&quot;http://static.betalabs.ru/media/upload/Files/2009/11/25/pisa_util.py.diff&quot; title=&quot;Pisa 3.0.32 http-auth patch&quot; target=&quot;_blank&quot;&gt;Pisa_3.0.32_http-auth_patch.diff&lt;/a&gt; ::  &lt;a href=&quot;http://static.betalabs.ru/media/upload/Files/2009/11/25/pisa_util.py.diff.gz&quot; title=&quot;Pisa 3.0.32 http-auth patch gziped&quot; target=&quot;_blank&quot;&gt;Pisa_3.0.32_http-auth_patch.gz&lt;/a&gt;&lt;/div&gt;
&lt;div&gt;&amp;nbsp;&lt;/div&gt;
&lt;div&gt;PS:&amp;nbsp;Пока копался в коде пизы, понял что в ближайшем будущем буду от нее отказываться - не устраивает архитектра и перегруженость. Слишком много не нужного в рамках проекта ТС&amp;nbsp;функционала.&lt;/div&gt;</description>
			<pubDate>Sat, 21 Nov 2009 21:04:00 +0400</pubDate>
			<guid isPermaLink="false">5</guid>
		</item>
		
		<item>
			<title>ЦЗППиП &quot;Ваше право&quot; - презумпция виновности</title>
			<link>http://betalabs.ru/2009-11-21/tszppip_vashe_pravo___prezumptsija_vinovnosti/</link>
			<description>&lt;div&gt;Пришли к нам в магазин недавно две женщины. Назвались какими-то именами, показали какие-то документы и заявили что они из Общественной Организации &amp;quot;Ваше право&amp;quot;. Показали девочкам нашим некое направление и собрались проводить какую-то проверку. Ни меня, ни Саши в магазине не было, а девчонки, само собой, растерялись. Позвонили нам, но по телефону трудно было в ситуации разобраться что к чему, поэтому проверку они провели, составили даже какой-то акт. В акте этом значилось несколько нарушений, не сказать что очень серьезных. Все их нам перессказли по телефону при этом объявив, что их организация не штрафующая, но зато они акт этот передают в вышестоящие инстанции. Помолчав с полминуты, они объявили что возможны, варианты... сотрудничества. В&amp;nbsp;качестве варианта было предложено оказать их организации посильную помощь в размере семи с половиной тысяч рублей. Увы, поскольку понимания ситуации не было, помощь таковая была оказана, в чем одна из продавщиц даже расписалась, но никакого документа о получении денег, разумеется, не получила.&lt;/div&gt;
&lt;div&gt;&lt;strong&gt;&lt;br&gt;&lt;/br&gt;
&lt;/strong&gt;&lt;/div&gt;
&lt;div&gt;&lt;strong&gt;АКТ&lt;/strong&gt;&lt;/div&gt;
&lt;div&gt;&amp;nbsp;&lt;/div&gt;
&lt;div&gt;Акт оказался бумажкой весьма забавной. Подробно описывать ее не буду, но фиктивность данного документа видна была невооруженным глазом. Бумага эта предписывала нам в пятидневный срок записаться на прием к юристу данной организации, для получения разъяснений по нарушениям, указанным в акте. Как выяснилось, посещение после проверки &amp;quot;бесплатное&amp;quot;. Поскольку деньги, на которые нас чистой воды развели (я бы сказал как лохов), вернуть все равно уже было невозможно, было решено посетить данное заведение, послушать что расскажут нового.&lt;/div&gt;
&lt;div&gt;&amp;nbsp;&lt;/div&gt;
&lt;div&gt;&lt;strong&gt;Офис ЦЗППиП &amp;quot;Ваше право&amp;quot;&lt;/strong&gt;&lt;/div&gt;
&lt;div&gt;&amp;nbsp;&lt;/div&gt;
&lt;div&gt;Судя по тому, что офис компании... простите, общественной организации, находится в практически в самом центре Москвы, жертвуют этой конторе не мало. Приехали мы к ним в гости, приняла нас их юрист и дала разъяснения. Кое-что оказалось действительно полезным, отрицать не буду. Однако! После консультации, нам снова было объявлено, что далее акт пойдет по инстанциям. Вот вам и добровольное пожертвование... Естественно, я осведомился, есть ли варианты обойтись без инстанций. Собственно, этого вопроса от меня и ждали - сначала уточнили, вносили ли мы что-либо, после чего, уточнив можем ли мы так сказать расширить сумму пожертвования (я на всякий случай ответил что можем), предложили два варианта - внести сейчас же или перечислить им на счет. Поскольку вносить наличные деньги я отказался категорически, мне была выдана квитанция для оплаты с пустым полем &amp;quot;Сумма&amp;quot;. Чтобы эту цифру как-то очертить, я осторожно спросил, какая сумма рекомендуется к пожертвованию. Намек в ответе был весьма недвусмысленный:&amp;nbsp;&amp;quot;Ну, мы не можем рекомендовать ничего. Сами смотрите. За аренду мы платим сто тысяч в месяц. Вот вы можете взять на себя небольшую часть этой суммы. Например, судебные издержки, если бы мы подали на вас в суд, составляли примерно тридцать тысяч... Вы когда перечислите, позвоните.&amp;quot;&lt;/div&gt;
&lt;div&gt;&amp;nbsp;&lt;/div&gt;
&lt;div&gt;&lt;strong&gt;Итого&lt;/strong&gt;&lt;/div&gt;
&lt;div&gt;&amp;nbsp;&lt;/div&gt;
&lt;div&gt;Разумеется, никаких денег мы им не перевели и не собираемся. И первый-то раз не надо было, но там, увы, недостаток информации сыграл на руку этим легализованным мошенникам.&lt;/div&gt;
&lt;div&gt;Но как и во всем, в этой ситуации тоже есть положительные стороны - нам указали на все ошибки нами допущенные, нам дали разъяснения по некоторым пунктам закона, в которых мы сам так и не разобрались. Ну и вообще - &amp;quot;Пока гром не грянет, мужик не перекрестится&amp;quot; (с).&lt;/div&gt;
&lt;div&gt;&amp;nbsp;&lt;/div&gt;
&lt;div&gt;PS: А еще это форсировало разработку собственной Торговой Системы. Тоже, Django-based.&lt;/div&gt;</description>
			<pubDate>Sat, 21 Nov 2009 15:45:00 +0400</pubDate>
			<guid isPermaLink="false">4</guid>
		</item>
		
		<item>
			<title>Забег</title>
			<link>http://betalabs.ru/2009-09-26/zabeg/</link>
			<description>&lt;div&gt;Завтра в подмосковном Королёве пройдет XXXIII (кажется) &amp;quot;&lt;a target=&quot;_blank&quot; href=&quot;http://www.kocmap.ru/&quot;&gt;Космический марафон&lt;/a&gt;&amp;quot;. Кроме самого марафона (42 км 195 м) будут забеги на 3, 10 и 20  километров.&lt;br&gt;&lt;/br&gt; &amp;nbsp;&lt;/div&gt; &lt;div&gt;Бегать я начал совсем недавно, так что решил поучаствовать в забеге на 10  километров, хотя по последним тренировкам, чувствую что сил достанет и на 20. Но папа рекомендует не рисковать зря. В конце концов, марафоны такого плана проходят достаточно часто, так что еще успею. Сам-то он бежит марафон, причем уже второй за эту осень - 13 сентбяря он бегал на &lt;a target=&quot;_blank&quot; href=&quot;http://www.marafon.msk.ru/&quot;&gt;Московском Международном Марафоне Мира&lt;/a&gt;.&lt;/div&gt; &lt;div&gt;&amp;nbsp;&lt;/div&gt; &lt;div&gt;Самое трудное во всем этом мероприятии - добраться до Королева, а потом выбраться обратно. Старт назначен на 11, так что приехать в худшем случае надо минут за 1:20 до старта - за час до старта уже надо проходить регистрацию. Сначала нас обещался подвезти мой друг, но, как с ним это в последнее время случается все чаще, в последний момент сослался на занятность и отказался. Так что завтра будет весело =) Метро-Электричка-Марафон-Электричка-Метро.&lt;/div&gt; &lt;div&gt;&amp;nbsp;&lt;/div&gt; &lt;div&gt;В любом случае, не сомневаюсь что это будет увлекательно. После финиша (а я планирую пробежать свои 10000 быстрее часа), мне придется еще не меньше трех часов ждать пока финиширует папа. Попробую устроить на него фотоохоту. Жаль, не получится взять с собой хорошую камеру - сдавать аппарат стоимостью в полсотни тысяч, да еще и с оптикой, в камеру хранения не очень хочется. Ничего, старый добрый Lumix FZ-5 по прежнему дает 12-ти кратный зум и 5-ти мегапиксельные снимки, так что не пропадем.&lt;/div&gt;</description>
			<pubDate>Sat, 26 Sep 2009 19:13:00 +0400</pubDate>
			<guid isPermaLink="false">3</guid>
		</item>
		
		<item>
			<title>Новый день, новый шаг</title>
			<link>http://betalabs.ru/2009-09-16/novyj_den_novyj_shag/</link>
			<description>&lt;div&gt;Сегодня добавил в блог базовую регистрацию. Зарегистрироваться в системе теперь можно, но вот редактирование профиля пока не работает. Параллельно с этим, добавил поддержку комментариев, тоже в самом простом варианте пока - без форматирования.&lt;/div&gt;
&lt;div&gt;&amp;nbsp;&lt;/div&gt;
&lt;div&gt;Никак не могу решить, нужна ли в комментариях поддержка ответов - построение древовидной структуры. В некоторых блогах это есть, а в некоторых нету. Количество плюсов-минусов для каждого варианта лично для меня представляется примерно одинаковым, хотя возможно я чего-то не понимаю. В любом случае комментирование подлежит капитально доработке, а начать ее надо, как мне кажется, с оформления комментариев. Уж больно убого сейчас они смотрятся.&lt;/div&gt;</description>
			<pubDate>Wed, 16 Sep 2009 23:22:00 +0400</pubDate>
			<guid isPermaLink="false">2</guid>
		</item>
		
		<item>
			<title>Hello World!</title>
			<link>http://betalabs.ru/2009-09-15/hello_world/</link>
			<description>&lt;div&gt;Итак, пришло время перейти от лабораторных изысканий к полевому тестированию. Тестировать мы будем разнообразные творения моего сомнительного гения, но начнем, собственно, с блогового движка AbendBlatt, создаваемого на базе фреймворка &lt;a href=&quot;http://djangoproject.com&quot;&gt;Django&lt;/a&gt;. О&amp;nbsp;самом фреймворке, а вернее о моих впечатлениях от него мы поговорим позже, а пока я вкратце опишу что представляет из себя на данный момент AbendBlatt.&lt;/div&gt;
&lt;div&gt;&amp;nbsp;&lt;/div&gt;
&lt;div&gt;Итак, для начала несколько слов об архитектуре:&lt;/div&gt;
&lt;div&gt;&amp;nbsp;&lt;/div&gt;
&lt;div&gt;AbendBlatt это многопользовательский блог имеющий несколько уровней пользователей:&lt;/div&gt;
&lt;ul&gt;
	&lt;li&gt;Администратор - пользовател обладающий абсолютно всеми правами. В данном случае это я.&lt;/li&gt;
	&lt;li&gt;Авторы - пользователи, имеющие возможность публиковать записи.&lt;/li&gt;
	&lt;li&gt;Читатели - могут читать все записи, комментировать их, участвовать в опросах ну и все такое прочее.&lt;/li&gt;
&lt;/ul&gt;
&lt;div&gt;Записи блога подразделяются на Колонки aka Категории. Корме общих категорий, каждый Автор может вести собственную, Авторскую Колонку.&lt;/div&gt;
&lt;div&gt;&amp;nbsp;&lt;/div&gt;
&lt;div&gt;Единственное - на данный момент регистрация еще не работает. =)&lt;/div&gt;
&lt;div&gt;&amp;nbsp;&lt;/div&gt;
&lt;div&gt;Далее. Одна из особенностей блога это обработчики записей. Их есть два типа - PostPost и PreView.&lt;/div&gt;
&lt;div&gt;PostPost-обработчики срабатывают при публикации записи. В первую очередь, они созданы для поддержки кросспостинга.&lt;/div&gt;
&lt;div&gt;PreView-обработчики переваривают записи перед их выводом на экран. Конвертиры смайлов, контекстные анализаторы и так далее.&lt;/div&gt;
&lt;div&gt;&amp;nbsp;&lt;/div&gt;
&lt;div&gt;Блог снабжен системой тегов для сообщений. Она реализована благодаря приложению &lt;a href=&quot;http://code.google.com/p/django-tagging/&quot;&gt;django-tagging&lt;/a&gt;.&lt;/div&gt;
&lt;div&gt;&amp;nbsp;&lt;/div&gt;
&lt;div&gt;Ну и все - что еще можно рассказать о системе в данный момент я не знаю, так что все остальное буду описывать в процессе. Вряд ли, конечно, кто-то в ближайшее время вообще найдет этот блог, но я пока и не очень хочу чтобы его активно находили, так что кросспостинг-обработчик (пока реализован только кросспостинг в LiveJournal) отключен. Сначала надо доделать интерфейсы регистрации, профиля пользователя и комментирования. После этого, думаю, кросспостинг уже можно будет включить, ну и ждать гостей.&lt;/div&gt;</description>
			<pubDate>Tue, 15 Sep 2009 22:59:00 +0400</pubDate>
			<guid isPermaLink="false">1</guid>
		</item>
		
	</channel>
</rss>

