aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorYaroslav de la Peña Smirnov <yps@yaroslavps.com>2022-10-16 23:02:03 +0300
committerYaroslav de la Peña Smirnov <yps@yaroslavps.com>2022-10-16 23:03:08 +0300
commit01482f7632e86a12b9ee6d97eafa1dafa712f84e (patch)
treef73daafd9a094f473c8edc5097dca21256ba4a9e
parentf2c1beb5c3139238a3570d8f5052635519367d26 (diff)
downloadrevela-01482f7632e86a12b9ee6d97eafa1dafa712f84e.tar.gz
revela-01482f7632e86a12b9ee6d97eafa1dafa712f84e.zip
Re-render album html when album.ini changedv0.1.2
-rw-r--r--README.md1
-rw-r--r--include/components.h19
-rw-r--r--include/fs.h3
-rw-r--r--src/components.c4
-rw-r--r--src/fs.c3
-rw-r--r--src/render.c2
-rw-r--r--src/revela.c3
-rw-r--r--src/site.c41
8 files changed, 53 insertions, 23 deletions
diff --git a/README.md b/README.md
index 3511fcf..14ab33e 100644
--- a/README.md
+++ b/README.md
@@ -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);
diff --git a/src/fs.c b/src/fs.c
index b2c94c8..3d2c4da 100644
--- a/src/fs.c
+++ b/src/fs.c
@@ -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 =
diff --git a/src/site.c b/src/site.c
index 3937376..0b76a0d 100644
--- a/src/site.c
+++ b/src/site.c
@@ -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) {