<?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>goodguy о разработке &#187; Языки</title>
	<atom:link href="http://dev.good-guy.me/archives/category/languages/feed" rel="self" type="application/rss+xml" />
	<link>http://dev.good-guy.me</link>
	<description>python, zope, php, sqlite, postgresql, mysql и прочее с чем сталкиваюсь</description>
	<lastBuildDate>Thu, 08 Jul 2010 09:17:47 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.0.1</generator>
		<item>
		<title>Настройка админской панели в django</title>
		<link>http://dev.good-guy.me/archives/419</link>
		<comments>http://dev.good-guy.me/archives/419#comments</comments>
		<pubDate>Thu, 08 Jul 2010 09:17:47 +0000</pubDate>
		<dc:creator>goodguy</dc:creator>
				<category><![CDATA[Open Source]]></category>
		<category><![CDATA[Языки]]></category>
		<category><![CDATA[django]]></category>
		<category><![CDATA[python]]></category>

		<guid isPermaLink="false">http://dev.good-guy.me/?p=419</guid>
		<description><![CDATA[Интересная заметка на habrahabr про то как минимальными усилиями сделать из обычной админской панели django красивый и удобный интерфейс.]]></description>
			<content:encoded><![CDATA[<p>
Интересная заметка на habrahabr про то как минимальными усилиями <a href="http://habrahabr.ru/blogs/django/98539/">сделать из обычной админской панели django красивый и удобный интерфейс</a>.</p>
]]></content:encoded>
			<wfw:commentRss>http://dev.good-guy.me/archives/419/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Do it satchmo way</title>
		<link>http://dev.good-guy.me/archives/413</link>
		<comments>http://dev.good-guy.me/archives/413#comments</comments>
		<pubDate>Wed, 07 Jul 2010 17:53:22 +0000</pubDate>
		<dc:creator>goodguy</dc:creator>
				<category><![CDATA[Open Source]]></category>
		<category><![CDATA[ПО]]></category>
		<category><![CDATA[Языки]]></category>
		<category><![CDATA[django]]></category>
		<category><![CDATA[python]]></category>
		<category><![CDATA[satchmo]]></category>
		<category><![CDATA[велосипед]]></category>

		<guid isPermaLink="false">http://dev.good-guy.me/?p=413</guid>
		<description><![CDATA[Недавно потребовалось быстро развернуть более-менее универсальный магазин для нашего нового проекта торговли велотоварами. PHP-системы мне как-то не нравились и из симпатии к python начал было писать проект на django, но вскоре понял, что скорее всего получается велосипед, и начал искать что-то готовое. Оно пришло в виде Satchmo, весьма универсального и накручиваемого решения для электронной торговли. [...]]]></description>
			<content:encoded><![CDATA[<p>Недавно потребовалось быстро развернуть более-менее универсальный магазин для нашего нового <a href="http://fysika.ru">проекта торговли велотоварами</a>. PHP-системы мне как-то не нравились и из симпатии к <a href="http://python.org">python</a> начал было писать проект на <a href="http://djangoproject.com">django</a>, но вскоре понял, что скорее всего получается велосипед, и начал искать что-то готовое. Оно пришло в виде <a href="http://www.satchmoproject.com/">Satchmo</a>, весьма универсального и накручиваемого решения для электронной торговли. Что понравилось &#8211; немало настроек, в которых поначалу можно запутаться. Есть тонкости в адаптации под себя, но они описаны в документации (один отсутствующий момент &#8211; это как обновлять sitemaps, пришлось додумывать и доделывать самома). Но главное, магазин развернулся из коробки и через пару часов в нём уже можно было добавлять товары. А вот допиливания мелочей происходят уже по ходу, и зачастую незаметно для посетителей <img src='http://dev.good-guy.me/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> </p>
]]></content:encoded>
			<wfw:commentRss>http://dev.good-guy.me/archives/413/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Антивелосипед</title>
		<link>http://dev.good-guy.me/archives/402</link>
		<comments>http://dev.good-guy.me/archives/402#comments</comments>
		<pubDate>Mon, 28 Jun 2010 09:43:18 +0000</pubDate>
		<dc:creator>goodguy</dc:creator>
				<category><![CDATA[Языки]]></category>
		<category><![CDATA[python]]></category>

		<guid isPermaLink="false">http://dev.good-guy.me/?p=402</guid>
		<description><![CDATA[Python опять обрадовал меня наличием готовых модулей для всего и вся. На этот раз повезло быстро разобраться с чтением конфигурации из XML файла &#8211; для этого идеально подошёл модуль xmlobjects и простая конструкция вида: import xmlobjects import psycopg2 xml = """ user password dbname """ conf = xmlobjects.fromstring(xml) conn = psycopg2.connect('dbname=%s user=%s password=%s' % ( [...]]]></description>
			<content:encoded><![CDATA[<p style="text-align: justify"><a href="http://python.org">Python</a> опять обрадовал меня наличием готовых модулей для всего и вся. На этот раз повезло быстро разобраться с чтением конфигурации из XML файла &#8211; для этого идеально подошёл модуль <a href="http://pypi.python.org/pypi/xmlobjects/">xmlobjects</a> и простая конструкция вида:
</p>
<pre name="code" class="python">
import xmlobjects
import psycopg2

xml = """<settings>
<db>
   <user>user</user>
<password>password</password>
   <dbname>dbname</dbname>
</db>
</settings>"""

conf = xmlobjects.fromstring(xml)
conn = psycopg2.connect('dbname=%s user=%s password=%s' % (
    conf.db.dbname, conf.db.user, conf.db.password))
</pre>
]]></content:encoded>
			<wfw:commentRss>http://dev.good-guy.me/archives/402/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Отлов ошибок PECL класса HTTPRequest</title>
		<link>http://dev.good-guy.me/archives/377</link>
		<comments>http://dev.good-guy.me/archives/377#comments</comments>
		<pubDate>Wed, 30 Sep 2009 06:35:34 +0000</pubDate>
		<dc:creator>goodguy</dc:creator>
				<category><![CDATA[Языки]]></category>
		<category><![CDATA[php]]></category>

		<guid isPermaLink="false">http://dev.goodguy.spb.ru/?p=377</guid>
		<description><![CDATA[В модуле pecl_http есть очень удобный, но при этом не всегда хорошо задокументированный класс HTTPRequest. Одной из проблем, с которой я столкнулся при работе с ним, это то, что в случае ошибок при HTTP-соединениях, выбрасывались исключения с текстами: (HttpInvalidParamException) Empty or too short HTTP message: '' Понятное дело, для отладки они не подходят. Но, если [...]]]></description>
			<content:encoded><![CDATA[<p style="text-align: justify">В модуле <tt>pecl_http</tt> есть очень удобный, но при этом не всегда хорошо задокументированный класс <tt>HTTPRequest</tt>. Одной из проблем, с которой я столкнулся при работе с ним, это то, что в случае ошибок при HTTP-соединениях, выбрасывались исключения с текстами:</p>
<p><code><br />
(HttpInvalidParamException) Empty or too short HTTP message: ''<br />
</code></p>
<p style="text-align: justify">Понятное дело, для отладки они не подходят. Но, если вывести исключение полностью, то обычно там как-раз и были подробности проблемы:</p>
<p><code><br />
exception 'HttpInvalidParamException' with message 'Empty or too short HTTP message: ''' in example.php:189 inner exception 'HttpRequestException' with message 'Timeout was reached; Operation timed out after 10000 milliseconds with 0 bytes received (https://example.ru/)' in example.php:160<br />
</code></p>
<p style="text-align: justify">Видно, что самое важное содержится в сообщении от inner exception. И его, оказывается, легко поймать, если поставить дополнительный блок <tt>catch</tt> на <tt>HTTPException</tt>, например:</p>
<pre name="code" class="php">
try {
    $request->send();
} catch (HttpException $ex) {
    if (isset($ex->innerException)){
        echo $ex->innerException->getMessage();
        exit;
    } else {
        echo $ex;
        exit;
    }
}
</pre>
<p style="text-align: justify">Информация получена <a href="http://www.markfosteronline.com/2009/01/06/how-to-pecl-http-request-exception-and-error-handling/">отсюда</a>.</p>
]]></content:encoded>
			<wfw:commentRss>http://dev.good-guy.me/archives/377/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>PHP и SOAP Message Security</title>
		<link>http://dev.good-guy.me/archives/356</link>
		<comments>http://dev.good-guy.me/archives/356#comments</comments>
		<pubDate>Wed, 29 Apr 2009 15:44:29 +0000</pubDate>
		<dc:creator>goodguy</dc:creator>
				<category><![CDATA[Языки]]></category>
		<category><![CDATA[php]]></category>
		<category><![CDATA[SOAP]]></category>
		<category><![CDATA[безопасность]]></category>

		<guid isPermaLink="false">http://dev.goodguy.spb.ru/?p=356</guid>
		<description><![CDATA[Очередной случай из жизни натолкнул меня на мысль расписать, как из PHP создать подписанный по стандарту SOAP Message Security SOAP-запрос по SSL-соединению. Насколько я понимаю, стандарт этот не единственный, но используется достаточно широко и базируется на различных XML-стандартах W3C. Сама суть механизма подписи хорошо описана в этой статье, из которой и я почерпнул для себя [...]]]></description>
			<content:encoded><![CDATA[<p style="text-align: justify">Очередной случай из жизни натолкнул меня на мысль расписать, как из PHP создать подписанный по стандарту <a href="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-soap-message-security-1.0.pdf">SOAP Message Security</a> SOAP-запрос по SSL-соединению. Насколько я понимаю, стандарт этот не единственный, но используется достаточно широко и базируется на различных XML-стандартах W3C.
<p style="text-align: justify">Сама суть механизма подписи хорошо описана в <a href="http://xmlhack.ru/texts/03/wssecurity/wssecurity.html">этой статье</a>, из которой и я почерпнул для себя несколько полезных моментов, на которых возник ступор поначалу. Но предлагаемый мной вариант имеет одно важное дополнение: он добавляет в SOAP-сообщение ещё и информацию о сертификате, с помощью которого была сделана подпись. Кстати, меня удивила логика одной системы, для которой это делалось (кстати, написанной на Microsoft&#8217;овских компонентах): помимо сертификата в SSL-соединении они ещё проверяли сертификат и в самом запросе, хотя могли бы и воспользоваться данными HTTPS и тем самым получить ещё дополнительную проверку того, что соединение открыто тем самым агентом, который подписывал запрос.</p>
<p style="text-align: justify">Основным моментом в подписи является то, что собираются хэши (дайджесты) узлов с данными, которые будут подписаны (при этом узлы приводятся в <a href="http://www.w3.org/TR/2002/REC-xml-exc-c14n-20020718/">канонический вид</a> с помощью утилиты <tt>xmllint</tt> из комплекта <tt>libxml2</tt>). После чего собранные внутри одной «обёртки» дайджесты подписываются ключом сертификата, тем самым гарантируя, что если подпись верна, то данные в этих узлах не были изменены во время передачи запроса.</p>
<p style="text-align: justify">Класс так-же переписывает механизм HTTP-запроса к удалённому серверу, т.к. даже с помощью <tt>stream_context</tt> PHP не позволяет использовать совместно с SOAP сертификаты в формате PKCS12. В итоге используется <tt>HTTPRequest</tt>, результат которого уже транслируется далее в обработку.</p>
<ul>
<li> Собственно сам класс: <a href='http://dev.goodguy.spb.ru/wp-content/uploads/2009/04/signedsoapclient.zip'>SignedSoapClient.zip</a></li>
</ul>
]]></content:encoded>
			<wfw:commentRss>http://dev.good-guy.me/archives/356/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Сколько же записей обновилось?</title>
		<link>http://dev.good-guy.me/archives/349</link>
		<comments>http://dev.good-guy.me/archives/349#comments</comments>
		<pubDate>Mon, 30 Mar 2009 12:43:48 +0000</pubDate>
		<dc:creator>goodguy</dc:creator>
				<category><![CDATA[Базы данных]]></category>
		<category><![CDATA[Языки]]></category>
		<category><![CDATA[mysql]]></category>
		<category><![CDATA[php]]></category>

		<guid isPermaLink="false">http://dev.goodguy.spb.ru/?p=349</guid>
		<description><![CDATA[Вроде бы простой вопрос, сколько рядов было затронуто SQL-операцией UPDATE, но и здесь притаился подводный камень (о котором, правда честно предупреждают в документации). В MySQL в это число могут не попадать записи, у которых данные не потребовалось изменять. А значит, если REPLACE не подходит, то нужно проводить дополнительные проверки на тему того, сколько же данных [...]]]></description>
			<content:encoded><![CDATA[<p style="text-align: justify">Вроде бы простой вопрос, сколько рядов было затронуто SQL-операцией <tt>UPDATE</tt>, но и здесь притаился подводный камень (о котором, правда честно предупреждают в документации). В MySQL в это число могут не попадать записи, у которых данные не потребовалось изменять. А значит, если <tt>REPLACE</tt> не подходит, то нужно проводить дополнительные проверки на тему того, сколько же данных вы обновили. Я споткнулся об этом в функции <tt><a href="http://ru2.php.net/manual/en/function.mysql-affected-rows.php">mysql_affected_rows</a></tt> в PHP. Там-же можно найти один из вариантов решения &#8211; использовать <tt><a href="http://ru2.php.net/manual/en/function.mysql-info.php">mysql_info</a></tt>, но в этом случае нужно парсить строку с ответом. Ну а дальше в вариантах <tt>SELECT</tt>&#8216;ы и т.п.</p>
]]></content:encoded>
			<wfw:commentRss>http://dev.good-guy.me/archives/349/feed</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Мощь python и лень</title>
		<link>http://dev.good-guy.me/archives/26</link>
		<comments>http://dev.good-guy.me/archives/26#comments</comments>
		<pubDate>Wed, 30 Jul 2008 06:15:45 +0000</pubDate>
		<dc:creator>goodguy</dc:creator>
				<category><![CDATA[Языки]]></category>
		<category><![CDATA[API]]></category>
		<category><![CDATA[livejournal]]></category>
		<category><![CDATA[python]]></category>
		<category><![CDATA[twisted]]></category>

		<guid isPermaLink="false">http://dev.goodguy.spb.ru/?p=26</guid>
		<description><![CDATA[Вот, что и требовалось доказать &#8211; стоило перестать лениться и откладывать «на потом», как за вечер бот из предыдущего поста научился понимать Atom (в необходимой мере) и постить в Blogger (благодаря чему обновляется ещё одно зеркало зеркало моего блога). А всё благодаря более-менее продуманной архитектуре, да удобству python и Twisted в качестве средства разработки. И [...]]]></description>
			<content:encoded><![CDATA[<p style="text-align: justify">Вот, что и требовалось доказать &#8211; стоило перестать лениться и откладывать «на потом», как за вечер бот из предыдущего поста научился понимать <a href="http://tools.ietf.org/html/rfc4287">Atom</a> (в необходимой мере) и постить в <a href="http://blogger.com">Blogger</a> (благодаря чему обновляется ещё одно зеркало <a href="http://goodguy-spb.blogspot.com/">зеркало моего блога</a>). А всё благодаря более-менее продуманной архитектуре, да удобству <a href="http://python.org">python</a> и <a href="http://www.twistedmatrix.com/">Twisted</a> в качестве средства разработки. И зачем люди ещё пишут на PHP сложные системы&#8230;
</p>
<p style="text-align: justify">Кстати, у Blogger&#8217;а выяснилась пара забавных моментов. Первый &#8211; это то, он строго следует спецификациям Atom при создании и редактировании сообщений. Но при этом, если отправлять ему содержимое поста с типом <tt>xhtml</tt>, завернутое в <tt>&lt;div xmlns=&quot;http://www.w3.org/1999/xhtml&quot;&gt;...&lt;/div&gt;</tt>, то назад он возвращает содержимое завёрнутое как <tt>html</tt>, но при этом сохраняет этот самый <tt>div</tt>. Логика загадочна для меня.
</p>
<p style="text-align: justify">Второй момент ещё более непонятный: по ходу тестирования я делал пачки постингов в блог. В какой-то момент получилось так, что пост проходит, возвращается назад с присвоенным id и т.п., а в блоге не появляется. Никаких намёков на то, почему так, нет. Буду пробовать дальше <img src='http://dev.good-guy.me/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' />
</p>
<p style="text-align: justify"><b>Дополнение:</b> всё оказалось очень просто. Из-за кучи постингов во время тестов blogger включил для моего аккаунта требование вводить captcha перед каждым постом. По сути можно было написать в блог только через веб-форму. Налицо явная недоработка API, так как ошибку внятную можно было и вернуть.</p>
]]></content:encoded>
			<wfw:commentRss>http://dev.good-guy.me/archives/26/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>
