lib/image.py
author terom
Fri, 21 Dec 2007 20:45:03 +0000
changeset 13 c229bcb1de41
parent 12 c2d8e9a754a1
child 14 4b5478da5850
permissions -rw-r--r--
image breadcrumb links back to page that said image is on
import os, os.path

import PIL.Image

import settings, utils
from log import index, render
from template import image as image_tpl
    
class Image (object) :
    def __init__ (self, dir, name) :
        # the image filename, e.g. DSC3948.JPG
        self.name = name

        # the Folder object that we are in
        self.dir = dir
        
        # the relative path from the root to us
        self.path = dir.pathFor(name)

        # the basename+ext, e.g. DSCR3948, .JPG
        self.base_name, self.ext = os.path.splitext(name)
        
        # our user-friendly title
        self.title = name

        # our long-winded description
        self.descr = ''

        # the image before and after us, both may be None
        self.prev = self.next = None
        
        # the image-relative names for the html page, thumb and preview images
        self.html_name = self.name + ".html"
        self.thumb_name = utils.url_join(settings.THUMB_DIR, self.name)
        self.preview_name = utils.url_join(settings.PREVIEW_DIR, self.name)

        # the root-relative paths to the html page, thumb and preview images
        self.html_path = self.dir.pathFor(self.html_name)
        self.thumb_path = self.dir.pathFor(settings.THUMB_DIR, self.name)
        self.preview_path = self.dir.pathFor(settings.PREVIEW_DIR, self.name)        
        
        #
        # Figured out after prepare
        #

        # (w, h) tuple
        self.img_size = None
        
        # the ShortURL code for this image
        self.shorturl_code = None

        # what to use in the rendered templates, intended to be overridden by subclasses
        self.series_act = "add"
        self.series_verb = "Add to"
    
    def getObjInfo (self) :
        """
            Metadata for shorturl2.db
        """
        return 'img', self.dir.path, self.name

    def breadcrumb (self) :
        """
            Returns a [(fname, title)] list of this image's parents
       """
        
        return self.dir.breadcrumb(forImg=self) + [(self.html_name, self.title)]

    def render (self) :
        """
            Write out the .html file
        """
        
        # stat the image file to get the filesize and mtime
        st = os.stat(self.path)

        self.filesize = st.st_size
        self.timestamp = st.st_mtime
        
        # open the image in PIL to get image attributes + generate thumbnails
        img = PIL.Image.open(self.path)

        self.img_size = img.size

        for out_path, geom in ((self.thumb_path, settings.THUMB_GEOM), (self.preview_path, settings.PREVIEW_GEOM)) :
            # if it doesn't exist, or it's older than the image itself, generate
            if not (os.path.exists(out_path) and os.stat(out_path).st_mtime > self.timestamp) :
                render.info("Create thumbnailed image at %s with geom %s", out_path, geom)
                
                # XXX: is this the most efficient way to do this? It seems slow
                out_img = img.copy()
                out_img.thumbnail(geom, resample=True)
                out_img.save(out_path)
        
        # look for the metadata file
        title_path = self.dir.pathFor(self.base_name + '.txt')
        
        self.title, self.descr = utils.readTitleDescr(title_path)
        
        if not self.title :
            self.title = self.name

        render.info("Rendering image %s", self.path)

        image_tpl.render_to(self.html_path,
            stylesheet_url             = self.dir.inRoot('style.css'),
            title                      = self.title,
            breadcrumb                 = self.breadcrumb(),
            
            prev                       = self.prev,
            next                       = self.next,
            img                        = self,
            
            description                = self.descr,
            
            filename                   = self.name,
            img_size                   = self.img_size,
            file_size                  = self.filesize,
            timestamp                  = self.timestamp,
            
            shorturl                   = self.dir.inRoot('s', self.shorturl_code),
            shorturl_code              = self.shorturl_code,
            
            series_url                 = self.dir.inRoot('series/%s/%s' % (self.series_act, self.shorturl_code)),
            series_verb                = self.series_verb,
        )   
    
    def __str__ (self) :
        return "Image `%s' in `%s'" % (self.name, self.dir.path)