fancy new log format
authorterom
Thu, 31 Jan 2008 19:13:00 +0000
changeset 28 70b6c13d084f
parent 27 301d738b1181
child 29 990300aa8010
fancy new log format
degal.py
lib/folder.py
lib/image.py
lib/log.py
lib/shorturl.py
lib/template.py
lib/utils.py
--- a/degal.py	Thu Jan 31 17:58:03 2008 +0000
+++ b/degal.py	Thu Jan 31 19:13:00 2008 +0000
@@ -23,7 +23,7 @@
 import os.path, os
 from optparse import OptionParser
 
-from lib import folder, shorturl
+from lib import folder, shorturl, log
 
 def main (dir='.', targets=()) :
     root_filter = {}
@@ -36,11 +36,19 @@
                     f[path_part] = {}
                     
                 f = f[path_part]
-
+    
+    log.title("Indexing %s...", dir)
     root = folder.Folder(dir)
     root.index(root_filter)
+    log.up()
+
+    log.title("Syncing ShortURLs...")
     shorturl.updateDB(root)
+    log.up()
+
+    log.title("Rendering updated dirs...")
     root.render()
+    log.up()
 
 if __name__ == '__main__' :
     parser = OptionParser(usage="usage: %prog [options] ... [target ...]")
--- a/lib/folder.py	Thu Jan 31 17:58:03 2008 +0000
+++ b/lib/folder.py	Thu Jan 31 19:13:00 2008 +0000
@@ -20,8 +20,7 @@
 
 import os, os.path
 
-import settings, image, utils, helpers
-from log import index, render
+import settings, image, utils, helpers, log
 from template import gallery as gallery_tpl
 from helpers import url_for_page
 
@@ -91,8 +90,6 @@
             method.
         """
 
-        index.info("Indexing %s", self.path)
-
         if filters :
             self.filtered = True
         
@@ -103,7 +100,7 @@
             
             # ignore dotfiles
             if fname.startswith('.') :
-                index.debug("Skipping dotfile %s", fname)
+                log.debug("Skipping dotfile %s", fname)
                 continue
             
             # apply filters
@@ -111,7 +108,7 @@
                 if fname in filters :
                     next_filter = filters[fname]
                 else :
-                    index.debug("Skip `%s' as we have a filter", fname)
+                    log.debug("Skip `%s' as we have a filter", fname)
                     continue
             else :
                 next_filter = None
@@ -121,21 +118,25 @@
                 and (fname not in (settings.THUMB_DIR, settings.PREVIEW_DIR))
                 and (self.parent or fname not in settings.ROOT_IGNORE)
             ) :
-                index.debug("Found subdir %s", fpath)
+                log.down(fname)
+
                 f = Folder(fname, self)
+
                 if f.index(next_filter) :   # recursion
                     # if a subdir is alive, we are alive as well
                     self.subdirs[fname] = f
                     self.alive = True
 
+                log.up()
+
             # handle images
             elif os.path.isfile(fpath) and utils.isImage(fname) :
-                index.debug("Found image %s", fname)
+                log.next(fname)
                 self.images[fname] = image.Image(self, fname)
 
             # ignore everything else
             else :
-                index.debug("Ignoring file %s", fname)
+                log.debug("Ignoring file %s", fname)
         
         # sort and link the images
         if self.images :
@@ -178,7 +179,7 @@
             self.title = self.name
         
         if not self.alive :
-            index.debug("Dir %s isn't alive" % self.path)
+            log.debug("Dir %s isn't alive" % self.path)
 
         return self.alive
 
@@ -240,12 +241,19 @@
         
         # ded folders are skipped
         if not self.alive :
-            render.info("Skipping dir %s (no images)", self.path)
+            # 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 :
-            render.warning("Dir `%s' contents were filtered, so we won't render the gallery index again", self.path)
+            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
@@ -253,15 +261,13 @@
                 path = self.pathFor(dir)
 
                 if not os.path.isdir(path) :
-                    render.info("Creating dir %s", path)
+                    log.info("mkdir %s", dir)
                     os.mkdir(path)
 
             # sort the subdirs
             subdirs = self.subdirs.values()
             subdirs.sort(key=lambda d: d.name)
             
-            render.info("Rendering %s", self.path)
-
             # paginate!
             images = self.sorted_images
             image_count = len(images)
@@ -274,9 +280,9 @@
             pagination_required = len(pages) > 1
 
             if pagination_required :
-                render.info("Index split into %d pages of %d images each", len(pages), settings.IMAGE_COUNT)
+                log.info("%d pages @ %d images", len(pages), settings.IMAGE_COUNT)
             elif not pages :
-                render.info("Dir with no images, render for subdirs")
+                log.info("no images, render for subdirs")
                 pages = [[]]
 
             for cur_page, images in enumerate(pages) :
@@ -302,12 +308,19 @@
                     shorturl                     = self.inRoot('s', shorturl),
                     shorturl_code                = shorturl,
                 )
-        
+
         # render images
-        for img in self.images.itervalues() :
+        image_count = len(self.sorted_images)
+        for i, img in enumerate(self.images.itervalues()) :
+            log.next("[%-4d/%4d] %s", i, image_count, img.name)
+
             img.render()
         
         # recurse into subdirs
         for dir in self.subdirs.itervalues() :
+            log.down(dir.name)
+
             dir.render()
-                
+
+            log.up()
+
--- a/lib/image.py	Thu Jan 31 17:58:03 2008 +0000
+++ b/lib/image.py	Thu Jan 31 19:13:00 2008 +0000
@@ -22,8 +22,7 @@
 
 import PIL.Image
 
-import settings, utils
-from log import index, render
+import settings, utils, log
 from template import image as image_tpl
     
 class Image (object) :
@@ -104,13 +103,15 @@
 
         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 not (os.path.exists(out_path) and os.stat(out_path).st_mtime > self.timestamp) :
-                render.info("Create thumbnailed image at %s with geom %s", out_path, geom)
+            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')
@@ -119,31 +120,33 @@
         
         if not self.title :
             self.title = self.name
-
-        render.info("Rendering image %s", self.path)
+        
+        if utils.mtime(self.html_path) < self.timestamp :
+            log.info("render %s.html", self.name)
 
-        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,
-            
-            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,
-        )   
+            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,
+                
+                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)
+
--- a/lib/log.py	Thu Jan 31 17:58:03 2008 +0000
+++ b/lib/log.py	Thu Jan 31 19:13:00 2008 +0000
@@ -18,19 +18,64 @@
 # 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
 #
 
-import logging
-
-logging.basicConfig(
-    level=logging.INFO,
-    format="%(message)s",
-#    format="%(name)8s %(levelname)8s   %(lineno)3d %(message)s",
+import logging, sys
 
-)
+log_level = logging.INFO
+stack = []
 
-index = logging.getLogger('index')
-render = logging.getLogger('render')
-template = logging.getLogger('template')
+class g :
+    out_depth = 0
+    node = None
 
-misc = logging.getLogger('misc')
+def title (title, *args) :
+    stack.append(title)
 
-template.setLevel(logging.ERROR)
+    print "%s- %s" % (" "*g.out_depth, title % args)
+
+    g.out_depth += 1
+
+def down (dir_name, *args) :
+    stack.append(dir_name % args)
+    g.node = None
+
+def next (fname, *args) :
+    g.node = fname % args
+
+def up () :
+    stack.pop(-1)
+    g.node = None
+    g.out_depth = min(g.out_depth, len(stack))
+
+def done () :
+    print "done"
+
+def log (level, message, *args, **kwargs) :
+    wait = kwargs.get("wait", False)
+
+    if level >= log_level :
+        if g.out_depth != len(stack) :
+            for segment in stack[g.out_depth:] :
+                print "%sd %s" % (" "*g.out_depth, segment)
+                g.out_depth += 1
+
+            if g.node :
+                print "%sf %s" % (" "*g.out_depth, g.node)
+                g.node = None
+        
+        if wait :
+            print "%s- %s..." % (" "*g.out_depth, message % args),
+            sys.stdout.flush()
+        else :
+            print "%s- %s" % (" "*g.out_depth, message % args)
+
+def _level (level) :
+    def _log_func (message, *args, **kwargs) :
+        log(level, message, *args, **kwargs)
+    
+    return _log_func
+
+debug       = _level(logging.DEBUG)
+info        = _level(logging.INFO)
+warning     = _level(logging.WARNING)
+error       = _level(logging.ERROR)
+
--- a/lib/shorturl.py	Thu Jan 31 17:58:03 2008 +0000
+++ b/lib/shorturl.py	Thu Jan 31 19:13:00 2008 +0000
@@ -23,9 +23,8 @@
 import shelve
 import os.path
 
-from log import index
 
-import utils, db, helpers, folder, image
+import utils, db, helpers, folder, image, log
 
 def int2key (id) :
     """
@@ -146,7 +145,7 @@
     else :
         assert(False, "%r %r" % (obj, id))
 
-    index.info("img %50s %15s = %d %s", dir, fname, id, key)
+    log.info("img %50s %15s = %d %s", dir, fname, id, key)
 
 def updateDB (root) :
     """
@@ -162,8 +161,6 @@
     # dict of (dir, fname) -> obj
     paths = {}
 
-    index.info("Processing ShortURLs...")
-
     while dirqueue :
         dir = dirqueue.pop(0)
 
@@ -172,18 +169,18 @@
         if dir.alive :
             pathtuple = (utils.strip_path(dir.path), '')
             
-            index.debug("dir %50s", pathtuple[0])
+            log.debug("dir %50s", pathtuple[0])
 
             paths[pathtuple] = dir
 
         for img in dir.images.itervalues() :
             pathtuple = (utils.strip_path(img.dir.path), img.name)
             
-            index.debug("img %50s %15s", *pathtuple)
+            log.debug("img %50s %15s", *pathtuple)
 
             paths[pathtuple] = img
     
-    print "%d nodes:" % (len(paths))
+    log.info("we have %d nodes", len(paths))
 
     for (id, dir, fname) in db.select("SELECT id, dirpath, filename FROM nodes") :
         try :
@@ -192,17 +189,20 @@
 
             obj.shorturl_code = key
 
-            index.debug("%s %50s %15s -> %d %s", dir and "img" or "dir", dir, fname, id, key)
+            log.debug("%s %50s %15s -> %d %s", dir and "img" or "dir", dir, fname, id, key)
         
         except KeyError :
             pass
-#            index.warning("non-existant node (%d, %s, %s) in db", id, dir, fname)
+#            log.warning("non-existant node (%d, %s, %s) in db", id, dir, fname)
     
-    print "%d NEW nodes:" % (len(paths))
+    if paths :
+        log.info("allocating shorturls for %d new nodes:", len(paths))
 
-    db.insert_many(
-        _got_obj_key,
-        "INSERT INTO nodes (dirpath, filename) VALUES (?, ?)",
-        ((obj, (path, fname)) for ((path, fname), obj) in paths.iteritems())
-    )
+        db.insert_many(
+            _got_obj_key,
+            "INSERT INTO nodes (dirpath, filename) VALUES (?, ?)",
+            ((obj, (path, fname)) for ((path, fname), obj) in paths.iteritems())
+        )
+    else :
+        log.info("no new images")
 
--- a/lib/template.py	Thu Jan 31 17:58:03 2008 +0000
+++ b/lib/template.py	Thu Jan 31 19:13:00 2008 +0000
@@ -46,11 +46,11 @@
         data.update(TEMPLATE_GLOBALS)
         
         try :
-            log.template.debug("render %s with %s", self.name, data)
+            log.debug("render %s with %s", self.name, data)
             return self.tpl.render(**data)
         except :
             data = exceptions.text_error_template().render()
-            log.template.error(data)
+            log.error(data)
             
             raise
     
--- a/lib/utils.py	Thu Jan 31 17:58:03 2008 +0000
+++ b/lib/utils.py	Thu Jan 31 19:13:00 2008 +0000
@@ -18,7 +18,7 @@
 # 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
 #
 
-import os.path
+import os, os.path
 
 import settings
 
@@ -80,3 +80,10 @@
 def strip_path (path) :
     return path.lstrip('.').lstrip('/')
 
+def mtime (path) :
+    try :
+        return os.stat(path).st_mtime
+    except OSError :
+        # no such file or directory
+        return None
+