--- a/degal/config.py Sun Jun 14 20:05:11 2009 +0300
+++ b/degal/config.py Sun Jun 14 22:52:07 2009 +0300
@@ -2,53 +2,117 @@
Configuration
"""
-import logging
+import copy, logging
-class Configuration (object) :
+class InstanceContext (object) :
+ """
+ An object that behaves like a dict, performing all item lookups as attribute lookups on the given object.
+
+ Useful for binding an exec statement's locals.
+ """
+
+ def __init__ (self, obj) : self.obj = obj
+ def __getitem__ (self, key) : return getattr(self.obj, key)
+ def __setitem__ (self, key, value) : setattr(self.obj, key, value)
+
+class ConfigurationMachinery (object) :
+ """
+ The low-level configuration machinery.
+ """
+
+ def import_py (self, path) :
+ """
+ Import python-style configuration from the given File object into this one.
+
+ This runs the file's code using exec, using a context mapped to this object.
+ """
+
+ # the code
+ file = open(path)
+
+ # build suitable locals/globals to proxy this object
+ locals = InstanceContext(self)
+
+ # run
+ exec file in {}, locals
+
+ def import_file (self, path) :
+ """
+ Import configuration from the given File into this one.
+ """
+
+ # as python code
+ self.import_py(path)
+
+ def load (self, path) :
+ """
+ Loads the configuration from the given File, creating a new Configuration with defaults from this one.
+ """
+
+ # copy ourself
+ new = copy.copy(self)
+
+ # import into it
+ new.import_file(path)
+
+ # return
+ return new
+
+class Configuration (ConfigurationMachinery) :
"""
Various configuration settings
"""
- ## runtime settings
- # the path to the gallery
+ # the path to the gallery root
+ # only valid in top-level config
gallery_path = "."
# force-update items
force_thumb = False
force_html = False
+ def get_force_update (self) :
+ return self.force_thumb or self.force_html
+
+ def set_force_update (self, value) :
+ self.force_thumb = self.force_html = value
+
+ force_update = property(get_force_update, set_force_update)
+
# minimum logging level
log_level = logging.INFO
+ def quiet (self) : self.log_level = logging.WARN
+ def debug (self) : self.log_level = logging.DEBUG
+
# number of threads to use for concurrency
thread_count = 2
- ## detailed configuration
- # the name of the gallery
- gallery_title = "Image Gallery"
+ # the name of this folder, only applies on one level
+ # default applies to the root gallery
+ title = "Image Gallery"
- # recognized image extensions
+ # recognized image extensions, case-insensitive
image_exts = ('jpg', 'jpeg', 'png', 'gif', 'bmp')
- # subdirectory used for generated thumbnails/previews
+ # subdirectory names used for generated thumbnails/previews
thumb_dir = 'thumbs'
preview_dir = 'previews'
- # size of generated thumbnails/previews
+ # size of generated thumbnails/previews as (width, height) tuples
thumb_size = (160, 120)
preview_size = (640, 480)
# number of images displayed per folder page
images_per_page = 50
- # load Exif data for images
- # this may be slow
- exif_enabled = False
+ # load Exif data for images, this may be slow
+ with_exif = False
# exif tags used in output
# Copyright (C) 2008, Santtu Pajukanta <santtu@pajukanta.fi>
# XXX: import from dexif?
- exif_tags = [
+ exif_tags = (
# TODO Create date is in a useless format, needs some strptime love
("CreateDate", "Create date" ),
("Model", "Camera model" ),
@@ -60,15 +124,15 @@
("ISO", "ISO" ),
("ShootingMode", "Shooting mode" ),
("LensType", "Lens type" ),
- ("FocalLength", "Focal length" )
- ]
-
+ ("FocalLength", "Focal length" ),
+ )
- ### functions
+ # XXX: move elsewhere?
def is_image (self, file) :
"""
Tests if the given File is an image, based on its file extension
+
"""
return file.matchext(self.image_exts)
-
+