summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/cgg.c15
-rw-r--r--src/gallery-utils.c29
-rw-r--r--src/gallery-utils.h5
-rw-r--r--src/generators.c165
-rw-r--r--src/generators.h11
-rw-r--r--src/job-manager.c96
-rw-r--r--src/setup.h1
7 files changed, 200 insertions, 122 deletions
diff --git a/src/cgg.c b/src/cgg.c
index f5776b4..aa8a2ab 100644
--- a/src/cgg.c
+++ b/src/cgg.c
@@ -44,19 +44,21 @@
* parse_cmd: parse commandline and fill global variable parameters
*/
gboolean
-parse_cmd (int argc, char* argv[], char **source_dir, char **dst_dir, gboolean *verbose, int *jobs)
+parse_cmd (int argc, char* argv[], char **source_dir, char **dst_dir, gboolean *verbose, int *jobs, gboolean *update)
{
static gboolean _verbose = FALSE;
static gchar *_source_dir = NULL;
static gchar *_dst_dir = NULL;
static int _jobs = 1;
+ static gboolean _update = FALSE;
static GOptionEntry entries[] =
{
{ "verbose", 'v', 0, G_OPTION_ARG_NONE, &_verbose, "Be verbose", NULL },
- { "source", 's', 0, G_OPTION_ARG_STRING, &_source_dir, "Specifies path to source structure", NULL },
+ { "source", 's', 0, G_OPTION_ARG_STRING, &_source_dir, "Specifies a path to source structure", NULL },
{ "output", 'o', 0, G_OPTION_ARG_STRING, &_dst_dir, "Generate files to the specified directory instead of current", NULL },
{ "jobs", 'j', 0, G_OPTION_ARG_INT, &_jobs, "Allow N jobs at once (default=1)", NULL },
+ { "update", 'u', 0, G_OPTION_ARG_NONE, &_update, "Update the output structure", NULL },
{ NULL }
};
@@ -73,7 +75,7 @@ parse_cmd (int argc, char* argv[], char **source_dir, char **dst_dir, gboolean *
g_option_context_add_main_entries (context, entries, NULL);
if (argc == 1) {
- s1 = g_option_context_get_help (context, TRUE, NULL);
+ s1 = g_option_context_get_help (context, TRUE, NULL);
g_print ("%s", s1);
g_free (s1);
g_option_context_free (context);
@@ -82,7 +84,7 @@ parse_cmd (int argc, char* argv[], char **source_dir, char **dst_dir, gboolean *
if (! g_option_context_parse (context, &argc, &argv, &error)) {
g_print ("option parsing failed: %s\n", error->message);
- s1 = g_option_context_get_help (context, TRUE, NULL);
+ s1 = g_option_context_get_help (context, TRUE, NULL);
g_print ("%s", s1);
g_free (s1);
g_option_context_free (context);
@@ -94,6 +96,7 @@ parse_cmd (int argc, char* argv[], char **source_dir, char **dst_dir, gboolean *
*dst_dir = _dst_dir;
*verbose = _verbose;
*jobs = _jobs;
+ *update = _update;
return TRUE;
}
@@ -106,6 +109,7 @@ main(int argc, char* argv[])
char *source_dir;
char *dst_dir;
gboolean verbose;
+ gboolean update;
int jobs;
TGallerySetup *setup;
time_t time_start = time (NULL);
@@ -130,7 +134,7 @@ main(int argc, char* argv[])
/* Parse commandline */
- if (! parse_cmd (argc, argv, &source_dir, &dst_dir, &verbose, &jobs))
+ if (! parse_cmd (argc, argv, &source_dir, &dst_dir, &verbose, &jobs, &update))
return -1;
if ((! source_dir) || (access (source_dir, R_OK))) {
@@ -165,6 +169,7 @@ main(int argc, char* argv[])
/* Start building the gallery tree */
setup->verbose = verbose;
+ setup->update_mode = update;
build_tree (setup, source_dir, dst_dir, NULL, -1, jobs);
if (verbose) {
diff --git a/src/gallery-utils.c b/src/gallery-utils.c
index 8ec258a..29c456d 100644
--- a/src/gallery-utils.c
+++ b/src/gallery-utils.c
@@ -326,3 +326,32 @@ log_error (const gchar *format, ...)
stats_errors_inc ();
}
+
+
+/*
+ * needs_update: returns TRUE if the destionation file needs updating, also when missing
+ */
+gboolean
+needs_update (const char *source, const char *dest)
+{
+ struct stat src_stat;
+ struct stat dst_stat;
+
+ memset (&src_stat, 0, sizeof (src_stat));
+ memset (&dst_stat, 0, sizeof (dst_stat));
+
+ /* if we can't stat the source file, return FALSE to prevent further errors during update */
+ if (stat (source, &src_stat) == -1) {
+ log_error ("needs_update: cannot stat source file \"%s\": %s\n", source, strerror (errno));
+ return FALSE;
+ }
+
+ /* if we can't stat the destination file, we need update anyway */
+ if (stat (dest, &dst_stat) == -1)
+ return TRUE;
+ /* destination file size should not be zero */
+ if (dst_stat.st_size <= 0)
+ return TRUE;
+
+ return (src_stat.st_mtime > dst_stat.st_mtime);
+}
diff --git a/src/gallery-utils.h b/src/gallery-utils.h
index d9c1d8a..85ad35d 100644
--- a/src/gallery-utils.h
+++ b/src/gallery-utils.h
@@ -73,6 +73,11 @@ const char *extract_file_ext (const char *filename);
*/
void log_error (const gchar *format, ...) G_GNUC_PRINTF (1, 2);
+/*
+ * needs_update: returns TRUE if the destionation file needs updating, also when missing
+ */
+gboolean needs_update (const char *source, const char *dest);
+
#ifdef __cplusplus
}
diff --git a/src/generators.c b/src/generators.c
index 0a21b7e..c094e32 100644
--- a/src/generators.c
+++ b/src/generators.c
@@ -38,12 +38,13 @@
/*
* generate_image: generate needed image sizes
*/
-void
+gboolean
generate_image (TGallerySetup *setup,
TAlbum *items,
TIndexItem *item,
unsigned int item_index,
- const char *dst_dir)
+ const char *dst_dir,
+ gboolean update_when_necessary)
{
unsigned long new_w, new_h;
unsigned long thumb_w, thumb_h;
@@ -55,16 +56,18 @@ generate_image (TGallerySetup *setup,
char *thumb_src_full;
char *s1;
int bigq;
+ gboolean res;
item->gen_img_src = NULL;
item->gen_thumb = NULL;
thumb_src_full = NULL;
img_src_full = NULL;
+ orig_dst = NULL;
if (items->type == GALLERY_TYPE_INDEX) {
if (item->thumbnail == NULL || strlen (item->thumbnail) == 0)
- return;
+ return FALSE;
img_src_full = g_strconcat (items->base_dir, "/", item->thumbnail, NULL);
thumb_src_full = g_strconcat (items->base_dir, "/", item->thumbnail, NULL);
item->gen_img_src = g_path_get_basename (item->thumbnail);
@@ -84,89 +87,99 @@ generate_image (TGallerySetup *setup,
g_free (s1);
}
- get_image_sizes (img_src_full, &new_w, &new_h);
-
- if ((new_w > 0) && (new_h > 0)) {
- stats_images_inc ();
- item->gen_portrait = (new_w / new_h) < 1;
-
- /* Generate thumbnail */
- g_assert (thumb_src_full != NULL);
- get_image_sizes (thumb_src_full, &thumb_w, &thumb_h);
- thumb_dst = g_strconcat (dst_dir, "/", setup->thumbnail_dir, "/", item->gen_thumb, NULL);
-
- if ((thumb_w > 0) && (thumb_h > 0)) {
- if (! item->gen_portrait)
- calculate_sizes (setup->thumbnail_landscape_width, setup->thumbnail_landscape_height, &thumb_w, &thumb_h);
- else
- calculate_sizes (setup->thumbnail_portrait_width, setup->thumbnail_portrait_height, &thumb_w, &thumb_h);
- if (! resize_image (thumb_src_full, thumb_dst, thumb_w, thumb_h, setup->thumbnail_quality, TRUE))
- log_error ("generate_image: error resizing thumbnail %s\n", thumb_src_full);
- else
- g_free (thumb_dst);
- } else
- log_error ("generate_image: thumbnail %s sizes are %lux%lu\n", thumb_src_full, thumb_w, thumb_h);
-
-
- /* Generate/copy preview and original image */
- if (items->type == GALLERY_TYPE_ALBUM)
- {
- big_dst = g_strconcat (dst_dir, "/", setup->img_big_dir, "/", item->gen_img_src, NULL);
- if (item->preview == NULL) {
- /* No preview image supplied, generate it from original */
- bigq = setup->preview_quality;
- if ((items->quality > 0) && (items->quality <= 100))
- bigq = items->quality;
- if ((item->quality > 0) && (item->quality <= 100))
- bigq = item->quality;
-
- if ((item->width > 0) && (item->height > 0)) {
- calculate_sizes (item->width, item->height, &new_w, &new_h);
- } else {
- if (! item->gen_portrait)
- {
- if ((items->landscape_width > 0) && (items->landscape_height > 0))
- calculate_sizes (items->landscape_width, items->landscape_height, &new_w, &new_h);
- else
- calculate_sizes (setup->preview_landscape_width, setup->preview_landscape_height, &new_w, &new_h);
- }
- else
- {
- if ((items->portrait_width > 0) && (items->portrait_height > 0))
- calculate_sizes (items->portrait_width, items->portrait_height, &new_w, &new_h);
+ /* Make paths */
+ thumb_dst = g_strconcat (dst_dir, "/", setup->thumbnail_dir, "/", item->gen_thumb, NULL);
+ big_dst = g_strconcat (dst_dir, "/", setup->img_big_dir, "/", item->gen_img_src, NULL);
+ if (item->force_fullsize || (items->fullsize && ! item->force_nofullsize) ||
+ (! item->force_nofullsize && ! items->nofullsize && ! setup->nofullsize))
+ orig_dst = g_strconcat (dst_dir, "/", setup->img_orig_dir, "/", item->gen_img_src, NULL);
+ res = (! update_when_necessary) || needs_update (thumb_src_full, thumb_dst) ||
+ (items->type == GALLERY_TYPE_ALBUM && (needs_update (img_src_full, big_dst) || (orig_dst && needs_update (img_src_full, orig_dst))));
+
+ /* Do something when necessary */
+ if (res) {
+ get_image_sizes (img_src_full, &new_w, &new_h);
+
+ if ((new_w > 0) && (new_h > 0)) {
+ stats_images_inc ();
+ item->gen_portrait = (new_w / new_h) < 1;
+
+ /* Generate thumbnail */
+ g_assert (thumb_src_full != NULL);
+ get_image_sizes (thumb_src_full, &thumb_w, &thumb_h);
+
+ if ((thumb_w > 0) && (thumb_h > 0)) {
+ if (! item->gen_portrait)
+ calculate_sizes (setup->thumbnail_landscape_width, setup->thumbnail_landscape_height, &thumb_w, &thumb_h);
+ else
+ calculate_sizes (setup->thumbnail_portrait_width, setup->thumbnail_portrait_height, &thumb_w, &thumb_h);
+ if (! resize_image (thumb_src_full, thumb_dst, thumb_w, thumb_h, setup->thumbnail_quality, TRUE))
+ log_error ("generate_image: error resizing thumbnail %s\n", thumb_src_full);
+ } else
+ log_error ("generate_image: thumbnail %s sizes are %lux%lu\n", thumb_src_full, thumb_w, thumb_h);
+
+
+ /* Generate/copy preview image */
+ if (items->type == GALLERY_TYPE_ALBUM) {
+ if (item->preview == NULL) {
+ /* No preview image supplied, generate it from original */
+ bigq = setup->preview_quality;
+ if ((items->quality > 0) && (items->quality <= 100))
+ bigq = items->quality;
+ if ((item->quality > 0) && (item->quality <= 100))
+ bigq = item->quality;
+
+ if ((item->width > 0) && (item->height > 0)) {
+ calculate_sizes (item->width, item->height, &new_w, &new_h);
+ } else {
+ if (! item->gen_portrait)
+ {
+ if ((items->landscape_width > 0) && (items->landscape_height > 0))
+ calculate_sizes (items->landscape_width, items->landscape_height, &new_w, &new_h);
+ else
+ calculate_sizes (setup->preview_landscape_width, setup->preview_landscape_height, &new_w, &new_h);
+ }
else
- calculate_sizes (setup->preview_portrait_width, setup->preview_portrait_height, &new_w, &new_h);
+ {
+ if ((items->portrait_width > 0) && (items->portrait_height > 0))
+ calculate_sizes (items->portrait_width, items->portrait_height, &new_w, &new_h);
+ else
+ calculate_sizes (setup->preview_portrait_width, setup->preview_portrait_height, &new_w, &new_h);
+ }
}
+
+ g_assert (img_src_full != NULL);
+ if (! resize_image (img_src_full, big_dst, new_w, new_h, bigq, FALSE))
+ log_error ("generate_image: error resizing big image %s\n", img_src_full);
+ }
+ else
+ {
+ /* Copy the preview (big) image provided */
+ big_src = g_strconcat (items->base_dir, "/", item->preview, NULL);
+ if (! copy_file (big_src, big_dst))
+ log_error ("generate_image: error copying preview image %s\n", big_src);
+ g_free (big_src);
}
+ modify_exif (big_dst, setup->erase_exif_thumbnail, setup->add_copyright);
- g_assert (img_src_full != NULL);
- if (! resize_image (img_src_full, big_dst, new_w, new_h, bigq, FALSE))
- log_error ("generate_image: error resizing big image %s\n", img_src_full);
- }
- else
- {
- /* Copy the preview (big) image provided */
- big_src = g_strconcat (items->base_dir, "/", item->preview, NULL);
- if (! copy_file (big_src, big_dst))
- log_error ("generate_image: error copying preview image %s\n", big_src);
- g_free (big_src);
- }
- modify_exif (big_dst, setup->erase_exif_thumbnail, setup->add_copyright);
- g_free (big_dst);
- if (item->force_fullsize || (items->fullsize && ! item->force_nofullsize) ||
- (! item->force_nofullsize && ! items->nofullsize && ! setup->nofullsize))
- {
- orig_dst = g_strconcat (dst_dir, "/", setup->img_orig_dir, "/", item->gen_img_src, NULL);
- if (! copy_file(img_src_full, orig_dst))
- log_error ("generate_image: error copying original image %s\n", img_src_full);
- modify_exif (orig_dst, setup->erase_exif_thumbnail, setup->add_copyright);
- g_free (orig_dst);
+ /* Generate/copy original image */
+ if (orig_dst) {
+ if (! copy_file (img_src_full, orig_dst))
+ log_error ("generate_image: error copying original image %s\n", img_src_full);
+ else
+ modify_exif (orig_dst, setup->erase_exif_thumbnail, setup->add_copyright);
+ }
}
}
}
g_free (img_src_full);
g_free (thumb_src_full);
+ g_free (big_dst);
+ g_free (thumb_dst);
+ g_free (orig_dst);
+
+ return res;
}
diff --git a/src/generators.h b/src/generators.h
index 584cff3..31636f0 100644
--- a/src/generators.h
+++ b/src/generators.h
@@ -23,11 +23,12 @@
/*
* generate_image: generate needed image sizes
*/
-void generate_image (TGallerySetup *setup,
- TAlbum *items,
- TIndexItem *item,
- unsigned int item_index,
- const char *dst_dir);
+gboolean generate_image (TGallerySetup *setup,
+ TAlbum *items,
+ TIndexItem *item,
+ unsigned int item_index,
+ const char *dst_dir,
+ gboolean update_when_necessary);
/*
* write_html_album: process album and index template files
diff --git a/src/job-manager.c b/src/job-manager.c
index 8344e60..1f37595 100644
--- a/src/job-manager.c
+++ b/src/job-manager.c
@@ -41,6 +41,7 @@ typedef struct {
TGallerySetup *setup;
TAlbum *items;
const char *dst_dir;
+ gboolean force_update;
} TJob;
@@ -51,10 +52,10 @@ mirror_files (TGallerySetup *setup, char **files, const char *src_tree, const ch
{
char **extra;
char *s1, *s2, *s3;
+ int processed = 0;
if (files && g_strv_length (files) > 0) {
extra = files;
- if (setup->verbose) printf ("%s", label);
while (*extra) {
s1 = g_strstrip (*extra);
if (strlen (s1) > 0) {
@@ -70,16 +71,24 @@ mirror_files (TGallerySetup *setup, char **files, const char *src_tree, const ch
g_free (s3);
/* Copy the file */
- if (setup->verbose) printf (" %s", s1);
s2 = g_strconcat (src_tree, "/", s1, NULL);
s3 = g_strconcat (dst_dir, "/", s1, NULL);
- copy_file (s2, s3);
+ if (! setup->update_mode || needs_update (s2, s3)) {
+ if (setup->verbose) {
+ if (processed == 0)
+ printf ("%s", label);
+ printf (" %s", s1);
+ }
+ copy_file (s2, s3);
+ processed++;
+ }
g_free (s2);
g_free (s3);
}
extra++;
}
- if (setup->verbose) printf ("\n");
+ if (setup->verbose && processed > 0)
+ printf ("\n");
}
}
@@ -99,6 +108,7 @@ thread_func (gpointer data)
char *s1, *s2, *s3;
int total, index, real_index;
TJob *job = data;
+ gboolean updated;
do {
item = NULL;
@@ -129,13 +139,16 @@ thread_func (gpointer data)
/* actually do some work */
if (item != NULL) {
imgname = g_path_get_basename ((item->path == NULL && item->preview) ? item->preview : item->path);
- G_LOCK (items_print);
- if (job->setup->verbose)
- g_print (" [%d/%d] Processing item \"%s\"\n", index, total, imgname);
- G_UNLOCK (items_print);
+ updated = generate_image (job->setup, job->items, item, real_index, job->dst_dir, ! job->force_update);
+
+ if (updated) {
+ G_LOCK (items_print);
+ if (job->setup->verbose)
+ g_print (" [%d/%d] Processing item \"%s\"\n", index, total, imgname);
+ G_UNLOCK (items_print);
+ }
- generate_image (job->setup, job->items, item, real_index, job->dst_dir);
- if (job->items->type == GALLERY_TYPE_ALBUM) {
+ if (updated && job->items->type == GALLERY_TYPE_ALBUM) {
s1 = g_strconcat (job->setup->real_templates_dir, "/", job->setup->template_photo, NULL);
s2 = g_strconcat (job->items->base_dir, "/", (item->path == NULL && item->preview) ? item->preview : item->path, NULL);
s3 = g_strconcat (job->dst_dir, "/", imgname, GET_EXT (job->setup->index_file_name), NULL);
@@ -181,12 +194,14 @@ build_tree (TGallerySetup *setup,
char *img_big_dir;
char *img_orig_dir;
char *template;
+ char *dst_album_file;
gboolean res;
int i;
TJob *job;
GError *error;
GThread *thread;
GList *thread_list;
+ gboolean force_update;
printf ("Processing directory \"%s\"\n", src_tree);
stats_dirs_inc ();
@@ -223,10 +238,14 @@ build_tree (TGallerySetup *setup,
free_album_data (items);
return FALSE;
}
- g_free (idx_file);
items->parent_index = parent_index;
items->parent_item_index = parent_item_index;
+ /* Check if update is necessary */
+ dst_album_file = g_strconcat (dst_dir, "/", setup->index_file_name, NULL);
+ force_update = (! setup->update_mode || needs_update (idx_file, dst_album_file));
+ g_free (idx_file);
+
/* Copy support files */
if (! setup->support_files_use_common_root || parent_index == NULL) {
/* copy only if we're in root level or old-style is active */
@@ -234,11 +253,13 @@ build_tree (TGallerySetup *setup,
/* favicon */
if (setup->favicon_file && strlen (setup->favicon_file) > 0) {
- if (setup->verbose) printf (" Copying favicon: %s\n", setup->favicon_file);
s3 = g_path_get_dirname (setup->setup_xml_path);
s1 = g_strconcat (s3, "/", setup->favicon_file, NULL);
s2 = g_strconcat (dst_dir, "/", setup->favicon_file, NULL);
- copy_file (s1, s2);
+ if (! setup->update_mode || needs_update (s1, s2)) {
+ if (setup->verbose) printf (" Copying favicon: %s\n", setup->favicon_file);
+ copy_file (s1, s2);
+ }
g_free (s1);
g_free (s2);
g_free (s3);
@@ -251,6 +272,7 @@ build_tree (TGallerySetup *setup,
if (g_mkdir_with_parents (thumb_dir, DEFAULT_DATA_DIR_MODE)) {
log_error ("error making target thumbnail directory: %s\n", strerror (errno));
g_free (thumb_dir);
+ g_free (dst_album_file);
free_album_data (items);
return FALSE;
}
@@ -275,6 +297,7 @@ build_tree (TGallerySetup *setup,
g_free (img_big_dir);
g_free (img_orig_dir);
if (! res) {
+ g_free (dst_album_file);
free_album_data (items);
return FALSE;
}
@@ -285,6 +308,7 @@ build_tree (TGallerySetup *setup,
job->items = items;
job->setup = setup;
job->dst_dir = dst_dir;
+ job->force_update = force_update;
#ifdef G_THREADS_ENABLED
thread_list = NULL;
@@ -315,33 +339,33 @@ build_tree (TGallerySetup *setup,
g_free (job);
- /* Start generating items */
- if (items->type == GALLERY_TYPE_INDEX)
- template = g_strconcat ("/", setup->template_index, NULL);
- else
- if (items->type == GALLERY_TYPE_ALBUM)
- template = g_strconcat ("/", setup->template_album, NULL);
- else
- /* default to album */
- template = g_strconcat ("/", setup->template_album, NULL);
-
- if (setup->verbose) printf (" Writing %s\n", setup->index_file_name);
- s1 = g_strconcat (setup->real_templates_dir, template, NULL);
- s2 = g_strconcat (dst_dir, "/", setup->index_file_name, NULL);
- res = write_html_album (setup, s1, s2, items);
- g_free (s1);
- g_free (s2);
- g_free (template);
- if (! res) {
- log_error ("error generating target index file\n");
- free_album_data (items);
- return FALSE;
+ /* Generate album page */
+ if (force_update) {
+ if (items->type == GALLERY_TYPE_INDEX)
+ template = g_strconcat ("/", setup->template_index, NULL);
+ else
+ if (items->type == GALLERY_TYPE_ALBUM)
+ template = g_strconcat ("/", setup->template_album, NULL);
+ else
+ /* default to album */
+ template = g_strconcat ("/", setup->template_album, NULL);
+
+ if (setup->verbose) printf (" Writing %s\n", setup->index_file_name);
+ s1 = g_strconcat (setup->real_templates_dir, template, NULL);
+ res = write_html_album (setup, s1, dst_album_file, items);
+ g_free (s1);
+ g_free (template);
+ if (! res) {
+ log_error ("error generating target index file\n");
+ free_album_data (items);
+ return FALSE;
+ }
}
+ g_free (dst_album_file);
/* Recurse to sub-albums (in case of album index) */
- if (items->type == GALLERY_TYPE_INDEX)
- {
+ if (items->type == GALLERY_TYPE_INDEX) {
if (items->items->len > 0) {
for (i = 0; i < items->items->len; i++) {
item = g_ptr_array_index (items->items, i);
diff --git a/src/setup.h b/src/setup.h
index 4cd2629..2356620 100644
--- a/src/setup.h
+++ b/src/setup.h
@@ -35,6 +35,7 @@
/* Global gallery setup */
typedef struct {
gboolean verbose;
+ gboolean update_mode;
char *real_templates_dir;
char *setup_xml_path;