diff -r 373392025533 -r 3b1579a7bffb degal/image.py --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/degal/image.py Wed Jun 03 19:03:28 2009 +0300 @@ -0,0 +1,166 @@ +# DeGAL - A pretty simple web image gallery +# Copyright (C) 2007 Tero Marttila +# http://marttila.de/~terom/degal/ +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the +# Free Software Foundation, Inc., +# 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +# + +import os, os.path + +import PIL.Image + +import dexif + +import settings, utils, log +from template import image as image_tpl + +class Image (object) : + def __init__ (self, dir, name) : + # the image filename, e.g. DSC3948.JPG + self.name = unicode(name) + + # the Folder object that we are in + self.dir = dir + + # the relative path from the root to us + self.path = dir.pathFor(self.name) + + # the basename+ext, e.g. DSCR3948, .JPG + self.base_name, self.ext = os.path.splitext(self.name) + + # our user-friendly title + self.title = self.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 + + # EXIF data + self.exif_data = {} + + # 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 utils.mtime(out_path) < self.timestamp : + log.info("render [%sx%s]", geom[0], geom[1], wait=True) + + # 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) + + log.done() + + # 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 + + if utils.mtime(self.html_path) < self.timestamp : + log.info("render %s.html", self.name) + + # parse the exif data from the file + try : + self.exif_data = dexif.parse_exif(self.path) + except dexif.ExifError, message: + log.warning("Reading EXIF data for %s failed: %s" % (self.filename, message)) + self.exif_data = {} + + + 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, + exif_data = self.exif_data, + + 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) +