#!/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__":