|
1 from degal.command import command, Option |
|
2 from degal.concurrent import task |
|
3 from degal import templates |
|
4 |
|
5 def render_image_html (ctx, image) : |
|
6 """ |
|
7 Render and write out the static .html file for the give image. |
|
8 """ |
|
9 |
|
10 ctx.log_debug("%s", image.html) |
|
11 |
|
12 # render full-xhtml-document |
|
13 tpl = templates.master(ctx.gallery, image, |
|
14 # with content |
|
15 templates.image_page(image) |
|
16 ) |
|
17 |
|
18 # write output |
|
19 tpl.render_file(image.html) |
|
20 |
|
21 def update_image_thumbs (image) : |
|
22 """ |
|
23 Update/render and write out the thumbnails (thumb+preview) for the given image, returning the image object |
|
24 itself. |
|
25 |
|
26 This /should/ be threadsafe. XXX: but it probably isn't entirely. |
|
27 """ |
|
28 |
|
29 # this will unconditionally update the image |
|
30 image.update() |
|
31 |
|
32 return image |
|
33 |
|
34 def render_folder_images (ctx, images) : |
|
35 """ |
|
36 Render the given series of images (html+thumbnails) as required based on the settings. |
|
37 |
|
38 This is capable of rendering the given set of images in parallel. |
|
39 """ |
|
40 |
|
41 # first, update HTML |
|
42 for image in images : |
|
43 if ctx.options.force_html or image.stale() : |
|
44 render_image_html(ctx, image) |
|
45 |
|
46 # define the render-tasks |
|
47 tasks = (task(update_image_thumbs, image) for image in images if ctx.options.force_thumb or image.stale()) |
|
48 |
|
49 # render the thumbnails themselves concurrently, returning the rendered Image objects |
|
50 for image in ctx.concurrent.execute(tasks) : |
|
51 # log image path |
|
52 ctx.log_info("%s", image) |
|
53 |
|
54 # release large objects that are not needed anymore |
|
55 image.cleanup() |
|
56 |
|
57 def render_folder_html (ctx, folder) : |
|
58 """ |
|
59 Render and write out the required static .html files for the given folder. |
|
60 |
|
61 This will paginate large numbers of images, handle Folders with only subfolders within as a single page, and as |
|
62 a bonus, will not render anything for (non-recursively) empty folders. |
|
63 """ |
|
64 |
|
65 # render each page separately |
|
66 for page in xrange(folder.page_count) : |
|
67 # output .html path |
|
68 html = folder.html_page(page) |
|
69 |
|
70 ctx.log_debug("%s", html) |
|
71 |
|
72 # render full-html template |
|
73 tpl = templates.master(ctx.gallery, folder, |
|
74 # content |
|
75 templates.folder_page(folder, page) |
|
76 ) |
|
77 |
|
78 # write output |
|
79 tpl.render_file(html) |
|
80 |
|
81 def render_folder (ctx, folder) : |
|
82 """ |
|
83 Recursively render a folder, with render_folder_images and render_folder. |
|
84 |
|
85 This does a depth-first search of subfolders. |
|
86 |
|
87 Updates the Images as needed (based on config.force_thumbs/config.force_html). |
|
88 |
|
89 Currently, this will always update the .html for non-empty Folders. |
|
90 """ |
|
91 |
|
92 # do depth-first recursion |
|
93 for subfolder in folder.subfolders : |
|
94 render_folder(ctx, subfolder) |
|
95 |
|
96 if folder.empty : |
|
97 # warn |
|
98 ctx.log_debug("%s - empty, skipping", folder) |
|
99 |
|
100 return |
|
101 |
|
102 # force-update HTML, every time |
|
103 render_folder_html(ctx, folder) |
|
104 |
|
105 # get the list of images that we are going to update, only those that are stale unless any force_update |
|
106 update_images = list(folder.index_images(for_update=not ctx.options.force_index)) |
|
107 |
|
108 if update_images : |
|
109 # status |
|
110 ctx.log_info("%s - rendering %d/%d images", folder, len(update_images), len(folder.images)) |
|
111 |
|
112 # update images as needed |
|
113 render_folder_images(ctx, folder.images) |
|
114 |
|
115 else : |
|
116 # nothing to do |
|
117 ctx.log_info("%s - up-to-date", folder) |
|
118 |
|
119 @command( |
|
120 options = ( |
|
121 Option('--force-html', help="Force-update HTML documents", action="store_true", default="False"), |
|
122 Option('--force-thumb', help="Force-update thumbnails", action="store_true", default="False"), |
|
123 Option('-F', '--force-update', help="Force-update both", action="store_true", default="False"), |
|
124 ) |
|
125 ) |
|
126 def update (ctx, *filter) : |
|
127 """ |
|
128 Scan the gallery for new folders/images, and render updated ones. |
|
129 """ |
|
130 |
|
131 # do the force_update/force_index semantics |
|
132 if ctx.options.force_update : |
|
133 ctx.options.force_index = ctx.options.force_html = ctx.options.force_thumb = True |
|
134 |
|
135 elif ctx.options.force_html or ctx.options.force_thumb : |
|
136 ctx.options.force_index = True |
|
137 |
|
138 else : |
|
139 ctx.options.force_index = False |
|
140 |
|
141 # render the gallery root as a folder |
|
142 render_folder(ctx, ctx.gallery) |
|
143 |