/* Cataract - Static web photo gallery generator * Copyright (C) 2008 Tomas Bzatek * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; either version 2 * of the License, or any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #include #include #include #include #include #include #include #include "config.h" #include "setup.h" #include "items.h" #include "jpeg-utils.h" #include "gallery-utils.h" /* * generate_image: auxiliary function for write_html_album * - img_src and thumb should be freed afterwards */ void generate_image (TGallerySetup *setup, TAlbum *items, TIndexItem *item, const char *dst, unsigned long *img_w, unsigned long *img_h, char **img_src, char **thumb) { unsigned long new_w, new_h; unsigned long thumb_w, thumb_h; char *thumb_dst; char *big_dst; char *big_src; char *orig_dst; char *img_src_full; char *thumb_src_full; char *s1; int bigq; *img_src = NULL; *thumb = NULL; *img_w = 0; *img_h = 0; if (items->type == GALLERY_TYPE_INDEX) { if (item->thumbnail == NULL || strlen (item->thumbnail) == 0) return; img_src_full = g_strconcat (items->base_dir, "/", item->thumbnail, NULL); thumb_src_full = g_strconcat (items->base_dir, "/", item->thumbnail, NULL); *img_src = g_path_get_basename (item->thumbnail); *thumb = g_path_get_basename (item->thumbnail); } else if (items->type == GALLERY_TYPE_ALBUM) { *img_src = (item->path == NULL && item->preview) ? item->preview : item->path; *thumb = (item->thumbnail) ? item->thumbnail : *img_src; img_src_full = g_strconcat (items->base_dir, "/", *img_src, NULL); thumb_src_full = g_strconcat (items->base_dir, "/", *thumb, NULL); *img_src = g_path_get_basename (*img_src); *thumb = g_path_get_basename (*thumb); } get_image_sizes (img_src_full, img_w, img_h); if ((img_w > 0) && (img_h > 0)) { new_w = *img_w; new_h = *img_h; /* Generate thumbnail */ get_image_sizes (thumb_src_full, &thumb_w, &thumb_h); s1 = g_path_get_dirname (dst); thumb_dst = g_strconcat (s1, "/", THUMBNAIL_DIR, "/", *thumb, NULL); g_free (s1); if (setup->verbose) printf (" Generating thumbnail of '%s' ...", *thumb); if ((thumb_w > 0) && (thumb_h > 0)) { if ((thumb_w / thumb_h) >= 1) 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)) fprintf (stderr, "write_html_index: error resizing thumbnail %s\n", thumb_src_full); else if (setup->verbose) printf (" done.\n"); g_free (thumb_dst); } else printf (" failed!\n"); /* Generate/copy preview and original image */ if (items->type == GALLERY_TYPE_ALBUM) { s1 = g_path_get_dirname (dst); big_dst = g_strconcat (s1, "/", IMG_BIG_DIR, "/", *img_src, NULL); g_free (s1); 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; new_w = *img_w; new_h = *img_h; if (setup->verbose) printf (" Generating preview of '%s' ...", *img_src); if ((item->width > 0) && (item->height > 0)) { calculate_sizes (item->width, item->height, &new_w, &new_h); } else { if ((*img_w / *img_h) >= 1) { 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); else calculate_sizes (setup->preview_portrait_width, setup->preview_portrait_height, &new_w, &new_h); } } if (! resize_image (img_src_full, big_dst, new_w, new_h, bigq)) fprintf (stderr, "write_html_index: error resizing big image %s\n", img_src_full); else if (setup->verbose) printf (" done.\n"); } else { /* Copy the preview (big) image provided */ big_src = g_strconcat (items->base_dir, "/", item->preview, NULL); if (setup->verbose) printf (" Copying preview image '%s' ...", *img_src); if (! copy_file (big_src, big_dst)) fprintf (stderr, "write_html_index: error copying preview image %s\n", big_src); else if (setup->verbose) printf (" done.\n"); g_free (big_src); } g_free (big_dst); if (! item->nofullsize) { s1 = g_path_get_dirname(dst); orig_dst = g_strconcat (s1, "/", IMG_ORIG_DIR, "/", *img_src, NULL); g_free (s1); if (setup->verbose) printf (" Copying original image '%s' ...", *img_src); if (! copy_file(img_src_full, orig_dst)) fprintf (stderr, "write_html_index: error copying original image %s\n", img_src_full); else if (setup->verbose) printf(" done.\n"); g_free (orig_dst); } } } g_free (img_src_full); g_free (thumb_src_full); } /* * write_html_album: process album and index template files * * template_src = template file of the album/index * dst = save generated file as * items = array of items in the album/index * */ gboolean write_html_album (TGallerySetup *setup, const char *template_src, const char *dst, TAlbum *items) { #define BUFFER_SIZE 65536 FILE *fin; FILE *fout; char *buffer; char *buf_img_list_landscape; char *buf_img_list_portrait; char *buf_img_separator; char *buf_go_up_string; gboolean in_img_list; gboolean in_img_list_landscape; gboolean in_img_list_portrait; gboolean in_img_separator; gboolean in_go_up_string; char *b; char *s1, *s2, *s3, *s4; TAlbum *parent; TIndexItem *item; TIndexItem *tmp_item; int level; gboolean res; int i; unsigned long img_w, img_h; char *img_src; char *thumb; unsigned int real_total_items; fin = fopen (template_src, "r"); if (fin == NULL) { fprintf (stderr, "write_html_index: error reading file \"%s\": %s\n", template_src, strerror (errno)); return FALSE; } fout = fopen (dst, "w"); if (fout == NULL) { fprintf (stderr, "write_html_index: error writing to file \"%s\": %s\n", dst, strerror (errno)); fclose (fin); return FALSE; } buffer = malloc (BUFFER_SIZE); buf_img_list_landscape = malloc (BUFFER_SIZE); buf_img_list_portrait = malloc (BUFFER_SIZE); buf_img_separator = malloc (BUFFER_SIZE); buf_go_up_string = malloc (BUFFER_SIZE); in_img_list = FALSE; in_img_list_landscape = FALSE; in_img_list_portrait = FALSE; in_img_separator = FALSE; in_go_up_string = FALSE; res = TRUE; /* Get number of real pictures in the list */ real_total_items = 0; for (i = 0; i < items->items->len; i++) { tmp_item = g_ptr_array_index (items->items, i); if (tmp_item->type == INDEX_ITEM_TYPE_PICTURE) real_total_items++; } /* Read through the template and replace placeholders with real data */ while (! feof (fin)) { memset (buffer, 0, BUFFER_SIZE); if (! fgets (buffer, BUFFER_SIZE, fin)) break; if (buffer == NULL) continue; b = strdup (buffer); /* Block placeholders */ if (in_img_list && (strstr (buffer, ""))) { in_img_list_landscape = TRUE; free (b); continue; } if (in_img_list && (strstr (buffer, ""))) { in_img_list_landscape = FALSE; free (b); continue; } if (in_img_list && (strstr (buffer, ""))) { in_img_list_portrait = TRUE; free (b); continue; } if (in_img_list && (strstr (buffer, ""))) { in_img_list_portrait = FALSE; free (b); continue; } if (in_img_list && (strstr (buffer, ""))) { in_img_separator = TRUE; free (b); continue; } if (in_img_list && (strstr (buffer, ""))) { in_img_separator = FALSE; free (b); continue; } if (in_img_list && in_img_list_landscape) { buf_img_list_landscape = strncat (buf_img_list_landscape, b, BUFFER_SIZE - strlen (buf_img_list_landscape) - 2); free (b); continue; } if (in_img_list && in_img_list_portrait) { buf_img_list_portrait = strncat (buf_img_list_portrait, b, BUFFER_SIZE - strlen (buf_img_list_portrait) - 2); free (b); continue; } if (in_img_list && in_img_separator) { buf_img_separator = strncat (buf_img_separator, b, BUFFER_SIZE - strlen (buf_img_separator) - 2); free (b); continue; } if (strstr (buffer, "")) { memset (buf_go_up_string, 0, BUFFER_SIZE); in_go_up_string = TRUE; free (b); continue; } if (in_go_up_string && (strstr (buffer, ""))) { in_go_up_string = FALSE; free (b); /* print the "Go Up" string if not toplevel */ if (items->parent_index) b = strdup (buf_go_up_string); else continue; } if (in_go_up_string) { buf_go_up_string = strncat (buf_go_up_string, b, BUFFER_SIZE - strlen (buf_go_up_string) - 2); free (b); continue; } /* Simple placeholders */ if (strstr (b, "") && items->ID) { s1 = g_strdup (items->ID); fix_entities (&s1); str_replace (&b, "", s1, NULL); g_free (s1); } if (strstr (b, "") && items->title) { s1 = g_strdup (items->title); fix_entities (&s1); str_replace (&b, "", s1, NULL); g_free (s1); } if (strstr (b, "") && items->desc) { s1 = g_strdup (items->desc); fix_entities (&s1); str_replace (&b, "", s1, NULL); g_free (s1); } if (strstr (b, "") && items->footnote) { s1 = g_strdup (items->footnote); fix_entities (&s1); str_replace (&b, "", s1, NULL); g_free (s1); } if (strstr (b, "") && setup->footer) { s1 = g_strdup (setup->footer); fix_entities (&s1); str_replace (&b, "", s1, NULL); g_free (s1); } if (strstr (b, "")) { s1 = g_strdup_printf ("\t\n", APP_VERSION); if (setup->meta_author) { s2 = g_strdup_printf ("%s\t\n", s1, setup->meta_author); g_free (s1); s1 = s2; } if (setup->meta_description) { s2 = g_strdup_printf ("%s\t\n", s1, setup->meta_description); g_free (s1); s1 = s2; } if (setup->meta_keywords) { s2 = g_strdup_printf ("%s\t\n", s1, setup->meta_keywords); g_free (s1); s1 = s2; } str_replace (&b, "", s1, NULL); g_free (s1); } if (strstr (b, "")) { s1 = g_strdup_printf ("%d", real_total_items); str_replace (&b, "", s1, NULL); g_free (s1); } if (strstr (b, "")) { s1 = g_strdup (items->ID); fix_entities (&s1); parent = items->parent_index; level = 1; while (parent) { s3 = make_string ("../", level); s4 = g_strdup (parent->ID); fix_entities (&s4); s2 = g_strconcat ("", s4, " > ", s1, NULL); free (s3); g_free (s1); g_free (s4); s1 = s2; parent = parent->parent_index; level++; } str_replace (&b, "", s1, NULL); g_free (s1); } /* Image list, nested placeholders */ if (strstr (buffer, "")) { memset (buf_img_list_landscape, 0, BUFFER_SIZE); memset (buf_img_list_portrait, 0, BUFFER_SIZE); memset (buf_img_separator, 0, BUFFER_SIZE); in_img_list = TRUE; in_img_list_landscape = FALSE; in_img_list_portrait = FALSE; in_img_separator = FALSE; free (b); continue; } if (in_img_list && (strstr (buffer, ""))) { in_img_list = FALSE; in_img_list_landscape = FALSE; in_img_list_portrait = FALSE; /* Now we have all block placeholders read, generate the items: */ for (i = 0; i < items->items->len; i++) { item = g_ptr_array_index (items->items, i); if (item == NULL) { fprintf (stderr, "write_html_index: error getting item %d\n", i); free (b); continue; } /* Generate the images (preview, original, thumbnail) */ img_w = 0; img_h = 0; img_src = NULL; thumb = NULL; switch (item->type) { case INDEX_ITEM_TYPE_PICTURE: generate_image (setup, items, item, dst, &img_w, &img_h, &img_src, &thumb); /* Process HTML box code */ if (img_w == 0 || img_h == 0 || (img_w / img_h) >= 1) s1 = strdup (buf_img_list_landscape); else s1 = strdup (buf_img_list_portrait); if (strstr (s1, "")) { s2 = g_strconcat (item->path, "/index.html", NULL); str_replace (&s1, "", s2, NULL); g_free (s2); } if (strstr (s1, "")) { s2 = g_strconcat (img_src, ".html", NULL); str_replace (&s1, "", s2, NULL); g_free (s2); } if (strstr (s1, "") && item->title) { s2 = g_strdup (item->title); fix_entities (&s2); str_replace (&s1, "", s2, NULL); g_free (s2); } if (strstr (s1, "") && item->title_description) { s2 = g_strdup (item->title_description); fix_entities (&s2); str_replace (&s1, "", s2, NULL); g_free (s2); } if (strstr(s1, "")) { s3 = g_strconcat (items->base_dir, "/", item->path, "/index.xml", NULL); s2 = g_strdup_printf ("%d", get_album_objects_count(s3)); str_replace (&s1, "", s2, NULL); g_free (s2); g_free (s3); } if (strstr (s1, "")) { s2 = g_strconcat (THUMBNAIL_DIR, "/", thumb, NULL); str_replace (&s1, "", s2, NULL); g_free (s2); } if (strstr (s1, "")) str_replace (&s1, "", img_src, NULL); break; case INDEX_ITEM_TYPE_SEPARATOR: s1 = strdup (buf_img_separator); if (strstr (s1, "") && item->title) { s2 = g_strdup (item->title); fix_entities (&s2); str_replace (&s1, "", s2, NULL); g_free (s2); } break; } #ifdef __DEBUG_ALL__ printf("***** %s ******\n", s1); #endif if (! fputs (s1, fout)) { fprintf (stderr, "write_html_index: error writing to file \"%s\": %s\n", dst, strerror (errno)); res = FALSE; free (s1); break; } free (s1); if (img_src) g_free (img_src); if (thumb) g_free (thumb); } free (b); continue; /* no need to write anything */ } /* Write the generated string to target file */ if (! fputs (b, fout)) { fprintf (stderr, "write_html_index: error writing to file \"%s\": %s\n", dst, strerror (errno)); res = FALSE; free (b); break; } free (b); } fclose (fout); fclose (fin); free (buffer); free (buf_img_list_landscape); free (buf_img_list_portrait); free (buf_img_separator); free (buf_go_up_string); return res; } /* * write_html_image: process single image template file * * template_src = template file of the album/index * original_img = source image file (original full-size) to get EXIF data from * dst = save generated file as * item = data for the current item * parent_items = array of items in the album, to determine our position and make links to previous/next image * */ gboolean write_html_image (TGallerySetup *setup, const char *template_src, const char *original_img, const char *dst, TIndexItem *item, TAlbum *parent_items) { #define BUFFER_SIZE 65536 FILE *fin; FILE *fout; char *buffer; char *big_dst; char *orig_dst; char *buf_img_fullsize_link; gboolean in_img_fullsize_link; TExifData *exif; unsigned long img_big_w, img_big_h, img_orig_w, img_orig_h; unsigned int item_index, real_item_index, real_total_items; TIndexItem *previous_item; TIndexItem *next_item; TIndexItem *tmp_item; TAlbum *parent; int i; char *s1, *s2, *s3, *s4; char *imgname; char *b; gboolean res; int level; fin = fopen (template_src, "r"); if (fin == NULL) { fprintf (stderr, "write_html_image: error reading file \"%s\": %s\n", template_src, strerror (errno)); return FALSE; } fout = fopen (dst, "w"); if (fout == NULL) { fprintf (stderr, "write_html_image: error writing to file \"%s\": %s\n", dst, strerror (errno)); fclose (fin); return FALSE; } buffer = malloc (BUFFER_SIZE); s1 = g_path_get_dirname (dst); imgname = (item->path == NULL && item->preview) ? g_path_get_basename (item->preview) : g_strdup (item->path); big_dst = g_strconcat (s1, "/", IMG_BIG_DIR, "/", imgname, NULL); orig_dst = g_strconcat (s1, "/", IMG_ORIG_DIR, "/", imgname, NULL); g_free (s1); buf_img_fullsize_link = malloc (BUFFER_SIZE); memset (buf_img_fullsize_link, 0, BUFFER_SIZE); in_img_fullsize_link = FALSE; res = TRUE; /* Get EXIF data from the original image */ if (get_exif (original_img, &exif)) fprintf (stderr, "write_html_image: error getting exif data from file \"%s\"\n", orig_dst); /* Retrieve image sizes of preview and original image */ get_image_sizes (big_dst, &img_big_w, &img_big_h); if (! item->nofullsize) get_image_sizes (orig_dst, &img_orig_w, &img_orig_h); /* Get our index in the album */ item_index = 0; real_item_index = 0; real_total_items = 0; for (i = 0; i < parent_items->items->len; i++) { tmp_item = g_ptr_array_index (parent_items->items, i); if (tmp_item->type == INDEX_ITEM_TYPE_PICTURE) { if (! item_index) real_item_index++; real_total_items++; } if (tmp_item == item) item_index = i + 1; } /* Get previous and next items */ previous_item = NULL; next_item = NULL; for (i = item_index - 2; i >= 0 && (previous_item == NULL || previous_item->type != INDEX_ITEM_TYPE_PICTURE); i--) previous_item = g_ptr_array_index (parent_items->items, i); if (previous_item && previous_item->type != INDEX_ITEM_TYPE_PICTURE) previous_item = NULL; for (i = item_index; item_index < parent_items->items->len && (next_item == NULL || next_item->type != INDEX_ITEM_TYPE_PICTURE); i++) next_item = g_ptr_array_index (parent_items->items, i); if (next_item && next_item->type != INDEX_ITEM_TYPE_PICTURE) next_item = NULL; /* Read through the template and replace placeholders with real data */ while (! feof (fin)) { memset (buffer, 0, BUFFER_SIZE); if (! fgets (buffer, BUFFER_SIZE, fin)) break; b = strdup (buffer); /* Block placeholders */ if (strstr (buffer, "")) { in_img_fullsize_link = TRUE; free (b); continue; } if (strstr (buffer, "")) { in_img_fullsize_link = FALSE; free (b); if (! item->nofullsize) b = strdup (buf_img_fullsize_link); else continue; } if (in_img_fullsize_link) { buf_img_fullsize_link = strncat (buf_img_fullsize_link, b, BUFFER_SIZE - strlen (buf_img_fullsize_link) - 2); free (b); continue; } /* Simple placeholders */ if (strstr (b, "")) str_replace (&b, "", imgname, NULL); if (strstr (b, "") && item->title) { s1 = g_strdup (item->title); fix_entities (&s1); str_replace (&b, "", s1, NULL); g_free (s1); } if (strstr (b, "") && item->title_description) { s1 = g_strdup (item->title_description); fix_entities (&s1); str_replace (&b, "", s1, NULL); g_free (s1); } if (strstr (b, "")) { s1 = g_strdup_printf ("%d", real_total_items); str_replace (&b, "", s1, NULL); g_free (s1); } if (strstr (b, "")) { s1 = g_strdup_printf ("%d", real_item_index); str_replace(&b, "", s1, NULL); g_free (s1); } if (strstr (b, "")) { // s1 = g_strconcat (item->title, " (", imgname, ")", NULL); s1 = g_strdup (imgname); parent = parent_items; level = 0; while (parent) { s3 = make_string ("../", level); s4 = g_strdup (parent->ID); fix_entities (&s4); s2 = g_strconcat ("", s4, " > ", s1, NULL); free (s3); g_free (s1); g_free (s4); s1 = s2; parent = parent->parent_index; level++; } str_replace (&b, "", s1, NULL); g_free (s1); } if (strstr (b, "")) { s1 = g_strconcat (IMG_BIG_DIR, "/", imgname, NULL); str_replace (&b, "", s1, NULL); g_free (s1); } if (strstr (b, "")) { s1 = g_strconcat (IMG_ORIG_DIR, "/", imgname, NULL); str_replace (&b, "", s1, NULL); g_free (s1); } if (strstr (b, "")) { s1 = g_strdup_printf ("%lu", img_big_w); str_replace (&b, "", s1, NULL); g_free (s1); } if (strstr (b, "")) { s1 = g_strdup_printf ("%lu", img_big_h); str_replace (&b, "", s1, NULL); g_free (s1); } if (strstr (b, "")) { s1 = g_strdup_printf ("%lu", img_orig_w); str_replace (&b, "", s1, NULL); g_free (s1); } if (strstr (b, "")) { s1 = g_strdup_printf ("%lu", img_orig_h); str_replace (&b, "", s1, NULL); g_free (s1); } if (strstr (b, "")) { s1 = item->border_style; if (s1 == NULL) s1 = parent_items->border_style; if (s1 == NULL) s1 = setup->border_style; if (s1 == NULL) s1 = "border_single"; str_replace (&b, "", s1, NULL); } if (strstr (b, "")) { if (exif->iso) str_replace (&b, "", exif->iso, NULL); else str_replace (&b, "", "??", NULL); } if (strstr (b, "")) { if (exif->exposure) str_replace (&b, "", exif->exposure, NULL); else str_replace (&b, "", "??", NULL); } if (strstr (b, "")) { if (exif->aperture) str_replace (&b, "", exif->aperture, NULL); else str_replace (&b, "", "??", NULL); } if (strstr (b, "")) { if (exif->focal_length) str_replace (&b, "", exif->focal_length, NULL); else str_replace (&b, "", "??", NULL); } if (strstr (b, "")) { if (exif->flash) str_replace (&b, "", exif->flash, NULL); else str_replace (&b, "", "??", NULL); } if (strstr (b, "")) { if (exif->datetime) str_replace (&b, "", exif->datetime, NULL); else str_replace (&b, "", "??", NULL); } if (strstr (b, "")) { if (exif->camera_model) str_replace (&b, "", exif->camera_model, NULL); else str_replace (&b, "", "??", NULL); } if (strstr (b, "")) { if (exif->focal_length_35mm) { s1 = g_strconcat ("(", exif->focal_length_35mm, ")", NULL); str_replace (&b, "", s1, NULL); g_free (s1); } else str_replace (&b, "", "", NULL); } if (strstr (b, "")) { if (next_item) { s2 = (next_item->path == NULL && next_item->preview) ? g_path_get_basename (next_item->preview) : g_strdup (next_item->path); s1 = g_strconcat (s2, ".html", NULL); str_replace (&b, "", s1, NULL); g_free (s1); g_free (s2); } else str_replace (&b, "", "index.html", NULL); } if (strstr(b, "")) { if (previous_item) { s2 = (previous_item->path == NULL && previous_item->preview) ? g_path_get_basename (previous_item->preview) : g_strdup (previous_item->path); s1 = g_strconcat (s2, ".html", NULL); str_replace (&b, "", s1, NULL); g_free (s1); g_free (s2); } else str_replace (&b, "", "index.html", NULL); } if (strstr (b, "") && setup->footer) { s1 = g_strdup (setup->footer); fix_entities (&s1); str_replace (&b, "", s1, NULL); g_free (s1); } if (strstr (b, "")) { s1 = g_strdup_printf ("\t\n", APP_VERSION); if (setup->meta_author) { s2 = g_strdup_printf ("%s\t\t\n", s1, setup->meta_author); g_free (s1); s1 = s2; } if (setup->meta_description) { s2 = g_strdup_printf ("%s\t\n", s1, setup->meta_description); g_free (s1); s1 = s2; } if (setup->meta_keywords) { s2 = g_strdup_printf ("%s\t\n", s1, setup->meta_keywords); g_free (s1); s1 = s2; } str_replace (&b, "", s1, NULL); g_free (s1); } if (! fputs (b, fout)) { fprintf (stderr, "write_html_image: error writing to file \"%s\": %s\n", dst, strerror (errno)); res = FALSE; free (b); break; } free (b); } fclose (fout); fclose (fin); free (buffer); free (big_dst); free (orig_dst); free (buf_img_fullsize_link); g_free (imgname); free_exif_data (exif); return res; } /* * build_tree: generate complete gallery tree based on source xml files * * src_tree = source directory of the items * dst_dir = destination of the generated items * parent_index = parent album to determine our descent in the tree * */ gboolean build_tree (TGallerySetup *setup, const char *src_tree, const char *dst_dir, TAlbum *parent_index) { char *idx_file; TAlbum *items; TIndexItem *item; char *s1, *s2, *s3; char *thumb_dir; char *img_big_dir; char *img_orig_dir; char *template; char *imgname; gboolean res; int i; printf ("*** Entering directory '%s'\n", src_tree); #ifdef __DEBUG_ALL__ printf ("setup->real_templates_dir = %s\n", setup->real_templates_dir); #endif /* Check access permissions */ if (access (src_tree, R_OK)) { fprintf (stderr, "error accessing source directory: %s\n", strerror (errno)); return FALSE; } if (access (dst_dir, R_OK | W_OK | X_OK)) { if (mkdir (dst_dir, S_IRUSR | S_IWUSR | S_IXUSR | S_IRGRP | S_IXGRP | S_IROTH | S_IXOTH)) { fprintf (stderr, "error creating destination directory: %s\n", strerror (errno)); return FALSE; } } /* Check the index file */ idx_file = g_strconcat (src_tree, "/index.xml", NULL); if (access (idx_file, R_OK)) { fprintf (stderr, "error accessing index file '%s': %s\n", idx_file, strerror (errno)); g_free (idx_file); return FALSE; } /* Read the index file and fill items array */ items = malloc (sizeof (TAlbum)); memset (items, 0, sizeof (TAlbum)); if (! parse_album_xml (idx_file, items)) { fprintf (stderr, "error reading index file '%s'\n", idx_file); g_free (idx_file); free_album_data (items); return FALSE; } g_free (idx_file); items->parent_index = parent_index; /* Copy support files */ if (setup->verbose) printf ("Writing '%s' ...", setup->styles); s1 = g_strconcat (setup->real_templates_dir, "/", setup->styles, NULL); s2 = g_strconcat (dst_dir, "/", setup->styles, NULL); copy_file (s1, s2); g_free (s1); g_free (s2); if (setup->verbose) printf (" done.\n"); if (setup->verbose) printf ("Writing '%s' ...", setup->scripts); s1 = g_strconcat (setup->real_templates_dir, "/", setup->scripts, NULL); s2 = g_strconcat (dst_dir, "/", setup->scripts, NULL); copy_file (s1, s2); g_free (s1); g_free (s2); if (setup->verbose) printf (" done.\n"); /* Prepare target thumbnail directory */ thumb_dir = g_strconcat (dst_dir, "/", THUMBNAIL_DIR, NULL); if (access (thumb_dir, R_OK | W_OK | X_OK)) if (mkdir (thumb_dir, S_IRUSR | S_IWUSR | S_IXUSR | S_IRGRP | S_IXGRP | S_IROTH | S_IXOTH)) { fprintf (stderr, "error making target thumbnail directory: %s\n", strerror (errno)); g_free (thumb_dir); free_album_data (items); return FALSE; } g_free (thumb_dir); /* Prepare target preview and orig directories */ if (items->type == GALLERY_TYPE_ALBUM) { res = TRUE; img_big_dir = g_strconcat (dst_dir, "/", IMG_BIG_DIR, NULL); img_orig_dir = g_strconcat (dst_dir, "/", IMG_ORIG_DIR, NULL); if (access (img_big_dir, R_OK | W_OK | X_OK)) if (mkdir (img_big_dir, S_IRUSR | S_IWUSR | S_IXUSR | S_IRGRP | S_IXGRP | S_IROTH | S_IXOTH)) { fprintf (stderr, "error making target preview directory: %s\n", strerror (errno)); res = FALSE; } if (access (img_orig_dir, R_OK | W_OK | X_OK)) if (mkdir (img_orig_dir, S_IRUSR | S_IWUSR | S_IXUSR | S_IRGRP | S_IXGRP | S_IROTH | S_IXOTH)) { fprintf (stderr, "error making target full size directory: %s\n", strerror (errno)); res = FALSE; } g_free (img_big_dir); g_free (img_orig_dir); if (! res) { free_album_data (items); return FALSE; } } /* 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); if (setup->verbose) printf ("Writing 'index.html' ...\n"); s1 = g_strconcat (setup->real_templates_dir, template, NULL); s2 = g_strconcat (dst_dir, "/index.html", NULL); res = write_html_album (setup, s1, s2, items); g_free (s1); g_free (s2); g_free (template); if (! res) { fprintf (stderr, "error generating target index file\n"); free_album_data (items); return FALSE; } if (setup->verbose) printf (" done.\n"); /* Recurse to sub-albums (in case of album 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); if (item == NULL) { fprintf (stderr, "build_tree: error getting item %d\n", i); continue; } if (item->type == INDEX_ITEM_TYPE_PICTURE) { s1 = g_strconcat (src_tree, "/", item->path, "/", NULL); s2 = g_strconcat (dst_dir, "/", item->path, "/", NULL); build_tree (setup, s1, s2, items); g_free (s1); g_free (s2); } } } } /* Generate separate image pages (in case of album) */ if (items->type == GALLERY_TYPE_ALBUM) { if (items->items->len > 0) { for (i = 0; i < items->items->len; i++) { item = g_ptr_array_index (items->items, i); if (item == NULL) { fprintf (stderr, "build_tree: error getting item %d\n", i); continue; } if (item->type == INDEX_ITEM_TYPE_PICTURE) { imgname = (item->path == NULL && item->preview) ? g_path_get_basename (item->preview) : g_strdup (item->path); if (setup->verbose) printf ("Writing '%s.html' ...", imgname); s1 = g_strconcat (setup->real_templates_dir, "/", setup->template_photo, NULL); s2 = g_strconcat (items->base_dir, "/", (item->path == NULL && item->preview) ? item->preview : item->path, NULL); s3 = g_strconcat (dst_dir, "/", imgname, ".html", NULL); res = write_html_image (setup, s1, s2, s3, item, items); g_free (s1); g_free (s2); g_free (s3); g_free (imgname); if (! res ) continue; if (setup->verbose) printf (" done.\n"); } } } } printf ("*** Leaving directory '%s'\n", src_tree); free_album_data (items); return TRUE; }