--- a/degal/image.py Fri Jun 05 19:29:04 2009 +0300
+++ b/degal/image.py Fri Jun 05 19:30:15 2009 +0300
@@ -1,15 +1,131 @@
-import os, os.path
+"""
+ Per-image gallery state
+"""
+
+from __future__ import with_statement
+
+import filesystem, render, html
import PIL.Image
-
-import dexif
+from lib import EXIF
-import settings, utils, log
-from template import image as image_tpl
+class Image (filesystem.File) :
+ """
+ An Image is a filesystem File that represents an image that can be thumbnailed, and handled.
+ """
-"""
- Handling induvidual Images
-"""
+ def __init__ (self, node, prev) :
+ """
+ Initialize as an Image based on the given Node, linked with the given previous node
+ """
+
+ super(Image, self).__init__(node)
+
+ # links
+ self.prev = prev
+ self.next = None
+
+ # the .html file for this image
+ self.html = self.parent.subfile(self.basename + '.html')
+
+ # info
+ self.title = self.name
+ self.description = None
+
+ # lazy-loading
+ self.img = None
+ self.exif = None
+ self.metadata = None
+ self.stat_data = None
+
+ def load_stat (self) :
+ """
+ Load and return the os.stat info for this file
+ """
+
+ if not self.stat_data :
+ self.stat_data = self.stat()
+
+ return self.stat_data
+
+ def load_image (self) :
+ """
+ Loads the image as a PIL.Image
+ """
+
+ if not self.img :
+ # open it up
+ self.img = PIL.Image.open(self.path)
+
+ return self.img
+
+ def load_exif (self) :
+ """
+ Loads the EXIF data for the image and returns as a dict of EXIF tag names -> values.
+
+ Returns None if no exif data was found
+ """
+
+ if self.exif is None :
+ # load
+ with self.open('rb') as fh :
+ # XXX: details=False?
+ self.exif = EXIF.process_file(fh)
+
+ # empty dict -> no exif data
+ if self.exif :
+ return self.exif
+
+ else :
+ return None
+
+ def load_metadata (self) :
+ """
+ Load and return the metadata for the image as a dictionary
+ """
+
+ if not self.metadata :
+ # load stuff
+ stat = self.load_stat()
+ exif = self.load_exif()
+
+ # XXX: avoid having to open the image?
+ size = self.load_image().size
+
+ # build
+ self.metadata = dict({
+ "File name": self.name,
+ "Resolution": "%dx%d" % size,
+ "File size": format.filesize(stat.st_size),
+ "Last modified": format.filetime(stat.st_mtime),
+ }, **dict(
+ (name, exif[tag]) for tag, name in self.config.exif_tags if exif and tag in exif
+ ))
+
+ return self.metadata
+
+ def render_image (self) :
+ """
+ Renders new thumbnails/previews for this image.
+
+ Note: this does not check for the existance of the thumbs/previews subdirs!
+ """
+
+ # load origional image
+ img = self.load_image()
+
+ # renderer to use
+ # XXX: get from elsewhere
+ render_machine = self.config.get_renderer()
+
+ # lazy-render both thumb and preview
+ self.thumb = render_machine.render_lazy(self
+ self.config.thumb_size, self.parent.load_thumb_dir.subnode(self.name)
+ )
+
+ self.preview = render_machine.render_lazy(self,
+ self.config.preview_size, self.parent.load_preview_dir.subnode(self.name)
+ )
class Image (object) :
def __init__ (self, dir, name) :
@@ -54,8 +170,8 @@
# the ShortURL code for this image
self.shorturl_code = None
- # EXIF data
- self.exif_data = {}
+ # EXIF data
+ self.exif_data = {}
# what to use in the rendered templates, intended to be overridden by subclasses
self.series_act = "add"
@@ -122,27 +238,27 @@
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,
+ stylesheet_url = self.dir.inRoot('style.css'),
+ title = self.title,
+ breadcrumb = self.breadcrumb(),
- filename = self.name,
- img_size = self.img_size,
- file_size = self.filesize,
- timestamp = self.timestamp,
- exif_data = self.exif_data,
+ prev = self.prev,
+ next = self.next,
+ img = self,
- shorturl = self.dir.inRoot('s', self.shorturl_code),
- shorturl_code = self.shorturl_code,
+ description = self.descr,
- series_url = self.dir.inRoot('series/%s/%s' % (self.series_act, self.shorturl_code)),
- series_verb = self.series_verb,
+ 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) :