diff options
| -rw-r--r-- | src/cgg.c | 15 | ||||
| -rw-r--r-- | src/gallery-utils.c | 29 | ||||
| -rw-r--r-- | src/gallery-utils.h | 5 | ||||
| -rw-r--r-- | src/generators.c | 165 | ||||
| -rw-r--r-- | src/generators.h | 11 | ||||
| -rw-r--r-- | src/job-manager.c | 96 | ||||
| -rw-r--r-- | src/setup.h | 1 |
7 files changed, 200 insertions, 122 deletions
@@ -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; |
