<?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>AlferSoft Blog &#187; mod_python</title>
	<atom:link href="http://www.alfersoft.com.ar/blog/tag/mod_python/feed/" rel="self" type="application/rss+xml" />
	<link>http://www.alfersoft.com.ar/blog</link>
	<description>Explaining this blog in a few words since 1999</description>
	<lastBuildDate>Wed, 01 Feb 2012 22:36:48 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.3.1</generator>
		<item>
		<title>File Upload Progress with mod_python</title>
		<link>http://www.alfersoft.com.ar/blog/2009/03/28/file-upload-progress-with-mod_python/</link>
		<comments>http://www.alfersoft.com.ar/blog/2009/03/28/file-upload-progress-with-mod_python/#comments</comments>
		<pubDate>Sat, 28 Mar 2009 05:07:42 +0000</pubDate>
		<dc:creator>fvicente</dc:creator>
				<category><![CDATA[Software Development]]></category>
		<category><![CDATA[ajax]]></category>
		<category><![CDATA[files]]></category>
		<category><![CDATA[iframe]]></category>
		<category><![CDATA[javascript]]></category>
		<category><![CDATA[mod_python]]></category>
		<category><![CDATA[progress]]></category>
		<category><![CDATA[progress bar]]></category>
		<category><![CDATA[python]]></category>
		<category><![CDATA[upload]]></category>

		<guid isPermaLink="false">http://www.alfersoft.com.ar/blog/?p=97</guid>
		<description><![CDATA[Now that Gmail has added a progress bar for attachment uploads, everybody wants to do the same including myself So, with the same method that everybody uses consisting in an upload form with a hidden &#60;iframe&#62; as target, and then a periodic Ajax request to update the progress, I made a simple implementation using mod_python [...]]]></description>
			<content:encoded><![CDATA[<div class="wp-caption alignnone" style="width: 451px"><img title="Upload Progress with mod_python" src="http://www.alfersoft.com.ar/files/uprogress.jpg" alt="Upload Progress with mod_python" width="441" height="216" /><p class="wp-caption-text">Upload Progress with mod_python</p></div>
<p>Now that Gmail has added a progress bar for attachment uploads, everybody wants to do the same including myself <img src='http://www.alfersoft.com.ar/blog/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /><br />
So, with the same method that everybody uses consisting in an upload form with a hidden  &lt;iframe&gt; as target, and then a periodic Ajax request to update the progress, I made a simple implementation using mod_python on the server side&#8230; This is a veeery simple example, like everything that you do with Python.<br />
Additionally I&#8217;ve added an upload size limit control based in examples that can be found in the mod_python forum site. Use the source Luke!</p>
<p>See <a title="Upload Progress Demo" href="http://www.alfersoft.com.ar/uprogress/" target="_blank">LIVE DEMO!</a></p>
<p><span id="more-97"></span></p>
<h2>Libraries that I used for this example</h2>
<p>The fancy JavaScript progress bar is from <a title="Bramus!" href="http://www.bram.us/" target="_blank">Bramus</a>, I just changed the default options, renamed the main script file to progressbar.js and the images just because I like everything in lower case. See the copyright inside the file or visit the site for more information.</p>
<p><a title="Prototype.js" href="http://www.prototypejs.org/" target="_blank">Prototype.js</a>: this well known library to avoid cross-browser compatibility issues, is small and practical. I use it in almost all my web projects. Also Bramus requires this library. If you don&#8217;t like it for some reason you will need to replace many many many functions like $() which is an improved getElementById(), or the Hash class that I use to track in-progress uploads, JSON encoding, etc. etc. You don&#8217;t want to remove it, seriously.</p>
<p><a title="simplejson" href="http://code.google.com/p/simplejson/" target="_blank">simplejson</a>: A python library to encode/decode JSON objects. I use this one for the messaging between the server and the page. In my opinion JSON is more efficient than XML because it generates more compact and still human-readable outputs. But you can use XML or any other method by modifying the example as you like.</p>
<h2>Download example</h2>
<p>Start by downloading the <a title="Source code for uprogress example" href="http://www.alfersoft.com.ar/files/uprogress.zip" target="_blank">source code for this example</a>. I decided to release the code under BSD license, so you can use it for whatever you want.</p>
<p>The source is organized like the following illustration:</p>
<div class="wp-caption alignnone" style="width: 382px"><img title="Upload Progress source directory structure" src="http://www.alfersoft.com.ar/files/uprogress_src.jpg" alt="Upload Progress source directory structure" width="372" height="360" /><p class="wp-caption-text">Upload Progress source directory structure</p></div>
<p>/src/img: contains images for JavaScript Bramus progress bar</p>
<p>/src/js: contains JavaScript libraries Prototype.js and Bramus progress bar that I renamed to progressbar.js</p>
<p>/src/temp: directory where the uploaded files will be stored. IMPORTANT: in unix like environments the group and permission of this folder must be configured properly in order to Apache to have write access on it.</p>
<p>/src/_upload_limit.py: mod_python fixup handler that controls the file upload size limit, verifies if the file already exist in the server, stores file size and location information on the session and does the actual file upload after all the verifications.</p>
<p>/src/index.py: The main python publisher handler. Exposed URLs are the main / &#8220;index&#8221; page that loads the test.html and /get_upload_progress function that returns the current % progress of the files being uploaded.</p>
<p>/src/test.html: HTML page that contains all the JavaScript code used to create the upload forms, post the files, track the progress via Ajax, update the progress bar status, etc&#8230; This file is parsed by index.py as a PSP but does not contains any embedded python code currently.</p>
<p>/lib/simplejson: simplejson python library to encode / decode JSON messages.</p>
<h2>Configuring Apache</h2>
<p>I&#8217;m assuming that you already have mod_python installed on your Apache. Take a look to the sample configuration:</p>
<pre>Alias / "/Users/fvicente/workspace/uprogress/src/"
&lt;Directory "/Users/fvicente/workspace/uprogress/src/"&gt;
    SetHandler python-program
    PythonHandler mod_python.publisher
    PythonDebug On
    PythonFixupHandler _upload_limit
    &lt;Files ~ "\.(gif|jpg|png|ico|js|css)$"&gt;
        SetHandler default-handler
    &lt;/Files&gt;
    Order allow,deny
    Allow from all
&lt;/Directory&gt;</pre>
<p>mod_python manual has a lot of information about the configuration options, so I&#8217;m not going to describe this in too much depth, just remark that I&#8217;m using the very useful mod_python publisher, and more &#8220;unusual&#8221; option PythonFixupHandler pointing to the _upload_limit.py file.</p>
<h2>Interesting parts of the code</h2>
<p>_upload_limit.py</p>
<p>The fixuphandler function contained in this file does the checking for the size limit of the file being uploaded by reading the http header Content-Length sent by the browser  allowing you to reject an upload even before starting the actual transfer&#8230; very clever!. I found _upload_limit.py <a title="mod_python forum example" href="http://www.modpython.org/pipermail/mod_python/2007-February/023158.html" target="_blank">example in the mod_python forum</a>, and used it as a based adding the specific code for the upload progress handling. _upload_limit.py also stores the file size and name in the current session to be used later by the get_upload_progress function defined in index.py. Note that every time that the Session is used it will be accessed with the option lock=False thus using the session.lock() and session.unlock() methods manually when necessary, if you don&#8217;t do this that way all the parallel requests will be held until the upload finishes making impossible to monitor the progress via parallel Ajax request.</p>
<p>index.py</p>
<p>The exposed function get_upload_progress calculates the current upload percent by making a file-stat to see how much of the file has been stored so far. It is requested by the page test.html via Ajax in intervals of one seconds while the file is being uploaded. The expected parameter is a dictionary where the keys are &#8220;upload slots&#8221; that the JavaScript generates and understand, and the values are the name of the files to get the upload percent.</p>
<p>test.html</p>
<p>This one is 90% JavaScript code. But is not so bad, only 100 lines of code. In a very brief description you will see 4 functions:</p>
<p>addUploadSlot(): creates an HTML code dynamically with an &#8220;upload slot&#8221; which is a form with the file to upload, the hidden &lt;iframe&gt; that is the form target, the progress bar control, and the &#8220;Upload&#8221; button. It uses a global counter called slotCnt to give a unique id to each slot. This id will be the &#8220;key&#8221; in the get_upload_progress dictionary (see index.py description).</p>
<p>sendFile(slot): shows the progress bar for given slot, adds the file into a global Hash() table called &#8220;uploading&#8221;, starts the periodic Ajax progress monitor (I used JavaScript function setInterval() to do the periodic Ajax) and sends the form to the server. Finally it will disable the controls for that slot and add a new slot dynamically for other uploads.</p>
<p>updateProgressBars(): This is the function called by setInterval() while the files are uploading that does the actual Ajax.Request to /get_upload_progress in order to get the % progress for each file. The parameter sent with the request is a dictionary where the keys are the slots Id&#8217;s and the values the file names stored in the hash table.</p>
<p>uploadDone(slot): Will be called by the &lt;iframe&gt; when the upload finishes (successfully or not). Here I remove the file from the hash and stop the interval if no longer necessary.</p>
<h2>Final comments</h2>
<p>Remember that this is just an example and may contain errors. Use it at your own risk, I&#8217;m not responsable of any possible damage or data lost, blah, blah, etc. etc. etc.</p>
<p>The code is poorly commented, but at least is well formatted <img src='http://www.alfersoft.com.ar/blog/wp-includes/images/smilies/icon_biggrin.gif' alt=':D' class='wp-smiley' /> . I recommend you to read it, it is very short and you may find interesting chunks.</p>
<p>Enjoy it!</p>
]]></content:encoded>
			<wfw:commentRss>http://www.alfersoft.com.ar/blog/2009/03/28/file-upload-progress-with-mod_python/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>MacOS X 10.5.x (Intel) + mod_python + PIL + PyCAPTCHA notes</title>
		<link>http://www.alfersoft.com.ar/blog/2009/03/03/macos-x-105x-intel-mod_python-pil-pycaptcha-notes/</link>
		<comments>http://www.alfersoft.com.ar/blog/2009/03/03/macos-x-105x-intel-mod_python-pil-pycaptcha-notes/#comments</comments>
		<pubDate>Wed, 04 Mar 2009 02:04:10 +0000</pubDate>
		<dc:creator>fvicente</dc:creator>
				<category><![CDATA[Software Development]]></category>
		<category><![CDATA[freetype2]]></category>
		<category><![CDATA[intel]]></category>
		<category><![CDATA[leopard]]></category>
		<category><![CDATA[libjpeg]]></category>
		<category><![CDATA[macosx]]></category>
		<category><![CDATA[mod_python]]></category>
		<category><![CDATA[pil]]></category>
		<category><![CDATA[pycaptcha]]></category>
		<category><![CDATA[python]]></category>

		<guid isPermaLink="false">http://www.alfersoft.com.ar/blog/?p=89</guid>
		<description><![CDATA[If you have a Mac OS X Leopard on an Intel platform, and you are interested in installing mod_python using your default apache setup and the python that comes with the Framework, even more if you want to give PyCAPTCHA a try together with mod_python, then check out this post! I&#8217;m covering also the installation [...]]]></description>
			<content:encoded><![CDATA[<p><img class="alignnone" title="Python" src="http://www.alfersoft.com.ar/files/python.jpg" alt="" width="300" height="225" /></p>
<p>If you have a Mac OS X Leopard on an Intel platform, and you are interested in installing mod_python using your default apache setup and the python that comes with the Framework, even more if you want to give PyCAPTCHA a try together with mod_python, then check out this post! I&#8217;m covering also the installation of required libraries for PyCAPTCHA under Leopard (FreeType2, libjpeg, PIL)</p>
<p><span id="more-89"></span></p>
<h2><strong>mod_python</strong></h2>
<p><span style="text-decoration: underline;">Compile mod_python</span></p>
<p>If you have Apple&#8217;s Xcode installed, compiling mod_python for Leopard to use with the system provided versions of httpd, python, etc. should be as simple as running these commands:</p>
<p><code><br />
$ mkdir -p ~/mod_python<br />
$ cd ~/mod_python<br />
$ svn co http://svn.apache.org/repos/asf/quetzalcoatl/mod_python/trunk mod_python-trunk<br />
$ cd mod_python-trunk<br />
$ ./configure --with-apxs=/usr/sbin/apxs<br />
$ make<br />
$ sudo make install<br />
$ cd test/<br />
$ python test.py</code></p>
<p>(original source: http://www.modpython.org/pipermail/mod_python/2008-March/025012.html)</p>
<p><span style="text-decoration: underline;">Configure Apache to load mod_python</span></p>
<p>Open /private/etc/apache2/httpd.conf with your favorite editor and add the following line:</p>
<p><code><br />
LoadModule python_module libexec/apache2/mod_python.so<br />
</code></p>
<p><span style="text-decoration: underline;">Example of how to configure Apache to load a mod_python application</span></p>
<p>This is just an example, I recommend reading the <a title="mod_python manual" href="http://www.modpython.org/live/current/doc-html/" target="_blank">mod_python manual</a> for more information.</p>
<p>Open /private/etc/apache2/users/<em>username</em>.conf with your favorite editor and add:</p>
<pre>Alias / "/Users/<em>username</em>/<em>htdocs</em>/"
&lt;Directory "/Users/<em>username</em>/<em>htdocs</em>/"&gt;
    SetHandler python-program
    PythonHandler mod_python.publisher
    # Disable following line when in production
    PythonDebug On
    &lt;Files ~ "\.(gif|jpg|png|ico|js|css)$"&gt;
        SetHandler default-handler
    &lt;/Files&gt;
    Order allow,deny
    Allow from all
&lt;/Directory&gt;</pre>
<p><span style="text-decoration: underline;">Restart Apache with the command below:</span></p>
<pre>$ /usr/sbin/apachectl restart</pre>
<p><br/></p>
<h2>PyCAPTCHA</h2>
<p>In order to build and install PyCAPTCHA you&#8217;ll need to compile, or make sure that you have these required libraries:</p>
<ul>
<li>FreeType2</li>
<li>libjpeg</li>
<li>PIL (Python Imaging Library)</li>
</ul>
<p>Let&#8217;s see how to set up these libraries under a Leopard / Intel environment.<br />
<br/></p>
<h2>FreeType2</h2>
<p>This library is required for PyCAPTCHA, as far as I know it is already installed with the SDK, to check the directory where the library is installed use the command:</p>
<p><code>$ locate libfreetype.dylib</code></p>
<p>A version of this library should appear under /Developer/SDKs/MacOSX10.5.sdk/usr/X11/<br />
<br/></p>
<h2>libjpeg</h2>
<p>Download <a title="libjpeg" href="http://www.ijg.org/" target="_blank">jpeg source</a> and uncompress it in any directory, e.g. ~/jpeg-6b then:</p>
<p><code><br />
$ cd ~/jpeg-6b<br />
$ chmod -R 777 *<br />
$ ./configure<br />
</code></p>
<p>Edit Makefile and change the following line from:</p>
<pre>    CFLAGS= -O2 -I$(srcdir)</pre>
<p>to:</p>
<pre>    CFLAGS= -arch ppc -arch i386 -arch ppc64 -arch x86_64 -O2 -I$(srcdir)</pre>
<p>Finally, build and install:<br />
<code><br />
$ make<br />
$ sudo make install-lib</code><br />
<br/></p>
<h2>PIL</h2>
<p>Download <a title="PIL source" href="http://www.pythonware.com/products/pil/" target="_blank">PIL source</a> and uncompress it in any directory, e.g. ~/imaging-1.1.6 then:</p>
<p><code><br />
$ cd ~/imaging-1.1.6<br />
</code></p>
<p>Edit setup.py and change the following lines from:</p>
<pre>    FREETYPE_ROOT = None</pre>
<p>to (note that I&#8217;m using the FreeType2 directory discovered previously with the locate command):</p>
<pre>    FREETYPE_ROOT = libinclude("/Developer/SDKs/MacOSX10.5.sdk/usr/X11/")</pre>
<p>and then following line from:</p>
<pre>    JPEG_ROOT = None</pre>
<p>to:</p>
<pre>    JPEG_ROOT = libinclude("/usr/local")</pre>
<p>Locate these lines:<code><br />
from distutils import sysconfig<br />
from distutils.core import Extension, setup<br />
from distutils.command.build_ext import build_ext<br />
</code><br />
And add the following lines (correctly indented from column 0):</p>
<pre>OrigExtension = Extension
def Extension(*args, **kwargs):
    extra_args = ['-arch', 'ppc', '-arch', 'ppc64', '-arch', 'i386', '-arch', 'x86_64']
    kwargs['extra_compile_args'] = extra_args + kwargs.get('extra_compile_args', [])
    kwargs['extra_link_args'] = extra_args + kwargs.get('extra_link_args', [])
    return OrigExtension(*args, **kwargs)</pre>
<p>Now proceed to compile and install the library:<br />
<code><br />
$ sudo python setup.py install</code><br />
<br/></p>
<h2>Install PyCAPTCHA</h2>
<p>Now you are ready to  build and install PyCAPTCHA. Checkout the source code from <a title="PyCAPTCHA" href="http://svn.navi.cx/misc/trunk/pycaptcha/" target="_blank">this link</a> and run the following command:<br />
<code><br />
$ sudo python setup.py install</code></p>
<p>That&#8217;s it!</p>
<h6><a title="Python" href="http://commons.wikimedia.org/wiki/File:Boomslang_(443113819).jpg" target="_blank">image source</a></h6>
]]></content:encoded>
			<wfw:commentRss>http://www.alfersoft.com.ar/blog/2009/03/03/macos-x-105x-intel-mod_python-pil-pycaptcha-notes/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>

