Bit more detail on how I implemented the favatars stuff, perhaps.
The template that defines how a comment is output looks like this:
<div id="au$cmt_time" class="onecomment">
<img class="favatar" alt=""
src="http://www.kryogenix.org/favatars/$cmt_link">
<h4>$cmt_author_and_link</h4>
$cmt_description
[<a href="#au$cmt_time">#</a>]
</div>
The key bit in there is the
<img class="favatar" alt=""
src="http://www.kryogenix.org/favatars/$cmt_link">.
http://www.kryogenix.org/favatars/*SOMETHING* goes to a Python
CGI. You call it with a full
URL, so http://www.kryogenix.org/favatars/http://simon.incutio.com/ will display either the favicon from Simon’s site or my “no icon” icon. This is made very easy by Python’s excellent
urlparse module. You see, we need to get the favicon from the root of the server. To do this, just use
urlparse.urljoin to join whatever
URL you like with “/favicon.ico“. The key thing there is the / at the beginning. Watch:
>>> import urlparse
>>> urlparse.urljoin('http://www.kryogenix.org/','/favicon.ico')
'http://www.kryogenix.org/favicon.ico'
>>> urlparse.urljoin('http://www.kryogenix.org/days/','/favicon.ico')
'http://www.kryogenix.org/favicon.ico'
>>> urlparse.urljoin('http://www.kryogenix.org/days/something','/favicon.ico')
'http://www.kryogenix.org/favicon.ico'
>>> urlparse.urljoin('something that is not a URL','/favicon.ico')
'/favicon.ico'
>>> urlparse.urljoin('','/favicon.ico')
'/favicon.ico'
So, if you join the
URL the punter left with “/favicon.ico“, then you get the
URL for favicon.ico at the root of their domain. If they fill in something that isn’t a proper
URL, like an email address, a mailto: with email address, blankness, or some bullshit, then you just get back “/favicon.ico“. The script checks, and, if the joined
URL is “/favicon.ico“, it shows the “no icon” icon. If it isn’t, then it fetches the
URL, transforms it to a 40×40
PNG, and streams that
PNG for display. All nice and easy, thanks to the Python urlparse, urllib, StringIO, and Image libraries.
The code also caches icons so that it works faster. You can
read the code for favatar.cgi if you would like more details; it won’t work directly for you without some tweaking. You’ll also want a line similar to this in your .htaccess file:
RewriteRule ^favatars/(.*) /pyblosxom/favatar.cgi?url=$1
That’s pretty cool, but two improvements I’d recommend are making the image a link (but I don’t know what a gravatar is so maybe they’re meant to fulfill some other purpose) and also supporting icons that are given as a in the poster’s URL. I don’t know if it is an MSism but many things (including Firefox) support it, it isn’t too hard to add, and it solves the problem of people in mrben’s situation (assuming he has his own pages on the shared host that he would be linking to and it isn’t a shared page causing the forced sharing of icons). Here’s a function to get the most likely URL of an icon:
I put that in code and pre blocks in the hope that it would not try to parse it, but the preview doesn’t look like it is going to work. It isn’t very hard to write yourself, but hopefully you can guess what it looks like untextiled (the numbered lists used to be comments) or get at the source somehow.
If you want to use this function you’ll have to rework the file naming since you probably don’t want to call this function for every request just to see what the cached image is/should be called, but that shouldn’t be too hard; saving the images as the user inputted URL instead of the image’s URL would eliminate the space saving feature of http://website/foobar always pointing to the file http—-website-favicon.ico for any value of foobar, but if you add in some code to normalise an URL (like always remove trailing slashes) it shouldn’t prove too much of a problem since most people would enter the root of their namespace. Or you could go all out and cache the results of this function in some sort of mapping file. – Testing:
>>>print getIcoUrl(‘http://www.python.org/doc/2.3/modindex.html‘)
‘http://www.python.org/doc/2.3/icons/pyfav.gif’
>>> print getIcoUrl(‘http://www.google.com‘)
‘http://www.google.com/favicon.ico’ – Transparency: If the icon is a gif (all I tested with), you seem to be able to get transparency working fine by doing i.save(thumb,‘PNG‘,transparency=i.info[‘transparency‘]) in loadResizeImage() but ICO files don’t get a ‘transparency’ key in their info dictionary (so you’d want to add a has_key() check before doing that form of save).
I have no idea really how transparency works in PIL or file formats in general, so I may be missing something obvious, but getcolors() only shows 4 colors for one of the icons with transparancy problems on your comments (simon.incutio.com/favicon.ico) and it looks like it uses 4 colors so one isn’t set aside just for transparency and converting to an RGBA image lists each of the 4 colors with a 4th value of 255 (fully opaque, I assume, but all the same value at any rate). Doing the same with the python.org gif gives you an extra color and lists one of the colors as having a 4th channel of value 0 (vs. 255 for the others) if converted to RGBA. So ICO files don’t support the same way of getting at the transparency info of other files, and I suspect it doesn’t support transparency on them at all.