One day, while searching for something Django related, I ran into a really nicely done Django weblog. What caught my attention here, is that he came up with a way to spiffy up his comments display by showing a country flag for each commenter. It looks really spiffy. So I decided to play copycat.
Well, it only took a few minutes to implement it in the testing version of my own blog, and I showed it off to a couple of my friends in IRC. One of them, tjfontaine, said something along the lines of "oh neat, libgeoip." Obviously, I hadn't seen or heard of this libgeoip thing so I asked him about it and he linked me to it. Now this was interesting, because it comes with python bindings. And the best part, of course, is that it is in portage. So I installed it, and had a look at their usage sample. Essentially, you just download their ip to country map, which they update once a month, and so you don't have to hit their servers everytime you do a lookup.
Next up, I wrote the templatetag to use GeoIP. In its entirety, it looks like this:
from django.template import Library
import GeoIP
register = Library()
def get_country(value, arg):
''' arg is the location of the flag imgs, eg '/media/img/flag/' '''
try:
gi = GeoIP.open('/usr/local/share/GeoIP/GeoIP.dat', GeoIP.GEOIP_STANDARD)
code = gi.country_code_by_addr(value)
name = gi.country_name_by_addr(value)
except:
return " "
if code:
img = "%s%s.png" % (arg, code.lower())
return '<img src="%s" alt="%s" title="%s"/>' % (img, name, name)
return " "
register.filter('get_country', get_country)
And to use it in a template, you would do something like this:
{% load iptocountry_filter %}
{{ comment.ip_address|get_country:"/media/images/site/flags/" }}
So by switching to this method, I no longer need to have a special Django model to store the ip to country maps (and since I use postgresql, I don't have to go through the pain of altering any columns or updating my Django database every so often. Instead, I can just set up a monthly cron job to fetch maxmind's database file and put it on my filesystem. And that is why you see those little flag icons on alll the comments on my site.
The only concern that some people might have is that GeoIP is a GPL-2 application, so there's a concern that using it might virally make your own code GPL-2. If that is the case, then the above code is licensed under the terms of the GPL-2 as well, so use as you see fit within those terms, I guess. If it is not viral, then let's say it's a freebie. Either way, no warranty on it.
The idea is entirely Coulix's and he deserves all the credit for it.
18 Comments
Nice, very neat.
This is only a test, I repeat, only a test :-).
Can't resist testing this. :) Excellent job here, Seemant! I knew of you as a Gentoo person, but I didn't know you were a Django person as well! That rocks.
Cool, looks good ;).
simply irresistible...
hello from sPAIN
Another hello from Czech republic
Greetings from New Zealand
hello, Seemant,
i'm posting this here, because i can't find your contact mail. anyway, there seems to be a problem, because your new post named Building my Django Weblog: Part 4 isn't visible (only visible on rss feed).
Keep up the good work ;) Martin
Hi Martin,
I'm so sorry about that. I was still just writing part 4, so I hadn't intended to publish it just yet. So you found a bug, because I was not filtering out unpublished entries from my feeds :(
I've fixed that (so it should disappear from the feeds), and I'll publish part 4 as soon as it is done.
I'm working on creating a contact form for this site, too.
looks cool
Does this know I'm Belgian?
(In truth, I'm Canadian...)
Another test from Italy. :-) And thanks for this writeup!
Looks great!
I like the flag addition.
http://www.signaldev.com
Great series, Seemant.
You might want to add OpenID to the list of technologies you are learning related to this series.
Also a subtle point. I've noticed in your post that you are querying the GeoIP database during template rendering. I don't know how likely this is to happen, but it might happen that some IP blocks eventually get reassigned to a different ISP in a different country. Since you are querying the database at the time of template display and you are keeping the database updated, an old comment by a person in one country might suddenly change flags and appear to be originating from a different country with the updated database.
On the plus side, a person with a newly assigned IP address that hasn't made it to the last database update might get the correct flag with the next db updated, but this is probably much less likely to happen because the time difference between the comment and the database will be less than one month, but using your way, the time difference will keep increasing for old comments and will probably be years.
Hi Ahmad,
I've been thinking about your comment for a while. I agree with you -- I will change the models to save the country information into the database instead of dynamically looking them up at template rendering time.
And yes, OpenID is definitely on my list of technologies to explore with this blog. With any luck, it'll be within the next few weeks :)
hi from guess where? :)
lovely! simply lovely!
I can't resist to make one brainless comment - cool.