diff options
| -rw-r--r-- | README.md | 1 | ||||
| -rw-r--r-- | include/components.h | 19 | ||||
| -rw-r--r-- | include/fs.h | 3 | ||||
| -rw-r--r-- | src/components.c | 4 | ||||
| -rw-r--r-- | src/fs.c | 3 | ||||
| -rw-r--r-- | src/render.c | 2 | ||||
| -rw-r--r-- | src/revela.c | 3 | ||||
| -rw-r--r-- | src/site.c | 41 | 
8 files changed, 53 insertions, 23 deletions
| @@ -27,6 +27,5 @@ system, or read the contents in `docs/` in the source.  ## TODO:  * Add exif tags to template hashmap. -* Re-render album html when an album.ini has changed.  * Better test coverage? (if I am not too lazy).  * Document templates. diff --git a/include/components.h b/include/components.h index 4317187..88023cb 100644 --- a/include/components.h +++ b/include/components.h @@ -11,7 +11,7 @@  #include <sys/stat.h>  #include <libexif/exif-data.h> -#define PHOTO_THUMB_SUFFIX "_thumb" +#define THUMB_SUFFIX "_thumb"  /* All data related to a single image's files, templates, and pages */  struct image { @@ -55,12 +55,19 @@ struct image {  /* All data related to an album's images, templates, and pages */  struct album {  	struct site *site; +	/* The album information, i.e. title, description */  	struct album_config *config; +	/* Modtime for the album.ini file; will be used to check whether we need to +	 * re-render the html for this album based on changes made to it. +	 */ +	struct timespec modtime; +	/* Whether the album.ini was updated */ +	bool config_updated;  	/* The path to the source directory */  	char *source; -	/* The full url that will be used in the template */ +	/* The full URL that will be used in the template */  	char *url; -	/* Pointer to the slug part in url that will be used for the new dir */ +	/* Pointer to the slug part in the URL that will be used for the new dir */  	const char *slug;  	/* Pointer to the human readable date of the earliest image */  	const char *datestr; @@ -68,8 +75,7 @@ struct album {  	char year[8];  	/* The date of the album is the date of the earliest image */  	time_t tstamp; -	/* -	 * List/vector with the images of this album to be sorted by from +	/* List/vector with the images of this album to be sorted by from  	 * older to newer.  	 */  	struct vector *images; @@ -77,8 +83,7 @@ struct album {  	struct hmap *preserved;  	/* Reference counted hashmap with values to be passed to the template */  	struct roscha_object *map; -	/* -	 * Reference counted vector with refcounted hashmaps of image thumbnails to +	/* Reference counted vector with refcounted hashmaps of image thumbnails to  	 * be passed to the template.  	 */  	struct roscha_object *thumbs; diff --git a/include/fs.h b/include/fs.h index 00be8a1..71c566b 100644 --- a/include/fs.h +++ b/include/fs.h @@ -41,6 +41,9 @@ bool isimage(const char *fname);   */  const char *delext(const char *restrict basename, char *restrict dest, size_t n); +#define TIMEQUAL(a, b) \ +	((a).tv_sec == (b).tv_sec && (a).tv_nsec == (b).tv_nsec) +  /*   * -1 if error; 0 if the timestamps are different; 1 if they are equal.   */ diff --git a/src/components.c b/src/components.c index f3d79d1..4d2afbd 100644 --- a/src/components.c +++ b/src/components.c @@ -156,12 +156,12 @@ image_new(char *src, const struct stat *pstat, struct album *album)  	size_t relstart = album->slug - album->url;  	image->url = joinpath(album->url, noext);  	image->url_image = joinpath(image->url, image->basename); -	image->url_thumb = malloc(strlen(image->url) + strlen(PHOTO_THUMB_SUFFIX) + +	image->url_thumb = malloc(strlen(image->url) + strlen(THUMB_SUFFIX) +  			strlen(image->basename) + 2);  	image->dst = image->url + relstart;  	image->dst_image = image->url_image + relstart;  	image->dst_thumb = image->url_thumb + relstart; -	sprintf(image->url_thumb, "%s/%s" PHOTO_THUMB_SUFFIX "%s", image->url, +	sprintf(image->url_thumb, "%s/%s" THUMB_SUFFIX "%s", image->url,  			noext, image->ext);  	image->exif_data = exif_data_new_from_file(image->source); @@ -138,8 +138,7 @@ file_is_uptodate(const char *path, const struct timespec *srcmtim)  			return -1;  		}  		return 0; -	} else if (dststat.st_mtim.tv_sec != srcmtim->tv_sec -			|| dststat.st_mtim.tv_nsec != srcmtim->tv_nsec) { +	} else if (!TIMEQUAL(dststat.st_mtim, *srcmtim)) {  		return 0;  	} diff --git a/src/render.c b/src/render.c index 9dbbe2a..8909570 100644 --- a/src/render.c +++ b/src/render.c @@ -145,7 +145,7 @@ bool  render_make_album(struct render *r, const char *path, const struct album *album)  {  	bool ok = true; -	if (album->images_updated == 0) { +	if (album->images_updated == 0 && !album->config_updated) {  		int isupdate = file_is_uptodate(path, &r->modtime);  		if (isupdate == -1) return false;  		if (isupdate == 1) return true; diff --git a/src/revela.c b/src/revela.c index 48c9ec4..f41d271 100644 --- a/src/revela.c +++ b/src/revela.c @@ -8,10 +8,9 @@  #include "log.h"  #include "site.h"  #include "config.h" -#include "bstree.h"  #ifndef VERSION -#define VERSION "0.1.1" +#define VERSION "0.1.2"  #endif  static const char *usage = @@ -1,5 +1,6 @@  #include "site.h" +#include <fcntl.h>  #include <unistd.h>  #include <stdlib.h>  #include <string.h> @@ -12,9 +13,11 @@  /* TODO: handle error cases for paths that are too long */ -#define THUMB_SUFFIX "_thumb" -  static const char *index_html = "index.html"; +/* File which revela uses solely to store the modtime of the album.ini file to + * check whether we should re-render the album html files. + */ +static const char *album_meta = ".revela";  /*   * Checks where the removed image used to be based on the modification time of @@ -162,7 +165,7 @@ images_walk(struct site *site, struct vector *images)  		int isupdate = file_is_uptodate(htmlpath, &site->render.modtime);  		if (isupdate == -1) return false; -		if (isupdate == 0) { +		if (isupdate == 0 || image->album->config_updated) {  			if (!render_make_image(&site->render, htmlpath, image)) {  				return false;  			} @@ -219,12 +222,33 @@ albums_walk(struct site *site)  	vector_foreach(site->albums, i, album) {  		struct stat dstat; -		if (!nmkdir(album->slug, &dstat, site->dry_run)) return false; +		char pathbuf[PATH_MAX]; +		switch (nmkdir(album->slug, &dstat, site->dry_run)) { +		case NMKDIR_ERROR: +			return false; +		case NMKDIR_CREATED: +			album->config_updated = true; +			if (!site->dry_run) { +				joinpathb(pathbuf, album->slug, album_meta); +				close(creat(pathbuf, 0644)); +				setdatetime(pathbuf, &album->modtime); +			} +			break; +		case NMKDIR_NOOP: +			joinpathb(pathbuf, album->slug, album_meta); +			if (file_is_uptodate(pathbuf, &album->modtime) == 0) { +				album->config_updated = true; +				if (!site->dry_run) { +					close(creat(pathbuf, 0644)); +					setdatetime(pathbuf, &album->modtime); +				} +			} +			break; +		}  		hmap_set(site->album_dirs, album->slug, (char *)album->slug);  		if (!site->dry_run) {  			if (!render_set_album_vars(&site->render, album)) return false; -  		}  		log_printl(LOG_DEBUG, "Album: %s, datetime %s", album->slug, album->datestr); @@ -233,6 +257,7 @@ albums_walk(struct site *site)  		}  		hmap_set(album->preserved, index_html, (char *)index_html); +		hmap_set(album->preserved, album_meta, (char *)album_meta);  		ssize_t deleted = rmextra(album->slug, album->preserved, prerm_imagedir,  				album, site->dry_run);  		if (deleted < 0) { @@ -245,9 +270,8 @@ albums_walk(struct site *site)  			site->render.albums_updated++;  		} -		char htmlpath[PATH_MAX]; -		joinpathb(htmlpath, album->slug, index_html); -		if (!render_make_album(&site->render, htmlpath, album)) return false; +		joinpathb(pathbuf, album->slug, index_html); +		if (!render_make_album(&site->render, pathbuf, album)) return false;  	}  	return true;  } @@ -296,6 +320,7 @@ traverse(struct site *site, const char *path, struct stat *dstat)  		} else if (!strcmp(ent->d_name, ALBUM_CONF)) {  			ok = album_config_read_ini(subpath, album_conf);  			if (!ok) goto fail; +			album->modtime = fstats.st_mtim;  		} else if (isimage(subpath)) {  			struct image *image = image_new(subpath, &fstats, album);  			if (image == NULL) { | 
