<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>Мастерская интернет-разработчика &#187; Программирование</title>
	<atom:link href="http://adw0rd.ru/category/programming/feed/" rel="self" type="application/rss+xml" />
	<link>http://adw0rd.ru</link>
	<description>Блог Михаила Андреева (aka adw0rd)</description>
	<lastBuildDate>Fri, 11 May 2012 12:49:15 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.3.2</generator>
		<item>
		<title>Python и Git. Автоматическая проверка кода требованиям спецификации</title>
		<link>http://adw0rd.ru/2012/python-pre-code-review/</link>
		<comments>http://adw0rd.ru/2012/python-pre-code-review/#comments</comments>
		<pubDate>Sat, 31 Mar 2012 20:30:16 +0000</pubDate>
		<dc:creator>adw0rd</dc:creator>
				<category><![CDATA[Программирование]]></category>
		<category><![CDATA[Django]]></category>
		<category><![CDATA[Git]]></category>
		<category><![CDATA[Hooks]]></category>
		<category><![CDATA[PEP]]></category>
		<category><![CDATA[PEP8]]></category>
		<category><![CDATA[Python]]></category>

		<guid isPermaLink="false">http://adw0rd.ru/?p=6345</guid>
		<description><![CDATA[Многие команды делают Code Review, другие больше сосредотачиваются над Design Review, а многие не делают и вовсе, но статья не о том зачем это нужно, а о том, как частично автоматизировать процесс Code Review. Для своих проектов я решил съэкономить немного времени и человеческих ресурсов, и использовать автоматизированную проверку кода проекта на соответствие PEP 8, [...]]]></description>
			<content:encoded><![CDATA[<p><noindex><a href="/2012/python-pre-code-review/"><img src="http://adw0rd.ru/wp-content/uploads/2012/03/pre-code-review.jpg"  alt="" title="pre-code-review" width="208" height="151" class="alignright size-full wp-image-7551" /></a></noindex></p>
<p>Многие команды делают <strong>Code Review</strong>, другие больше сосредотачиваются над <strong>Design Review</strong>, а многие не делают и вовсе, но статья не о том зачем это нужно, а о том, как частично автоматизировать процесс Code Review. Для своих проектов я решил съэкономить немного времени и человеческих ресурсов, и использовать автоматизированную проверку кода проекта на соответствие <noindex><a rel="nofollow" href="http://www.python.org/dev/peps/pep-0008/" >PEP 8</a></noindex>, а также <em>качества кода</em> (pyflakes) и <em>качество сообщений</em> в Git. Полноценный Code Review при этом делать всёравно нужно, но уже в меньших объемах, а иногда и вовсе можно им пренебречь.</p>
<p>Итак, для работы нам понадобится установить <noindex><a rel="nofollow" href="http://pypi.python.org/pypi/pep8" >pep8</a></noindex>, <noindex><a rel="nofollow" href="http://pypi.python.org/pypi/pyflakes" >pyflakes</a></noindex>, а также отредактировать на рабочих станциях разработчиков хуки для Git: &laquo;pre-commit&raquo; и &laquo;commit-msg&raquo;.</p>
<p>Серверные хуки специально не используются, так как уже будет произведен коммит и разработчику придется откатываться и т.д., что совсем не экономит время разработчика.<br />
<span id="more-6345"></span></p>
<h3>Установка</h3>
<p>Установим зависимости:</p>
<div class="codecolorer-container bash default" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:650px;"><div class="bash codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color: #c20cb9; font-weight: bold;">sudo</span> <span style="color: #c20cb9; font-weight: bold;">apt-get install</span> pyflakes pep8</div></div>
<p>Установим хуки:</p>
<div class="codecolorer-container bash default" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:650px;"><div class="bash codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color: #7a0874; font-weight: bold;">cd</span> ~<span style="color: #000000; font-weight: bold;">/</span>work<br />
<span style="color: #c20cb9; font-weight: bold;">git clone</span> git:<span style="color: #000000; font-weight: bold;">//</span>gist.github.com<span style="color: #000000; font-weight: bold;">/</span><span style="color: #000000;">2184955</span>.git pre-code-review<br />
<span style="color: #c20cb9; font-weight: bold;">ln</span> <span style="color: #660033;">-s</span> <span style="color: #000000; font-weight: bold;">/</span>home<span style="color: #000000; font-weight: bold;">/&lt;</span>username<span style="color: #000000; font-weight: bold;">&gt;/</span>work<span style="color: #000000; font-weight: bold;">/</span>pre-code-review<span style="color: #000000; font-weight: bold;">/</span>pre-commit.py <span style="color: #000000; font-weight: bold;">/</span>home<span style="color: #000000; font-weight: bold;">/&lt;</span>username<span style="color: #000000; font-weight: bold;">&gt;/</span>work<span style="color: #000000; font-weight: bold;">/&lt;</span>project<span style="color: #000000; font-weight: bold;">&gt;/</span>.git<span style="color: #000000; font-weight: bold;">/</span>hooks<span style="color: #000000; font-weight: bold;">/</span>pre-commit<br />
<span style="color: #c20cb9; font-weight: bold;">ln</span> <span style="color: #660033;">-s</span> <span style="color: #000000; font-weight: bold;">/</span>home<span style="color: #000000; font-weight: bold;">/&lt;</span>username<span style="color: #000000; font-weight: bold;">&gt;/</span>work<span style="color: #000000; font-weight: bold;">/</span>pre-code-review<span style="color: #000000; font-weight: bold;">/</span>commit-msg.py <span style="color: #000000; font-weight: bold;">/</span>home<span style="color: #000000; font-weight: bold;">/&lt;</span>username<span style="color: #000000; font-weight: bold;">&gt;/</span>work<span style="color: #000000; font-weight: bold;">/&lt;</span>project<span style="color: #000000; font-weight: bold;">&gt;/</span>.git<span style="color: #000000; font-weight: bold;">/</span>hooks<span style="color: #000000; font-weight: bold;">/</span>commit-msg<br />
<span style="color: #c20cb9; font-weight: bold;">chmod</span> +x <span style="color: #000000; font-weight: bold;">/</span>home<span style="color: #000000; font-weight: bold;">/&lt;</span>username<span style="color: #000000; font-weight: bold;">&gt;/</span>work<span style="color: #000000; font-weight: bold;">/&lt;</span>project<span style="color: #000000; font-weight: bold;">&gt;/</span>.git<span style="color: #000000; font-weight: bold;">/</span>hooks<span style="color: #000000; font-weight: bold;">/</span>pre-commit<br />
<span style="color: #c20cb9; font-weight: bold;">chmod</span> +x <span style="color: #000000; font-weight: bold;">/</span>home<span style="color: #000000; font-weight: bold;">/&lt;</span>username<span style="color: #000000; font-weight: bold;">&gt;/</span>work<span style="color: #000000; font-weight: bold;">/&lt;</span>project<span style="color: #000000; font-weight: bold;">&gt;/</span>.git<span style="color: #000000; font-weight: bold;">/</span>hooks<span style="color: #000000; font-weight: bold;">/</span>commit-msg</div></div>
<p>Код для хука &laquo;pre-commit.py&raquo; повзаимствован <noindex><a rel="nofollow" href="http://tech.myemma.com/python-pep8-git-hooks/" >отсюда</a></noindex> и впоследствии доработан. В будующем планировалось добавить туда проверку докстрингов (процентное соотношение документации к коду, либо какие-либо другие метрики) и запуск тестов (но это сомнительно, так как скажется на производительности выполнения коммитов).</p>
<p>Для таких тяжелых операций как тесты есть удобный инструмент&nbsp;&mdash; Continius Integraton (CI), такие как <noindex><a rel="nofollow" href="http://hudson-ci.org/" >Hudson</a></noindex>, <noindex><a rel="nofollow" href="http://jenkins-ci.org/" >Jenkins</a></noindex> (<noindex><a rel="nofollow" href="http://pypi.python.org/pypi/django-jenkins" >Django Jenkins</a></noindex>), <noindex><a rel="nofollow" href="http://cruisecontrol.sourceforge.net/" >CruiseControl</a></noindex> и <noindex><a rel="nofollow" href="http://www.atlassian.com/software/bamboo" >Atlassian Bamboo</a></noindex>. Также, рекомендую ознакомится с продуктом для Code Review&nbsp;&mdash; <noindex><a rel="nofollow" href="http://www.atlassian.com/software/crucible/" >Atlassian Crucible</a></noindex>.</p>
<h3>Примеры</h3>
<p>Пример проверки кода:</p>
<div class="codecolorer-container bash default" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:650px;"><div class="bash codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap">$ <span style="color: #c20cb9; font-weight: bold;">git commit</span> <span style="color: #660033;">-m</span> <span style="color: #ff0000;">&quot;Something I&quot;</span><br />
<span style="color: #000000; font-weight: bold;">*********************************</span><br />
<span style="color: #000000; font-weight: bold;">*****</span> CODE REVIEW IS FAILED <span style="color: #000000; font-weight: bold;">*****</span><br />
<span style="color: #000000; font-weight: bold;">*********************************</span><br />
Check files: <span style="color: #000000; font-weight: bold;">&lt;</span>project<span style="color: #000000; font-weight: bold;">&gt;/&lt;</span>app<span style="color: #000000; font-weight: bold;">&gt;/</span>views.py, <span style="color: #000000; font-weight: bold;">&lt;</span>project<span style="color: #000000; font-weight: bold;">&gt;/</span>common<span style="color: #000000; font-weight: bold;">/</span>context_processors.py, <span style="color: #000000; font-weight: bold;">&lt;</span>project<span style="color: #000000; font-weight: bold;">&gt;/</span>common<span style="color: #000000; font-weight: bold;">/</span>decorators.py,<br />
<span style="color: #000000; font-weight: bold;">&lt;</span>project<span style="color: #000000; font-weight: bold;">&gt;/</span>settings.py, <span style="color: #000000; font-weight: bold;">&lt;</span>project<span style="color: #000000; font-weight: bold;">&gt;/&lt;</span>app<span style="color: #000000; font-weight: bold;">&gt;/</span>models.py, <span style="color: #000000; font-weight: bold;">&lt;</span>project<span style="color: #000000; font-weight: bold;">&gt;/</span>urls.py<br />
pep8:<br />
.<span style="color: #000000; font-weight: bold;">/&lt;</span>project<span style="color: #000000; font-weight: bold;">&gt;/</span>urls.py:<span style="color: #000000;">14</span>:<span style="color: #000000;">19</span>: E241 multiple spaces after <span style="color: #ff0000;">','</span><br />
.<span style="color: #000000; font-weight: bold;">/&lt;</span>project<span style="color: #000000; font-weight: bold;">&gt;/&lt;</span>app<span style="color: #000000; font-weight: bold;">&gt;/</span>models.py:<span style="color: #000000;">18</span>:<span style="color: #000000;">1</span>: E302 expected <span style="color: #000000;">2</span> blank lines, found <span style="color: #000000;">1</span><br />
pyflakes:<br />
.<span style="color: #000000; font-weight: bold;">/&lt;</span>project<span style="color: #000000; font-weight: bold;">&gt;/</span>urls.py:<span style="color: #000000;">3</span>: <span style="color: #ff0000;">'include'</span> imported but unused<br />
.<span style="color: #000000; font-weight: bold;">/&lt;</span>project<span style="color: #000000; font-weight: bold;">&gt;/</span>urls.py:<span style="color: #000000;">4</span>: undefined name <span style="color: #ff0000;">'User'</span></div></div>
<p>Хук &laquo;pre-commit&raquo; проверяет только staged изменения (поэтому после каждого фикса вам придется делать git-add), для того чтобы проверять весь индекс сразу нужно использовать &laquo;--debug&raquo;:</p>
<div class="codecolorer-container text default" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:650px;"><div class="text codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap">$ .git/hooks/pre-commit --debug</div></div>
<p>Пример проверки сообщения коммита:</p>
<div class="codecolorer-container bash default" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:650px;"><div class="bash codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap">$ <span style="color: #c20cb9; font-weight: bold;">git commit</span> <span style="color: #660033;">-m</span> <span style="color: #ff0000;">&quot;Something II&quot;</span><br />
<span style="color: #000000; font-weight: bold;">**********************************</span><br />
<span style="color: #000000; font-weight: bold;">*****</span> CHECK COMMIT IS FAILED <span style="color: #000000; font-weight: bold;">*****</span><br />
<span style="color: #000000; font-weight: bold;">**********************************</span><br />
<span style="color: #000000; font-weight: bold;">&gt;</span> check_task_tracking_identificator:<br />
<span style="color: #000000; font-weight: bold;">&gt;&gt;</span> Wrong Issue ID<span style="color: #000000; font-weight: bold;">!</span> Use format: <span style="color: #7a0874; font-weight: bold;">&#91;</span><span style="color: #7a0874; font-weight: bold;">&#123;</span>project_id<span style="color: #7a0874; font-weight: bold;">&#125;</span>-<span style="color: #7a0874; font-weight: bold;">&#123;</span>issue_number<span style="color: #7a0874; font-weight: bold;">&#125;</span><span style="color: #7a0874; font-weight: bold;">&#93;</span>, example: <span style="color: #7a0874; font-weight: bold;">&#91;</span>PROJ-<span style="color: #000000;">1027</span><span style="color: #7a0874; font-weight: bold;">&#93;</span></div></div>
<p>Если добавить к команде git-commit опцию &laquo;--no-verify&raquo;, то вы сможете пропустить проверку хуков.</p>
<div class="codecolorer-container text default" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:650px;"><div class="text codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap">-n, --no-verify<br />
&nbsp; &nbsp; This option bypasses the pre-commit and commit-msg hooks. See also githooks(5).</div></div>
<p>Такого вида контроль повышает качества кода на входе в репозиторий, разработчики оставляют меньше граблей в коде и т.д. Вообщем это минимум, который нужен для повышения качества вашего проекта.</p>
]]></content:encoded>
			<wfw:commentRss>http://adw0rd.ru/2012/python-pre-code-review/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Python и Django. Отладка при помощи PuDB</title>
		<link>http://adw0rd.ru/2012/python-django-pudb/</link>
		<comments>http://adw0rd.ru/2012/python-django-pudb/#comments</comments>
		<pubDate>Sat, 24 Mar 2012 15:19:50 +0000</pubDate>
		<dc:creator>adw0rd</dc:creator>
				<category><![CDATA[Программирование]]></category>
		<category><![CDATA[Debug]]></category>
		<category><![CDATA[Django]]></category>
		<category><![CDATA[IPython]]></category>
		<category><![CDATA[PuDB]]></category>
		<category><![CDATA[Python]]></category>

		<guid isPermaLink="false">http://adw0rd.ru/?p=7448</guid>
		<description><![CDATA[Этим отладчиком я пользуюсь недавно, где-то полгода, может чуть больше. До этого обходился (надо признаться мучался) с pdb, а также print&#39;ами, logger&#39;ом, debug_toolbar&#39;ом и т.д. Главное отличие в том, что у PuDB есть графический интерфейс с подсветкой синтаксиса, панелями для вывода дополнительной информации, интеграцией с IPython, удобными хоткеями и т.д., всё это делает его незаменимым [...]]]></description>
			<content:encoded><![CDATA[<p><a href="http://adw0rd.ru/2012/python-django-pudb/" ><img src="http://adw0rd.ru/wp-content/uploads/2012/03/pudb-mini-logo.png" alt="" title="pudb-mini-logo" width="219" height="158" class="alignright size-full wp-image-7453" /></a></p>
<p>Этим отладчиком я пользуюсь недавно, где-то полгода, может чуть больше. До этого обходился (надо признаться мучался) с pdb, а также print&#39;ами, logger&#39;ом, debug_toolbar&#39;ом и т.д. Главное отличие в том, что у <noindex><a rel="nofollow" href="http://mathema.tician.de/software/pudb" >PuDB</a></noindex> есть графический интерфейс с подсветкой синтаксиса, панелями для вывода дополнительной информации, интеграцией с IPython, удобными хоткеями и т.д., всё это делает его незаменимым инструмент на каждый день!</p>
<p>Автор: <noindex><a rel="nofollow" href="https://github.com/inducer" >Andreas Klöckner</a></noindex><br />
Страница проекта на PyPI: <noindex><a rel="nofollow" href="http://pypi.python.org/pypi/pudb" >http://pypi.python.org/pypi/pudb</a></noindex><br />
Исходный код проекта <noindex><a rel="nofollow" href="https://github.com/inducer/pudb" >на GitHub</a></noindex> или в <noindex><a rel="nofollow" href="http://git.tiker.net/pudb.git" >GitWeb автора</a></noindex><br />
Текущая версия: <strong>2012.1</strong></p>
<p>Отладчик использует <noindex><a rel="nofollow" href="http://excess.org/urwid/examples.html" >urwid</a></noindex> для построения графического интерфейса и <noindex><a rel="nofollow" href="http://pygments.org/" >pygments</a></noindex> для подсветки синтаксиса.<br />
<span id="more-7448"></span></p>
<h3>Установка и настройка</h3>
<p>Всё предельно просто, ставим из PyPI:</p>
<div class="codecolorer-container bash default" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:650px;"><div class="bash codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap">pip <span style="color: #c20cb9; font-weight: bold;">install</span> pudb</div></div>
<p>Или из исходников:</p>
<div class="codecolorer-container bash default" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:650px;"><div class="bash codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color: #c20cb9; font-weight: bold;">git clone</span> git:<span style="color: #000000; font-weight: bold;">//</span>github.com<span style="color: #000000; font-weight: bold;">/</span>inducer<span style="color: #000000; font-weight: bold;">/</span>pudb.git<br />
<span style="color: #7a0874; font-weight: bold;">cd</span> pudb <span style="color: #000000; font-weight: bold;">&amp;&amp;</span> setup.py <span style="color: #c20cb9; font-weight: bold;">install</span><br />
<span style="color: #666666; font-style: italic;"># либо сделайте симлинк в site-packages (я так обычно делаю, использую virtualenv и пакеты из транка)</span><br />
<span style="color: #c20cb9; font-weight: bold;">ln</span> <span style="color: #660033;">-s</span> ~<span style="color: #000000; font-weight: bold;">/</span>pudb<span style="color: #000000; font-weight: bold;">/</span>pudb ~<span style="color: #000000; font-weight: bold;">/</span>venv<span style="color: #000000; font-weight: bold;">/&lt;</span>virtualenv<span style="color: #000000; font-weight: bold;">&gt;/</span>lib<span style="color: #000000; font-weight: bold;">/</span>python2.7<span style="color: #000000; font-weight: bold;">/</span>site-packages<span style="color: #000000; font-weight: bold;">/</span>pudb</div></div>
<p>Запустите PuDB:</p>
<div class="codecolorer-container python default" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:650px;"><div class="python codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap">$ python<br />
<span style="color: #66cc66;">&gt;&gt;&gt;</span> <span style="color: #ff7700;font-weight:bold;">import</span> pudb<br />
<span style="color: #66cc66;">&gt;&gt;&gt;</span> pudb.<span style="color: black;">set_trace</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span></div></div>
<p>Перед вами предстанет отладчик и попросит вас его настроить, а если не попросит, то можно вызвать настройки самостоятельно&nbsp;&mdash; нажмите &laquo;Ctrl+p&raquo;. Там вы сможете выбрать shell (classic или <b>ipython</b>), тему (classic, vim, dark vim, <b>midnight</b>, либо создать тему самому), порядок вывода стека, способ вывода значений переменных контекста (type, str, repr, либо собственная реализация).</p>
<h3>Инструкция по применению</h3>
<p>Сразу надо заметить, что в интерфейсе сразу все понятно что к чему, а если что-то не понятно, то надо нажать &laquo;?&raquo; и вы увидите полный &laquo;help&raquo;. Приведу его только часть, в порядке частоты использования:</p>
<blockquote>
<h5 style="margin:0">Основное:</h5>
<p><b>!</b>&nbsp;&mdash; вызвать shell, при этом будет доступен весь контекст в котором вы находитесь<br />
<b>o</b>&nbsp;&mdash; вывести консоль, но только для просмотра, удобно когда вы вводили что-то в консоле и хотите снова это посмотреть</p>
<p><b>n</b>&nbsp;&mdash; &laquo;step over&raquo; (перешагнуть), перейти к следующей строке кода<br />
<b>s</b>&nbsp;&mdash; &laquo;step into&raquo;, перейти во внутрь объекта, если это возможно, иначе перейти к следующей строке кода<br />
<b>u</b>&nbsp;&mdash; подняться на один стек-фрейм вверх<br />
<b>d</b>&nbsp;&mdash; опуститься на один стек-фрейм вниз</p>
<p><b>c</b>&nbsp;&mdash; &laquo;continue&raquo;, продолжить (до первого брейкпоинта или до завершения работы программы)<br />
<b>f</b>&nbsp;&mdash; завершить текущую функцию<br />
<b>q</b>&nbsp;&mdash; выход из отладчика и продолжение работы программы</p>
<p><b>e</b>&nbsp;&mdash; показать трейсбек, при этом вы сначала в шапке отладчика отчётливо увидите что произошол трейсбек<br />
<b>L</b>&nbsp;&mdash; показать путь до текущего файла и номер строки, а также goto-line<br />
<b>/</b>&nbsp;&mdash; поиск строки (&laquo;,&raquo;&nbsp;&mdash; вперед, &laquo;.&raquo;&nbsp;&mdash; назад)</p>
<h5 style="margin:0">Работа с брейкпоинтами:</h5>
<p><b>b</b>&nbsp;&mdash; установить брейкпоинт<br />
<b>enter</b>&nbsp;&mdash; отредактировать брейкопинт (работает в панели брейкпоинтов)<br />
<b>d</b>&nbsp;&mdash; удалить брейкпоинт (работает в панели брейкпоинтов)</p>
<h5 style="margin:0">Работа с панелями:</h5>
<p><b>V</b>&nbsp;&mdash; перейти в панель Variables<br />
<b>S</b>&nbsp;&mdash; перейти в панель Stack<br />
<b>B</b>&nbsp;&mdash; перейти в панель Breakpoints<br />
<b>+</b><span style="color:#d0d0d0">/</span><b>&mdash; </b>&nbsp;&mdash; расширить/сузить панель в ширину<br />
<b>_</b><span style="color:#d0d0d0">/</span><b>=</b>&nbsp;&mdash; минимализировать/максимализировать панель в ширину<br />
<b>[</b><span style="color:#d0d0d0">/</span><b>]</b>&nbsp;&mdash; расширить/сузить панель в высоту</p>
<h5 style="margin:0">Работа с панелью переменных (Variables):</h5>
<p><b>\</b>&nbsp;&mdash; развернуть/свернуть содержимое переменной<br />
<b>t</b><span style="color:#d0d0d0">/</span><b>r</b><span style="color:#d0d0d0">/</span><b>s</b><span style="color:#d0d0d0">/</span><b>c</b>&nbsp;&mdash; переключаться между type/repr/str/custom форматом вывода переменной<br />
<b>h</b>&nbsp;&mdash; подсветить переменную в панели (также и отключает подсветку)<br />
<b>@</b>&nbsp;&mdash; закрепить переменную в верхней части панели<br />
<b>w</b>&nbsp;&mdash; переключится в режим word-wrap для переменных (и обратно также)<br />
<b>n</b><span style="color:#d0d0d0">/</span><b>Insert</b>&nbsp;&mdash; добавить в верхнюю панель выражение для слежения (например вы ожидаете появления переменной &laquo;test_something&raquo;, то добавьте её название, когда она будет доступна, тогда появится в верхней панели со значением)<br />
<b>enter</b>&nbsp;&mdash; управление переменными в Variables, в том числе и удаление
</p>
</blockquote>
<h3>Интеграция с Django и IPython</h3>
<p>До версии PuDB 2012.1 необходимо было сделать <noindex><a rel="nofollow" href="http://wiki.tiker.net/PuDB/DjangoIntegration" >следующие манипуляции</a></noindex>, если по каким-либо причинам вы используете старую версию PuDB, то вам это должно пригодится. В новой версии ничего делать не надо, всё работает из коробки!</p>
<p><img src="http://adw0rd.ru/wp-content/uploads/2012/03/pudb_django_50.png" alt="" title="pudb_django_50" width="683" height="372" class="alignnone size-full wp-image-7498" /></p>
<p>Также с IPython (версии  0.13+) и PuDB до версии 2012.1 были проблемы, но если вы используете IPython 0.10.x (который до сих пор в пакетах Ubuntu как основной), то всё будет хорошо. <noindex><a rel="nofollow" href="http://wiki.tiker.net/PuDB/IPythonIntegration" >Вот, к слову, о PuDB+IPython интергации</a></noindex>.</p>
<h3>Использование</h3>
<p>Приведу пару примеров о том как пользоваться PuDB:</p>
<div class="codecolorer-container bash default" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:650px;"><div class="bash codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color: #666666; font-style: italic;"># Запуск отладчика для определенного скрипта</span><br />
python <span style="color: #660033;">-m</span> pudb.run script.py<br />
python <span style="color: #660033;">-m</span> pudb.run manage.py runcpdebug<br />
<span style="color: #666666; font-style: italic;"># Далее, устанавливайте брейкпоинты и жмите &quot;c&quot; (Continue),</span><br />
<span style="color: #666666; font-style: italic;"># &nbsp; как только отладчик дойдёт до брейкпоинта он остановится</span></div></div>
<p>В коде можно вызвать так:</p>
<div class="codecolorer-container python default" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:650px;"><div class="python codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color: #808080; font-style: italic;"># В любом месте вставьте:</span><br />
<span style="color: #ff7700;font-weight:bold;">import</span> pudb<span style="color: #66cc66;">;</span> pudb.<span style="color: black;">set_trace</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span></div></div>
<p>Ко всему прочему привожу видеокаст от автора:<br />
<iframe src="http://player.vimeo.com/video/5255125?title=0&amp;byline=0&amp;portrait=0" width="400" height="308" frameborder="0" webkitAllowFullScreen mozallowfullscreen allowFullScreen></iframe>
<p><noindex><a rel="nofollow" href="http://vimeo.com/5255125" >PuDB Intro Screencast</a></noindex> from <noindex><a rel="nofollow" href="http://vimeo.com/user559834" >Andreas Klöckner</a></noindex> on <noindex><a rel="nofollow" href="http://vimeo.com" >Vimeo</a></noindex>.</p>
<h3>Реализация установки брейкпоинтов для Emacs</h3>
<p>Так как я пользуюсь Emacs, то решил для него сделать функцию и хот-кей для вставки брейкпоинта в PuDB.<br />
Поместите следующий код в свой &laquo;~/.emacs&raquo;:</p>
<div class="codecolorer-container lisp default" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:650px;"><div class="lisp codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color: #66cc66;">&#40;</span><span style="color: #b1b100;">defun</span> pudb-save-breakpoint <span style="color: #66cc66;">&#40;</span><span style="color: #66cc66;">&#41;</span><br />
&nbsp; <span style="color: #66cc66;">&#40;</span>interactive<span style="color: #66cc66;">&#41;</span><br />
&nbsp; <span style="color: #66cc66;">&#40;</span><span style="color: #b1b100;">setq</span> file <span style="color: #66cc66;">&#40;</span>buffer-file-<span style="color: #b1b100;">name</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span><br />
&nbsp; <span style="color: #66cc66;">&#40;</span><span style="color: #b1b100;">setq</span> line <span style="color: #66cc66;">&#40;</span>substring <span style="color: #66cc66;">&#40;</span>what-line<span style="color: #66cc66;">&#41;</span> <span style="color: #cc66cc;">5</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span><br />
&nbsp; <span style="color: #66cc66;">&#40;</span><span style="color: #b1b100;">setq</span> saved-breakpoints <span style="color: #ff0000;">&quot;~/.config/pudb/saved-breakpoints&quot;</span><span style="color: #66cc66;">&#41;</span><br />
&nbsp; <span style="color: #66cc66;">&#40;</span>with-temp-buffer<br />
&nbsp; &nbsp; <span style="color: #66cc66;">&#40;</span>insert <span style="color: #ff0000;">&quot;b &quot;</span> file <span style="color: #ff0000;">&quot;:&quot;</span> line <span style="color: #ff0000;">&quot;<span style="color: #000099; font-weight: bold;">\n</span>&quot;</span><span style="color: #66cc66;">&#41;</span><br />
&nbsp; &nbsp; <span style="color: #66cc66;">&#40;</span><span style="color: #b1b100;">when</span> <span style="color: #66cc66;">&#40;</span>file-writable-p saved-breakpoints<span style="color: #66cc66;">&#41;</span><br />
&nbsp; &nbsp; &nbsp; <span style="color: #66cc66;">&#40;</span>append-to-file <span style="color: #66cc66;">&#40;</span>point-<span style="color: #b1b100;">min</span><span style="color: #66cc66;">&#41;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #66cc66;">&#40;</span>point-<span style="color: #b1b100;">max</span><span style="color: #66cc66;">&#41;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; saved-breakpoints<span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span><br />
<span style="color: #66cc66;">&#41;</span><br />
<span style="color: #66cc66;">&#40;</span>global-set-key <span style="color: #66cc66;">&#91;</span>?\C-x ?\C-_<span style="color: #66cc66;">&#93;</span> 'pudb-save-breakpoint<span style="color: #66cc66;">&#41;</span></div></div>
<p>Идея простая, все брейкпоинты PuDB пишет в свой файл &laquo;~/.config/pudb/saved-breakpoints&raquo;, в формате:</p>
<div class="codecolorer-container text default" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:650px;"><div class="text codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap">b &lt;file&gt;:&lt;line&gt;<br />
b &lt;file&gt;:&lt;line&gt;</div></div>
<p>Воспользоваться этим как видите очень просто&nbsp;&mdash; надо дописывать брейкпоинты. Также можно реализовать удаление брейкпоинта, очистку (в том числе с неймспейсом по проекту) и т.д., но мне пока и этого достаточно. Если кто знает готовый или хочет сделать полноценный модуль для Emacs+PuDB, то пишите, буду очень рад!</p>
<p>Так как в elisp я особо не силён, то можно сделать python-скрипт, в который elisp будет передавать аргументы, а скрипт будет уже делать все манипуляции с файлом брейкпоинтов.</p>
<p>Также, рекомендую ознакомиться со списком отладчиков для python: <noindex><a rel="nofollow" href="http://wiki.python.org/moin/PythonDebuggers" >PythonDebuggers&nbsp;&mdash; PythonInfo Wiki</a></noindex>.</p>
]]></content:encoded>
			<wfw:commentRss>http://adw0rd.ru/2012/python-django-pudb/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Обрабатываем LESS &#171;на лету&#187; с помощью Nginx и Node.js</title>
		<link>http://adw0rd.ru/2012/processing-less-via-nginx-and-nodejs/</link>
		<comments>http://adw0rd.ru/2012/processing-less-via-nginx-and-nodejs/#comments</comments>
		<pubDate>Sun, 04 Mar 2012 12:30:09 +0000</pubDate>
		<dc:creator>adw0rd</dc:creator>
				<category><![CDATA[Операционные системы]]></category>
		<category><![CDATA[Программирование]]></category>
		<category><![CDATA[LESS]]></category>
		<category><![CDATA[Linux]]></category>
		<category><![CDATA[Nginx]]></category>
		<category><![CDATA[node.js]]></category>

		<guid isPermaLink="false">http://adw0rd.ru/?p=6982</guid>
		<description><![CDATA[Сегодня начал использовать twitter-bootstrap и решил процессить less не на клиентской стороне, а средствами сервера, просто по приколу. Сразу же вспомнил про статью на хабре Серверный процессинг LESS файлов «на лету» своими руками и решил реализовать то, что там написано. Принцип работы заключается в том, что все обращения к файлам &#171;*.less&#187; будут проксироваться через Nginx [...]]]></description>
			<content:encoded><![CDATA[<p><noindex><a href="/2012/processing-less-via-nginx-and-nodejs/"><img src="http://adw0rd.ru/wp-content/uploads/2012/03/less-nginx-and-nodejs.png"  alt="" title="less-via-nginx-and-nodejs" width="199" height="97" class="alignright size-full wp-image-6999" /></a></noindex></p>
<p>Сегодня начал использовать <noindex><a rel="nofollow" href="http://twitter.github.com/bootstrap/" >twitter-bootstrap</a></noindex> и решил процессить <noindex><a rel="nofollow" href="http://lesscss.org/" >less</a></noindex> не на клиентской стороне, а средствами сервера, просто по приколу. Сразу же вспомнил про статью на хабре <noindex><a rel="nofollow" href="http://habrahabr.ru/blogs/nginx/138103/" >Серверный процессинг LESS файлов «на лету» своими руками</a></noindex> и решил реализовать то, что там написано.</p>
<p>Принцип работы заключается в том, что все обращения к файлам &laquo;*.less&raquo; будут проксироваться через <strong>Nginx</strong> и преобразовываться на лету (можно и <a href="/2010/nginx-fastcgi-cache/">nginx-кеш</a> прикрутить, если надо) в <strong>css</strong> средствами <strong>node.js</strong>.<br />
<span id="more-6982"></span></p>
<h3>Установка</h3>
<p>Для начала нам надо установить nginx и node.js:</p>
<div class="codecolorer-container bash default" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:650px;"><div class="bash codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color: #c20cb9; font-weight: bold;">sudo</span> <span style="color: #c20cb9; font-weight: bold;">apt-get install</span> nginx nodejs</div></div>
<p>Скачиваем <noindex><a rel="nofollow" href="https://github.com/adw0rd/less.js/downloads" >отсюда</a></noindex> последнюю версию <strong>less.js</strong> и устанавливаем:</p>
<div class="codecolorer-container text default" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:650px;"><div class="text codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap">cd ~<br />
wget -O adw0rd-less.js.tar.gz https://github.com/adw0rd/less.js/tarball/master<br />
tar -xzf adw0rd-less.js.tar.gz<br />
cd adw0rd-less.js-*<br />
<br />
# Проверяем less<br />
make test</div></div>
<h3>Настройка</h3>
<p>Добавим в &laquo;/etc/hosts&raquo; хост &laquo;example.loc&raquo;:</p>
<div class="codecolorer-container text default" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:650px;"><div class="text codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap">127.0.0.1 example.loc</div></div>
<h4>Отконфигурируем Nginx</h4>
<p>Добавим в &laquo;/etc/nginx/nginx.conf&raquo; апстрим &laquo;lessserv&raquo;:</p>
<div class="codecolorer-container text default" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:650px;"><div class="text codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap">upstream lessserv {<br />
&nbsp; &nbsp; server localhost:1337;<br />
}</div></div>
<p>Отредакируем ваш server-конфиг для &laquo;example.loc&raquo;&nbsp;&mdash; &laquo;/etc/nginx/sites-available/example.conf&raquo;:</p>
<div class="codecolorer-container text default" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:650px;"><div class="text codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap">server {<br />
&nbsp; &nbsp; listen 80;<br />
&nbsp; &nbsp; server_name example.loc;<br />
&nbsp; &nbsp; root /path/to/example;<br />
<br />
&nbsp; &nbsp; location ~* \.less$ {<br />
&nbsp; &nbsp; &nbsp; &nbsp; proxy_pass http://lessserv;<br />
&nbsp; &nbsp; }<br />
}</div></div>
<p>После чего не забываем добавить в sites-enabled и зарелоадить Nginx:</p>
<div class="codecolorer-container bash default" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:650px;"><div class="bash codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color: #c20cb9; font-weight: bold;">ln</span> <span style="color: #660033;">-s</span> <span style="color: #000000; font-weight: bold;">/</span>etc<span style="color: #000000; font-weight: bold;">/</span>nginx<span style="color: #000000; font-weight: bold;">/</span>sites-available<span style="color: #000000; font-weight: bold;">/</span>example.conf <span style="color: #000000; font-weight: bold;">/</span>etc<span style="color: #000000; font-weight: bold;">/</span>nginx<span style="color: #000000; font-weight: bold;">/</span>sites-enabled<span style="color: #000000; font-weight: bold;">/</span>example.conf<br />
<span style="color: #c20cb9; font-weight: bold;">sudo</span> nginx <span style="color: #660033;">-s</span> reload</div></div>
<h4>Теперь перейдем к node.js</h4>
<p>В файле &laquo;bin/lessserv&raquo; вы можете указать нужный вам <strong>listen_host</strong> и <strong>listen_port</strong>, по умолчанию:</p>
<div class="codecolorer-container text default" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:650px;"><div class="text codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap">var listen_port = 1337,<br />
&nbsp; &nbsp; listen_host = &quot;127.0.0.1&quot;;</div></div>
<p>Запускаем lessserv, который и будет проксировать наши less-файлы:</p>
<div class="codecolorer-container text default" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:650px;"><div class="text codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap">cd ~/adw0rd-less.js-*<br />
node bin/lessserv --path=/path/to/example</div></div>
<p>Проверяем по ссылке: <noindex><a rel="nofollow" href="http://example.loc/bootstrap/less/bootstrap.less" >http://example.loc/bootstrap/less/bootstrap.less</a></noindex>, если отдается готовый css-файл, то все у вас получилось!</p>
<blockquote class="info">
<p>
Ествественно, в каталоге &laquo;/path/to/example&raquo; должен присутствовать распакованный каталог <noindex><a rel="nofollow" href="https://github.com/twitter/bootstrap/downloads" >bootstrap</a></noindex>.
</p>
</blockquote>
<p>Далее в <strong>html</strong> подключать можно так:</p>
<div class="codecolorer-container html4strict default" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:650px;"><div class="html4strict codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color: #009900;">&lt;<span style="color: #000000; font-weight: bold;">link</span> <span style="color: #000066;">rel</span><span style="color: #66cc66;">=</span><span style="color: #ff0000;">&quot;stylesheet&quot;</span> <span style="color: #000066;">type</span><span style="color: #66cc66;">=</span><span style="color: #ff0000;">&quot;text/css&quot;</span> <span style="color: #000066;">href</span><span style="color: #66cc66;">=</span><span style="color: #ff0000;">&quot;http://example.loc/bootstrap/less/bootstrap.less&quot;</span> <span style="color: #66cc66;">/</span>&gt;</span></div></div>
<p>P.S. Вообщем статья это &laquo;толстый Like&raquo; <noindex><a rel="nofollow" href="http://habrahabr.ru/blogs/nginx/138103/" >статьи с хабра</a></noindex>, хотя более подробная в плане настроек, пофикшены инструкции (proxy_pass, вместо proxy_path), а также немного улучшен &laquo;less.js&raquo; на <noindex><a rel="nofollow" href="https://github.com/adw0rd/less.js" >GitHub</a></noindex>&#39;е :)</p>
]]></content:encoded>
			<wfw:commentRss>http://adw0rd.ru/2012/processing-less-via-nginx-and-nodejs/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>jQuery. Написал плагин jquery-cleverfocus</title>
		<link>http://adw0rd.ru/2012/jquery-cleverfocus/</link>
		<comments>http://adw0rd.ru/2012/jquery-cleverfocus/#comments</comments>
		<pubDate>Thu, 01 Mar 2012 15:47:37 +0000</pubDate>
		<dc:creator>adw0rd</dc:creator>
				<category><![CDATA[Программирование]]></category>
		<category><![CDATA[Проекты]]></category>
		<category><![CDATA[jQuery]]></category>

		<guid isPermaLink="false">http://adw0rd.ru/?p=6936</guid>
		<description><![CDATA[Зарелизил сегодня плагин для jQuery, который при вводе на сайте текста пользователем &#171;в никуда&#187; перехватывает это и по истечению лимита введенных символов выбрасывает собранные данные в нужный нам инпут и ставит на него фокус. Плагин совместим с версией jQuery 1.7.1, так как тестировался только на нём. Исходный код на GitHub Демка на demo.adw0rd.ru А зачем [...]]]></description>
			<content:encoded><![CDATA[<p><noindex><a href="/2012/jquery-cleverfocus/"><img src="http://adw0rd.ru/wp-content/uploads/2012/03/jquery-cleverfocus-min.png"  alt="" title="jquery-cleverfocus-min" width="268" height="87" class="alignright size-full wp-image-6948" /></a></noindex></p>
<p>Зарелизил сегодня плагин для <strong>jQuery</strong>, который при вводе на сайте текста пользователем &laquo;в никуда&raquo; перехватывает это и по истечению лимита введенных символов выбрасывает собранные данные в нужный нам инпут и ставит на него фокус.</p>
<p>Плагин совместим с версией <strong>jQuery 1.7.1</strong>, так как тестировался только на нём.</p>
<ul>
<li><noindex><a rel="nofollow" href="https://github.com/adw0rd/jquery-cleverfocus" >Исходный код на GitHub</a></noindex></li>
<li><a href="http://demo.adw0rd.ru/jquery-cleverfocus/functional_test.html" >Демка на demo.adw0rd.ru</a></li>
</ul>
<h3>А зачем вообще это?</h3>
<p><strong>Случай #1</strong><br />
Пользователь приходит на сайт, видит форму поиска, набирает искомое слово (при этом он чаще всего смотрит в клавиатуру), подняв голову он понимает что набирал текст &laquo;в никуда&raquo;, сильно бесится, ставит фокус, вводит несколько символов, проверяет что у него получается набирать текст &laquo;куда надо&raquo; и со спокойной душой продолжает набирать искомое слово.</p>
<p>Тут вы скажете &laquo;Эй! надо ставить фокус после загрузки DOM!&raquo;, ан нет, это тоже плохое решение, разберем второй кейс.</p>
<p><strong>Случай #2</strong><br />
Пользователь приходит на сайт, ему не интересна форма поиска, он хочет поскроллить/полистать (Left/Right, Up/Down, PgUp/PgDown, Home/End и т.д.) страницу с помощью клавиатуры (пользователей, которые пользуются ноутбуками без использования мыши достаточно много), а так как у нас стоит фокус в форме поиска, то он снова обламывается.</p>
<p>Для решения этих вот двух кейсов и был создан плагин <noindex><a rel="nofollow" href="http://github.com/adw0rd/jquery-cleverfocus" >jquery-cleverfocus</a></noindex>.<br />
<span id="more-6936"></span></p>
<h3>Пример использования</h3>
<p>Допустим у вам есть форма поиска с id="search_input":</p>
<div class="codecolorer-container html4strict default" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:650px;"><div class="html4strict codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color: #009900;">&lt;<span style="color: #000000; font-weight: bold;">input</span> <span style="color: #000066;">id</span><span style="color: #66cc66;">=</span><span style="color: #ff0000;">&quot;search_input&quot;</span> <span style="color: #66cc66;">/</span>&gt;</span></div></div>
<p>То для неё следует использовать плагин так:</p>
<div class="codecolorer-container javascript default" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:650px;"><div class="javascript codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap">$<span style="color: #009900;">&#40;</span><span style="color: #3366CC;">&quot;#search_input&quot;</span><span style="color: #009900;">&#41;</span>.<span style="color: #660066;">cleverfocus</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#123;</span><br />
&nbsp; &nbsp; keypress_limit<span style="color: #339933;">:</span> <span style="color: #CC0000;">3</span><br />
<span style="color: #009900;">&#125;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></div></div>
<p>В поставку входит <noindex><a rel="nofollow" href="https://github.com/adw0rd/jquery-cleverfocus/blob/master/functional_test.html" >functional_test.html</a></noindex>, на котором вы можете проверить плагин, также в целях демонстрации я разместил плагин на <a href="http://demo.adw0rd.ru/jquery-cleverfocus/functional_test.html" >demo.adw0rd.ru/jquery-cleverfocus/functional_test.html</a></p>
<h3>Почему он так называется?</h3>
<p>Сначала, я дал ему имя &laquo;jquery-autofocus&raquo;, но потом поискал в гугле это название и нашёл <noindex><a rel="nofollow" href="https://github.com/miketaylr/autofocus" >плагин с таким же названием</a></noindex>, которой призван эмулировать атрибут autofocus из HTML5 в HTML меньших версий.</p>
<p>Потом я решил назвать его &laquo;jquery-smartfocus&raquo;, но и тут поджидало меня разочарование, так как есть и <noindex><a rel="nofollow" href="http://archive.plugins.jquery.com/project/smartFocus" >такой плагин</a></noindex>.</p>
<p>В итоге, назвал его по &laquo;человечному&raquo;&nbsp;&mdash; <strong>cleverfocus</strong>.</p>
]]></content:encoded>
			<wfw:commentRss>http://adw0rd.ru/2012/jquery-cleverfocus/feed/</wfw:commentRss>
		<slash:comments>8</slash:comments>
		</item>
		<item>
		<title>Python. Работаем с xls через xlwt/xlrd и python-uno</title>
		<link>http://adw0rd.ru/2012/python-excel-xlwt-xlrd-xlutils-and-python-uno/</link>
		<comments>http://adw0rd.ru/2012/python-excel-xlwt-xlrd-xlutils-and-python-uno/#comments</comments>
		<pubDate>Tue, 28 Feb 2012 13:50:09 +0000</pubDate>
		<dc:creator>adw0rd</dc:creator>
				<category><![CDATA[Программирование]]></category>
		<category><![CDATA[Excel]]></category>
		<category><![CDATA[Python]]></category>
		<category><![CDATA[xls]]></category>

		<guid isPermaLink="false">http://adw0rd.ru/?p=6520</guid>
		<description><![CDATA[Понадобилось без потери данных и функциональности модифицировать xls документы, то есть мы имеем несколько листов в документе, на одном из листов есть фильтры, списки и прочие компоненты современного екселя. Первое что приходит на ум&#160;&#8212; это старый-добрый Python Excel (xlwt/xlrd), попробуем реализовать модификацию ячейки с помощью этого инструмента, а потом перейдем к PyUNO. Python Excel: xlwt, [...]]]></description>
			<content:encoded><![CDATA[<p><noindex><a href="/2012/python-excel-xlwt-xlrd-xlutils-and-python-uno/"><img src="http://adw0rd.ru/wp-content/uploads/2012/12/python-xls.png"  alt="" title="python-xls" width="366" height="102" class="alignright size-full wp-image-6860" /></a></noindex></p>
<p>Понадобилось без потери данных и функциональности модифицировать xls документы, то есть мы имеем несколько листов в документе, на одном из листов есть фильтры, списки и прочие компоненты современного екселя.</p>
<p>Первое что приходит на ум&nbsp;&mdash; это старый-добрый <strong>Python Excel</strong> (xlwt/xlrd), попробуем реализовать модификацию ячейки с помощью этого инструмента, а потом перейдем к <strong>PyUNO</strong>.<br />
<span id="more-6520"></span></p>
<h3>Python Excel: xlwt, xlrd, xlutils</h3>
<p>Более подробно об этих пакетах можно почитать на странице <noindex><a rel="nofollow" href="http://www.python-excel.org/" >Python Excel</a></noindex>.<br />
Для начала установим их:</p>
<div class="codecolorer-container bash default" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:650px;"><div class="bash codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color: #c20cb9; font-weight: bold;">sudo</span> pip <span style="color: #c20cb9; font-weight: bold;">install</span> xlwt xlrd xlutils</div></div>
<p>А теперь пример кода:</p>
<div class="codecolorer-container python default" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:650px;"><div class="python codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color: #ff7700;font-weight:bold;">import</span> xlwt<span style="color: #66cc66;">,</span> xlrd<br />
<span style="color: #ff7700;font-weight:bold;">from</span> xlutils.<span style="color: #dc143c;">copy</span> <span style="color: #ff7700;font-weight:bold;">import</span> <span style="color: #dc143c;">copy</span> <span style="color: #ff7700;font-weight:bold;">as</span> xlcopy<br />
<br />
source_filename <span style="color: #66cc66;">=</span> <span style="color: #483d8b;">&quot;/tmp/example.xls&quot;</span><br />
destination_filename <span style="color: #66cc66;">=</span> <span style="color: #483d8b;">&quot;/tmp/example_new.xls&quot;</span><br />
<br />
read_book <span style="color: #66cc66;">=</span> xlrd.<span style="color: black;">open_workbook</span><span style="color: black;">&#40;</span>source_filename<span style="color: #66cc66;">,</span> on_demand<span style="color: #66cc66;">=</span><span style="color: #008000;">True</span><span style="color: black;">&#41;</span> &nbsp;<span style="color: #808080; font-style: italic;"># Открываем исходный документ</span><br />
read_sheet <span style="color: #66cc66;">=</span> read_book.<span style="color: black;">get_sheet</span><span style="color: black;">&#40;</span><span style="color: #ff4500;">0</span><span style="color: black;">&#41;</span> &nbsp;<span style="color: #808080; font-style: italic;"># Читаем из первого листа</span><br />
write_book <span style="color: #66cc66;">=</span> xlcopy<span style="color: black;">&#40;</span>read_book<span style="color: black;">&#41;</span> &nbsp;<span style="color: #808080; font-style: italic;"># Копируем таблицу в память, в неё мы ниже будем записывать</span><br />
write_sheet <span style="color: #66cc66;">=</span> write_book.<span style="color: black;">get_sheet</span><span style="color: black;">&#40;</span><span style="color: #ff4500;">0</span><span style="color: black;">&#41;</span> &nbsp;<span style="color: #808080; font-style: italic;"># Будем записывать в первый лист</span><br />
write_sheet.<span style="color: black;">write</span><span style="color: black;">&#40;</span><span style="color: #ff4500;">0</span><span style="color: #66cc66;">,</span> <span style="color: #ff4500;">0</span><span style="color: #66cc66;">,</span> read_sheet.<span style="color: black;">cell_value</span><span style="color: black;">&#40;</span><span style="color: #ff4500;">0</span><span style="color: #66cc66;">,</span> <span style="color: #ff4500;">0</span><span style="color: black;">&#41;</span> + <span style="color: #ff4500;">42</span><span style="color: black;">&#41;</span> &nbsp;<span style="color: #808080; font-style: italic;"># Прибавим к значению из ячейки &quot;A1&quot; число 42</span><br />
write_book.<span style="color: black;">save</span><span style="color: black;">&#40;</span>destination_filename<span style="color: black;">&#41;</span> &nbsp;<span style="color: #808080; font-style: italic;"># Сохраняем таблицу</span></div></div>
<p>Простейший пример использования <strong>испортит</strong> нам документ, в котором есть формулы, фильтры и прочие компоненты таблицы, поэтому это решение нам не подходит.</p>
<h3>PyUNO</h3>
<p>Теперь попробуем <strong>python-uno</strong>, его мы тоже установим, в добавок нам необходимо установить <strong>libreoffice</strong>, так как именно в libreoffice мы и будем производить изменения:</p>
<div class="codecolorer-container bash default" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:650px;"><div class="bash codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color: #c20cb9; font-weight: bold;">sudo</span> <span style="color: #c20cb9; font-weight: bold;">apt-get install</span> python-uno libreoffice</div></div>
<p>Пакеты python-uno и libreoffice можно установить на разные хосты, так как первый будет клиентом для второго.</p>
<p>Теперь запустим <strong>libreoffice</strong> на локальном хосте:</p>
<div class="codecolorer-container bash default" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:650px;"><div class="bash codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap">libreoffice <span style="color: #660033;">--accept</span>=<span style="color: #ff0000;">&quot;socket,host=localhost,port=2002;urp;StarOffice.ServiceManager&quot;</span></div></div>
<p>Пример кода по модификации одной ячейки через PyUNO:</p>
<div class="codecolorer-container python default" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:650px;"><div class="python codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color: #ff7700;font-weight:bold;">import</span> uno<br />
<br />
source_filename <span style="color: #66cc66;">=</span> <span style="color: #483d8b;">&quot;/tmp/example.xls&quot;</span><br />
destination_filename <span style="color: #66cc66;">=</span> <span style="color: #483d8b;">&quot;/tmp/example_new.xls&quot;</span><br />
<br />
<span style="color: #ff7700;font-weight:bold;">def</span> get_document<span style="color: black;">&#40;</span>filename<span style="color: black;">&#41;</span>:<br />
&nbsp; &nbsp; <span style="color: #483d8b;">&quot;&quot;&quot;Небольшая обертка для корретного открытия документа&quot;&quot;&quot;</span><br />
&nbsp; &nbsp; local <span style="color: #66cc66;">=</span> uno.<span style="color: black;">getComponentContext</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span><br />
&nbsp; &nbsp; resolver <span style="color: #66cc66;">=</span> local.<span style="color: black;">ServiceManager</span>.<span style="color: black;">createInstanceWithContext</span><span style="color: black;">&#40;</span><span style="color: #483d8b;">&quot;com.sun.star.bridge.UnoUrlResolver&quot;</span><span style="color: #66cc66;">,</span> local<span style="color: black;">&#41;</span><br />
&nbsp; &nbsp; context <span style="color: #66cc66;">=</span> resolver.<span style="color: black;">resolve</span><span style="color: black;">&#40;</span><span style="color: #483d8b;">&quot;uno:socket,host=localhost,port=2002;urp;StarOffice.ComponentContext&quot;</span><span style="color: black;">&#41;</span><br />
&nbsp; &nbsp; desktop <span style="color: #66cc66;">=</span> context.<span style="color: black;">ServiceManager</span>.<span style="color: black;">createInstanceWithContext</span><span style="color: black;">&#40;</span><span style="color: #483d8b;">&quot;com.sun.star.frame.Desktop&quot;</span><span style="color: #66cc66;">,</span> context<span style="color: black;">&#41;</span><br />
&nbsp; &nbsp; document <span style="color: #66cc66;">=</span> desktop.<span style="color: black;">loadComponentFromURL</span><span style="color: black;">&#40;</span>uno.<span style="color: black;">systemPathToFileUrl</span><span style="color: black;">&#40;</span>filename<span style="color: black;">&#41;</span><span style="color: #66cc66;">,</span> <span style="color: #483d8b;">&quot;_blank&quot;</span><span style="color: #66cc66;">,</span> <span style="color: #ff4500;">0</span><span style="color: #66cc66;">,</span> <span style="color: #008000;">tuple</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span><span style="color: black;">&#41;</span><br />
&nbsp; &nbsp; <span style="color: #ff7700;font-weight:bold;">return</span> document<br />
<br />
document <span style="color: #66cc66;">=</span> get_document<span style="color: black;">&#40;</span>source_filename<span style="color: black;">&#41;</span> &nbsp;<span style="color: #808080; font-style: italic;"># Окроем исходный документ</span><br />
sheet <span style="color: #66cc66;">=</span> document.<span style="color: black;">getSheets</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>.<span style="color: black;">getByIndex</span><span style="color: black;">&#40;</span><span style="color: #ff4500;">0</span><span style="color: black;">&#41;</span> &nbsp;<span style="color: #808080; font-style: italic;"># Получем первый лист</span><br />
cell <span style="color: #66cc66;">=</span> sheet.<span style="color: black;">getCellByPosition</span><span style="color: black;">&#40;</span><span style="color: #ff4500;">0</span><span style="color: #66cc66;">,</span> <span style="color: #ff4500;">0</span><span style="color: black;">&#41;</span> &nbsp;<span style="color: #808080; font-style: italic;"># Получим необходимую нам ячейку</span><br />
cell.<span style="color: black;">setString</span><span style="color: black;">&#40;</span><span style="color: #008000;">int</span><span style="color: black;">&#40;</span>cell.<span style="color: black;">getString</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span><span style="color: black;">&#41;</span> + <span style="color: #ff4500;">42</span><span style="color: black;">&#41;</span> &nbsp;<span style="color: #808080; font-style: italic;"># И запишем в неё новый результат</span><br />
<br />
<span style="color: #808080; font-style: italic;"># Сохраняем документ</span><br />
document.<span style="color: black;">storeToURL</span><span style="color: black;">&#40;</span>uno.<span style="color: black;">systemPathToFileUrl</span><span style="color: black;">&#40;</span>destination_filename<span style="color: black;">&#41;</span><span style="color: #66cc66;">,</span> <span style="color: black;">&#40;</span><span style="color: black;">&#41;</span><span style="color: black;">&#41;</span></div></div>
<p>Код далек от идеала, но для презентации возможностей это самое то.</p>
<p>Результат был достигнут&nbsp;&mdash; все компоненты в таблице остались не тронутыми, поменялась лишь ячейка, которую мы меняли.<br />
Вообщем <strong>python-uno</strong> идеально подходит для автоматизации работы с офисными документами без потерь!</p>
<h4>Рекомендую почитать</h4>
<ul>
<li><noindex><a rel="nofollow" href="http://wiki.services.openoffice.org/wiki/PyUNO_bridge" >PyUNO bridge&nbsp;&mdash; Apache OpenOffice.org Wiki</a></noindex></li>
<li><noindex><a rel="nofollow" href="http://vorushin.ru/blog/61-pyuno-django-interactive-shell/" >Интерактивная консоль для pyuno + django</a></noindex></li>
<li><noindex><a rel="nofollow" href="http://vorushin.ru/blog/58-openoffice-python-ms-word/" >OpenOffice + Python, pабота с файлами MS Word</a></noindex></li>
</ul>
]]></content:encoded>
			<wfw:commentRss>http://adw0rd.ru/2012/python-excel-xlwt-xlrd-xlutils-and-python-uno/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Django. Зарелизил расширение django-multi-sessions</title>
		<link>http://adw0rd.ru/2012/django-multi-sessions/</link>
		<comments>http://adw0rd.ru/2012/django-multi-sessions/#comments</comments>
		<pubDate>Mon, 27 Feb 2012 16:13:06 +0000</pubDate>
		<dc:creator>adw0rd</dc:creator>
				<category><![CDATA[Программирование]]></category>
		<category><![CDATA[Проекты]]></category>
		<category><![CDATA[Django]]></category>
		<category><![CDATA[GitHub]]></category>
		<category><![CDATA[PyPI]]></category>
		<category><![CDATA[Python]]></category>
		<category><![CDATA[Сессии]]></category>

		<guid isPermaLink="false">http://adw0rd.ru/?p=6833</guid>
		<description><![CDATA[Данное расширение предоставляет интерфейсы для работы с несколькими сессионными бекендами. В основном предназначено для переноса сессий с одного механизма на другой, при этом не останавливая работу с сессиями, это так называемый &#171;прозрачный перенос&#187;. Текущая версия: 0.0.3 Установить его можно так: pip install django-multi-sessions Или скачайте тарболл, распакуйте и выполните: python setup.py install Настройки Надо в [...]]]></description>
			<content:encoded><![CDATA[<p><noindex><a href="/2012/django-multi-sessions/"><img src="http://adw0rd.ru/wp-content/uploads/2009/11/Djangologo.gif"  alt="" title="Multi-sessions backend for Django" width="125" height="50" class="alignright size-full wp-image-4834" /></a></noindex></p>
<p>Данное расширение предоставляет интерфейсы для работы с несколькими сессионными бекендами. В основном предназначено для переноса сессий с одного механизма на другой, при этом не останавливая работу с сессиями, это так называемый &laquo;прозрачный перенос&raquo;.</p>
<p><strong>Текущая версия: 0.0.3</strong></p>
<p>Установить его можно так:</p>
<div class="codecolorer-container bash default" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:650px;"><div class="bash codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap">pip <span style="color: #c20cb9; font-weight: bold;">install</span> django-multi-sessions</div></div>
<p>Или <noindex><a rel="nofollow" href="http://pypi.python.org/pypi/django-multi-sessions" >скачайте тарболл</a></noindex>, распакуйте и выполните:</p>
<div class="codecolorer-container bash default" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:650px;"><div class="bash codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap">python setup.py <span style="color: #c20cb9; font-weight: bold;">install</span></div></div>
<p><span id="more-6833"></span></p>
<h3>Настройки</h3>
<p>Надо в settings.py объявить &laquo;multi_sessions.session&raquo; как SESSION_ENGINE и заполнить SESSION_MULTISESSIONS_POOL, как в примере:</p>
<div class="codecolorer-container python default" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:650px;"><div class="python codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap">SESSION_ENGINE <span style="color: #66cc66;">=</span> <span style="color: #483d8b;">&quot;multi_sessions.session&quot;</span><br />
SESSION_MULTISESSIONS_POOL <span style="color: #66cc66;">=</span> <span style="color: black;">&#40;</span><br />
&nbsp; &nbsp; <span style="color: black;">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #483d8b;">&quot;backend&quot;</span>: <span style="color: #483d8b;">&quot;redis_sessions.session&quot;</span><span style="color: #66cc66;">,</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #483d8b;">&quot;modes&quot;</span>: <span style="color: black;">&#91;</span><span style="color: #483d8b;">&quot;read&quot;</span><span style="color: #66cc66;">,</span> <span style="color: #483d8b;">&quot;write&quot;</span><span style="color: #66cc66;">,</span> <span style="color: #483d8b;">&quot;delete&quot;</span><span style="color: black;">&#93;</span><br />
&nbsp; &nbsp; <span style="color: black;">&#125;</span><span style="color: #66cc66;">,</span><br />
&nbsp; &nbsp; <span style="color: black;">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #483d8b;">&quot;backend&quot;</span>: <span style="color: #483d8b;">&quot;django.contrib.sessions.backends.db&quot;</span><span style="color: #66cc66;">,</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #483d8b;">&quot;modes&quot;</span>: <span style="color: black;">&#91;</span><span style="color: #483d8b;">&quot;read&quot;</span><span style="color: #66cc66;">,</span> <span style="color: #483d8b;">&quot;delete&quot;</span><span style="color: black;">&#93;</span><br />
&nbsp; &nbsp; <span style="color: black;">&#125;</span><span style="color: #66cc66;">,</span><br />
<span style="color: black;">&#41;</span></div></div>
<p>В этом примере <strong>redis-backend</strong> используется как приоритетное хранилище (чтение, сохранение/создание, удаление) данных, а <strong>database-backend</strong> используется только для чтения и удаления сессий, так как мы с него переходим на <strong>redis</strong>, то не имеет смысла в него сохранять данные.</p>
<h3>Исходники</h3>
<p>Исходные коды можно получить на <noindex><a rel="nofollow" href="https://github.com/adw0rd/django-multi-sessions" >гитхабе</a></noindex>!</p>
]]></content:encoded>
			<wfw:commentRss>http://adw0rd.ru/2012/django-multi-sessions/feed/</wfw:commentRss>
		<slash:comments>5</slash:comments>
		</item>
		<item>
		<title>Доступ к Wikipedia на время действия экрана SOPA</title>
		<link>http://adw0rd.ru/2012/wikipedia-sopa/</link>
		<comments>http://adw0rd.ru/2012/wikipedia-sopa/#comments</comments>
		<pubDate>Wed, 18 Jan 2012 13:43:32 +0000</pubDate>
		<dc:creator>adw0rd</dc:creator>
				<category><![CDATA[Программирование]]></category>
		<category><![CDATA[SOPA]]></category>
		<category><![CDATA[Wiki]]></category>
		<category><![CDATA[Wikipedia]]></category>

		<guid isPermaLink="false">http://adw0rd.ru/?p=6547</guid>
		<description><![CDATA[По просьбе моего друга решил запостить этот пост, вдруг кому пригодится! Википедия сегодня, 18 Января 2011 года, протестует против SOPA и закрыла доступ к контенту. Но при желании можно все равно этот контент посмотреть. Википедия никуда не убрала контент, она просто добавила на каждую страничку новый div, который и содержит слой с информацией про протест [...]]]></description>
			<content:encoded><![CDATA[<p><a href="http://adw0rd.ru/wp-content/uploads/2012/01/WP_SOPA_Splash_Full.jpg" ><img src="http://adw0rd.ru/wp-content/uploads/2012/01/WP_SOPA_Splash_Full-150x150.jpg" alt="" title="WP_SOPA_Splash_Full" width="150" height="150" class="alignright size-thumbnail wp-image-6548" /></a></p>
<p>По просьбе моего друга решил запостить этот пост, вдруг кому пригодится!</p>
<blockquote>
<p>
Википедия сегодня, 18 Января 2011 года, протестует против SOPA и закрыла доступ к контенту.</p>
<p>Но при желании можно все равно этот контент посмотреть. Википедия никуда не убрала контент, она просто добавила на каждую страничку новый div, который и содержит слой с информацией про протест против SOPA. А также добавила стиль display=none к слоям с контентом.</p>
<p>Все это дело легко отключается следующим скриптом (я написал его за 1-2 минуты), который выполняется из консоли Chrome или Firefox:</p>
<div class="codecolorer-container javascript default" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:650px;"><div class="javascript codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color: #003366; font-weight: bold;">var</span> jq <span style="color: #339933;">=</span> document.<span style="color: #660066;">createElement</span><span style="color: #009900;">&#40;</span><span style="color: #3366CC;">'script'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span><br />
jq.<span style="color: #660066;">src</span> <span style="color: #339933;">=</span> <span style="color: #3366CC;">&quot;https://ajax.googleapis.com/ajax/libs/jquery/1.6.2/jquery.min.js&quot;</span><span style="color: #339933;">;</span><br />
document.<span style="color: #660066;">getElementsByTagName</span><span style="color: #009900;">&#40;</span><span style="color: #3366CC;">'head'</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#91;</span><span style="color: #CC0000;">0</span><span style="color: #009900;">&#93;</span>.<span style="color: #660066;">appendChild</span><span style="color: #009900;">&#40;</span>jq<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span><br />
$<span style="color: #009900;">&#40;</span><span style="color: #3366CC;">'#mw-sopaOverlay'</span><span style="color: #009900;">&#41;</span>.<span style="color: #660066;">remove</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span><br />
$<span style="color: #009900;">&#40;</span><span style="color: #3366CC;">'#content'</span><span style="color: #009900;">&#41;</span>.<span style="color: #660066;">show</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></div></div>
<p>Все элементарно: первые три строчки подключают jquery, 4-я строчка удаляет слой SOPA, 5-я строчка показывает слой с контентом.</p>
<p>Можно этот скрипт повесить на Greaemonkey, и тогда автоматически вся википедия будет нормально показываться, как и прежде.</p>
<p>И да, я поддерживаю их протест против SOPA. Просто иногда нужно срочно получить информацию, даже если она скрыта.
</p>
</blockquote>
<p>Автор: Ivan, 18 января 2012 16:18.<br />
Оригинал: <noindex><a rel="nofollow" href="http://jdevnotes.blogspot.com/2012/01/wikipedia-sopa.html" >http://jdevnotes.blogspot.com/2012/01/wikipedia-sopa.html</a></noindex></p>
]]></content:encoded>
			<wfw:commentRss>http://adw0rd.ru/2012/wikipedia-sopa/feed/</wfw:commentRss>
		<slash:comments>4</slash:comments>
		</item>
		<item>
		<title>Андрей Аксенов: “Как готовить Sphinx” / мастер-класс, Киев, 18-ое июня</title>
		<link>http://adw0rd.ru/2011/sphinx-master-class/</link>
		<comments>http://adw0rd.ru/2011/sphinx-master-class/#comments</comments>
		<pubDate>Wed, 01 Jun 2011 19:28:24 +0000</pubDate>
		<dc:creator>adw0rd</dc:creator>
				<category><![CDATA[Конференции]]></category>
		<category><![CDATA[Операционные системы]]></category>
		<category><![CDATA[Программирование]]></category>
		<category><![CDATA[Sphinx]]></category>

		<guid isPermaLink="false">http://adw0rd.ru/?p=6322</guid>
		<description><![CDATA[В субботу, 18-го июня в Киеве пройдет мастер-класс создателя движка полнотекстового поиска Sphinx Андрея Аксенова ”Как готовить Sphinx”. Мастер-класс будет интересен разработчикам, руководителям и владельцам проектов, которые сталкиваются с проблемой поиска при высоких нагрузках. Sphinx используют такие монстры, как CraigsList, DailyMotion, Meetup, HupPages, HabraHabr и еще десятки высоконагруженных сайтов такие как Кинсбург. Андрей Аксенов выступал [...]]]></description>
			<content:encoded><![CDATA[<p><a href="http://adw0rd.ru/2011/sphinx-master-class/" ><img src="http://adw0rd.ru/wp-content/uploads/2011/06/axenov.jpg" alt="" title="axenov" width="100" height="112" class="alignright size-full wp-image-6323" /></a><br />
<strong>В субботу, 18-го июня в Киеве</strong> пройдет мастер-класс создателя движка полнотекстового поиска Sphinx Андрея Аксенова ”Как готовить Sphinx”.</p>
<p>Мастер-класс будет интересен разработчикам, руководителям и владельцам проектов, которые сталкиваются с проблемой поиска при высоких нагрузках.</p>
<p>Sphinx используют такие монстры, как <strong>CraigsList</strong>, <strong>DailyMotion</strong>, <strong>Meetup</strong>, <strong>HupPages</strong>, <strong>HabraHabr</strong> и еще десятки высоконагруженных сайтов такие как <noindex><a rel="nofollow" href="http://kinsburg.ru/" >Кинсбург</a></noindex>. Андрей Аксенов  выступал на многочисленных конференциях в России: <strong>“DevPoint 1-2″, “РИТ”, “DevConf 2011″, “HighLoad ++”</strong>. Организатор конференции пользователей Sphinx в Москве. Автор нашумевшего доклада “Как прекратить писать”.</p>
<p>Дополнительная информация и подробный план мастер-класса можно посмотреть на сайте <noindex><a rel="nofollow" href=" http://www.smartme.com.ua/sphinx-workshop/" >http://www.smartme.com.ua/sphinx-workshop/</a></noindex></p>
]]></content:encoded>
			<wfw:commentRss>http://adw0rd.ru/2011/sphinx-master-class/feed/</wfw:commentRss>
		<slash:comments>7</slash:comments>
		</item>
		<item>
		<title>FreeBSD. XHProf для анализа производительности PHP</title>
		<link>http://adw0rd.ru/2010/freebsd-xhprof-php/</link>
		<comments>http://adw0rd.ru/2010/freebsd-xhprof-php/#comments</comments>
		<pubDate>Wed, 24 Nov 2010 23:00:20 +0000</pubDate>
		<dc:creator>adw0rd</dc:creator>
				<category><![CDATA[Операционные системы]]></category>
		<category><![CDATA[Программирование]]></category>
		<category><![CDATA[FreeBSD]]></category>
		<category><![CDATA[PHP]]></category>
		<category><![CDATA[XHProf]]></category>
		<category><![CDATA[Оптимизация]]></category>

		<guid isPermaLink="false">http://adw0rd.ru/?p=5510</guid>
		<description><![CDATA[Решил я воспользоваться утилитой для профилирования производительности веб-приложения XHProf от Facebook. И она мне так понравилась, что я решил написать про неё небольшой пост. Утилита проводит анализ работы сайта, выводит информацию о использование каждой функции на пути работы приложения (например, загрузки определенной страницы сайта), а именно: количество вызовов определенной функции, затраченное время, кол-во потребляемой памяти [...]]]></description>
			<content:encoded><![CDATA[<p><a href="http://adw0rd.ru/wp-content/uploads/2010/04/xhprof.jpg" ><img src="http://adw0rd.ru/wp-content/uploads/2010/04/xhprof.jpg" alt="" title="xhprof" width="199" height="100" class="alignright size-full wp-image-5526" /></a></p>
<p>Решил я воспользоваться утилитой для профилирования производительности веб-приложения <strong>XHProf</strong> от Facebook. И она мне так понравилась, что я решил написать про неё небольшой пост.</p>
<p>Утилита проводит анализ работы сайта, выводит информацию о использование каждой функции на пути работы приложения (например, загрузки определенной страницы сайта), а именно: количество вызовов определенной функции, затраченное время, кол-во потребляемой памяти и ресурсов процессора.</p>
<blockquote>
<p>
<strong>Профилирование</strong> — сбор характеристик работы программы, таких как время выполнения отдельных фрагментов (обычно подпрограмм), число верно предсказанных условных переходов, число кэш промахов и т. д. Инструмент, используемый для анализа работы, называют профилировщиком. Обычно выполняется совместно с оптимизацией программы.</p>
<p><noindex><a rel="nofollow" href="http://ru.wikipedia.org/wiki/%D0%9F%D1%80%D0%BE%D1%84%D0%B8%D0%BB%D0%B8%D1%80%D0%BE%D0%B2%D0%B0%D0%BD%D0%B8%D0%B5_%28%D0%B8%D0%BD%D1%84%D0%BE%D1%80%D0%BC%D0%B0%D1%82%D0%B8%D0%BA%D0%B0%29" >Профилирование в Wikipedia</a></noindex>
</p>
</blockquote>
<p><span id="more-5510"></span></p>
<p>Данные выводятся в виде таблицы:</p>
<p><img src="http://adw0rd.ru/wp-content/uploads/2010/05/xhprof_table.jpg" alt="" title="xhprof_table" width="809" height="407" class="alignnone size-full wp-image-6186" style="border:dotted 2px gray;padding:10px;" /></p>
<p>Так же она может отрисовать граф с помощью <noindex><a rel="nofollow" href="http://ru.wikipedia.org/wiki/Graphviz" >GraphViz</a></noindex>, но для этого он должен быть предварительно собран в системе (об этом ниже):</p>
<p><img src="http://adw0rd.ru/wp-content/uploads/2010/05/xhprof_callgraph.jpg" alt="" title="xhprof_callgraph" width="223" height="528" class="alignnone size-full wp-image-6187" style="border:dotted 2px gray;padding:10px;" /></p>
<p><strong>XHProf</strong> представляет собой pecl-расширение для PHP, написана она на си, поэтому достигается высокая с ее стороны производительность и ее можно использовать на продакшен сервере для анализа реальных данных.</p>
<h3>Установка</h3>
<p>Я собирал расширение из сорцов, для этого заходим на <noindex><a rel="nofollow" href="http://pecl.php.net/package/xhprof" >страницу расширения</a></noindex> и качаем необходимую нам версию, у меня это <noindex><a rel="nofollow" href="http://pecl.php.net/get/xhprof-0.9.2.tgz" >xhprof-0.9.2</a></noindex>:</p>
<div class="codecolorer-container bash default" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:650px;"><div class="bash codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color: #7a0874; font-weight: bold;">cd</span> <span style="color: #000000; font-weight: bold;">/</span>tmp<br />
fetch http:<span style="color: #000000; font-weight: bold;">//</span>pecl.php.net<span style="color: #000000; font-weight: bold;">/</span>get<span style="color: #000000; font-weight: bold;">/</span>xhprof-0.9.2.tgz<br />
<span style="color: #c20cb9; font-weight: bold;">tar</span> <span style="color: #660033;">-xzf</span> xhprof-0.9.2.tgz<br />
<span style="color: #7a0874; font-weight: bold;">cd</span> xhprof-0.9.2<span style="color: #000000; font-weight: bold;">/</span>extension<span style="color: #000000; font-weight: bold;">/</span><br />
phpize<br />
.<span style="color: #000000; font-weight: bold;">/</span>configure <span style="color: #660033;">--with-php-config</span>=<span style="color: #000000; font-weight: bold;">/</span>usr<span style="color: #000000; font-weight: bold;">/</span>local<span style="color: #000000; font-weight: bold;">/</span>bin<span style="color: #000000; font-weight: bold;">/</span>php-config<br />
<span style="color: #c20cb9; font-weight: bold;">make</span> <span style="color: #000000; font-weight: bold;">&amp;&amp;</span> <span style="color: #c20cb9; font-weight: bold;">make</span> <span style="color: #c20cb9; font-weight: bold;">install</span></div></div>
<p>Пропишите расширение в php.ini или в php/extensions.ini:</p>
<div class="codecolorer-container text default" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:650px;"><div class="text codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap">extension=xhprof.so</div></div>
<blockquote>
<p>
Вы можете поставить расширение <strong>XHProf</strong> из портов (/usr/ports/devel/pecl-xhprof/).<br />
В мае, когда я практически написал эту статью, его ещё там небыло.
</p>
</blockquote>
<p>Укажите в php.ini каталог, который будет играть роль хранилища ваших данных:</p>
<div class="codecolorer-container text default" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:650px;"><div class="text codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap">[xhprof] &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <br />
xhprof.output_dir=/usr/local/xhprof/out</div></div>
<p>Ну и создать его тоже надо, естественно:</p>
<div class="codecolorer-container text default" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:650px;"><div class="text codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap">mkdir -p /usr/local/xhprof/out</div></div>
<h4>XHProf UI</h4>
<p>Теперь настроим веб-интерфейс <strong>XHProf</strong>, для этого скопируем сорцы в свой каталог:</p>
<div class="codecolorer-container bash default" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:650px;"><div class="bash codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color: #c20cb9; font-weight: bold;">mkdir</span> <span style="color: #000000; font-weight: bold;">/</span>usr<span style="color: #000000; font-weight: bold;">/</span>local<span style="color: #000000; font-weight: bold;">/</span>xhprof<span style="color: #000000; font-weight: bold;">/</span><br />
<span style="color: #c20cb9; font-weight: bold;">cp</span> <span style="color: #660033;">-R</span> <span style="color: #000000; font-weight: bold;">/</span>tmp<span style="color: #000000; font-weight: bold;">/</span>xhprof-0.9.2<span style="color: #000000; font-weight: bold;">/</span> <span style="color: #000000; font-weight: bold;">/</span>usr<span style="color: #000000; font-weight: bold;">/</span>local<span style="color: #000000; font-weight: bold;">/</span>xhprof<span style="color: #000000; font-weight: bold;">/</span></div></div>
<p>И пропишем новый хост в nginx:</p>
<div class="codecolorer-container bash default" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:650px;"><div class="bash codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap">server <span style="color: #7a0874; font-weight: bold;">&#123;</span><br />
&nbsp; &nbsp; listen <span style="color: #000000;">80</span>;<br />
&nbsp; &nbsp; server_name xhprof.test;<br />
&nbsp; &nbsp; charset utf8;<br />
&nbsp; &nbsp; root <span style="color: #000000; font-weight: bold;">/</span>usr<span style="color: #000000; font-weight: bold;">/</span>local<span style="color: #000000; font-weight: bold;">/</span>xhprof<span style="color: #000000; font-weight: bold;">/</span>xhprof_html;<br />
&nbsp; &nbsp; index index.php;<br />
<br />
&nbsp; &nbsp; location ~ \.php$ <span style="color: #7a0874; font-weight: bold;">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; fastcgi_pass php-fpm;<br />
&nbsp; &nbsp; &nbsp; &nbsp; fastcgi_index index.php;<br />
&nbsp; &nbsp; &nbsp; &nbsp; fastcgi_param SCRIPT_FILENAME <span style="color: #007800;">$document_root</span><span style="color: #007800;">$fastcgi_script_name</span>;<br />
&nbsp; &nbsp; &nbsp; &nbsp; include fastcgi_params;<br />
&nbsp; &nbsp; <span style="color: #7a0874; font-weight: bold;">&#125;</span><br />
<span style="color: #7a0874; font-weight: bold;">&#125;</span></div></div>
<p>Перезагружаем nginx:</p>
<div class="codecolorer-container bash default" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:650px;"><div class="bash codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap">nginx <span style="color: #660033;">-s</span> reload</div></div>
<p>А в локальном файле hosts завяжем домен:</p>
<div class="codecolorer-container text default" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:650px;"><div class="text codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap">123.45.67.89 xhprof.test</div></div>
<p>Где &laquo;123.45.67.89&raquo;&nbsp;&mdash; ip машины на которой стоит <strong>XHProf</strong>, то есть где мы его только что устанавливали.</p>
<h4>Собираем Graphviz</h4>
<p>Для построение визуализации соберем Graphviz (крайне рекомендую это сделать, будет намного нагляднее).</p>
<div class="codecolorer-container bash default" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:650px;"><div class="bash codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color: #7a0874; font-weight: bold;">cd</span> <span style="color: #000000; font-weight: bold;">/</span>usr<span style="color: #000000; font-weight: bold;">/</span>ports<span style="color: #000000; font-weight: bold;">/</span>graphics<span style="color: #000000; font-weight: bold;">/</span>graphviz<br />
<span style="color: #c20cb9; font-weight: bold;">make</span> <span style="color: #c20cb9; font-weight: bold;">install</span> clean</div></div>
<h4>Собираем Ctype</h4>
<p>Вам так же может понадобится Ctype</p>
<div class="codecolorer-container bash default" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:650px;"><div class="bash codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color: #7a0874; font-weight: bold;">cd</span> <span style="color: #000000; font-weight: bold;">/</span>usr<span style="color: #000000; font-weight: bold;">/</span>ports<span style="color: #000000; font-weight: bold;">/</span>textproc<span style="color: #000000; font-weight: bold;">/</span>php5-ctype<br />
<span style="color: #c20cb9; font-weight: bold;">make</span> <span style="color: #c20cb9; font-weight: bold;">install</span> clean</div></div>
<h3>Настройка</h3>
<p>Теперь настроим <strong>XHProf</strong> так, чтобы он профилировал только когда у нас установлена специальная кука. Для это создадим два файла &laquo;/usr/local/xhprof/header.php&raquo; и &laquo;/usr/local/xhprof/footer.php&raquo;, со следующим содержимым:</p>
<p>1. Отредактируйте &laquo;/usr/local/xhprof/header.php&raquo;:</p>
<div class="codecolorer-container php default" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:650px;"><div class="php codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color: #000000; font-weight: bold;">&lt;?php</span><br />
<span style="color: #b1b100;">if</span><span style="color: #009900;">&#40;</span><span style="color: #990000;">isset</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$_COOKIE</span><span style="color: #009900;">&#91;</span><span style="color: #0000ff;">'xhprof'</span><span style="color: #009900;">&#93;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#123;</span><br />
&nbsp; &nbsp; <span style="color: #b1b100;">if</span> <span style="color: #009900;">&#40;</span><span style="color: #990000;">extension_loaded</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'xhprof'</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #000088;">$utils_path</span> <span style="color: #339933;">=</span> <span style="color: #0000ff;">&quot;/usr/local/xhprof/xhprof_lib/utils/&quot;</span><span style="color: #339933;">;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #b1b100;">include_once</span> <span style="color: #000088;">$utils_path</span><span style="color: #339933;">.</span><span style="color: #0000ff;">'xhprof_lib.php'</span><span style="color: #339933;">;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #b1b100;">include_once</span> <span style="color: #000088;">$utils_path</span><span style="color: #339933;">.</span><span style="color: #0000ff;">'xhprof_runs.php'</span><span style="color: #339933;">;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; xhprof_enable<span style="color: #009900;">&#40;</span>XHPROF_FLAGS_CPU <span style="color: #339933;">+</span> XHPROF_FLAGS_MEMORY<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span><br />
&nbsp; &nbsp; <span style="color: #009900;">&#125;</span><br />
<span style="color: #009900;">&#125;</span></div></div>
<p>Он срабатывает только если установлена кука &laquo;xhprof&raquo;, подключает необходимые библиотеки и устанавливает необходимые флаги (об этом чуть ниже).</p>
<p>2. Отредактируйте &laquo;/usr/local/xhprof/footer.php&raquo;:</p>
<div class="codecolorer-container php default" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:650px;"><div class="php codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color: #000000; font-weight: bold;">&lt;?php</span><br />
<span style="color: #b1b100;">if</span><span style="color: #009900;">&#40;</span><span style="color: #990000;">isset</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$_COOKIE</span><span style="color: #009900;">&#91;</span><span style="color: #0000ff;">'xhprof'</span><span style="color: #009900;">&#93;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#123;</span><br />
&nbsp; &nbsp; <span style="color: #b1b100;">if</span> <span style="color: #009900;">&#40;</span><span style="color: #990000;">extension_loaded</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'xhprof'</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #000088;">$profiler_namespace</span> <span style="color: #339933;">=</span> <span style="color: #0000ff;">'myapp'</span><span style="color: #339933;">;</span> <span style="color: #666666; font-style: italic;">// namespace for your application</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #000088;">$xhprof_data</span> <span style="color: #339933;">=</span> xhprof_disable<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #000088;">$xhprof_runs</span> <span style="color: #339933;">=</span> <span style="color: #000000; font-weight: bold;">new</span> XHProfRuns_Default<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #000088;">$run_id</span> <span style="color: #339933;">=</span> <span style="color: #000088;">$xhprof_runs</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">save_run</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$xhprof_data</span><span style="color: #339933;">,</span> <span style="color: #000088;">$profiler_namespace</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span><br />
<br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #666666; font-style: italic;">// url to the XHProf UI libraries (change the host name and path)</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #000088;">$profiler_url</span> <span style="color: #339933;">=</span> <span style="color: #990000;">sprintf</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'http://xhprof.test/index.php?run=%s&amp;source=%s'</span><span style="color: #339933;">,</span> <span style="color: #000088;">$run_id</span><span style="color: #339933;">,</span> <span style="color: #000088;">$profiler_namespace</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #b1b100;">echo</span> <span style="color: #0000ff;">'&lt;a href=&quot;'</span><span style="color: #339933;">.</span><span style="color: #000088;">$profiler_url</span><span style="color: #339933;">.</span><span style="color: #0000ff;">'&quot;&gt;Profiler output&lt;/a&gt;'</span><span style="color: #339933;">;</span><br />
&nbsp; &nbsp; <span style="color: #009900;">&#125;</span><br />
<span style="color: #009900;">&#125;</span></div></div>
<p>Он срабатывает только если установлена кука &laquo;xhprof&raquo;, устанавливает неймспейс и сохраняет собранные показатели. После чего отрисовывает ссылку на веб-интерфейс <strong>XHProf</strong> для последующего анализа.</p>
<p>Теперь добавим в конец две строки в php.ini, для того чтобы эти два скрипта стартовали в начале и конце соответственно:</p>
<div class="codecolorer-container text default" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:650px;"><div class="text codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap">auto_prepend_file = /usr/local/xhprof/header.php<br />
auto_append_file = /usr/local/xhprof/footer.php</div></div>
<p>Более подробная документация по <strong>XHProf</strong>: <noindex><a rel="nofollow" href="http://mirror.facebook.net/facebook/xhprof/doc.html" >http://mirror.facebook.net/facebook/xhprof/doc.html</a></noindex></p>
<h3>Проблема с dot</h3>
<p>Утилита dot это тот самый Graphviz и с ним бывает проблема, что-то типа того:</p>
<blockquote>
<p>Error: either we can not find profile data for run_id 4ced888563969 or the threshold 0.01 is too small or you do not have &#39;dot&#39; image generation utility installed.</p>
</blockquote>
<p>Сначала зайдите в &laquo;/usr/local/xhprof/xhprof_lib/utils/callgraph_utils.php&raquo; и найдите функцию &laquo;xhprof_generate_image_by_dot&raquo; (примерно 96 строка). Отредактируйте массив $descriptorspec, указав путь до файла лога:</p>
<div class="codecolorer-container php default" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:650px;"><div class="php codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap">&nbsp; <span style="color: #000088;">$descriptorspec</span> <span style="color: #339933;">=</span> <span style="color: #990000;">array</span><span style="color: #009900;">&#40;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp;<span style="color: #666666; font-style: italic;">// stdin is a pipe that the child will read from</span><br />
&nbsp; &nbsp; &nbsp; &nbsp;<span style="color: #cc66cc;">0</span> <span style="color: #339933;">=&gt;</span> <span style="color: #990000;">array</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">&quot;pipe&quot;</span><span style="color: #339933;">,</span> <span style="color: #0000ff;">&quot;r&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">,</span><br />
&nbsp; &nbsp; &nbsp; &nbsp;<span style="color: #666666; font-style: italic;">// stdout is a pipe that the child will write to</span><br />
&nbsp; &nbsp; &nbsp; &nbsp;<span style="color: #cc66cc;">1</span> <span style="color: #339933;">=&gt;</span> <span style="color: #990000;">array</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">&quot;pipe&quot;</span><span style="color: #339933;">,</span> <span style="color: #0000ff;">&quot;w&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">,</span><br />
&nbsp; &nbsp; &nbsp; &nbsp;<span style="color: #666666; font-style: italic;">// stderr is a file to write to</span><br />
&nbsp; &nbsp; &nbsp; &nbsp;<span style="color: #666666; font-style: italic;">//2 =&gt; array(&quot;file&quot;, &quot;/dev/null&quot;, &quot;a&quot;)</span><br />
&nbsp; &nbsp; &nbsp; &nbsp;<span style="color: #666666; font-style: italic;">// Путь до файла лога</span><br />
&nbsp; &nbsp; &nbsp; &nbsp;<span style="color: #cc66cc;">2</span> <span style="color: #339933;">=&gt;</span> <span style="color: #990000;">array</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">&quot;file&quot;</span><span style="color: #339933;">,</span> <span style="color: #0000ff;">&quot;/var/log/xhprof.log&quot;</span><span style="color: #339933;">,</span> <span style="color: #0000ff;">&quot;a+&quot;</span><span style="color: #009900;">&#41;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp;<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></div></div>
<p>Ну и теперь запускайте и смотрите лог, если у вас там:</p>
<blockquote>
<p>
dot: not found
</p>
</blockquote>
<p>То просто укажите полный путь до dot:</p>
<div class="codecolorer-container php default" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:650px;"><div class="php codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color: #000088;">$cmd</span> <span style="color: #339933;">=</span> <span style="color: #0000ff;">&quot; /usr/local/bin/dot -T&quot;</span><span style="color: #339933;">.</span><span style="color: #000088;">$type</span><span style="color: #339933;">;</span></div></div>
<p>Это примерно 107 строка того же файла &laquo;/usr/local/xhprof/xhprof_lib/utils/callgraph_utils.php&raquo;.</p>
<h3>Ссылки</h3>
<p>Посты, от которых я узнал о <strong>XHProf</strong>:</p>
<ul>
<li><noindex><a rel="nofollow" href="http://highload.com.ua/index.php/2009/08/21/xhprof-%D0%BF%D1%80%D0%BE%D1%84%D0%B8%D0%BB%D0%B8%D1%80%D0%BE%D0%B2%D0%B0%D0%BD%D0%B8%D0%B5-php-%D0%BE%D1%82-facebook/" >XHprof&nbsp;&mdash; профилирование PHP от Facebook</a></noindex></li>
<li><noindex><a rel="nofollow" href="http://habrahabr.ru/blogs/php/78210/" >Профилирование PHP-кода</a></noindex></li>
</ul>
<p>Советую почитать:</p>
<ul>
<li><noindex><a rel="nofollow" href="http://tigor.com.ua/blog/2009/12/13/profiling-php-with-xhprof/" >XHprof – профайлер PHP от Facebook</a></noindex></li>
<li><noindex><a rel="nofollow" href="http://mirror.facebook.net/facebook/xhprof/doc.html" >XHProf Documentation</a></noindex></li>
</ul>
]]></content:encoded>
			<wfw:commentRss>http://adw0rd.ru/2010/freebsd-xhprof-php/feed/</wfw:commentRss>
		<slash:comments>6</slash:comments>
		</item>
		<item>
		<title>Django. Первое приложение</title>
		<link>http://adw0rd.ru/2010/django-first-app/</link>
		<comments>http://adw0rd.ru/2010/django-first-app/#comments</comments>
		<pubDate>Wed, 26 May 2010 17:09:03 +0000</pubDate>
		<dc:creator>adw0rd</dc:creator>
				<category><![CDATA[Python. Изучаем вместе!]]></category>
		<category><![CDATA[Программирование]]></category>
		<category><![CDATA[Django]]></category>
		<category><![CDATA[Python]]></category>

		<guid isPermaLink="false">http://adw0rd.ru/?p=4852</guid>
		<description><![CDATA[Захотелось мне поведать как использовать связь ManyToMany, начал я значит писать пост, но так как я хотел его детализировать то он слишком разросся... И я решил сначала написать пост о том, как создавать первый проект и приложение на Django, чтобы потом ссылаться сюда. &#8212; начинал я этот пост писать еще в том году, да все [...]]]></description>
			<content:encoded><![CDATA[<p><img src="http://adw0rd.ru/wp-content/uploads/2009/11/Djangologo.gif" alt="Djangologo" title="Djangologo" width="125" height="50" class="alignright size-full wp-image-4834" /></p>
<p>Захотелось мне поведать как использовать связь <strong>ManyToMany</strong>, начал я значит писать пост, но так как я хотел его детализировать то он слишком разросся... И я решил сначала написать пост о том, как создавать первый проект и приложение на <strong>Django</strong>, чтобы потом ссылаться сюда.</p>
<p><i style="color:#c4c4c4">&mdash; начинал я этот пост писать еще в том году, да все руки не доходили его закончить, спасибо vasa_c за терпение</i></p>
<h3>Устанавливаем Django</h3>
<p>Заходим на страницу <noindex><a rel="nofollow" href="http://www.djangoproject.com/download/" >загрузки официального сайта</a></noindex>, скачиваем <noindex><a rel="nofollow" href="http://www.djangoproject.com/download/1.1.1/tarball/" >Django 1.1.1</a></noindex> (или выше). Далее, как и в инструкции:</p>
<div class="codecolorer-container bash default" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:650px;"><div class="bash codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color: #7a0874; font-weight: bold;">cd</span> <span style="color: #000000; font-weight: bold;">/</span>tmp<br />
<span style="color: #c20cb9; font-weight: bold;">wget</span> <span style="color: #660033;">-O</span> Django-1.1.1.tar.gz http:<span style="color: #000000; font-weight: bold;">//</span>www.djangoproject.com<span style="color: #000000; font-weight: bold;">/</span>download<span style="color: #000000; font-weight: bold;">/</span>1.1.1<span style="color: #000000; font-weight: bold;">/</span>tarball<span style="color: #000000; font-weight: bold;">/</span><br />
<span style="color: #c20cb9; font-weight: bold;">tar</span> <span style="color: #660033;">-xzvf</span> Django-1.1.1.tar.gz<br />
<span style="color: #7a0874; font-weight: bold;">cd</span> Django-1.1.1<br />
<span style="color: #c20cb9; font-weight: bold;">sudo</span> python setup.py <span style="color: #c20cb9; font-weight: bold;">install</span></div></div>
<p>Все, джанго установлен!<br />
<span id="more-4852"></span><br />
Так как мы будем работать с MySQL, то вам надо установить библиотеку py-mysqldb, представляющая собой интерфейс к MySQL.</p>
<h4>Для Ubuntu:</h4>
<div class="codecolorer-container bash default" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:650px;"><div class="bash codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color: #c20cb9; font-weight: bold;">apt-get install</span> python-mysqldb</div></div>
<h4>Для FreeBSD</h4>
<div class="codecolorer-container bash default" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:650px;"><div class="bash codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color: #7a0874; font-weight: bold;">cd</span> <span style="color: #000000; font-weight: bold;">/</span>usr<span style="color: #000000; font-weight: bold;">/</span>ports<span style="color: #000000; font-weight: bold;">/</span>databases<span style="color: #000000; font-weight: bold;">/</span>py-MySQLdb<br />
<span style="color: #c20cb9; font-weight: bold;">make</span> <span style="color: #c20cb9; font-weight: bold;">install</span> clean</div></div>
<p>А для Windows можно скачать <noindex><a rel="nofollow" href="http://sourceforge.net/projects/mysql-python/files/mysql-python/" >тут</a></noindex>.</p>
<h3>Создаем наш первый проект</h3>
<p>Допустим, что имя проекта у нас будет &laquo;myproject&raquo;:</p>
<div class="codecolorer-container python default" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:650px;"><div class="python codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color: #dc143c;">cd</span> /www<br />
django-admin.<span style="color: black;">py</span> startproject myproject</div></div>
<p>Теперь создайте себе новую БД &laquo;myproject&raquo;:</p>
<div class="codecolorer-container sql default" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:650px;"><div class="sql codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color: #993333; font-weight: bold;">CREATE</span> <span style="color: #993333; font-weight: bold;">DATABASE</span> <span style="color: #ff0000;">`myproject`</span> <span style="color: #993333; font-weight: bold;">DEFAULT</span> <span style="color: #993333; font-weight: bold;">CHARACTER</span> <span style="color: #993333; font-weight: bold;">SET</span> utf8 <span style="color: #993333; font-weight: bold;">COLLATE</span> utf8_general_ci;</div></div>
<p>И отредактируйте &laquo;/www/myproject/settings.py&raquo;, заменив только соответствующие части:</p>
<div class="codecolorer-container python default" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:650px;"><div class="python codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color: #808080; font-style: italic;"># ~*~ coding: utf-8 ~*~</span><br />
<br />
...<br />
<span style="color: #808080; font-style: italic;"># Настройки БД</span><br />
DATABASE_ENGINE <span style="color: #66cc66;">=</span> <span style="color: #483d8b;">'mysql'</span> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #808080; font-style: italic;"># 'postgresql_psycopg2', 'postgresql', 'mysql', 'sqlite3' or 'oracle'.</span><br />
DATABASE_NAME <span style="color: #66cc66;">=</span> <span style="color: #483d8b;">'myproject'</span> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #808080; font-style: italic;"># Or path to database file if using sqlite3.</span><br />
DATABASE_USER <span style="color: #66cc66;">=</span> <span style="color: #483d8b;">'username'</span> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #808080; font-style: italic;"># Not used with sqlite3.</span><br />
DATABASE_PASSWORD <span style="color: #66cc66;">=</span> <span style="color: #483d8b;">'password'</span> &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #808080; font-style: italic;"># Not used with sqlite3.</span><br />
DATABASE_HOST <span style="color: #66cc66;">=</span> <span style="color: #483d8b;">''</span> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #808080; font-style: italic;"># Set to empty string for localhost. Not used with sqlite3.</span><br />
DATABASE_PORT <span style="color: #66cc66;">=</span> <span style="color: #483d8b;">''</span> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #808080; font-style: italic;"># Set to empty string for default. Not used with sqlite3.</span><br />
<br />
...<br />
<span style="color: #808080; font-style: italic;"># Путь до каталога, где лежат наши медиа файлы (css, js, images)</span><br />
MEDIA_ROOT <span style="color: #66cc66;">=</span> <span style="color: #483d8b;">'/www/myproject/static/'</span><br />
<br />
...<br />
<span style="color: #808080; font-style: italic;"># URL медиа файлов (css, js, images)</span><br />
MEDIA_URL <span style="color: #66cc66;">=</span> <span style="color: #483d8b;">'/'</span><br />
<br />
...<br />
<span style="color: #808080; font-style: italic;"># URL медиа файлов админки (css, js, images, etc)</span><br />
ADMIN_MEDIA_PREFIX <span style="color: #66cc66;">=</span> <span style="color: #483d8b;">'/admin-media/'</span><br />
<br />
...<br />
<span style="color: #808080; font-style: italic;"># Путь до каталога с шаблонами</span><br />
TEMPLATE_DIRS <span style="color: #66cc66;">=</span> <span style="color: black;">&#40;</span><br />
&nbsp; &nbsp; <span style="color: #483d8b;">&quot;/www/myproject/blog/templates&quot;</span><span style="color: #66cc66;">,</span><br />
<span style="color: black;">&#41;</span><br />
<br />
...<br />
<span style="color: #808080; font-style: italic;"># Установленные приложения в нашем проекте</span><br />
INSTALLED_APPS <span style="color: #66cc66;">=</span> <span style="color: black;">&#40;</span><br />
&nbsp; &nbsp; <span style="color: #483d8b;">'django.contrib.auth'</span><span style="color: #66cc66;">,</span><br />
&nbsp; &nbsp; <span style="color: #483d8b;">'django.contrib.contenttypes'</span><span style="color: #66cc66;">,</span><br />
&nbsp; &nbsp; <span style="color: #483d8b;">'django.contrib.sessions'</span><span style="color: #66cc66;">,</span><br />
&nbsp; &nbsp; <span style="color: #483d8b;">'django.contrib.sites'</span><span style="color: #66cc66;">,</span><br />
&nbsp; &nbsp; <span style="color: #483d8b;">'django.contrib.admin'</span><span style="color: #66cc66;">,</span><br />
&nbsp; &nbsp; <span style="color: #483d8b;">'myproject.blog'</span><span style="color: #66cc66;">,</span><br />
<span style="color: black;">&#41;</span><br />
<span style="color: #808080; font-style: italic;"># в конец добавлено две строки, первая подключает джанговскую админку,</span><br />
<span style="color: #808080; font-style: italic;"># а второе наше приложение, которое мы ниже опишем</span></div></div>
<p>Для чего я ставлю в начале строки <strong>&laquo;#~*~ coding: utf-8 ~*~&raquo;</strong> читайте <noindex><a rel="nofollow" href="http://www.python.org/dev/peps/pep-0263/" >тут</a></noindex>.</p>
<h3>Создаем наше первое приложение</h3>
<p>После того, как вы создали проект, надо создать приложение, если у вас проект состоит из одного приложения&nbsp;&mdash; можете его назвать &laquo;main&raquo;.</p>
<p>Создаем приложение &laquo;blog&raquo;:</p>
<div class="codecolorer-container python default" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:650px;"><div class="python codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color: #dc143c;">cd</span> /www/myproject<br />
python manage.<span style="color: black;">py</span> startapp blog</div></div>
<h4>Файл модели</h4>
<p>Теперь перейдем к разработке модели нашего приложения, отредактируем &laquo;/www/myproject/blog/models.py&raquo;.<br />
У нас будет пока одна сущность, это Посты в Блоге:</p>
<div class="codecolorer-container python default" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:650px;"><div class="python codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color: #808080; font-style: italic;"># ~*~ coding: utf-8 ~*~</span><br />
<br />
<span style="color: #808080; font-style: italic;"># импортируем класс модели</span><br />
<span style="color: #ff7700;font-weight:bold;">from</span> django.<span style="color: black;">db</span> <span style="color: #ff7700;font-weight:bold;">import</span> models<br />
<span style="color: #808080; font-style: italic;"># и админки</span><br />
<span style="color: #ff7700;font-weight:bold;">from</span> django.<span style="color: black;">contrib</span> <span style="color: #ff7700;font-weight:bold;">import</span> admin<br />
<br />
<span style="color: #483d8b;">'''<br />
Blog posts<br />
'''</span><br />
<span style="color: #ff7700;font-weight:bold;">class</span> Post<span style="color: black;">&#40;</span>models.<span style="color: black;">Model</span><span style="color: black;">&#41;</span>:<br />
&nbsp; &nbsp; <span style="color: #808080; font-style: italic;"># название поста</span><br />
&nbsp; &nbsp; title <span style="color: #66cc66;">=</span> models.<span style="color: black;">CharField</span><span style="color: black;">&#40;</span>max_length<span style="color: #66cc66;">=</span><span style="color: #ff4500;">100</span><span style="color: black;">&#41;</span><br />
&nbsp; &nbsp; <span style="color: #808080; font-style: italic;"># содержимое поста</span><br />
&nbsp; &nbsp; text <span style="color: #66cc66;">=</span> models.<span style="color: black;">TextField</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span><br />
<br />
&nbsp; &nbsp; <span style="color: #808080; font-style: italic;"># функция необходима для того, чтобы при выводе объекта Post</span><br />
&nbsp; &nbsp; <span style="color: #808080; font-style: italic;"># как строки выводился вместо этого его title</span><br />
&nbsp; &nbsp; <span style="color: #ff7700;font-weight:bold;">def</span> <span style="color: #0000cd;">__unicode__</span><span style="color: black;">&#40;</span><span style="color: #008000;">self</span><span style="color: black;">&#41;</span>:<br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #ff7700;font-weight:bold;">return</span> <span style="color: #008000;">self</span>.<span style="color: black;">title</span><span style="color: #66cc66;">;</span><br />
<br />
<span style="color: #483d8b;">'''<br />
Класс для админки, тут будут дополнительные атрибуты необходимые для админки<br />
'''</span><br />
<span style="color: #ff7700;font-weight:bold;">class</span> PostAdmin<span style="color: black;">&#40;</span>admin.<span style="color: black;">ModelAdmin</span><span style="color: black;">&#41;</span>:<br />
&nbsp; &nbsp; <span style="color: #808080; font-style: italic;"># в таблице списка постов выводить только колонку title, если вы добавите еще одно имя поля, то и оно выведется</span><br />
&nbsp; &nbsp; list_display <span style="color: #66cc66;">=</span> <span style="color: black;">&#40;</span><span style="color: #483d8b;">'title'</span><span style="color: #66cc66;">,</span><span style="color: black;">&#41;</span><br />
<br />
<span style="color: #808080; font-style: italic;"># связываем эту модель с моделью PostAdmin</span><br />
admin.<span style="color: #dc143c;">site</span>.<span style="color: black;">register</span><span style="color: black;">&#40;</span>Post<span style="color: #66cc66;">,</span> PostAdmin<span style="color: black;">&#41;</span></div></div>
<blockquote class="info">
<p>Вы можете все что связано с админкой вынести в <strong>admins.py</strong> и импортировать его, чтобы избавится от лишнего кода</p>
</blockquote>
<p>После создания файла моделей, вам необходимо запустить синхронизацию с БД, для того чтобы создались структуры данных:</p>
<div class="codecolorer-container bash default" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:650px;"><div class="bash codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color: #7a0874; font-weight: bold;">cd</span> <span style="color: #000000; font-weight: bold;">/</span>www<span style="color: #000000; font-weight: bold;">/</span>myproject<br />
python manage.py syncdb</div></div>
<blockquote class="info">
<p>
Для более детального изучения команд manage.py введите:</p>
<div class="codecolorer-container bash default" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:650px;"><div class="bash codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap">python manage.py <span style="color: #7a0874; font-weight: bold;">help</span></div></div>
<p>Если вас интересует конкретная комманда, например syncdb, то:</p>
<div class="codecolorer-container bash default" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:650px;"><div class="bash codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap">python manage.py <span style="color: #7a0874; font-weight: bold;">help</span> syncdb</div></div>
<p>Вы так же можете создавать свои команды, но об этом поговорим не в этот раз.
</p>
</blockquote>
<p><strong>syncdb</strong> создаст таблицы в вашей БД, а также при первой инициализации попросит <em>создать</em> рутовую учетную запись для вашего проекта в django (это будет админский аккаунт):</p>
<div class="codecolorer-container text default" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:650px;"><div class="text codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap">Creating table auth_permission<br />
Creating table auth_group_permissions<br />
Creating table auth_group<br />
Creating table auth_user_user_permissions<br />
Creating table auth_user_groups<br />
Creating table auth_user<br />
Creating table auth_message<br />
Creating table django_content_type<br />
Creating table django_session<br />
Creating table django_site<br />
Creating table django_admin_log<br />
Creating table blog_post<br />
<br />
You just installed Django's auth system, which means you don't have any superusers defined.<br />
Would you like to create one now? (yes/no): yes<br />
Username (Leave blank to use 'root'): <br />
E-mail address: mail@example.com<br />
Password: <br />
Password (again): <br />
Superuser created successfully.<br />
Installing index for auth.Permission model<br />
Installing index for auth.Message model<br />
Installing index for admin.LogEntry model</div></div>
<p>Когда вы создадите новый класс модели вам будет необходимо вновь запустить syncdb.<br />
Если вы внесли изменения в уже синхронизированное приложение, а именно в его модель, то syncdb НЕ внесет их в вашу БД, для этого используйте sqlall и другие sql* комманды:</p>
<div class="codecolorer-container bash default" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:650px;"><div class="bash codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap">python manage.py sqlall название_приложения <span style="color: #7a0874; font-weight: bold;">&#40;</span>например: blog<span style="color: #7a0874; font-weight: bold;">&#41;</span></div></div>
<p>Или попробуйте расширение для Django <noindex><a rel="nofollow" href="http://code.google.com/p/django-evolution/" >Django Evolution</a></noindex> (для этого необходимо его установить в вашу систему и добавить в INSTALLED_APPS&nbsp;&mdash; &laquo;django_evolution&raquo;).</p>
<h4>Файл урлов</h4>
<p>Для навигации по вашему проекту вам нужен роутер (URL диспетчер).<br />
Отредактируем &laquo;/www/myproject/urls.py&raquo;:</p>
<div class="codecolorer-container python default" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:650px;"><div class="python codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color: #808080; font-style: italic;"># ~*~ coding: utf-8 ~*~</span><br />
<br />
<span style="color: #808080; font-style: italic;"># импортируем админку</span><br />
<span style="color: #ff7700;font-weight:bold;">from</span> django.<span style="color: black;">contrib</span> <span style="color: #ff7700;font-weight:bold;">import</span> admin<br />
<br />
<span style="color: #808080; font-style: italic;"># Makes the patterns() function available</span><br />
<span style="color: #ff7700;font-weight:bold;">from</span> django.<span style="color: black;">conf</span>.<span style="color: black;">urls</span>.<span style="color: black;">defaults</span> <span style="color: #ff7700;font-weight:bold;">import</span> *<br />
<br />
<span style="color: #808080; font-style: italic;"># импортируем наши вьюхи (см. ниже описание файла вьюх)</span><br />
<span style="color: #ff7700;font-weight:bold;">from</span> myproject.<span style="color: black;">blog</span>.<span style="color: black;">views</span> <span style="color: #ff7700;font-weight:bold;">import</span> main_page<span style="color: #66cc66;">,</span> get_post<br />
<br />
<span style="color: #808080; font-style: italic;"># Above we used admin.autodiscover() to automatically load the INSTALLED_APPS admin.py modules</span><br />
admin.<span style="color: black;">autodiscover</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span><br />
<br />
urlpatterns <span style="color: #66cc66;">=</span> patterns<span style="color: black;">&#40;</span><span style="color: #483d8b;">''</span><span style="color: #66cc66;">,</span><br />
&nbsp; &nbsp; <span style="color: #808080; font-style: italic;"># Если ничего не введено, то отдаем управление mainpage вьюхе</span><br />
&nbsp; &nbsp; <span style="color: black;">&#40;</span>r<span style="color: #483d8b;">'^$'</span><span style="color: #66cc66;">,</span> main_page<span style="color: black;">&#41;</span><span style="color: #66cc66;">,</span><br />
&nbsp; &nbsp; <span style="color: #808080; font-style: italic;"># Если передан id поста, то отдаем управление get_post вьюхе</span><br />
&nbsp; &nbsp; <span style="color: black;">&#40;</span>r<span style="color: #483d8b;">'^post/([0-9]{1,5})'</span><span style="color: #66cc66;">,</span> get_post<span style="color: black;">&#41;</span><span style="color: #66cc66;">,</span><br />
&nbsp; &nbsp; <span style="color: #808080; font-style: italic;"># Если введен /admin/, то идем в админку</span><br />
&nbsp; &nbsp; <span style="color: black;">&#40;</span>r<span style="color: #483d8b;">'^admin/'</span><span style="color: #66cc66;">,</span> include<span style="color: black;">&#40;</span>admin.<span style="color: #dc143c;">site</span>.<span style="color: black;">urls</span><span style="color: black;">&#41;</span><span style="color: black;">&#41;</span><span style="color: #66cc66;">,</span><br />
<span style="color: black;">&#41;</span></div></div>
<p>Вы конечно можете отредактировать локальный для приложения &laquo;blog&raquo;&nbsp;&mdash; urls.py (&laquo;/www/myproject/blog/urls.py&raquo;), но тогда вам надо будет импортировать &laquo;/www/myproject/blog/urls.py&raquo; в корневом &laquo;urls.py&raquo;. Либо вы можете его определить в settings.py (ROOT_URLCONF).</p>
<h4>Файл вьюхи</h4>
<p>Ту роль, которую играет &laquo;Controller&raquo; в MVC, в Django играет роль View. Почему это так читайте <noindex><a rel="nofollow" href="http://docs.djangoproject.com/en/dev/faq/general/#django-appears-to-be-a-mvc-framework-but-you-call-the-controller-the-view-and-the-view-the-template-how-come-you-don-t-use-the-standard-names" >тут</a></noindex>.<br />
Отредактируем &laquo;/www/myproject/blog/views.py&raquo;:</p>
<div class="codecolorer-container python default" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:650px;"><div class="python codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color: #808080; font-style: italic;"># ~*~ coding: utf-8 ~*~</span><br />
<br />
<span style="color: #808080; font-style: italic;"># функция генерирующая 404 страницу</span><br />
<span style="color: #ff7700;font-weight:bold;">from</span> django.<span style="color: black;">http</span> <span style="color: #ff7700;font-weight:bold;">import</span> Http404<br />
<br />
<span style="color: #808080; font-style: italic;"># функция отрисовки страницы, принимающая путь до шаблона и данные помещенные в шаблон</span><br />
<span style="color: #ff7700;font-weight:bold;">from</span> django.<span style="color: black;">shortcuts</span> <span style="color: #ff7700;font-weight:bold;">import</span> render_to_response<br />
<br />
<span style="color: #808080; font-style: italic;"># наша модель</span><br />
<span style="color: #ff7700;font-weight:bold;">from</span> myproject.<span style="color: black;">blog</span>.<span style="color: black;">models</span> <span style="color: #ff7700;font-weight:bold;">import</span> Post<br />
<br />
<span style="color: #ff7700;font-weight:bold;">def</span> main_page <span style="color: black;">&#40;</span>request<span style="color: black;">&#41;</span>:<br />
&nbsp; &nbsp; <span style="color: #808080; font-style: italic;"># Получаем список постов</span><br />
&nbsp; &nbsp; posts <span style="color: #66cc66;">=</span> Post.<span style="color: black;">objects</span>.<span style="color: #008000;">all</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span><br />
&nbsp; &nbsp; <span style="color: #808080; font-style: italic;"># отрисовываем</span><br />
&nbsp; &nbsp; <span style="color: #ff7700;font-weight:bold;">return</span> render_to_response<span style="color: black;">&#40;</span><span style="color: #483d8b;">'list.html'</span><span style="color: #66cc66;">,</span> <span style="color: black;">&#123;</span><span style="color: #483d8b;">&quot;posts&quot;</span>: &nbsp;posts<span style="color: black;">&#125;</span><span style="color: black;">&#41;</span><br />
<br />
<span style="color: #ff7700;font-weight:bold;">def</span> get_post <span style="color: black;">&#40;</span>request<span style="color: #66cc66;">,</span> post_id<span style="color: black;">&#41;</span>:<br />
&nbsp; &nbsp; <span style="color: #ff7700;font-weight:bold;">try</span>:<br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #808080; font-style: italic;"># выбираем конкретный пост, pk - primary key</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; post <span style="color: #66cc66;">=</span> Post.<span style="color: black;">objects</span>.<span style="color: black;">get</span><span style="color: black;">&#40;</span>pk<span style="color: #66cc66;">=</span>post_id<span style="color: black;">&#41;</span><br />
&nbsp; &nbsp; <span style="color: #ff7700;font-weight:bold;">except</span> Post.<span style="color: black;">DoesNotExist</span>:<br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #808080; font-style: italic;"># если такого поста нет, то генерируем 404</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #ff7700;font-weight:bold;">raise</span> Http404<br />
<br />
&nbsp; &nbsp; <span style="color: #808080; font-style: italic;"># отрисовываем</span><br />
&nbsp; &nbsp; <span style="color: #ff7700;font-weight:bold;">return</span> render_to_response<span style="color: black;">&#40;</span><span style="color: #483d8b;">'single.html'</span><span style="color: #66cc66;">,</span> <span style="color: black;">&#123;</span><span style="color: #483d8b;">&quot;title&quot;</span>: &nbsp;post.<span style="color: black;">title</span><span style="color: #66cc66;">,</span> <span style="color: #483d8b;">&quot;text&quot;</span>: post.<span style="color: black;">text</span><span style="color: black;">&#125;</span><span style="color: black;">&#41;</span></div></div>
<h3>Вывод в шаблоне</h3>
<p>В Django очень мощный и гибкий шаблонизатор, у него даже есть аналог на PHP&nbsp;&mdash; <strong>Twig</strong>, что говорит о его удобстве (был бы неудобным&nbsp;&mdash; не копировали бы), хотя <strong>Twig</strong> по слухам сильно хуже.<br />
Однако, есть более крутой шаблонизатор для Django&nbsp;&mdash; <noindex><a rel="nofollow" href="http://jinja.pocoo.org/2/" >Jinja2</a></noindex>, с более высокой производительностью и более гибкими возможностями. Описывать <strong>Jinja</strong> я не буду, ведь не это цель сего поста, поэтому делюсь только ссылочками:</p>
<ul>
<li><noindex><a rel="nofollow" href="http://vostryakov.ru/blog/13-perehod-ot-django-templejtovk-jinja2/" >Переход от Django темплэйтов к Jinja2</a></noindex></li>
<li><noindex><a rel="nofollow" href="http://docs.djangoproject.com/en/dev/ref/templates/api/#using-an-alternative-template-language" >Django: Using an alternative template language</a></noindex></li>
</ul>
<p>С более полными возможностями <strong>Django Template</strong> вы можете познакомится на <noindex><a rel="nofollow" href="http://docs.djangoproject.com/en/dev/topics/templates/" >официальной странице</a></noindex>.</p>
<p>В <strong>Django Template</strong> поддерживается наследование, поэтому мы напишем общий шаблон и будем его использовать <strong>base.html</strong>:</p>
<div class="codecolorer-container html4strict default" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:650px;"><div class="html4strict codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color: #00bbdd;">&lt;!DOCTYPE html PUBLIC &quot;-//W3C//DTD XHTML 1.0 Strict//EN&quot; &quot;http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd&quot;&gt;</span><br />
<span style="color: #009900;">&lt;<span style="color: #000000; font-weight: bold;">html</span> xmlns<span style="color: #66cc66;">=</span><span style="color: #ff0000;">&quot;http://www.w3.org/1999/xhtml&quot;</span>&gt;</span><br />
<span style="color: #009900;">&lt;<span style="color: #000000; font-weight: bold;">head</span>&gt;</span><br />
&nbsp; &nbsp; <span style="color: #009900;">&lt;<span style="color: #000000; font-weight: bold;">meta</span> <span style="color: #000066;">http-equiv</span><span style="color: #66cc66;">=</span><span style="color: #ff0000;">&quot;content-type&quot;</span> <span style="color: #000066;">content</span><span style="color: #66cc66;">=</span><span style="color: #ff0000;">&quot;text/html; charset=utf-8&quot;</span> <span style="color: #66cc66;">/</span>&gt;</span><br />
&nbsp; &nbsp; <span style="color: #009900;">&lt;<span style="color: #000000; font-weight: bold;">title</span>&gt;</span>{% block title %}Default{% endblock %} / MyProject<span style="color: #009900;">&lt;<span style="color: #66cc66;">/</span><span style="color: #000000; font-weight: bold;">title</span>&gt;</span><br />
<span style="color: #009900;">&lt;<span style="color: #66cc66;">/</span><span style="color: #000000; font-weight: bold;">head</span>&gt;</span><br />
<span style="color: #009900;">&lt;<span style="color: #000000; font-weight: bold;">body</span>&gt;</span><br />
&nbsp; &nbsp; {% block content %}<br />
&nbsp; &nbsp; {% endblock %}<br />
<span style="color: #009900;">&lt;<span style="color: #66cc66;">/</span><span style="color: #000000; font-weight: bold;">body</span>&gt;</span><br />
<span style="color: #009900;">&lt;<span style="color: #66cc66;">/</span><span style="color: #000000; font-weight: bold;">html</span>&gt;</span></div></div>
<p>Шаблон вывода списка постов <strong>list.html</strong>:</p>
<div class="codecolorer-container html4strict default" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:650px;"><div class="html4strict codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap">{% extends &quot;base.html&quot; %}<br />
<br />
{% block title %}List!{% endblock %}<br />
<br />
{% block content %}<br />
<span style="color: #009900;">&lt;<span style="color: #000000; font-weight: bold;">ul</span> <span style="color: #000066;">style</span><span style="color: #66cc66;">=</span><span style="color: #ff0000;">&quot;list-style-type:none&quot;</span>&gt;</span><br />
{% for post in posts %}<br />
<span style="color: #009900;">&lt;<span style="color: #000000; font-weight: bold;">li</span> <span style="color: #000066;">style</span><span style="color: #66cc66;">=</span><span style="color: #ff0000;">&quot;padding-left:10px;{% if forloop.counter0|divisibleby:&quot;</span><span style="color: #cc66cc;">4</span><span style="color: #ff0000;">&quot; %}background-color:#E1F3C9{% endif %}&quot;</span>&gt;</span><br />
&nbsp; &nbsp; <span style="color: #009900;">&lt;<span style="color: #000000; font-weight: bold;">a</span> <span style="color: #000066;">href</span><span style="color: #66cc66;">=</span><span style="color: #ff0000;">&quot;/post/{{ post.id }}/&quot;</span>&gt;</span>{{ post.title }}<span style="color: #009900;">&lt;<span style="color: #66cc66;">/</span><span style="color: #000000; font-weight: bold;">a</span>&gt;</span><br />
&nbsp; &nbsp; <span style="color: #009900;">&lt;<span style="color: #000000; font-weight: bold;">p</span>&gt;</span>{{ post.text }}<span style="color: #009900;">&lt;<span style="color: #66cc66;">/</span><span style="color: #000000; font-weight: bold;">p</span>&gt;</span><br />
<span style="color: #009900;">&lt;<span style="color: #66cc66;">/</span><span style="color: #000000; font-weight: bold;">li</span>&gt;</span><br />
{% endfor %}<br />
<span style="color: #009900;">&lt;<span style="color: #66cc66;">/</span><span style="color: #000000; font-weight: bold;">ul</span>&gt;</span><br />
<span style="color: #009900;">&lt;<span style="color: #66cc66;">/</span><span style="color: #000000; font-weight: bold;">div</span>&gt;</span><br />
{% endblock %}</div></div>
<p>Шаблон вывода одной записи <strong>single.html</strong>:</p>
<div class="codecolorer-container html4strict default" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:650px;"><div class="html4strict codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap">{% extends &quot;base.html&quot; %}<br />
<br />
{% block title %}{{ title }}{% endblock %}<br />
<br />
{% block content %}<br />
<span style="color: #009900;">&lt;<span style="color: #000000; font-weight: bold;">h1</span>&gt;</span>{{ title }}<span style="color: #009900;">&lt;<span style="color: #66cc66;">/</span><span style="color: #000000; font-weight: bold;">h1</span>&gt;</span><br />
<br />
<span style="color: #009900;">&lt;<span style="color: #000000; font-weight: bold;">div</span>&gt;</span><br />
{{ text }}<br />
<span style="color: #009900;">&lt;<span style="color: #66cc66;">/</span><span style="color: #000000; font-weight: bold;">div</span>&gt;</span><br />
{% endblock %}</div></div>
<h3>Nginx</h3>
<p>Теперь настроим Nginx для того, чтобы запуская &laquo;manage.py runserver&raquo; нам не прописывать порт в URL и чтобы использовать нормальное имя хоста, хотя вы может вполне без это обойтись.<br />
Но я очень рекомендую использовать Nginx.</p>
<div class="codecolorer-container text default" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:650px;"><div class="text codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap">server {<br />
&nbsp; &nbsp; listen 80;<br />
&nbsp; &nbsp; server_name myproject.loc;<br />
<br />
&nbsp; &nbsp; location ^~ /admin-media {<br />
&nbsp; &nbsp; &nbsp; &nbsp; alias /usr/local/lib/python2.6/dist-packages/django/contrib/admin/media;<br />
&nbsp; &nbsp; }<br />
<br />
&nbsp; &nbsp; location /static/ {<br />
&nbsp; &nbsp; &nbsp; &nbsp; root /www/myproject/static/;<br />
&nbsp; &nbsp; }<br />
<br />
&nbsp; &nbsp; location ~* \.(jpg|jpeg|gif|png|ico|css|zip|js|swf)$ {<br />
&nbsp; &nbsp; &nbsp; &nbsp; root /www/myproject/static/;<br />
&nbsp; &nbsp; &nbsp; &nbsp; expires 7d;<br />
&nbsp; &nbsp; }<br />
<br />
&nbsp; &nbsp; location / {<br />
&nbsp; &nbsp; &nbsp; &nbsp; proxy_pass http://127.0.0.1:8001/;<br />
&nbsp; &nbsp; &nbsp; &nbsp; proxy_redirect off;<br />
&nbsp; &nbsp; &nbsp; &nbsp; proxy_set_header Host $host;<br />
&nbsp; &nbsp; &nbsp; &nbsp; proxy_set_header X-Real-IP $remote_addr;<br />
&nbsp; &nbsp; &nbsp; &nbsp; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;<br />
&nbsp; &nbsp; }<br />
}</div></div>
<p>Добавить в &laquo;/etc/hosts&raquo; ваш хост:</p>
<div class="codecolorer-container text default" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:650px;"><div class="text codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap">127.0.0.1 &nbsp; &nbsp; &nbsp;myproject.loc</div></div>
<p>И перезагрузить Nginx:</p>
<div class="codecolorer-container bash default" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:650px;"><div class="bash codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color: #666666; font-style: italic;"># в новых версиях nginx можно послать сигнал</span><br />
nginx <span style="color: #660033;">-s</span> reload<br />
<br />
<span style="color: #666666; font-style: italic;"># или для ubuntu/debian через скрипт инициализации</span><br />
service nginx restart<br />
<span style="color: #000000; font-weight: bold;">/</span>etc<span style="color: #000000; font-weight: bold;">/</span>init.d<span style="color: #000000; font-weight: bold;">/</span>nginx restart<br />
<br />
<span style="color: #666666; font-style: italic;"># или для freebsd</span><br />
<span style="color: #000000; font-weight: bold;">/</span>usr<span style="color: #000000; font-weight: bold;">/</span>local<span style="color: #000000; font-weight: bold;">/</span>etc<span style="color: #000000; font-weight: bold;">/</span>rc.d<span style="color: #000000; font-weight: bold;">/</span>nginx restart</div></div>
<p>Запускаем веб-сервер проекта на 8001 порту, так как мы туда будем проксировать из Nginx:</p>
<div class="codecolorer-container bash default" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:650px;"><div class="bash codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color: #7a0874; font-weight: bold;">cd</span> <span style="color: #000000; font-weight: bold;">/</span>www<span style="color: #000000; font-weight: bold;">/</span>myproject<br />
python manage.py runserver <span style="color: #000000;">8001</span></div></div>
<p>Теперь зайдите в админку (<noindex><a rel="nofollow" href="http://myproject.loc/admin/" >http://myproject.loc/admin/</a></noindex>), введите вашу &laquo;root&raquo; учетку, которую создавали при syncdb.</p>
<blockquote class="download">
<p>Вы можете скачать архив с исходниками проекта <a href="/files/django-myproject/myproject-20100526.tgz">тут</a></p>
</blockquote>
<p>Вот мы и познакомились с первым приложение на Django, как я и обещал в начале этого поста следующая статья будет о <strong>ManyToMany</strong>, где мы подключим к нашему &laquo;Блогу&raquo; возможность создавать и выводить теги, а также расскажу более полно о возможностях моделях и ORM, View и о URL диспетере.</p>
<p>P.S. Пост дописывал в торопях, если найдете любые ошибки&nbsp;&mdash; обязательно отпишитесь в комментарии, спасибо!</p>
]]></content:encoded>
			<wfw:commentRss>http://adw0rd.ru/2010/django-first-app/feed/</wfw:commentRss>
		<slash:comments>23</slash:comments>
		</item>
	</channel>
</rss>

