<?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>treibsand.com &#187; Python</title>
	<atom:link href="http://www.treibsand.com/tag/python/feed/" rel="self" type="application/rss+xml" />
	<link>http://www.treibsand.com</link>
	<description></description>
	<lastBuildDate>Tue, 27 Dec 2011 12:46:03 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.3</generator>
		<item>
		<title>Ärger mit Generic Views von Django</title>
		<link>http://www.treibsand.com/2009/03/09/arger-mit-generic-views-von-django/</link>
		<comments>http://www.treibsand.com/2009/03/09/arger-mit-generic-views-von-django/#comments</comments>
		<pubDate>Mon, 09 Mar 2009 10:16:12 +0000</pubDate>
		<dc:creator>Toast</dc:creator>
				<category><![CDATA[Coding]]></category>
		<category><![CDATA[Django]]></category>
		<category><![CDATA[Generic Views]]></category>
		<category><![CDATA[Python]]></category>

		<guid isPermaLink="false">http://www.treibsand.com/?p=285</guid>
		<description><![CDATA[Django ist ja eines der besten Frameworks für Python um schnell Webanwendungen zu realisieren. Allerdings ist es leider noch nicht so ausgereift wie z.B. Ruby on Rails. Die Generic Views von Django sind zwar sehr hilfreich, allerdings nicht ganz konsequent umgesetzt. So gibt es bei den Views create\_object, update\_object und delete\_object die Möglichkeit login\_required zu [...]]]></description>
			<content:encoded><![CDATA[<p><a href="http://www.djangoproject.com">Django</a> ist ja eines der besten Frameworks für Python um schnell Webanwendungen zu realisieren. Allerdings ist es leider noch nicht so ausgereift wie z.B. Ruby on Rails. Die Generic Views von Django sind zwar sehr hilfreich, allerdings nicht ganz konsequent umgesetzt.</p>
<p><span id="more-285"></span><br />
So gibt es bei den Views <b>create\_object</b>, <b>update\_object</b> und <b>delete\_object</b> die Möglichkeit <b>login\_required</b> zu übergeben, aber bei anderen Views wie z.B. <b>direct\_to\_template</b> nicht. Das ist ziemlich ärgerlich, da es hier genauso Sinn machen würde.</p>
<p>Allerdings gibt es einen kleinen Workaround&#8230;</p>

<div class="wp_syntax"><div class="code"><pre class="python" style="font-family:monospace;"><span style="color: #ff7700;font-weight:bold;">from</span> django.<span style="color: black;">contrib</span>.<span style="color: black;">auth</span>.<span style="color: black;">decorators</span> <span style="color: #ff7700;font-weight:bold;">import</span> login_required 
<span style="color: #ff7700;font-weight:bold;">from</span> django.<span style="color: black;">views</span>.<span style="color: black;">generic</span>.<span style="color: black;">simple</span> <span style="color: #ff7700;font-weight:bold;">import</span> direct_to_template
&nbsp;
urlpatterns = patterns<span style="color: black;">&#40;</span><span style="color: #483d8b;">''</span>,
	<span style="color: black;">&#40;</span>r<span style="color: #483d8b;">'^meineurl/$'</span>,login_required<span style="color: black;">&#40;</span>direct_to_template<span style="color: black;">&#41;</span>,
		<span style="color: black;">&#123;</span><span style="color: #483d8b;">'template'</span>:<span style="color: #483d8b;">'welcome.html'</span><span style="color: black;">&#125;</span><span style="color: black;">&#41;</span>,
...</pre></div></div>

<p>Dadurch erhält man das gleiche Ergebnis, wie wenn man <b>login\_required</b> als Argument dem View übergibt.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.treibsand.com/2009/03/09/arger-mit-generic-views-von-django/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Brute Force Angriffe mit DenyHosts abwehren</title>
		<link>http://www.treibsand.com/2008/09/19/brute-force-angriffe-mit-denyhosts-abwehren/</link>
		<comments>http://www.treibsand.com/2008/09/19/brute-force-angriffe-mit-denyhosts-abwehren/#comments</comments>
		<pubDate>Fri, 19 Sep 2008 16:07:46 +0000</pubDate>
		<dc:creator>Toast</dc:creator>
				<category><![CDATA[Unix]]></category>
		<category><![CDATA[FreeBSD]]></category>
		<category><![CDATA[Python]]></category>
		<category><![CDATA[Sicherheit]]></category>
		<category><![CDATA[SSH]]></category>

		<guid isPermaLink="false">http://test.treibsand.com/?p=165</guid>
		<description><![CDATA[Viele Systemadministratoren kennen bestimmt das Problem, dass sehr viele Brute Force Angriffe gegen die eigenen Server laufen. Systematisch werden Logins mit den ueblichen Benutzernamen bzw. Passwörtern per SSH versucht. Genau hier hilft DenyHosts. Es handelt sich hierbei um einen kleinen Daemon, welcher permanent die Datei /var/auth.log liest und bei mehrmaligen fehlgeschlagenen Login Versuchen die IP [...]]]></description>
			<content:encoded><![CDATA[<p>Viele Systemadministratoren kennen bestimmt das Problem, dass sehr viele Brute Force Angriffe gegen die eigenen Server laufen. Systematisch werden Logins mit den ueblichen Benutzernamen bzw. Passwörtern per SSH versucht. </p>
<p><span id="more-165"></span><br />
Genau hier hilft DenyHosts. Es handelt sich hierbei um einen kleinen Daemon, welcher permanent die Datei /var/auth.log liest und bei mehrmaligen fehlgeschlagenen Login Versuchen die IP per /etc/hosts.allow blockt. Das Prinzip ist nicht neu, es gibt z.B. auch andere Tools, welche die gleiche Funktionalität z.B. per iptables lösen.</p>
<p>Das ist aber noch nicht alles, man kann den Daemon auch so einstellen, dass der die gefundenen IPs der globalen Datenbank von DenyHosts meldet. Im Gegenzug kann auch die Datenbank verwendet werden um die Hosts Datei zu füttern. Seit dem ich das Tool auf meinen Servern installiert habe, haben die Angriffe fast aufgehört bzw. es wurden fast alle sofort geblockt.</p>
<p>Die Konfiguration ist denkbar einfach. Nachdem die Software installiert ist, muss als erstes die Datei denyhosts.conf angepasst werden. Die Konfigurationsdatei ist ziemlich selbsterklärend. Danach kann auch schon der Daemon gestartet werden. Dank der Ports Collection von FreeBSD war das Startscript bereits vorhanden. Der Daemon schreibt seine Einträge dann üblicherweise in die Datei /etc/hosts.deniedssh, welche nur noch in die Datei /etc/hosts.allow eingebunden werden muss mit&#8230;</p>

<div class="wp_syntax"><div class="code"><pre class="bash" style="font-family:monospace;">sshd : <span style="color: #000000; font-weight: bold;">/</span>etc<span style="color: #000000; font-weight: bold;">/</span>hosts.deniedssh : deny  
sshd : ALL : allow</pre></div></div>

<p>Danach ist das komplette System fertig konfiguriert und das System blockt automatisch SSH Anfragen von IPs, welche in der Datenbank von DenyHosts gelistet sind. </p>
]]></content:encoded>
			<wfw:commentRss>http://www.treibsand.com/2008/09/19/brute-force-angriffe-mit-denyhosts-abwehren/feed/</wfw:commentRss>
		<slash:comments>4</slash:comments>
		</item>
		<item>
		<title>PETA Demonstranten attackieren Python Programmierer</title>
		<link>http://www.treibsand.com/2008/06/24/peta_python/</link>
		<comments>http://www.treibsand.com/2008/06/24/peta_python/#comments</comments>
		<pubDate>Tue, 24 Jun 2008 15:55:31 +0000</pubDate>
		<dc:creator>Toast</dc:creator>
				<category><![CDATA[Coding]]></category>
		<category><![CDATA[Fun]]></category>
		<category><![CDATA[Python]]></category>

		<guid isPermaLink="false">http://test.treibsand.com/?p=156</guid>
		<description><![CDATA[Durch Zufall bin ich über einen Blog Eintrag gestolpert, welcher ueber eine Demostration von Tierschutzanhängern vor einem Treffen von Python Programmierern berichtet ) http://techfaux.com/2008/06/17/peta-targets-computer-programmers-with-string-of-bizarre-protests/]]></description>
			<content:encoded><![CDATA[<p>Durch Zufall bin ich über einen Blog Eintrag gestolpert, welcher ueber eine Demostration von Tierschutzanhängern vor einem Treffen von Python Programmierern berichtet <img src='http://www.treibsand.com/wp-includes/images/smilies/icon_smile.gif' alt=':-)' class='wp-smiley' /> ) </p>
<p><span id="more-156"></span><br />
<a href="http://techfaux.com/2008/06/17/peta-targets-computer-programmers-with-string-of-bizarre-protests/ ">http://techfaux.com/2008/06/17/peta-targets-computer-programmers-with-string-of-bizarre-protests/ </a></p>
]]></content:encoded>
			<wfw:commentRss>http://www.treibsand.com/2008/06/24/peta_python/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Mit Django Datenbank Tabellen ändern</title>
		<link>http://www.treibsand.com/2008/04/17/mit-django-datenbank-tabellen-andern/</link>
		<comments>http://www.treibsand.com/2008/04/17/mit-django-datenbank-tabellen-andern/#comments</comments>
		<pubDate>Thu, 17 Apr 2008 15:40:30 +0000</pubDate>
		<dc:creator>Toast</dc:creator>
				<category><![CDATA[Coding]]></category>
		<category><![CDATA[Django]]></category>
		<category><![CDATA[JSON]]></category>
		<category><![CDATA[Python]]></category>

		<guid isPermaLink="false">http://test.treibsand.com/?p=139</guid>
		<description><![CDATA[&#8230;geht leider nicht. Ist ein Datenbank Model einmal definiert, lässt es sich nicht ohne Umwege erweitern. Ruby on Rails ist da schon ein Stück weiter. Das Problem lässt sich aber mit einem kleinen Trick lösen. Mit Django hat man die Möglichkeit die komplette Datenbank serialisiert zu dumpen und anschliesend wieder zu laden. Die Vorgehensweise ist [...]]]></description>
			<content:encoded><![CDATA[<p>&#8230;geht leider nicht. Ist ein Datenbank Model einmal definiert, lässt es sich nicht ohne Umwege erweitern. Ruby on Rails ist da schon ein Stück weiter.</p>
<p><span id="more-139"></span><br />
Das Problem lässt sich aber mit einem kleinen Trick lösen. Mit Django hat man die Möglichkeit die komplette Datenbank serialisiert zu dumpen und anschliesend wieder zu laden. Die Vorgehensweise ist einfach, einen Dump vom Model bzw. der ganzen Datenbank machen, Model um die gewünschten Felder erweitern, DB Tabellen löschen, Tabellen mit syncdb neu anlegen und den Dump wieder einspielen.</p>
<p>Die komplette Datenbank kann mit</p>

<div class="wp_syntax"><div class="code"><pre class="bash" style="font-family:monospace;">python manage.py dumpdata <span style="color: #000000; font-weight: bold;">&gt;</span> mydump.json</pre></div></div>

<p>gedumpt werden. Einzelne Models mit</p>

<div class="wp_syntax"><div class="code"><pre class="bash" style="font-family:monospace;">python manage.py dumpdata MyModel <span style="color: #000000; font-weight: bold;">&gt;</span> mydump.json</pre></div></div>

<p>Das importieren des Dumps geht wie folgt:</p>

<div class="wp_syntax"><div class="code"><pre class="bash" style="font-family:monospace;">python manage.py loaddata mydump.json</pre></div></div>

<p>Will man aber z.B. eine Anwendung mit initialen Daten versorgen, dann kann das mit Fixtures gemacht werden. Hierfür ist ein Eintrag in der Settings Datei notwendig.</p>

<div class="wp_syntax"><div class="code"><pre class="python" style="font-family:monospace;">FIXTURE_DIRS = <span style="color: black;">&#40;</span>
        <span style="color: #483d8b;">'/absoluter/pfad/zum/fixtures/verzeichnis'</span>,
<span style="color: black;">&#41;</span></pre></div></div>

<p>Liegt nun in diesem Verzeichnis eine Datei mit der Endung json, dann wird diese automatisch beim syncdb geladen und importiert. </p>
]]></content:encoded>
			<wfw:commentRss>http://www.treibsand.com/2008/04/17/mit-django-datenbank-tabellen-andern/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Sitemaps mit Django erstellen</title>
		<link>http://www.treibsand.com/2008/04/12/django_sitemaps/</link>
		<comments>http://www.treibsand.com/2008/04/12/django_sitemaps/#comments</comments>
		<pubDate>Sat, 12 Apr 2008 15:45:25 +0000</pubDate>
		<dc:creator>Toast</dc:creator>
				<category><![CDATA[Coding]]></category>
		<category><![CDATA[Django]]></category>
		<category><![CDATA[Python]]></category>

		<guid isPermaLink="false">http://test.treibsand.com/?p=143</guid>
		<description><![CDATA[Eine Sitemap ist nichts weiter als eine XML Datei auf dem Webserver, welche Suchmaschinen sagt wie sich Seiten geändert haben, und wie wichtig einzelne Seiten sind. Ausserdem kann man so Seiten Suchmaschinen geben, die evtl. nicht in den Index aufgenommen werden. Zum Glück nimmt Django einem die Arbeit ab, so dass Sitemaps automatisch erzeugt werden [...]]]></description>
			<content:encoded><![CDATA[<p>Eine Sitemap ist nichts weiter als eine XML Datei auf dem Webserver, welche Suchmaschinen sagt wie sich Seiten geändert haben, und wie wichtig einzelne Seiten sind. Ausserdem kann man so Seiten Suchmaschinen geben, die evtl. nicht in den Index aufgenommen werden.</p>
<p><span id="more-143"></span><br />
Zum Glück nimmt Django einem die Arbeit ab, so dass Sitemaps automatisch erzeugt werden können. Die Installation ist ziemlich simpel:</p>
<ul>
<li>Das Modul &#8216;django.contrib.sitemaps&#8217; zu den INSTALLED_APPS hinzufügen</li>
<li>Sicherstellen, dass &#8216;django.template.loaders.app_directories.load_template_source&#8217; in den Template Loaders eingetragen ist</li>
<li>Sicherstellen, dass das sites framework aktiviert ist</li>
</ul>
<p>Danach sind nur noch wenige Einträge in der Datei urls.py zu machen&#8230;</p>

<div class="wp_syntax"><div class="code"><pre class="python" style="font-family:monospace;"><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> <span style="color: #66cc66;">*</span>
<span style="color: #ff7700;font-weight:bold;">from</span> django.<span style="color: black;">contrib</span>.<span style="color: black;">sitemaps</span> <span style="color: #ff7700;font-weight:bold;">import</span> FlatPageSitemap, GenericSitemap
<span style="color: #ff7700;font-weight:bold;">from</span> mysite.<span style="color: black;">blog</span>.<span style="color: black;">models</span> <span style="color: #ff7700;font-weight:bold;">import</span> Entry
&nbsp;
info_dict = <span style="color: black;">&#123;</span>
    <span style="color: #483d8b;">'queryset'</span>: Entry.<span style="color: black;">objects</span>.<span style="color: #008000;">all</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>,
    <span style="color: #483d8b;">'date_field'</span>: <span style="color: #483d8b;">'pub_date'</span>,
<span style="color: black;">&#125;</span>
&nbsp;
sitemaps = <span style="color: black;">&#123;</span>
    <span style="color: #483d8b;">'flatpages'</span>: FlatPageSitemap,
    <span style="color: #483d8b;">'blog'</span>: GenericSitemap<span style="color: black;">&#40;</span>info_dict, priority=<span style="color: #ff4500;">0.6</span><span style="color: black;">&#41;</span>,
<span style="color: black;">&#125;</span>
&nbsp;
urlpatterns = patterns<span style="color: black;">&#40;</span><span style="color: #483d8b;">''</span>,
    <span style="color: #808080; font-style: italic;"># ...</span>
    <span style="color: black;">&#40;</span>r<span style="color: #483d8b;">'^sitemap.xml$'</span>, <span style="color: #483d8b;">'django.contrib.sitemaps.views.sitemap'</span>, <span style="color: black;">&#123;</span><span style="color: #483d8b;">'sitemaps'</span>: sitemaps<span style="color: black;">&#125;</span><span style="color: black;">&#41;</span>
<span style="color: black;">&#41;</span></pre></div></div>

<p>Mehr ist nicht zu machen <img src='http://www.treibsand.com/wp-includes/images/smilies/icon_smile.gif' alt=':-)' class='wp-smiley' />  </p>
<p>Es ist sogar möglich, bei Aenderungen am Model Google zu pingen, so dass die Sitemaps neu eingelesen werden&#8230;</p>

<div class="wp_syntax"><div class="code"><pre class="python" style="font-family:monospace;"><span style="color: #ff7700;font-weight:bold;">from</span> django.<span style="color: black;">contrib</span>.<span style="color: black;">sitemaps</span> <span style="color: #ff7700;font-weight:bold;">import</span> ping_google
&nbsp;
<span style="color: #ff7700;font-weight:bold;">class</span> Entry<span style="color: black;">&#40;</span>models.<span style="color: black;">Model</span><span style="color: black;">&#41;</span>:
    <span style="color: #808080; font-style: italic;"># ...</span>
    <span style="color: #ff7700;font-weight:bold;">def</span> save<span style="color: black;">&#40;</span><span style="color: #008000;">self</span><span style="color: black;">&#41;</span>:
        <span style="color: #008000;">super</span><span style="color: black;">&#40;</span>Entry, <span style="color: #008000;">self</span><span style="color: black;">&#41;</span>.<span style="color: black;">save</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>
        <span style="color: #ff7700;font-weight:bold;">try</span>:
            ping_google<span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>
        <span style="color: #ff7700;font-weight:bold;">except</span> <span style="color: #008000;">Exception</span>:
            <span style="color: #808080; font-style: italic;"># Bare 'except' because we could get a variety</span>
            <span style="color: #808080; font-style: italic;"># of HTTP-related exceptions.</span>
            <span style="color: #ff7700;font-weight:bold;">pass</span></pre></div></div>

]]></content:encoded>
			<wfw:commentRss>http://www.treibsand.com/2008/04/12/django_sitemaps/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Google&#8217;s App Engine</title>
		<link>http://www.treibsand.com/2008/04/11/google_appengine/</link>
		<comments>http://www.treibsand.com/2008/04/11/google_appengine/#comments</comments>
		<pubDate>Fri, 11 Apr 2008 15:26:55 +0000</pubDate>
		<dc:creator>Toast</dc:creator>
				<category><![CDATA[Coding]]></category>
		<category><![CDATA[Google]]></category>
		<category><![CDATA[Python]]></category>

		<guid isPermaLink="false">http://test.treibsand.com/?p=125</guid>
		<description><![CDATA[Vor kurzem hat Google wieder etwas neues vorgestellt, und zwar die App Engine. Mit der App Engine hat man die Möglichkeit eigene Webanwendungen auf der Google Infrastruktur zu betreiben. Google stellt hierfür eine komplette Entwicklungsumgebung zur Verfügung und bietet skalierbares Hosting. Aktuell kann die App Engine nur mit Python (2.5) benutzt werden. Es aber wohl [...]]]></description>
			<content:encoded><![CDATA[<p>Vor kurzem hat Google wieder etwas neues vorgestellt, und zwar die App Engine. Mit der App Engine hat man die Möglichkeit eigene Webanwendungen auf der Google Infrastruktur zu betreiben. Google stellt hierfür eine komplette Entwicklungsumgebung zur Verfügung und bietet skalierbares Hosting. </p>
<p><span id="more-125"></span><br />
Aktuell kann die App Engine nur mit Python (2.5) benutzt werden. Es aber wohl absehbar, dass dies für andere Sprachen erweitert wird. Da es sich noch um ein Preview handelt ist die Benutzung noch auf 10000 Entwickler beschränkt, wahrscheinlich gibt es schon eine ziemlich lange Warteliste&#8230;</p>
<p>Wenn man zu den wenigen gehört, die einen Account haben, dann erwarten einen folgende Features:</p>
<ul>
<li>Hosting der Webanwendung</li>
<li>Persistent storage (Mit BigTable und GFS)</li>
<li>Automatische Skalierung und Loadbalancing</li>
<li>Google APIs</li>
<li>Komplette Entwicklungsumgebung</li>
</ul>
<p>Während der Testphase sind aber die Resourcen etwas beschränkt (je nachdem wie man es sieht):</p>
<ul>
<li>500MB Speicherplatz</li>
<li>ausreichend CPU (200 Millionen Megacycles pro Tag)</li>
<li>10GB Bandbreite am Tag</li>
</ul>
<p>Das ist eigentlich schon mal gar nicht wenig. Auf jeden Fall war die Veröffentlichung von App Engine ein guter Tag für die Python Community und Django. Python ist leider noch nicht so weit verbreitet wie z.B. Perl und PHP, obwohl es die Sprache schon ziemlich lange gibt. Für Django dürfte es auch recht erfreulich sein, dass Google Teile von Django verwendet. Vielleicht wird dadurch Django ja so bekannt wie Ruby on Rails.</p>
<p>Von Django wurde z.B. das Template System verwendet, welches ich für eines der besten halte. Wenn ich in Richtung TurboGears schaue, wo fuer die Templates KID verwendet wird, dann bekomm ich das Grauen&#8230;</p>
<p>Auch das Datastorage von App Engine ist ähnlich zu Django&#8217;s data modelling API. Die Models werden z.B. wie folgt erstellt:</p>

<div class="wp_syntax"><div class="code"><pre class="python" style="font-family:monospace;"><span style="color: #ff7700;font-weight:bold;">class</span> Greeting<span style="color: black;">&#40;</span>db.<span style="color: black;">Model</span><span style="color: black;">&#41;</span>:
  author = db.<span style="color: black;">UserProperty</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>
  content = db.<span style="color: black;">StringProperty</span><span style="color: black;">&#40;</span>multiline=<span style="color: #008000;">True</span><span style="color: black;">&#41;</span>
  date = db.<span style="color: black;">DateTimeProperty</span><span style="color: black;">&#40;</span>auto_now_add=<span style="color: #008000;">True</span><span style="color: black;">&#41;</span></pre></div></div>

<p>Der grosse Unterscheid ist einfach, dass bei App Engine keine gewöhnliche SQL Datenbank wie PostgreSQL dahinter ist. Deswegen kann auch nicht SQL zur Abfrage verwendet werden, stattdessen gibt es GQL, welches eine ähnlich Syntax hat. Eine Abfrage kann z.B. mit</p>

<div class="wp_syntax"><div class="code"><pre class="python" style="font-family:monospace;">greetings = db.<span style="color: black;">GqlQuery</span><span style="color: black;">&#40;</span><span style="color: #483d8b;">&quot;SELECT * FROM Greeting ORDER BY date DESC LIMIT 10&quot;</span><span style="color: black;">&#41;</span></pre></div></div>

<p>formuliert werden. Wenn man nun aber schon Objektorientiert Daten speichern kann, warum kann man diese dann nicht auf dem gleichen Weg wieder Abfragen? Die meisten anderen Frameworks können es ja auch&#8230;</p>
]]></content:encoded>
			<wfw:commentRss>http://www.treibsand.com/2008/04/11/google_appengine/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>SQLite zu MySQL konvertieren</title>
		<link>http://www.treibsand.com/2008/02/15/sqlite_mysql/</link>
		<comments>http://www.treibsand.com/2008/02/15/sqlite_mysql/#comments</comments>
		<pubDate>Fri, 15 Feb 2008 14:48:07 +0000</pubDate>
		<dc:creator>Toast</dc:creator>
				<category><![CDATA[Coding]]></category>
		<category><![CDATA[MySQL]]></category>
		<category><![CDATA[Python]]></category>
		<category><![CDATA[SQLite]]></category>

		<guid isPermaLink="false">http://test.treibsand.com/?p=82</guid>
		<description><![CDATA[Es kann vorkommen, dass man ein kleines Projekt beginnt und der Einfachheit halber eine SQLite Datenbank dafuer verwendet. Mit der Zeit wachst aber der Datenbestand und SQLite ist dann damit überfordert. Da Hilft nur noch die Datenbank in ein performanteres System zu migrieren, z.B. MySQL. Allerdings gibt es dabei ein kleines Problem. Die SQLite Dumps [...]]]></description>
			<content:encoded><![CDATA[<p>Es kann vorkommen, dass man ein kleines Projekt beginnt und der Einfachheit halber eine SQLite Datenbank dafuer verwendet. Mit der Zeit wachst aber der Datenbestand und SQLite ist dann damit überfordert. </p>
<p><span id="more-82"></span><br />
Da Hilft nur noch die Datenbank in ein performanteres System zu migrieren, z.B. MySQL. Allerdings gibt es dabei ein kleines Problem.</p>
<p>Die SQLite Dumps sind nicht kompatibel mit MySQL, so dass man erst den Dump konvertieren muss. Für den Fall hilft ein kleines Script aus:</p>

<div class="wp_syntax"><div class="code"><pre class="python" style="font-family:monospace;"><span style="color: #808080; font-style: italic;">#!/usr/bin/env python</span>
&nbsp;
<span style="color: #ff7700;font-weight:bold;">import</span> <span style="color: #dc143c;">sys</span>
<span style="color: #ff7700;font-weight:bold;">import</span> <span style="color: #dc143c;">re</span>
&nbsp;
<span style="color: #008000;">file</span> = <span style="color: #dc143c;">sys</span>.<span style="color: black;">stdin</span>.<span style="color: black;">read</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>
<span style="color: #008000;">file</span> = <span style="color: #dc143c;">re</span>.<span style="color: black;">sub</span><span style="color: black;">&#40;</span>r<span style="color: #483d8b;">'(CREATE (TABLE|INDEX)[^;]*|COMMIT|BEGIN TRANSACTION);'</span>, <span style="color: #483d8b;">''</span>, <span style="color: #008000;">file</span><span style="color: black;">&#41;</span>
<span style="color: #008000;">file</span> = <span style="color: #dc143c;">re</span>.<span style="color: black;">sub</span><span style="color: black;">&#40;</span>r<span style="color: #483d8b;">'INSERT INTO &quot;([^&quot;]+)&quot;'</span>, <span style="color: #ff7700;font-weight:bold;">lambda</span> m: <span style="color: #483d8b;">'INSERT INTO `%s`'</span> <span style="color: #66cc66;">%</span> m.<span style="color: black;">groups</span><span style="color: black;">&#40;</span><span style="color: #ff4500;">1</span><span style="color: black;">&#41;</span>, <span style="color: #008000;">file</span><span style="color: black;">&#41;</span>
<span style="color: #dc143c;">sys</span>.<span style="color: black;">stdout</span>.<span style="color: black;">write</span><span style="color: black;">&#40;</span><span style="color: #008000;">file</span><span style="color: black;">&#41;</span></pre></div></div>

<p>Damit lässt sich der Dump wie folgt konvertieren:</p>

<div class="wp_syntax"><div class="code"><pre class="bash" style="font-family:monospace;">.<span style="color: #000000; font-weight: bold;">/</span>sqlite2mysql <span style="color: #000000; font-weight: bold;">&lt;</span> sqlite_dump.sql <span style="color: #000000; font-weight: bold;">&gt;</span> mysql_dump_dataonly.sql</pre></div></div>

]]></content:encoded>
			<wfw:commentRss>http://www.treibsand.com/2008/02/15/sqlite_mysql/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Mit Django JSON ausliefern</title>
		<link>http://www.treibsand.com/2008/02/14/django_json/</link>
		<comments>http://www.treibsand.com/2008/02/14/django_json/#comments</comments>
		<pubDate>Thu, 14 Feb 2008 14:50:27 +0000</pubDate>
		<dc:creator>Toast</dc:creator>
				<category><![CDATA[Coding]]></category>
		<category><![CDATA[Django]]></category>
		<category><![CDATA[JSON]]></category>
		<category><![CDATA[Python]]></category>

		<guid isPermaLink="false">http://test.treibsand.com/?p=85</guid>
		<description><![CDATA[Dank den neuen JavaScript Frameworks wie z.B. Prototype und MochiKit ist es mittlerweile ziemlich einfach dynamische Webinhalte mit AJAX zu machen. Doch die Daten müssen erstmal in die passende Form gebracht werden, um verarbeitet werden zu können. Eine Möglichkeit ist JSON (JavaScript Object Notation). Dank Djano kann das auch sehr einfach werden. Um zum Beispiel [...]]]></description>
			<content:encoded><![CDATA[<p>Dank den neuen JavaScript Frameworks wie z.B. Prototype und MochiKit ist es mittlerweile ziemlich einfach dynamische Webinhalte mit AJAX zu machen. </p>
<p><span id="more-85"></span><br />
Doch die Daten müssen erstmal in die passende Form gebracht werden, um verarbeitet werden zu können. Eine Möglichkeit ist JSON (JavaScript Object Notation).</p>
<p>Dank Djano kann das auch sehr einfach werden. Um zum Beispiel alle Einträge aus den Feldern &#8220;name&#8221; und &#8220;size&#8221; einer Tabelle mit JSON bereitzustellen reicht folgender Code aus:</p>

<div class="wp_syntax"><div class="code"><pre class="python" style="font-family:monospace;"><span style="color: #ff7700;font-weight:bold;">from</span> someproject.<span style="color: black;">someapp</span>.<span style="color: black;">models</span> <span style="color: #ff7700;font-weight:bold;">import</span> SomeModel
<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> HttpResponse
<span style="color: #ff7700;font-weight:bold;">from</span> django.<span style="color: black;">core</span> <span style="color: #ff7700;font-weight:bold;">import</span> serializers
&nbsp;
<span style="color: #ff7700;font-weight:bold;">def</span> json<span style="color: black;">&#40;</span>request,<span style="color: black;">&#41;</span>:
  data = serializers.<span style="color: black;">serialize</span><span style="color: black;">&#40;</span><span style="color: #483d8b;">'json'</span>, SomeModel.<span style="color: black;">objects</span>.<span style="color: #008000;">all</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>, fields=<span style="color: black;">&#40;</span><span style="color: #483d8b;">'name'</span>,<span style="color: #483d8b;">'size'</span><span style="color: black;">&#41;</span><span style="color: black;">&#41;</span>
  <span style="color: #ff7700;font-weight:bold;">return</span> HttpResponse<span style="color: black;">&#40;</span>data, mimetype=<span style="color: #483d8b;">&quot;text/plain&quot;</span><span style="color: black;">&#41;</span></pre></div></div>

<p>Und schon kann man per URL JSON Daten abfragen. Happy coding! </p>
]]></content:encoded>
			<wfw:commentRss>http://www.treibsand.com/2008/02/14/django_json/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>f == f -&gt; False!?</title>
		<link>http://www.treibsand.com/2007/03/16/float_equality/</link>
		<comments>http://www.treibsand.com/2007/03/16/float_equality/#comments</comments>
		<pubDate>Fri, 16 Mar 2007 14:39:19 +0000</pubDate>
		<dc:creator>Toast</dc:creator>
				<category><![CDATA[Coding]]></category>
		<category><![CDATA[Python]]></category>

		<guid isPermaLink="false">http://test.treibsand.com/?p=78</guid>
		<description><![CDATA[Wann ist ein Vergleich einer Variable mit sich selber nicht mehr True? &#62;&#62;&#62; type&#40;f&#41; &#60;type 'float'&#62; &#62;&#62;&#62; f == f False &#62;&#62;&#62; type&#40;f2&#41; &#60;type 'float'&#62; &#62;&#62;&#62; f2 == f2 True]]></description>
			<content:encoded><![CDATA[<p>Wann ist ein Vergleich einer Variable mit sich selber nicht mehr True? <img src='http://www.treibsand.com/wp-includes/images/smilies/icon_smile.gif' alt=':-)' class='wp-smiley' />  </p>
<p><span id="more-78"></span></p>

<div class="wp_syntax"><div class="code"><pre class="python" style="font-family:monospace;"><span style="color: #66cc66;">&gt;&gt;&gt;</span> <span style="color: #008000;">type</span><span style="color: black;">&#40;</span>f<span style="color: black;">&#41;</span>
<span style="color: #66cc66;">&lt;</span>type <span style="color: #483d8b;">'float'</span><span style="color: #66cc66;">&gt;</span>
<span style="color: #66cc66;">&gt;&gt;&gt;</span> f == f
<span style="color: #008000;">False</span>
<span style="color: #66cc66;">&gt;&gt;&gt;</span> <span style="color: #008000;">type</span><span style="color: black;">&#40;</span>f2<span style="color: black;">&#41;</span>
<span style="color: #66cc66;">&lt;</span>type <span style="color: #483d8b;">'float'</span><span style="color: #66cc66;">&gt;</span>
<span style="color: #66cc66;">&gt;&gt;&gt;</span> f2 == f2
<span style="color: #008000;">True</span></pre></div></div>

]]></content:encoded>
			<wfw:commentRss>http://www.treibsand.com/2007/03/16/float_equality/feed/</wfw:commentRss>
		<slash:comments>5</slash:comments>
		</item>
		<item>
		<title>SMTP Engine in Python</title>
		<link>http://www.treibsand.com/2007/03/15/smtpd_python/</link>
		<comments>http://www.treibsand.com/2007/03/15/smtpd_python/#comments</comments>
		<pubDate>Thu, 15 Mar 2007 13:10:31 +0000</pubDate>
		<dc:creator>Toast</dc:creator>
				<category><![CDATA[Coding]]></category>
		<category><![CDATA[Mail]]></category>
		<category><![CDATA[Python]]></category>
		<category><![CDATA[SMTP]]></category>

		<guid isPermaLink="false">http://test.treibsand.com/?p=43</guid>
		<description><![CDATA[Vor kurzem war ich dabei einen Contentfilter für Postfix zu schreiben. Einfache Contentfilter lassen sich ja sogar mit Shell Scripts machen, diese werden dann aber per Pipe aufgerufen, was mir nicht wirklich gefällt&#8230; Viel interessanter ist es einen Contentfilter per spawn einzubinden, was ein Program startet und es an einen Socket bindet, etwa so wie [...]]]></description>
			<content:encoded><![CDATA[<p>Vor kurzem war ich dabei einen Contentfilter für Postfix zu schreiben. Einfache Contentfilter lassen sich ja sogar mit Shell Scripts machen, diese werden dann aber per Pipe aufgerufen, was mir nicht wirklich gefällt&#8230; </p>
<p><span id="more-43"></span><br />
Viel interessanter ist es einen Contentfilter per spawn einzubinden, was ein Program startet und es an einen Socket bindet, etwa so wie inetd. Die Kommunikation zwischen Postfix und dem Contentfilter läuft dann per STDIN bzw. STDOUT&#8230;</p>
<p>Der Contentfilter muss aber SMTP sprechen können, da Postfix per STDIN Smtp Kommandos schickt. Somit musste ich eine SMTPD Klasse in Python schreiben. Da es allgemein wenig Dokumentiert ist, wie so etwas programmiert werden kann, stelle ich hier die Basis-Klasse zur<br />
Verfügung.</p>

<div class="wp_syntax"><div class="code"><pre class="python" style="font-family:monospace;"><span style="color: #ff7700;font-weight:bold;">import</span> <span style="color: #dc143c;">sys</span>, <span style="color: #dc143c;">string</span>, <span style="color: #dc143c;">os</span>
&nbsp;
<span style="color: #808080; font-style: italic;">#---------------------------------------------------------------------------------------------</span>
<span style="color: #ff7700;font-weight:bold;">class</span> SMTPServerEngine:
	ST_INIT = <span style="color: #ff4500;">0</span>
	ST_HELO = <span style="color: #ff4500;">1</span>
	ST_MAIL = <span style="color: #ff4500;">2</span>
	ST_RCPT = <span style="color: #ff4500;">3</span>
	ST_DATA = <span style="color: #ff4500;">4</span>
	ST_QUIT = <span style="color: #ff4500;">5</span>
&nbsp;
	<span style="color: #ff7700;font-weight:bold;">def</span> <span style="color: #0000cd;">__init__</span><span style="color: black;">&#40;</span><span style="color: #008000;">self</span><span style="color: black;">&#41;</span>:
		<span style="color: #008000;">self</span>.<span style="color: black;">state</span> = SMTPServerEngine.<span style="color: black;">ST_INIT</span>
&nbsp;
	<span style="color: #ff7700;font-weight:bold;">def</span> chug<span style="color: black;">&#40;</span><span style="color: #008000;">self</span><span style="color: black;">&#41;</span>:
		<span style="color: #ff7700;font-weight:bold;">while</span> <span style="color: #ff4500;">1</span>:
			data = <span style="color: #483d8b;">''</span>
			completeLine = <span style="color: #ff4500;">0</span>
			<span style="color: #ff7700;font-weight:bold;">while</span> <span style="color: #ff7700;font-weight:bold;">not</span> completeLine:
				lump = <span style="color: #dc143c;">os</span>.<span style="color: black;">read</span><span style="color: black;">&#40;</span><span style="color: #dc143c;">sys</span>.<span style="color: black;">stdin</span>.<span style="color: black;">fileno</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>, <span style="color: #ff4500;">1024</span><span style="color: black;">&#41;</span>
				<span style="color: #ff7700;font-weight:bold;">if</span> <span style="color: #008000;">len</span><span style="color: black;">&#40;</span>lump<span style="color: black;">&#41;</span>:
					data += lump
					<span style="color: #ff7700;font-weight:bold;">if</span> <span style="color: black;">&#40;</span><span style="color: #008000;">len</span><span style="color: black;">&#40;</span>data<span style="color: black;">&#41;</span> <span style="color: #66cc66;">&gt;</span>= <span style="color: #ff4500;">2</span><span style="color: black;">&#41;</span> <span style="color: #ff7700;font-weight:bold;">and</span> data<span style="color: black;">&#91;</span>-<span style="color: #ff4500;">2</span>:<span style="color: black;">&#93;</span> == <span style="color: #483d8b;">'<span style="color: #000099; font-weight: bold;">\r</span><span style="color: #000099; font-weight: bold;">\n</span>'</span>:
						completeLine = <span style="color: #ff4500;">1</span>
						<span style="color: #ff7700;font-weight:bold;">if</span> <span style="color: #008000;">self</span>.<span style="color: black;">state</span> <span style="color: #66cc66;">!</span>= SMTPServerEngine.<span style="color: black;">ST_DATA</span>:
							rsp, keep = <span style="color: #008000;">self</span>.<span style="color: black;">doCommand</span><span style="color: black;">&#40;</span>data<span style="color: black;">&#41;</span>
						<span style="color: #ff7700;font-weight:bold;">else</span>:
							rsp = <span style="color: #008000;">self</span>.<span style="color: black;">doData</span><span style="color: black;">&#40;</span>data<span style="color: black;">&#41;</span>
&nbsp;
						<span style="color: #ff7700;font-weight:bold;">if</span> rsp == <span style="color: #008000;">None</span>:
							<span style="color: #ff7700;font-weight:bold;">continue</span>
&nbsp;
						<span style="color: #dc143c;">sys</span>.<span style="color: black;">stdout</span>.<span style="color: black;">write</span><span style="color: black;">&#40;</span>rsp + <span style="color: #483d8b;">&quot;<span style="color: #000099; font-weight: bold;">\r</span><span style="color: #000099; font-weight: bold;">\n</span>&quot;</span><span style="color: black;">&#41;</span>
						<span style="color: #dc143c;">sys</span>.<span style="color: black;">stdout</span>.<span style="color: black;">flush</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>
&nbsp;
						<span style="color: #ff7700;font-weight:bold;">if</span> keep == <span style="color: #ff4500;">0</span>:	
							<span style="color: #dc143c;">sys</span>.<span style="color: black;">exit</span><span style="color: black;">&#40;</span><span style="color: #ff4500;">0</span><span style="color: black;">&#41;</span>
							<span style="color: #ff7700;font-weight:bold;">return</span>	
				<span style="color: #ff7700;font-weight:bold;">else</span>:
					<span style="color: #ff7700;font-weight:bold;">return</span>
&nbsp;
		<span style="color: #ff7700;font-weight:bold;">return</span>
&nbsp;
	<span style="color: #ff7700;font-weight:bold;">def</span> doCommand<span style="color: black;">&#40;</span><span style="color: #008000;">self</span>, data<span style="color: black;">&#41;</span>:
		<span style="color: #483d8b;">&quot;&quot;&quot;Process a single SMTP Command&quot;&quot;&quot;</span>
		<span style="color: #dc143c;">cmd</span> = data<span style="color: black;">&#91;</span><span style="color: #ff4500;">0</span>:<span style="color: #ff4500;">4</span><span style="color: black;">&#93;</span>
		<span style="color: #dc143c;">cmd</span> = <span style="color: #dc143c;">string</span>.<span style="color: black;">upper</span><span style="color: black;">&#40;</span><span style="color: #dc143c;">cmd</span><span style="color: black;">&#41;</span>
		keep = <span style="color: #ff4500;">1</span>
		<span style="color: #ff7700;font-weight:bold;">if</span> <span style="color: #dc143c;">cmd</span> == <span style="color: #483d8b;">&quot;HELO&quot;</span>:
			<span style="color: #008000;">self</span>.<span style="color: black;">state</span> = SMTPServerEngine.<span style="color: black;">ST_HELO</span>
		<span style="color: #ff7700;font-weight:bold;">elif</span> <span style="color: #dc143c;">cmd</span> == <span style="color: #483d8b;">&quot;RSET&quot;</span>:
			<span style="color: #008000;">self</span>.<span style="color: black;">dataAccum</span> = <span style="color: #483d8b;">&quot;&quot;</span>
			<span style="color: #008000;">self</span>.<span style="color: black;">state</span> = SMTPServerEngine.<span style="color: black;">ST_INIT</span>
		<span style="color: #ff7700;font-weight:bold;">elif</span> <span style="color: #dc143c;">cmd</span> == <span style="color: #483d8b;">&quot;NOOP&quot;</span>:
			<span style="color: #ff7700;font-weight:bold;">pass</span>
		<span style="color: #ff7700;font-weight:bold;">elif</span> <span style="color: #dc143c;">cmd</span> == <span style="color: #483d8b;">&quot;QUIT&quot;</span>:
			keep = <span style="color: #ff4500;">0</span>
		<span style="color: #ff7700;font-weight:bold;">elif</span> <span style="color: #dc143c;">cmd</span> == <span style="color: #483d8b;">&quot;MAIL&quot;</span>:
			<span style="color: #ff7700;font-weight:bold;">if</span> <span style="color: #008000;">self</span>.<span style="color: black;">state</span> <span style="color: #66cc66;">!</span>= SMTPServerEngine.<span style="color: black;">ST_HELO</span>:
				<span style="color: #ff7700;font-weight:bold;">return</span> <span style="color: black;">&#40;</span><span style="color: #483d8b;">&quot;503 Bad command sequence&quot;</span>, <span style="color: #ff4500;">1</span><span style="color: black;">&#41;</span>
			<span style="color: #008000;">self</span>.<span style="color: black;">state</span> = SMTPServerEngine.<span style="color: black;">ST_MAIL</span>
		<span style="color: #ff7700;font-weight:bold;">elif</span> <span style="color: #dc143c;">cmd</span> == <span style="color: #483d8b;">&quot;RCPT&quot;</span>:
			<span style="color: #ff7700;font-weight:bold;">if</span> <span style="color: black;">&#40;</span><span style="color: #008000;">self</span>.<span style="color: black;">state</span> <span style="color: #66cc66;">!</span>= SMTPServerEngine.<span style="color: black;">ST_MAIL</span><span style="color: black;">&#41;</span> <span style="color: #ff7700;font-weight:bold;">and</span> <span style="color: black;">&#40;</span><span style="color: #008000;">self</span>.<span style="color: black;">state</span> <span style="color: #66cc66;">!</span>= SMTPServerEngine.<span style="color: black;">ST_RCPT</span><span style="color: black;">&#41;</span>:
				<span style="color: #ff7700;font-weight:bold;">return</span> <span style="color: black;">&#40;</span><span style="color: #483d8b;">&quot;503 Bad command sequence&quot;</span>, <span style="color: #ff4500;">1</span><span style="color: black;">&#41;</span>
			<span style="color: #008000;">self</span>.<span style="color: black;">state</span> = SMTPServerEngine.<span style="color: black;">ST_RCPT</span>
		<span style="color: #ff7700;font-weight:bold;">elif</span> <span style="color: #dc143c;">cmd</span> == <span style="color: #483d8b;">&quot;DATA&quot;</span>:
			<span style="color: #ff7700;font-weight:bold;">if</span> <span style="color: #008000;">self</span>.<span style="color: black;">state</span> <span style="color: #66cc66;">!</span>= SMTPServerEngine.<span style="color: black;">ST_RCPT</span>:
				<span style="color: #ff7700;font-weight:bold;">return</span> <span style="color: black;">&#40;</span><span style="color: #483d8b;">&quot;503 Bad command sequence&quot;</span>, <span style="color: #ff4500;">1</span><span style="color: black;">&#41;</span>
			<span style="color: #008000;">self</span>.<span style="color: black;">state</span> = SMTPServerEngine.<span style="color: black;">ST_DATA</span>
			<span style="color: #008000;">self</span>.<span style="color: black;">dataAccum</span> = <span style="color: #483d8b;">&quot;&quot;</span>
			<span style="color: #ff7700;font-weight:bold;">return</span> <span style="color: black;">&#40;</span><span style="color: #483d8b;">&quot;354 OK, Enter data, terminated with a <span style="color: #000099; font-weight: bold;">\\</span>r<span style="color: #000099; font-weight: bold;">\\</span>n.<span style="color: #000099; font-weight: bold;">\\</span>r<span style="color: #000099; font-weight: bold;">\\</span>n&quot;</span>, <span style="color: #ff4500;">1</span><span style="color: black;">&#41;</span>
		<span style="color: #ff7700;font-weight:bold;">else</span>:
			<span style="color: #ff7700;font-weight:bold;">return</span> <span style="color: black;">&#40;</span><span style="color: #483d8b;">&quot;505 Eh? WTF was that?&quot;</span>, <span style="color: #ff4500;">1</span><span style="color: black;">&#41;</span>
&nbsp;
		<span style="color: #ff7700;font-weight:bold;">return</span><span style="color: black;">&#40;</span><span style="color: #483d8b;">&quot;250 OK&quot;</span>, keep<span style="color: black;">&#41;</span>
&nbsp;
	<span style="color: #ff7700;font-weight:bold;">def</span> doData<span style="color: black;">&#40;</span><span style="color: #008000;">self</span>, data<span style="color: black;">&#41;</span>:
		<span style="color: #483d8b;">&quot;&quot;&quot;
		Process SMTP Data. Accumulates client DATA until the
		terminator is found.
		&quot;&quot;&quot;</span>
		<span style="color: #008000;">self</span>.<span style="color: black;">dataAccum</span> = <span style="color: #008000;">self</span>.<span style="color: black;">dataAccum</span> + data
		<span style="color: #ff7700;font-weight:bold;">if</span> <span style="color: #008000;">len</span><span style="color: black;">&#40;</span><span style="color: #008000;">self</span>.<span style="color: black;">dataAccum</span><span style="color: black;">&#41;</span> <span style="color: #66cc66;">&gt;</span> <span style="color: #ff4500;">4</span> <span style="color: #ff7700;font-weight:bold;">and</span> <span style="color: #008000;">self</span>.<span style="color: black;">dataAccum</span><span style="color: black;">&#91;</span>-<span style="color: #ff4500;">5</span>:<span style="color: black;">&#93;</span> == <span style="color: #483d8b;">'<span style="color: #000099; font-weight: bold;">\r</span><span style="color: #000099; font-weight: bold;">\n</span>.<span style="color: #000099; font-weight: bold;">\r</span><span style="color: #000099; font-weight: bold;">\n</span>'</span>:
			<span style="color: #008000;">self</span>.<span style="color: black;">dataAccum</span> = <span style="color: #008000;">self</span>.<span style="color: black;">dataAccum</span><span style="color: black;">&#91;</span>:-<span style="color: #ff4500;">5</span><span style="color: black;">&#93;</span>
			<span style="color: #008000;">self</span>.<span style="color: black;">state</span> = SMTPServerEngine.<span style="color: black;">ST_HELO</span>
&nbsp;
			<span style="color: #ff7700;font-weight:bold;">return</span> <span style="color: #483d8b;">&quot;250 OK - message accepted&quot;</span>
		<span style="color: #ff7700;font-weight:bold;">else</span>:
			<span style="color: #ff7700;font-weight:bold;">return</span> <span style="color: #008000;">None</span>
&nbsp;
&nbsp;
<span style="color: #808080; font-style: italic;">#---------------------------------------------------------------------------------------------</span>
<span style="color: #ff7700;font-weight:bold;">if</span> __name__ == <span style="color: #483d8b;">'__main__'</span>:
	<span style="color: #ff7700;font-weight:bold;">try</span>:
		<span style="color: #dc143c;">sys</span>.<span style="color: black;">stdout</span>.<span style="color: black;">write</span><span style="color: black;">&#40;</span><span style="color: #483d8b;">&quot;220 localhost<span style="color: #000099; font-weight: bold;">\r</span><span style="color: #000099; font-weight: bold;">\n</span>&quot;</span><span style="color: black;">&#41;</span>
		<span style="color: #dc143c;">sys</span>.<span style="color: black;">stdout</span>.<span style="color: black;">flush</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>
		<span style="color: #ff7700;font-weight:bold;">while</span> <span style="color: #ff4500;">1</span>:
			engine = SMTPServerEngine<span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>
			engine.<span style="color: black;">chug</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>
	<span style="color: #ff7700;font-weight:bold;">except</span> <span style="color: #008000;">SystemExit</span>:
		<span style="color: #ff7700;font-weight:bold;">pass</span></pre></div></div>

]]></content:encoded>
			<wfw:commentRss>http://www.treibsand.com/2007/03/15/smtpd_python/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>

