#!/usr/bin/python
#
# generate an album from a set of rules
#
import kimdaba_album
import os
import kid
kid.enable_import()
import one_image
import flat_image_list
class abstract_size:
"""Derive hard-coded sizes from this"""
@classmethod
def name(cls):
return cls.__name__.replace("size","",1)
# or just construct these from real sizes?
# maybe scale_arg should be here too
class origsize(abstract_size):
w,h = None, None
class thumbsize(abstract_size):
w,h = 64,64
# image builder
class image_maker:
def __init__(self, inbase, base, sizes, force=False):
self.inbase = inbase
self.base = base
self.sizes = sizes
self.force = force
def sizetag(self, size):
if hasattr(size, "name"):
return size.name()
else:
return "%sx%s" % size
def destname(self, img, size):
name, ext = img.rsplit(".",1)
extra = self.sizetag(size)
return os.path.join(self.base, name + "_" + extra + "." + ext)
def pathmap(self, source_image):
imgname = os.path.basename(source_image)
return dict([(size, self.destname(imgname, size)) for size in self.sizes])
def scale_arg(self, size):
if isinstance(size, tuple):
w,h = size
elif size.w and size.h:
w,h = size.w, size.h
else:
return ""
return "-scale %sx%s" % (w,h)
def generate(self, img, prev=None, next=None):
source_image = os.path.join(self.inbase, img.get("file"))
imgname = os.path.basename(source_image)
rotation = ""
if img.get("angle") != "0":
# be clever and use jpegtran if we can
rotation = "-rotate %s" % img.get("angle")
print "rotating", imgname, "by", rotation
allsizes = [os.path.basename(self.destname(imgname, s) )
for s in self.sizes]
for size in self.sizes + [thumbsize]:
dst = self.destname(imgname, size)
dst_prev = None
if prev:
dst_prev = os.path.basename(self.destname(prev.get("file"), size))
dst_next = None
if next:
dst_next = os.path.basename(self.destname(next.get("file"), size))
# convert the image (the way bins did it?)
if self.force and os.path.exists(dst):
os.remove(dst)
# still need rotate arg!
if not os.path.exists(dst):
st = os.system("set -x; convert %s %s %s %s" %
(rotation, self.scale_arg(size), source_image, dst))
if st:
raise Exception("convert blew out")
if size == thumbsize:
# give up after the image, for thumbs
continue
template = one_image.Template(img=img,
imglink=os.path.basename(dst),
prev=dst_prev, next=dst_next,
allsizes=allsizes)
outlink = dst + ".html"
template.write(outlink)
def make_flat_index(self, outpath, images, title):
outindex = os.path.join(outpath, "index.html")
allsizes = [(os.path.basename(img.get("file")),
os.path.basename(self.destname(img.get("file"), thumbsize)),
[(self.sizetag(s),
os.path.basename(self.destname(img.get("file"), s)))
for s in self.sizes])
for img in images]
template = flat_image_list.Template(all=allsizes, title=title)
template.write(outindex)
def prev_curr_next(i):
i = iter(i)
prev = None
curr = i.next()
for next in i:
yield prev, curr, next
prev = curr
curr = next
yield prev, curr, None
class album:
def __init__(self):
self.filename = kimdaba_album.kimdaba_default_album()
self.elements = kimdaba_album.parse(self.filename)
self.keys_in = set()
self.keys_out = set()
self._title = ""
self._description = ""
self._sizes = []
def include_keywords(self, *kw):
# check against keywords actually existing?
self.keys_in.update(kw)
def exclude_keywords(self, *kw):
# check against keywords actually existing?
self.keys_out.update(kw)
def title(self, txt):
self._title = txt
def description(self, txt):
self._description = txt
def sizes(self, *sz):
# check for validity?
self._sizes.extend(sz)
def generate(self, outpath, noisy=True):
images = kimdaba_album.select_images(self.elements, self.keys_in, self.keys_out)
inbase = self.elements.findall("config")[0].get("imageDirectory")
maker = image_maker(inbase, outpath, self._sizes)
# don't see an itertools way to do it...
for img_p, img, img_n in prev_curr_next(images):
if noisy: print "img", img.get("file")
maker.generate(img, prev=img_p, next=img_n)
# use maker.pathmap to get the things to href
maker.make_flat_index(outpath, images, self._title)
# for all images
# generate the sizes
# generate the single-image page for each size
# -- later, don't regnerate what's already there
# -- also, generate "up" links to the indices:
# generate time-oriented index page
# generate number-oriented index page
# just to get started, one single flat image page...
# if __name__ == "__main__":