Things about me, the web and the wonderful world of software development.
 

  • Ack! Looks like Twitter's codes are broken!

 

Image Conversion in Python

Yesterday I had to convert a lot of pictures to different formats. I quickly came up with a Python Script that searches a specified path recursively for images and converts them to one or more output formats. It's nothing fancy and it was late at night so don't blame me for bad code. I just thought I'd share it here because it might be useful for someone. In order to run this script you need to have PIL installed.

class ImageConverter(object):

def __init__(self, types_in, types_out):
self.types_in = types_in
self.types_out = types_out

def search_files(self, path):
if path[-1] != '/':
path += '/'

print "searching files in " + path
for root, dirs, files in os.walk(path):
for fname in files:
fullpath = os.path.join(root, fname)
if os.path.splitext(fname)[1] in self.types_in:
self.convert_image(fullpath)
def convert_image(self, filepath):

for t in self.types_out:
outfile = os.path.splitext(filepath)[0] + t.lower()
print "converting image %s to %s" % (filepath, outfile)

try:
im = Image.open(filepath)
im.save(outfile)
except IOError as detail:
print "Failed to convert image %s to %s. Details: %s" % (filepath, outfile, detail)

except:
print "Unexpected error: ", sys.exc_info()[0]
raise
if __name__ == '__main__':
if len(sys.argv) == 1 or len(sys.argv) > 2:
print 'Usgae: python ' + str(sys.argv[0]) + ' /path/to/search/'
else:
converter = ImageConverter(['.gif',], ['.tiff',])
converter.search_files(sys.argv[1])

I think the script is pretty self-explanatory. Simply pass the path to search for images as a command line argument. When instantiating the class, the input and output formats can be specified as a list.

I think that's it for today.

Posted in: Development  Tags: python

Extend Django's manage.py command

In Django 1.0 it's very easy to extend the default functionality of the manage.py command.
I use it to delete the comments that have been marked as spam. The cool thing is that you can access the data model using the ORM. So, let's see how this whole thing works.

First off, we need to create a 'management' folder within our application. In there, we need to create a folder called 'commands'. This is the place where we can put our Python scripts. Don't forget to create the __init__.py files in both folders. The directory structure should look something like this

app/
__init__.py
models.py
management/
__init__.py
commands/
__init__.py
greatcmd.py
views.py

As you can see above, I have already created a file called 'greatcmd.py' within the commands directory. The name of the file will also be the name of our command. In this example, we would execute the command like this

./manage.py greatcmd

Now let's take a look inside the greatcmd.py file

from django.core.management.base import BaseCommand
class Command(BaseCommand):
help = "This doesn't do anything yet"
def handle(self, *args, **options):
print 'greatcmd was called'
# other fancy code here

That's basically it. You can add pretty much anything in the handle method. It's also possible to import your models etc. Pretty convenient and straightforward. Please note that you have to be in your application's directory when executing the manage.py command. Otherwise you won't be able to run the custom command.

If you wanna know more about it, take a look at the official Django Documentation. If you're interested in how I fight spam in my Django Apps, feel free to read my other post Preventing Spam In Dango.

Posted in: Development  Tags: django, python

Django Admin tweaks

In an earlier post I wrote about adding a WYSIWYG editor to Django's Admin interface.
As a fallow up, I'd like to share some thoughts about an interesting project I came across recently.
It's called django-grappelli and is hosted on Google Code.
It basically changes the whole look of the Django-Admin interface. Some people might not like that as they love the original look.
I have to say, I like the original look too but I think django-grappelli just improves the interface dramatically! The look & feel is totally different. When I first used it, I really thought, whow, this is big.
They even added a nice looking TinyMCE theme.
So I have to say, everything looks complete and consistent.
Anyway, enaugh teasing. Check out the screenshot below and make sure to visit the project site here.

Grappelli Admin Interface

Posted in: Development  Tags: django

Serve Django on Gentoo with lighttpd

In this post you'll find a step by step guide on how you can serve your Django site on Gentoo, using lighthttpd and FastCGI.
Even though this guide is written specifically for Gentoo, it might also be helpful if you use another Linux distribution.

Let's start with installing the required packages. As root, run the following command (flup is required for Django's init.d script)
emerge flup lighttpd
Next, go and grab yourself a copy of Django's InitdScript for Gentoo and give it an appropriate name. Mine is called django-fastcgi. Just to mention it, a version for other Linux distributions is also available here. The script is pretty self-explaining. You only have to change the DJANGO_SITES and SITES_PATH variables. The DJANGO_SITES variable is the name of your Django project, and the SITES_PATH variable is the path to your project (without a trailing slash I think).
Let's assume the absolute path to your project is /var/www/myproject/. The configuration for this setup would look as follows

DJANGO_SITES="myproject"
SITES_PATH=/var/www
RUNFILES_PATH=/var/django/run
HOST=127.0.0.1
PORT_START=3000

Now you can go ahead and copy the script to the init.d directory by running
cp scriptname /etc/init.d/
Make sure the script is executable
chmod +x /etc/init.d/scriptname
Try to start the fast-cgi process like this
/etc/init.d/scriptname start
If you don't see any errors showing up, you can add the script to the default runlevel to make it start automatically in case you have to reboot your server. In order to do so, simply run
rc-update add scriptname default
Alright, still with me? Cause we're not done yet.
We can now configure our lighttpd server. With your editor of choice, open up lighty's config file. You can find it in /etc/lighttpd/lighttpd.conf.
Make sure you have the following modules enabled

server.modules = (
"mod_rewrite",
"mod_redirect",
"mod_alias",
"mod_access",
"mod_fastcgi",
"mod_accesslog"
)

Now let's configure lighty to work with our fast-cgi process. Somewhere at the bottom of the configuration file, add the following part

$HTTP["host"] =~ "(^|\.)yourdomain\.com$" {
server.document-root = "path/to/your/django/project" # same path as the SITES_PATH in the fastcgi script
server.errorlog = "/path/to/your/logdir/yourdomain-error.log"
accesslog.filename = "/path/to/your/logdir/yourdomain-access.log"
fastcgi.server = (
"/youdomain.fcgi" => (
"main" => (
"host" => "127.0.0.1",
"port" => 3000,
)
),
)
alias.url = (
"/media" => "/usr/lib64/python2.5/site-packages/django/contrib/admin/media/",
"/favicon.ico" => "/path/to/favicon/favicon.ico",
)
url.rewrite-once = (
"^(/media.*)$" => "$1",
"^/favicon.ico" => "/favicon.ico",
"^(/.*)$" => "/yourdomain.fcgi$1",
)
}

Some quick notes about this. The regex pattern at the top makes sure you can use both www.yourdomain.com and yourdomain.com to visit the site. The media alias url is used for the Django Admin site and it's media content. So change this path to wherever you have installed the Django source-code. The favicon part is optional. You only have to add that if you actually have a favicon and want to display it. As you can see, there's also another fast-cgi script mentioned in the configuration. We are going to create this file now. Open an editor and put the following line in it

#!/bin/sh
export DJANGOSETTINGSMODULE=yourproject.settings.main

Place this script in your Django project folder. Also make sure it is executable
chmod +x /path/to/your/docroot/yourdomain.fcgi
Now try to start lighttpd
/etc/init.d/lighttpd start
If this works, you can also add lighttpd to the default runlevel
rc-update add lighttpd default
Ok, now you should be able to visit yourdomain.com and see your Django application. When I first tried this, I ran into a small problem. Sometimes, the url looked weird because it displayed the name of the fast-cgi script in it. I was able to solve this issue by adding the following line to my settings.py file
FORCE_SCRIPT_NAME = ''
I hope I didn't forget anything. It's been a while since I set up this environment.

One last note, you could also run the Django fast-cgi process using Unix sockets rather than using a TCP connection. I didn't try it myself but it looks pretty easy. You can find more information about that here.

I hope this post helps some people to get things running correctly.

Posted in: Development  Tags: django, gentoo

Back After Some Downtime

Over the last weekend I migrated my Webserver from FreeBSD to Gentoo. Most of the things worked flawlessly. Since I was in an updatey mood, I decided to change the way the Django site is served too. I used Apache & mod_python before which was a rather slow solution. I am now using lighttpd aka lighty and fcgi to serve this site. I can say, it's definitely a lot faster now.
I'm gonna write a detailed post about serving Django with lighttpd on Gentoo later on. I'm kind of busy at the moment so I don't find much time to write down all the stuff I want to.
Here are some posts I'm planning to write in the near future:

  • Serve Django with lighty on Gentoo
  • Complex Queries with Django's Q object
  • Create a simple site search with Django

So ya, I guess that's pretty much it for this post.

Posted in: Random  Tags: random

« Older Page 1 of 4