Platinum Partner

Latest And Greatest Directory Thumbnailer

This does basically the same thing as my original code (http://www.bigbold.com/snippets/posts/show/1296), but significantly faster. Thumbnail sizes are cached between executions, and they could probably be kept around as static data in the mod_python environment if I could figure out how.

Also note that the thumbnailing function no longer returns a complete page, but rather a single table (compatible with either HTML or XHTML). This allows the code to be embedded into something like a photo gallery.

A simple function is shown at the end of this snippet, to set up thumbnailing with mod_python on apache. 


from os.path import join,exists
from os import stat,mkdir,listdir
import re
from PIL import Image
import cPickle

images_per_row = 5
max_width,max_height = 150,150

search = re.compile("(.*\.jpe?g$)|(.*\.png$)|(.*\.gif$)", re.IGNORECASE)

def list_directory(path):
  thumbnail_size_cache = {}
  thumbnail_size_cache_changed = False

  return_value = []
  dir_list = listdir(path)
  images = [file for file in dir_list if search.match(file)]

  if len(images) < 1:
    return ''

  # Interesting directories
  thumbsdir = join(path, ".thumbnails")

  # Try to load the size cache from a file
  cache_file_path = join(thumbsdir, "thumbnail_size_cache.dat")
  if exists (cache_file_path):
    cache_file = open(cache_file_path, "r")
    thumbnail_size_cache = cPickle.load(cache_file)
    cache_file.close()

  images.sort()
  return_value.append('\n')
  row_template = '\n')

    else:
      return_value.append('\n')

  return_value.append("
%(name)s' # If the thumbnail directory does not exist, create it if not exists(thumbsdir): mkdir(thumbsdir) image_num = 0 for image in images: image_num += 1 thumbfile = join(thumbsdir, image) filepath = join(path, image) width,height = 0,0 # Check if there is an already-existing thumbnail create_new_thumbnail = True if exists(thumbfile): thumb_stat = stat(thumbfile) img_stat = stat(filepath) # Check if the thumbnail is newer than the image if img_stat.st_mtime < thumb_stat.st_mtime: try: width,height = thumbnail_size_cache[image] create_new_thumbnail = False except KeyError: pass if create_new_thumbnail: # Thumbnail the image thumbnail = Image.open(filepath) thumbnail.thumbnail((max_width, max_height), Image.ANTIALIAS) thumbnail.save(thumbfile) thumbnail_size_cache[image] = thumbnail.size thumbnail_size_cache_changed = True width,height = thumbnail.size return_value.append(row_template % {'name': image, 'width': width, 'height': height}) if image_num % images_per_row: return_value.append('
") # Save the cache if thumbnail_size_cache_changed: return_value.append("Saved cache") cache_file = open(cache_file_path, "w") cPickle.dump(thumbnail_size_cache, cache_file, cPickle.HIGHEST_PROTOCOL) cache_file.close() return ''.join(return_value) #################################### ### mod_python stuff starts here ### #################################### from mod_python import apache html_header = ''' Directory Listing
''' xhtml_header = ''' Directory Listing
''' def handler(req): if not os.path.isdir(req.filename): file = open(req.filename) req.write(file.read()) return apache.OK return_value = [] # Check for XHTML acceptance accept_types = req.headers_in["Accept"].split(",") # Don't do any measure of preference for now if "application/xhtml+xml" in accept_types: # Accepts XHTML return_value.append(xhtml_header) req.content_type="application/xhtml+xml" else: # Does not accept XHTML return_value.append(html_header) req.content_type="text/html" return_value.append(list_directory(req.filename)) return_value.append("
") req.write(''.join(return_value)) return apache.OK
{{ tag }}, {{tag}},

{{ parent.title || parent.header.title}}

{{ parent.tldr }}

{{ parent.urlSource.name }}
{{ parent.authors[0].realName || parent.author}}

{{ parent.authors[0].tagline || parent.tagline }}

{{ parent.views }} ViewsClicks
Tweet

{{parent.nComments}}