<?xml version='1.0' encoding='UTF-8'?><?xml-stylesheet href="http://www.blogger.com/styles/atom.css" type="text/css"?><feed xmlns='http://www.w3.org/2005/Atom' xmlns:openSearch='http://a9.com/-/spec/opensearchrss/1.0/' xmlns:georss='http://www.georss.org/georss' xmlns:gd='http://schemas.google.com/g/2005' xmlns:thr='http://purl.org/syndication/thread/1.0'><id>tag:blogger.com,1999:blog-19662631</id><updated>2012-02-16T06:52:40.413Z</updated><category term='Learning Log'/><category term='django'/><category term='links'/><category term='wsgi'/><category term='Project: WebExport'/><category term='MPI'/><category term='notes'/><category term='Quick hacks'/><title type='text'>The constant buzz</title><subtitle type='html'>Snippets from my daily learning, copy-pasting, mindless scribbling, and... stuff</subtitle><link rel='http://schemas.google.com/g/2005#feed' type='application/atom+xml' href='http://caffeinoverdose.blogspot.com/feeds/posts/default'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/19662631/posts/default?max-results=100'/><link rel='alternate' type='text/html' href='http://caffeinoverdose.blogspot.com/'/><link rel='hub' href='http://pubsubhubbub.appspot.com/'/><author><name>shawnchin</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='23' height='32' src='http://static.flickr.com/29/49747509_6a5618aced_t.jpg'/></author><generator version='7.00' uri='http://www.blogger.com'>Blogger</generator><openSearch:totalResults>8</openSearch:totalResults><openSearch:startIndex>1</openSearch:startIndex><openSearch:itemsPerPage>100</openSearch:itemsPerPage><entry><id>tag:blogger.com,1999:blog-19662631.post-1026081128690859656</id><published>2010-07-27T13:29:00.008Z</published><updated>2010-07-27T20:39:36.925Z</updated><category scheme='http://www.blogger.com/atom/ns#' term='notes'/><category scheme='http://www.blogger.com/atom/ns#' term='wsgi'/><category scheme='http://www.blogger.com/atom/ns#' term='django'/><title type='text'>Hosting Django projects on a subURL in Apache with mod_wsgi</title><content type='html'>Here are some rough notes on hosting django apps on a subURL, i.e. &lt;span style="font-stye:italic;"&gt;/somepath&lt;/span&gt; instead of &lt;span style="font-style:italic;"&gt;/&lt;/span&gt;. (this is a note to self, really).&lt;br /&gt;&lt;br /&gt;In apache config, alias media dirs (and admin-media if required)&lt;br /&gt;&lt;code&gt;&lt;pre&gt;&lt;br /&gt;Alias /suburl/media /home/projects/django/project/media/&lt;br /&gt;&amp;lt;Directory /home/projects/django/project/media/&amp;gt;&lt;br /&gt;    Order deny,allow&lt;br /&gt;    Allow from all&lt;br /&gt;&amp;lt;/Directory&amp;gt;&lt;br /&gt;WSGIScriptAlias /suburl /home/projects/django/project/project.wsgi&lt;br /&gt;&lt;/pre&gt;&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;We also need some mod_rewrite magic to solve &lt;a href='http://stackoverflow.com/questions/2519519'&gt;this&lt;/a&gt; problem. In short, if users access /suburl instead of /suburl/, reverse urls will fail (sent to /some/path instead of /suburl/some/path)&lt;br /&gt;&lt;br /&gt;&lt;code&gt;&lt;pre&gt;&lt;br /&gt;RewriteEngine On&lt;br /&gt;RewriteRule ^/suburl$ /suburl/ [R]&lt;br /&gt;&lt;/pre&gt;&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;In settings.py, we'll need to manually append url prefix to MEDIA_URL, ADMIN_MEDIA_PREFIX, and if you need it, LOGIN_URL&lt;br /&gt;&lt;code&gt;&lt;pre&gt;&lt;br /&gt;WEB_PREFIX = '/suburl'&lt;br /&gt;MEDIA_URL = WEB_PREFIX + '/media'&lt;br /&gt;ADMIN_MEDIA_PREFIX = MEDIA_URL + '/admin-media'&lt;br /&gt;LOGIN_URL = WEB_PREFIX + '/accounts/login'&lt;br /&gt;&lt;/pre&gt;&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;Finally, if you're using django.contrib.auth, it is important that you override SESSION_COOKIE_* vars in settings.py or authentication in Google Chrome will fail if you host multiple django projects within the same VirtualHost. (Well, it failed at the time of writing anyway).&lt;br /&gt;&lt;code&gt;&lt;pre&gt;&lt;br /&gt;SESSION_COOKIE_PATH = WEB_PREFIX&lt;br /&gt;SESSION_COOKIE_NAME = WEB_PREFIX.replace('/','_') + 'sessionid'&lt;br /&gt;&lt;/pre&gt;&lt;/code&gt;&lt;br /&gt;N.B. In your Sites entry in DB, you still want the entry to be http://your.domain, not http://your.domain/suburl&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/19662631-1026081128690859656?l=caffeinoverdose.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://caffeinoverdose.blogspot.com/feeds/1026081128690859656/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=19662631&amp;postID=1026081128690859656' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/19662631/posts/default/1026081128690859656'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/19662631/posts/default/1026081128690859656'/><link rel='alternate' type='text/html' href='http://caffeinoverdose.blogspot.com/2010/07/hosting-django-projects-on-suburl-in.html' title='Hosting Django projects on a subURL in Apache with mod_wsgi'/><author><name>shawnchin</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='23' height='32' src='http://static.flickr.com/29/49747509_6a5618aced_t.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-19662631.post-1218382765568074042</id><published>2008-01-16T09:48:00.000Z</published><updated>2008-01-16T09:50:36.799Z</updated><category scheme='http://www.blogger.com/atom/ns#' term='MPI'/><title type='text'>Obscure bug</title><content type='html'>This lil' MPI program will get its knickers in a twist when run using MPICH. Why? Take a guess.&lt;br /&gt;&lt;br /&gt;&lt;code&gt;&lt;pre&gt;&lt;br /&gt;#include &amp;lt;mpi.h&amp;gt;&lt;br /&gt;&lt;br /&gt;void shutdown() {&lt;br /&gt;    MPI_Finalize();&lt;br /&gt;    exit(0);&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;int main (int argc, char ** argv) {&lt;br /&gt;    int w_rank, w_size;&lt;br /&gt;&lt;br /&gt;    /* Initialise MPI environment */&lt;br /&gt;    MPI_Init(&amp;argc, &amp;argv);&lt;br /&gt;    MPI_Comm_size(MPI_COMM_WORLD, &amp;w_size);&lt;br /&gt;    MPI_Comm_rank(MPI_COMM_WORLD, &amp;w_rank);&lt;br /&gt;&lt;br /&gt;    /* For some reason, we MUST use only 2 procs */&lt;br /&gt;    if (w_size != 2)&lt;br /&gt;    {&lt;br /&gt;        printf("Sorry mate, use only 2 procs\n");&lt;br /&gt;        shutdown();&lt;br /&gt;    }&lt;br /&gt;&lt;br /&gt;    /* Do stuff ... */&lt;br /&gt;    printf("Proc %d of %d\n", w_rank, w_size);&lt;br /&gt;&lt;br /&gt;    /* Finalise MPI environment */&lt;br /&gt;    shutdown();&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;&lt;/pre&gt;&lt;/code&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/19662631-1218382765568074042?l=caffeinoverdose.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://caffeinoverdose.blogspot.com/feeds/1218382765568074042/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=19662631&amp;postID=1218382765568074042' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/19662631/posts/default/1218382765568074042'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/19662631/posts/default/1218382765568074042'/><link rel='alternate' type='text/html' href='http://caffeinoverdose.blogspot.com/2008/01/obscure-bug.html' title='Obscure bug'/><author><name>shawnchin</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='23' height='32' src='http://static.flickr.com/29/49747509_6a5618aced_t.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-19662631.post-627697253054890181</id><published>2007-04-18T08:37:00.000Z</published><updated>2007-04-18T08:40:34.819Z</updated><category scheme='http://www.blogger.com/atom/ns#' term='links'/><title type='text'>Development of the C Language</title><content type='html'>&lt;a href="http://cm.bell-labs.com/cm/cs/who/dmr/chist.html"&gt;The Development of the C Language&lt;/a&gt;, by Dennis M. Ritchie&lt;br /&gt;&lt;br /&gt;From the abstract:&lt;br /&gt;&lt;blockquote&gt;&lt;i&gt;"The C programming language was devised in the early 1970s as a system implementation language for the nascent Unix operating system. Derived from the typeless language BCPL, it evolved a type structure; created on a tiny machine as a tool to improve a meager programming environment, it has become one of the dominant languages of today. This paper studies its evolution."&lt;/i&gt;&lt;/blockquote&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/19662631-627697253054890181?l=caffeinoverdose.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://caffeinoverdose.blogspot.com/feeds/627697253054890181/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=19662631&amp;postID=627697253054890181' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/19662631/posts/default/627697253054890181'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/19662631/posts/default/627697253054890181'/><link rel='alternate' type='text/html' href='http://caffeinoverdose.blogspot.com/2007/04/development-of-c-language.html' title='Development of the C Language'/><author><name>shawnchin</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='23' height='32' src='http://static.flickr.com/29/49747509_6a5618aced_t.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-19662631.post-349143677189650991</id><published>2007-03-28T16:24:00.000Z</published><updated>2007-03-28T17:17:44.201Z</updated><category scheme='http://www.blogger.com/atom/ns#' term='Quick hacks'/><title type='text'>Exporting selected mails from Evolution</title><content type='html'>Had an &lt;i&gt;impromptu&lt;/i&gt; need to export different selections of emails from &lt;a href="http://www.gnome.org/projects/evolution/"&gt;Evolution&lt;/a&gt; onto the web. &lt;br /&gt;&lt;br /&gt;A brief (read: impatient) googling did not reveal any pre-existing solutions, so a quick hack was in order. &lt;br /&gt;&lt;br /&gt;Digging around the &lt;tt&gt;~/.evolution&lt;/tt&gt; directory, I noted that local Evolution foldes are store in &lt;tt&gt;~/evolution/mail/local/&amp;lt;folder_name&amp;gt;&lt;/tt&gt; as flat files which looks suspiciously like the &lt;tt&gt;mbox&lt;/tt&gt; format. That looks like a good start.&lt;br /&gt;&lt;br /&gt;Searching for "&lt;a href="http://www.google.co.uk/search?q=mbox+to+HTML"&gt;mbox to HMTL&lt;/a&gt;", I was lead to &lt;a href="http://sourceforge.net/projects/hypermail/"&gt;hypermail&lt;/a&gt;.&lt;br /&gt;&lt;blockquote&gt;Hypermail is a program that takes a file of mail messages in UNIX mailbox format and generates a set of cross-referenced HTML documents. Each file that is created represents a separate message in the mail archive and contains links to other articles, so that the entire archive can be browsed in a number of ways by following links. Archives generated by Hypermail can be incrementally updated, and Hypermail is set by default to only update archives when changes are detected.&lt;/blockquote&gt;&lt;br /&gt;A quick solution was now obvious:&lt;br /&gt;&lt;br /&gt;1. Install hypermail&lt;br /&gt;2. Copy selected emails to a new&lt;sup&gt;&lt;a href="#1"&gt;1&lt;/a&gt;&lt;/sup&gt; local folder, say &lt;i&gt;"hypermail_temp"&lt;/i&gt;&lt;br /&gt;3. Run hypermail&lt;br /&gt;&lt;tt&gt;cat ~/.evolution/mail/local/hypermail_temp | hypermail -i -l "Title of Export" -d output_dir&lt;/tt&gt;&lt;br /&gt;&lt;br /&gt;The output produced by hypermail was exactly what I needed. Sortable by thread, author, date, subject, and attachment (&lt;a href="http://www.hypermail-project.org/archive/06/index.html"&gt;Example output&lt;/a&gt;).&lt;br /&gt;&lt;br /&gt;&lt;i&gt;&lt;sup&gt;&lt;a name="1"&gt;1&lt;/a&gt;&lt;/sup&gt;[Note: mails deleted from within Evolution (which are sent to trash) will still remain the flat file and would thus also appear in the output of hypermail. Therefore, if running hypermail on an existing folder, you might want to Expunge (ctrl-e) the folder beforehand to ensure deleted mails do not appear]&lt;/i&gt;&lt;br /&gt;&lt;hr /&gt;&lt;br /&gt;Ideally, cooking up a tool based on the &lt;a href="http://www.gnome.org/projects/evolution/eplugins.shtml"&gt;Eplugin&lt;/a&gt; system would have be really neat. Alas, investing too much time on a one-off requirement is just not practical. Maybe next time.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/19662631-349143677189650991?l=caffeinoverdose.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://caffeinoverdose.blogspot.com/feeds/349143677189650991/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=19662631&amp;postID=349143677189650991' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/19662631/posts/default/349143677189650991'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/19662631/posts/default/349143677189650991'/><link rel='alternate' type='text/html' href='http://caffeinoverdose.blogspot.com/2007/03/exporting-selected-mails-from-evolution.html' title='Exporting selected mails from Evolution'/><author><name>shawnchin</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='23' height='32' src='http://static.flickr.com/29/49747509_6a5618aced_t.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-19662631.post-4292735026922550221</id><published>2007-02-28T18:15:00.000Z</published><updated>2007-02-28T18:43:00.560Z</updated><category scheme='http://www.blogger.com/atom/ns#' term='Project: WebExport'/><title type='text'>WebExport: It's Alive!!</title><content type='html'>The &lt;tt&gt;ResourceSubscription&lt;/tt&gt; and &lt;tt&gt;ResourcePublished&lt;/tt&gt; classes from &lt;a href="http://twistedmatrix.com/documents/current/api/twisted.web.distrib.html"&gt;twisted.web.distrib&lt;/a&gt;  made life a lot easier. &lt;br /&gt;&lt;br /&gt;WebExport clients publish the directories via &lt;tt&gt;ResourcePublished&lt;/tt&gt;, and connects to the server to announce its existence. Upon successful registration, the server associates a &lt;tt&gt;ResourceSubscription&lt;/tt&gt; to the web root on a random path, and informs the client of where the web view is published.&lt;br /&gt;&lt;pre&gt;&lt;tt&gt;&lt;br /&gt;[lsc@home ~]$ webexport ./web/files&lt;br /&gt;View exported to http://external.domain:8888/17785&lt;br /&gt;&lt;/tt&gt;&lt;/pre&gt;&lt;br /&gt;When client disconnects, the &lt;tt&gt;ResourceSubscription&lt;/tt&gt; is destroyed and the path removed from the web root.&lt;br /&gt;&lt;br /&gt;WebExport server is started by root, gets daemonised, and sheds it's priviledges to &lt;i&gt;nobody:nobody&lt;/i&gt;. It listens to two ports, one for web requests and the another for webexport clients.&lt;br /&gt;&lt;br /&gt;Not bad of half a day's work :)&lt;br /&gt;Lines of code: ~120 :p&lt;br /&gt;&lt;br /&gt;More info to come. Time to rush for the last bus home!!!&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/19662631-4292735026922550221?l=caffeinoverdose.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://caffeinoverdose.blogspot.com/feeds/4292735026922550221/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=19662631&amp;postID=4292735026922550221' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/19662631/posts/default/4292735026922550221'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/19662631/posts/default/4292735026922550221'/><link rel='alternate' type='text/html' href='http://caffeinoverdose.blogspot.com/2007/02/webexport-its-alive.html' title='WebExport: It&apos;s Alive!!'/><author><name>shawnchin</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='23' height='32' src='http://static.flickr.com/29/49747509_6a5618aced_t.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-19662631.post-4153114267753565830</id><published>2007-02-27T15:16:00.000Z</published><updated>2007-02-27T18:38:30.944Z</updated><category scheme='http://www.blogger.com/atom/ns#' term='Project: WebExport'/><title type='text'>WebExport: Using Twisted</title><content type='html'>&lt;a href="http://www.jaychin.net"&gt;Jay&lt;/a&gt; directed my attention to &lt;a href=""http://twistedmatrix.com/trac/&gt;Twisted&lt;/a&gt;.&lt;a href="http://twistedmatrix.com/projects/web/documentation/howto/web-overview.html"&gt;web&lt;/a&gt;.&lt;br /&gt;&lt;blockquote&gt;Twisted is a networking engine written in Python, supporting numerous protocols. It contains a web server, numerous chat clients, chat servers, mail servers, and more. Twisted is made up of a number of sub-projects which can be accessed individually through the &lt;a href="http://twistedmatrix.com/trac/wiki/TwistedProjects"&gt;twisted projects index&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;&lt;a href="http://twistedmatrix.com/trac/wiki/TwistedWeb"&gt;Twisted Web&lt;/a&gt; is a web application server written in pure Python, with APIs at multiple levels of abstraction to facilitate different kinds of web programming. ... [It] provides a simple, stable resource publishing API, on top of an HTTP/1.0 server implementation with some HTTP/1.1 features.&lt;/blockquote&gt;&lt;br /&gt;Publishing an arbitrary web directory was a breeze using the preconfigured web server. I just had to create a &lt;i&gt;web.tap&lt;/i&gt; file, and start the server:&lt;br /&gt;&lt;pre&gt;&lt;tt&gt;[lsc@home ~]$ mktap web --path /path/to/web/dir&lt;br /&gt;[lsc@home ~]$ twistd -f web.tab&lt;/pre&gt;&lt;/tt&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://bp1.blogger.com/__r2FteFskoo/ReRZgLib6mI/AAAAAAAAACU/qG7y7bcFPDI/s1600-h/l8080.jpg"&gt;&lt;img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;" src="http://bp1.blogger.com/__r2FteFskoo/ReRZgLib6mI/AAAAAAAAACU/qG7y7bcFPDI/s400/l8080.jpg" border="0" alt=""id="BLOGGER_PHOTO_ID_5036248692694968930" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;While this does not yet meet the requirements of my intended project, &lt;i&gt;Twisted&lt;/i&gt; has caught my attention.&lt;br /&gt;&lt;br /&gt;Glancing through the &lt;a href="http://twistedmatrix.com/projects/core/documentation/howto/index.html"&gt;HOWTO&lt;/a&gt;s, I was thrilled by the rich set of APIs that made network application programming a breeze (really?). Apart from the core which provides utilities for asynchronous network programming, authentication, DB interfaces, unit testion, etc, there's a host of sub &lt;a href="http://twistedmatrix.com/trac/wiki/TwistedProjects"&gt;projects&lt;/a&gt; which provide convenient protocol implementations for Web, SSH, Mail, IRC/IM, DNS, and such.&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;code&gt;&lt;b&gt;&lt;i&gt;# Within a few minutes, I had my first 'server' running&lt;/i&gt;&lt;/b&gt;&lt;br /&gt;from twisted.internet import protocol, reactor&lt;br /&gt;from twisted.protocols import basic&lt;br /&gt;from sys import stdout&lt;br /&gt;&lt;br /&gt;class ParrotProtocol(basic.LineReceiver):&lt;br /&gt;    def connectionMade(self):&lt;br /&gt;        stdout.write("Polly found a friend\r\n")&lt;br /&gt;        self.sendLine("Polly wants a cracker")&lt;br /&gt;    def lineReceived(self, line):&lt;br /&gt;        if line == "cracker":&lt;br /&gt;            self.sendLine("Thank you!")&lt;br /&gt;            self.transport.loseConnection()&lt;br /&gt;        else:&lt;br /&gt;            self.sendLine("Aark!! %s" % (line))&lt;br /&gt;    def connectionLost(self, reason):&lt;br /&gt;        stdout.write("Polly lost a friend\r\n")&lt;br /&gt;        self.sendLine("Bye bye!")&lt;br /&gt;#/end class ParrotProtocol&lt;br /&gt;&lt;br /&gt;f = protocol.Factory()&lt;br /&gt;f.protocol = ParrotProtocol&lt;br /&gt;reactor.listenTCP(8888, f)&lt;br /&gt;reactor.run()&lt;br /&gt;&lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;Nice. This thingamagic seems like something worth investing some time in.&lt;br /&gt;&lt;br /&gt;I've earmarked several packages/modules which might come in handy:&lt;br /&gt;* &lt;a href="http://twistedmatrix.com/projects/core/documentation/howto/options.html"&gt;twisted.python.usage&lt;/a&gt;&lt;br /&gt;* &lt;a href="http://twistedmatrix.com/projects/core/documentation/howto/cred.html"&gt;twisted.cred&lt;/a&gt;&lt;br /&gt;* &lt;a href="http://twistedmatrix.com/projects/core/documentation/howto/pb.html"&gt;twisted.spread&lt;/a&gt;&lt;br /&gt;* &lt;a href="http://twistedmatrix.com/projects/web/documentation/howto/"&gt;twisted.web&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;b&gt;[update]&lt;/b&gt;&lt;br /&gt;&lt;i&gt;Twisted&lt;/i&gt; by name, twisted by nature. &lt;br /&gt;&lt;br /&gt;Naming convention used in some of the packages are a little OTT. &lt;br /&gt;Eg. In the spreadable (distributed) computing package -- &lt;i&gt;twisted.spead&lt;/i&gt;&lt;br /&gt;&lt;a href="http://twistedmatrix.com/documents/current/api/twisted.spread.banana.html"&gt;banana&lt;/a&gt;... &lt;a href="http://twistedmatrix.com/documents/current/api/twisted.spread.jelly.html"&gt;jelly&lt;/a&gt;... &lt;a href="http://twistedmatrix.com/documents/current/api/twisted.spread.flavors.html"&gt;flavors&lt;/a&gt;... InsecureJelly... Unjellyable... &lt;br /&gt;Amusing? For a while. Meaningful? Hmmmm...&lt;br /&gt;&lt;br /&gt;Documentation is very extensive, which is great. However, there were sections of the tutorials which took quantum leaps rather than steps. Perhaps it's just due to my limited experience with python and proper program design, but I had trouble progressing from &lt;a href="http://twistedmatrix.com/projects/core/documentation/howto/tutorial/style.html"&gt;step 3&lt;/a&gt; to &lt;a href="http://twistedmatrix.com/projects/core/documentation/howto/tutorial/components.html"&gt;step 4&lt;/a&gt; without first groping in the dark (Enlightenment was found in the &lt;i&gt;twisted.python.components&lt;/i&gt; &lt;a href="http://twistedmatrix.com/projects/core/documentation/howto/components.html"&gt; tutorial&lt;/a&gt;).   &lt;br /&gt;&lt;br /&gt;Stumbled upon similar speedbumps in latter steps where things magically appeared warranting further scouring for the associated documentation.&lt;br /&gt;&lt;br /&gt;Patience...&lt;br /&gt;&lt;b&gt;[/update]&lt;/b&gt;&lt;br /&gt;&lt;br /&gt;&lt;b&gt;[update2]&lt;/b&gt;&lt;br /&gt;Useful &lt;a href="http://www.artima.com/weblogs/viewpost.jsp?thread=156396"&gt;article&lt;/a&gt;&lt;br /&gt;&lt;b&gt;[/update2]&lt;/b&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/19662631-4153114267753565830?l=caffeinoverdose.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://caffeinoverdose.blogspot.com/feeds/4153114267753565830/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=19662631&amp;postID=4153114267753565830' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/19662631/posts/default/4153114267753565830'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/19662631/posts/default/4153114267753565830'/><link rel='alternate' type='text/html' href='http://caffeinoverdose.blogspot.com/2007/02/webexport-using-twisted.html' title='WebExport: Using Twisted'/><author><name>shawnchin</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='23' height='32' src='http://static.flickr.com/29/49747509_6a5618aced_t.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://bp1.blogger.com/__r2FteFskoo/ReRZgLib6mI/AAAAAAAAACU/qG7y7bcFPDI/s72-c/l8080.jpg' height='72' width='72'/><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-19662631.post-9177356309549147813</id><published>2007-02-23T15:04:00.000Z</published><updated>2007-02-23T17:50:07.804Z</updated><category scheme='http://www.blogger.com/atom/ns#' term='Project: WebExport'/><title type='text'>Possible mini project: WebExport</title><content type='html'>Here's a mini project I'm thinking of. Fruits of another one of those &lt;i&gt;"wouldn't it be nice if I could do this?"&lt;/i&gt; moments.&lt;br /&gt;&lt;br /&gt;&lt;b&gt;&lt;u&gt;The scenario:&lt;/u&gt;&lt;/b&gt;&lt;br /&gt;I have a bunch of HTML files on a machine within a LAN which I would like &lt;i&gt;temporarily&lt;/i&gt; expose to the world. Instead of having to go through the hassle of obtaining webspace on an external web server, and copying all the files over, and later removing it again, I would like to be able to do something like:&lt;br /&gt;&lt;tt&gt;&lt;pre&gt;&lt;br /&gt;[lsc@lan ~]$ webexport -d /path/to/html/dir&lt;br /&gt;Reading config file ~/.webexport ...&lt;br /&gt;Exporting view to webexport server ...&lt;br /&gt;&lt;br /&gt;View available at http://external.web.domain/webexport/93123&lt;br /&gt;Access password: caffeinOverdose&lt;br /&gt;&lt;br /&gt;(Enter Ctrl-d to end session)&lt;br /&gt;&lt;/pre&gt;&lt;/tt&gt;&lt;br /&gt;&lt;br /&gt;The config file would define where to access the WebExport server, as well as the user's authentication details (username/passord? private key? no authentication?).&lt;br /&gt;&lt;br /&gt;Access password would be an application generated word/phrase which external viewers would have to enter in order to view the exported files. A &lt;i&gt;--password [pwd]&lt;/i&gt; option to define my own password, or &lt;i&gt;--no-password&lt;/i&gt; to disable authentication would be nice.&lt;br /&gt;&lt;br /&gt;An additional feature would be to be able to export pages hosted on an internal webserver. So, if I want pages hosted in &lt;i&gt;http://10.0.0.88/project1/prototype&lt;/i&gt; to be exported:&lt;br /&gt;&lt;tt&gt;&lt;pre&gt;&lt;br /&gt;[lsc@lan ~]$ webexport -s http://10.0.0.88/project1/prototype&lt;br /&gt;Reading config file ~/.webexport ...&lt;br /&gt;Exporting view to webexport server ...&lt;br /&gt;&lt;br /&gt;View available at http://external.web.domain/webexport/55699&lt;br /&gt;&lt;br /&gt;(Enter Ctrl-d to end session)&lt;br /&gt;&lt;/pre&gt;&lt;/tt&gt;&lt;br /&gt;&lt;br /&gt;Proper path translations would have to be done so that:&lt;br /&gt;&lt;i&gt;http://10.0.0.88/project1/prototype/&lt;b&gt;admin/a.html&lt;/b&gt;&lt;/i&gt;&lt;br /&gt;would be accessible via:&lt;br /&gt;&lt;i&gt;http://external.web.domain/webexport/55699/&lt;b&gt;admin/a.html&lt;/b&gt;&lt;/i&gt;&lt;br /&gt;&lt;br /&gt;&lt;b&gt;Why do I even need this?&lt;/b&gt;&lt;br /&gt;There are several analysis tools we provide which generate a whole bunch of HTML files as output. Users wanting to use these tools would have to do so via &lt;i&gt;ssh&lt;/i&gt; into an internal server (we don't distribute the tools due to licensing limitations).&lt;br /&gt;&lt;br /&gt;Typically, users would have to &lt;i&gt;scp/sftp&lt;/i&gt; the result files back to their local machine for viewing. Not a very friendly solution, especially if repeated analysis is required after the results have been reviewed.&lt;br /&gt;&lt;br /&gt;Currently, I've included a wrapper around the tools, which attempts to &lt;i&gt;X-forward&lt;/i&gt; a browser instance onto the user machine, or reverts to displaying it in &lt;a href="http://docs.python.org/lib/module-BaseHTTPServer.html"&gt;links&lt;/a&gt; if X-forwarding is not possible. It works... sort of... but it's just too much of a hack. Hence the idea of WebExport.&lt;br /&gt;&lt;br /&gt;&lt;b&gt;Possible approach:&lt;/b&gt;&lt;br /&gt;I've only just recently picked up Python, so if I were to give WebExport (WE) a go, I'll probably pythonify it. Best way to learn french is to live in france. Python Land, here I come!&lt;br /&gt;&lt;br /&gt;A quick googling reveals that there are several modules and frameworks that might come in handy:&lt;br /&gt;* Pythons builtin &lt;a href="http://docs.python.org/lib/module-BaseHTTPServer.html"&gt;BaseHTTPServer&lt;/a&gt; module&lt;br /&gt;* &lt;a href="http://www.cherrypy.org/"&gt;CherryPy&lt;/a&gt;&lt;br /&gt;* &lt;a href="http://www.amk.ca/python/code/medusa.html"&gt;Medusa&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;Yes, I'm thinking of a client-server setup. The WE-server could act as a dynamic web proxy supporting may WE-clients, and WE-clients could be light-weight HTTP servers which registers itself with the WE-server. &lt;br /&gt;&lt;br /&gt;Alternatively, the WE-server could be a webserver which queries for data from the WE-clients connected to it. Some form of caching could be incorporate to improve performance.&lt;br /&gt;&lt;br /&gt;In the first incarnation, the WE-server, whatever the implementation, should probably not be connected directly to the WWW, but rather served via Apache using &lt;a href="http://httpd.apache.org/docs/1.3/mod/mod_proxy.html#proxypass"&gt;proxyPass&lt;/a&gt;. That ought to minimise security concerns, and sit on the current server setup without much modification.&lt;br /&gt;&lt;br /&gt;&lt;a href="http://www.nightmare.com/medusa/programming.html"&gt;Some&lt;/a&gt; &lt;a href="http://squirl.nightmare.com/medusa/async_sockets.html"&gt;useful&lt;/a&gt; &lt;a href="http://docs.python.org/lib/module-BaseHTTPServer.html"&gt;links&lt;/a&gt; &lt;a href="http://docs.cherrypy.org/cherrypy-tutorial"&gt;here&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;b&gt;Hmmm...&lt;/b&gt;&lt;br /&gt;Is there already something out there that does this? Or is there a better approach???&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/19662631-9177356309549147813?l=caffeinoverdose.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://caffeinoverdose.blogspot.com/feeds/9177356309549147813/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=19662631&amp;postID=9177356309549147813' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/19662631/posts/default/9177356309549147813'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/19662631/posts/default/9177356309549147813'/><link rel='alternate' type='text/html' href='http://caffeinoverdose.blogspot.com/2007/02/possible-mini-project-webexport.html' title='Possible mini project: WebExport'/><author><name>shawnchin</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='23' height='32' src='http://static.flickr.com/29/49747509_6a5618aced_t.jpg'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-19662631.post-2129311338892508678</id><published>2007-02-21T17:59:00.000Z</published><updated>2007-02-21T18:38:29.564Z</updated><category scheme='http://www.blogger.com/atom/ns#' term='Learning Log'/><category scheme='http://www.blogger.com/atom/ns#' term='MPI'/><title type='text'>Triggering function call on MPI process termination</title><content type='html'>Was flipping through the &lt;a href="http://www.mpi-forum.org/docs/mpi-20-html/mpi2-report.htm#Node0"&gt;MPI-2 Standards&lt;/a&gt; when I stumbled upon &lt;a href="http://www.mpi-forum.org/docs/mpi-20-html/node51.htm#Node51"&gt;this&lt;/a&gt;:&lt;br /&gt;&lt;br /&gt;&lt;blockquote&gt;"There are times in which it would be convenient to have &lt;b&gt;actions happen when an MPI process finishes&lt;/b&gt;. For example, a routine may do initializations that are useful until the MPI job (or that part of the job that being terminated in the case of dynamically created processes) is finished. This can be accomplished in MPI-2 by attaching an &lt;b&gt;attribute to MPI_COMM_SELF with a callback function&lt;/b&gt;."&lt;br /&gt;&lt;/blockquote&gt;&lt;br /&gt;&lt;br /&gt;Looked like good fun. Here's a quick code to see it in action.&lt;br /&gt;&lt;code&gt;&lt;pre&gt;&lt;br /&gt;#include &amp;lt;mpi.h&amp;gt;&lt;br /&gt;&lt;br /&gt;/* callback function triggered when Communicator is freed */&lt;br /&gt;int comm_self_delete_fn (MPI_Comm comm, int keyval, \&lt;br /&gt;        void *attr_val, void *extra_state) {&lt;br /&gt;&lt;br /&gt;    printf("[%d] In callback function\n", *((int *)attr_val));&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;int main (int argc, char **argv) {&lt;br /&gt;&lt;br /&gt;    int onquit;&lt;br /&gt;    int rank;&lt;br /&gt;&lt;br /&gt;    MPI_Init(&amp;argc, &amp;argv);&lt;br /&gt;    MPI_Comm_rank(MPI_COMM_WORLD, &amp;rank);&lt;br /&gt;&lt;br /&gt;    /* Create attribute with callback function */&lt;br /&gt;    MPI_Comm_create_keyval(MPI_COMM_NULL_COPY_FN, \&lt;br /&gt;        comm_self_delete_fn, &amp;onquit, (void *)0);&lt;br /&gt;&lt;br /&gt;    /* Assign attribute to MPI_COMM_SELF with tank as value */&lt;br /&gt;    MPI_Comm_set_attr(MPI_COMM_SELF, onquit, &amp;rank);&lt;br /&gt;    MPI_Comm_free_keyval(&amp;onquit);&lt;br /&gt;&lt;br /&gt;    printf("[%d] Before finalize\n", rank);&lt;br /&gt;    MPI_Finalize();&lt;br /&gt;    printf("[%d] After finalize\n", rank);&lt;br /&gt;&lt;br /&gt;    return 0;&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;&lt;u&gt;&lt;b&gt;Notes:&lt;/b&gt;&lt;/u&gt;&lt;br /&gt;&lt;ul&gt;&lt;br /&gt;&lt;li&gt;&lt;tt&gt;MPI_COMM_SELF&lt;/tt&gt; is used (instead of, say &lt;tt&gt;MPI_COMM_WORLD&lt;/tt&gt;) because that is the first object freed during &lt;tt&gt;MPI_Finalize()&lt;/tt&gt; before any other parts of MPI are affected.&lt;/li&gt;&lt;br /&gt;&lt;li&gt;MPI-2 introduces attribute caching functions for Windows and Datatypes (previously only available for Communicators): &lt;tt&gt;MPI_{Comm,Win,Type}_{create,set}_keyval&lt;/tt&gt;.&lt;/li&gt;&lt;br /&gt;&lt;li&gt;Callback function for &lt;i&gt;COPY&lt;/i&gt; used when Communicator (or windows/datatypes) are duplicated.&lt;/li&gt;&lt;br /&gt;&lt;/ul&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/19662631-2129311338892508678?l=caffeinoverdose.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://caffeinoverdose.blogspot.com/feeds/2129311338892508678/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=19662631&amp;postID=2129311338892508678' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/19662631/posts/default/2129311338892508678'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/19662631/posts/default/2129311338892508678'/><link rel='alternate' type='text/html' href='http://caffeinoverdose.blogspot.com/2007/02/triggering-function-call-on-mpi-process.html' title='Triggering function call on MPI process termination'/><author><name>shawnchin</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='23' height='32' src='http://static.flickr.com/29/49747509_6a5618aced_t.jpg'/></author><thr:total>0</thr:total></entry></feed>
