<?xml version="1.0" encoding="utf-8"?>
<?xml-stylesheet href="/topics-files/atom2xhtml.xsl" type="text/xsl"?>
<!-- This is a 512 byte XML comment that one must put into XML Atom feeds
such that browsers like Firefox 2.0 and IE7 will obey the XSL stylesheet.
Everybody hates overbearing browsers.
This is a 512 byte XML comment that one must put into XML Atom feeds
such that browsers like Firefox 2.0 and IE7 will obey the XSL stylesheet.
Everybody hates overbearing browsers.
This is a 512 byte XML comment that one must put into XML Atom feeds
such that browsers like Firefox 2.0 and IE7 will obey the XSL stylesheet.
Everybody hates overbearing browsers.
This is a 512 byte XML comment that one must put into XML Atom feeds
such that browsers like Firefox 2.0 and IE7 will obey the XSL stylesheet.
Everybody hates overbearing browsers.
This is a 512 byte XML comment that one must put into XML Atom feeds
such that browsers like Firefox 2.0 and IE7 will obey the XSL stylesheet.
Everybody hates overbearing browsers.
This is a 512 byte XML comment that one must put into XML Atom feeds
such that browsers like Firefox 2.0 and IE7 will obey the XSL stylesheet.
Everybody hates overbearing browsers. -->
<feed xmlns="http://www.w3.org/2005/Atom"
><title
>Blog@Case Topics: programming</title
><link rel="self" href="http://blog.case.edu/topics/programming"
 /><id
>http://blog.case.edu/topics/programming</id
><category term="programming" label="programming"
 /><link rel="related" href="http://blog.case.edu/topics/mainblog" title="mainblog"
 /><link rel="related" href="http://blog.case.edu/topics/web%20services" title="web services"
 /><link rel="related" href="http://blog.case.edu/topics/linkblog" title="linkblog"
 /><link rel="related" href="http://blog.case.edu/topics/http" title="http"
 /><link rel="related" href="http://blog.case.edu/topics/projects" title="projects"
 /><link rel="related" href="http://blog.case.edu/topics/python" title="python"
 /><link rel="related" href="http://blog.case.edu/topics/blog@case%20developments" title="blog@case developments"
 /><link rel="related" href="http://blog.case.edu/topics/weblog%20tech" title="weblog tech"
 /><link rel="related" href="http://blog.case.edu/topics/general%20information%20technology" title="general information technology"
 /><link rel="related" href="http://blog.case.edu/topics/failures%20of%20technology" title="failures of technology"
 /><link rel="related" href="http://blog.case.edu/topics/ldap" title="ldap"
 /><contributor
><name
>Brian Beck</name
><email
>brian.beck@case.edu</email
><uri
>http://blog.case.edu/bmb12</uri
></contributor
><contributor
><name
>Jeremy Smith</name
><email
>jeremy.smith@case.edu</email
><uri
>http://blog.case.edu/jeremy.smith</uri
></contributor
><contributor
><name
>Sean Maxwell</name
><email
>sean.maxwell@case.edu</email
><uri
>http://blog.case.edu/stm</uri
></contributor
><updated
>2008-02-29T00:13:11Z</updated
><entry
><title
>Satire?</title
><link href="http://blog.case.edu/jeremy.smith/2008/02/28/satire"
 /><id
>http://blog.case.edu/jeremy.smith/2008/02/28/satire</id
><published
>2008-02-29T00:10:26Z</published
><updated
>2008-02-29T00:13:11Z</updated
><category term="Programming" label="Programming"
 /><category term="linkblog" label="linkblog"
 /><content type="xhtml"
><div xmlns="http://www.w3.org/1999/xhtml"
>
<p>
<a title="O'Reilly Network -- Does Enterprise Development Have to Be Painful?" href="http://www.oreillynet.com/pub/a/network/2008/02/28/does-enterprise-development-have-to-be-painful.html">Does Enterprise Development Have to Be Painful?</a>
</p>
<blockquote>
<p>that gives me a lot of confidence that things will make a lot of sense in context from here&#8230; Writing software this way may be much easier than I thought.</p>
</blockquote>
<p>I can't decide if 
<a title="chromatic" href="http://perlmonks.org/?node=chromatic">chromatic</a> is being serious or if the satire is just embedded really deeply.</p>
</div
></content
><author
><name
>Jeremy Smith</name
><email
>jeremy.smith@case.edu</email
><uri
>http://blog.case.edu/jeremy.smith</uri
></author
></entry
><entry
><title
>Perceptions of Perl</title
><link href="http://blog.case.edu/jeremy.smith/2008/02/18/perceptions_of_perl"
 /><id
>http://blog.case.edu/jeremy.smith/2008/02/18/perceptions_of_perl</id
><published
>2008-02-18T22:23:23Z</published
><updated
>2008-02-18T23:43:26Z</updated
><category term="Programming" label="Programming"
 /><category term="mainblog" label="mainblog"
 /><category term="perl" label="perl"
 /><category term="php" label="php"
 /><category term="rails" label="rails"
 /><category term="ruby" label="ruby"
 /><category term="rubyonrails" label="rubyonrails"
 /><content type="xhtml"
><div xmlns="http://www.w3.org/1999/xhtml"
>
<p>This is going to end up being a catch-all post on a number of things I've been meaning to write about for the past year or so.</p>
<p>What got me on this track was reading 
<a title="Perceptions of Perl - views from the edge &#239;&#191;&#189; Not this&#226;&#8364;&#166;" href="http://blog.timbunce.org/2008/02/14/perceptions-of-perl-views-from-the-edge/">Perceptions of Perl - views from the edge</a>. 
<a href="http://www.case.edu">Here</a>, I do a majority of my programming in Perl (and PL/SQL and increasingly 
<a href="http://en.wikipedia.org/wiki/Unobtrusive_JavaScript">JavaScript</a>). Previously, I have done a lot (
<strong>a lot</strong>) of PHP programming. When I take on independent gigs, I do my work in 
<a href="http://www.rubyonrails.org/">Rails</a>. Recently, I did a medium sized programming job for a client and had to use PHP (was going to use Rails, but the place said that web programming had to be done in PHP). Rather than roll-my-own-
<a href="http://en.wikipedia.org/wiki/Object-relational_mapping">ORM</a> (seriously, people still do that(??)), I used 
<a title="CakePHP: the rapid development php framework. Home" href="http://www.cakephp.org/">CakePHP</a>.
<sup id="number1-2008-02-18">
<a href="#note1-2008-02-18">1</a>
</sup></p>
<p>So having participated within these languages/cultures/communities, I have my own perspective. First and foremost, the Perl community is more than two times better than any I found within PHP or Ruby. That is, if the PHP community improved by 100%, it would still be less useful than the Perl community. And by "useful" I mean possessing the ability for someone to engage in a discussion, get answers to questions, explore best practices, learn, maybe even do a little programming goofing around, etc.</p>
<p>At this point, I was going to provide a long list of links to my posts within these communities asking questions and trying to stir up some discussions; but I honestly had a hard time finding the links. The communities seem almost transient in comparison to places like 
<a title="PerlMonks - The Monastery Gates" href="http://www.perlmonks.org/">PerlMonks</a> and 
<a title="use Perl: All the Perl that's Practical to Extract and Report" href="http://use.perl.org/">use Perl;</a>. Granted, this invites the comments along the lines of "if you can't even remember where the communities are, it's probably your err in not being able to-engage/stay-engaged with them." Okay, I'll accept that criticism; though, I never had that problem with the Perl community even though I go through numerous periods of dropping in and dropping out that each can stretch months of time.</p>
<p>Syntax, sigils, white space, semicolons&#8230; the make-or-break for me is the community. (Unless it's Python; then the make-or-break is white space.)</p>
<p>So my perception of Perl is that it still has the best community; and all it needs is a 
<a title="David Heinemeier Hansson - Wikipedia, the free encyclopedia" href="http://en.wikipedia.org/wiki/David_Heinemeier_Hansson">DHH personality</a> and a set of shiny, sexy 
<a title="Halo vehicle - Wikipedia, the free encyclopedia" href="http://en.wikipedia.org/wiki/Halo_vehicle">halo</a> services built atop a framework like 
<a href="http://catalyst.perl.org/">Catalyst</a> to "get its groove back," so to speak.</p>
<p>All that being said, like I stated above, I program using Rails if given the choice. (As an aside, I would never use CakePHP again.
<sup id="number2-2008-02-18">
<a href="#note2-2008-02-18">2</a>
</sup>)</p>
<ol style="margin-top: 80px;">
<li id="note1-2008-02-18">My displeasure of CakePHP was always meant to warrant its own blog post. But, really, it all boils down to the fact that you pass around hashes in the controllers and not actual objects. All of the other suckiness is just a derivative of that property. 
<a href="#number1-2008-02-18">&#8617;</a></li>
<li id="note2-2008-02-18">I don't mean to bash 
<a title="CakePHP: the rapid development php framework. Home" href="http://www.cakephp.org/">CakePHP</a> so blatantly. The 
<a title="CakePHP Manual" href="http://manual.cakephp.org/">manual</a> is excellent as is the 
<a title="API for CakePHP : The PHP Rapid Development Framework :: version 1.1.x.x" href="http://api.cakephp.org/">API documentation</a>. As a matter of fact, most questions I had or problems I ran into were easily serviced by just looking through the actual source code (it's quite well done and well documented). The 
<a title="The Bakery, Everything CakePHP : Home" href="http://bakery.cakephp.org/">Bakery</a> and 
<a title="CakeForge: Welcome" href="http://cakeforge.org/">Forge</a> were not very conducive to use. And a lot wasn't helped by the fact that they were transitioning their documentation away from a wiki &#8211; 
<a href="http://bakery.cakephp.org/wiki/">http://bakery.cakephp.org/wiki/</a> &#8211; which had been closed down leading to a lot of dead-end search results (why they couldn't leave the wiki open for posterity while the transition was taking place&#8230; I don't know). 
<a href="#number2-2008-02-18">&#8617;</a></li>
</ol>
</div
></content
><author
><name
>Jeremy Smith</name
><email
>jeremy.smith@case.edu</email
><uri
>http://blog.case.edu/jeremy.smith</uri
></author
></entry
><entry
><title
>Rounding up an int to a power of two in Java</title
><link href="http://blog.case.edu/jeremy.smith/2007/11/05/epic_fail"
 /><id
>http://blog.case.edu/jeremy.smith/2007/11/05/epic_fail</id
><published
>2007-11-05T18:47:59Z</published
><updated
>2008-01-23T23:58:43Z</updated
><category term="Programming" label="Programming"
 /><category term="java" label="java"
 /><category term="linkblog" label="linkblog"
 /><content type="xhtml"
><div xmlns="http://www.w3.org/1999/xhtml"
>It's just too funny not to link to &#8212; 
<a title="Java Programming [Archive] - Rounding up an int to a power of two" href="http://forum.java.sun.com/thread.jspa?threadID=248212&amp;start=0&amp;tstart=0">How many Java programmers does it take to round up an int to a power of two</a>. The following quote is from 
<a title="del.icio.us/url/a969293ed814b3fcee49dc5f91a64a06" href="http://del.icio.us/url/a969293ed814b3fcee49dc5f91a64a06">Joe Gregorio's del.icio.us comment</a>:
<blockquote>There are three levels to creating software: computer science, software engineering, and this thing that people do with Java inside enterprises.</blockquote></div
></content
><author
><name
>Jeremy Smith</name
><email
>jeremy.smith@case.edu</email
><uri
>http://blog.case.edu/jeremy.smith</uri
></author
></entry
><entry
><title
>How to send a Cookie with an xmlHttpRequest from IE</title
><link href="http://blog.case.edu/stm/2007/09/06/how_to_send_a_cookie_with_an_xmlhttprequest_from_ie"
 /><id
>http://blog.case.edu/stm/2007/09/06/how_to_send_a_cookie_with_an_xmlhttprequest_from_ie</id
><published
>2007-09-06T13:51:52Z</published
><updated
>2007-09-06T15:10:19Z</updated
><category term="Programming" label="Programming"
 /><content type="xhtml"
><div xmlns="http://www.w3.org/1999/xhtml"
>I'm not sure if this was just me, or if anyone else has ever struggled with this. I did some Googling and found a few posts related to other people trying to do a similar thing and encountering the same problem. The problem I encountered was when I used an xmlHttpRequest in IE (IE only. I didn't see this behavior in any other browsers...), it did not send the Cookie(s) for the current session with the request. Also, if I tried to set the Cookie header directly using setRequestHeader("Cookie",foo) the Cookie value would arrive blank at the server. I determined this by writing a cgi script to print out all request headers for a given request to a log file so I could track them. The interesting thing I noticed is if I instead used a custom header setRequestHeader("MyHeader",foo) rather than the Cookie header, the custom header and value would arrive intact at the server. So what I did was wrote a conditional statement into the server code that first checked for the existence of the Cookie value, and if it did not exist, it checked for the existence of MyHeader to get the Cookie value. It seems to work around the problem in IE, and it has also worked in Opera, FireFox and Safari with no problems/errors. There may be an explanation for the IE behavior that involves me being wrong/trying to do something restricted by protocol/blah blah blah...but either way you look at it, I need to get it done, so this at least worked. Hopefully it will help somebody.</div
></content
><author
><name
>Sean Maxwell</name
><email
>sean.maxwell@case.edu</email
><uri
>http://blog.case.edu/stm</uri
></author
></entry
><entry
><title
>Not So Advanced</title
><link href="http://blog.case.edu/jeremy.smith/2007/07/12/not_so_advanced"
 /><id
>http://blog.case.edu/jeremy.smith/2007/07/12/not_so_advanced</id
><published
>2007-07-12T18:11:30Z</published
><updated
>2007-07-12T18:12:39Z</updated
><category term="Programming" label="Programming"
 /><category term="javascript" label="javascript"
 /><category term="linkblog" label="linkblog"
 /><category term="web" label="web"
 /><content type="xhtml"
><div xmlns="http://www.w3.org/1999/xhtml"
>
<a title="ONLamp.com -- Writing Advanced JavaScript" href="http://www.onlamp.com/pub/a/onlamp/2007/07/05/writing-advanced-javascript.html">Writing Advanced JavaScript</a> Using 
<code>onclick()</code>'s? 
<a title="Unobtrusive JavaScript - Wikipedia, the free encyclopedia" href="http://en.wikipedia.org/wiki/Unobtrusive_JavaScript">What</a>?</div
></content
><author
><name
>Jeremy Smith</name
><email
>jeremy.smith@case.edu</email
><uri
>http://blog.case.edu/jeremy.smith</uri
></author
></entry
><entry
><title
>Multiple sites, one Python: Pagoda import tricks</title
><link href="http://blog.case.edu/bmb12/2007/04/multiple_sites_one_python_pagoda_import_tricks"
 /><id
>http://blog.case.edu/bmb12/2007/04/multiple_sites_one_python_pagoda_import_tricks</id
><published
>2007-04-17T23:57:24Z</published
><updated
>2007-04-18T00:30:43Z</updated
><category term="Pagoda" label="Pagoda"
 /><category term="Programming" label="Programming"
 /><category term="Projects" label="Projects"
 /><category term="Python" label="Python"
 /><content type="xhtml"
><div xmlns="http://www.w3.org/1999/xhtml"
>One of our early goals when designing 
<a href="http://www.pagodacms.org">Pagoda</a> was to allow a single Pagoda instance to support multiple sites. This was due to the way memory works for web servers running on Python and TurboGears. How exactly this adds up depends on your threading and web server configuration (mod_python), but traditionally hosting multiple sites means running at least one Python instance per site, each costing 10-20 MB. The more modules each instance loads, the higher the memory usage, and since Pagoda sites will likely use a bunch of modules, that adds up. The most limiting factor in many hosting services is the amount of memory your account is allowed to consume. Obviously if each Pagoda site is large and running custom code, it might be a good idea to run each in its own Python instance, so one site can't bring down all the others. But the common case, we think, is a bunch of moderately sized sites using just the built-in page management tools. So we devised some ways to allow multiple sites to run from one TurboGears project... The first and simplest plan involved a database model, where pages and other table rows point to whichever site they belong to. You probably already know why this is a bad idea. First of all, every single table in the database needed to have a site_id column, since nothing would be shared between sites. Unique things like usernames would need their constraints modified to only be unique per-site. That got old pretty fast. Secondly was security. How could we ensure that every piece of code touching the database, even the eventual third-party plugins, would use the correct site in their queries so as not to mess with the others? And finally, having each site's contents in one massive database would not be very convenient if the site owners wanted backups of their portion of the database. So we started looking at multi-database solutions, and quickly realized we were pretty much on our own for what we wanted to do. We don't just want some models in one database, and other models in a difference database; we want the same models in every database. Every site needs a pages table, for example. Since we're mapping tables with 
<a href="http://www.sqlalchemy.org">SQLAlchemy</a>, and each mapper is bound to 
<a href="http://www.sqlalchemy.org/docs/metadata.html">metadata</a>, an engine, and a session, it seems that we'd need to run the table and mapper definitions once per site; each time, the engine would point to the appropriate site's. And now the big trick: how do we do this without modifying any model code, so that plugin writers don't have to learn any silly new details, and without doing a bunch of extra work every time a controller needs to use a model? If our controllers import 
<tt>pagoda.models.pages</tt>, how will it know to get the 
<tt>Page</tt> class bound to the current site's engine, and not another site's? We looked to 
<a href="http://www.cherrypy.org">CherryPy</a> for inspiration. In a TurboGears controller, importing 
<tt>cherrypy.request</tt> and 
<tt>cherrypy.response</tt> will make the current thread's request and response objects available. How do these objects magically belong to the appropriate thread? They simply use a class called 
<tt>ThreadLocalProxy</tt>. As the name suggests, 
<tt>cherrypy.request</tt> and 
<tt>cherrypy.response</tt> are proxy objects that determine the current thread and point object access to the correct 
<tt>request</tt> and 
<tt>response</tt> instances. Similarly, we want something like 
<tt>SiteLocalProxy</tt>, which will make model classes available that are magically bound to the correct site's engine. Using 
<tt>ThreadLocalProxy</tt> as inspiration, we made a clever little object called 
<tt>site</tt>. When anything is imported from 
<tt>pagoda.site</tt>, it will rebind 
<tt>turbogears.database.metadata</tt> and 
<tt>turbogears.database.session</tt> after updating 
<tt>sqlalchemy.dburi</tt> in the config to point to the current site's. Then the requested module is imported and cached for next time (so the models aren't reinitialized every time). No model code was changed at all! The only necessary modification was importing from 
<tt>pagoda.site.models</tt> instead of 
<tt>pagoda.models</tt> in our controllers. Our first implementation looked very much like 
<tt>ThreadLocalProxy</tt>, but it made our import statements look funny since 
<tt>site</tt> wasn't a real module. So we started investigating the 
<tt>imp</tt>, 
<tt>ihooks</tt>, and 
<tt>imputils</tt> modules, eventually leading us to 
<a href="http://www.python.org/dev/peps/pep-0302/">PEP 302</a>. With help from 
<a href="http://peak.telecommunity.com/DevCenter/Importing">Importing</a> (to reduce the amount of code necessary), we now have a special pseudo-module called 
<tt>site</tt>, and Pagoda modules imported from that will take the current request's site into account instead of just being imported once for the entire process. Before writing up this entry, I came across 
<a href="http://cheeseshop.python.org/pypi/Alchemyware">Alchemyware</a>. At first it looked promising for what we want to do, but as far as I can tell it requires modifying the way you write models and reinstantiating them on every request. Also, I don't understand how the mapped class can be "shared by everyone" if it's being mapped to multiple databases. Anyway, after cleaning up our proof-of-concept I'll share the code behind our import trickery in case anyone is trying to do something similar, but mostly just because such tricks are interesting. In case you forgot, we missed the end-of-March deadline we set for our demo, due in part to being burned out after PyCon. We're shooting for the end of April now.</div
></content
><author
><name
>Brian Beck</name
><email
>brian.beck@case.edu</email
><uri
>http://blog.case.edu/bmb12</uri
></author
></entry
><entry
><title
>Scaling Towards &lt;em&gt;Really Big&lt;/em&gt;</title
><link href="http://blog.case.edu/jeremy.smith/2007/04/05/scaling_towards_really_big"
 /><id
>http://blog.case.edu/jeremy.smith/2007/04/05/scaling_towards_really_big</id
><published
>2007-04-05T19:03:05Z</published
><updated
>2007-04-05T19:03:06Z</updated
><category term="Programming" label="Programming"
 /><category term="information architecture" label="information architecture"
 /><category term="linkblog" label="linkblog"
 /><category term="mysql" label="mysql"
 /><category term="oracle" label="oracle"
 /><category term="rdbms" label="rdbms"
 /><content type="xhtml"
><div xmlns="http://www.w3.org/1999/xhtml"
>To scale to the petabyte level and beyond and handle billions of transactions a day, your database needs to eschew 
<a title="Joe Gregorio | BitWorking | ETech '07 Summary - Part 2 - MegaData" href="http://bitworking.org/news/158/ETech-07-Summary-Part-2-MegaData">transactions, normalization, referential integrity, stored procedures, joins, etc.</a>. Interesting. There was another good link in there to 
<a title="joshua's blog" href="http://joshua.schachter.org/">Joshua Schachter's</a> 
<a title="joshua's blog: lessons learned: autoincrement considered harmful" href="http://joshua.schachter.org/2007/01/autoincrement.html">lessons learned: autoincrement considered harmful</a>.</div
></content
><author
><name
>Jeremy Smith</name
><email
>jeremy.smith@case.edu</email
><uri
>http://blog.case.edu/jeremy.smith</uri
></author
></entry
><entry
><title
>I Program in JavaScript</title
><link href="http://blog.case.edu/jeremy.smith/2007/03/26/i_program_in_javascript"
 /><id
>http://blog.case.edu/jeremy.smith/2007/03/26/i_program_in_javascript</id
><published
>2007-03-26T20:55:21Z</published
><updated
>2007-03-26T20:58:27Z</updated
><category term="Programming" label="Programming"
 /><category term="javascript" label="javascript"
 /><category term="mainblog" label="mainblog"
 /><content type="xhtml"
><div xmlns="http://www.w3.org/1999/xhtml"
>At one point in time, I primarily programmed in C, C++, VB, and Java (yes, this was when I was an undergrad 
<a href="http://www.case.edu">here</a>). Then, I programmed primarily in Perl. Then, I programmed primarily in PHP. Then, I went back to Perl. (Spatter a lot of heavy development done in Transact-SQL and PL/SQL that I don't like to think about.) Throughout all those phases, I also did a fair amount of JavaScript programming. But I hated it. I mean 
<em>really</em> hated it. I would mutter things like "hackery," "stupid DOM," "poo," etc. when I knew I had to descend into the world of JavaScript; and when I closed my eyes, I would see millions of lines of 
<code>document.getElementById</code>. I swear, though, nowadays, I probably program more JavaScript than I do any other language; and I enjoy it. JavaScript seems to be undergoing a renaissance. Or, it might just be that I finally learned how to 
<em>properly</em> program in JavaScript. Anyways, the whole point of this post was to give me an excuse to point to this 
<a title="adamlogic: Metaprogramming JavaScript Presentation" href="http://www.adamlogic.com/2007/03/20/3_metaprogramming-javascript-presentation">Metaprogramming JavaScript Presentation</a>.</div
></content
><author
><name
>Jeremy Smith</name
><email
>jeremy.smith@case.edu</email
><uri
>http://blog.case.edu/jeremy.smith</uri
></author
></entry
><entry
><title
>OpenID Server Integrated with CAS</title
><link href="http://blog.case.edu/jeremy.smith/2007/03/09/openid_server_integrated_with_cas"
 /><id
>http://blog.case.edu/jeremy.smith/2007/03/09/openid_server_integrated_with_cas</id
><published
>2007-03-10T00:53:01Z</published
><updated
>2007-03-10T00:55:54Z</updated
><category term="Federated Identity" label="Federated Identity"
 /><category term="HTTP" label="HTTP"
 /><category term="Programming" label="Programming"
 /><category term="Shibboleth" label="Shibboleth"
 /><category term="Web Services" label="Web Services"
 /><category term="cas" label="cas"
 /><category term="identity management" label="identity management"
 /><category term="mainblog" label="mainblog"
 /><category term="openid" label="openid"
 /><category term="web" label="web"
 /><category term="web standards" label="web standards"
 /><content type="xhtml"
><div xmlns="http://www.w3.org/1999/xhtml"
>With the help of some of the Network Engineers (to get some magic routing working), I cobbled together an 
<a title="OpenID: an actually distributed identity system" href="http://openid.net/">OpenID</a> server and integrated it with 
<a href="http://www.case.edu">Case's</a> 
<a title="Case Central Authentication Service (CAS)" href="https://login.case.edu">Single Sign On</a> system, 
<a title="Central Authentication Service - CaseWiki" href="http://wiki.case.edu/Central_Authentication_Service">CAS</a>. The "server" end-point is located at 
<a href="http://login.case.edu/id">http://login.case.edu/id</a>. Your "identity URL" is the 
<em>first.last</em> portion of your email address followed with 
<strong>.id.case.edu</strong>. For example, my email is 
<a href="mailto:jeremy.smith@case.edu">jeremy.smith@case.edu</a>, so my OpenID identity URL is 
<a href="http://jeremy.smith.id.case.edu">
<strong>jeremy.smith.id.case.edu</strong>
</a>. For those averse to typing (like I am), you can also use your 
<a title="Case Network ID - CaseWiki" href="http://wiki.case.edu/Case_Network_ID">Case Network ID</a> followed by 
<strong>.id.case.edu</strong>. So, I could also use 
<a href="http://jms18.id.case.edu">
<strong>jms18.id.case.edu</strong>
</a>. If you want to try logging in with it, you can head over to 
<a title="Simon Willison's Weblog" href="http://simonwillison.net/">Simon Willison's Weblog</a> and, at the top where it says "Sign in with OpenID," click on that and enter 
<strong>&lt;USERNAME&gt;.id.case.edu</strong>. A better example is logging into 
<a title="Free Worldwide Travel Guides - Wikitravel" href="http://wikitravel.org/">Wikitravel</a> because it shows how information (such as nicknames, email address, full name, etc.) can be shared between a OpenID Provider and client. You can sign in to Wikitravel 
<a title="Login with OpenID - Wikitravel" href="http://wikitravel.org/en/Special:OpenIDLogin">here</a>. The information sharing part doesn't so much "work" yet. I'm getting there. And because it is integrated upwards towards 
<a href="http://wiki.case.edu/CAS">CAS</a>, it should interoperate with all of the other "identity systems/protocols" we've integrated with CAS like 
<a title="Shibboleth Project - Internet2 Middleware" href="http://shibboleth.internet2.edu/">Shibboleth</a> (and, in testing, Oracle's Single Sign On, Sun's, and 
<a title="Google Apps - SAML-based Single Sign-On" href="http://code.google.com/apis/apps/sso/saml_reference_implementation.html">Google's SAML-based Single Sign-On</a>). I may throw up some screencasts showing the effects of this by bouncing in between normal CAS-protected apps (like this 
<a href="http://blog.case.edu">blog system</a> or the 
<a href="http://wiki.case.edu">wiki</a>), Shibboleth protected ones, and OpenID protected ones.</div
></content
><author
><name
></name
><email
>blog-admin@case.edu</email
><uri
>http://blog.case.edu/jeremy.smith</uri
></author
></entry
><entry
><title
>CAS 1.0 Authentication for Django, Part 2</title
><link href="http://blog.case.edu/bmb12/2006/12/cas_for_django_part_2"
 /><id
>http://blog.case.edu/bmb12/2006/12/cas_for_django_part_2</id
><published
>2006-12-01T18:27:12Z</published
><updated
>2006-12-01T18:39:00Z</updated
><category term="Programming" label="Programming"
 /><category term="Projects" label="Projects"
 /><category term="Python" label="Python"
 /><content type="xhtml"
><div xmlns="http://www.w3.org/1999/xhtml"
>
<p>After using 
<a href="http://blog.case.edu/bmb12/2006/11/simple_cas_for_django">my Django CAS authentication module</a> for a while, I decided to make a couple improvements.</p>
<p>The biggest improvement is that instead of modifying code in the CAS module itself to set your CAS address and do things like custom User field population, all this stuff can now be configured in your settings file.</p>
<p>Another improvement is that CAS authentication now works for the 
<a href="http://www.djangoproject.com/documentation/tutorial2/">bundled admin interface</a>. Since the administration interface does not account for an authentication backend that doesn't know the user's password, this makes the login form useless. The CAS module will now intercept requests to the administration interface and do the proper authentication routine if necessary, never showing the login form (which doesn't make sense for CAS). Intercepting requests, you ask? Yes, that means the CAS module is now 
<a href="http://www.djangoproject.com/documentation/middleware/">middleware</a>. Actually it's middleware, a couple views, and an 
<a href="http://www.djangoproject.com/documentation/authentication/#other-authentication-sources">authentication backend</a>.</p>
<p>So here's how to use it now...</p>
<p>Get 
<a href="http://exogen.case.edu/cas_middleware.tar.gz">cas_middleware.tar.gz</a>.</p>
<p>Extract it in 
<code>django/contrib/</code>. The code will be located at 
<code>django/contrib/cas/</code>. Is this a valid place to install 
<em>third-party</em> middleware? It's not really clear. Just do it anyway.</p>
<p>Now add it to the middleware and authentication backends in your settings. Make sure you also have the authentication middleware installed. Here's what mine looks like:</p>
<pre>
<code>MIDDLEWARE_CLASSES = (
    'django.middleware.common.CommonMiddleware',
    'django.contrib.sessions.middleware.SessionMiddleware',
    'django.contrib.auth.middleware.AuthenticationMiddleware',
    'django.contrib.cas.middleware.CASMiddleware',
    'django.middleware.doc.XViewMiddleware',
)

AUTHENTICATION_BACKENDS = (
    'django.contrib.cas.backend.CASBackend',
)</code>
</pre>
<p>You can now configure the CAS module in the same settings file. Here are the possible options, most of which can be safely ignored:</p>
<ul>
<li>
<code>CAS_SERVICE_URL</code>: This is the only setting you must explicitly define. Set it to the base URL of your CAS source.</li>
<li>
<code>CAS_POPULATE_USER</code>: A callable or the location of a callable. When a user logs in and is missing name and email attributes in the database, this will be called with their User model instance. Default is None (do nothing).</li>
<li>
<code>CAS_ADMIN_PREFIX</code>: The URL prefix of the Django administration site. If undefined, the CAS middleware will just check the view being rendered to see if it lives in 
<code>django.contrib.admin.views</code>. The method is a little evil, but it works.</li>
<li>
<code>CAS_LOGIN_URL</code>: The URL where you bound 
<code>django.contrib.cas.views.login</code>. If undefined, assume 
<code>/accounts/login/</code>.</li>
<li>
<code>CAS_LOGOUT_URL</code>: The URL where you bound 
<code>django.contrib.cas.views.logout</code>. If undefined, assume 
<code>/accounts/logout/</code>.</li>
<li>
<code>CAS_REDIRECT_URL</code>: Where to send a user after logging in or out if there is no referrer and no 
<code>next</code> page set. Default is 
<code>/</code>.</li>
<li>
<code>CAS_REDIRECT_FIELD_NAME</code>: The name of the GET parameter in which to store the page URL to send the user to after logging in. Default is 
<code>next</code>.</li>
</ul>
<p>Need an example? Here's what my CAS settings look like:</p>
<pre>
<code>CAS_SERVICE_URL = 'https://login.case.edu/cas/'
CAS_POPULATE_USER = 'present.utils.populate_user'
</code>
</pre>
<p>And the callable that lives at 
<code>present.utils.populate_user</code> (notice this code lives in my project instead of tinkering with the CAS module) looks like this:</p>
<pre>
<code>def populate_user(user):
    try:
        ldap = LDAP()
        person = ldap.filter_one_by(uid=user.username)
    except:
        if not user.email:
            user.email = "%s@case.edu" % user.username
    else:
        # If it succeeds, update their User entry
        user.email = person.mail[0]
        user.first_name = fix_case(person.givenName[0])
        user.last_name = fix_case(person.sn[0])
</code>
</pre>
<p>(
<code>LDAP</code> and 
<code>fix_case</code> also live in my 
<code>utils</code> module).</p>
<p>Finally, make sure your project knows how to log users in and out by adding these to your URLconf:</p>
<pre>
<code>(r'^accounts/login/$', 'django.contrib.cas.views.login'),
(r'^accounts/logout/$', 'django.contrib.cas.views.logout'),</code>
</pre>
<p>Users should now be able to log into your site, and staff into the administration interface, using CAS 1.0.</p>
</div
></content
><author
><name
>Brian Beck</name
><email
>brian.beck@case.edu</email
><uri
>http://blog.case.edu/bmb12</uri
></author
></entry
><entry
><title
>Simple CAS 1.0 Authentication for Django</title
><link href="http://blog.case.edu/bmb12/2006/11/simple_cas_for_django"
 /><id
>http://blog.case.edu/bmb12/2006/11/simple_cas_for_django</id
><published
>2006-11-27T20:18:13Z</published
><updated
>2006-11-27T21:12:30Z</updated
><category term="Case" label="Case"
 /><category term="Programming" label="Programming"
 /><category term="Projects" label="Projects"
 /><category term="Python" label="Python"
 /><content type="xhtml"
><div xmlns="http://www.w3.org/1999/xhtml"
>Back when I expressed interest in making the 
<a href="http://blog.case.edu/bmb12/2006/10/a_webbased_presentation_system_for_case">web presentation bounty based solely on client-side code</a>, Simon (bounty master and 
<a href="http://filer.case.edu">Filer</a> admin) expressed his wish to keep the two services decoupled (so I shouldn't rely on Filer for slideshow storage). While I still want to have a save-to-Filer feature, I decided that I should just go ahead and get the web presentation system up and running before worrying about a client-side-only version. So I started a 
<a href="http://www.djangoproject.com">Django</a> project. Anyway, the result is that I got 
<a href="http://wiki.case.edu/CAS">CAS</a> 1.0 working alongside the Django authentication system, which means I can take advantage of built-in features like 
<a href="http://www.djangoproject.com/documentation/authentication/">permissions and messages</a> with CAS-authenticated users. If anyone else is interested in using CAS authentication with Django, you can 
<a href="http://exogen.case.edu/django_cas.tar.gz">download the code I'm using</a>. Here's a brief usage guide:
<ul>
<li>Set 
<code>SERVICE_URL</code> in 
<code>cas/__init__.py</code> to the location of your CAS service. For example, Case's is 
<code>https://login.case.edu/cas/</code>.</li>
<li>Set 
<code>DEFAULT_REDIRECT_URL</code> in 
<code>cas/__init__.py</code>. Normally the user will be sent back to their 
<code>HTTP_REFERER</code> (the page that requested login) after authentication. But if the user requests 
<code>/accounts/login/</code> directly (or there is no 
<code>HTTP_REFERER</code>), they will be sent to 
<code>DEFAULT_REDIRECT_URL</code>.</li>
<li>Enable the 
<code>login</code> and 
<code>logout</code> views by adding these to your URLconf (customize the URLs if you want):
<pre>
<code>(r'^accounts/login/$', 'your_site.cas.views.login'),
(r'^accounts/logout/$', 'your_site.cas.views.logout'),
</code>
</pre></li>
<li>Add the backend in 
<code>settings.py</code>:
<pre>
<code>AUTHENTICATION_BACKENDS = (
    'your_site.cas.backends.CASBackend',
)
</code>
</pre></li>
<li>Make sure at least the following apps are installed:
<pre>
<code>INSTALLED_APPS = (
    'django.contrib.auth',
    'django.contrib.sessions',
    'your_site.cas',
)
</code>
</pre></li>
<li>Finally, if you have a way to populate the user's name and e-mail address fields from their username, put it in 
<code>cas/backends.py</code> (see the comments). For example, I have LDAP code there.</li>
</ul>P.S.: This just implements the minimum required for CAS authentication. Features like gateway, renew, and proxies are not supported. An alpha version of the presentation system should be online to play with later this week.</div
></content
><author
><name
>Brian Beck</name
><email
>brian.beck@case.edu</email
><uri
>http://blog.case.edu/bmb12</uri
></author
></entry
><entry
><title
>Workshop: Making Databases Fun with Python</title
><link href="http://blog.case.edu/bmb12/2006/11/workshop_making_databases_fun_with_python"
 /><id
>http://blog.case.edu/bmb12/2006/11/workshop_making_databases_fun_with_python</id
><published
>2006-11-20T17:13:41Z</published
><updated
>2006-11-20T17:14:11Z</updated
><category term="Case" label="Case"
 /><category term="Case" label="Case"
 /><category term="Programming" label="Programming"
 /><category term="Python" label="Python"
 /><content type="xhtml"
><div xmlns="http://www.w3.org/1999/xhtml"
>
<strong>Reminder!</strong> This is today! Did you ever notice how writing SQL is not very fun? This 
<strong>Monday (November 20th)</strong> on behalf of Case 
<a href="http://wiki.case.edu/Project_Club">Project Club</a>, I will be hosting a workshop for those interested in Python and databases. The talk will be at 
<strong>7:01 PM (sharp) until 8:30 PM in the Olin 303 classroom/computer lab</strong>. I'll have Python all set up for everyone to play with and follow along. Pizza and drinks will be provided! 
<a href="http://www.python.org">Python</a> is a powerful dynamic programming language suitable for many tasks, including data analysis for research, web programming, and just plain fun. Even if you don't know Python, there won't be any crazy wizardry going on during the worskhop, so you should be able to pick up the basics very quickly. Some contents of the talk will include:
<ul>
<li>Simple data/object persistence, for when SQL is overkill.</li>
<li>The dbapi, a standardized interface for talking to databases with Python.</li>
<li>An overview of object-relational mappers that will let you harness the power of relational databases without writing a single line of SQL (and easily swap out SQL backends).</li>
<li>Construction of a database application during the workshop everyone can play with, made with 
<a href="http://www.djangoproject.com">Django</a>'s object-relational mapper (or perhaps 
<a href="http://www.sqlalchemy.org">SQLAlchemy</a>).</li>
</ul>Again, no prior knowledge of Python or any of the related libraries is required. Hope to see you there! 
<a href="http://blog.case.edu/bmb12/2006/11/17/databases_72.png">
<img alt="databases_72.png" src="http://blog.case.edu/bmb12/2006/11/17/databases_72-thumb.png" width="320" height="452" />
</a></div
></content
><author
><name
>Brian Beck</name
><email
>brian.beck@case.edu</email
><uri
>http://blog.case.edu/bmb12</uri
></author
></entry
><entry
><title
>Java Has Been Open Sourced</title
><link href="http://blog.case.edu/jeremy.smith/2006/11/13/java_has_been_open_sourced"
 /><id
>http://blog.case.edu/jeremy.smith/2006/11/13/java_has_been_open_sourced</id
><published
>2006-11-13T08:05:31Z</published
><updated
>2006-11-13T08:07:20Z</updated
><category term="Programming" label="Programming"
 /><category term="java" label="java"
 /><category term="linkblog" label="linkblog"
 /><category term="open source" label="open source"
 /><category term="sun" label="sun"
 /><content type="xhtml"
><div xmlns="http://www.w3.org/1999/xhtml"
>
<a title="ongoing &#239;&#191;&#189; Java Is Free" href="http://www.tbray.org/ongoing/When/200x/2006/11/12/OSS-Java">Java Is GPLed</a> It's about 5 years late but better late than never. Though, the move certainly smacks of Java trying to fight against its own obsolescence (how excited would anyone be if Microsoft suddenly GPLed the VB compiler (ignore the distinction with the .Net runtime, please)?). The next move they 
<em>really</em> need to take is to deprecate anything with the three letters "
<strong>JSR</strong>" in front of it and move to a more socially constructive path of standardization.</div
></content
><author
><name
>Jeremy Smith</name
><email
>jeremy.smith@case.edu</email
><uri
>http://blog.case.edu/jeremy.smith</uri
></author
></entry
><entry
><title
>Two Programmers</title
><link href="http://blog.case.edu/jeremy.smith/2006/11/03/two_programmers"
 /><id
>http://blog.case.edu/jeremy.smith/2006/11/03/two_programmers</id
><published
>2006-11-03T16:41:01Z</published
><updated
>2006-11-03T16:40:11Z</updated
><category term="General Information Technology" label="General Information Technology"
 /><category term="Programming" label="Programming"
 /><category term="it" label="it"
 /><category term="joke" label="joke"
 /><category term="linkblog" label="linkblog"
 /><category term="project management" label="project management"
 /><content type="xhtml"
><div xmlns="http://www.w3.org/1999/xhtml"
>
<a title="The Parable of the Two Programmers" href="http://www.csd.uwo.ca/staff/magi/personal/humour/Computer_Audience/The%20Parable%20of%20the%20Two%20Programmers.html">The Parable of the Two Programmers</a> An oldie but goodie. You have to read it through to the end.</div
></content
><author
><name
>Jeremy Smith</name
><email
>jeremy.smith@case.edu</email
><uri
>http://blog.case.edu/jeremy.smith</uri
></author
></entry
><entry
><title
>Automating Case Wiki Tasks</title
><link href="http://blog.case.edu/bmb12/2006/10/automating_case_wiki_tasks"
 /><id
>http://blog.case.edu/bmb12/2006/10/automating_case_wiki_tasks</id
><published
>2006-10-22T03:41:38Z</published
><updated
>2006-10-24T00:01:38Z</updated
><category term="Programming" label="Programming"
 /><category term="Python" label="Python"
 /><category term="Wiki" label="Wiki"
 /><content type="xhtml"
><div xmlns="http://www.w3.org/1999/xhtml"
>
<p>A while ago 
<a href="http://blog.case.edu/csh11/">Chris</a> added a 
<code>login</code> method to the 
<a href="http://opensource.case.edu/projects/CaseClasses/browser/python/trunk/Case/case_cas.py">CAS module</a> in 
<a href="http://opensource.case.edu/projects/CaseClasses/">CaseClasses</a>. It returns a 
<a href="http://wwwsearch.sourceforge.net/mechanize/">mechanize</a> Browser object so that you can programmatically surf the web as if you had logged into CAS in a real web browser.</p>
<p>CaseClasses also has a 
<a href="http://opensource.case.edu/projects/CaseClasses/browser/python/trunk/Case/case_codes.py">Codes module</a> that has the abbreviated codes for majors, departments, and 
<strong>buildings</strong>. I combined these two features to tackle the 
<a href="http://wiki.case.edu/CaseWiki:Projects/Building_codes">Building codes project</a> on the 
<a href="http://wiki.case.edu">Case Wiki</a>.</p>
<p>
<strong>P.S.:</strong> There is a 
<a href="http://wiki.case.edu/api.php">MediaWiki API</a> that would normally be used to do this kind of stuff, but 
<a href="http://wiki.case.edu/User_talk:Brian.Beck">according to Greg</a>, editing is not fully functional yet.</p>
<p>Think you could add a lot to the wiki with some automated task? Here's how it was done.</p>
<p>First, you'll need 
<a href="http://wwwsearch.sourceforge.net/mechanize/">mechanize</a> and CaseClasses:</p>
<pre>
<code>$ sudo easy_install mechanize
$ sudo easy_install http://opensource.case.edu/svn/CaseClasses/python/trunk
</code>
</pre>
<p>Now log into CAS with mechanize:</p>
<pre>
<code>import Case
from getpass import getpass

username = 'bmb12'
password = getpass() # Enter a password without echoing

cas = Case.CAS()
browser = cas.login(username, password)
</code>
</pre>
<p>You can open any page with 
<code>browser</code> and interact with it as a logged in Case user. So let's go to the Case Wiki and log in:</p>
<pre>
<code>browser.set_handle_robots(False)
browser.open("http://wiki.case.edu")
browser.follow_link(text_regex='Log In')
</code>
</pre>
<p>Editing can be done like so:</p>
<pre>
<code>browser.open("http://wiki.case.edu/User:Brian.Beck")
<br />browser.follow_link(text='Edit this page')
browser.select_form(name='editform')
browser['wpTextbox1'] += " Also, this guy sucks!"
browser.submit()
</code>
</pre>
<p>Automating the building code edits was done like so:</p>
<pre>
<code>for code, name in Case.Codes.buildings.iteritems():
    url = "http://wiki.case.edu/%s" % name.replace(' ', '_')
    try:
        browser.open(url)
    except:
        print "Didn't find %r." % name
    else:
        browser.follow_link(text='Edit this page')
        browser.select_form(name='editform')
        source = browser['wpTextbox1']
        add_text = "The building code for %s is [[building code:=%s]].\r\n"
        add_text %= (name, code)
        if 'code:=' not in source:
            insert_at = source.find('{{Building')
            if insert_at != -1:
                new_source = source[:insert_at] + add_text + source[insert_at:]
            else:
                new_source = source + add_text
            browser['wpTextbox1'] = new_source
            browser.submit()
            print "Added building code for %r." % name
</code>
</pre>
<p>Happy automating!</p>
<strong>Update:</strong> The same has now been done for the 
<a href="http://wiki.case.edu/CaseWiki:Projects/Street_addresses">Street addresses project</a>. Check out 
<a href="http://wiki.case.edu/CaseWiki_talk:Projects/Street_addresses">the discussion</a> to see how.</div
></content
><author
><name
>Brian Beck</name
><email
>brian.beck@case.edu</email
><uri
>http://blog.case.edu/bmb12</uri
></author
></entry
><entry
><title
>geopy 0.93 Released: distance, util, GeoNames</title
><link href="http://blog.case.edu/bmb12/2006/10/geopy_093_released_distance_util_geonames"
 /><id
>http://blog.case.edu/bmb12/2006/10/geopy_093_released_distance_util_geonames</id
><published
>2006-10-08T23:48:36Z</published
><updated
>2006-10-09T00:02:31Z</updated
><category term="Programming" label="Programming"
 /><category term="Projects" label="Projects"
 /><category term="Python" label="Python"
 /><content type="xhtml"
><div xmlns="http://www.w3.org/1999/xhtml"
>Finally released 
<a href="http://cheeseshop.python.org/pypi/geopy/0.93">geopy 0.93</a>, which contains the 
<a href="http://blog.case.edu/bmb12/2006/09/geopy_gets_distance_and_util_modules">distance and util modules I previously mentioned</a>, a 
<a href="http://www.geonames.org/">GeoNames</a> geocoder, and improvements to the Google geocoder in other formats. Updating 
<a href="http://exogen.case.edu/projects/geopy/">the documentation</a> was all that was holding it back, really. You can now pass 
<code>domain</code> and 
<code>resource</code> arguments to the Google geocoder. To query the actual Google Maps interface (instead of their official HTTP geocoder), initialize like so:
<pre>
<code>g = geocoders.Google(resource='maps')</code>
</pre>The JavaScript results tend to be the best for this resource, so change that as well:
<pre>
<code>g = geocoders.Google(resource='maps', output_format='js')</code>
</pre>Finally, for geocoding addresses outside of the US, change the domain being queried:
<pre>
<code>g = geocoders.Google(domain='maps.google.co.uk', resource='maps', output_format='js')</code>
</pre>As 
<a href="http://groups-beta.google.com/group/geopy/browse_frm/thread/3ad6a1f131342a32">James Robinson brought up on the geopy mailing list</a>, work is under way for accuracy support. This will let you determine how precise the geocoded result is for the given location. For example, is it only guaranteed to be the correct city? Street? Is it the exact address? I decided to release this version of geopy without completing this, because not much work is done so far (and we also want to normalize values across geocoders), and the distance module was a pretty big addition. To upgrade:
<pre>
<code>sudo easy_install geopy</code>
</pre></div
></content
><author
><name
>Brian Beck</name
><email
>brian.beck@case.edu</email
><uri
>http://blog.case.edu/bmb12</uri
></author
></entry
><entry
><title
>A Web-Based Presentation System for Case</title
><link href="http://blog.case.edu/bmb12/2006/10/a_webbased_presentation_system_for_case"
 /><id
>http://blog.case.edu/bmb12/2006/10/a_webbased_presentation_system_for_case</id
><published
>2006-10-02T05:37:15Z</published
><updated
>2006-10-02T10:08:03Z</updated
><category term="Case" label="Case"
 /><category term="JavaScript" label="JavaScript"
 /><category term="Programming" label="Programming"
 /><category term="Projects" label="Projects"
 /><content type="xhtml"
><div xmlns="http://www.w3.org/1999/xhtml"
>If you saw the new 
<a href="http://www.eecs.case.edu/tech/bounties">EECS department bounty system</a>, you may have noticed the bounty for a web-based presentation system. This is now a work-in-progress by yours truly. The goal is to let Case people generate slideshows through the web with Case-themed templates, mostly for use on the plasma displays in the EECS department (well, the displays that 
<em>will be</em> in Glennan). Another use could be by faculty in place of PowerPoint (so it should have familiar features such as transitions). You may have seen those displays in the fishbowl last year showing pictures and such. Apparently these are a pain to administer because they are connected by a wireless connection and thus are not easy to connect to via Remote Desktop. So when they are rebooted or PowerPoint closes somehow, getting the slideshow back up and running can be a real hassle. Having them in kiosk mode in a web browser will allow them to easily refresh if anything goes wrong, and will also let them grab updated content. This is how the plasma displays around campus show their (I think Flash-based) slideshows. There are two such tools on which to base such a system: 
<a href="http://meyerweb.com/eric/tools/s5/">S5</a> and 
<a href="http://www.w3.org/Talks/Tools/Slidy/">Slidy</a>. If you've ever viewed a text-based presentation online, it was probably with S5. This is the first time I have heard of Slidy, but it actually looks a lot better to me. Every time I've encountered S5 in the wild, the JavaScript has eventually completely messed up the text sizing and positioning, making everything unreadable. There are existing services that combine web presentation systems with editing and sharing, such as 
<a href="http://rubyforge.org/projects/s5presents/">S5 Presents</a> and 
<a href="http://soapbx.com/">SoapBX</a>. SoapBX is not open source while S5 Presents is GPL licensed and in Ruby. I would have no problem with using S5 Presents, but apparently it has gone unmaintained for almost two years, and Simon was disappointed when he looked into configuring it to run under a real web server. Tonight I decided to see what actually using S5 is like, so I customized the default theme to resemble the Case PowerPoint template found on the 
<a href="http://www.case.edu/univrel/marcomm/branding/logos/index.html">Case branding page</a>. So here is my 
<a href="http://exogen.case.edu/s5/s5-blank/s5-blank/s5-case.html">Case-themed S5 presentation</a>. It's pretty incomplete and doesn't match exactly, but it's close (and anyway, the goal is to make it look good, not match exactly&#8212;their PowerPoint template could use some work). When I first considered this bounty, I thought "hmm, web-based, which web framework will I use?" One of the major goals is to be easily maintainable once I leave, so something popular or at least very easy would be the best choice. Which best fits this description? 
<a href="http://www.djangoproject.com">Django</a>? 
<a href="http://www.turbogears.org/">TurboGears</a>? 
<a href="http://webpy.org/">web.py</a>? I've never really considered the maintainability of any of these, since usually I can choose whichever I like at the moment. After a bit of talking with 
<a href="http://blog.case.edu/csh11">Chris</a>, we determined that any server-side code at all isn't even really needed. The only thing it would be used for is to display view and edit pages for the presentations and to store them. The first two can be done with static HTML and JavaScript, while the third can be used by POSTing with AJAX to some location. For example, we could POST presentations to the 
<a href="http://www.eecs.case.edu/wiki/dokuwiki">EECS department's new DokuWiki-powered site</a> with the appropriate permissions. Since S5 and Slidy presentations are just HTML, the wiki page itself would be the presentation outline, and the slideshow viewer could just grab the markup from there. Or we could use AJAX to upload the presentation via WebDAV to the author's 
<a href="http://filer.case.edu">Filer</a> account. Since there would be heavy JavaScript usage regardless of the selected framework, the author would need to be fluent in it anyway. So why not a pure JavaScript solution, given the possibilities above? This is what I'll be looking into for the next few weeks. The code will soon live at 
<a href="http://opensource.case.edu/projects/present/">opensource.case.edu/projects/present</a>. If anyone has experience with S5 or Slidy and would like to share their opinions, please do (even if it's just which system you like more).</div
></content
><author
><name
>Brian Beck</name
><email
>brian.beck@case.edu</email
><uri
>http://blog.case.edu/bmb12</uri
></author
></entry
><entry
><title
>dmath: Math routines for Python's arbitrary-precision Decimal type</title
><link href="http://blog.case.edu/bmb12/2006/09/dmath_math_routines_for_pythons_arbitraryprecision_decimal_type"
 /><id
>http://blog.case.edu/bmb12/2006/09/dmath_math_routines_for_pythons_arbitraryprecision_decimal_type</id
><published
>2006-09-25T20:27:33Z</published
><updated
>2006-09-25T20:31:14Z</updated
><category term="Programming" label="Programming"
 /><category term="Projects" label="Projects"
 /><category term="Python" label="Python"
 /><content type="xhtml"
><div xmlns="http://www.w3.org/1999/xhtml"
>Yesterday 
<a href="http://blog.case.edu/csh11/">Chris</a> and I spent all day writing math functions for 
<a href="http://docs.python.org/lib/module-decimal.html">Python's Decimal type</a>. The result is our new 
<a href="http://cheeseshop.python.org/pypi/dmath">dmath</a> library, 
<a href="http://code.google.com/p/dmath/">available on Google Code</a> and the 
<a href="http://cheeseshop.python.org/pypi/dmath">Cheese Shop</a> under the MIT/X11 license. Sparked by the routine for 
<code>atan</code> in 
<a href="http://blog.case.edu/bmb12/2006/09/geocoding_and_pythons_decimal_module">my last post</a>, I decided it wouldn't be too hard to go ahead and do the rest of the functions already offered by 
<code>math</code> and 
<code>cmath</code>. We now have 
<code>acos</code>, 
<code>asin</code>, 
<code>atan</code>, 
<code>atan2</code>, 
<code>ceil</code>, 
<code>cos</code>, 
<code>cosh</code>, 
<code>degrees</code>, 
<code>e</code>, 
<code>exp</code>, 
<code>floor</code>, 
<code>golden_ratio</code>, 
<code>hypot</code>, 
<code>log</code>, 
<code>log10</code>, 
<code>pi</code>, 
<code>pow</code>, 
<code>radians</code>, 
<code>sign</code>, 
<code>sin</code>, 
<code>sinh</code>, 
<code>sqrt</code>, 
<code>tan</code>, and 
<code>tanh</code>. Check it out:
<pre>
<code>&gt;&gt;&gt; from dmath import *
&gt;&gt;&gt; from decimal import Decimal as D, getcontext
&gt;&gt;&gt; getcontext().prec = 50
&gt;&gt;&gt; asin(D(1))
Decimal("1.5707963267948966192313216916397514420985846996876")
&gt;&gt;&gt; golden_ratio()
Decimal("1.6180339887498948482045868343656381177203091798058")
</code>
</pre>We're calling this release 0.9 because it just needs some testing and maybe some speed improvements, otherwise it's ready to use. There is currently some 
<a href="http://svn.python.org/projects/sandbox/trunk/decimal-c/">work being done</a> in Python sandbox/trunk to convert the decimal module to C, and maybe they'll include fast versions of all these routines. But hey, you can use these right now! Arbitrary precision is one of the coolest things in programming. We spent a lot of time in 
<a href="http://www.wolfram.com/">Mathematica</a>, where if you ask it to tell you the precision, it says 'Infinity'. During our testing, we actually stumbled across a bug in 
<a href="http://functions.wolfram.com/ElementaryFunctions/ArcTan2/">Mathematica's ArcTan function</a>! 
<a href="http://functions.wolfram.com/ElementaryFunctions/ArcTan2/03/01/01/">This page</a> correctly states that ArcTan[-Infinity, y] should always be Pi (with the sign of y). However, Mathematica always returns 0. I sent a message with my findings to the 
<a href="http://groups.google.com/group/comp.soft-sys.math.mathematica">Mathematica mailing list</a> and Daniel Lichtblau of Wolfram Research confirmed that it is indeed a simple bug. ArcTan users, beware! Anyway, enjoy 
<a href="http://cheeseshop.python.org/pypi/dmath">dmath</a>. Contributions are welcome, especially if you have any speed tips!</div
></content
><author
><name
>Brian Beck</name
><email
>brian.beck@case.edu</email
><uri
>http://blog.case.edu/bmb12</uri
></author
></entry
><entry
><title
>Geocoding and Python's decimal module</title
><link href="http://blog.case.edu/bmb12/2006/09/geocoding_and_pythons_decimal_module"
 /><id
>http://blog.case.edu/bmb12/2006/09/geocoding_and_pythons_decimal_module</id
><published
>2006-09-24T09:56:00Z</published
><updated
>2006-09-24T20:56:23Z</updated
><category term="Programming" label="Programming"
 /><category term="Projects" label="Projects"
 /><category term="Python" label="Python"
 /><category term="geopy" label="geopy"
 /><content type="xhtml"
><div xmlns="http://www.w3.org/1999/xhtml"
>Python has an awesome 
<a href="http://docs.python.org/lib/module-decimal.html">decimal module</a> for decimal floating point arithmetic. It has configurable precision and keeps track of significant digits and does some other neat stuff. While I was adding the 
<a href="http://blog.case.edu/bmb12/2006/09/geopy_gets_distance_and_util_modules">geopy distance module</a>, I began to wonder if it would be worth the effort to switch everything in geopy over to use Decimals instead of floats. After checking out the decimal module (I had never used it before), I decided that I had nothing to lose, so I went for it... I quickly ran into some snags when I realized that I'd have to code my own trigonometric functions for use with Decimals, since those that come with Python are for complex or floating point numbers. The 
<a href="http://docs.python.org/lib/decimal-recipes.html">decimal recipes</a> page in the documentation has functions for 
<code>sin</code> and 
<code>cos</code>, but 
<code>distance</code> uses 
<code>asin</code>, 
<code>acos</code>, 
<code>atan</code>, and 
<code>atan2</code>. 
<a href="http://www.gdssw.com">Don Peterson</a> has a nice 
<a href="http://cheeseshop.python.org/pypi/decimalfuncs">decimalfuncs module</a> with most of these, but it's GPL (and would be an uncommon dependency) &#8212; geopy is 
<a href="http://www.opensource.org/licenses/mit-license.php">MIT/X11</a>. So I went ahead and started on these... I decided it would be easiest to define 
<code>asin</code> and 
<code>acos</code> in terms of 
<code>atan</code>, and it turns out there is a (relatively) quickly converging algorithm for that. Here's what I came up with for a Decimal-compatible 
<code>atan</code>:
<pre>
<code>def atan(x):
    if x == D('-Inf'):
        return pi() / -2
    elif x == 0:
        return D(0)
    elif x == D('Inf'):
        return pi() / 2
    
    if x &lt; -1:
        c = pi() / -2
        x = 1 / x
    elif x &gt; 1:
        c = pi() / 2
        x = 1 / x
    else:
        c = 0
    
    getcontext().prec += 2
    x_squared = x ** 2
    y = x_squared / (1 + x_squared)
    y_over_x = y / x
    i, lasts, s, coeff, num = D(0), 0, y_over_x, 1, y_over_x
    while s != lasts:
        lasts = s    
        i += 2
        coeff *= i / (i + 1)
        num *= y
        s += num * coeff
    if c:
        s = c - s
    getcontext().prec -= 2
    return +s
</code>
</pre>It depends on the 
<code>pi</code> function from the 
<a href="http://docs.python.org/lib/decimal-recipes.html">decimal recipes page</a>, which calculates pi to the currently configured precision. Upon finishing this, 
<a href="http://blog.case.edu/csh11/">Chris</a> came home and I told him what I was doing. Immediately, he tried to talk me out of it, asserting that floating point was good enough for geocoding. I tried to counter by explaining all the floating point calculations being performed in 
<code>distance</code>, but in the end he won. I no longer think it would be a very important change to convert everything in geopy to use the Decimal type. What finally convinced me was this quote from the 
<a href="http://www.movable-type.co.uk/scripts/LatLongVincenty.html">Vincenty distance page</a> I used for reference:
<blockquote>Vincenty&#226;&#8364;&#8482;s formula is accurate to within 0.5mm, or 0.000015&#226;&#8364;&#179; (!), on the ellipsoid being used.</blockquote>0.000015 arcseconds is about 4.16667e-9 degrees. Well, if floating point is good to about 10 decimal places, I guess Chris wins this time... Still, if anyone wants Decimal support in the future, maybe I'll just ask Don Peterson for permission to include decimalfuncs with geopy... 
<strong>Update:</strong> On second thought, maybe I will just continue implementing my own trig functions for Decimals. Chris and I just spent a while investigating the precision of my atan vs. decimalfunc's, and mine seems to be faster and more precise.</div
></content
><author
><name
>Brian Beck</name
><email
>brian.beck@case.edu</email
><uri
>http://blog.case.edu/bmb12</uri
></author
></entry
><entry
><title
>geopy gets distance and util modules</title
><link href="http://blog.case.edu/bmb12/2006/09/geopy_gets_distance_and_util_modules"
 /><id
>http://blog.case.edu/bmb12/2006/09/geopy_gets_distance_and_util_modules</id
><published
>2006-09-24T09:20:50Z</published
><updated
>2006-10-08T23:02:07Z</updated
><category term="Programming" label="Programming"
 /><category term="Projects" label="Projects"
 /><category term="Python" label="Python"
 /><category term="geopy" label="geopy"
 /><content type="xhtml"
><div xmlns="http://www.w3.org/1999/xhtml"
>If you check out 
<a href="http://geopy.googlecode.com/svn/trunk/">geopy trunk</a> right now you'll notice a few changes. I introduced two modules: 
<a href="http://geopy.googlecode.com/svn/trunk/geopy/util.py">
<code>util</code>
</a> and 
<a href="http://geopy.googlecode.com/svn/trunk/geopy/distance.py">
<code>distance</code>
</a>. 
<code>util</code> now contains the 
<code>parse_geo</code> and 
<code>arc_angle</code> functions, and will grow more in the future. 
<code>distance</code> is a bigger addition and contains helpful functions for calculating geodesic distances. I planned to add this eventually, but development was sparked by a request from 
<a href="http://polimetrix.com">Chris Mulligan</a>. There are two distance formulas: 
<a href="http://en.wikipedia.org/wiki/Great-circle_distance">Great-circle (aka haversine, aka spherical law of cosines) distance</a> and 
<a href="http://www.movable-type.co.uk/scripts/LatLongVincenty.html">Vincenty distance</a>. Great-circle distance uses a spherical model of the earth, using the average great-circle radius of 6372.795 kilometers (this is configurable). This results in an error of up to about 0.5%. Vincenty distance uses a more accurate ellipsoidal model of the earth. This is the default distance formula, and is thus aliased as 
<code>distance.distance</code> &#8212; so you can easily swap out distance formulas just by changing 
<code>distance.distance</code> at the top of your code. There are multiple popular ellipsoidal models, and which one will be the most accurate depends on where your points are located on the earth. geopy includes a few good models in the 
<code>distance.ELLIPSOIDS</code> dictionary:
<pre>
<code>#             model             major (km)   minor (km)     flattening
ELLIPSOIDS = {'WGS-84':        (6378.137,    6356.7523142,  1 / 298.257223563),
              'GRS-80':        (6378.137,    6356.7523141,  1 / 298.257222101),
              'Airy (1830)':   (6377.563396, 6356.256909,   1 / 299.3249646),
              'Intl 1924':     (6378.388,    6356.911946,   1 / 297.0),
              'Clarke (1880)': (6378.249145, 6356.51486955, 1 / 293.465),
              'GRS-67':        (6378.1600,   6356.774719,   1 / 298.25),
              }
</code>
</pre>Here's an example usage of 
<code>distance.distance</code>:
<pre>
<code>&gt;&gt;&gt; from geopy import distance
&gt;&gt;&gt; import Case
&gt;&gt;&gt; wiki = Case.Geocode.CaseWikiGeocoder()
&gt;&gt;&gt; _, a = wiki.geocode('Wade')
&gt;&gt;&gt; _, b = wiki.geocode('Fribley')
&gt;&gt;&gt; distance.distance(a, b).kilometers
1.342250272726943
&gt;&gt;&gt; distance.distance(a, b).miles
0.83403565192666562
</code>
</pre>Using Great-circle distance:
<pre>
<code>&gt;&gt;&gt; distance.distance = distance.GreatCircleDistance
&gt;&gt;&gt; distance.distance(a, b).miles
0.835175984734287
</code>
</pre>You can change the ellipsoid model used by the Vincenty formula like so:
<pre>
<code>&gt;&gt;&gt; distance.VincentyDistance.ELLIPSOID = 'Intl 1924'
</code>
</pre>The above model name will automatically be retrieved from the ELLIPSOIDS dictionary. Alternatively, you can specify the model values directly:
<pre>
<code>&gt;&gt;&gt; distance.VincentyDistance.ELLIPSOID = (6377., 6356., 1 / 297.)
</code>
</pre>Oh yeah, you can add distances too (for paths and such). Here's the distance from 
<a href="http://wiki.case.edu/Fribley">Fribley</a> to 
<a href="http://wiki.case.edu/Wade">Wade</a> to 
<a href="http://wiki.case.edu/Phi_Kappa_Theta">Phi Kappa Theta</a>:
<pre>
<code>&gt;&gt;&gt; _, c = wiki.geocode('Phi Kappa Theta')
&gt;&gt;&gt; (distance.distance(b, a) + distance.distance(a, c)).miles
1.0596624112817861
</code>
</pre>Also included in the 
<code>distance</code> module are functions for converting between length units (kilometers, miles, feet, nautical miles), and calculating a destination given a starting point, initial bearing, and distance. This stuff is still just in trunk, no egg or updated documentation yet...</div
></content
><author
><name
>Brian Beck</name
><email
>brian.beck@case.edu</email
><uri
>http://blog.case.edu/bmb12</uri
></author
></entry
></feed
>