PROGRAMMING

Django, reStructuredText and image thumbnails

#python , #django

I use reStructuredText at my blog. I have decided to write my own simple directive for generating image thumbnails and returning html tags. I’m using sorl.thumbnail for this.

import os
from docutils import nodes
from docutils.parsers.rst import directives, Directive
from sorl.thumbnail import get_thumbnail
from project.settings import MEDIA_ROOT, MEDIA_URL

class Thumb(Directive):

    def align(argument):
        """Conversion function for the "align" option."""
        return directives.choice(argument, ('left', 'center', 'right'))

    required_arguments = 1
    optional_arguments = 0
    final_argument_whitespace = True
    option_spec = {
        'alt': directives.unchanged,
        'height': directives.length_or_unitless,
        'width': directives.length_or_percentage_or_unitless,
        'align': align
    }

    def run(self):
        alt = self.options.get('alt')
        img = self.arguments[0].strip()
        # Default parameters
        width = 500
        height = ''
        align = 'center'

        if 'width' in self.options:
            width = self.options['width']

        if 'height' in self.options:
            height = self.options['height']

        if 'align' in self.options:
            align = self.options['align']

        # Get image path.
        if any(x in img for x in ['http', 'www']):
            # Received path like /media/test/1.jpg
            img_path = os.path.join(MEDIA_ROOT, img.replace(MEDIA_URL, ''))
        else:
            # Received url like http://www.eshlox.net/media/test/1.jpg
            project_root = os.path.abspath(os.path.dirname(__file__))
            img_path = os.path.realpath(project_root + img)

        if width and height:
            size = '{0}x{1}'.format(width, height)
        elif not width and height:
            size = 'x{0}'.format(height)
        else:
            size = str(width)

        img_thumb = get_thumbnail(img_path, size, upscale=False, quality=99)

        html = u'<a href="{0}" title="{1}" class="align-{2}">' \
            u'<img src="{3}" alt="{4}" /></a>'.format(
            img, alt, align, img_thumb.url, alt
        )

        return [nodes.raw('', html, format='html')]

directives.register_directive('thumb', Thumb)

Now I can use this in RST code.

.. thumb:: /media/test/1.jpg
    :alt: Test

.. thumb:: http://eshlox.net/media/test/1.jpg
    :alt: Test

.. thumb:: /media/test/1.jpg
    :alt: Test
    :width: 300
    :height: 300

.. thumb:: /media/test/1.jpg
    :alt: Test
    :height: 200