diff options
| -rw-r--r-- | include/bstree.h | 68 | ||||
| -rw-r--r-- | include/components.h | 10 | ||||
| -rw-r--r-- | include/render.h | 3 | ||||
| -rw-r--r-- | include/site.h | 4 | ||||
| -rw-r--r-- | src/bstree.c | 183 | ||||
| -rw-r--r-- | src/components.c | 29 | ||||
| -rw-r--r-- | src/render.c | 52 | ||||
| -rw-r--r-- | src/site.c | 262 | 
8 files changed, 188 insertions, 423 deletions
| diff --git a/include/bstree.h b/include/bstree.h deleted file mode 100644 index 9577b73..0000000 --- a/include/bstree.h +++ /dev/null @@ -1,68 +0,0 @@ -/* - * Copyright 2021 Yaroslav de la Peña Smirnov - *  - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - *  - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - *  - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ -#ifndef BSTREE_H -#define BSTREE_H - -#include <stdbool.h> - -/* < 0 means a less than b; 0 means equal; > 0 means a more than b. */ -typedef int (*bst_cmp_fn)(const void *a, const void *b); -typedef void (*bst_free_fn)(void *data); - -struct bstree { -	struct bstnode *root; -	bst_cmp_fn cmp; -	/* It can be NULL, in which case you will have to free the values manually */ -	bst_free_fn free; -}; - -struct bstnode { -	void *value; -	struct bstnode *parent; -	struct bstnode *left; -	struct bstnode *right; -}; - -typedef bool (*bst_walk_cb)(struct bstnode *, void *data); - -struct bstree *bstree_new(bst_cmp_fn, bst_free_fn); - -struct bstnode *bstree_add(struct bstree *, void *val); - -/* Returns NULL if a node with the value wasn't found */ -struct bstnode *bstree_search(struct bstree *, void *val); - -struct bstnode *bstree_min(struct bstnode *); - -struct bstnode *bstree_max(struct bstnode *); - -struct bstnode *bstree_predecessor(struct bstnode *); - -struct bstnode *bstree_successor(struct bstnode *); - -bool bstree_inorder_walk(struct bstnode *, bst_walk_cb, void *data); - -void bstree_remove(struct bstree *, struct bstnode *); - -void bstree_destroy(struct bstree *); - -#endif diff --git a/include/components.h b/include/components.h index f08d79a..4317187 100644 --- a/include/components.h +++ b/include/components.h @@ -68,11 +68,11 @@ struct album {  	char year[8];  	/* The date of the album is the date of the earliest image */  	time_t tstamp; -	/*  -	 * Binary search tree with the images of this album sorted by date from +	/* +	 * List/vector with the images of this album to be sorted by from  	 * older to newer.  	 */ -	struct bstree *images; +	struct vector *images;  	/* Files/dirs that belong to images and which shouldn't be deleted */  	struct hmap *preserved;  	/* Reference counted hashmap with values to be passed to the template */ @@ -92,7 +92,7 @@ struct image *image_old(struct stat *istat);  int image_cmp(const void *a, const void *b); -void image_destroy(void *data); +void image_destroy(struct image *);  struct album *album_new(struct album_config *, struct site *,  		const char *src, const char *rsrc, const struct stat *); @@ -103,6 +103,6 @@ void album_add_image(struct album *, struct image *);  void album_set_year(struct album *); -void album_destroy(void *data); +void album_destroy(struct album *);  #endif diff --git a/include/render.h b/include/render.h index 9b5e9e2..24c931a 100644 --- a/include/render.h +++ b/include/render.h @@ -1,7 +1,6 @@  #ifndef REVELA_RENDER_H  #define REVELA_RENDER_H -#include "bstree.h"  #include "config.h"  #include "components.h" @@ -86,7 +85,7 @@ bool render_make_image(struct render *r, const char *path,  bool render_set_album_vars(struct render *, struct album *);  bool render_init(struct render *, const char *path, struct site_config *, -		struct bstree *albums); +		struct vector *albums);  void render_deinit(struct render *); diff --git a/include/site.h b/include/site.h index 43a20d2..0f45667 100644 --- a/include/site.h +++ b/include/site.h @@ -2,7 +2,6 @@  #define REVELA_SITE_H  #include "config.h" -#include "bstree.h"  #include "render.h"  #include "components.h" @@ -29,7 +28,8 @@ struct site {  	 * site_init()  	 */  	size_t rel_content_dir; -	struct bstree *albums; +	/* List/vector with the albums to be sorted from newer to older */ +	struct vector *albums;  	/* Files/dirs that belong to albums and which shouldn't be deleted */  	struct hmap *album_dirs;  	struct render render; diff --git a/src/bstree.c b/src/bstree.c deleted file mode 100644 index 7d4f14f..0000000 --- a/src/bstree.c +++ /dev/null @@ -1,183 +0,0 @@ -/* - * Copyright 2021 Yaroslav de la Peña Smirnov - *  - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - *  - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - *  - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ -#include "bstree.h" - -#include <stdlib.h> - -struct bstree * -bstree_new(bst_cmp_fn bstcmp, bst_free_fn bstfree) -{ -	struct bstree *tree = malloc(sizeof *tree); -	tree->root = NULL; -	tree->cmp = bstcmp; -	tree->free = bstfree; - -	return tree; -} - -struct bstnode * -bstree_add(struct bstree *tree, void *val) -{ -	struct bstnode **cur; -	struct bstnode *prev = NULL; -	cur = &tree->root; -	while (*cur != NULL) { -		prev = *cur; -		if (tree->cmp(val, prev->value) < 0) { -			cur = &prev->left; -		} else { -			cur = &prev->right; -		} -	} -	*cur = calloc(1, sizeof **cur); -	(*cur)->value = val; -	(*cur)->parent = prev; - -	return *cur; -} - -struct bstnode * -bstree_search(struct bstree *tree, void *val) -{ -	struct bstnode *node = tree->root; -	while (node != NULL) { -		int res; -		if ((res = tree->cmp(val, node->value)) == 0) { -			break; -		} -		if (res < 0) { -			node = node->left; -		} else { -			node = node->right; -		} -	} - -	return node; -} - -#define bstree_extreme(node, d) \ -	while (node != NULL && node->d != NULL) { \ -		node = node->d; \ -	} - -struct bstnode * -bstree_max(struct bstnode *node) -{ -	bstree_extreme(node, right) -	return node; -} - -struct bstnode * -bstree_min(struct bstnode *node) -{ -	bstree_extreme(node, left) -	return node; -} - -#define bstree_xcessor(na, d, m) \ -	if (na->d != NULL) { \ -		return bstree_##m(na->d); \ -	} \ -	struct bstnode *nb = na->parent; \ -	while (nb != NULL && nb->d == na) { \ -		na = nb; \ -		nb = nb->parent; \ -	} \ -	return nb - -struct bstnode * -bstree_successor(struct bstnode *na) -{ -	bstree_xcessor(na, right, min); -} - -struct bstnode * -bstree_predecessor(struct bstnode *na) -{ -	bstree_xcessor(na, left, max); -} - -bool -bstree_inorder_walk(struct bstnode *node, bst_walk_cb cb, void *data) -{ -	if (node->left != NULL) { -		if (!bstree_inorder_walk(node->left, cb, data)) return false; -	} -	if (!cb(node, data)) return false; -	if (node->right != NULL) { -		return bstree_inorder_walk(node->right, cb, data); -	} -	return true; -} - -static void -bstree_transplant(struct bstree *tree, struct bstnode *a, struct bstnode *b) -{ -	if (a->parent == NULL) { -		tree->root = b; -	} else if (a == a->parent->left) { -		a->parent->left = b; -	} else { -		a->parent->right = b; -	} -	if (b != NULL) { -		b->parent = a->parent; -	} -} - -void -bstree_remove(struct bstree *tree, struct bstnode *na) -{ -	if (na->left == NULL) { -		bstree_transplant(tree, na, na->right); -	} else if (na->right == NULL) { -		bstree_transplant(tree, na, na->left); -	} else { -		struct bstnode *nb = bstree_min(na->right); -		if (nb->parent != na) { -			bstree_transplant(tree, nb, nb->right); -			nb->right = na->right; -			nb->right->parent = nb; -		} -		bstree_transplant(tree, na, nb); -		nb->left = na->left; -		nb->left->parent = nb; -	} -	tree->free(na->value); -	free(na); -} - -static void -bstree_subdestroy(struct bstree *tree, struct bstnode *node) -{ -	if (node->right) bstree_subdestroy(tree, node->right); -	if (node->left) bstree_subdestroy(tree, node->left); -	tree->free(node->value); -	free(node); -} - -void -bstree_destroy(struct bstree *tree) -{ -	if (tree->root) bstree_subdestroy(tree, tree->root); -	free(tree); -} diff --git a/src/components.c b/src/components.c index aeb14b1..f3d79d1 100644 --- a/src/components.c +++ b/src/components.c @@ -175,17 +175,16 @@ image_new(char *src, const struct stat *pstat, struct album *album)  }  int -image_cmp(const void *a, const void *b) +image_cmp(const void *va, const void *vb)  { +	struct image *a = *(struct image **)va, *b = *(struct image **)vb;  	/* Compare in ascending order */ -	return (((struct image *)a)->tstamp > ((struct image *)b)->tstamp) -		- (((struct image *)a)->tstamp < ((struct image *)b)->tstamp); +	return (a->tstamp > b->tstamp) - (a->tstamp < b->tstamp);  }  void -image_destroy(void *data) +image_destroy(struct image *image)  { -	struct image *image = data;  	free(image->source);  	free(image->url);  	free(image->url_image); @@ -213,7 +212,7 @@ album_new(struct album_config *conf, struct site *site, const char *src,  	album->config = conf;  	album->source = strdup(src);  	album->slug = slugify(rsrc, site->config->base_url, &album->url); -	album->images = bstree_new(image_cmp, image_destroy); +	album->images = vector_new_with_cap(64);  	album->tstamp = MAXTIME;  	album->preserved = hmap_new();  	album->map = roscha_object_new(hmap_new()); @@ -223,11 +222,11 @@ album_new(struct album_config *conf, struct site *site, const char *src,  }  int -album_cmp(const void *a, const void *b) +album_cmp(const void *va, const void *vb)  { +	struct album *a = *(struct album **)va, *b = *(struct album **)vb;  	/* Compare in descending order */ -	return (((struct album *)a)->tstamp < ((struct album *)b)->tstamp) -		- (((struct album *)a)->tstamp > ((struct album *)b)->tstamp); +	return (a->tstamp < b->tstamp) - (a->tstamp > b->tstamp);  } @@ -238,7 +237,7 @@ album_add_image(struct album *album, struct image *image)  		album->tstamp = image->tstamp;  		album->datestr = image->datestr;  	} -	bstree_add(album->images, image); +	vector_push(album->images, image);  }  void @@ -251,15 +250,19 @@ album_set_year(struct album *album)  }  void -album_destroy(void *data) +album_destroy(struct album *album)  { -	struct album *album = data;  	if (album->config != NULL) {  		album_config_destroy(album->config);  	} +	size_t i; +	struct image *img; +	vector_foreach(album->images, i, img) { +		image_destroy(img); +	} +	vector_free(album->images);  	free(album->source);  	free(album->url); -	bstree_destroy(album->images);  	hmap_free(album->preserved);  	roscha_object_unref(album->map);  	roscha_object_unref(album->thumbs); diff --git a/src/render.c b/src/render.c index bc9b8df..9dbbe2a 100644 --- a/src/render.c +++ b/src/render.c @@ -7,33 +7,33 @@  #include "log.h"  #include "site.h" -/* TODO: refactor to use roscha instead of unja */ - -static bool -images_walk(struct bstnode *node, void *data) +static void +images_walk(struct vector *images)  { -	struct image *image = node->value; - -	roscha_hmap_set_new(image->map, "source", (slice_whole(image->url_image))); -	roscha_hmap_set_new(image->map, "date", (slice_whole(image->datestr))); -	struct bstnode *prev = bstree_predecessor(node),  -				   *next = bstree_successor(node); -	char *url; -	if (prev) { -		url = ((struct image *)prev->value)->url; -		roscha_hmap_set_new(image->map, "prev", (slice_whole(url))); -	} -	if (next) { -		url = ((struct image *)next->value)->url; -		roscha_hmap_set_new(image->map, "next", (slice_whole(url))); -	} - -	roscha_hmap_set_new(image->thumb, "link", (slice_whole(image->url))); -	roscha_hmap_set_new(image->thumb, "source", (slice_whole(image->url_thumb))); +	size_t i; +	struct image *image; +	size_t last = images->len - 1; + +	vector_foreach(images, i, image) { +		roscha_hmap_set_new(image->map, "source", (slice_whole(image->url_image))); +		roscha_hmap_set_new(image->map, "date", (slice_whole(image->datestr))); +		char *url; +		if (i > 0) { +			struct image *prev = images->values[i - 1]; +			url = prev->url; +			roscha_hmap_set_new(image->map, "prev", (slice_whole(url))); +		} +		if (i < last) { +			struct image *next = images->values[i + 1]; +			url = next->url; +			roscha_hmap_set_new(image->map, "next", (slice_whole(url))); +		} -	roscha_vector_push(image->album->thumbs, image->thumb); +		roscha_hmap_set_new(image->thumb, "link", (slice_whole(image->url))); +		roscha_hmap_set_new(image->thumb, "source", (slice_whole(image->url_thumb))); -	return true; +		roscha_vector_push(image->album->thumbs, image->thumb); +	}  }  static inline void @@ -84,7 +84,7 @@ render_set_album_vars(struct render *r, struct album *album)  	roscha_hmap_set_new(album->map, "date", (slice_whole(album->datestr)));  	roscha_hmap_set_new(album->map, "year", (slice_whole(album->year))); -	bstree_inorder_walk(album->images->root, images_walk, NULL); +	images_walk(album->images);  	roscha_hmap_set(album->map, "thumbs", album->thumbs); @@ -182,7 +182,7 @@ done:  bool  render_init(struct render *r, const char *root, struct site_config *conf, -		struct bstree *albums) +		struct vector *albums)  {  	char *tmplpath = joinpath(root, TEMPLATESDIR);  	struct stat tstat; @@ -33,32 +33,33 @@ prerm_imagedir(const char *path, void *data)  		return false;  	}  	if (S_ISDIR(st.st_mode)) { -		struct image *old = image_old(&st); -		struct bstnode *imnode = bstree_add(album->images, old), -					   *prev = bstree_predecessor(imnode), -					   *next = bstree_successor(imnode); +		struct image *prev, *next = NULL; +		size_t i; +		vector_foreach(album->images, i, prev) { +			if (prev->tstamp > st.st_mtim.tv_sec) { +				prev = next; +				break; +			} +			next = prev; +		}  		if (prev) { -			struct image *imprev = (struct image *)prev->value; -			if (!imprev->modified) { -				joinpathb(htmlpath, imprev->dst, index_html); -				if (!render_make_image(&album->site->render, htmlpath, imprev)) { +			if (!prev->modified) { +				joinpathb(htmlpath, prev->dst, index_html); +				if (!render_make_image(&album->site->render, htmlpath, prev)) {  					goto fail;  				}  			}  		} -		if (next) { -			struct image *imnext = (struct image *)next->value; -			if (!imnext->modified) { -				joinpathb(htmlpath, imnext->dst, index_html); -				if (!render_make_image(&album->site->render, htmlpath, imnext)) { +		if (next != prev) { +			if (!next->modified) { +				joinpathb(htmlpath, next->dst, index_html); +				if (!render_make_image(&album->site->render, htmlpath, next)) {  					goto fail;  				}  			}  		} -		bstree_remove(album->images, imnode);  		return true;  fail: -		bstree_remove(album->images, imnode);  		return false;  	}  	return true; @@ -120,131 +121,134 @@ magick_fail:  }  static bool -images_walk(struct bstnode *node, void *data) +images_walk(struct site *site, struct vector *images)  { -	struct site *site = data; -	struct image *image = node->value; -	struct stat dstat; -	struct timespec ddate = { .tv_sec = image->tstamp, .tv_nsec = 0 }; -	int imgupdate, thumbupdate; -	char htmlpath[PATH_MAX]; -	const char *base = rbasename(image->dst); - -	log_printl(LOG_DEBUG, "Image: %s, datetime %s", image->basename,  -			image->datestr); - -	if (!nmkdir(image->dst, &dstat, site->dry_run)) return false; - -	imgupdate = file_is_uptodate(image->dst_image, &image->modtime); -	if (imgupdate == -1) goto magick_fail; -	thumbupdate = file_is_uptodate(image->dst_image, &image->modtime); -	if (thumbupdate == -1) goto magick_fail; -	if (!site->dry_run && (!imgupdate || !thumbupdate)) { -		TRYWAND(site->wand, MagickReadImage(site->wand, image->source)); -	} -	if (!imgupdate && !optimize_image(site->wand, image->dst_image, -				&site->config->images, &image->modtime, site->dry_run)) { -		goto magick_fail; -	} -	if (!thumbupdate && !optimize_image(site->wand, image->dst_thumb, -				&site->config->thumbnails, &image->modtime, site->dry_run)) { -		goto magick_fail; -	} -	if (!site->dry_run && (!imgupdate || !thumbupdate)) { -		MagickRemoveImage(site->wand); -	} +	size_t i; +	struct image *image; +	 +	vector_foreach(images, i, image) { +		struct stat dstat; +		struct timespec ddate = { .tv_sec = image->tstamp, .tv_nsec = 0 }; +		int imgupdate, thumbupdate; +		char htmlpath[PATH_MAX]; +		const char *base = rbasename(image->dst); + +		log_printl(LOG_DEBUG, "Image: %s, datetime %s", image->basename,  +				image->datestr); + +		if (!nmkdir(image->dst, &dstat, site->dry_run)) return false; + +		imgupdate = file_is_uptodate(image->dst_image, &image->modtime); +		if (imgupdate == -1) goto magick_fail; +		thumbupdate = file_is_uptodate(image->dst_image, &image->modtime); +		if (thumbupdate == -1) goto magick_fail; +		if (!site->dry_run && (!imgupdate || !thumbupdate)) { +			TRYWAND(site->wand, MagickReadImage(site->wand, image->source)); +		} +		if (!imgupdate && !optimize_image(site->wand, image->dst_image, +					&site->config->images, &image->modtime, site->dry_run)) { +			goto magick_fail; +		} +		if (!thumbupdate && !optimize_image(site->wand, image->dst_thumb, +					&site->config->thumbnails, &image->modtime, site->dry_run)) { +			goto magick_fail; +		} +		if (!site->dry_run && (!imgupdate || !thumbupdate)) { +			MagickRemoveImage(site->wand); +		} -	joinpathb(htmlpath, image->dst, index_html); -	hmap_set(image->album->preserved, base, (char *)base); +		joinpathb(htmlpath, image->dst, index_html); +		hmap_set(image->album->preserved, base, (char *)base); -	int isupdate = file_is_uptodate(htmlpath, &site->render.modtime); -	if (isupdate == -1) return false; -	if (isupdate == 0) { -		if (!render_make_image(&site->render, htmlpath, image)) { -			return false; -		} -		image->modified = true; -		image->album->images_updated++; -		/* Check if previous image wasn't updated, if so, render it */ -		struct bstnode *prev = bstree_predecessor(node); -		if (prev) { -			struct image *iprev = prev->value; -			if (!iprev->modified) { -				joinpathb(htmlpath, iprev->dst, index_html); -				if (!render_make_image(&site->render, htmlpath, iprev)) { -					return false; +		int isupdate = file_is_uptodate(htmlpath, &site->render.modtime); +		if (isupdate == -1) return false; +		if (isupdate == 0) { +			if (!render_make_image(&site->render, htmlpath, image)) { +				return false; +			} +			image->modified = true; +			image->album->images_updated++; +			/* Check if previous image wasn't updated, if so, render it */ +			if (i > 0) { +				struct image *prev = images->values[i - 1]; +				if (!prev->modified) { +					joinpathb(htmlpath, prev->dst, index_html); +					if (!render_make_image(&site->render, htmlpath, prev)) { +						return false; +					} +					goto success;  				} -				goto success;  			} -		} -		goto success; -	} +			goto success; +		} -	/* -	 * Render anyway if next image doesn't exist yet in directory or if previous -	 * image was updated. -	 */ -	struct bstnode *next = bstree_successor(node), *prev = NULL; -	if (next) { -		struct image *inext = next->value; -		if (access(inext->dst, F_OK) != 0) { -			image->album->images_updated++; -			return render_make_image(&site->render, htmlpath, image); +		/* +		 * Render anyway if next image doesn't exist yet in directory or if +		 * previous image was updated. +		 */ +		if (i < images->len - 1) { +			struct image *next = images->values[i + 1]; +			if (access(next->dst, F_OK) != 0) { +				image->album->images_updated++; +				return render_make_image(&site->render, htmlpath, image); +			}  		} -	} -	if ((prev = bstree_predecessor(node)) != NULL) { -		struct image *iprev = prev->value; -		if (iprev->modified) { -			image->album->images_updated++; -			return render_make_image(&site->render, htmlpath, image); +		if (i > 0) { +				struct image *prev = images->values[i - 1]; +			if (prev->modified) { +				image->album->images_updated++; +				return render_make_image(&site->render, htmlpath, image); +			}  		} -	} -success: -	if (!site->dry_run) setdatetime(image->dst, &ddate); +	success: +		if (!site->dry_run) setdatetime(image->dst, &ddate); +		continue; +	magick_fail: +		return false; +	}  	return true; -magick_fail: -	return false;  }  static bool -albums_walk(struct bstnode *node, void *data) +albums_walk(struct site *site)  { -	struct site *site = data; -	struct album *album = node->value; -	struct stat dstat; -	if (!nmkdir(album->slug, &dstat, site->dry_run)) return false; - -	hmap_set(site->album_dirs, album->slug, (char *)album->slug); -	if (!site->dry_run) { -		if (!render_set_album_vars(&site->render, album)) return false; +	size_t i; +	struct album *album; -	} +	vector_foreach(site->albums, i, album) { +		struct stat dstat; +		if (!nmkdir(album->slug, &dstat, site->dry_run)) return false; -	log_printl(LOG_DEBUG, "Album: %s, datetime %s", album->slug, album->datestr); -	if (!bstree_inorder_walk(album->images->root, images_walk, site)) { -		return false; -	} +		hmap_set(site->album_dirs, album->slug, (char *)album->slug); +		if (!site->dry_run) { +			if (!render_set_album_vars(&site->render, album)) return false; -	hmap_set(album->preserved, index_html, (char *)index_html); -	ssize_t deleted = rmextra(album->slug, album->preserved, prerm_imagedir, -			album, site->dry_run); -	if (deleted < 0) { -		log_printl_errno(LOG_ERROR,  -					"Something happened while deleting extraneous files"); -	} else { -		album->images_updated += deleted; -	} -	if (album->images_updated > 0) { -		site->render.albums_updated++; -	} +		} -	char htmlpath[PATH_MAX]; -	joinpathb(htmlpath, album->slug, index_html); -	if (!render_make_album(&site->render, htmlpath, album)) return false; +		log_printl(LOG_DEBUG, "Album: %s, datetime %s", album->slug, album->datestr); +		if (!images_walk(site, album->images)) { +			return false; +		} +		hmap_set(album->preserved, index_html, (char *)index_html); +		ssize_t deleted = rmextra(album->slug, album->preserved, prerm_imagedir, +				album, site->dry_run); +		if (deleted < 0) { +			log_printl_errno(LOG_ERROR,  +						"Something happened while deleting extraneous files"); +		} else { +			album->images_updated += deleted; +		} +		if (album->images_updated > 0) { +			site->render.albums_updated++; +		} +		char htmlpath[PATH_MAX]; +		joinpathb(htmlpath, album->slug, index_html); +		if (!render_make_album(&site->render, htmlpath, album)) return false; +	}  	return true;  } @@ -304,9 +308,11 @@ traverse(struct site *site, const char *path, struct stat *dstat)  		free(subpath);  	} -	if (album->images->root != NULL) { +	if (album->images->len != 0) {  		album_set_year(album); -		bstree_add(site->albums, album); +		qsort(album->images->values, +			  album->images->len, sizeof(void *), image_cmp); +		vector_push(site->albums, album);  		closedir(dir);  		return true;  	} @@ -333,7 +339,7 @@ site_build(struct site *site)  		return false;  	} -	if (!bstree_inorder_walk(site->albums->root, albums_walk, (void *)site)) { +	if (!albums_walk(site)) {  		return false;  	} @@ -371,6 +377,7 @@ site_load(struct site *site)  	}  	if (!traverse(site, site->content_dir, &cstat)) return false; +	qsort(site->albums->values, site->albums->len, sizeof(void *), album_cmp);  	return render_init(&site->render, site->root_dir, site->config, site->albums);  } @@ -380,7 +387,7 @@ site_init(struct site *site)  {  	site->config = site_config_init();  	if (!site_config_read_ini(site->root_dir, site->config)) return false; -	site->albums = bstree_new(album_cmp, album_destroy); +	site->albums = vector_new();  	if (site->root_dir == NULL) {  		site->root_dir = malloc(PATH_MAX); @@ -405,7 +412,14 @@ site_init(struct site *site)  void  site_deinit(struct site *site)  { -	if (site->albums) bstree_destroy(site->albums); +	if (site->albums) { +		size_t i; +		struct album *a; +		vector_foreach(site->albums, i, a) { +			album_destroy(a); +		} +		vector_free(site->albums); +	}  	site_config_destroy(site->config);  	free(site->content_dir);  	free(site->root_dir); | 
