degal/image.py
branchuse-distutils
changeset 41 3b1579a7bffb
parent 33 4943047bfcb5
child 44 533b7e8b5d3b
--- /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)
+