programmierung - 2.8.2005 - 2.10.2005

IRC logger for #django

There now is a IRC logger for #django on freenode.net. Ever since the loglibrary broke down, I thought about rolling my own. So I started to build the stuff needed for an IRC logger. The interface itself is written with django, of course

As allways, the source is available in my trac instance. It's currently only running in #django, but it can easily be extended to other channels. And it stores log lines in a database, so I will be able to add searching and stuff like that. It already has a calendar view on the logs.

The logging itself is done with muh - a nice IRC proxy that allows logging to named pipes. Then there is a script fetch.py that pulls the lines from the named pipe and stores them in the database. The last part is the django-based viewer for those logs.

Update: the logging is now done with a dedicated IRC logger written in python. It's in the source tree as loggerbot.py.

I could make use of generic views in Django, only that I needed to parameterize them. I did that with a wrapper function that moves stuff from the keywords of a view function to the extra_lookup args and extra context keywords of generic views. You can see the code in the repository.

The rest is just standard Django stuff: generic templates (that make use of the cool regroup tag) and some custom tags for the calendar and the user colorization. A bit of model hackery and that's it, actually. Nice and simple. Took only a few hours to bang together, and that includes playing with muh and named pipes ...

TwistedDAV is a WebDAV server in Python that runs under Twisted. Very interesting if you want to build something on DAV - so far there was only the Zope source as an example and basis.

How-to get decimal.py if I have Python 2.3.x describes how to get numbers in decimal representation (as opposed to the silly binary floats with their annoying rounding problems) for Python 2.3. Starting with 2.4, this is a standard module.

i18n and django

Jacob did set up branch commit rights for me and a branch for i18n stuff. So I worked today on the ideas in the patch on ticket 65 by nesh. I did write the stuff mostly from scratch because I wanted some things a bit differently and now it is available for testing.

So first on how you can use the i18n stuff with your django checkout. You need to have a current svn trunk checkout and go to the root of your checkout and issue the following command:

svn switch http://code.djangoproject.com/svn/django/branches/i18n/

After that you should have a tree with my patches applied. I currently only translated very little stuff to make the patch and changes as small as possible, but I already added a german translation file with stuf for the admin index and the isAlphaNumeric validator. I think I will add some more stuff to the translations soon.

The patch only addresses the translation part - other things like date formatting, number formatting, timezone handling should go into different patches to make each one of them as small as possible. The translation object (that's the beast that is responsible for turning strings into their new form) is built on request. This gives us the chance to look at various places that might help in deciding what language to present to the user. The code starts by looking into the session for a django_language variable. If that isn't found, it looks into the cookies for a django_lanaguage cookie. If that isn't found, too, it digs at the HTTP headers. It looks for the Http-accept-language header and splits that up by languages and sorts them by preference. It will use the first language (ordered by preference, highest preferences first) found in the django messagefile repository. If none of those languages can be found, it will ultimately fall back to the default translation object that is defined by the LANGUAGE_CODE setting in your settings file.Message files can be stored in three different places: the django project message files are stored in the django.conf package in a locale subdirectory. This is much like the admin_media and admin template directories. The locale subdirectory is structured as is typical with locale storage: one subdirectory per language and a LC MESSAGES directory in there. The language domain for django message files is allways django . The next place where django looks for message files is in the project - if you have a locale directory in your project, you can store additional message files there. The third place is the application - you can have a locale directory besides your apps views directory. All locale directories are structured the same.

A translation object for a given language is actually a concatenation of four translation objects: first the application translation object. This will have a fallback to the project translation. That in turn will fallback to the global translation object which will fallback to the translation object for the default language. That way higher levels can override translations from lower levels and applications can provide their own translations.

The application for the translations is actually discovered by module introspection - it uses the view func to call on a URL to discover what application carries this view func and uses that to look for local translations. There are two tools provided to manage translations: make-messages.py and compile-messages.py. Both tools can be called in either the root of the django svn tree or in the project directory or the application directory. make-messages.py will scan the current directory and everything below that for strings to translate and will create a django.po file in the locale directory for the given language. compile-messages.py will just turn all .po files into .mo files. Adding translations is easy. In python code you just surround strings (only string constants!) with ('...') or ("..."). That will mark those strings for translation so that make-messages.py can pull them out and write them to the .po files. And it will translate the string on runtime, using the current translation object as discovered from the request. In templates there is the template tag {% i18n ('....') %} - same syntax as with python code, only you need to wrap it as a template tag. Those strings will be pulled from the .html files into the .po, too. The i18n tag supports string interpolation from the context: {% i18n ('blah %(blubb) s blubber') %} would first translate the string and then interpolate the context variable blubb into the translated result.

A hint: when writing strings to translate, don't use positional parameters for interpolation (the %s stuff) but use named parameters (%(blah) s) instead. That way people building translations can reorder the string without breaking your code - some languages have different orders from english.

Using the translations is easy, too: you just need to set your default language in the LANGUAGE_CODE setting and add the django.middleware.locale.LocaleMiddleware to your middleware setting. You need to put it to the top - especially in the admin it should come before the AdminUserRequired middleware - but it needs to be after the SessionMiddleware, if you use that.

That's it for a start, play with it and tell me when something goes wrong. Best place to tell is on the ticket in the django trac.

Open Dylan

Open Dylan is ex-Harlequin Dylan, ex-Functional Developer - an integrated environment for Dylan programming and a library of various classes for different purposes - open-sourced some time ago and now available as the first beta for download for Linux and Windows.

I would prefer if Apple would release Apple Dylan, because its development environment was really light years ahead of everything else on the market, but that will probably never happen - rather there will be an OS X version of Open Dylan. Also quite nice.

Routes for Python

Very interesting: Ben Bangert has ported Routes to Python. Routes is the core of the mapping of URLs to functions and back that is used in Ruby on Rails. So a general mechanism with which a Python object can be determined from a URL and a URL can be determined from a Python object - flexibly configurable.

Could also be interesting as an element in Django, as an alternative to the current URL pattern system. The current system elegantly provides the function to be called from a URL - but unfortunately there is not the same way back from the object or the function back to the URL.

In addition, Routes could also be interesting within WSGI projects - it elegantly solves a small sub-area and in such an abstract way that it should harmonize well with things like Python Paste(Ian Bickings Meta-Framework for WSGI applications).

Why I Have My Doubts About Rails

It could become clear if you read through the article here: Choose a single layer of cleverness (Loud Thinking) - yes, exactly, his opinion is, out with referential integrity, stored procedures, and triggers from the database, because he wants to keep them all in his code. How about "throwing out the baby with the bathwater"?

It's so embarrassing that I almost don't know whether I should laugh about it - but one thing I certainly won't do: put my money on such a horse ...

Casual approaches with simple, clever solutions that sometimes go against conventions are okay (and important - otherwise we would all end up with Java and J2EE ...) - but if programming consists only of patching together half-baked solutions, then I'd rather stay out of it. I might as well use PHP then ...

I was looking for it for a company project: InformixDB is a Python-DBAPI1 client for Informix databases. It also works with Informix SE.

wxWindows Book

There is a book about wxWindows/wxWidgets: Cross-Platform GUI Programming with wxWidgets - although it focuses on wxWidgets and is primarily for C++ programmers, the wxPython bindings are left out. Nevertheless, it is certainly interesting if you use wxWindows in any form, as the bindings for other languages are always based on the original library.

Common Scheme

Common Scheme is an implementation of a common module standard for various Scheme implementations, including a package installer that can fetch its stuff from the net. This comes with a number of initial modules that are distributed via it. Could become something like CPAN for Scheme.

Similar approaches have been made before, but unfortunately only for individual Schemes (e.g. MZScheme has something like that). A Scheme-wide solution could make things a lot easier in the long run - and get Scheme out of the academic corner. The language deserves it.

And the best part: Gambit-C and Chicken are among the supported Schemes

Unfortunately, MZScheme is missing from the list of supported Schemes - it would be pretty cool to develop your programs with DrScheme and then simply run them through Chicken to get them quickly ...

I want one!

First signs of life from Open Genera on PowerMac - that would be really something if Open Genera didn't just run on weird OpenVMS boxes, but also on a PowerMac - I'd actually buy a desktop computer for that

Django Gallery Status

Again news from my gallery project - it's making good progress, even if some of my latest stuff isn't directly visible. I did a lot of reworking in the code and a lot of admin interface changes. Things in the source that might be interesting for other djangonistas:

  • I still have a fully filesystem based gallery - but I added a database stored cache. So now when contents is pulled from the filesystem, the code directly checks with it's database cache and updates that accordingly. This led to a heavy rework of the code so that now actually all stuff is driven by model objects - the cache entries are just part of the django model. Makes code much easier and allows the next two changes.
  • I added an automatic sitemap for galleries. First versions traversed the filesystem, but now it just uses the database cache to draw a folder hierarchy with thumbnails.
  • I added RSS support. The main gallery selection references a RSS feed over all galleries and the folder and image views within a gallery reference a RSS feed only for images within that gallery. This makes use of the RSS framework of Django.
  • the view that showed gallery folders and images was reworked to make much more use of django-like stuff: instead of lazy closures that are passed in to the template, I now use custom templates that help to reduce the code of the view drastically (ok, the code is moved to the taglib, but that's much better decoupling than before).

The result: the gallery is much faster, I have RSS up and running and I have automatic sitemaps. The code itself is much easier as it is more model-driven - the former clash between picturefolder model stuff on the one side and FSObject instances on the other side ist gone - and cache maintenance is automatic. And the XMLRPC integration is much faster, too. All in all some very useful internal changes.

Other changes are in the management interface where you now not only have the AJAX-stuff to change object names and hidden state, but can do that from a filemanager, too. That filemanager will be extended for simple management functions like moving, deleting etc., too. It already is able to create new folders.

Parser for Python-like configuration files

Philip J. Eby hacks again. This time, a parser for configuration languages whose syntax is based on Python. Particularly interesting: with the parser, you can beautifully build abstract languages that use Python for code in parts - you can convert Python blocks contained in it from the token form back into cleanly formatted and indented Python code. The parser, of course, knows all the edge cases of source formatting in Python and can handle them as well.

This is interesting because with Python, unfortunately, you don't have a macro language and therefore cannot directly map your own syntax extensions and languages with domain-specific syntax and semantics to Python - but you can build a translator for such DSLs via this parser and then convert them back into Python. Add a bit of import magic and you would have something like poor-mans-macros for Python ...

MochiKit Tutorial Part 1

The first part of the MochiKit Tutorial is online. Very interesting reading - some of the points are quite thought-provoking. And MochiKit has already proven itself to me in real-world use - and yes, I almost exclusively use JSON in the process.

News from the Gallery project

News from my Django Gallery project: it's coming along nicely. If you want sample code for AJAX with Django or XML-RPC with Django - look into it's source. I implemented parts of the blogger API, metaWeblog API and MoveableType API - just enough so that Photon can post pictures to my gallery. AJAX is used for logged in users to change the title of pictures and folders by just clicking the title and for activating the toolbox on the backside of pictures. Additionally the gallery includes the usual PIL stuff like thumbnailing - I am especially proud of the flipped corner look for folder thumbnails Other stuff worth looking into might be the usage of lazy evaluation to push stuff into the template without precalculating it - it's only calculated when the template actually uses it. And interesting might be the abstraction of the filesystem based content - only the base path is stored in the database model, the rest of the gallery is in the filesystem (and can so be easily managed with FTP, SSH or directly on the unix shell).

Additionally you might look into it for handling of authentication - user registration isn't yet done, but will follow some day. As will comments and RSS - but I have to write that, first. And I am starting to write documentation - docstrings in the code and documentation pages in the wiki.

JavaScript + CSS Box Model Puzzle

So, I have this HTML table. All the TDs are centered with their content using text-align: center. In these TDs, I have two DIVs displayed on top of each other. The top one contains an IMG, and the bottom one just contains some text. Both contents are also centered. Now, using JavaScript DOM functions, I swap the top DIV with the IMG inside it with another DIV that contains two DIVs, which in turn contain text. The texts in the inner DIVs of the new DIV are centered. However, the DIV itself, which contains the inner DIVs, is no longer centered relative to the encompassing TD. The problem is reproducible with Safari and Camino - somehow the "align content center" property is lost for the newly added elements. I've tried all possible CSS attributes and experimented with everything (e.g., checking if the old DIV with the IMG inside or the IMG itself has a value for left), but for some reason, it just won't work.

The background for all this: when you click on an icon, an IMG should be completely replaced with a DIV of the same size, containing some switches with which properties of the IMG can be changed. Basically, something similar to the widgets in Dashboard - configuration on the "back" of an image.

At the moment, I'm only taking over the height of the image, so the vertical alignment is perfect. However, the horizontal alignment remains dynamic. If I have two cells on top of each other and both switch to configuration, the table changes in width. This causes ugly jerking. But I don't want to statically expand the TDs, otherwise the layout would no longer dynamically adjust to the browser width.

Oh, and all this has to work with Safari, it's finally my main browser.

Update: in the comments, there are links to test pages with which you can see the effect.

JavaScript and the escape() Function

Note to self: escape() in JavaScript is only suitable for latin-1 - a utf-8 string with special characters sends these as latin-1 characters over the line. Pretty stupid when you're tinkering with a form via Ajax and then sending a value to a function in the backend that actually expects utf-8. encodeURIComponent is the answer, not escape.

MochiKit - First Experiences

I had already briefly mentioned MochiKit – A lightweight Javascript library. I used it at viele-bunte-bilder.de (offline since 2007) (so that the owner of a gallery could change the image names and folder names). Pretty brilliant small library for JavaScript. Makes working with JavaScript much more pleasant.

PostgresPy is a collection of various Python modules around Postgres. Server-side and client-side.

DjangoGallery - sample app with sample installation

Mal wieder englisch, da auch für #django interessant I have uploaded the source and made available the repository and a trac instance for my django projects. The first one that's there is the DjangoGallery - that's what I am using at viele-bunte-bilder.de. I have written a first take at an installation instruction that shows how to get the gallery running on your own site - you could even integrate it into your own project (although you will have to do some minor source changes - mostly replacing the projectname "gallery" by whatever your project is called).

The application isn't fully done, yet. There are many plans on how to extend it, as it will be my main motiviation to remove all other gallery software I am running (I already replaced PHP Gallery and now I am targeting my old mod_perl stuff and last one will be attacking my Wordpress based gallery), so be warned that it will change over time.

If you find bugs, feel free to file tickets. You can file enhancement wishes, too - but since the main target of this project will be to replace my own other gallery projects, it's doubtfull that I will do much work besides what is needed to reach that goal. At least for now - there's no limit to what can be done to the code after I phased out all PHP and Perl code

Since 2007 these links are non-functional, so I removed them.

Kibot is an IRC bot written in Python. With a simple plugin interface, you can let it loose as an all-round bot on a channel.

first Django application live

So, my first Django application is live - not finished yet, but at the moment already so good that it's better than the old PHP mess that was running before. And it's about my image gallery at viele-bunte-bilder.de. At the moment there is user registration and everything related to it - but I'll probably implement that later. Or maybe not. Let's see.

In any case, it's already quite nice - I can upload pictures directly from iPhoto again (which was the most important advantage of the old gallery software) and the files are in the filesystem, not in a database - which was also quite an important point.

The software itself is of course available - anyone who wants to browse, I have set up a Trac instance with my Django experiments.

Since 2007 nothing has been online.

ObjectiveCLIPS

Way cool: Objective CLIPS is a new development environment for OS X. From the description:

Using Objective C runtime introspection, CLIPS, and FScript, it is possible to write intelligent Cocoa applications. Any Objective C object can be asserted as a fact in CLIPS, however, CoreData provides an additional meta model along with object persistence.

CLIPS is an expert system environment that is based on a Lisp dialect and enables the management of rules and facts, as well as reasoning about them. FScript is a scripting language inspired by Smalltalk that works directly with the ObjectiveC classes in OS X. Both together should enable pretty cool things, especially since databases and documents can also be easily created with CoreData. And both languages (CLIPS and FScript) I found quite interesting in my experiments with them - CLIPS was even used by me for a longer time as a "Lisp replacement", because it is indeed a rather old-fashioned Lisp, but is equipped with powerful additional abstraction possibilities.

RSS 3 - twice

Again someone who thinks they can create a great new format: RSS 3.0 - and that someone is too stupid to google first. Because otherwise they would have stumbled upon RSS 3.0 and maybe thought about it.

Oh well, thinking isn't one of the usual activities of great inventors of syndication formats, as we already noticed in the discussion around Atom. I'm still convinced that all syndication formats are a large-scale net psychological test.

Heise also has something about it. And just like Rogers Cadenhead - who is on the RSS Advisory Board.

Writing PlugIns describes how to create iPhoto Exporter Plugins. Could be quite interesting.

Django has taken an important step for the release 1.0: anonymous sessions. Sessions were previously tied to user login in Django, but now it also works without registration. Much nicer than creating thousands of cookies for the user.

CRUD with Django

Create, Read, Update, Delete - the standard functions of classic interfaces - can be easily assembled with Django. For this, there are Generic Views. On Postneo there is now a CRUD Tutorial, which shows how simple such interfaces can be put together with Django.

Something interesting in Rails

Finally an application in Ruby on Rails that goes beyond the usual example applications - and is not just a weblog or a totally pointless to-do list management or something similar: VitalSource is an iTunes-like application for books with a corresponding backend and a frontend also based on Rails (but integrated into the application):

Apparently their backend applications have been running Rails for a while. But they've recently released their client software, and it runs Rails as well. Except... you won't see it running in a conventional browser. As the picture shows, the Rails app runs embedded within the client executable: in the case of the Mac client it uses WebKit to render the responses from the Rails app.

I was already fed up with all the Rails applications - which all sounded like textbook exercises.

A comparison of Django with Rails is a rather good comparison of Rails and Django. However, comparing two systems that address quite different topics is naturally quite difficult - but the article at least tries to position the two frameworks against each other.

Living Data

Funny title, isn't it? Well, I just noticed something while dealing with web frameworks and other applications, specifically in the Ruby and Python environments. Namely, the way mini-data is stored and how configuration data is handled, for example.

In the Java environment, there is an inflation of XML mini-languages - mountains of dead data. Dead because this data only exists in XML format and can only be processed and modified using XML tools. For example, if I have constantly repeating or algorithmically describable configuration blocks (e.g., a mountain of quite similar-looking URL patterns for a web framework), I can only generate these using XML tools - e.g., generate them from simpler formats using XSLT. Or I write small tools for this.

In Ruby, the situation is similar - only that instead of XML, YAML is used here. Ultimately, however, this is not better - the configuration is still a dead file.

But both in the Python environment and in various other dynamic languages, there is a good alternative to this: just use a module in your programming language. For example, Python modules live - if the structure is complex but partially repetitive - simply write a small Python function that helps with the dynamic creation of the config. If the config should partially come from database contents - simply write a Python function that reads this data from the DB at runtime and mixes it into the config. Living configuration data, after all.

Of course, security issues come into play here - we don't want to repeat the PHP mistake with the eternal eval. What is urgently necessary for this would be a clean sandbox for such modules. Unfortunately, there is a massive hole in the implementation right there in Python. There were bytecode hacks in the past, which were also revived - but these are just hacks. The method of building a pseudo-sandbox using restricted imports and proxy objects, as Zope does, is also not the be-all and end-all.

Perl offers a very clean method here - as is usual for all security features in Perl, this is of course used by almost no project - to regulate down to the smallest detail what the code in such a sandbox is allowed to do - and thus a configuration via Perl module is definitely better secured than in languages without such a concept.

Java itself, of course, has a pretty sophisticated security management system - necessarily, as it is also supposed to run in browsers with very restricted rights. This security model is also usable for applications and could be used, for example, for servlets or Java configs - especially since you can also easily translate files at runtime and load them dynamically with Java. Now explain to me why the Java people are so fixated on XML when they have the best foundations for secure living data ...

We will ignore the safe model of PHP here, because it is a soda-or-seltzer model - either every code runs under safemode, or none at all. What we would need is a selective activation of different security classes for a single code block or module import (ok, PHP also doesn't have module imports, only includes - I say, we just ignore it).

So far, you can only work with living configurations in Python if you are sure that the configurations are only edited by users without malicious intent. Django, for example, only uses living configurations - it would therefore be a pretty stupid idea to make the configuration files editable via the web for centrally hosted applications.

We urgently need a clean sandbox for Python. I even believe that this would be a more important subproject than the various syntactic extensions that are repeatedly addressed.

wxWindows now also for Common Lisp

wxCL provides Common Lisp libraries for using the brilliant wxWindows GUI library. Very nice - I have already appreciated wxWindows in its Python incarnation, and in Scheme (via DrScheme) it is also very helpful. Now Common Lispers can use it too. I know that in Common Lisp, of course, CLIM (today often in the form of McCLIM) is the toolkit of choice, especially since it is much more powerful than wxWindows. But still, it's nice to have a cross-platform GUI library, especially because it is available for more than one programming language.

the strange tendency of PHP programmers to eval

Vulnerabilities in PHP modules endanger (once again) numerous web applications - and once again it's XML-RPC. They are still using eval - and that's for evaluating tags. Seriously? Sorry, folks, but this is just ridiculous - eval has already blown up in your face, why weren't all those calls removed back then? Or at least properly secured?

And people wonder why I don't have much faith in PHP software ...

trac - Easy Software Project Management

trac is a web interface for Subversion repositories. However, it is not just the appropriate web interface - it also includes a wiki, a bug tracking system, a milestone management, and very comfortably created reports based on the bug tracking. And all of this in a very easy-to-install package - on Debian, an apt-get install trac is sufficient and then with trac-admin initenv a Trac instance can be created. It also looks quite appealing and the functions are very well integrated - links from the tickets to the wiki or links from changeset descriptions to the wiki or the bug tracking are easy to make and of course help enormously in managing software changes. Additionally, there is a nice timeline that documents and links changes to the system over time - among other things, also to a very comfortable changeset browser.

I have now thrown away all the handmade stuff for TooFpy and switched to trac. Just the possibility of assigning my ToDo list, which was previously managed in the source tree, to planned releases via tickets brings a lot of overview to the project.

Yep, anyone who has to manage a software project should definitely take a look at trac, because anyone who is not necessarily a control fetishist will certainly be happier with the rather open structure of trac than with some overengineered parts.

kenosis is a Python library for a simple P2P protocol that is based on XMLRPC. Simple and straightforward, but without any form of encryption - should therefore be used over externally encrypted or otherwise secured channels.

Nitro is a web framework for Ruby. Clearly positioned as a competitor to Rails, it addresses some of Rails' weaknesses - for example, the rather meager Object-Relation-Mappers in Rails via ActiveRecords. Nitro uses Og instead. Otherwise, the features are significantly more developed - more code, less hype.

XchatPython is a plugin for X-Chat that allows you to write extensions in Python.

Mathematical Ignorance

It's almost modern to talk about how bad you were at math (I wasn't, I was very good at math - and yes, I really enjoyed math), but when you read James Gosling asking questions about sine/cosine and the meaning of the period definition with 2*Pi, you really scratch your head. Slava Prestov at least sees in this the explanation why most programmers ask really stupid questions about the simplest mathematical problems, when even the big shots in the industry don't understand basic trigonometry ...

International Components for Unicode is a library of reference implementations of all Unicode standards, specifically concerning character transformation, normalization, and sorting, but also many other localization issues such as date formatting, etc.

PyICU is an integration of the ICU C++ interface into Python. Seems quite comprehensive in terms of scope. Integration with Python string data types is also provided.

Connecting databases to Python with SQLObject is a quite nice introduction to SQLObject - one of the nicer Object-Relation-Mappers for Python.

Unicode HOWTO for Python. Python programmers should read.

Crypt::PasswdMD5 is a Perl module that hashes MD5 passwords the same way Linux and Solaris do.

md5crypt.py is the same algorithm for MD5 passwords, this time in Python.

Store passwords as hashes - safe?

Not quite new (it was new last summer, but I somehow missed it, the underlying paper is even two years old), but still interesting: Project RainbowCrack is a project aimed at creating tools for faster cracking of hashes. Hashes can normally only be resolved through brute force - supported by algorithmic weaknesses (as recently found in MD5 and SHA1). However, there is an approach to create the more complex calculations that arise during the brute-force process (i.e. essentially algorithmic sub-steps) in advance - for example, if you only intend to crack passwords with a maximum number of characters.

Of course, this does not come for free: you trade computing time for storage space. Tables for cracking up to 14-digit Windows passwords occupy a casual 64 GiB of memory. The practical relevance of the approach and the tools may become obvious from this quote:

Some ready to work lanmanager and md5 tables are demonstrated in Rainbow Table section. One interesting stuff among them is the lm #6 table, with which we can break any windows password up to 14 characters in a few minutes.

There is also a web interface to a distributed computing cluster for Project RainbowCrack, through which you can send MD5 hashes to an MD5 cracker, which then - if it is a string with a maximum of 8 characters - spits out the plain text. And this thing is constantly building more Rainbow Tables, making cracking faster and faster.

Just as a warning for those who think that a simple MD5 hash (or ultimately almost any hash) on the password would be sufficient. Unix systems typically use salted hashes - the password is extended by a plain text and then the hash is formed together with it. This extends the password in principle, even if the extension is of course not secret - for the computing time or the table size it doesn't matter, the passwords are simply longer and thus harder to crack. But it is also only a matter of space until they are not secure.

Better are passphrases instead of passwords - just simply normally long sentences. On the one hand, you can often remember these better (many people cannot remember a phone number, but can quote lines from poems) and on the other hand, they are simply longer (and especially flexibly long), so that Rainbow Tables as an attack method are out of the question. The algorithmic weaknesses of MD5 and SHA1 remain, of course.

A Treeview in JavaScript that can be used within pages (without frames) and still remembers its state.

Again something new with Django

There's always news, but this time there's a very interesting feature again: the inspectdb command delivers all the tables and fields from a PostgreSQL database in the format of a Python data model. Additionally, foreign keys are also found if they are stored in the database. Very practical if you need to build an interface for an existing database, you save a lot of typing work.

Ian Bicking on what's currently happening with SQLObject - it had become quite quiet around one of the nicest SQL object layers for Python, but now it's moving forward again. The most interesting point for me: Tool support for database upgrades. A point that, for example, is still missing in Django.

Coroutines for Python

Philip J. Eby has provided a patch for the implementation of PEP 342. This means that the chances of Python having coroutines in the future are very good.

And that, in turn, means that Python will get a - albeit primitive - form of continuations. Now all that's missing is for something like statesaver to be integrated into Python - for multishot continuations (ok, first just copyable coroutines, but that would be a start at least).

All of this, of course, just to finally be able to work with continuations in web frameworks. Ok, it's already possible with CherryFlow, but it would be nice if all of this would make it into mainstream Python.

Whoever wants to deal with larger Erlang software and try out a Jabber server, might find ejabberd interesting - a Jabber server that uses all the nice features of Erlang to offer, for example, simple clustering and good data distribution.

The Illusive setdefaultencoding

Ian Bicking mentioned a nice trick in his article about setdefaultencoding: simply reload the sys module with reload(sys) to make setdefaultencoding available.

setdefaultencoding is used to set the default encoding for bytestrings. Normally, this is ASCII, but it can be changed to iso-8859-1 or utf-8 - if you have setdefaultencoding at all. Unfortunately, it is deleted when the Python runtime environment starts - because the Python developers want to patronize the users again.

reload(sys) is of course something that does not necessarily inspire confidence - sys is after all not an unimportant module. But in my experiments it has worked so far and it definitely helps with the whole Unicode problem if you can give your programs a different encoding as standard.

It would be nicer if setdefaultencoding were not deleted in the standard distribution. Of course, this can also be achieved by patching site.py, but that is not better than reloading sys ...