Reverse mashup

Web September 3rd, 2008

I barely remember when was the last time I updated Gelman. This project starts as an exercise to practice my Django + dojo skills, and also to manage my eBook collection, I were stuck in UI design which I suck and the authentication/registration which I takes little interest in.

What if we take a different approach to avoid the reinvention of the wheel? Let’s take an online eBook management Web2.0 application, for example LibraryThing, to manage the Read, Reading, Wish to Read list, if an electronic copy is available, it will be inserted into the LibraryThing search/detail page, and we can add it to Reading list for quick access later. We just mashup our web service into LibraryThing!

This application can be decomposed to two parts:

  • A Web service to CRUD eBook collection hosted in home-brew server
  • Firefox Add-on or GreaseMonkey user script for mashup
  • A web service client to automate importing books
  • Find your favorite app, then mash it up!

A more portable solution to glue the pieces is to leave the mashup in the server side, using a proxy server to insert all the mashup data.

As all comments, tags, reading history has been hosted in the cloud, it is essential to do something against the raining day:

  • Big name may endorse the availability. I would seriously consider Shelfari only after it is acquired by Amazon
  • Open API is the key. This is the trend, the web site could not lock on the user by closing itself, the users may cold feet in the first place. Douban, the leader in the Chinese market, did an excellent job to open its platform.

I am working on an prototype of the RESTful web service using Django, stay in tune.

Django’s D-day

Development, Web April 7th, 2008

Google just released the Google App Engine in python development environment. The environment is loaded with WSGI, and Django 0.96 “for convenience”.

Just checked the Datastore API, it is a copycat of Django reference. Google’s engineers hacked the Django’s Model to support Google’s datastore, aka BigTable. Bang! Google Account is also supported via User API, no idea whether it is integrated to Django’s authentication framework though.

I am so glad that Google has made such a move, I can bet the Django users may grow exponentially in the following couple months. Today is Django’s D-day.

HOWTO deploy Django in Jumpline

Web February 24th, 2008

The blogosphere discussed the headache of deployment for modern Web Framework on shared hosting recently in couple weeks ago. This HOWTO documents the bumps and workaround in deploying Django to Jumpline’s VDS(Virtual Dedicated Servers) hosting.

Compared with the ironclad shared hosting, VDS provides SSH access, and private Apache server. Jumpline’s plan is also shipped with mod_python(python 2.5) and write access to PYTHON/site-package and /usr/local/bin, that make the whole process less painful.

Setup the VirtualHost

Add a sub-domain as planet.kunxi.org in VDS console as our testbed.

Install Django SVN

It is a pity that Subversion is not installed in the chroot jail. In fact the Subversion hosting is a premium feature you need to pay for. Anyway, we can just check out the code in the local machine, then copy it back to the server. In the server:

python setup.py build
python setup.py install –prefix=/home/lib

If you happen not to have write privilege PYTHON/site-package, you may consider add –prefix to override the default installation path, then add the prefix to your PYTHONPATH environment variable.

Setup the mod_python

Load mod_python in httpd.conf

LoadModule python_module modules/mod_python.so

As the name suggests, planet.kunxi.org is a feed aggregation portal based upon FeedJack, some enhancement are in plan to scratch the etch, now it is just mere a simple deployment:

<VirtualHost *:80>
    ServerName planet.kunxi.org
    DocumentRoot /var/www/planet
    SetHandler python-program
    PythonHandler django.core.handlers.modpython
    PythonDebug On
    PythonPath “['/home/projects'] + sys.path”
    SetEnv DJANGO_SETTINGS_MODULE feedpipe.settings
    <Location “/media”>
        SetHandler None
    </Location>
    <Location “/static”>
        SetHandler None
    </Location>
</VirtualHost>

/media and /static are set to host static media contents. /media is mere a soft symbol link to django/contrib/admin/media. We also link /static/feedjack to feedjack’s media files as FeedJack’s document suggests. Here is the feedpipe.settings:

MEDIA_ROOT = ‘/var/www/planet/static’
MEDIA_URL = ‘/static/’
ADMIN_MEDIA_PREFIX = ‘/media/’

Restart httpd, done.

Learning Django by Example(7) Attach a tag

Web January 20th, 2008

Tag is probably the most distinguish feature of Web 2.0 applications that differentiate them from the traditional hierarchy categories. I want to attach a Web 2.0 tag to Gelman, so the user could simply click the tag, and find the related books that may arouse his/her interest.

django-taggingis a generic tag application to simplify the backend development, all you need to do is just add the TagField to the Book model:
class Book(models.Model):
……
tags = TagField()

And in the book_detail.html template, refer it as object.tags as this:

{{ object.tags|popuptags|safe }}

popuptags is a custom tag that decorates the tags as a list of HTML links, and join them:

@register.filter
def popuptags(value):
    tags = value.split(” “)
    return ” “.join([‘<a href="/bookshelf/tags/%s">%s</a>’ % (x, x) for x in tags])

So tag foo is linked with /bookshelf/tags/foo, so just redirect the request to the view:

(r‘^tags/(?P<tag_name>[\w-]+)/$’, views.by_tag)

And handle it in views.py:

@login_required
def by_tag(request, tag_name):
    tag = Tag.objects.get(name=tag_name)
    return list_detail.object_list(
        request,
        queryset=TaggedItem.objects.get_by_model(Book, tag),
        template_name=“bookshelf/book_list.html”,
        extra_context={‘title’: ‘Tagged by %s’ % tag_name},
    )

All the tedious work has been handled by django-tagging: we first get a tag object by name, and then build a QuerySet using get_by_model method; the rest is handled by the generic view, done. Salute to django-tagging developers!

We would discuss how to add a tag in the next post, that is the magic of Dojo.

Learning Django by Example(6): Search

Web January 4th, 2008

Search is one of the must-have functionalities in Gelman. Here is an SearchQuerySet based upon MySQL full text search extension. It is really cool and neat, but

  • first, I don’t want to build my application against specific database extension, even though MySQL is universally picked up in the Web application.
  • second, I still prefer more flexible and powerful search syntax other than what MySQL provides
  • Last but not the least, I may still need Lucene or Xapian to index, search the PDF, CHM eBooks

So I home-brew the search using PLY, the Python Lex Yacc toolchain. You could check the code here, most of parser.py is just boilerplate, the interesting part is to build django.db.models.Q:

def p_expression_term(t):
    ‘expression : TERM’
    t[0] = Q(**{‘title__icontains’:t[1]})

The semantics is quite straightforward: AND(the default), OR operations are supported directly from Q; and only field title is searched. We may extend the syntax using author: like Google does later, so stay tune.