remove old Folder, Image code, wrap up both
authorTero Marttila <terom@fixme.fi>
Fri, 05 Jun 2009 23:05:11 +0300
changeset 70 67dd32adf159
parent 69 5b53fe294034
child 71 98da2964c95c
remove old Folder, Image code, wrap up both
degal/folder.py
degal/image.py
--- a/degal/folder.py	Fri Jun 05 23:03:35 2009 +0300
+++ b/degal/folder.py	Fri Jun 05 23:05:11 2009 +0300
@@ -114,6 +114,8 @@
     def index (self) :
         """
             Recursively index this Folder, yielding a series of all Folder objects inside.
+
+            XXX: not used
         """
         
         # and subfolders
@@ -123,296 +125,3 @@
             for item in subfolder.index_subfolders() :
                 yield item
    
-class Folder (object) :
-    def __init__ (self, name='.', parent=None) :
-        # the directory name, no trailing /
-        self.name = unicode(name.rstrip(os.sep))
-
-        # our parent Folder, or None
-        self.parent = parent
-
-        # the path to this dir, as a relative path to the root of the image gallery, always starts with .
-        if parent and name :
-            self.path = parent.pathFor(self.name)
-        else :
-            self.path = self.name
-
-        # the url-path to the index.html file
-        self.html_path = self.path
-        
-        # dict of fname -> Folder
-        self.subdirs = {}
-
-        # dict of fname -> Image
-        self.images = {}
-        
-        # our human-friendly title
-        self.title = None
-
-        # our long-winded description
-        self.descr = ''
-
-        # is this folder non-empty?
-        self.alive = None
-        
-        # self.images.values(), but sorted by filename
-        self.sorted_images = []
-        
-        # the ShortURL key to this dir
-        self.shorturl_code = None
-
-        # were we filtered out?
-        self.filtered = False
-   
-    def pathFor (self, *fnames) :
-        """
-            Return a root-relative path to the given path inside this dir
-        """
-        return os.path.join(self.path, *fnames)
-
-    def index (self, filters=None) :
-        """
-            Look for other dirs and images inside this dir. Filters must be either None,
-            whereupon all files will be included, or a dict of {filename -> next_filter}.
-            If given, only filenames that are present in the dict will be indexed, and in
-            the case of dirs, the next_filter will be passed on to that Folder's index
-            method.
-        """
-
-        if filters :
-            self.filtered = True
-        
-        # iterate through listdir
-        for fname in os.listdir(self.path) :
-            # the full filesystem path to it
-            fpath = self.pathFor(fname)
-            
-            # ignore dotfiles
-            if fname.startswith('.') :
-                log.debug("Skipping dotfile %s", fname)
-                continue
-            
-            # apply filters
-            if filters :
-                if fname in filters :
-                    next_filter = filters[fname]
-                else :
-                    log.debug("Skip `%s' as we have a filter", fname)
-                    continue
-            else :
-                next_filter = None
-                
-            # recurse into subdirs, but not thumbs/previews
-            if (os.path.isdir(fpath) 
-                and (fname not in (settings.THUMB_DIR, settings.PREVIEW_DIR))
-                and (self.parent or fname not in settings.ROOT_IGNORE)
-            ) :
-                log.down(fname)
-
-                f = Folder(fname, self)
-                
-                try :
-                    if f.index(next_filter) :   # recursion
-                        # if a subdir is alive, we are alive as well
-                        self.subdirs[fname] = f
-                        self.alive = True
-                except Exception, e :
-                    log.warning("skip - %s: %s" % (type(e), e))
-
-                log.up()
-
-            # handle images
-            elif os.path.isfile(fpath) and utils.isImage(fname) :
-                log.next(fname)
-                self.images[fname] = image.Image(self, fname)
-
-            # ignore everything else
-            else :
-                log.debug("Ignoring file %s", fname)
-        
-        # sort and link the images
-        if self.images :
-            self.alive = True
-
-            # sort the images
-            fnames = self.images.keys()
-            fnames.sort()
-
-            prev = None
-
-            # link
-            for fname in fnames :
-                img = self.images[fname]
-
-                img.prev = prev
-
-                if prev :
-                    prev.next = img
-
-                prev = img
-                
-                # add to the sorted images list
-                self.sorted_images.append(img)
-                
-        # figure out our title/ descr. Must be done before our parent dir is rendered (self.title)
-        title_path = self.pathFor(settings.TITLE_FILE)
-        
-        self.title, self.descr = utils.readTitleDescr(title_path)
-        
-        # default title for the root dir
-        if self.title or self.descr :
-            self.alive = True
-            pass # use what was in the title file
-            
-        elif not self.parent :
-            self.title = 'Index'
-
-        else :
-            self.title = self.name
-        
-        if not self.alive :
-            log.debug("Dir %s isn't alive" % self.path)
-
-        return self.alive
-
-    def getObjInfo (self) :
-        """
-            Metadata for shorturls2.db
-        """
-        return 'dir', self.path, ''
-
-    def breadcrumb (self, forImg=None) :
-        """
-            Returns a [(fname, title)] list of this dir's parent dirs
-        """
-
-        f = self
-        b = []
-        d = 0
-        
-        while f :
-            # functionality of the slightly-hacked-in variety
-            if f is self and forImg is not None :
-                url = helpers.url_for_page(self.getPageNumber(forImg))
-            else :
-                url = dirUp(d)
-                
-            b.insert(0, (url, f.title))
-
-            d += 1
-            f = f.parent
-        
-        return b
-        
-    def getPageNumber (self, img) :
-        """
-            Get the page number that the given image is on
-        """
-        
-        return self.sorted_images.index(img) // settings.IMAGE_COUNT
-
-    def countParents (self, acc=0) :
-        if self.parent :
-            return self.parent.countParents(acc+1)
-        else :
-            return acc
-    
-    def inRoot (self, *fnames) :
-        """
-            Return a relative URL from this dir to the given path in the root dir
-        """
-
-        c = self.countParents()
-
-        return utils.url_join(*((['..']*c) + list(fnames)))
-
-    def render (self) :
-        """
-            Render the index.html, Images, and recurse into subdirs
-        """
-        
-        # ded folders are skipped
-        if not self.alive :
-            # dead, skip, no output
-            return
-        
-        index_mtime = utils.mtime(self.pathFor("index.html"))
-        dir_mtime = utils.mtime(self.path)
-
-        # if this dir's contents were filtered out, then we can't render the index.html, as we aren't aware of all the images in here
-        if self.filtered :
-            log.warning("Dir `%s' contents were filtered, so we won't render the gallery index again", self.path)
-
-        elif index_mtime > dir_mtime :
-            # no changes, pass, ignored
-            pass
-
-        else :  
-            # create the thumb/preview dirs if needed
-            for dir in (settings.THUMB_DIR, settings.PREVIEW_DIR) :
-                path = self.pathFor(dir)
-
-                if not os.path.isdir(path) :
-                    log.info("mkdir %s", dir)
-                    os.mkdir(path)
-
-            # sort the subdirs
-            subdirs = self.subdirs.values()
-            subdirs.sort(key=lambda d: d.name)
-            
-            # paginate!
-            images = self.sorted_images
-            image_count = len(images)
-            pages = []
-            
-            while images :
-                pages.append(images[:settings.IMAGE_COUNT])
-                images = images[settings.IMAGE_COUNT:]
-
-            pagination_required = len(pages) > 1
-
-            if pagination_required :
-                log.info("%d pages @ %d images", len(pages), settings.IMAGE_COUNT)
-            elif not pages :
-                log.info("no images, render for subdirs")
-                pages = [[]]
-
-            for cur_page, images in enumerate(pages) :
-                if pagination_required and cur_page > 0 :
-                    shorturl = "%s/%s" % (self.shorturl_code, cur_page+1)
-                else :
-                    shorturl = self.shorturl_code
-                
-                # render to index.html
-                gallery_tpl.render_to(self.pathFor(url_for_page(cur_page)), 
-                    stylesheet_url               = self.inRoot('style.css'),
-                    title                        = self.title,
-                    breadcrumb                   = self.breadcrumb(),
-                    
-                    dirs                         = subdirs,
-                    images                       = images,
-                    
-                    num_pages                    = len(pages),
-                    cur_page                     = cur_page,
-                    
-                    description                  = self.descr,
-                    
-                    shorturl                     = self.inRoot('s', shorturl),
-                    shorturl_code                = shorturl,
-                )
-
-        # render images
-        image_count = len(self.sorted_images)
-        for i, img in enumerate(self.images.itervalues()) :
-            log.next("[%-4d/%4d] %s", i + 1, image_count, img.name)
-
-            img.render()
-        
-        # recurse into subdirs
-        for dir in self.subdirs.itervalues() :
-            log.down(dir.name)
-
-            dir.render()
-
-            log.up()
-
--- a/degal/image.py	Fri Jun 05 23:03:35 2009 +0300
+++ b/degal/image.py	Fri Jun 05 23:05:11 2009 +0300
@@ -104,163 +104,32 @@
 
         return self.metadata
     
-    def render_image (self) :
+    @lazy_load
+    def thumb (self) :
         """
-            Renders new thumbnails/previews for this image.
-            
-            Note: this does not check for the existance of the thumbs/previews subdirs!
+            Load and update the thumbnail if needed
         """
 
-        # 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
+        # render if needed
+        return render_machine.render_lazy(self
             self.config.thumb_size, self.parent.load_thumb_dir.subnode(self.name)
         )
+    
+    @lazy_load
+    def preview (self) :
+        """
+            Load and update the preview if needed
+        """
 
-        self.preview = render_machine.render_lazy(self, 
+        # renderer to use
+        # XXX: get from elsewhere
+        render_machine = self.config.get_renderer()
+
+        return 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) :
-        # 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)
-