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