<?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/"
	xmlns:georss="http://www.georss.org/georss" xmlns:geo="http://www.w3.org/2003/01/geo/wgs84_pos#" xmlns:media="http://search.yahoo.com/mrss/"
	>

<channel>
	<title>Not Really a Blog &#187; python</title>
	<atom:link href="http://blog.notreally.org/tag/python/feed/" rel="self" type="application/rss+xml" />
	<link>http://blog.notreally.org</link>
	<description>or is it?</description>
	<lastBuildDate>Tue, 13 Jul 2010 09:48:09 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.com/</generator>
<cloud domain='blog.notreally.org' port='80' path='/?rsscloud=notify' registerProcedure='' protocol='http-post' />
<image>
		<url>http://1.gravatar.com/blavatar/93018cad14db97a3057eb332c3ba920a?s=96&#038;d=http://s2.wp.com/i/buttonw-com.png</url>
		<title>Not Really a Blog &#187; python</title>
		<link>http://blog.notreally.org</link>
	</image>
	<atom:link rel="search" type="application/opensearchdescription+xml" href="http://blog.notreally.org/osd.xml" title="Not Really a Blog" />
	<atom:link rel='hub' href='http://blog.notreally.org/?pushpress=hub'/>
		<item>
		<title>Speeding up trac&#8217;s response time</title>
		<link>http://blog.notreally.org/2006/12/04/speeding-up-tracs-response-time/</link>
		<comments>http://blog.notreally.org/2006/12/04/speeding-up-tracs-response-time/#comments</comments>
		<pubDate>Mon, 04 Dec 2006 18:30:44 +0000</pubDate>
		<dc:creator>jroncero</dc:creator>
				<category><![CDATA[Internet]]></category>
		<category><![CDATA[Programming]]></category>
		<category><![CDATA[program]]></category>
		<category><![CDATA[python]]></category>
		<category><![CDATA[tips]]></category>
		<category><![CDATA[trac]]></category>
		<category><![CDATA[tricks]]></category>

		<guid isPermaLink="false">http://blognotreally.wordpress.com/2006/12/04/speeding-up-tracs-response-time/</guid>
		<description><![CDATA[I&#8217;ve been trying to speed up an installation of trac over the last few days. The web interface took ages to display each of the directories or files within the subversion repository. But this one wasn&#8217;t too big. The only change to the subversion repository is that we started using a vendor branch imported into [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=blog.notreally.org&amp;blog=8911601&amp;post=40&amp;subd=blognotreally&amp;ref=&amp;feed=1" width="1" height="1" />]]></description>
			<content:encoded><![CDATA[<p>I&#8217;ve been trying to speed up an installation of <a href="http://trac.edgewall.org/">trac</a> over the last few days. The web interface took ages to display each of the directories or files within the subversion repository. But this one wasn&#8217;t too big. The only change to the subversion repository is that we started using a vendor branch imported into our main repository using <a href="http://search.cpan.org/~clkao/SVN-Mirror-0.72/bin/svm">svm</a></p>
<p>So, after a few hours trying different solutions, and reading trac&#8217;s source code, I think I got where the bottleneck was.Well, it was <a href="sqlite">http://www.sqlite.org/download.html</a> which was causing the bottleneck. Trac uses an object <em>CachedRepository</em> to access the repositories. Whenever we want to get the <em>chagesets</em>, a function to synchronize the repository is called:</p>
<pre class="brush: python;">
class CachedRepository(Repository):
  def get_changeset(self, rev):
    if not self.synced:
      self.sync()
      self.synced = 1
      return CachedChangeset(self.repos.normalize_rev(rev), self.db, self.authz)
</pre>
<p>and such method, sync(), makes a call to:</p>
<pre class="brush: python;">
youngest_stored = self.repos.get_youngest_rev_in_cache(self.db)
</pre>
<p>which is all this:</p>
<pre class="brush: python;">
def get_youngest_rev_in_cache(self, db):
    &quot;&quot;&quot;Get the latest stored revision by sorting the revision strings
    numerically
    &quot;&quot;&quot;
    cursor = db.cursor()
    cursor.execute(&quot;SELECT rev FROM revision ORDER BY -LENGTH(rev), rev DESC LIMIT 1&quot;)
    row = cursor.fetchone()
    return row and row[0] or None
</pre>
<p>And that SQL query was taking around 1-2 seconds each time it was executed. It happened that we were running an old version of <a href="http://www.sqlite.org/">sqlite</a> and <a href="http://www.initd.org/pub/software/pysqlite/">pysqlite</a>, so a <strong>./cofigure &amp;&amp; make &amp;&amp; make install</strong> using the recommended installation saved my day <img src='http://s.wordpress.com/wp-includes/images/smilies/icon_smile.gif' alt=':-)' class='wp-smiley' /> </p>
<p>Hope it is useful to anybody if it gets indexed by <a href="http://www.google.com">Google</a>.</p>
<br /><img alt="" border="0" src="http://feeds.wordpress.com/1.0/categories/blognotreally.wordpress.com/40/" /> <img alt="" border="0" src="http://feeds.wordpress.com/1.0/tags/blognotreally.wordpress.com/40/" /> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/blognotreally.wordpress.com/40/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/blognotreally.wordpress.com/40/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/blognotreally.wordpress.com/40/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/blognotreally.wordpress.com/40/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/blognotreally.wordpress.com/40/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/blognotreally.wordpress.com/40/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/blognotreally.wordpress.com/40/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/blognotreally.wordpress.com/40/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/blognotreally.wordpress.com/40/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/blognotreally.wordpress.com/40/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/blognotreally.wordpress.com/40/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/blognotreally.wordpress.com/40/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/blognotreally.wordpress.com/40/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/blognotreally.wordpress.com/40/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=blog.notreally.org&amp;blog=8911601&amp;post=40&amp;subd=blognotreally&amp;ref=&amp;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://blog.notreally.org/2006/12/04/speeding-up-tracs-response-time/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
	
		<media:content url="http://0.gravatar.com/avatar/e39e820dfad61c10be3c1f2c7f9c2747?s=96&#38;d=identicon&#38;r=G" medium="image">
			<media:title type="html">golan</media:title>
		</media:content>
	</item>
		<item>
		<title>Playing with web services</title>
		<link>http://blog.notreally.org/2006/08/16/playing-with-web-services/</link>
		<comments>http://blog.notreally.org/2006/08/16/playing-with-web-services/#comments</comments>
		<pubDate>Wed, 16 Aug 2006 03:25:14 +0000</pubDate>
		<dc:creator>jroncero</dc:creator>
				<category><![CDATA[Internet]]></category>
		<category><![CDATA[Programming]]></category>
		<category><![CDATA[python]]></category>
		<category><![CDATA[ruby]]></category>
		<category><![CDATA[web]]></category>

		<guid isPermaLink="false">http://blognotreally.wordpress.com/2006/08/16/playing-with-web-services/</guid>
		<description><![CDATA[Some of you may know that I run a website for displaying the temperature in Seville which has many visitors, mainly from Seville. I&#8217;ve run that website since 2001 and it is actually number one when you perform a google search on temperatura en sevilla. I find it quite useful. Eversince I have implemented various [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=blog.notreally.org&amp;blog=8911601&amp;post=34&amp;subd=blognotreally&amp;ref=&amp;feed=1" width="1" height="1" />]]></description>
			<content:encoded><![CDATA[<p>Some of you may know that I run a website for displaying the <a href="http://temp.roncero.org">temperature in Seville</a> which has many visitors, mainly from Seville. I&#8217;ve run that website since 2001 and it is actually number one when you perform a google search on <a href="http://www.google.co.uk/search?q=temperatura+en+sevilla">temperatura en sevilla</a>. I find it quite useful.</p>
<p>Eversince I have implemented various related services, basically playing around in my free time. Some of them are a <a href="http://temp.roncero.org/rss.xml">RSS service</a> and a jabber service (which you can subscribe by adding sevillatemp@jabber.org to your jabber application &#8211; even Gtalk -). There are people that use it on a daily basis and I am glad that they do <img src='http://s.wordpress.com/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> </p>
<p>So, I had this idea in mind since some time, I just wanted to create a web service  so other people could use it on their applications, be it web or desktop application. that would me let me play with webservices and, also, with <a href="http://www.ruby-lang.org">Ruby</a>.</p>
<p>So, I did some coding and implemented something that I would like you to know.</p>
<h3>The web service</h3>
<p>The temperature is read from a couple of sensors from <a href="http://www.dalsemi.com">Dallas Semiconductor</a> using a program called <a href="http://www.digitemp.com">digitemp</a>. It is a unix command line program that is used by a set of shell scripts that create all the fancy graphics you can see at <a href="http://temp.roncero.org">http://temp.roncero.org</a> using <a href="http://oss.oetiker.ch/rrdtool/">rrdtool</a>. These  scripts are executed every five minutes to both insert the data into the database and generate the graphs. The system usually works ok, but it has some flaws, mainly because of old hardware and by the fact that I am living in London and the machine is in Seville.</p>
<p>In order to avoid problems with the actual system, I added a ruby script to the previous shell scripts to generate an XML file that would be later on used by the web service. The file content is</p>
<pre class="brush: plain;">
    1030AC15000800CB
    27.38
    Wed Aug 16 03:00:05 CEST 2006
    Celsius

    10952F1A00080063
    21.44
    Wed Aug 16 03:00:06 CEST 2006
    Celsius
</pre>
<p>This is what I am using to feed the web service. Notice that each of the sensors has a unique serial number and that would be used by the calls to the webservice. I created a small ruby program mapped to the url http://temp.roncero.org/temperature in order to work. There are two different methods now:</p>
<ul>
<li>list_sn* used to discover all the S/N available.</li>
<li>read_temp(sn)* used to read the data from a sensor. *sn* is the serial number of the desired sensor.</li>
</ul>
<h3>Client programs</h3>
<p>So here are two different client little programs that you can use to access the data. One in ruby and another one in python. Very simple, no error check.</p>
<h4>Ruby</h4>
<pre class="brush: ruby;">
#!/usr/bin/env ruby

require 'soap/rpc/driver'
proxy = SOAP::RPC::Driver.new(&quot;http://temp.roncero.org/temperature&quot;,
&quot;http://temp.roncero.org/temperature&quot;)
proxy.add_method('read_temp', 'sn')
proxy.add_method('list_sn')
puts &quot;List S/N: #{proxy.list_sn}&quot;
puts &quot;reading from s/n  1030AC15000800CB&quot;
puts &quot;#{proxy.read_temp(&quot;1030AC15000800CB&quot;)}&quot;
puts &quot;reading from s/n  10952F1A00080063&quot;
puts &quot;#{proxy.read_temp(&quot;10952F1A00080063&quot;)}&quot;
</pre>
<h4>Python</h4>
<pre class="brush: python;">
#!/usr/bin/env python

from SOAPpy import SOAPProxy

url = 'http://temp.roncero.org/temperature'
namespace = 'http://temp.roncero.org/temperature'
server = SOAPProxy(url, namespace)
print &quot;Printing S/N&quot;
server.list_sn()
print &quot;Temperature for 1030AC15000800CB&quot;
print server.read_temp(&quot;1030AC15000800CB&quot;)
print &quot;Temperature for 10952F1A00080063&quot;
print server.read_temp(&quot;10952F1A00080063&quot;)
</pre>
<p>you can test both right now or come up with a new version in another language or improve these ones. Here is a typical output:</p>
<pre class="brush: plain;">
$ ./client.rb
List S/N: 1030AC15000800CB, 10952F1A00080063
reading from s/n  1030AC15000800CB
27.31 degrees at Wed Aug 16 03:20:05 CEST 2006
reading from s/n  10952F1A00080063
21.25 degrees at Wed Aug 16 03:20:06 CEST 2006
</pre>
<h3>So</h3>
<p>Yeah, this is a work-in-progress thing. I have no idea if this is the way to do it.  No <a href="http://en.wikipedia.org/wiki/WSDL">WSDL</a>, not yet. Expect it to fail at some time, as I have yet to implement more error checking, etc.</p>
<p>So, I would like all of you, if you have an opinion on these kind of things, to comment or suggest, say if you would like it to do something different or better.</p>
<p>I have done some assumptions basically because my lack of knowledge on the matter.</p>
<ol>
<li> I have created the webservice using ruby&#8217;s webrick own webserver on a high port and mapping it to an apache url using proxypass directives. Is this the way to do it?</li>
<li> I only created two methods. Would make sense to have more methods? Like one that would only return the temperature value?</li>
</ol>
<p>Have something to say? Go ahead <img src='http://s.wordpress.com/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> </p>
<br /><img alt="" border="0" src="http://feeds.wordpress.com/1.0/categories/blognotreally.wordpress.com/34/" /> <img alt="" border="0" src="http://feeds.wordpress.com/1.0/tags/blognotreally.wordpress.com/34/" /> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/blognotreally.wordpress.com/34/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/blognotreally.wordpress.com/34/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/blognotreally.wordpress.com/34/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/blognotreally.wordpress.com/34/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/blognotreally.wordpress.com/34/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/blognotreally.wordpress.com/34/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/blognotreally.wordpress.com/34/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/blognotreally.wordpress.com/34/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/blognotreally.wordpress.com/34/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/blognotreally.wordpress.com/34/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/blognotreally.wordpress.com/34/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/blognotreally.wordpress.com/34/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/blognotreally.wordpress.com/34/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/blognotreally.wordpress.com/34/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=blog.notreally.org&amp;blog=8911601&amp;post=34&amp;subd=blognotreally&amp;ref=&amp;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://blog.notreally.org/2006/08/16/playing-with-web-services/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
	
		<media:content url="http://0.gravatar.com/avatar/e39e820dfad61c10be3c1f2c7f9c2747?s=96&#38;d=identicon&#38;r=G" medium="image">
			<media:title type="html">golan</media:title>
		</media:content>
	</item>
		<item>
		<title>Creating images on the fly (human verification)</title>
		<link>http://blog.notreally.org/2004/08/05/creating-images-on-the-fly-human-verification/</link>
		<comments>http://blog.notreally.org/2004/08/05/creating-images-on-the-fly-human-verification/#comments</comments>
		<pubDate>Thu, 05 Aug 2004 12:24:00 +0000</pubDate>
		<dc:creator>jroncero</dc:creator>
				<category><![CDATA[Programming]]></category>
		<category><![CDATA[python]]></category>

		<guid isPermaLink="false">http://blognotreally.wordpress.com/2004/08/05/creating-images-on-the-fly-human-verification/</guid>
		<description><![CDATA[Ok, so yesterday I implemented all the logic behind a anti spam system for pybloxsom comments. The only thing missing was the generation of images on the fly, showing the secret number in a way that humans can read it and also making it weird enough to mess an OCR system. So, I spent some [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=blog.notreally.org&amp;blog=8911601&amp;post=5&amp;subd=blognotreally&amp;ref=&amp;feed=1" width="1" height="1" />]]></description>
			<content:encoded><![CDATA[<p>Ok, so yesterday <a href="http://notreally.org/blog/devel/Python/pybloxsomnospam">I<br />
implemented</a>  all the logic behind a anti spam system for pybloxsom<br />
comments. The only thing missing was the generation of images on the<br />
fly, showing the secret number in a way that humans can read it and also<br />
making it weird enough to mess an OCR system.</p>
<p>So, I spent some time investigating PIL, the <a href="http://www.pythonware.com/products/pil/">Python Imaging<br />
Library</a>, a set of python modules to manipulate and create images.</p>
<p>Basically what I do is create an small image using <u>PIL</u>, write the number on it and a small grid in two very close colors (grey). You can<br />
have a look at the result below in this page.</p>
<p>To display the image, I just use a <u>CGI</u> python script that generates this image from the parameter passed to it like this way:</p>
<pre>
&lt;img src="/snumber.png?hash=eef334ab8..." /&gt;</pre>
<p>hash being the filename I was talking about yesterday.</p>
<p>The generation of the image is pretty simple, the code is like:</p>
<pre>
def generateImage(number):
    font = ImageFont.truetype(fontPath, fontSize)
    im = Image.new("RGB", imageSize, bgColor)
    draw = ImageDraw.Draw(im)

    xsize, ysize = im.size

    # Do we want the grid start at 0,0 or want some offset?
    x, y = 1,1

    draw.setink(gridInk)
    while x &lt;= xsize:
        draw.line(((x, 0), (x, ysize)))
        x = x + xstep
    while y &lt;= ysize:
        draw.line(((0, y), (xsize, y)))
        y = y + ystep

    draw.setink(fontInk)
    draw.text((3, 2), number, font=font)

    return im</pre>
<p>which creates the image. The rest of the implementation consist in writing the img to stdout (web) among the <u>HTTP</u> headers.</p>
<p>Well, this is a little hack to do the trick. I believe this code can be further enhaced by, for example, creating a class for generating this<br />
kind of images.</p>
<p>You can find the source code here for <a href="http://roncero.org/src/snumber.py">snumber.png</a>. Just rename it to<br />
a name of your choice and make it execute as an CGI. It should work</p>
<blockquote><p> This and yesterday&#8217;s work are a fast hack to avoid spam. It surely can be enhanced. I intend to do it in the next weeks, when I have free time. Feel free to send comments or tell me if you are using it on your system (and if it works). Suggestion, patches and critics<br />
are welcome <img src='http://s.wordpress.com/wp-includes/images/smilies/icon_wink.gif' alt=';-)' class='wp-smiley' /> </p></blockquote>
<br /><img alt="" border="0" src="http://feeds.wordpress.com/1.0/categories/blognotreally.wordpress.com/5/" /> <img alt="" border="0" src="http://feeds.wordpress.com/1.0/tags/blognotreally.wordpress.com/5/" /> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/blognotreally.wordpress.com/5/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/blognotreally.wordpress.com/5/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/blognotreally.wordpress.com/5/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/blognotreally.wordpress.com/5/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/blognotreally.wordpress.com/5/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/blognotreally.wordpress.com/5/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/blognotreally.wordpress.com/5/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/blognotreally.wordpress.com/5/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/blognotreally.wordpress.com/5/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/blognotreally.wordpress.com/5/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/blognotreally.wordpress.com/5/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/blognotreally.wordpress.com/5/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/blognotreally.wordpress.com/5/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/blognotreally.wordpress.com/5/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=blog.notreally.org&amp;blog=8911601&amp;post=5&amp;subd=blognotreally&amp;ref=&amp;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://blog.notreally.org/2004/08/05/creating-images-on-the-fly-human-verification/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
	
		<media:content url="http://0.gravatar.com/avatar/e39e820dfad61c10be3c1f2c7f9c2747?s=96&#38;d=identicon&#38;r=G" medium="image">
			<media:title type="html">golan</media:title>
		</media:content>
	</item>
		<item>
		<title>Adding human verification to comments</title>
		<link>http://blog.notreally.org/2004/08/04/adding-human-verification-to-comments/</link>
		<comments>http://blog.notreally.org/2004/08/04/adding-human-verification-to-comments/#comments</comments>
		<pubDate>Wed, 04 Aug 2004 01:30:00 +0000</pubDate>
		<dc:creator>jroncero</dc:creator>
				<category><![CDATA[Programming]]></category>
		<category><![CDATA[python]]></category>

		<guid isPermaLink="false"></guid>
		<description><![CDATA[I&#8217;ve been nailed by a bastard spammer for some time at another blog I happen to run in Spanish. What he usually does is try to create hundreds of comments pointing to some kind of crappy web site I don&#8221;t intend to visit at all. All I know is he uses lots of times the [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=blog.notreally.org&amp;blog=8911601&amp;post=3&amp;subd=blognotreally&amp;ref=&amp;feed=1" width="1" height="1" />]]></description>
			<content:encoded><![CDATA[<p>I&#8217;ve been nailed by a bastard spammer for some time at <a href="http://roncero.org/blog"><br />
another blog</a> I happen to run in Spanish. What he usually does is<br />
<em>try</em> to create hundreds of comments pointing to some kind of<br />
crappy web site I don&#8221;t intend to visit at all. All I know is he uses<br />
lots of times the word <em>casino</em> and <em>grants</em>.</p>
<p>Investigating a bit, I learned  he uses the <span style="text-decoration:underline;">UserAgent</span> <em>AIRF</em><br />
string, which happens to be used by this program:<br />
<a href="http://www.roboform.com">roboform</a>, a program for automating<br />
the filling of forms, somehow a paradise for spammers <img src='http://s.wordpress.com/wp-includes/images/smilies/icon_sad.gif' alt=':-(' class='wp-smiley' /> </p>
<p>As It says in the<br />
<a href="http://www.roboform.com/faq.html#faq_airf">FAQ</a>, newer versions<br />
disable the use of that UserAgent string so it makes it virtually<br />
impossible to filter those comments from a web server point of view. My<br />
spammer must also use many open proxies as all the request seem to come<br />
from different IPs. Very annoying.</p>
<p>While thinking about the different possibilities of castration <img src='http://s.wordpress.com/wp-includes/images/smilies/icon_wink.gif' alt=';-)' class='wp-smiley' />  if I<br />
could grab the spammer, I thought I could implement a human verification<br />
process to post comments, the same way<br />
<a href="http://www.gmail.com">gmail</a> and others implement it, using a<br />
distorted image to display a number which you have to manually type in<br />
the form. I am not a very experienced python programmer, so I took it as<br />
an exercise to see what I could come up with. I spent a whole evening<br />
reading part of the pybloxsom code and specially the comments.py<br />
plugin.</p>
<p>So this is what I did to<br />
implement the logic of the verification (I have yet to think about the<br />
generation of the images, or let others do it <img src='http://s.wordpress.com/wp-includes/images/smilies/icon_wink.gif' alt=';-)' class='wp-smiley' /> </p>
<p>I modified the comment-form.html template an added a couple of<br />
variables, like this:</p>
<pre>&lt;input type="hidden" name="hash" value="$hash"&gt;
Secret Number ($snumber):
&lt;input maxlength="5" name="snumber" size="6" type="text" value=""/&gt;</pre>
<p>So, the idea is this one: Each time an entry is displayed, I generate a<br />
text file in a directory readable and writable by the web server<br />
containing inside a random number. The name of the file would be a md5<br />
hash ended by a &#8220;.txt&#8221;. I use this hash in the form to pass it to the<br />
routines in charge of processing the POST action, along with the number<br />
the poster must have typed beforehand (supposedly from the image, not<br />
now at the moment). The POST routine should get the hash from the hash<br />
variable, construct the file name and locate it in the hard disc from<br />
the directory it was written which, by the way, is out of the web tree.<br />
This way, it can retrieve the random number and compare it to what the<br />
user typed. This way, I believe, I can know if it is a bot or a human<br />
behind.</p>
<pre>if form.has_key("title") and form.has_key("author") and form.has_key("body")
    and form.has_key("hash") and form.has_key("snumber"):

    hash = form["hash"].value
    diskHash = getHashNumber(hash)
    try:
        form_snumber = int(form["snumber"].value)
    except ValueError:
        # The user did not enter a number
        form_snumber = -1
    if diskHash == form_snumber:</pre>
<p>This, and a couple of auxiliary functions make all the magic, and it<br />
looks like it works <img src='http://s.wordpress.com/wp-includes/images/smilies/icon_smile.gif' alt=':-)' class='wp-smiley' /> </p>
<p>As I said before, I am not an expert, neither in Python nor http and web<br />
programming and I don&#8221;t know if this approach has severe flaws or not,<br />
if it is a bottle neck or it is just fine (looks like it works to me).<br />
So I would really appreciate your comments on the topic, especially if<br />
this a valid starting point to build a more secure comment system in<br />
pybloxsom.</p>
<p>I believe there are other aspects to work on, like the removal of old<br />
files from the temp directory and the posibility, although highly<br />
unlikely, to have two identical files names. Other is the dynamic<br />
generation of the images. I found some scripts, but in<br />
<a href="http://skriptke.locual.com/hv/es.htm">perl</a> [Sorry, the link<br />
is in Spanish, but you get the idea].</p>
<p>The source code is <a href="http://roncero.org/src/comments.py">here</a>.</p>
<blockquote><p>There is a followup of this article at <a href="http://notreally.org/blog/devel/Python/pybloxsomnospam2"></p>
<p>http://notreally.org/blog/devel/Python/pybloxsomnospam2</a></p></blockquote>
<br /><img alt="" border="0" src="http://feeds.wordpress.com/1.0/categories/blognotreally.wordpress.com/3/" /> <img alt="" border="0" src="http://feeds.wordpress.com/1.0/tags/blognotreally.wordpress.com/3/" /> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/blognotreally.wordpress.com/3/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/blognotreally.wordpress.com/3/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/blognotreally.wordpress.com/3/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/blognotreally.wordpress.com/3/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/blognotreally.wordpress.com/3/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/blognotreally.wordpress.com/3/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/blognotreally.wordpress.com/3/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/blognotreally.wordpress.com/3/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/blognotreally.wordpress.com/3/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/blognotreally.wordpress.com/3/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/blognotreally.wordpress.com/3/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/blognotreally.wordpress.com/3/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/blognotreally.wordpress.com/3/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/blognotreally.wordpress.com/3/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=blog.notreally.org&amp;blog=8911601&amp;post=3&amp;subd=blognotreally&amp;ref=&amp;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://blog.notreally.org/2004/08/04/adding-human-verification-to-comments/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
	
		<media:content url="http://0.gravatar.com/avatar/e39e820dfad61c10be3c1f2c7f9c2747?s=96&#38;d=identicon&#38;r=G" medium="image">
			<media:title type="html">golan</media:title>
		</media:content>
	</item>
	</channel>
</rss>