Python Programming, news on the Voidspace Python Projects and all things techie.


My Honoured Guests

emoticon:restart Yup... the time has come, The Voidspace Python Guestbook 1.4.1 has been released into the wild.

What is the Voidspace Python Guestbook

Guestbook is a Python script that allows you to add a 'guestbook' facility to your website. It is fully customisable using HTML templates - so the guestbook will appear to be fully integrated with your website. The entries are saved in a plain text file, for easy editing, and there is a naughty word filter as well. Almost every aspect of the appearance is editable using the templates. A few other user settings can be configured as well. All the instructions are contained in the template file.

It can email you when an entry is made by someone, and also features smilies, spam protection, javascript form validation, and allows a limited set of html in comments. It is regularly improved and updated.

What's New ?

This is a major update since the last release [2]. The new features are :

  • Javascript form validation (client side)
  • More advanced anti-spam features (we do a basic check that the entry was made by a human rather than a bot)
  • A limited set of html is now allowed in entries
  • Smilies !!!!
  • Better use of CSS in the standard template
  • Counter tells you how many times the guestbook has been viewed
  • A few other bugfixes and improvements

Because of the changes there are a few external files (python modules and javascript files) that will need to be installed, as well as the smiley images. Full instructions come with the docs.

[1]Using the HTML templates
[2]Version 1.3.0 was the last released version. 1.4.0 did exist for a few days before it was superceded.....

Like this post? Digg it or it.

Posted by Fuzzyman on 2005-04-29 12:33:38 | |

Categories: ,


Stripping Off

emoticon:python I'm preparing for a new release of the guestbook. It will also soon have it's own sourceforge project [1]. I'm just adding a DNSBL lookup, as a further measure to combat spam, and it will be ready.

UPDATE: I've added a nifty counter which tells you how many times the guestbook has been viewed. I'm releasing this as 1.4.1 and updating when I've had time to add a DNSBL lookup.

I'm not going to list all the new features here - as there are several nice new touches, and I'll save it for the announcement. One of the things it does do is allow a subset of HTML in the guestbook entries. It allows the html savvy user to use tags like '<em>', '<strong>', '<code>', etc [2]. It will also attempt to correct any bad html (i.e. unclosed tags) so that the whole of the guestbook doesn't end up in a bold faced font Bad Grin

There are various possible approaches to this, but I ended up using a simple function and the excellent htmldata module by Connelly Barnes. As requests for something like this turn up on comp.lang.python from time to time, I thought I'd put the code here.

from htmldata import tagextract, tagjoin
allowed_tags = ['br', 'b', 'strong', 'em', 'i', 'u', 'tt', 'a', 'big', 'small',
                'h2', 'h3', 'h4', 'strike', 'sub', 'sup', 'samp', 's', 'code', 'ins',
# I haven't allowed 'h1', 'pre', 'hr', 'table', 'ol', 'ul', etc
# 'pre' breaks my page layout :-(
def stripHTML(intext, allowed_tags=allowed_tags):
    """Uses htmldata to strip extraneous tags from HTML.
    operates on a 'whitelist'.
    from htmldata import tagextract, tagjoin

    html = tagextract(intext)
    out_html = []
    skip = None
    unclosed = []
    for entry in html:
        if isinstance(entry, basestring):
            if skip is not None:
            tag = entry[0]
            if skip is not None:
                if tag.startswith('/') and tag[1:] == skip:
                    skip = None
            otag = tag
            if tag.startswith('/'):
                otag = tag[1:]
            if otag in allowed_tags:
                if tag.startswith('/'):
                    if otag in unclosed:
                    else:   # bad html
                elif tag not in ['br', '/br', 'br/', 'hr', '/hr',
                                 'hr/', 'img', '/img', 'img/']:
               # we don't need to close 'br' tags
            if not tag.startswith('/'):
                skip = tag
    for tag in unclosed:
        out_html.append(('/%s' % (tag,), {}))   # close any unclosed tags
    return tagjoin(out_html)
[1]Not especially because it needs one, but because (as far as I can see) there's no Python guestbook script there yet.
[2]But not '<pre>' which breaks my layout (on IE) for some reason, and isn't needed anyway.

Like this post? Digg it or it.

Posted by Fuzzyman on 2005-04-28 11:33:38 | |

Categories: ,


Can I Grok It ?, Yes I Can

emoticon:paper Grok is a weird American word. I don't know why I find it quite so awkward, but that's really irrelevant anyway. It basically means to read and understand, or to take in [1] - and it probably has some weird techie genesis that I can't be bothered to look into - and this is still all irrelevant.

Anyway, it is often said [2] that programmers find it easier to implement something themselves, than to understand someone else's code. A vital skill for being an effective programmer is being able to read and understand other people's code. Otherwise you get bogged down in your own familiar design patterns - and don't develop the flexibility of seeing things from an alternate point of view.

That's why I always like using other people's libraries - at the very least you have to understand the interface they've designed.

This week I've been doing both. The latest update to the guestbook uses two (small) libraries created by other people. by Mark Andrews and htmldata by Connolley Barnes. I've made some modifications to, which includes further explorations into javascript. I've also added javascript form validation to the guestbook, which took some fairly heavy grokking of the excellent unobtrusive javascript code by Christian Heilmann. Javascript isn't quite as black as it's painted [3], I'm enjoying learning it. It's nice to be learning another language - it complements Python well.

What was more of a headache - but probably more useful - was trying to undo the hacks I made in firedrop [4]. I've trying to reverse the order it generates some of the blog entries, and the order it displays entries in the GUI. By some injudicious use of sort() I'd managed to randomise the order it generated blog entries. Now Firedrop is intended to be more than a blog tool - and I'd like to use (and possibly extend) it's document generating powers. This means that :

  1. It's more complicated under the hood than might appear
  2. I'd like to learn to use the extra functionality it has.

Chasing through the forest of Publisher class, the Weblog subclass, the archiver, the macros, the mainframe gui etc etc was a real mission. Eventually I managed to sort all the categories, archives, and the front page in the order I wanted. I also understand Firedrop a lot more than I did. It's not bad - and it looks like that I can get it to generate whatever style documentation I want by subclassing Publisher. I might use this to help me overcome the limitation of docutils - that it can't generate multipage documents.

[1]Explanation for the sake of the ignorant English Very Happy
[2]Well, I remember reading it somewhere anyway - it is certainly true in practise for me. Note: one reference is Joel Spolsky, who actually said Programmers find it easier to write code than to read it.
[3]As a language it's ok, cross browser stuff is a nuisance though. The DOM is nice though - with all sorts of exciting possibilities when you combine server-side and client-side processing.
[4]The client side blog tool I use, by Hans Nowak.

Like this post? Digg it or it.

Posted by Fuzzyman on 2005-04-29 11:48:53 | |

Categories: ,

Hosted by Webfaction