terom@144: from degal.command import command, Option terom@117: from degal.concurrent import task terom@66: from degal import templates terom@48: terom@94: def render_image_html (ctx, image) : terom@66: """ terom@132: Render and write out the static .html file for the give image. terom@66: """ terom@87: terom@101: ctx.log_debug("%s", image.html) terom@101: terom@132: # render full-xhtml-document terom@119: tpl = templates.master(ctx.gallery, image, terom@132: # with content terom@66: templates.image_page(image) terom@66: ) terom@66: terom@66: # write output terom@66: tpl.render_file(image.html) terom@66: terom@117: def update_image_thumbs (image) : terom@94: """ terom@132: Update/render and write out the thumbnails (thumb+preview) for the given image, returning the image object terom@132: itself. terom@117: terom@132: This /should/ be threadsafe. XXX: but it probably isn't entirely. terom@94: """ terom@117: terom@117: # this will unconditionally update the image terom@117: image.update() terom@94: terom@117: return image terom@94: terom@132: def render_folder_images (ctx, images) : terom@94: """ terom@132: Render the given series of images (html+thumbnails) as required based on the settings. terom@132: terom@132: This is capable of rendering the given set of images in parallel. terom@94: """ terom@118: terom@132: # first, update HTML terom@123: for image in images : terom@144: if ctx.options.force_html or image.stale() : terom@132: render_image_html(ctx, image) terom@94: terom@132: # define the render-tasks terom@144: tasks = (task(update_image_thumbs, image) for image in images if ctx.options.force_thumb or image.stale()) terom@132: terom@132: # render the thumbnails themselves concurrently, returning the rendered Image objects terom@132: for image in ctx.concurrent.execute(tasks) : terom@94: # log image path terom@94: ctx.log_info("%s", image) terom@94: terom@101: # release large objects that are not needed anymore terom@123: image.cleanup() terom@101: terom@117: def render_folder_html (ctx, folder) : terom@48: """ terom@132: Render and write out the required static .html files for the given folder. terom@132: terom@132: This will paginate large numbers of images, handle Folders with only subfolders within as a single page, and as terom@132: a bonus, will not render anything for (non-recursively) empty folders. terom@48: """ terom@48: terom@87: # render each page separately terom@66: for page in xrange(folder.page_count) : terom@132: # output .html path terom@119: html = folder.html_page(page) terom@101: terom@119: ctx.log_debug("%s", html) terom@66: terom@132: # render full-html template terom@119: tpl = templates.master(ctx.gallery, folder, terom@132: # content terom@66: templates.folder_page(folder, page) terom@66: ) terom@66: terom@66: # write output terom@119: tpl.render_file(html) terom@66: terom@87: def render_folder (ctx, folder) : terom@94: """ terom@132: Recursively render a folder, with render_folder_images and render_folder. terom@131: terom@132: This does a depth-first search of subfolders. terom@131: terom@132: Updates the Images as needed (based on config.force_thumbs/config.force_html). terom@132: terom@132: Currently, this will always update the .html for non-empty Folders. terom@94: """ terom@131: terom@132: # do depth-first recursion terom@131: for subfolder in folder.subfolders : terom@132: render_folder(ctx, subfolder) terom@131: terom@132: if folder.empty : terom@132: # warn terom@132: ctx.log_debug("%s - empty, skipping", folder) terom@132: terom@132: return terom@132: terom@132: # force-update HTML, every time terom@132: render_folder_html(ctx, folder) terom@131: terom@132: # get the list of images that we are going to update, only those that are stale unless any force_update terom@144: update_images = list(folder.index_images(for_update=not ctx.options.force_index)) terom@132: terom@132: if update_images : terom@132: # status terom@132: ctx.log_info("%s - rendering %d/%d images", folder, len(update_images), len(folder.images)) terom@87: terom@132: # update images as needed terom@132: render_folder_images(ctx, folder.images) terom@132: terom@87: else : terom@132: # nothing to do terom@132: ctx.log_info("%s - up-to-date", folder) terom@66: terom@144: @command( terom@144: options = ( terom@144: Option('--force-html', help="Force-update HTML documents", action="store_true", default="False"), terom@144: Option('--force-thumb', help="Force-update thumbnails", action="store_true", default="False"), terom@144: Option('-F', '--force-update', help="Force-update both", action="store_true", default="False"), terom@144: ) terom@144: ) terom@144: def update (ctx, *filter) : terom@66: """ terom@144: Scan the gallery for new folders/images, and render updated ones. terom@66: """ terom@144: terom@144: # do the force_update/force_index semantics terom@144: if ctx.options.force_update : terom@144: ctx.options.force_index = ctx.options.force_html = ctx.options.force_thumb = True terom@144: terom@144: elif ctx.options.force_html or ctx.options.force_thumb : terom@144: ctx.options.force_index = True terom@144: terom@144: else : terom@144: ctx.options.force_index = False terom@66: terom@132: # render the gallery root as a folder terom@66: render_folder(ctx, ctx.gallery) terom@48: