tag:blogger.com,1999:blog-104043992024-03-12T19:44:02.675-04:00Revotera VojaĝoSemi-random musings on various (mostly technical) topics.Fenerichttp://www.blogger.com/profile/02260982910947326581noreply@blogger.comBlogger12125tag:blogger.com,1999:blog-10404399.post-20010122636648740552009-12-30T13:48:00.006-05:002009-12-30T14:44:58.426-05:00End-of-Year Miscellanea<p>I haven't posted too much lately. Here and there I have been working on a few interesting projects; I continue to add little bits of functionality to <a href="http://www.antichristwatch.net/" title="Go to Antichrist Watch">Antichrist Watch</a> and have added dojox.gfx vector graphics to a handful of sites (including among others <a href="http://www.nearta.com/" title="Go to the NEARTA site">NEARTA</a>, <a href="http://www.keepsaugusatown.info/" title="Go to the Keep Saugus a Town site">Keep Saugus A Town</a>, and <a href="http://www.shiningstarslearningcenter.com/" title="Go to the Shining Stars site">Shining Stars Learning Center</a>). Using dojox.gfx vector graphics is really interesting; it enables the sizing of elements within a site to be completely based on em size and/or window size without significant increase in load times or loss of graphical clarity. My <a href="http://dist.saugus.net/" title="Grab the original svg2gfx.xslt">svg2gfx.xslt</a> utility was recently promoted to <a href="http://www.dojotoolkit.org/" title="Go to the Dojo Toolkit community site">Dojo</a> proper (in time for the 1.4 release), too, and this should hopefully make creating dojox.gfx graphics a bit simpler for some. I'll try to write something up describing the general process of making a vector image logo for a site in the relative near future. I've also been messing around with getting egg-based builds of <a href="http://zope2.zope.org/" title="Go to the Zope community site">Zope 2</a> and <a href="http://www.plone.org/" title="Go to the Plone community site">Plone</a> working under <a href="http://www.repoze.org/" title="Go to the Repoze community site">Repoze</a> with varying degrees of success. I don't have a solid, simple enough solution for either of these to post much of anything yet.</p>
<p>I've also spent a not-insignificant time lately messing around with e-mail. I've been using Apple's Mail.app for awhile now, and whenever I've needed encryption I've simply used its built-in <abbr title="Secure / Multipurpose Internet Mail Extensions ">S/MIME</abbr> capabilities. With a free Thawte client certificate, it was extremely easy to set up and just worked everywhere. As you're probably aware, Thawte recently dropped its free certificate service. This meant that I had to change my ways. The simplest path was to start using the free <a href="http://www.cacert.org/" title="Go to the CA Cert site">CAcert</a> service for client certificates and instruct those with whom I'd already been communicating via <abbr title="Secure / Multipurpose Internet Mail Extensions ">S/MIME</abbr> to pull in the appropriate root certificates. I did this fairly painlessly (although I still have to hunt around for some locals willing to vouch for my <abbr title="identity">ID</abbr>; if you're in the North-of-Boston area and willing to do so, please drop me a line). As I'll be working more closely with the <a href="http://www.sitepen.com/" title="Go to SitePen">SitePen</a> folks though in the near future and they all use <abbr title="Pretty Good Privacy">PGP</abbr> I wanted to get it working as well. Sadly, Mail.app does not have the nice built-in support for <abbr title="Pretty Good Privacy">PGP</abbr> that it does for <abbr title="Secure / Multipurpose Internet Mail Extensions ">S/MIME</abbr>; to make matters worse, the <a href="http://gpgmail.sourceforge.net/" title="Go to the GPGMail site">GPGMail plug-in</a> to give Mail.app <abbr title="Pretty Good Privacy">PGP</abbr> capabilities isn't quite yet ready for the current version of Mail.app. There are some unofficial releases available through the forums, and I got the newest of these to work. Thus I now (finally) have both <abbr title="Secure / Multipurpose Internet Mail Extensions ">S/MIME</abbr> and <abbr title="Pretty Good Privacy">PGP</abbr> signing & encryption working for my e-mail. (Although I also have to hunt around for locals to sign my <abbr title="Pretty Good Privacy">PGP</abbr> key; if you're in the North-of-Boston area and willing to do so, please drop me a line.)</p>Fenerichttp://www.blogger.com/profile/02260982910947326581noreply@blogger.com0tag:blogger.com,1999:blog-10404399.post-42672348052358997852009-10-04T21:37:00.005-04:002009-10-04T23:07:32.496-04:00Plone, Repoze, and the Dojo Toolkit<p>I was hoping it would be made public a couple weeks ago in September, but it just went live this weekend. It's the first of a series of sites <a href="http://www.saugus.net/" title="Go to Saugus.net">Saugus.net</a> has been working on to utilize cross-platform vector graphics via the <a href="http://www.dojotoolkit.org/" title="Go to the Dojo Toolkit site">Dojo Toolkit</a>. To make it more interesting, most of these sites also use the <a href="http://www.plone.org/" title="Go to the Plone site">Plone</a> <abbr title="Content Management System">CMS</abbr>.</p><p>Plone and Dojo don't coexist so easily. There is an old product called <a href="http://plone.org/products/zpdojo" title="Go to the ZPDojo site">ZPDojo</a> (with a slightly newer <a href="http://blog.delaguardia.com.mx/plone-and-dojo-80004004-strikes-again">fork</a>) that managed to pull it off a few years ago, but it was using an old version of Dojo. I decided to take a different approach and instead used <a href="http://www.repoze.org/" title="Go to the Repoze site">Repoze</a> and <a href="http://deliverance.openplans.org/" title="Go to the Deliverance site">Deliverance</a> to layer the Dojo portion in a logically separate portion from the Plone portion. By doing so it became fairly straightforward to use Dojo's excellent build system to build the requisite custom JavaScript package to insert into the Deliverance portion while continuing to use Plone's own excellent merge system to operate on Plone's requisite JavaScript (and even preserve <abbr title="Kinetic Style Sheets">KSS</abbr> capabilities).</p><p>All is not perfect. <abbr title="Kinetic Style Sheets">KSS</abbr> relies upon <a href="http://www.jquery.com/" title="Go to the JQuery site">JQuery</a>; theoretically this is somewhat wasteful as by pulling in Dojo's <abbr title="Graphics">GFX</abbr> package one is already getting pretty much all the capabilities that JQuery offers resulting in a slightly slower-than-necessary initial load time, and practically it breaks unless one removes JQuery from Plone's automerge system and pulls it in manually. The next version of Dojo has a JQuery compatibility package planned, so long term the theoretical solution is probably one of removing JQuery entirely and relying on the compatibility package (perhaps even gaining a bit of <a href="http://dante.dojotoolkit.org/taskspeed/" title="Test the speed of JavaScript toolkits">speed</a>), but it's still early to say for certain. In the meanwhile, separating out JQuery from the rest of the Plone JavaScript source files and linking it directly solves the practical problem.</p><p>The site in question is the <a href="http://www.shiningstarslearningcenter.com/" title="Go to the Shining Stars site">Shining Stars Learning Center</a>. They wanted lots of stars on a light blue background, and they got them in spades. A single star drawing routine is looped through a number of times based upon the client's screen size, filling the current browser window (actually the maximum possible browser window should the window be resized) with stars of random size, rotation, and position. To add a bit of whimsy, all the stars can be independently dragged around the window.</p><p>The Shining Stars logo in the upper left hand corner is also drawn via vector graphics, although it can't be moved. I disallowed stars being drawn behind it in the initial star populating phase, but they can be dragged behind it after the window has been drawn. It was converted from <abbr title="Scalable Vector Graphics">SVG</abbr> to Dojo <abbr title="Graphics">GFX</abbr> <acronym title="JavaScript Object Notation">JSON</acronym> using <a href="http://dist.saugus.net/">my fork</a> of <a href="http://archive.dojotoolkit.org/nightly/dojotoolkit/dojox/gfx/demos/data/">svg2gfx.xsl</a> (which will soon hopefully go into the main trunk).</p><p>The whole site, including the logo and stars, is built around em size, so resizing the text causes the logo and stars to resize accordingly, too, and since they're defined using vectors they never get fuzzy.</p><p>Actually, for the fun of it I tried copying a few of the resulting vector images into bitmap images (one of which is used for the <a href="http://twitter.com/ShiningStarsLC" title="Go to the Shining Stars Twitter page">Shining Stars Twitter</a> background). Besides being noticeably fuzzier, the image ended up being somewhat larger than the JavaScript used to define it, too. Obviously this won't always be the case depending upon specifics (and it certainly wasn't my driving motivation; I wanted a clean appearance with nice resizing) but I found it to be an interesting perk.</p><p>When I say it's a cross-platform solution I really mean it. Not only does it work on the usual suspects (Firefox, Safari, Opera, Chrome, <abbr title="Microsoft Internet Explorer">MSIE</abbr>, etc.) but it works on the Wii Internet Channel as well. Shining Stars has a Wii in their boardroom (how cool is that?) that they can use for browsing the Web (among other things) with the Wiimote as a pointer. I thus did as much testing of the site on the Wii as I did with the other more common browsers, and it works surprisingly well. It's a bit slow rendering the vector graphics, but not disastrously so, and the star dragging even works. The only problem I had with it is that when one switches into its so-called "Single Column Mode" almost nothing gets displayed at all. This could be simply alleviated by selectively turning off some JavaScript and <abbr title="Cascading Style Sheets">CSS</abbr> when the mode is enabled, but I've yet to find a way to reliably detect it. It's not a huge worry though as the site does work fine in the Wii's default display mode.</p><p>Microsoft Internet Explorer (as usual) provided its own set of problems. While on most browsers (including the Wii Internet Channel) the Dojo <abbr title="Graphics">GFX</abbr> stuff gets rendered as <abbr title="Scalable Vector Graphics">SVG</abbr>, <abbr title="Microsoft Internet Explorer">MSIE</abbr> instead uses <abbr title="Vector Markup Language">VML</abbr>. Unfortunately Microsoft's recent crusade to catch up with other browsers' support of standards has not included standard vector graphics in the form of <abbr title="Scalable Vector Graphics">SVG</abbr>, and to make matters worse they've allowed their own <abbr title="Vector Markup Language">VML</abbr> to rot with each new version of <abbr title="Microsoft Internet Explorer">MSIE</abbr> seeming to introduce new, unaddressed <abbr title="Vector Markup Language">VML</abbr> problems. In particular, some of the vector graphics the site uses cause <abbr title="Vector Markup Language">VML</abbr> issues in <abbr title="Microsoft Internet Explorer">MSIE</abbr>8, and the only way I was able to fix it was to use the Microsoft-specific <code>X-UA-Compatible</code> to explicitly request that <abbr title="Microsoft Internet Explorer">MSIE</abbr>8 render the site as if it were really <abbr title="Microsoft Internet Explorer">MSIE</abbr>7. Since I was forced to mess with this anyway, I took it one step further and added <a href="http://code.google.com/chrome/chromeframe/">Chrome Frame</a> support with the line:</p><pre><meta http-equiv="X-UA-Compatible" content="chrome=1;IE=7"></pre><p>and dropping all <abbr title="Microsoft Internet Explorer">MSIE</abbr>-specific hacks when it is engaged.</p><p>It now uses Chrome Frame (if present) in preference to any of <abbr title="Microsoft Internet Explorer">MSIE</abbr>'s native rendering modes, and uses <abbr title="Microsoft Internet Explorer">MSIE</abbr>7 rendering mode if in a newer version (that lacks Chrome Frame). Chrome Frame is visibly faster than all of the <abbr title="Microsoft Internet Explorer">MSIE</abbr> native rendering modes for this site, so much so that we (for the moment, anyway, we may remove it) added a notice to let regular users of the site know about it in order to improve their browsing experience. I'm assuming that the speed difference is mostly due to a combination of Chrome's faster JavaScript implementation and the fact that no extra JavaScript hacks are required to make up for <abbr title="Cascading Style Sheets">CSS</abbr> deficiencies, but regardless of its source it is significant.</p><p>Please note that <a href="http://www.shiningstarslearningcenter.com/" title="Go to the Shining Stars site">the site</a> is still in a beta mode of sorts and thus may not only still have bugs but will also be in fairly frequent flux. If things don't look as you'd expect from the above description, please try again in a few minutes; you probably just caught it during an update.</p>Fenerichttp://www.blogger.com/profile/02260982910947326581noreply@blogger.com2tag:blogger.com,1999:blog-10404399.post-31321224146538933932009-08-28T12:28:00.004-04:002009-08-28T13:33:48.860-04:00Maintaining Data Integrity<p>I promised <a href="http://feneric.blogspot.com/2009/05/antichrist-structure.html" title="Read the earlier entry">several posts ago</a> that I'd discuss some of the interesting internals of <a href="http://www.antichristwatch.net/" title="Go to Antichrist Watch">Antichrist Watch</a> in more detail.</p><p>I've since gotten a bit off track, posting <a href="http://feneric.blogspot.com/2009/07/plone-33-and-repoze.html" title="Read about some Repoze stuff">three entries</a> about some of the <a href="http://www.repoze.org/" title="Go to the Repoze site">Repoze</a> stuff I've been doing lately. As I've been getting deeper and deeper into other projects I realize I'd better catch up and make good on my original promise or else I may never get back to it.</p><p>Today I figured I'd cover the principles behind Antichrist Watch's back-end database connection. It's using <a href="http://www.postgresql.org/" title="Go to the PostgreSQL site">PostgreSQL</a> and making heavy use of some of the features that many other database servers lack. In particular, PostgreSQL has great support for embedded logic (also known in database land as stored functions or stored procedures); not only does it have its own PL/pgSQL (similar to Oracle's PL/SQL) it also supports embedding code in other languages like Python, Perl, Tcl, and others besides. This embedded code can be tied into constraints that get executed (roughly) prior to a SQL command, rules that get executed (roughly) during a SQL command, and triggers that get executed after a SQL command. Additionally these stored procedures can be called directly allowing not only the effective batching of SQL commands but also multiple SQL commands bound together logically (that is, it's trivial to make a stored procedure execute one list of SQL commands under one set of conditions but execute another under a different set of conditions), or fashioned into views that behave like tables.</p><p>This combination gives the designer two big advantages over less capable database systems: first, it becomes possible to embed code to help guarantee data integrity within the database itself by careful use of constraints, rules, and triggers; and second it becomes possible to hide the database's implementation details from any client code by creating a public <abbr title="application programming interface">API</abbr> via stored procedures. Thus we're basically using information hiding and restricting data access to certain controlled channels. I'm guessing that anyone who has read this far will understand in principle why these are good things. I'll carry it further though and list some specific benefits obtained by using this type of database design.</p><p>No raw tables are accessed in Antichrist Watch. It has a database access <abbr title="application programming interface">API</abbr> fashioned from stored procedures and views. This level insulates the client from the raw tables; right now internally it is heavily normalized and even uses table inheritance to avoid repetition, but if at some point down the road it became necessary to duplicate some information for the sake of performance, the tables could be completely redesigned without requiring any change in client code whatsoever. Furthermore, with a clean interface it's easy to change clients. Antichrist Watch has had three completely different front-ends already. My original version was hacked together quickly from basic Python; my second version used <abbr title="PHP Hypertext Preprocessor ">PHP</abbr>; the current version uses <a href="http://www.twistedmatrix.com/" title="Go to the Twisted Python site">Twisted</a> and Zope Page Templates (via <a href="http://chameleon.repoze.org/" title="Go to the Chameleon site">Repoze Chameleon</a>). At each stage making the transition was reasonably easy. It would have been a bear (possibly even unthinkable) if the interface were using raw tables and the client was responsible for data integrity.</p><p>On that note it must be said that data integrity is also improved. I'm a big believer in trying to enforce data constraints as close to the data itself as practically possible. The further away the constraint enforcement is from the data, the more space there is for loopholes, security holes, and logic errors to breed. Antichrist Watch has all data constraints and relationships enforced by the database itself. Even if someone with malicious intent were to somehow get beyond the client-side JavaScript and server-side Twisted Python (or some bugs were to crop up in my code, be it client-side or server-side), the allowed options on the database side are restricted limiting the potential damage that could be done. Basically it would be possible for <em>fake</em> data to get inserted, but it would not be possible for <em>invalid</em> data to get inserted, and this can mean the difference between a minor failure (accompanied by some embarrassment) and a critical failure (accompanied by a system crash). As an added bonus overall performance also often improves by moving such data constraint enforcement into the tightly optimized world of the database server itself.</p><p>Please note that I'm not advocating the moving of all logic out of things like Zope, Twisted, or <abbr title="PHP Hypertext Preprocessor ">PHP</abbr> into the database server itself. This would be counterproductive. Tools for developing in languages like PL/pgSQL tend to be more primitive than tools for developing in languages like unembedded Python, and application logic definitely belongs outside the database. What I am advocating is making the database responsible for its own data checking while hiding its source internals.</p>Fenerichttp://www.blogger.com/profile/02260982910947326581noreply@blogger.com0tag:blogger.com,1999:blog-10404399.post-62072857278376941602009-07-31T10:26:00.004-04:002009-07-31T12:20:22.973-04:00Plone 3.3 and Repoze<p>While I've already discussed what's generally required for <a href="http://feneric.blogspot.com/2009/07/repoze-zope-plone-urispace-and.html" title="Read my earlier post">making Plone run with Repoze and mod_wsgi</a>, I had been using Plone 3.3rc3. Anyone (myself included) who's tried to sub in anything more recent (like Plone 3.3rc4) has run into a problem with version conflicts due to changes between 3.3rc3 and 3.3rc4. Specifically the upgrade of five.localsitemanager from 0.4 to 1.1 sets off a zope.component version conflict, as any version of it 1.0 or beyond tries to pull in a whole bunch of eggs that aren't really necessary. Now obviously pinning five.localsitemanager to a version less than 1.0 will allow the buildout to complete properly, but this isn't really a good solution as it creates a mutant (and thus untested) version of Plone that may or may not work in random situations.</p>
<p>The real fix isn't that hard, though. It's simply a matter of utilizing fake Zope 2 eggs. The only catch here is that in order for them to work, they must be in place <em>before</em> the Plone eggs get pulled, but as always they cannot be created until <em>after</em> Zope 2 itself is in place. This necessitates splitting the one Zope part I showed <a href="http://feneric.blogspot.com/2009/07/repoze-zope-plone-urispace-and.html" title="Read my earlier post">last time</a> into two and sticking a fake eggs part in between. The second part will have to reference the eggs of the first part. To make things just a little more interesting, z3c.recipe.fakezope2eggs expects a location to be provided by the [zope2] part. We thus have to create one. The changed section will look as follows:</p>
<pre>
[zope2]
recipe = zc.recipe.egg
dependent-scripts = true
location = ${buildout:directory}/parts
eggs =
lxml
repoze.zope2
[zopeliblink]
recipe = iw.recipe.cmd
on_install = true
on_update = true
cmds =
mkdir -p ${buildout:directory}/parts/lib/python
ln -sh ${buildout:directory}/eggs/zopelib*/zope ${buildout:directory}/parts/lib/python/zope
[fakezope2eggs]
recipe = z3c.recipe.fakezope2eggs
[plone]
recipe = zc.recipe.egg
dependent-scripts = true
interpreter = zopepy
eggs =
${zope2:eggs}
Plone
PIL
Products.DocFinderTab
Products.ExternalEditor
plone.openid
deliverance
repoze.urispace
repoze.dvselect
mysite.policy
</pre>
<p>It's probably obvious, but just in case it's not, the two new parts have to be added to the parts section near the top:</p>
<pre>
parts =
lxml
zope2
zopeliblink
fakezope2eggs
plone
instance
slugs
addpaths
</pre>
<p>Don't forget that the order is important, as the fake Zope eggs have to be created after Zope proper but before Plone.</p>
<p>Deliverance and URISpace should continue to work without changes.</p>
<p>Also, I've created eggs for zopelib 2.10.8.0 and ZODB 3.7.3 (the official versions that the Plone 3.3 builds are based upon; I've also made a zopelib 2.11.3 for people using straight Zope) and submitted them to the <a href="http://www.repoze.org/" title="Go to the Repoze site">Repoze</a> guys for inclusion in their <a href="http://dist.repoze.org/">distribution section</a>. If you'd like to play around with these before they become official, you can find them in the <a href="http://dist.saugus.net/">Saugus.net distribution section</a>.</p>Fenerichttp://www.blogger.com/profile/02260982910947326581noreply@blogger.com2tag:blogger.com,1999:blog-10404399.post-41432326145226617922009-07-15T12:20:00.006-04:002009-07-15T14:47:56.441-04:00Repoze, Zope, Plone, URISpace, and Deliverance<p>I've further developed the technique I outlined in my last post for making <a href="http://feneric.blogspot.com/2009/06/buildout-with-repoze-zope-and-plone.html" title="Read about making Plone work with Repoze">Plone run with Repoze and mod_wsgi</a>. In particular I've included the ability to skin via Deliverance (including the ability to separate out different sections of the site for different treatments via URISpace) and enhanced the <code>addpaths.py</code> script to remove the limitations I'd indicated were there without going into details; it now both handles update cases better and is far more intelligent with regards to ensuring that egg path order is maintained regardless of whether <a href="http://pythonpaste.org/" title="Go to the Paste site">Paste</a> or <a href="http://www.modwsgi.org/" title="Go to the mod_wsgi site">mod_wsgi</a> is being used. If you had trouble getting my prior instructions to work in your environment, you may just want to update to the smarter <code>addpaths.py</code> included below.</p>
<p>My use case is <a href="http://www.saugus.org/" title="Go to Saugus.org">Saugus.org</a> (although note that the current public version may not yet reflect the changes discussed in this post as they're obviously being done on a separate development server). Basically several different not-for-profit entities have their sites located on this domain, and while there is a significant overlap between members of the various sub-sites (probably 10% - 25% or so) it's certainly not absolute, and each sub-site has different administrators and different styles. While there are ways of making <a href="http://deliverance.openplans.org/" title="Go to the Deliverance site">Deliverance</a> theme things differently for different portions of a site, I didn't really care for any of them in this application as they'd make it too easy to break things for particular sub-sites and/or make it too difficult to actually do the theming for individual sub-sites. The obvious solution is <a href="http://docs.repoze.org/urispace/" title="Go to the repoze.urispace site">repoze.urispace</a> (which implements the <a href="http://www.w3.org/TR/urispace.html" title="Read the W3C URISpace spec">W3C URISpace specification</a> in a way that can be used to make Deliverance distinguish between different portions of a site). With repoze.urispace, it becomes easy to give each sub-site its own independent set of Deliverance rules and themes, and working on one will in no way affect another.</p>
<h4>Making It Happen</h4>
<p>Now that you understand the motivation it's time to see the implementation. Generally one needs to follow the instructions I outlined in <a href="http://feneric.blogspot.com/2009/06/buildout-with-repoze-zope-and-plone.html" title="Read about making Plone work with Repoze">my earlier post</a>, but make a few changes:</p>
<ol>
<li><p>First, substitute its copy of <code>addpaths.py</code> with the following much improved version prior to running <code>bin/buildout</code>:</p>
<pre>
import os
from dircache import listdir
# The bin directory holds all the executables for the buildout
BinDir = 'bin'
# The unadorned files aren't given any of the egg paths on creation
UnadornedFiles = (os.path.abspath(BinDir+'/zope2.wsgi'),)
# Most regular files are given the egg paths, but not the old-style products path
RegularFiles = [os.path.abspath('%s/%s'%(BinDir,filename)) for filename in listdir(BinDir)]
# Eggs can live in more than one location
EggDirs = ('eggs',)
# Old style products should all be contained in one location
ProductsPath = os.path.abspath('products')
# The sample file should be regular file with a regular egg path
SampleFile = os.path.abspath(BinDir+'/paster')
def main(options, buildout):
# We have to ensure that the zopelib directory is earlier in the search path
# than other possibly competing packages. Unfortunately, we don't know its
# full name a priori and have to hunt it down first.
for eggDir in EggDirs:
for filename in listdir(eggDir):
if 'zopelib' in filename:
zopelibPath=os.path.abspath('%s/%s/%s'%(os.getcwd(),eggDir,filename))
break
# First we handle the regular files. We both relocate the zopelib component
# (if present) to the beginning of the list and prepend the old-style products
# path. Note that this will ignore unadorned files mixed in.
for filename in RegularFiles:
lines = open(filename, 'r').readlines()
file = open(filename, 'w')
for line in lines:
if 'zopelib' not in line:
file.write(line)
if line.startswith('sys.path'):
if ProductsPath not in ' '.join(lines):
file.write(" '%s',\n"%ProductsPath)
if zopelibPath:
file.write(" '%s',\n"%zopelibPath)
file.close()
# The path list should now be perfect in our sample file. Grab it.
lines=open(SampleFile,'r').readlines()
lineNum=begLineNum=endLineNum=0
for line in lines:
lineNum+=1
if line.startswith('import sys'):
begLineNum=lineNum-1
elif begLineNum and ']' in line:
endLineNum=lineNum
eggLines=lines[begLineNum:endLineNum]
# Now we're ready to handle the unadorned files. Simply replace any existing
# sys path with the good one we've obtained from the sample, or add it if nothing
# yet exists. We're assuming that in a healthy file the import os statement will
# occur after the import sys statement.
for filename in UnadornedFiles:
lines = open(filename,'r').readlines()
alreadyProcessed=False
lineNum=begLineNum=endLineNum=0
for line in lines:
lineNum+=1
if line.startswith('import sys'):
alreadyProcessed=True
begLineNum=lineNum-1
elif begLineNum and ']' in line:
endLineNum=lineNum
elif line.startswith('import os') and not alreadyProcessed:
begLineNum=endLineNum=lineNum-1
lines[begLineNum:endLineNum]=eggLines
file = open(filename,'w')
file.writelines(lines)
file.close()
# All done! Let's just tell the user roughly what we've done.
print "Egg paths added to %s" % ', '.join(UnadornedFiles)
print "Product path added to %s" % ', '.join(RegularFiles)
</pre></li>
<li><p>Next, a slightly modified <code>buildout.cfg</code> must be used (obviously also before running <code>bin/buildout</code>). The following should work:</p>
<pre>
[buildout]
extends =
http://good-py.appspot.com/release/repoze.zope2/1.0
http://dist.plone.org/release/3.3rc3/versions.cfg
versions = versions
find-links =
http://dist.repoze.org/zope2/latest
http://dist.repoze.org/zope2/dev
http://dist.plone.org/release/3.3rc3
http://download.zope.org/ppix/
http://download.zope.org/distribution/
http://effbot.org/downloads
develop =
src/mysite.policy
parts =
lxml
zope2
instance
slugs
addpaths
[versions]
zopelib = 2.10.7.0
[lxml]
recipe = z3c.recipe.staticlxml
egg = lxml
libxml2-url = http://xmlsoft.org/sources/libxml2-2.7.2.tar.gz
libxslt-url = http://xmlsoft.org/sources/libxslt-1.1.24.tar.gz
[zope2]
recipe = zc.recipe.egg
dependent-scripts = true
interpreter = zopepy
eggs =
lxml
repoze.zope2
Plone
PIL
Products.DocFinderTab
Products.ExternalEditor
plone.openid
deliverance
repoze.urispace
repoze.dvselect
mysite.policy
[slugs]
recipe = collective.recipe.zcml
zope2-location=${buildout:directory}
zcml =
mysite.policy
[instance]
recipe = iw.recipe.cmd
on_install = true
cmds =
bin/mkzope2instance --use-zeo --zeo-port=${buildout:directory}/var/zeo.zdsock --zope-port=8888
sed -i "" "s/server localhost:/server /" ${buildout:directory}/etc/zope.conf
echo "Please run 'bin/runzeo -C etc/zeo.conf' and 'bin/paster serve etc/zope2.ini', then 'bin/addzope2user '"
[addpaths]
recipe = z3c.recipe.runscript
install-script = addpaths.py:main
update-script = addpaths.py:main
</pre>
<p>As before note the dummy <em>mysite.policy</em> product included to show the most general solution. If you are not developing any products and do not need any additional <abbr title="Zope Configuration Mark-up Language">ZCML</abbr> slugs, these can be totally omitted. Otherwise they should be changed accordingly.</li>
<li><p>Next, add <code>rules</code> and <code>themes</code> subdirectories to the <code>etc</code> directory.</p></li>
<li><p>Create a <code>default.xml</code> file in the <code>rules</code> directory. The following sample:</p>
<pre>
<?xml version="1.0" encoding="UTF-8"?>
<rules xmlns:xi="http://www.w3.org/2001/XInclude"
xmlns="http://www.plone.org/deliverance">
<replace theme="/html/head" content="/html/head" />
<replace theme="/html/body" content="/html/body||/html/frameset" />
</rules>
</pre>
<p>is basically a <abbr title="no operation">NOP</abbr> and will get you started. There's more information on the <a href="http://deliverance.openplans.org/" title="Go to the Deliverance site">Deliverance site</a> on the sorts of commands you can add in here. Ultimately you'll be making more of these rules files with each one being used for a different section of your site.</p></li>
<li><p>Create a <code>default.html</code> file in the <code>themes</code> directory. Something as basic as:</p>
<pre>
<html>
<head>
<title>default.html theme for Deliverance</title>
</head>
<body>
</body>
</html>
</pre>
<p>will likewise be enough to get you started. You can ultimately create this file however you'd like using any sorts of <abbr title="Hypertext Mark-up Language">HTML</abbr> generation tools that tickle your fancy. Ultimately you'll be making more of these theme files (probably one to go with each rules file) with each one being used for a different section of your site.</p></li>
<li><p>Lastly you'll need to create a URISpace configuration file <code>urispace.xml</code> in the <code>etc</code> directory. While there's more info on the <a href="http://docs.repoze.org/urispace/" title="Go to the repoze.urispace site">repoze.urispace site</a> on the options that you can include in here, the following is a minimal one that directs everything to the default rules and theme we have already defined:</p>
<pre>
<?xml version="1.0" ?>
<themeselect
xmlns:uri='http://www.w3.org/2000/urispace'
xmlns:uriext='http://repoze.org/repoze.urispace/extensions'
xmlns:rdf='http://www.w3.org/1999/02/22-rdf-syntax-ns#'
>
<!-- default theme and rules -->
<theme>file:///home/eric/WSGI/SaugusOrg/etc/themes/theme.xhtml</theme>
<rules>file:///home/eric/WSGI/SaugusOrg/etc/rules/rules.xml</rules>
</themeselect>
</pre></li>
<li><p>Finally, before trying to run the new site one must ensure that the <abbr title="Web Server Gateway Interface">WSGI</abbr> pipeline is properly prepared. The following new <code>zope2.ini</code> will do so:</p>
<pre>
[DEFAULT]
debug = True
[app:zope2]
paste.app_factory = repoze.obob.publisher:make_obob
repoze.obob.get_root = repoze.zope2.z2bob:get_root
repoze.obob.initializer = repoze.zope2.z2bob:initialize
repoze.obob.helper_factory = repoze.zope2.z2bob:Zope2ObobHelper
zope.conf = %(here)s/zope.conf
[filter:errorlog]
use = egg:repoze.errorlog#errorlog
path = /__error_log__
keep = 20
ignore = paste.httpexceptions:HTTPUnauthorized
paste.httpexceptions:HTTPNotFound
paste.httpexceptions:HTTPFound
[filter:deliverance]
use = egg:deliverance#main
theme_uri = http://www.example.com/
rule_uri = file:///%(here)s/rules/rules.xml
[filter:urispace]
use = egg:repoze.urispace#urispace
filename = %(here)s/urispace.xml
[pipeline:main]
pipeline = egg:Paste#cgitb
egg:Paste#httpexceptions
# egg:Paste#translogger
egg:repoze.retry#retry
egg:repoze.tm#tm
egg:repoze.vhm#vhm_xheaders
errorlog
urispace
egg:repoze.dvselect#main
deliverance
zope2
# Note: replace egg:Paste#cgitb with egg:Paste#evalerror above to get
# the browser to display eval'able traceback stacks (unsuitable for
# production).
# If you enable (uncomment) the translogger, it will show access log
# info to the console.
[server:main]
use = egg:repoze.zope2#zserver
host = 127.0.0.1
port = 8888
</pre>
<p>The theme referenced in the Deliverance section will never actually be used as it'll be overridden by repoze.urispace.</p></li>
</ol>
<h4>Details To Note</h4>
<p>First off, thanks to Tres Seaver not just for originally writing repoze.urispace and its companion repoze.dvselect, but for also putting up with (and acting on) both my bug reports and suggestions for making things easier to use. I had originally gotten this all working with an earlier version of repoze.urispace and and the original unreleased version of repoze.dvselect, but the method described here is much cleaner, and it wouldn't have been possible without Tres' numerous recent updates to both repoze.urispace and repoze.dvselect.</p>
<p>Second, as seems to happen a lot lately, just as I was starting to write this I was informed of <a href="http://lichota.pl/blog/2009/07/12/buildout-for-plone-3-with-deliverance-on-wsgi" title="Read about the other method">another effort</a> to do something similar. Wojciech Lichota's technique seems to do some things better and some things worse than the technique described above. Depending upon what you're doing, you may find that what he's doing more directly addresses your needs. Probably a hybrid technique will be better than either...</p>
<p>Also, one may wonder about the whole <code>z3c.recipe.staticlxml</code> used above to build <code>lxml</code> and whether or not it's really necessary. It may look like extra work, but this method allows the exact same buildout to work on Mac OS X in addition to regular more traditional UNIX and UNIX-like environments.</p>
<p>Finally, note that as presented here Deliverance and URISpace won't actually do anything... it's expected that you'll add rules and themes appropriate to your own project.</p>Fenerichttp://www.blogger.com/profile/02260982910947326581noreply@blogger.com5tag:blogger.com,1999:blog-10404399.post-67840842799037539272009-06-19T12:39:00.004-04:002009-06-19T16:01:42.985-04:00Buildout with Repoze, Zope, and Plone<p>I know in my <a href="http://feneric.blogspot.com/2009/05/antichrist-structure.html" title="Read my last post">last post</a> I indicated that I'd post more about the various technologies I'm using for the <a href="http://www.antichristwatch.net/" title="Go to Antichrist Watch">Antichrist Watch site</a>, but I've now had a few requests related to some of the <a href="http://www.repoze.org/" title="Go to the Repoze site">Repoze</a> work I'm doing with some of the local <a href="http://www.saugus.net" title="Go to Saugus.net">Saugus, <abbr title="Massachusetts">MA</abbr></a> sites, so I'll be making a slight detour. I will get back to the <a href="http://www.dojotoolkit.org/" title="Go to the Dojo Toolkit site">Dojo</a> stuff. I promise.</p><p>I discovered Repoze when first dabbling around with what would eventually become the aforementioned Antichrist Watch, and in fact I directly made use of <a href="http://chameleon.repoze.org/" title="Go to the Chameleon site">repoze.chameleon</a> to handle its templating needs. I liked what I saw, and decided to try first experimenting a bit with it and then actually porting over some real-world sites to it. We were in the process of doing some hardware upgrades on the some servers anyway, so the sites they hosted seemed liked good candidates. To make things interesting, most of them came in basically two distinct flavors: straight <a href="http://www.zope.org/" title="Go to the Zope site">Zope</a>, and customized <a href="http://www.plone.org/" title="Go to the Plone site">Plone</a>.</p><p>The first group was largely composed of mostly non-technical customers who take advantage of the bottom of the so-called "Z shaped curve" to do basic site edits through the Web. Some of these customers enjoy having fairly current versions of Zope. The second group featured various degrees of customization, from the fairly vanilla to the strikingly different. Most of these were handled via custom Plone products designed more or less in the manner described in Martin Aspeli's <cite>Professional Plone Development</cite>. With this logical grouping, <a href="http://www.buildout.org/" title="Go to the buildout site">buildout</a> seemed a logical choice for site construction as I could make just three buildouts and then trivially generate as many sites as desired. The only problems were that the Repoze guys themselves seem not to use it much and (understandably considering the drudgery involved) don't have prepackaged versions of the latest-and-greatest of either Zope or Plone currently available.</p><p>Ultimately I wanted all the sites running through <a href="http://www.modwsgi.org/" title="Go to the mod_wsgi site">mod_wsgi</a> using as few physical servers as practical. I wanted to only have one <a href="http://www.supervisord.org/" title="Go to the supervisord site">supervisord</a> instance per physical server monitoring all the <abbr title="Zope Enterprise Objects">ZEO</abbr> servers it contained. I also wanted to minimize the number of ports in use in order to reduce the bureaucracy of port tracking we'd have to do afterwards.</p><p>Getting current versions of Zope and Plone running under Repoze turned out not to be so simple. I read <a href="http://www.martinaspeli.net/articles/rolling-out-repoze" title="Read 'Rolling Out Repoze'">a</a> <a href="http://valentinewebsystems.com/en/blog/2008/02/19/plone-repoze-and-buildout" title="Read 'How to add repoze to your plone buildout'">few</a> <a href="http://blog.redinnovation.com/2009/03/13/setting-up-plone-32-and-repoze-hackyish/" title="Read 'Setting up Plone 3.2 and Repoze, hackyish'">articles</a> on the topic in addition to the <a href="http://repoze.org/quickstart.html" title="Read the Repoze Quickstart">Repoze Quick Start</a>, but due to differences in versions and/or environment none of them did what I needed.</p>
<h4>Making It Happen</h4><p>Enough introduction! Here's what I did for the variant with Plone:</p>
<ol><li><p><code>paster create -t zope2_buildout <em>targetname</em></code></p>
<p>It doesn't much matter what answers are given, as <code>buildout.cfg</code> gets overwritten anyway.</p>
</li>
<li><p><code>cd <em>targetname</em></code></p>
</li>
<li><p>Replaced <code>buildout.cfg</code> with the following:</p>
<pre>
[buildout]
extends =
http://good-py.appspot.com/release/repoze.zope2/1.0
http://dist.plone.org/release/3.3rc3/versions.cfg
versions = versions
find-links =
http://dist.repoze.org/zope2/latest
http://dist.repoze.org/zope2/dev
http://dist.plone.org/release/3.3rc3
http://download.zope.org/ppix/
http://download.zope.org/distribution/
http://effbot.org/downloads
develop =
src/mysite.policy
parts =
zope2
instance
slugs
addpaths
[zope2]
recipe = zc.recipe.egg
dependent-scripts = true
interpreter = zopepy
eggs =
repoze.zope2
Plone
PIL
Products.DocFinderTab
Products.ExternalEditor
plone.openid
mysite.policy
[slugs]
recipe = collective.recipe.zcml
zope2-location=${buildout:directory}
zcml =
mysite.policy
[instance]
recipe = iw.recipe.cmd
on_install = true
cmds =
bin/mkzope2instance --use-zeo --zeo-port=${buildout:directory}/var/zeo.zdsock --zope-port=8888
sed -i "" "s/server localhost:/server /" ${buildout:directory}/etc/zope.conf
echo "Please run 'bin/runzeo -C etc/zeo.conf' and 'bin/paster serve etc/zope2.ini', then 'bin/addzope2user <username> <password>'"
[addpaths]
recipe = z3c.recipe.runscript
install-script = addpaths.py:main
update-script = addpaths.py:main
</pre>
</li>
<li>
<p>Added the file <code>addpaths.py</code> to the buildout's top level directory with the following contents:</p>
<pre>
import os
from dircache import listdir
BinDir = 'bin'
UnadornedFiles = ('bin/zope2.wsgi',)
RegularFiles = ['%s/%s'%(BinDir,filename) for filename in listdir(BinDir)]
EggDirs = ('eggs',)
ProductsPath = os.path.abspath('products')
def main(options, buildout):
for filename in UnadornedFiles:
lines = open(filename,'r').readlines()
file = open(filename,'w')
alreadyProcessed=False
for line in lines:
if line.startswith('import sys'):
alreadyProcessed=True
elif line.startswith('import os') and not alreadyProcessed:
file.write("import sys\nsys.path[0:0] = [\n")
for eggDir in EggDirs:
for filename in listdir(eggDir):
file.write(" '%s',\n"%os.path.abspath('%s/%s'%(eggDir,filename)))
file.write(" ]\n\n")
file.write(line)
for filename in RegularFiles:
lines = open(filename, 'r').readlines()
file = open(filename, 'w')
for line in lines:
file.write(line)
if line.startswith('sys.path'):
file.write(" '%s',\n"%ProductsPath)
file.close()
print "Egg paths added to %s" % ', '.join(UnadornedFiles)
print "Product path added to %s" % ', '.join(RegularFiles)
</pre>
</li>
<li><p><code>python2.4 bootstrap.py</code></p>
</li>
<li><p><code>bin/buildout</code></p>
<p>Just ignore any <code>'return' outside function</code> types of errors you see.</p>
</li>
</ol>
<p>Once these steps have been completed, <abbr title="Zope Enterprise Objects">ZEO</abbr> can be started with the command <code>bin/runzeo -C etc/zeo.conf</code> (which can be easily controlled via supervisord) and Zope can be started manually for testing with <code> bin/paster serve etc/zope2.ini</code> or in a more production-ready form via mod_wsgi using <code>zope2.wsgi</code>.</p>
<h4>Details To Note</h4><p>I borrowed but heavily modified the <code>addpath.py</code> concept <a href="http://svn.plone.org/svn/collective/experimental.plonerepozebuildout/addpath.py" title="Read the original version">already living in the Plone collective</a> to add all missing paths to all the scripts in <code>bin</code>. The <abbr title="Web Server Gateway Interface">WSGI</abbr> script as created lacks pretty much everything, and all the others lack the products directory used for old-style products. As written it's not very clever and could be greatly improved, but it serves my current needs.</p><p>The order of parts matters somewhat, as both <code>slugs</code> and <code>addpaths</code> rely on pieces created earlier.</p><p>I'm using direct sockets in lieu of ports since these sites are living on single physical servers anyway and it means I have less to manage afterwards. Unfortunately the <code>mkzope2instance</code> doesn't do exactly what one might want in this case, so the <code>sed</code> line is necessary afterwards to clean up.</p><p>The slugs section adds <abbr title="Zope Configuration Management Language">ZCML</abbr> slugs for those products that need them, including the hypothetical product <em>mysite.policy</em> being actively developed in <code>src</code>.</p><p>I just recently discovered Martin Aspeli's <a href="http://good-py.appspot.com/" title="Go to Good-Py">Good-Py</a>. I was originally individually pinning the versions of the pieces that mattered, and only made this simplification this morning... so far it seems to be fine, though.</p><p>Just before starting this post I spotted <a href="http://aclark.net/Members/aclark/blog/a-sane-buildout-for-repoze-zope2-plone" title="Read 'A sane buildout for repoze.zope2 + Plone?'">Alex Clark's post</a> also discussing this topic. We're doing a lot alike, but a few things differently. Depending upon what you're doing, you may find that what he's doing more directly addresses your needs.</p><p>Earlier on I mentioned how I needed to handle two main groups of sites: Plone ones and straight Zope ones. The above instructions <em>only</em> cover how I handled the Plone ones. This post has gotten long enough already, and although my treatment of the straight Zope ones is similar it's different enough to make things confusing for those who don't need it. If you need it, let me know and I'll probably give it a similar treatment to what I did here.</p>Fenerichttp://www.blogger.com/profile/02260982910947326581noreply@blogger.com2tag:blogger.com,1999:blog-10404399.post-49777868560592827552009-05-29T16:16:00.006-04:002009-06-19T16:03:38.827-04:00Antichrist Structure<p><a href="http://feneric.blogspot.com/2009/03/who-is-antichrist.html">Last time</a> I mentioned how I'll post some articles discussing how some of the key technologies (like the <a href="http://www.dojotoolkit.org/" title="Go to the Dojo community site">Dojo Toolkit</a>, <a href="http://www.postgresql.org/" title="Go to the PostgreSQL community site">PostgreSQL</a>, <a href="http://www.twistedmatrix.com/" title="Go to the Twisted community site">Twisted</a>, <a href="http://www.zope.org/" title="Go to the Zope community site">Zope</a>, <a href="http://www.python.org/" title="Go to the Python community site">Python</a>, and <a href="http://www.repoze.org/" title="Go to the Repoze site">Repoze</a>) are used by <a href="http://www.antichristwatch.net/" title="Go to Antichrist Watch">Antichrist Watch</a>. In this post I'll discuss some of the general architecture behind the site, along with motivations behind some of the design decisions I made. In future posts I'll follow up with specifics related to some of the key technologies employed.</p>
<p>I've already covered the originally planned core features of the site, so I won't repeat them here. What's important for this discussion is that those features require fast access to live data on votes, tallies, and comments, and the ability to display that data in a number of ways, and that everything be done cleanly according to current industry standards (that is, using decent semantic <abbr title="Hypertext Mark-up Language">HTML</abbr> backed by appropriate <abbr title="Cascading Style Sheet">CSS</abbr> and <abbr title="Resource Description Framework">RDF</abbr> that'll not cause the respective <a href="http://www.w3c.org/" title="Go to the W3C site">W3C</a> validators to choke). Obviously an <abbr title="Asynchronous JavaScript and XML">AJaX</abbr> design is called for, and the individual toolkits and frameworks used must be flexible enough to support reasonably standards-compliant code and mark-up. This may sound trivial on the surface, but oftentimes toolkits, frameworks, and even design tools have their own axes to grind and introduce deliberate incompatibilities or proprietary extensions in an attempt to promote their own stuff or denigrate others' stuff.</p>
<p>PostgreSQL for the back-end database was an easy choice. It performs well, has great support for standard SQL (and even <abbr title="Extensible Mark-up Language">XML</abbr>) built-in, and has advanced capabilities like triggers, rules, and stored procedures that can be used to help ensure data integrity. I'm a big believer in keeping code that enforces data integrity as deep within a Web application as practically possible; the closer it is to the front-end the more space there is for something to go wrong. With PostgreSQL I was able to get most of the code that handles data integrity embedded in the database itself, so not only is there not even a theoretical way for a crafty user to bypass constraints, there's not even a theoretical way for misbehaving middleware to bypass them. I'll discuss this in more detail later.</p>
<p>The Dojo Toolkit for the front-end JavaScript will be surprising to some as many believe its recent (post 1.0) versions cannot be used within a site that validates. This is incorrect. What is true is that Dojo's Dijit widgets can not be used in a validating site via mark-up without modifying Dojo's parser. This is a completely different statement, as there are other (and better) ways to apply Dijit widgets to a site. I'll discuss my use of the Dojo Toolkit in quite a bit more detail later. Most of the site's code is actually Dojo code, so I suspect I'll dedicate a couple of posts to it.</p>
<p>Of course, the JavaScript needs to be tied into some mark-up, and for this I used a single Zope Page Template designed to output clean <abbr title="Extensible Hypertext Mark-up Protocol">XHTML</abbr>. This would be trivial for a typical Zope site, but in this case it's certainly not typical as only scattered Zope technologies are being used. I'll get back to this in a bit.</p>
<p>The Dojo Toolkit has the concept of an abstracted data store that it leverages heavily for most of its widgets. It has numerous concrete implementations of this store that make binding it to various data sources fairly trivial. The one it includes for dealing with relational databases requires data to adhere to a particular format that would be awkward to generate directly in PostgreSQL, so it was necessary to create some code to fetch data from PostgreSQL and format it for Dojo. Since I had already built a great deal of intelligence into the PostgreSQL database itself, it was actually fairly simple to create this middleware, and during development I tested out a couple of different approaches (including raw Python and <a href="http://www.php.net/" title="Go to the PHP site">PHP</a>) before settling on one designed around Twisted Python. It makes good use of Twisted Enterprise and the <a href="http://pypi.python.org/pypi/psycopg2/" title="Go to the psycopg2 site">psycopg2</a> database adapter (including its splendid DictCursor) to make database access fast, efficient, and comprehensible. I also tied the rendering of the main Zope Page Template into this Twisted app by virtue of <a href="http://chameleon.repoze.org/" title="Go to the Chameleon site">Repoze Chameleon</a> in lieu of making it a typical Zope site. This whole layer is probably also worthy of its own post.</p>
<p>That's a quick run-through of what it takes to <a href="http://www.antichristwatch.net/" title="Go to Antichrist Watch">reveal the Antichrist</a>. I'll be posting more details on these individual components later; please feel free to point out areas of particular interest.</p>Fenerichttp://www.blogger.com/profile/02260982910947326581noreply@blogger.com0tag:blogger.com,1999:blog-10404399.post-8050196256323862322009-03-18T10:29:00.013-04:002009-06-19T16:04:03.027-04:00Who Is The Antichrist?<p>I know it's been a long time since I've written anything here. A <em>really</em> long time. I figured I'd break this silence with an overview of a project I've been working on lately that will hopefully prove interesting.</p>
<p>It's a site called <a href="http://www.antichristwatch.net" title="Go to Antichrist Watch">Antichrist Watch</a>. It's a site that attempts to answer this article's titular question <q><a href="http://www.antichristwatch.net" title="Go to Antichrist Watch">who is the Antichrist?</a></q> in a Web 2.0 sort of way using a fun mix of AJaX technologies.</p>
<p>I recently realized that much of the work that I do ends up buried within various intranets and extranets and is thus invisible to the world at large. While I've worked on all sorts of dynamic systems that do all sorts of things (both server-side and client-side), I really don't have any that I can show people. Most of the public sites that I work on tend to be simpler sorts of things, and people viewing them tend to mostly remember the graphics design elements (which in most cases I didn't actually work on anyway). With Antichrist Watch I have something that I can show both curious acquaintances and potential clients. The dynamic properties of it are fundamental to how the site works, and even people not all that familiar with the Web can get it.</p>
<p>Under the hood it uses a somewhat unusual combination of key technologies that not too many others use together: the <a href="http://www.dojotoolkit.org/" title="Go to the Dojo community site">Dojo Toolkit</a>, <a href="http://www.zope.org/" title="Go to the Zope community site">Zope</a>, <a href="http://www.twistedmatrix.com/" title="Go to the Twisted community site">Twisted</a>, <a href="http://www.python.org/" title="Go to the Python community site">Python</a>, and <a href="http://www.postgresql.org/" title="Go to the PostgreSQL community site">PostgreSQL</a>. While people familiar with my company <a href="http://www.saugus.net/" title="Go to Saugus.net">Saugus.net</a> will not at all be surprised with Zope, Python, and PostgreSQL (we've been using them all pretty prominently for <em>years</em>), Dojo and Twisted may be unexpected. We've actually also been using these off and on for quite awhile too, but not in too many public projects. In fact, thinking back, there are currently only two public areas of Saugus.net sites that utilize Dojo, and no public areas at all that use Twisted. While we are hoping to change this in the relative near future, Antichrist Watch demonstrates how these technologies can work together in harmony <em>now</em>.</p>
<p>While I'm still working on the site fixing bugs and adding new minor features, all of my originally planned core features are in place:</p>
<ol>
<li>The ability to vote on one's own choice of Antichrist, whether or not he or she is already in the list, with autocompletion based upon the live list of everyone's past choices.</li>
<li>Charts and tables showing current leaders for the past day, the past week, the past month, the past year, and all time.</li>
<li>Additional charts and tables showing votes as they come in with individual votes mapped to rough geographical areas, and the recent levels of voting activity over time.</li>
<li>A way to drill down and see the numbers for any particular Antichrist candidate.</li>
<li>A facility that allows one to argue for or against the likelihood of a particular Antichrist candidate being the Antichrist, respond to others' comments, and display it all in a tree.</li>
<li>The means to moderate the aforementioned comments.</li>
<li>A login system allowing people to establish identities within the site and voluntarily add personal information that will be displayed along with their comments to add personality.</li>
<li>Support for various <a href="http://feneric.blogspot.com/2006/04/web-site-icons.html" title="Read my earlier article on Web icons">icon</a> types to go along with login identities, including at minimum <a href="http://www.cs.indiana.edu/picons/ftp/" title="Go to the PIcon site">PIcons</a>, <a href="http://www.gravatar.com/" title="Go to the Gravatar site">Gravatars</a>, and <a href="http://www.mac.com/" title="Go to the .Mac site">.Mac</a> icons.</li>
<li>Support for <a href="http://www.openid.net/" title="Go to the OpenID community site">OpenID</a> to ease the whole login process.</li>
<li>Basic support for forward and back buttons within the site.</li>
<li>A reasonably semantic design including a fully populated external <abbr title="Resource Description Framework">RDF</abbr> metadata file boasting appropriate <a href="http://www.dublincore.org/" title="Go to the Dublin Core site">Dublin Core terms</a> and <a href="http://trac.usefulinc.com/doap" title="Go to the DOAP site"><abbr title="Description of a Project">DOAP</abbr> information</a> (plus a few other useful nuggets).</li>
<li>Cleanly handle the full UTF-8 character set throughout.</li>
<li>Proper validation of pretty much everything according to the <a href="http://www.w3c.org/" title="Go to the W3C site">W3C</a>'s respective validators.</li>
</ol>
<p>It does all of this in a way that almost totally avoids page reloads (the only exception is with OpenID authentication which by definition requires a redirect offsite and back). It also heavily makes use of lazy loading within its tables and trees, so that although access is provided to all data all the way back to day one, only data actually required for the current view gets downloaded keeping things fast on both client and server side. Of course, through the magic of Dojo it also works pretty well in all major browsers.</p>
<p>There are still lots of little details that need to be added. A means for automated password recovery quickly comes to mind, as well as more styling (what's there now is pretty close to being bare Dojo tundra), some more selective refreshing of data based on user input, better error handling (both in terms of weird user input and <abbr title="Hypertext Transfer Protocol">HTTP</abbr> type errors like the dreaded 404), some friendly help for new users, and some more intelligence added to certain buttons and dialogs already within the site.</p>
<p>I'll post some more articles here discussing some of the key technologies and how I put them to use within the site. If anyone has any particular areas of interest, don't be afraid to speak up.</p>Fenerichttp://www.blogger.com/profile/02260982910947326581noreply@blogger.com0tag:blogger.com,1999:blog-10404399.post-1146088696073939262006-04-26T17:57:00.002-04:002009-06-19T16:05:04.298-04:00Web Site Icons<p>I recently got this following short article posted in the Mac-focused <cite><a href="http://www.smalldog.com/kibbles/kibbles_display.php?id=457">Kibbles & Bytes</a></cite>. I thought that there was probably a pretty small overlap between readers of this blog and <cite>Kibbles & Bytes</cite>, so I’m reprinting it here (with permission, of course) minus the author introduction (which would only make me blush). I hope you’ll find it interesting.</p>
<h4>More on Favicons</h4>
<p>Two issues ago there was an introduction to favicons. If you found it informative, read on, as there’s lots more to favicons (and more generically page icons) than was covered in that first article. In particular there are three things that should be additionally mentioned: favicons have another important capability, they have one key limitation, and they have a more standard alternative.</p>
<p>To really understand favicons at a deeper level it’s necessary to consider very briefly their origins. It’s clear that Microsoft hadn’t really thought through either the favicon implementation or its consequences when they first introduced favicon support in Microsoft Internet Explorer (<abbr title="Microsoft Internet Explorer">MSIE</abbr>) 5.0. There were a few obvious issues:</p>
<ol>
<li><p>The <code>.ICO</code> format was very much an MS-Windows specific format. Even today it’s not too well supported on non-MS-Windows systems, and it didn’t yet have an official registered <acronym title="Multi-purpose Internet Mail Extensions">MIME</acronym> type (further slowing its adoption elsewhere). Even <abbr title="Microsoft Internet Explorer">MSIE</abbr> itself didn’t support <code>.ICO</code> files in its Solaris, HP-UX, and Mac OS incarnations.</p></li>
<li><p>The versions of <abbr title="Microsoft Internet Explorer">MSIE</abbr> that did support favicons did something contrary to the nature of the Web itself by automatically assuming that a particular file would exist in a particular location on every server in the world. They automatically tried to download <code>/favicon.ico</code> whenever a user tried to set a bookmark. This sort of behavior is strictly taboo and it got lots of webmasters <em>really</em> upset with Microsoft.</p></li>
<li><p>Because the favicon resource would be downloaded only when users tried to set bookmarks, privacy advocates also got a little upset with Microsoft as it became theoretically possible for webmasters to track individual users who bookmarked their sites.</p></li>
<li><p>The recommended favicon <code><link></code> tag of:</p>
<pre> <link rel="shortcut icon" type="image/x-icon" href="/favicon.ico" /></pre>
<p>is logically invalid <abbr title="Hypertext Mark-up Language">HTML</abbr> because the <code>rel</code> attribute officially contains space-delimited items, so <code>shortcut icon</code> should be treated as two separate relations rather than one. It’s also already been mentioned that the <acronym title="Multi-purpose Internet Mail Extensions">MIME</acronym> type listed in the <code>type</code> attribute was unregistered. Of course, this line could be omitted as <abbr title="Microsoft Internet Explorer">MSIE</abbr> would try to download <code>/favicon.ico</code> regardless; it was only necessary if an alternative location for the icon were specified.</p></li>
<li><p>When Microsoft finally registered an official <acronym title="Multi-purpose Internet Mail Extensions">MIME</acronym> type for the <code>.ICO</code> format (<code>image/vnd.microsoft.com</code>) they didn’t go out of their way to support it and encourage webmasters to stop using the unofficial <code>image/x-icon</code> type. In fact, even today, if you’re going to be using favicons, you’re advised to use the improper form for compatibility reasons.</p></li>
</ol>
<p>By now you may be thinking “what does all this have to do with additional capabilities, limitations, and alternatives?” The answer is that (as you might guess from #1 above) there are some tricks and issues that arise from the <code>.ICO</code> format’s MS-Windows origins, and (as you might guess from all the points above) there was some motivation to try and clean up a messy situation by introducing alternatives.</p>
<p>First I’ll touch on the additional capability of traditional favicons. Basically it’s the fact that the <code>.ICO</code> format isn’t really an icon as it may appear at first blush; it’s more of a bundle of icons. A single <code>.ICO</code> file can contain one or more icons of different sizes, and MS-Windows can make use of more than just the common 16×16 size. In fact, MS-Windows will happily gobble down 16×16, 32×32, and 48×48 icons and use each appropriately (16×16 for various places including the <abbr title="Uniform Resource Locator">URL</abbr> box and the others for various places including the desktop). In fact, if a favicon lacks larger versions, MS-Windows will take the 16×16 version and attempt to scale it up with sometimes hilarious (at least on other people’s favicons — with your own favicons it tends to be more depressing) results. I’ve also heard, but never personally verified, that certain versions of MS-Windows in certain circumstances will use both 24×24 and 64×64 favicons if available. The obvious drawback with providing more sizes is that it leads to a larger <code>.ICO</code> file and thus slower download times. Certainly though if you’re planning to create a favicon for your site, it’s worth making at least the 16×16, 32×32, and 48×48 versions, and Microsoft themselves recommend including at least this many.</p>
<p>Other browsers and other platforms have had to add some favicon support. Nowadays the 16×16 icon is supported by pretty much every graphical browser on every platform, but the support for other sizes remains weak. Of particular interest though is that Mac OS X natively supports 128×128 icons, and Vista natively supports 256×256 icons. Really forward-thinking webmasters will realize that these sizes probably also ought to be embedded into favicons sooner rather than later as they’re pretty much guaranteed to find a use, but again consider file sizes.</p>
<p>Next it’s important to mention the big limitation with traditional favicons: color. To make a favicon that’s guaranteed to display the same everywhere, it’s necessary to stick to the limited 4-bit, 16-color “Windows Default Palette”. This palette basically consists of white, red, yellow, blue, green, magenta, cyan, dark gray, and darker versions of the same (with “dark white” being light gray, and “dark dark gray” being black). This palette does not usually lend itself to the creation of beautiful favicons. There are two work-arounds. The first is to accept that some viewers will see your favicon as a psychedelic mess and use a larger palette; if you stick to the regular 216-color “<a href="http://www.saugus.net/Local/Tests/Colors/">Web Safe Palette</a>” the vast majority of users will have no trouble. The second is to include multiple icons of different palettes within the favicon. This latter approach quickly leads to large file sizes (a favicon with both 8-bit and 24-bit color versions will not be just twice the size of the favicon with only an 8-bit version, it’ll be roughly four times the size), and it’s still not guaranteed that every system will be smart enough to pick the best color depth it can properly display.</p>
<p>Actually making a multi-icon favicon is a topic for another article. I’ll provide a quick tip though for advanced readers who aren’t afraid to use the Terminal.app: check out the free <a href="http://netpbm.sourceforge.net/">NetPBM utilities</a>. The included program <code>ppmtowinicon</code> can create multi-icon favicons.</p>
<p>Now it’s finally time to get to the standard alternative. Basically all one does is to use:</p>
<pre> <link rel="icon" type="image/png" href="/icon.png" /></pre>
<p>in lieu of the common <code>shortcut icon</code> version mentioned above. Note that this changes three things:</p>
<ol>
<li><p>The <code>shortcut icon</code> changes to <code>icon</code> fixing the <abbr title="Hypertext Mark-up Language">HTML</abbr> logic issues with the original.</p></li>
<li><p>The type changes to <code>image/png</code>, a standard, platform-neutral image format with a proper <acronym title="Multi-purpose Internet Mail Extensions">MIME</acronym> type. You’re also free to use <abbr title="Graphics Interchange Format">GIF</abbr>s rather than <abbr title="Portable Network Graphics">PNG</abbr>s. Either way, they are more size-efficient than <code>.ICO</code> files. While it’s still prudent to stick to the Web Safe Palette in most cases (and the need for even this is reducing each day), one never has to worry about a 16-color Windows Default Palette. <abbr title="Portable Network Graphics">PNG</abbr>s and <abbr title="Graphics Interchange Format">GIF</abbr>s are also far easier to work with, and advanced features like transparency and animation are already somewhat supported.</p></li>
<li><p>The <code>href</code> attribute should be set to point to an image of the appropriate type. There’s no longer a default. In fact, there’s not even a requirement that the icon be hosted on the same domain.</p></li>
</ol>
<p>You can freely use both a favicon and a standard icon without worrying about making your site slower. Browsers are generally smart enough to automatically pick between the two as needed without having to download both. Usually you’d want the two versions to look fairly similar to one another, but that’s not a requirement.</p>
<p>The last topic I’ll mention (because its name and purpose are similar enough to cause confusion) is the somewhat related notion of domain <abbr title="personal icons">picons</abbr>. A <abbr title="personal icon">picon</abbr> is a personal icon, and a domain <abbr title="personal icon">picon</abbr> is a special icon you create that represents your entire domain. The details of how to make and use <abbr title="personal icons">picons</abbr> are clearly outside of the scope of this article, but the most important facts are that:</p>
<ol>
<li><p><abbr title="personal icons">Picons</abbr> don’t generally get used within your site — they get used in other places that refer to your domain in some way. For example, many forums, e-mail & news clients, mailing lists, and similar entities display domain <abbr title="personal icons">picons</abbr> with each message appropriate to the originating domain. (Locally in Massachusetts two examples that use <abbr title="personal icons">picons</abbr> include <a href="http://www.shelltown.net/">ShellTown</a>'s online mail system and <a href="http://news.saugus.net/">Saugus' forums</a>.)</p></li>
<li><p>There’s a global master repository of <abbr title="personal icons">picons</abbr> maintained at the Indiana University called the “<a href="http://ftp.cs.indiana.edu/pub/faces/picons/">Picons Archive</a>”. Forums and other similar sites that make use of <abbr title="personal icons">picons</abbr> typically synchronize their local <abbr title="personal icon">picon</abbr> databases with this master copy periodically. Everyone is allowed to submit new <abbr title="personal icons">picons</abbr> for their own sites to this repository.</p></li>
<li><p><abbr title="personal icons">Picons</abbr> are 48×48 images provided in both monochrome (in <abbr title="X Bitmap">XBM</abbr> format) and indexed color versions (in at least <abbr title="X Pixmap">XPM</abbr> format but also usually <abbr title="Graphics Interchange Format">GIF</abbr>).</p></li>
<li><p>As a consequence of #1, you can (and probably should) make a <abbr title="personal icon">picon</abbr> in addition to your other icon(s) in order to preserve your own site branding, and it normally makes sense to make your <abbr title="personal icon">picon</abbr> look like your other icon(s).</p></li>
<li><p>As another consequence of #1, providing a <abbr title="personal icon">picon</abbr> doesn’t make your site any slower to download.</p></li>
</ol>
<p>That’s enough to get you started. If there’s enough interest I’ll perhaps write a little in the future on creating multi-icon favicons and/or creating <abbr title="personal icons">picons</abbr>.</p>Fenerichttp://www.blogger.com/profile/02260982910947326581noreply@blogger.com0tag:blogger.com,1999:blog-10404399.post-1137347380687247492006-01-15T11:26:00.001-05:002009-06-19T16:05:31.841-04:00Newton Technology in 2006<p>With the <a href="http://wwnc.newtontalk.net/">Worldwide Newton Conference</a> going on and all the attention currently focused on the Newton, I was recently posed the following question:</p>
<blockquote>Everyone keeps saying that the Newton could do things that no other PDA can. Could we get some examples?</blockquote>
<p>People who haven't used the Newton tend not to recognize its capabilities, as they're not something that are really obvious from the outside. At first glance, it may appear to be just a bulky (and these days, old) <abbr title="Personal Digital Assistant">PDA</abbr>.</p>
<p>This is really a flawed analysis, though. Even though the term <abbr title="Personal Digital Assistant">PDA</abbr> was coined to describe the first Newton MessagePad, its current usage tends to be more associated with less capable devices that have since come onto the scene in force and took the term for their own. Both Apple and Newton, Inc. realized this themselves in the final couple years of MessagePad production, and they tried to distance themselves from the term by calling the later model MessagePads "hand-held computers".</p>
<p>These days people can better understand Newton devices if they compare them not to modern <abbr title="Personal Digital Assistant">PDA</abbr>s, but instead to modern tablet computers. The difference may be subtle, but at the heart of it is the idea that a typical modern <abbr title="Personal Digital Assistant">PDA</abbr> is something one uses as an extension of a desktop computer (and it has to be synchronized all the time to stay useful), while the tablet computer can itself serve more or less as a replacement to a desktop system.</p>
<p>The Newton devices sport a freely available, yet sophisticated development environment with a choice of modern languages. They support a wide range of hardware and protocols including 802.11g wireless networking, Bluetooth, land-line ethernet, and <abbr title="Infrared Data Association ">IrDA</abbr> in addition to regular telephony (including both <abbr title="fascimile">FAX</abbr> send and receive as well as networking). They can handle extremely large memory cards, and they use these essentially as solid-state drives (they don't use hard drives). They have grayscale displays large enough to do some real work, and the entire display is touch-sensitive with support for free-form natural writing anywhere. Its handwriting recognition system is good enough for everyday use, can be tuned to one's own handwriting, and is flexible enough to handle accented characters. For those times though when writing isn't comfortable, they have a keyboard add-on that's small enough to fit in a winter coat pocket but large enough for touch-typing. It has a powerful, yet energy-efficient processor that makes for long battery life (and it can even use standard AA batteries). Its <acronym title="operating system">OS</acronym> is fully multi-tasking, and it's capable of even playing a few movies simultaneously without losing frames.</p>
<p>Internally it also has some interesting concepts and capabilities. Its concept of "soups" makes novel exchange of data between applications possible. Its "Intelligent Assistant" gives it the ability to turn random, unscripted commands like <code>call Mom</code> or <code>fax Darren</code> not just work, but do the appropriate thing based upon your current location (supplying phone area codes, region codes, and prefixes as needed) and other factors (like time of day).</p>
<p>The combination of all of these factors makes for an extremely adaptable device.</p>
<p>For applications they have all the usual things expected from a <abbr title="Personal Digital Assistant">PDA</abbr> (like notebook, address book, calendar, etc.) but also have the sorts of full-featured apps one would expect from a tablet computer (like a word processor good enough that people have literally written novels with it, a spreadsheet app worthy of a desktop, a graphing calculator, a personal finance system, etc.). In addition to these things, they have modern Internet apps (including among others what's probably the best e-mail client I've ever seen on a hand-held device and a full graphical browser) plus some more technical apps like Telnet that (coupled with all the networking capabilities mentioned above) make the device good for checking out networks in addition to its more typical tasks.</p>
<p>They of course also have all the sorts of applications that people over the years have written for hand-held devices of all types; if your interest is astronomy, there's software for you; if your interest is hiking, there's software (with <abbr title="Global Positioning System">GPS</abbr> support) for you; if your interest is photography, there's software to connect to your digital camera; if your interest is interactive fiction, there's software that will let you run all the Z-machine titles, including all the original Infocom games as well as all the newer stories.</p>
<p>They have a great built-in e-book parser, and in fact, the Newton book is according to some the original e-book format. This is of especial interest not just because there are <a href="http://www.newtonslibrary.org/">large libraries of Newton books</a> available, but because during the late '90s Newton, Inc. (before it was absorbed into Apple Computer) released the details of its Newton book packaging format to the world. The Newton book format is thus arguably an open format, and is thus open to all sorts of uses without fear of future lock-out. It's also a modern format with Unicode support that can handle many languages. I've personally been working on a <a href="http://www.newtonslibrary.org/nbrdr/">Newton book reader</a> that currently functions as an extension to Firefox (it makes it possible to read Newton books on machines running Mac OS X, Solaris, Linux, Windows XP, and everything else that supports Firefox), but any number of applications are possible.</p>
<p>The big thing that makes a Newton device useful isn't any one of these particular features; it's the combination of them all in a portable package. It's really got all the advantages of a typical tablet computer, but it's packed into a smaller and lighter unit, has instant-on / instant-off capabilities, was designed to even be used with just one hand while standing up, and pretty much never crashes. While these days people tend to think of <abbr title="Personal Digital Assistant">PDA</abbr>s as being devices to manage personal information and track meetings, Newton devices are much, much more.</p>
<p>Newton devices have come in many shapes and sizes. Besides the Newton MessagePad and eMate made by Apple and Newton, Inc., there are military-grade units made by Digital Ocean, a all-in-one <abbr title="fascimile">FAX</abbr> / copier station made by Siemens, and even other hand-helds made by other companies.</p>
<p>The later model Newton MessagePads stand out, though. Some people who've been in the computer business long enough get the ability to admire particular items not just on the merits of computer science, but on more artistic grounds. It's a little hard to explain, but some devices are more beautiful than others simply based upon the artistry in their design, and I don't mean this in a physical way based upon case mods and the like. It's a bit more like how a mathematician may find a certain formula beautiful, or a physicist may find a certain theorum beautiful. The Newton MessagePad is one such device; a person with enough background and enough exposure to it will invariably come to appreciate its elegance and beauty.</p>
<p>The Worldwide Newton Conference is going on right now in San Francisco as I write this, and even though I can't personally attend I'm actively following new announcments. One of particular interest is that Paul Guyot has gotten his <a href="http://www.kallisys.com/newton/einstein/en">Einstein Newton emulation project</a> running on other hand-held devices. This means that in the future it'll be possible to essentially turn other tablet machines into Newton devices; all that's required is that they be able to run Linux. It remains to be seen though whether these devices on new hardware will ever manage to be as elegant as original Newton devices.</p>Fenerichttp://www.blogger.com/profile/02260982910947326581noreply@blogger.com5tag:blogger.com,1999:blog-10404399.post-1111101815333248982005-03-17T16:56:00.002-05:002009-07-31T16:15:35.357-04:00Adventures with Apache 2<p>I've been again spending some quality time with <a href="http://httpd.apache.org/">Apache 2</a>. The <a href="http://www.apache.org/">Apache Group</a> has been stating that <q>we consider this release to be the best version of Apache available and encourage users of all prior versions to upgrade</q> for quite some time now; you can find this in <a href="http://www.apache.org/dist/httpd/Announcement2.html">official announcement</a> and <a href="http://www.apachenews.org/archives/000557.html">here</a> and <a href="http://osstudio.net/pr442/node/view/2059">there</a> elsewhere. Apache 2.0 does offer some major improvements Apache 1.3 (like filtering and internationalized error messages). It is also significantly, measurably faster.</p><p>Besides the comments by the Apache Group, you'll also find <a href="http://www.serverwatch.com/tutorials/article.php/10825_1497301_2">articles</a> and <a href="http://apache.slashdot.org/apache/02/09/09/209235.shtml?tid=148">discussions</a> questioning whether or not to upgrade and often implying that upgrading is a bad idea. The usual conclusion they come to as to why one may not want to upgrade is that not all third-party plug-ins have been upgraded to 2.0 yet. This is of course becoming less and less of a problem as time goes on, and is thus becoming a flimsier and flimsier argument.</p><p>Still, of all the production servers I manage, only one of them is currently running Apache 2. I'd love to upgrade the others, for the speed increase if nothing else, but I am still prevented from doing so. My problem isn't third-party plug-ins (in fact, the three plug-ins I most frequently use in Apache 1.3 are now standard components of Apache 2.0, so the plug-ins are actually easier with 2.0) but is instead something I haven't yet seen mentioned as a deal-breaker with Apache 2.0: caching.</p><p>With Apache 1.3 caching is robust and reliable. With Apache 2.0 caching is something of an adventure. I'd say it's a little more hit or miss, but actually it even lacks the <code>X-Cache</code> <code>HIT</code> or <code>MISS</code> <abbr title="HyperText Transfer Protocol">HTTP</abbr> header lines that make checking caching performance on Apache 1.3 so easy.</p><p>Going through the documentation for the Apache 2.0 versions of modules <code><a href="http://httpd.apache.org/docs-2.0/mod/mod_cache.html">mod_cache</a></code> and <code><a href="http://httpd.apache.org/docs-2.0/mod/mod_disk_cache.html">mod_disk_cache</a></code>, one finds a lot of messages stating that various directives are not yet implemented, and that in fact both modules are still experimental. They're also (often cryptically) buggy.</p><p>You might wonder why I need the Apache caching facility on the majority of my servers. The answer is simple: <a href="http://www.zope.org/">Zope</a>. <a href="http://www.saugus.net/">Saugus.net</a> (where I work days) is a <a href="http://www.zope.org/Resources/ZSP/">Zope Solution Provider</a>, and the majority of sites we serve utilize the dynamic capabilities of Zope behind a robust Apache front-end, and Apache caching is a simple and effective way of reducing a Zope server's load.</p><p>Every so often I try Apache 2 on a non-production machine to see how it handles caching, and each time I come to the same basic conclusion that it's not yet ready for prime time. Well, that is until 2.0.53 came out on February 8.</p><p>I tried it as usual and had it running for quite awhile on a test machine without problems. The lack of the <code>X-Cache</code> header made testing more painful than it should otherwise have to be, but it was still readily possible to tell whether a request had been served by Apache via cache or by Zope via dynamic generation. I actually started to dig into the source at one point to see if I could temporarily reactivate the header for testing purposes, but doing so was non-trivial and I did have other deadlines. In any case it looked pretty good even in a relatively complicaated fake set-up.</p><p>I then tried it on our <a href="http://www.shelltown.com/">ShellTown</a> machine. This machine primarily exists to provide shell accounts for customers; it only serves a handful of domains, basically just for itself and the shell customers who utilize it.</p><p>Things seemed fine at first, but after a couple days we got some trouble reports in that involved a very strange behavior: some of the domains would work properly if addressed without a prepended <code>www.</code> but wouldn't work properly in the opposite case. Specifically for the most troublesome case, the site <a href="http://www.ochmoneks.com/">Ochmoneks</a> worked reliably 100% of the time if it were accessed as <code>ochmoneks.com</code> but would produce a virtual directory listing (which even showed the proper <code>index.html</code> file in it) if it were accessed as <code>www.ochmoneks.com</code>. Weirdly, one could make it work if two trailing slashes were appended (one wasn't enough). Also, of course I checked the <abbr title="Domain Name Service">DNS</abbr> records for Ochmoneks.com, and they were fine and showed nothing unusual.</p><p>Turning caching off completely made the problem go away. Doing a search through the <a href="http://issues.apache.org/bugzilla/">Apache Software Foundation Bugzilla</a> reveals nothing that sounds similar out of the over fifty reported bugs involving caching in Apache 2.0, although I confess I've not been able to reduce this to a simple case. It only seems to happen on the real server.</p><p>The Ochmoneks site doesn't utilize Zope, so my workaround has been to hand-tune the <code>httpd.conf</code> file to cache only Zope-generated content. This is far from ideal, but there are few enough domains (and few enough Zope-generated pages as some domains feature both static and dynamic content) to make it viable.</p><p>Thus the <a href="http://www.shelltown.net/">ShellTown</a> customers get the advantages of Apache 2.0, but due to the oddities we've experienced we're in no hurry to upgrade any of the more complicated machines.</p>Fenerichttp://www.blogger.com/profile/02260982910947326581noreply@blogger.com0tag:blogger.com,1999:blog-10404399.post-1107045901007823842005-01-29T19:06:00.000-05:002005-02-06T12:38:44.643-05:00The Beginning<blockquote cite="http://www.imdb.com/title/tt0087182/">
<p>A beginning is a very delicate time.</p>
</blockquote>
<p>Or so spake Princess Irulan from 1984’s <cite>Dune</cite>. It’s one of those fun statements that’s both profoundly true and demonstrably false depending upon circumstances (bringing to mind Malaclypse the Younger’s quote, <q>All things are true, even false things</q>). It’s frequently said that a first impression can never be unmade, but yet when does a band make sound checks?</p>
<p>This post is intended to be more of the blogging equivalent of a sound check than anything else; the next post here will hopefully give a better taste of what this blog will be about. Since this is my personal blog I’ll occasionally be posting on various things that catch my fancy, but it’ll still mostly focus on computers and (especially) software. This post I’m using primarily as a testbed to try out various software and play around with layouts.</p>
<p>I’m currently expecting to post more or less fortnightly, but that is bound to change with real-world schedules.</p>
<p>The next section can be completely ignored. It’s some traditional dummy text in Latin used to fill space in documents for purposes of typesetting and layout. I’m using it not only for the latter purpose but also some <abbr title="Extensible Hypertext Mark-Up Language">XHTML</abbr>/<abbr title="Cascading Style Sheets">CSS</abbr> coding tests as well...</p>
<p lang="la">Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.</p>
<p>Of course, even though it’s basically Latin, it’s also semi-nonsense as it’s a bad chop & combo job on a couple of paragraphs from Cicero’s <cite lang="la">de Finibus Bonorum et Malorum</cite> (which translates roughly to the “Extremes of Good and Evil”). The original paragraphs are as follows:</p>
<blockquote lang="la">
<p>Sed ut perspiciatis unde omnis iste natus error sit voluptatem accusantium doloremque laudantium, totam rem aperiam, eaque ipsa quae ab illo inventore veritatis et quasi architecto beatae vitae dicta sunt explicabo. Nemo enim ipsam voluptatem quia voluptas sit aspernatur aut odit aut fugit, sed quia consequuntur magni dolores eos qui ratione voluptatem sequi nesciunt. Neque porro quisquam est, qui dolorem ipsum quia dolor sit amet, consectetur, adipisci velit, sed quia non numquam eius modi tempora incidunt ut labore et dolore magnam aliquam quaerat voluptatem. Ut enim ad minima veniam, quis nostrum exercitationem ullam corporis suscipit laboriosam, nisi ut aliquid ex ea commodi consequatur? Quis autem vel eum iure reprehenderit qui in ea voluptate velit esse quam nihil molestiae consequatur, vel illum qui dolorem eum fugiat quo voluptas nulla pariatur?</p>
<p>At vero eos et accusamus et iusto odio dignissimos ducimus qui blanditiis praesentium voluptatum deleniti atque corrupti quos dolores et quas molestias excepturi sint occaecati cupiditate non provident, similique sunt in culpa qui officia deserunt mollitia animi, id est laborum et dolorum fuga. Et harum quidem rerum facilis est et expedita distinctio. Nam libero tempore, cum soluta nobis est eligendi optio cumque nihil impedit quo minus id quod maxime placeat facere possimus, omnis voluptas assumenda est, omnis dolor repellendus. Temporibus autem quibusdam et aut officiis debitis aut rerum necessitatibus saepe eveniet ut et voluptates repudiandae sint et molestiae non recusandae. Itaque earum rerum hic tenetur a sapiente delectus, ut aut reiciendis voluptatibus maiores alias consequatur aut perferendis doloribus asperiores repellat.</p>
</blockquote>
<p>Translating the first paragraph into Esperanto (to both add length for this layout tweaking exercise and check on Unicode support) we have:</p>
<p lang="eo">Sed mi klarigas vin kiel ĉio tiu ĉi erara ideo pri plezuro denunca kaj doloro laŭda naskiĝis kay mi donos vin raporto kompleta de la sistemo, kay prezentas la efektivaj instruaĵoj de la esploristo granda de la vero, la konstruistestro de homa feliĉeco. Ja, neniu evitas plezuron mem, ĉar ĝi estas plezuro, sed ĉar oni kiu ne scias kiel postkuri racie plezuro renkontus sekvojn doloregajn. Krome neniu amas aŭ postkuras doloron mem, ĉar ĝi estas doloro, sed ĉar de tempo al tempo incidentoj de laboro kay doloro havigas al si iom plezurega. Ja, por malgranda ekzemplo, kiu de ni entreprenas ekzercon fizika peniga, krom gajni ia supereco konsekvenca? Kiu havas ia pravigon trovi kulpo kun homo kiu elektas ĝui plezuron kun ne ĝena konsekvencoj, aŭ oni kiu evitas doloron kun ne plezuro rezulta?</p>
<p>Of course, I don’t claim to know any Latin at all and my Esperanto is by no means the best in the world. I’m sure I’ll find any comments or corrections from folks with more Latin and/or Esperanto experience educational.</p>Fenerichttp://www.blogger.com/profile/02260982910947326581noreply@blogger.com1