summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--sample/src/setup.xml51
-rw-r--r--src/cgg.c15
-rw-r--r--src/gallery-utils.h1
-rw-r--r--src/generators.c564
-rw-r--r--src/generators.h4
-rw-r--r--src/items.c33
-rw-r--r--src/items.h21
-rw-r--r--src/job-manager.c178
-rw-r--r--src/setup.c348
-rw-r--r--src/setup.h125
-rw-r--r--templates/Makefile.am7
-rw-r--r--templates/default.xml97
-rw-r--r--templates/template_album.html (renamed from templates/template-album.tmpl)0
-rw-r--r--templates/template_index.html (renamed from templates/template-index.tmpl)0
-rw-r--r--templates/template_picture.html (renamed from templates/template-view_photo.tmpl)2
15 files changed, 903 insertions, 543 deletions
diff --git a/sample/src/setup.xml b/sample/src/setup.xml
index 72ce9dd..63f9caf 100644
--- a/sample/src/setup.xml
+++ b/sample/src/setup.xml
@@ -1,44 +1,16 @@
<?xml version="1.0" encoding="utf-8"?>
<gallery_setup>
- <templates>
- <!-- path to templates (design) -->
- <path>../../templates</path>
-
- <!-- index: top level page -->
- <index>template-index.tmpl</index>
- <!-- album: list of photos in directory -->
- <album>template-album.tmpl</album>
- <!-- photo: single photo page -->
- <photo>template-view_photo.tmpl</photo>
-
- <!-- support files for selected theme (templates) -->
- <!-- should include all used CSS styles, images, scripts... -->
- <!-- subdirectories are allowed and will be mirrored to destination -->
- <template_files><![CDATA[
- styles.css
- scripts-general.js
- ]]></template_files>
-
- <!-- specify index file name to use (default = index.html) -->
- <!-- e.g. you may want 'index.php' if your templates are server-side dynamic -->
- <!-- filename extension is also used for separate image files -->
- <index_file>index.html</index_file>
+ <design>
+ <!-- path to the design setup xml file -->
+ <setup_file>../../templates/default.xml</setup_file>
<!-- use root gallery directory to store all support files -->
<!-- and relative paths in sub-albums -->
<!-- default = no (old behaviour) -->
- <support_files_use_common_root value="yes" />
- </templates>
-
+ <supplemental_files_use_common_root value="yes" />
+ </design>
+
<images>
- <!-- default sizes of thumbnail and preview images -->
- <thumbnail landscape_w="180" landscape_h="120"
- portrait_w="120" portrait_h="180"
- square="180"
- quality="80" />
- <preview landscape_w="900" landscape_h="600"
- portrait_w="500" portrait_h="750"
- quality="95" />
<!-- preview image border style - use your custom CSS style to display frame around image -->
<border style="border_single" />
<!-- preload next image (allowed values: "yes", "no") default = yes -->
@@ -61,17 +33,6 @@
<!-- - override with <fullsize/> for album or for separate image -->
<!-- <nofullsize /> -->
- <!-- target image directories -->
- <thumbnail_dir>_thumb</thumbnail_dir>
- <preview_dir>_big</preview_dir>
- <original_dir>_orig</original_dir>
-
- <!-- printf() format-style string of thumbnail file names -->
- <!-- %s is mandatory, represents file name (with ext.) -->
- <!-- %d is optional, denotes item index in the album -->
- <!-- this also avoids conflicts with identical names -->
- <thumbnail_name_format>thn_%d_%s</thumbnail_name_format>
-
<!-- Make thumbnails squared, crop in different ways: -->
<!-- none - no squared thumbnails, retain previous behaviour (default) -->
<!-- simple - crop from center, shave 5% from borders -->
diff --git a/src/cgg.c b/src/cgg.c
index 0f72fb3..f7c7e67 100644
--- a/src/cgg.c
+++ b/src/cgg.c
@@ -108,6 +108,7 @@ main (int argc, char* argv[])
time_t time_start = time (NULL);
time_t time_stop;
gchar *s;
+ gchar *templates_basedir;
TPathInfo *path_info;
/*
@@ -141,10 +142,17 @@ main (int argc, char* argv[])
fprintf (stderr, "error: could not parse gallery settings file\n");
return -2;
}
+ setup->design = parse_design_setup_xml (setup->design_setup_file);
+ if (! setup->design) {
+ fprintf (stderr, "error: could not parse design setup file\n");
+ return -6;
+ }
+ if (! validate_design_setup (setup->design))
+ return -7;
- setup->real_templates_dir = find_templates_directory (setup);
- if (setup->real_templates_dir == NULL) {
- fprintf (stderr, "error: could not determine templates directory\n");
+ templates_basedir = find_design_directory (setup);
+ if (templates_basedir == NULL) {
+ fprintf (stderr, "error: could not determine design templates directory\n");
return -3;
}
@@ -172,6 +180,7 @@ main (int argc, char* argv[])
setup->override_nofullsize = fullsize;
path_info = g_malloc0 (sizeof (TPathInfo));
+ path_info->templates_root = templates_basedir;
path_info->source_root = g_strdup (source_dir);
path_info->src_dir = g_strdup (source_dir);
path_info->dest_root = g_strdup (dst_dir);
diff --git a/src/gallery-utils.h b/src/gallery-utils.h
index 2bffc18..29c7d8f 100644
--- a/src/gallery-utils.h
+++ b/src/gallery-utils.h
@@ -26,7 +26,6 @@ G_BEGIN_DECLS
#define IS_DIR_SEP(ch) ((ch) == '/' || (ch) == '~')
#define IS_EQUAL_SIGN(ch) ((ch) == '=')
-#define GET_EXT(s) strrchr (s, '.')
/*
* str_replace: replace substring 'search' with a 'replace' string
diff --git a/src/generators.c b/src/generators.c
index 95bed37..051ee28 100644
--- a/src/generators.c
+++ b/src/generators.c
@@ -35,67 +35,89 @@
#include "stats.h"
-
-/* Returns newly allocated string */
-static gchar *
-make_thumbnail_string (TGallerySetup *setup, unsigned int item_index, const gchar *imgname)
-{
- gchar *s;
- gchar *num;
-
- s = g_strdup (setup->thumbnail_name_format);
- str_replace (&s, "%s", imgname);
- num = g_strdup_printf ("%.3d", item_index);
- str_replace (&s, "%d", num);
- g_free (num);
-
- return s;
-}
-
-/* Get full image source path */
-/* Returns newly allocated string */
-static gchar *
-item_get_img_src (TGallerySetup *setup, TAlbum *items, TIndexItem *item)
+#define IS_NOFULLSIZE(item,parent_items,setup) \
+ (! item->force_fullsize && ! setup->override_nofullsize && \
+ (! parent_items->fullsize || item->force_nofullsize) && \
+ (item->force_nofullsize || parent_items->nofullsize || setup->nofullsize))
+
+static void
+get_image_paths (TGallerySetup *setup,
+ TAlbum *items,
+ TIndexItem *item,
+ unsigned int item_index,
+ TPathInfo *path_info,
+ TImageSize *image_size,
+ gchar **full_img_src,
+ gchar **full_img_dst,
+ gchar **page_img_dst)
{
- if (items->type == GALLERY_TYPE_INDEX) {
- if (item->thumbnail == NULL || strlen (item->thumbnail) == 0)
- return NULL;
- return g_path_get_basename (item->thumbnail);
- }
- else
- if (items->type == GALLERY_TYPE_ALBUM) {
- return g_path_get_basename ((item->path == NULL && item->preview) ? item->preview : item->path);
+ gboolean nofullsize;
+ gboolean is_thumbnail;
+ gboolean is_preview;
+ gboolean is_original;
+ gchar *s1, *s2, *s3;
+ gchar *target_image_dir;
+
+ if (full_img_src)
+ *full_img_src = NULL;
+ if (full_img_dst)
+ *full_img_dst = NULL;
+ if (page_img_dst)
+ *page_img_dst = NULL;
+
+ /* ignore combinations that are not valid */
+ nofullsize = IS_NOFULLSIZE (item, items, setup);
+ is_thumbnail = g_ascii_strcasecmp ("thumbnail", image_size->name) == 0;
+ is_preview = g_ascii_strcasecmp ("preview", image_size->name) == 0;
+ is_original = g_ascii_strcasecmp ("original", image_size->name) == 0;
+ if ((items->type == GALLERY_TYPE_INDEX && ! is_thumbnail) ||
+ (is_thumbnail && item->hidden) ||
+ (is_thumbnail && items->type == GALLERY_TYPE_INDEX && (item->thumbnail == NULL || strlen (item->thumbnail) == 0)) /* ||
+ -- in several cases we need to get path to the source image, e.g. to retrieve EXIF metadata; disabling the check for now
+ (is_original && nofullsize) */ )
+ return;
+
+ target_image_dir = g_strdup_printf ("%s%s", TARGET_IMAGE_DIR_PREFIX, image_size->name);
+
+ /* Thumbnail special case */
+ if (is_thumbnail) {
+ s1 = NULL;
+ if (items->type == GALLERY_TYPE_INDEX) {
+ s1 = item->thumbnail;
+ } else
+ if (items->type == GALLERY_TYPE_ALBUM) {
+ s1 = (item->path == NULL && item->preview) ? item->preview : item->path;
+ s1 = (item->thumbnail) ? item->thumbnail : s1;
+ }
+ s2 = g_path_get_basename (s1);
+ if (full_img_src)
+ *full_img_src = g_build_filename (path_info->src_dir, s1, NULL);
+ s3 = g_strdup_printf (THUMBNAIL_NAME_FORMAT, item_index, s2);
+ g_free (s2);
+ if (full_img_dst)
+ *full_img_dst = g_build_filename (path_info->dest_dir, target_image_dir, s3, NULL);
+ if (page_img_dst)
+ *page_img_dst = g_build_filename (target_image_dir, s3, NULL);
+ g_free (s3);
}
- g_assert_not_reached ();
- return NULL;
-}
-/* Get full thumbnail source path */
-/* Returns newly allocated string */
-static gchar *
-item_get_thumbnail_src (TGallerySetup *setup, TAlbum *items, TIndexItem *item, unsigned int item_index)
-{
- gchar *s1, *ret;
- const gchar *gen_img_src;
-
- if (items->type == GALLERY_TYPE_INDEX) {
- if (item->thumbnail == NULL || strlen (item->thumbnail) == 0)
- return NULL;
- s1 = g_path_get_basename (item->thumbnail);
- ret = make_thumbnail_string (setup, item_index, s1);
- g_free (s1);
- return ret;
- }
- else
- if (items->type == GALLERY_TYPE_ALBUM) {
- gen_img_src = (item->path == NULL && item->preview) ? item->preview : item->path;
- s1 = g_path_get_basename ((item->thumbnail) ? item->thumbnail : gen_img_src);
- ret = make_thumbnail_string (setup, item_index, s1);
- g_free (s1);
- return ret;
+ /* Other image sizes */
+ else {
+ if (is_preview)
+ s1 = (item->preview) ? item->preview : item->path;
+ else
+ s1 = (item->path == NULL && item->preview) ? item->preview : item->path;
+ if (full_img_src)
+ *full_img_src = g_build_filename (path_info->src_dir, s1, NULL);
+ s2 = g_path_get_basename (s1);
+ if (full_img_dst)
+ *full_img_dst = g_build_filename (path_info->dest_dir, target_image_dir, s2, NULL);
+ if (page_img_dst)
+ *page_img_dst = g_build_filename (target_image_dir, s2, NULL);
+ g_free (s2);
}
- g_assert_not_reached ();
- return NULL;
+
+ g_free (target_image_dir);
}
@@ -109,145 +131,120 @@ generate_image (TGallerySetup *setup,
TIndexItem *item,
unsigned int item_index,
TPathInfo *path_info,
- gboolean update_when_necessary)
+ gboolean query_update)
{
- unsigned long new_w, new_h;
- unsigned long thumb_w, thumb_h;
- gchar *thumb_dst;
- gchar *big_dst;
- gchar *big_src;
- gchar *orig_dst;
- gchar *img_src_full;
- gchar *thumb_src_full;
- gchar *s1;
- int bigq;
gboolean res;
- gboolean source_img_portrait;
-
-
- 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 FALSE;
- img_src_full = g_build_filename (path_info->src_dir, item->thumbnail, NULL);
- thumb_src_full = g_build_filename (path_info->src_dir, item->thumbnail, NULL);
- }
- else
- if (items->type == GALLERY_TYPE_ALBUM) {
- s1 = (item->path == NULL && item->preview) ? item->preview : item->path;
- thumb_src_full = (item->thumbnail) ? item->thumbnail : s1;
- img_src_full = g_build_filename (path_info->src_dir, s1, NULL);
- thumb_src_full = g_build_filename (path_info->src_dir, thumb_src_full, NULL);
- }
-
- /* Make paths */
- s1 = item_get_thumbnail_src (setup, items, item, item_index);
- thumb_dst = g_build_filename (path_info->dest_dir, setup->thumbnail_dir, s1, NULL);
- g_free (s1);
- s1 = item_get_img_src (setup, items, item);
- big_dst = g_build_filename (path_info->dest_dir, setup->img_big_dir, s1, NULL);
- if (item->force_fullsize || setup->override_nofullsize || (items->fullsize && ! item->force_nofullsize) ||
- (! item->force_nofullsize && ! items->nofullsize && ! setup->nofullsize))
- orig_dst = g_build_filename (path_info->dest_dir, setup->img_orig_dir, s1, NULL);
- res = (! update_when_necessary) || (! item->hidden && 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))));
- g_free (s1);
-
- /* 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 ();
- source_img_portrait = new_h > new_w;
-
- /* 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->hidden) {
- /* Squared thumbnails */
- if (setup->squared_thumbnail_type != THUMBNAIL_SQUARE_TYPE_NONE) {
- thumb_w = setup->thumbnail_square_size;
- thumb_h = setup->thumbnail_square_size;
- } else
- /* Portrait / Landscape thumbnails */
- if (thumb_h > thumb_w)
- calculate_sizes (setup->thumbnail_portrait_width, setup->thumbnail_portrait_height, &thumb_w, &thumb_h);
+ gboolean is_thumbnail;
+ gboolean is_preview;
+ gboolean is_original;
+ gchar *img_src;
+ gchar *img_dst;
+ unsigned long img_w, img_h;
+ int quality;
+ GList *l;
+ TImageSize *image_size;
+
+
+ res = ! query_update;
+ for (l = g_list_first (setup->design->image_sizes); l; l = g_list_next (l)) {
+ image_size = l->data;
+
+ is_thumbnail = g_ascii_strcasecmp ("thumbnail", image_size->name) == 0;
+ is_preview = g_ascii_strcasecmp ("preview", image_size->name) == 0;
+ is_original = g_ascii_strcasecmp ("original", image_size->name) == 0;
+
+ get_image_paths (setup, items, item, item_index, path_info, image_size, &img_src, &img_dst, NULL);
+ if (img_src == NULL || img_dst == NULL)
+ continue;
+
+ /* Do something when required */
+ res = res || needs_update (img_src, img_dst);
+ if (! query_update) {
+ /* Copy the source file */
+ if ((is_preview && item->preview) || (is_original && image_size->no_resize)) {
+ if (! copy_file (img_src, img_dst))
+ log_error ("generate_image: error copying image %s\n", img_src);
+ }
+ /* Resize image */
+ else {
+ get_image_sizes (img_src, &img_w, &img_h);
+ if (img_w > 0 && img_h > 0) {
+ stats_images_inc ();
+
+ /* Calculate sizes */
+ if (is_thumbnail && setup->squared_thumbnail_type != THUMBNAIL_SQUARE_TYPE_NONE)
+ img_w = img_h = image_size->square_size;
else
- calculate_sizes (setup->thumbnail_landscape_width, setup->thumbnail_landscape_height, &thumb_w, &thumb_h);
- if (! resize_image (thumb_src_full, thumb_dst, thumb_w, thumb_h, setup->thumbnail_quality, TRUE, setup->squared_thumbnail_type))
- log_error ("generate_image: error resizing thumbnail %s\n", thumb_src_full);
+ if (is_preview && item->width > 0 && item->height > 0)
+ calculate_sizes (item->width, item->height, &img_w, &img_h);
+ if (img_w > img_h) {
+ if (is_preview && items->landscape_width > 0 && items->landscape_height > 0)
+ calculate_sizes (items->landscape_width, items->landscape_height, &img_w, &img_h);
+ else
+ calculate_sizes (image_size->landscape_width, image_size->landscape_height, &img_w, &img_h);
+ } else {
+ if (is_preview && items->portrait_width > 0 && items->portrait_height > 0)
+ calculate_sizes (items->portrait_width, items->portrait_height, &img_w, &img_h);
+ else
+ calculate_sizes (image_size->portrait_width, image_size->portrait_height, &img_w, &img_h);
+ }
+ /* Calculate quality */
+ quality = image_size->quality;
+ if (is_preview && items->quality > 0 && items->quality <= 100)
+ quality = items->quality;
+ if (is_preview && item->quality > 0 && item->quality <= 100)
+ quality = item->quality;
+
+ /* Perform resize and strip */
+ if (! resize_image (img_src, img_dst, img_w, img_h, quality, is_thumbnail, setup->squared_thumbnail_type))
+ log_error ("generate_image: error resizing image %s\n", img_src);
+ } else {
+ log_error ("generate_image: image %s sizes are %lux%lu\n", img_src, img_w, img_h);
}
- } else {
- log_error ("generate_image: thumbnail %s sizes are %lux%lu\n", thumb_src_full, thumb_w, thumb_h);
}
+ }
+ if (! is_thumbnail)
+ modify_exif (img_dst, setup->erase_exif_thumbnail, setup->add_copyright);
+ g_free (img_src);
+ g_free (img_dst);
+ }
+ return res;
+}
- /* 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 (! source_img_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);
- 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, 0))
- log_error ("generate_image: error resizing big image %s\n", img_src_full);
- }
- else {
- /* Copy the preview (big) image provided */
- big_src = g_build_filename (path_info->src_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);
+static TImageSize *
+find_image_size_for_name (TGallerySetup *setup, const gchar *name)
+{
+ GList *l;
+ TImageSize *image_size;
- /* 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);
- }
- }
- }
+ for (l = g_list_first (setup->design->image_sizes); l; l = g_list_next (l)) {
+ image_size = l->data;
+ g_assert (image_size != NULL);
+ if (g_ascii_strcasecmp (name, image_size->name) == 0)
+ return image_size;
}
- g_free (img_src_full);
- g_free (thumb_src_full);
- g_free (big_dst);
- g_free (thumb_dst);
- g_free (orig_dst);
-
- return res;
+ return NULL;
}
+static gchar *
+get_index_filename (TAlbum *items, TGalleryDesignTheme *theme, TPathInfo *path_info, TIndexItem *retrieve_child)
+{
+ gchar *s;
+ TGalleryType gallery_type;
+
+ gallery_type = items->type;
+ if (retrieve_child) {
+ s = g_build_filename (path_info->src_dir, retrieve_child->path, "index.xml", NULL);
+ gallery_type = get_child_gallery_type (s);
+ g_free (s);
+ }
+
+ return (gallery_type == GALLERY_TYPE_ALBUM || theme->index_filename == NULL) ? theme->album_filename : theme->index_filename;
+}
/*
* write_html_album: process album and index template files
@@ -260,6 +257,7 @@ generate_image (TGallerySetup *setup,
gboolean
write_html_album (TGallerySetup *setup,
TPathInfo *path_info,
+ TGalleryDesignTheme *theme,
const gchar *template_src,
const gchar *dst,
TAlbum *items)
@@ -281,6 +279,7 @@ write_html_album (TGallerySetup *setup,
ReplaceTable *global_replace_table;
ReplaceTable *local_replace_table;
BlockParser *block_parser;
+ TImageSize *image_size, *thumb_image_size;
fin = fopen (template_src, "r");
@@ -335,17 +334,19 @@ write_html_album (TGallerySetup *setup,
level += count_dir_levels (tmp_item->path) - 1;
}
/* Go Up string */
- s3 = make_string ("../", level);
- s2 = setup->use_inpage_links ? g_strdup_printf ("#i%d", old_parent_item_index) : g_strdup ("");
- replace_table_add_key_printf (global_replace_table, "GO_UP_LINK", "%s%s%s", s3, setup->index_file_name, s2);
- g_free (s2);
- g_free (s3);
+ if (parent) {
+ s3 = make_string ("../", level);
+ s2 = setup->use_inpage_links ? g_strdup_printf ("#i%d", old_parent_item_index) : g_strdup ("");
+ replace_table_add_key_printf (global_replace_table, "GO_UP_LINK", "%s%s%s", s3, get_index_filename (parent, theme, NULL, NULL), s2);
+ g_free (s2);
+ g_free (s3);
+ }
while (parent) {
s3 = make_string ("../", level);
s4 = g_strdup (parent->ID);
s5 = setup->use_inpage_links ? g_strdup_printf ("#i%d", old_parent_item_index) : g_strdup ("");
- s2 = g_strdup_printf ("<a href=\"%s%s%s\">%s</a> &gt; %s", s3, setup->index_file_name, s5, s4, s1);
+ s2 = g_strdup_printf ("<a href=\"%s%s%s\">%s</a> &gt; %s", s3, get_index_filename (parent, theme, NULL, NULL), s5, s4, s1);
g_free (s3);
g_free (s1);
g_free (s4);
@@ -365,7 +366,7 @@ write_html_album (TGallerySetup *setup,
/* Supportfiles path */
s1 = make_string ("../", level - 1);
- replace_table_add_key (global_replace_table, "TEMPLATES_PATH", setup->support_files_use_common_root ? s1 : "");
+ replace_table_add_key (global_replace_table, "TEMPLATES_PATH", setup->supplemental_files_use_common_root ? s1 : "");
g_free (s1);
/* META tags */
@@ -397,9 +398,9 @@ write_html_album (TGallerySetup *setup,
if (setup->favicon_file && strlen (setup->favicon_file) > 0) {
s3 = make_string ("../", level - 1);
if (setup->favicon_type)
- s2 = g_strdup_printf ("%s\t<link rel=\"icon\" type=\"%s\" href=\"%s%s\" />\n", s1, setup->favicon_type, setup->support_files_use_common_root ? s3 : "", setup->favicon_file);
+ s2 = g_strdup_printf ("%s\t<link rel=\"icon\" type=\"%s\" href=\"%s%s\" />\n", s1, setup->favicon_type, setup->supplemental_files_use_common_root ? s3 : "", setup->favicon_file);
else
- s2 = g_strdup_printf ("%s\t<link rel=\"icon\" href=\"%s%s\" />\n", s1, setup->support_files_use_common_root ? s3 : "", setup->favicon_file);
+ s2 = g_strdup_printf ("%s\t<link rel=\"icon\" href=\"%s%s\" />\n", s1, setup->supplemental_files_use_common_root ? s3 : "", setup->favicon_file);
g_free (s1);
g_free (s3);
s1 = s2;
@@ -416,6 +417,10 @@ write_html_album (TGallerySetup *setup,
g_free (s1);
}
+ /* Theming */
+ /* TODO: "image_size" will be used for album themes showing pictures inpage */
+ image_size = find_image_size_for_name (setup, theme->album_image_size);
+ thumb_image_size = find_image_size_for_name (setup, "thumbnail");
/* Setup block parser */
block_parser_register_key (block_parser, "IMG_LIST", "IMG_LIST");
@@ -462,37 +467,38 @@ write_html_album (TGallerySetup *setup,
case INDEX_ITEM_TYPE_PICTURE:
/* Skip HTML code generation if it's a hidden item */
if (! item->hidden) {
- s2 = item_get_thumbnail_src (setup, items, item, i);
- if (s2 != NULL) {
- s4 = g_build_filename (path_info->dest_dir, setup->thumbnail_dir, s2, NULL);
- get_image_sizes (s4, &img_thumb_w, &img_thumb_h);
- g_free (s4);
- s1 = (img_thumb_h > img_thumb_w) ? "IMG_LIST_PORTRAIT" : "IMG_LIST_LANDSCAPE";
- }
+ img_thumb_w = img_thumb_h = 0;
+ get_image_paths (setup, items, item, i, path_info, thumb_image_size, NULL, &s2, &s3);
+ if (s2 != NULL)
+ get_image_sizes (s2, &img_thumb_w, &img_thumb_h);
- if (setup->squared_thumbnail_type != THUMBNAIL_SQUARE_TYPE_NONE)
+ if (setup->squared_thumbnail_type != THUMBNAIL_SQUARE_TYPE_NONE || img_thumb_w == img_thumb_h)
s1 = "IMG_LIST_SQUARED";
- if (! s1)
- s1 = "IMG_LIST_LANDSCAPE"; /* fallback case */
+ else
+ s1 = (img_thumb_h > img_thumb_w) ? "IMG_LIST_PORTRAIT" : "IMG_LIST_LANDSCAPE";
s1 = block_parser_get_data (block_parser, s1);
- if (s2 != NULL) {
- replace_table_add_key_printf (local_replace_table, "IMG_THUMBNAIL", "%s/%s", setup->thumbnail_dir, s2);
- replace_table_add_key_int (local_replace_table, "IMG_SIZE_THUMB_W", img_thumb_w);
- replace_table_add_key_int (local_replace_table, "IMG_SIZE_THUMB_H", img_thumb_h);
+ if (s3 != NULL) {
+ replace_table_add_key (local_replace_table, "IMG_THUMBNAIL", s3);
+ if (img_thumb_w > 0 && img_thumb_h > 0) {
+ replace_table_add_key_int (local_replace_table, "IMG_SIZE_THUMB_W", img_thumb_w);
+ replace_table_add_key_int (local_replace_table, "IMG_SIZE_THUMB_H", img_thumb_h);
+ }
}
g_free (s2);
- replace_table_add_key_printf (local_replace_table, "ALBUM_SUBPATH", "%s/%s", item->path, setup->index_file_name);
- s3 = item_get_img_src (setup, items, item);
- replace_table_add_key_printf (local_replace_table, "IMG_SUBPAGE", "%s%s", s3, GET_EXT (setup->index_file_name));
- replace_table_add_key (local_replace_table, "IMG_FILENAME", s3);
g_free (s3);
+
+ s2 = GET_ITEM_TARGET_FILENAME (item);
+ replace_table_add_key_printf (local_replace_table, "IMG_SUBPAGE", theme->picture_filename, s2);
+ replace_table_add_key (local_replace_table, "IMG_FILENAME", s2);
+ g_free (s2);
replace_table_add_key (local_replace_table, "IMG_TITLE", item->title);
replace_table_add_key (local_replace_table, "IMG_DESCRIPTION", item->title_description);
replace_table_add_key_printf (local_replace_table, "IMG_LIST_ID", "i%d", i + 1);
if (items->type == GALLERY_TYPE_INDEX) {
s3 = g_build_filename (path_info->src_dir, item->path, "index.xml", NULL);
replace_table_add_key_int (local_replace_table, "ALBUM_NUM_ITEMS", get_album_objects_count (s3));
+ replace_table_add_key_printf (local_replace_table, "ALBUM_SUBPATH", "%s/%s", item->path, get_index_filename (items, theme, path_info, item));
g_free (s3);
}
}
@@ -521,6 +527,8 @@ write_html_album (TGallerySetup *setup,
replace_table_process (&block, global_replace_table);
replace_table_add_key (global_replace_table, "IMG_LIST", block);
g_free (block);
+ /* We don't use data from this key directly, let's mark it as used since we've built the structure we needed. */
+ block_parser_set_as_used (block_parser, "IMG_LIST");
}
/* Replace all known tags */
@@ -556,6 +564,7 @@ write_html_album (TGallerySetup *setup,
gboolean
write_html_image (TGallerySetup *setup,
TPathInfo *path_info,
+ TGalleryDesignTheme *theme,
const gchar *template_src,
const gchar *dst,
TIndexItem *item,
@@ -563,11 +572,15 @@ write_html_image (TGallerySetup *setup,
{
FILE *fin;
FILE *fout;
- gchar *big_dst;
- gchar *orig_dst;
+ gchar *img_dst;
+ gchar *img_dst_page;
+ gchar *img_orig_src;
+ gchar *img_orig_dst;
+ gchar *img_orig_dst_page;
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;
+ unsigned long img_w, img_h;
+ unsigned long img_orig_w, img_orig_h;
+ unsigned int item_index, next_item_index, real_item_index, real_total_items;
TIndexItem *previous_item;
TIndexItem *next_item;
TIndexItem *tmp_item;
@@ -583,8 +596,10 @@ write_html_image (TGallerySetup *setup,
int level, old_parent_item_index;
gboolean override_title_meta;
gboolean image_fullsize;
+ gboolean theme_size_is_original;
ReplaceTable *replace_table;
BlockParser *block_parser;
+ TImageSize *image_size;
fin = fopen (template_src, "r");
@@ -599,7 +614,11 @@ write_html_image (TGallerySetup *setup,
return FALSE;
}
+ img_orig_src = NULL;
+ img_orig_dst = NULL;
+ img_orig_dst_page = NULL;
preload_imgname = NULL;
+ res = TRUE;
replace_table = replace_table_new ();
block_parser = block_parser_new ();
@@ -621,45 +640,55 @@ write_html_image (TGallerySetup *setup,
/* Get previous and next items */
previous_item = NULL;
next_item = NULL;
+ next_item_index = 0;
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; i < parent_items->items->len && (next_item == NULL || next_item->type != INDEX_ITEM_TYPE_PICTURE); i++)
+ for (i = item_index; i < 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_index = i;
+ }
+ if (next_item && next_item->type != INDEX_ITEM_TYPE_PICTURE) {
next_item = NULL;
-
- /* Paths setup */
- imgname = g_path_get_basename ((item->path == NULL && item->preview) ? item->preview : item->path);
- if (next_item && setup->preload) {
- s1 = g_path_get_basename ((next_item->path == NULL && next_item->preview) ? next_item->preview : next_item->path);
- preload_imgname = g_build_filename (setup->img_big_dir, s1, NULL);
- g_free (s1);
+ next_item_index = 0;
}
- big_dst = g_build_filename (path_info->dest_dir, setup->img_big_dir, imgname, NULL);
- orig_dst = g_build_filename (path_info->dest_dir, setup->img_orig_dir, imgname, NULL);
- res = TRUE;
+
+ /* If currently processed picture size is original, disable fullsize tags */
+ theme_size_is_original = g_ascii_strcasecmp (theme->picture_image_size, "original") == 0;
+ /* Original size is needed for several things, like EXIF and IPTC metadata */
+ image_size = find_image_size_for_name (setup, "original");
+ get_image_paths (setup, parent_items, item, item_index, path_info, image_size, &img_orig_src, &img_orig_dst, &img_orig_dst_page);
+ image_size = find_image_size_for_name (setup, theme->picture_image_size);
+ get_image_paths (setup, parent_items, item, item_index, path_info, image_size, NULL, &img_dst, &img_dst_page);
+ imgname = g_path_get_basename (img_dst);
+ if (next_item && setup->preload)
+ get_image_paths (setup, parent_items, next_item, next_item_index, path_info, image_size, NULL, NULL, &preload_imgname);
/* Get EXIF data from the original image */
- s1 = g_build_filename (path_info->src_dir, (item->path == NULL && item->preview) ? item->preview : item->path, NULL);
- exif = get_exif (s1);
- g_free (s1);
- if (exif == NULL)
- log_error ("write_html_image: error getting exif data from file \"%s\"\n", orig_dst);
+ exif = NULL;
+ if (img_orig_src) {
+ exif = get_exif (img_orig_src);
+ if (exif == NULL)
+ log_error ("write_html_image: error getting exif data from file \"%s\"\n", img_orig_src);
+ }
+ /* Try destination image instead, though it might have the metadata stripped */
+ if (exif == NULL) {
+ exif = get_exif (img_dst);
+ if (exif == NULL)
+ log_error ("write_html_image: error getting exif data from file \"%s\"\n", img_dst);
+ }
/* Retrieve image sizes of preview and original image */
- get_image_sizes (big_dst, &img_big_w, &img_big_h);
- image_fullsize = item->force_fullsize || setup->override_nofullsize ||
- (parent_items->fullsize && ! item->force_nofullsize) ||
- (! item->force_nofullsize && ! parent_items->nofullsize && ! setup->nofullsize);
+ get_image_sizes (img_dst, &img_w, &img_h);
+ image_fullsize = ! theme_size_is_original && img_orig_dst != NULL && ! IS_NOFULLSIZE (item, parent_items, setup);
if (image_fullsize)
- get_image_sizes (orig_dst, &img_orig_w, &img_orig_h);
+ get_image_sizes (img_orig_dst, &img_orig_w, &img_orig_h);
/* Get title and description from IPTC/EXIF/JPEG if not defined */
title = g_strdup (item->title);
title_desc = g_strdup (item->title_description);
- if (setup->use_iptc_exif && title == NULL && title_desc == NULL) {
+ if (setup->use_iptc_exif && title == NULL && title_desc == NULL && exif != NULL) {
if (exif->iptc_caption)
title = g_strdup (exif->iptc_caption);
if (exif->jpeg_comment) {
@@ -713,13 +742,15 @@ write_html_image (TGallerySetup *setup,
replace_table_add_key (replace_table, "FOOTER", setup->footer);
replace_table_add_key_int (replace_table, "TOTAL_ITEMS", real_total_items);
replace_table_add_key_int (replace_table, "FILE_NO", real_item_index);
- replace_table_add_key_int (replace_table, "IMG_SIZE_BIG_W", img_big_w);
- replace_table_add_key_int (replace_table, "IMG_SIZE_BIG_H", img_big_h);
- replace_table_add_key_int (replace_table, "IMG_SIZE_ORIG_W", img_orig_w);
- replace_table_add_key_int (replace_table, "IMG_SIZE_ORIG_H", img_orig_h);
- replace_table_add_key_printf (replace_table, "IMG_SRC_BIG", "%s/%s", setup->img_big_dir, imgname);
- replace_table_add_key_printf (replace_table, "IMG_SRC_FULL", "%s/%s", setup->img_orig_dir, imgname);
+ replace_table_add_key_int (replace_table, "IMG_SIZE_W", img_w);
+ replace_table_add_key_int (replace_table, "IMG_SIZE_H", img_h);
+ replace_table_add_key_printf (replace_table, "IMG_SRC", "%s%s/%s", TARGET_IMAGE_DIR_PREFIX, image_size->name, imgname);
replace_table_add_key (replace_table, "IMG_SRC_PRELOAD", preload_imgname ? preload_imgname : "");
+ if (image_fullsize) {
+ replace_table_add_key_int (replace_table, "IMG_SIZE_ORIG_W", img_orig_w);
+ replace_table_add_key_int (replace_table, "IMG_SIZE_ORIG_H", img_orig_h);
+ replace_table_add_key (replace_table, "IMG_SRC_FULL", img_orig_dst_page);
+ }
/* Navigation bar (NOTE: 'int level' is used below + favicon) */
s1 = g_strdup (imgname);
@@ -730,7 +761,7 @@ write_html_image (TGallerySetup *setup,
s3 = make_string ("../", level);
s4 = g_strdup (parent->ID);
s5 = setup->use_inpage_links ? g_strdup_printf ("#i%d", parent == parent_items ? item_index : old_parent_item_index) : g_strdup ("");
- s2 = g_strdup_printf ("<a href=\"%s%s%s\">%s</a> &gt; %s", s3, setup->index_file_name, s5, s4, s1);
+ s2 = g_strdup_printf ("<a href=\"%s%s%s\">%s</a> &gt; %s", s3, get_index_filename (parent, theme, NULL, NULL), s5, s4, s1);
g_free (s3);
g_free (s1);
g_free (s4);
@@ -750,20 +781,22 @@ write_html_image (TGallerySetup *setup,
/* Supportfiles path */
s1 = make_string ("../", level - 1);
- replace_table_add_key (replace_table, "TEMPLATES_PATH", setup->support_files_use_common_root ? s1 : "");
+ replace_table_add_key (replace_table, "TEMPLATES_PATH", setup->supplemental_files_use_common_root ? s1 : "");
g_free (s1);
/* EXIF values */
- replace_table_add_key (replace_table, "EXIF_ISO", exif->iso ? exif->iso : "??");
- replace_table_add_key (replace_table, "EXIF_TIME", exif->exposure ? exif->exposure : "??");
- replace_table_add_key (replace_table, "EXIF_APERTURE", exif->aperture ? exif->aperture : "??");
- replace_table_add_key (replace_table, "EXIF_FOCAL_LENGTH", exif->focal_length ? exif->focal_length : "??");
- replace_table_add_key (replace_table, "EXIF_FLASH", exif->flash ? exif->flash : "??");
- replace_table_add_key (replace_table, "EXIF_DATE", exif->datetime ? exif->datetime : "??");
- replace_table_add_key (replace_table, "EXIF_CAMERA_MODEL", exif->camera_model ? exif->camera_model : "??");
- s1 = g_strdup_printf ("(%s)", exif->focal_length_35mm);
- replace_table_add_key (replace_table, "EXIF_FOCAL_35", exif->focal_length_35mm ? s1 : "");
- g_free (s1);
+ if (exif) {
+ replace_table_add_key (replace_table, "EXIF_ISO", exif->iso ? exif->iso : "??");
+ replace_table_add_key (replace_table, "EXIF_TIME", exif->exposure ? exif->exposure : "??");
+ replace_table_add_key (replace_table, "EXIF_APERTURE", exif->aperture ? exif->aperture : "??");
+ replace_table_add_key (replace_table, "EXIF_FOCAL_LENGTH", exif->focal_length ? exif->focal_length : "??");
+ replace_table_add_key (replace_table, "EXIF_FLASH", exif->flash ? exif->flash : "??");
+ replace_table_add_key (replace_table, "EXIF_DATE", exif->datetime ? exif->datetime : "??");
+ replace_table_add_key (replace_table, "EXIF_CAMERA_MODEL", exif->camera_model ? exif->camera_model : "??");
+ s1 = g_strdup_printf ("(%s)", exif->focal_length_35mm);
+ replace_table_add_key (replace_table, "EXIF_FOCAL_35", exif->focal_length_35mm ? s1 : "");
+ g_free (s1);
+ }
/* Border style */
s1 = item->border_style;
@@ -777,19 +810,19 @@ write_html_image (TGallerySetup *setup,
/* Next/Previous links */
if (next_item) {
- s2 = g_path_get_basename ((next_item->path == NULL && next_item->preview) ? next_item->preview : next_item->path);
- replace_table_add_key_printf (replace_table, "LINK_NEXT", "%s%s", s2, GET_EXT (setup->index_file_name));
+ s2 = GET_ITEM_TARGET_FILENAME (next_item);
+ replace_table_add_key_printf (replace_table, "LINK_NEXT", theme->picture_filename, s2);
g_free (s2);
}
else
- replace_table_add_key (replace_table, "LINK_NEXT", setup->index_file_name);
+ replace_table_add_key (replace_table, "LINK_NEXT", get_index_filename (parent_items, theme, NULL, NULL));
if (previous_item) {
- s2 = g_path_get_basename ((previous_item->path == NULL && previous_item->preview) ? previous_item->preview : previous_item->path);
- replace_table_add_key_printf (replace_table, "LINK_PREV", "%s%s", s2, GET_EXT (setup->index_file_name));
+ s2 = GET_ITEM_TARGET_FILENAME (previous_item);
+ replace_table_add_key_printf (replace_table, "LINK_PREV", theme->picture_filename, s2);
g_free (s2);
}
else
- replace_table_add_key (replace_table, "LINK_PREV", setup->index_file_name);
+ replace_table_add_key (replace_table, "LINK_PREV", get_index_filename (parent_items, theme, NULL, NULL));
/* META tags */
override_title_meta = setup->use_title_as_meta && title && (strlen (title) > 0);
@@ -821,9 +854,9 @@ write_html_image (TGallerySetup *setup,
if (setup->favicon_file && strlen (setup->favicon_file) > 0) {
s3 = make_string ("../", level - 1);
if (setup->favicon_type)
- s2 = g_strdup_printf ("%s\t<link rel=\"icon\" type=\"%s\" href=\"%s%s\" />\n", s1, setup->favicon_type, setup->support_files_use_common_root ? s3 : "", setup->favicon_file);
+ s2 = g_strdup_printf ("%s\t<link rel=\"icon\" type=\"%s\" href=\"%s%s\" />\n", s1, setup->favicon_type, setup->supplemental_files_use_common_root ? s3 : "", setup->favicon_file);
else
- s2 = g_strdup_printf ("%s\t<link rel=\"icon\" href=\"%s%s\" />\n", s1, setup->support_files_use_common_root ? s3 : "", setup->favicon_file);
+ s2 = g_strdup_printf ("%s\t<link rel=\"icon\" href=\"%s%s\" />\n", s1, setup->supplemental_files_use_common_root ? s3 : "", setup->favicon_file);
g_free (s1);
g_free (s3);
s1 = s2;
@@ -887,8 +920,11 @@ write_html_image (TGallerySetup *setup,
fclose (fin);
g_free (title);
g_free (title_desc);
- g_free (big_dst);
- g_free (orig_dst);
+ g_free (img_dst);
+ g_free (img_dst_page);
+ g_free (img_orig_src);
+ g_free (img_orig_dst);
+ g_free (img_orig_dst_page);
g_free (imgname);
g_free (preload_imgname);
free_exif_data (exif);
diff --git a/src/generators.h b/src/generators.h
index 6a54ac3..c284f37 100644
--- a/src/generators.h
+++ b/src/generators.h
@@ -36,7 +36,7 @@ gboolean generate_image (TGallerySetup *setup,
TIndexItem *item,
unsigned int item_index,
TPathInfo *path_info,
- gboolean update_when_necessary);
+ gboolean query_update);
/*
* write_html_album: process album and index template files
@@ -48,6 +48,7 @@ gboolean generate_image (TGallerySetup *setup,
*/
gboolean write_html_album (TGallerySetup *setup,
TPathInfo *path_info,
+ TGalleryDesignTheme *theme,
const gchar *template_src,
const gchar *dst,
TAlbum *items);
@@ -63,6 +64,7 @@ gboolean write_html_album (TGallerySetup *setup,
*/
gboolean write_html_image (TGallerySetup *setup,
TPathInfo *path_info,
+ TGalleryDesignTheme *theme,
const gchar *template_src,
const gchar *dst,
TIndexItem *item,
diff --git a/src/items.c b/src/items.c
index 98f97d2..74cfb49 100644
--- a/src/items.c
+++ b/src/items.c
@@ -330,12 +330,45 @@ get_album_titles (const gchar *filename, gchar **title, gchar **description, gch
}
/*
+ * get_child_gallery_type: retrieve gallery type from the source XML file
+ */
+TGalleryType
+get_child_gallery_type (const gchar *filename)
+{
+ TXMLFile *xml;
+ gchar *gallery_type;
+ TGalleryType result;
+
+ /* fallback return value */
+ result = GALLERY_TYPE_INDEX;
+
+ xml = xml_parser_load (filename);
+ if (xml == NULL)
+ return result;
+
+ gallery_type = xml_file_get_node_attribute (xml, "/gallery", "type");
+ if (strcmp (gallery_type, "index") == 0)
+ result = GALLERY_TYPE_INDEX;
+ else
+ if (strcmp (gallery_type, "album") == 0)
+ result = GALLERY_TYPE_ALBUM;
+ else {
+ log_error ("Invalid gallery type (%s)\n", gallery_type);
+ }
+ g_free (gallery_type);
+
+ xml_parser_free (xml);
+ return result;
+}
+
+/*
* free_path_info: free allocated pathinfo data
*/
void
free_path_info (TPathInfo *path_info)
{
if (path_info) {
+ g_free (path_info->templates_root);
g_free (path_info->source_root);
g_free (path_info->dest_root);
g_free (path_info->src_dir);
diff --git a/src/items.h b/src/items.h
index e83961a..cef184c 100644
--- a/src/items.h
+++ b/src/items.h
@@ -74,15 +74,21 @@ typedef struct {
} TIndexItem;
typedef struct {
- gchar *source_root; /* relative or absolute path of the source root */
- gchar *dest_root; /* relative or absolute path of the output directory */
- gchar *src_dir; /* album source directory */
- gchar *dest_dir; /* album output directory */
- gchar *album_path; /* current path in the gallery hierarchy, starting with '/' */
+ gchar *templates_root; /* relative or absolute path of design templates directory */
+ gchar *source_root; /* relative or absolute path of the source root */
+ gchar *dest_root; /* relative or absolute path of the output directory */
+ gchar *src_dir; /* album source directory */
+ gchar *dest_dir; /* album output directory */
+ gchar *album_path; /* current path in the gallery hierarchy, starting with '/' */
} TPathInfo;
/*
+ * GET_ITEM_TARGET_FILENAME: get target item filename
+ */
+#define GET_ITEM_TARGET_FILENAME(i) g_path_get_basename ((i->path == NULL && i->preview) ? i->preview : i->path);
+
+/*
* parse_album_xml: XML parser for gallery index.xml files
*/
TAlbum * parse_album_xml (const gchar *filename, TPathInfo *path_info);
@@ -103,6 +109,11 @@ int get_album_objects_count (const gchar *filename);
void get_album_titles (const gchar *filename, gchar **title, gchar **description, gchar **thumbnail);
/*
+ * get_child_gallery_type: retrieve gallery type from the source XML file
+ */
+TGalleryType get_child_gallery_type (const gchar *filename);
+
+/*
* free_path_info: free allocated pathinfo data
*/
void free_path_info (TPathInfo *path_info);
diff --git a/src/job-manager.c b/src/job-manager.c
index c2188a9..bf3b0df 100644
--- a/src/job-manager.c
+++ b/src/job-manager.c
@@ -114,9 +114,10 @@ thread_func (gpointer data)
gchar *imgname;
gchar *s1, *s2, *s3;
TJob *job = data;
- gboolean updated;
+ gboolean needs_update;
GList *l;
TJobItem *job_item;
+ TGalleryDesignTheme *theme;
do {
item = NULL;
@@ -137,24 +138,34 @@ thread_func (gpointer data)
/* actually do some work */
if (item != NULL && job_item != NULL) {
- imgname = g_path_get_basename ((item->path == NULL && item->preview) ? item->preview : item->path);
- updated = generate_image (job->setup, job->items, item, job_item->real_index, job->path_info, ! job->force_update);
+ imgname = GET_ITEM_TARGET_FILENAME (item);
+ /* Two-pass check whether images need to be updated. First check does no I/O except of stat() calls. */
+ needs_update = job->force_update;
+ if (! needs_update)
+ needs_update = generate_image (job->setup, job->items, item, job_item->real_index, job->path_info, TRUE);
+ if (needs_update)
+ generate_image (job->setup, job->items, item, job_item->real_index, job->path_info, FALSE);
- if (updated && job->setup->verbose) {
+ if (needs_update && job->setup->verbose) {
G_LOCK (items_print);
g_print (" [%d/%d] Processing item \"%s\"\n", job_item->index, job->total_items, imgname);
G_UNLOCK (items_print);
}
- if (updated && job->items->type == GALLERY_TYPE_ALBUM) {
- s1 = g_build_filename (job->setup->real_templates_dir, job->setup->template_photo, NULL);
- s2 = g_strconcat (imgname, GET_EXT (job->setup->index_file_name), NULL);
- s3 = g_build_filename (job->path_info->dest_dir, s2, NULL);
- write_html_image (job->setup, job->path_info, s1, s3, item, job->items);
- g_free (s1);
- g_free (s2);
- g_free (s3);
- }
+ if (needs_update && job->items->type == GALLERY_TYPE_ALBUM)
+ for (l = g_list_first (job->setup->design->themes); l; l = g_list_next (l)) {
+ theme = l->data;
+ /* Do not generate particular image pages when theme doesn't define it */
+ if (theme->enabled && theme->picture_template && theme->picture_filename) {
+ s1 = g_build_filename (job->path_info->templates_root, theme->picture_template, NULL);
+ s2 = g_strdup_printf (theme->picture_filename, imgname);
+ s3 = g_build_filename (job->path_info->dest_dir, s2, NULL);
+ write_html_image (job->setup, job->path_info, theme, s1, s3, item, job->items);
+ g_free (s1);
+ g_free (s2);
+ g_free (s3);
+ }
+ }
g_free (imgname);
}
@@ -182,13 +193,7 @@ build_tree (TGallerySetup *setup,
gchar *idx_file;
TAlbum *items;
TIndexItem *item;
- gchar *s1, *s2, *s3;
- gchar *thumb_dir;
- gchar *img_big_dir;
- gchar *img_orig_dir;
- const gchar *template;
- gchar *dst_album_file;
- gboolean res;
+ gchar *s1, *s2, *s3, *s4;
int i;
TJob *job;
GError *error;
@@ -199,6 +204,9 @@ build_tree (TGallerySetup *setup,
GList *job_items;
GList *l;
TPathInfo *child_path_info;
+ TGalleryDesignTheme *theme;
+ TImageSize *image_size;
+
printf ("Processing directory \"%s\"\n", path_info->src_dir);
stats_dirs_inc ();
@@ -233,15 +241,17 @@ build_tree (TGallerySetup *setup,
items->parent_index = parent_index;
items->parent_item_index = parent_item_index;
- /* Check if update is necessary */
- dst_album_file = g_build_filename (path_info->dest_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) {
+ if (! setup->supplemental_files_use_common_root || parent_index == NULL) {
/* copy only if we're in root level or old-style is active */
- mirror_files (setup, setup->template_files, setup->real_templates_dir, path_info->dest_dir, " Copying template files: ");
+ mirror_files (setup, setup->design->supplemental_files, path_info->templates_root, path_info->dest_dir, " Copying global theme supplemental files: ");
+
+ for (l = g_list_first (setup->design->themes); l; l = g_list_next (l)) {
+ theme = l->data;
+ g_assert (theme != NULL);
+ if (theme->enabled)
+ mirror_files (setup, theme->supplemental_files, path_info->templates_root, path_info->dest_dir, " Copying theme supplemental files: ");
+ }
/* favicon */
if (setup->favicon_file && strlen (setup->favicon_file) > 0) {
@@ -258,41 +268,45 @@ build_tree (TGallerySetup *setup,
}
}
- /* Prepare target thumbnail directory */
- thumb_dir = g_build_path (G_DIR_SEPARATOR_S, path_info->dest_dir, setup->thumbnail_dir, NULL);
- if (access (thumb_dir, R_OK | W_OK | X_OK))
- 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;
+ /* Copy extra files */
+ mirror_files (setup, items->extra_files, path_info->src_dir, path_info->dest_dir, " Copying extra files: ");
+
+ /* Prepare target image directories */
+ for (l = g_list_first (setup->design->image_sizes); l; l = g_list_next (l)) {
+ image_size = l->data;
+ g_assert (image_size != NULL);
+ /* We don't allow having single pictures in index pages at the moment, might change in the future */
+ if (items->type != GALLERY_TYPE_INDEX || g_ascii_strcasecmp (image_size->name, "thumbnail") == 0) {
+ s1 = g_strdup_printf ("%s%s", TARGET_IMAGE_DIR_PREFIX, image_size->name);
+ s2 = g_build_path (G_DIR_SEPARATOR_S, path_info->dest_dir, s1, NULL);
+ g_free (s1);
+ if (access (s2, R_OK | W_OK | X_OK))
+ if (g_mkdir_with_parents (s2, DEFAULT_DATA_DIR_MODE)) {
+ log_error ("error making target image directory '%s': %s\n", s2, strerror (errno));
+ g_free (s2);
+ free_album_data (items);
+ return FALSE;
+ }
+ g_free (s2);
}
- g_free (thumb_dir);
-
- /* Prepare target preview and orig directories */
- if (items->type == GALLERY_TYPE_ALBUM) {
- res = TRUE;
- img_big_dir = g_build_path (G_DIR_SEPARATOR_S, path_info->dest_dir, setup->img_big_dir, NULL);
- img_orig_dir = g_build_path (G_DIR_SEPARATOR_S, path_info->dest_dir, setup->img_orig_dir, NULL);
- if (access (img_big_dir, R_OK | W_OK | X_OK))
- if (g_mkdir_with_parents (img_big_dir, DEFAULT_DATA_DIR_MODE)) {
- log_error ("error making target preview directory: %s\n", strerror (errno));
- res = FALSE;
- }
- if (access (img_orig_dir, R_OK | W_OK | X_OK))
- if (g_mkdir_with_parents (img_orig_dir, DEFAULT_DATA_DIR_MODE)) {
- log_error ("error making target full size directory: %s\n", strerror (errno));
- res = FALSE;
+ }
+
+ /* Check if update of whole album/index is necessary */
+ force_update = ! setup->update_mode;
+ if (! force_update)
+ for (l = g_list_first (setup->design->themes); l; l = g_list_next (l)) {
+ theme = l->data;
+ g_assert (theme != NULL);
+ if (theme->enabled) {
+ s1 = (items->type == GALLERY_TYPE_ALBUM || ! theme->index_filename) ? theme->album_filename : theme->index_filename;
+ s2 = g_build_filename (path_info->dest_dir, s1, NULL);
+ force_update = needs_update (idx_file, s2);
+ g_free (s2);
}
- g_free (img_big_dir);
- g_free (img_orig_dir);
- if (! res) {
- g_free (dst_album_file);
- free_album_data (items);
- return FALSE;
+ if (force_update)
+ break;
}
- }
+ g_free (idx_file);
/* Prepare job manager structures */
job = g_malloc0 (sizeof (TJob));
@@ -356,28 +370,28 @@ build_tree (TGallerySetup *setup,
g_list_free (job_items);
/* Generate album page */
- if (force_update) {
- if (items->type == GALLERY_TYPE_INDEX)
- template = setup->template_index;
- else
- if (items->type == GALLERY_TYPE_ALBUM)
- template = setup->template_album;
- else
- /* default to album */
- template = setup->template_album;
-
- if (setup->verbose) printf (" Writing %s\n", setup->index_file_name);
- s1 = g_build_filename (setup->real_templates_dir, template, NULL);
- res = write_html_album (setup, path_info, s1, dst_album_file, items);
- g_free (s1);
- if (! res) {
- log_error ("error generating target index file\n");
- free_album_data (items);
- return FALSE;
+ if (force_update)
+ for (l = g_list_first (setup->design->themes); l; l = g_list_next (l)) {
+ theme = l->data;
+ g_assert (theme != NULL);
+ if (theme->enabled) {
+ if (items->type == GALLERY_TYPE_ALBUM || ! theme->index_template) {
+ s1 = theme->album_template;
+ s2 = theme->album_filename;
+ } else {
+ s1 = theme->index_template;
+ s2 = theme->index_filename;
+ }
+ if (setup->verbose)
+ printf (" Writing %s\n", s2);
+ s3 = g_build_filename (path_info->templates_root, s1, NULL);
+ s4 = g_build_filename (path_info->dest_dir, s2, NULL);
+ if (! write_html_album (setup, path_info, theme, s3, s4, items))
+ log_error ("error generating target index file\n");
+ g_free (s3);
+ g_free (s4);
+ }
}
- }
- g_free (dst_album_file);
-
/* Recurse to sub-albums (in case of album index) */
if (items->type == GALLERY_TYPE_INDEX) {
@@ -390,6 +404,7 @@ build_tree (TGallerySetup *setup,
}
if (item->type == INDEX_ITEM_TYPE_PICTURE) {
child_path_info = g_malloc0 (sizeof (TPathInfo));
+ child_path_info->templates_root = g_strdup (path_info->templates_root);
child_path_info->source_root = g_strdup (path_info->source_root);
child_path_info->dest_root = g_strdup (path_info->dest_root);
child_path_info->src_dir = g_build_path (G_DIR_SEPARATOR_S, path_info->src_dir, item->path, NULL);
@@ -402,9 +417,6 @@ build_tree (TGallerySetup *setup,
}
}
- /* Copy extra files */
- mirror_files (setup, items->extra_files, path_info->src_dir, path_info->dest_dir, " Copying extra files: ");
-
free_album_data (items);
return TRUE;
}
diff --git a/src/setup.c b/src/setup.c
index 68c3cd3..f09a908 100644
--- a/src/setup.c
+++ b/src/setup.c
@@ -21,11 +21,6 @@
#include <errno.h>
#include <unistd.h>
-#include <libxml/xmlmemory.h>
-#include <libxml/parser.h>
-#include <libxml/xpath.h>
-#include <libxml/xpathInternals.h>
-
#include <glib.h>
#include <glib/gstdio.h>
@@ -91,122 +86,264 @@ parse_setup_xml (const gchar *filename)
setup = g_malloc0 (sizeof (TGallerySetup));
setup->setup_xml_path = g_strdup (filename);
- setup->templates_path = xml_file_get_node_value (xml, "/gallery_setup/templates/path/text()");
- setup->template_index = xml_file_get_node_value (xml, "/gallery_setup/templates/index/text()");
- setup->template_album = xml_file_get_node_value (xml, "/gallery_setup/templates/album/text()");
- setup->template_photo = xml_file_get_node_value (xml, "/gallery_setup/templates/photo/text()");
- s = xml_file_get_node_value (xml, "/gallery_setup/templates/template_files/text()");
- if (s) {
- setup->template_files = g_strsplit (s, "\n", -1);
- g_free (s);
- }
- setup->support_files_use_common_root = xml_file_get_node_attribute_boolean (xml, "/gallery_setup/templates/support_files_use_common_root", "value", FALSE);
- setup->index_file_name = xml_file_get_node_value_with_default (xml, "/gallery_setup/templates/index_file/text()", DEFAULT_INDEX_FILENAME);
-
- setup->thumbnail_dir = xml_file_get_node_value_with_default (xml, "/gallery_setup/images/thumbnail_dir/text()", DEFAULT_THUMBNAIL_DIR);
- setup->img_big_dir = xml_file_get_node_value_with_default (xml, "/gallery_setup/images/preview_dir/text()", DEFAULT_IMG_BIG_DIR);
- setup->img_orig_dir = xml_file_get_node_value_with_default (xml, "/gallery_setup/images/original_dir/text()", DEFAULT_IMG_ORIG_DIR);
- setup->thumbnail_name_format = xml_file_get_node_value_with_default (xml, "/gallery_setup/images/thumbnail_name_format/text()", DEFAULT_THUMBNAIL_NAME_FORMAT);
- if (strstr (setup->thumbnail_name_format, "%s") == NULL) {
- g_free (setup->thumbnail_name_format);
- setup->thumbnail_name_format = g_strdup (DEFAULT_THUMBNAIL_NAME_FORMAT);
- }
+ /* design section */
+ setup->design_setup_file = xml_file_get_node_value (xml, "/gallery_setup/design/setup_file/text()");
+ setup->supplemental_files_use_common_root = xml_file_get_node_attribute_boolean (xml, "/gallery_setup/design/supplemental_files_use_common_root", "value", FALSE);
- setup->thumbnail_landscape_width = xml_file_get_node_attribute_long (xml, "/gallery_setup/images/thumbnail", "landscape_w", 0);
- setup->thumbnail_landscape_height = xml_file_get_node_attribute_long (xml, "/gallery_setup/images/thumbnail", "landscape_h", 0);
- setup->thumbnail_portrait_width = xml_file_get_node_attribute_long (xml, "/gallery_setup/images/thumbnail", "portrait_w", 0);
- setup->thumbnail_portrait_height = xml_file_get_node_attribute_long (xml, "/gallery_setup/images/thumbnail", "portrait_h", 0);
- setup->thumbnail_square_size = xml_file_get_node_attribute_long (xml, "/gallery_setup/images/thumbnail", "square", 0);
- setup->thumbnail_quality = xml_file_get_node_attribute_long (xml, "/gallery_setup/images/thumbnail", "quality", -1);
- setup->preview_landscape_width = xml_file_get_node_attribute_long (xml, "/gallery_setup/images/preview", "landscape_w", 0);
- setup->preview_landscape_height = xml_file_get_node_attribute_long (xml, "/gallery_setup/images/preview", "landscape_h", 0);
- setup->preview_portrait_width = xml_file_get_node_attribute_long (xml, "/gallery_setup/images/preview", "portrait_w", 0);
- setup->preview_portrait_height = xml_file_get_node_attribute_long (xml, "/gallery_setup/images/preview", "portrait_h", 0);
- setup->preview_quality = xml_file_get_node_attribute_long (xml, "/gallery_setup/images/preview", "quality", -1);
- setup->footer = xml_file_get_node_value (xml, "/gallery_setup/footer/text()");
+ /* images section */
setup->border_style = xml_file_get_node_attribute (xml, "/gallery_setup/images/border", "style");
+ setup->preload = xml_file_get_node_attribute_boolean (xml, "/gallery_setup/images/preload", "value", TRUE);
+ setup->use_iptc_exif = xml_file_get_node_attribute_boolean (xml, "/gallery_setup/images/use_iptc_exif", "value", FALSE);
+ setup->erase_exif_thumbnail = xml_file_get_node_attribute_boolean (xml, "/gallery_setup/images/erase_embed_thumbnail", "value", FALSE);
+ setup->nofullsize = xml_file_get_node_present (xml, "/gallery_setup/images/nofullsize");
+
+ s = xml_file_get_node_attribute (xml, "/gallery_setup/images/squared_thumbnails", "type");
+ if (s && g_ascii_strcasecmp (s, "simple") == 0)
+ setup->squared_thumbnail_type = THUMBNAIL_SQUARE_TYPE_SIMPLE;
+ else
+ setup->squared_thumbnail_type = THUMBNAIL_SQUARE_TYPE_NONE;
+ g_free (s);
+
+ /* meta section */
setup->meta_author = xml_file_get_node_value (xml, "/gallery_setup/meta/author/text()");
setup->meta_author_email = xml_file_get_node_value (xml, "/gallery_setup/meta/author_email/text()");
setup->meta_description = xml_file_get_node_value (xml, "/gallery_setup/meta/description/text()");
setup->meta_keywords = xml_file_get_node_value (xml, "/gallery_setup/meta/keywords/text()");
-
- setup->preload = xml_file_get_node_attribute_boolean (xml, "/gallery_setup/images/preload", "value", TRUE);
- setup->use_iptc_exif = xml_file_get_node_attribute_boolean (xml, "/gallery_setup/images/use_iptc_exif", "value", FALSE);
- setup->erase_exif_thumbnail = xml_file_get_node_attribute_boolean (xml, "/gallery_setup/images/erase_embed_thumbnail", "value", FALSE);
setup->use_title_as_meta = xml_file_get_node_attribute_boolean (xml, "/gallery_setup/meta/use_title_as_meta", "value", TRUE);
-
setup->site_title = xml_file_get_node_attribute (xml, "/gallery_setup/meta/site", "title");
setup->add_copyright = xml_file_get_node_value (xml, "/gallery_setup/meta/add_copyright/text()");
+ setup->favicon_file = xml_file_get_node_value (xml, "/gallery_setup/meta/favicon/text()");
+ setup->favicon_type = xml_file_get_node_attribute (xml, "/gallery_setup/meta/favicon", "type");
+
+ /* navigation section */
setup->use_inpage_links = xml_file_get_node_attribute_boolean (xml, "/gallery_setup/navigation/use_inpage_links", "value", TRUE);
setup->show_go_up = xml_file_get_node_attribute_boolean (xml, "/gallery_setup/navigation/show_go_up", "value", TRUE);
setup->show_exif_table = xml_file_get_node_attribute_boolean (xml, "/gallery_setup/navigation/show_exif_table", "value", TRUE);
- setup->nofullsize = xml_file_get_node_present (xml, "/gallery_setup/images/nofullsize");
-
- setup->favicon_file = xml_file_get_node_value (xml, "/gallery_setup/meta/favicon/text()");
- setup->favicon_type = xml_file_get_node_attribute (xml, "/gallery_setup/meta/favicon", "type");
-
+ /* feed section */
setup->feed_enabled = xml_file_get_node_attribute_boolean (xml, "/gallery_setup/feed", "enable", FALSE);
setup->feed_filename = xml_file_get_node_value (xml, "/gallery_setup/feed/filename/text()");
setup->feed_title = xml_file_get_node_value (xml, "/gallery_setup/feed/title/text()");
setup->feed_base_url = xml_file_get_node_value (xml, "/gallery_setup/feed/base_url/text()");
- s = xml_file_get_node_attribute (xml, "/gallery_setup/images/squared_thumbnails", "type");
- if (s && g_ascii_strcasecmp (s, "simple") == 0)
- setup->squared_thumbnail_type = THUMBNAIL_SQUARE_TYPE_SIMPLE;
- else
- setup->squared_thumbnail_type = THUMBNAIL_SQUARE_TYPE_NONE;
- g_free (s);
+ /* footer section */
+ setup->footer = xml_file_get_node_value (xml, "/gallery_setup/footer/text()");
xml_parser_free (xml);
return setup;
}
-
-static int
-test_tmpl_access (const gchar *dir, const gchar *path)
+/*
+ * parse_design_setup_xml: XML parser for design.xml file
+ */
+TGalleryDesign *
+parse_design_setup_xml (const gchar *filename)
{
+ TXMLFile *xml;
gchar *s;
- int b;
+ gchar *s2;
+ TGalleryDesign *design;
+ TImageSize *image_size;
+ TGalleryDesignTheme *theme;
+ int count;
+ int i;
- s = g_build_filename (dir, path, NULL);
- b = g_access (s, R_OK);
- g_free (s);
- return b;
+ xml = xml_parser_load (filename);
+ if (xml == NULL)
+ return NULL;
+
+ design = g_malloc0 (sizeof (TGalleryDesign));
+
+ s2 = xml_file_get_node_value (xml, "/design_setup/supplemental_files/text()");
+ if (s2) {
+ design->supplemental_files = g_strsplit (s2, "\n", -1);
+ g_free (s2);
+ }
+
+
+ /* image_sizes section */
+ count = xml_file_node_get_children_count (xml, "/design_setup/image_sizes/size");
+ for (i = 0; i < count; i++) {
+ image_size = g_malloc0 (sizeof (TImageSize));
+ design->image_sizes = g_list_append (design->image_sizes, image_size);
+
+ s = g_strdup_printf ("/design_setup/image_sizes/size[%d]", i + 1);
+ image_size->name = xml_file_get_node_attribute (xml, s, "name");
+ g_free (s);
+
+ s = g_strdup_printf ("/design_setup/image_sizes/size[%d]/landscape", i + 1);
+ image_size->landscape_width = xml_file_get_node_attribute_long (xml, s, "w", 0);
+ image_size->landscape_height = xml_file_get_node_attribute_long (xml, s, "h", 0);
+ g_free (s);
+
+ s = g_strdup_printf ("/design_setup/image_sizes/size[%d]/portrait", i + 1);
+ image_size->portrait_width = xml_file_get_node_attribute_long (xml, s, "w", 0);
+ image_size->portrait_height = xml_file_get_node_attribute_long (xml, s, "h", 0);
+ g_free (s);
+
+ s = g_strdup_printf ("/design_setup/image_sizes/size[%d]/square", i + 1);
+ image_size->square_size = xml_file_get_node_attribute_long (xml, s, "size", 0);
+ g_free (s);
+
+ s = g_strdup_printf ("/design_setup/image_sizes/size[%d]/quality", i + 1);
+ image_size->quality = xml_file_get_node_attribute_long (xml, s, "value", -1);
+ g_free (s);
+
+ s = g_strdup_printf ("/design_setup/image_sizes/size[%d]/no_resize", i + 1);
+ image_size->no_resize = xml_file_get_node_present (xml, s);
+ g_free (s);
+ }
+
+
+ /* theme section */
+ count = xml_file_node_get_children_count (xml, "/design_setup/theme");
+ for (i = 0; i < count; i++) {
+ theme = g_malloc0 (sizeof (TGalleryDesignTheme));
+ design->themes = g_list_append (design->themes, theme);
+
+ s = g_strdup_printf ("/design_setup/theme[%d]", i + 1);
+ theme->enabled = xml_file_get_node_attribute_boolean (xml, s, "enabled", TRUE);
+ g_free (s);
+
+ s = g_strdup_printf ("/design_setup/theme[%d]/index/template/text()", i + 1);
+ theme->index_template = xml_file_get_node_value (xml, s);
+ g_free (s);
+ s = g_strdup_printf ("/design_setup/theme[%d]/index/target_filename/text()", i + 1);
+ theme->index_filename = xml_file_get_node_value_with_default (xml, s, DEFAULT_INDEX_FILENAME);
+ g_free (s);
+
+ s = g_strdup_printf ("/design_setup/theme[%d]/album/template/text()", i + 1);
+ theme->album_template = xml_file_get_node_value (xml, s);
+ g_free (s);
+ s = g_strdup_printf ("/design_setup/theme[%d]/album/target_filename/text()", i + 1);
+ theme->album_filename = xml_file_get_node_value_with_default (xml, s, DEFAULT_INDEX_FILENAME);
+ g_free (s);
+ s = g_strdup_printf ("/design_setup/theme[%d]/album/picture_size/text()", i + 1);
+ theme->album_image_size = xml_file_get_node_value (xml, s);
+ g_free (s);
+
+ s = g_strdup_printf ("/design_setup/theme[%d]/picture/template/text()", i + 1);
+ theme->picture_template = xml_file_get_node_value (xml, s);
+ g_free (s);
+ s = g_strdup_printf ("/design_setup/theme[%d]/picture/target_filename/text()", i + 1);
+ theme->picture_filename = xml_file_get_node_value (xml, s);
+ g_free (s);
+ s = g_strdup_printf ("/design_setup/theme[%d]/picture/picture_size/text()", i + 1);
+ theme->picture_image_size = xml_file_get_node_value (xml, s);
+ g_free (s);
+
+ s = g_strdup_printf ("/design_setup/theme[%d]/supplemental_files/text()", i + 1);
+ s2 = xml_file_get_node_value (xml, s);
+ if (s2) {
+ theme->supplemental_files = g_strsplit (s2, "\n", -1);
+ g_free (s2);
+ }
+ g_free (s);
+ }
+
+ xml_parser_free (xml);
+ return design;
}
-static int
-test_tmpl_files (const gchar *dir, TGallerySetup *setup)
+
+static gboolean
+lookup_image_size (TGalleryDesign *design, const gchar *image_size_name)
+{
+ GList *l;
+ TImageSize *image_size;
+
+ g_return_val_if_fail (image_size_name != NULL, FALSE);
+ g_return_val_if_fail (strlen (image_size_name) > 0, FALSE);
+
+ for (l = g_list_first (design->image_sizes); l; l = g_list_next (l)) {
+ image_size = l->data;
+ g_assert (image_size != NULL);
+ if (image_size->name == NULL || strlen (image_size->name) == 0) {
+ fprintf (stderr, "design validation warning: image size %p defined with no name\n", image_size);
+ continue;
+ }
+ if (image_size->landscape_width <= 0 || image_size->landscape_height <= 0 ||
+ image_size->portrait_width <= 0 || image_size->portrait_height <= 0) {
+ fprintf (stderr, "design validation warning: image size %s defined with zero sized element\n", image_size->name);
+ continue;
+ }
+ if (g_ascii_strcasecmp (image_size_name, image_size->name) == 0)
+ return TRUE;
+ }
+
+ return FALSE;
+}
+
+/*
+ * validate_design_setup: validate design.xml file setup
+ */
+gboolean
+validate_design_setup (TGalleryDesign *design)
{
- return test_tmpl_access (dir, setup->template_album) |
- test_tmpl_access (dir, setup->template_photo) |
- test_tmpl_access (dir, setup->template_index);
+ GList *l;
+ TGalleryDesignTheme *theme;
+
+ /* validate sizes */
+ if (g_list_length (design->image_sizes) == 0) {
+ fprintf (stderr, "design validation error: no image size defined\n");
+ return FALSE;
+ }
+
+ /* validate themes */
+ if (g_list_length (design->themes) == 0) {
+ fprintf (stderr, "design validation error: no theme defined\n");
+ return FALSE;
+ }
+ for (l = g_list_first (design->themes); l; l = g_list_next (l)) {
+ theme = l->data;
+ g_assert (theme != NULL);
+ if (theme->album_image_size && ! lookup_image_size (design, theme->album_image_size)) {
+ fprintf (stderr, "design validation error: theme-defined image size '%s' not found\n", theme->album_image_size);
+ return FALSE;
+ }
+ if (theme->picture_image_size == NULL || strlen (theme->picture_image_size) == 0) {
+ fprintf (stderr, "design validation error: theme does not define mandatory picture size argument\n");
+ return FALSE;
+ }
+ if (! lookup_image_size (design, theme->picture_image_size)) {
+ fprintf (stderr, "design validation error: theme-defined image size '%s' not found\n", theme->picture_image_size);
+ return FALSE;
+ }
+ }
+
+ return TRUE;
}
+
/*
- * find_templates_directory: absolute/relative path checks, trying to find templates directory
- * - returned string should be freed
+ * find_design_directory: try to find design templates directory
+ * - returned string should be freed
*/
gchar *
-find_templates_directory (TGallerySetup *setup)
+find_design_directory (TGallerySetup *setup)
{
gchar *base_dir;
- gchar *pth;
+ gchar *base_design_dir;
+ gchar *pth = NULL;
- if (IS_DIR_SEP (*setup->templates_path)) {
- if (! test_tmpl_files (setup->templates_path, setup))
- return g_strdup (setup->templates_path);
+ if (IS_DIR_SEP (*setup->design_setup_file)) {
+ pth = g_path_get_dirname (setup->design_setup_file);
+ if (g_access (pth, R_OK))
+ return pth;
} else {
base_dir = g_path_get_dirname (setup->setup_xml_path);
- pth = g_build_path (G_DIR_SEPARATOR_S, base_dir, setup->templates_path, NULL);
+ base_design_dir = g_path_get_dirname (setup->design_setup_file);
+ pth = g_build_path (G_DIR_SEPARATOR_S, base_dir, base_design_dir, NULL);
g_free (base_dir);
+ g_free (base_design_dir);
- if (! test_tmpl_files (pth, setup))
+ if (g_access (pth, R_OK) == 0)
return pth;
}
- log_error ("Couldn't find proper templates directory (tried '%s')\n", setup->templates_path);
+ log_error ("Couldn't find proper design templates directory (tried '%s')\n", pth);
+ g_free (pth);
return NULL;
}
@@ -218,31 +355,64 @@ void
free_setup_data (TGallerySetup *setup)
{
if (setup) {
- g_free (setup->real_templates_dir);
g_free (setup->setup_xml_path);
- g_free (setup->templates_path);
- g_free (setup->template_index);
- g_free (setup->template_album);
- g_free (setup->template_photo);
- g_strfreev (setup->template_files);
- g_free (setup->index_file_name);
- g_free (setup->footer);
+ g_free (setup->design_setup_file);
+ g_free (setup->border_style);
g_free (setup->meta_author);
g_free (setup->meta_author_email);
g_free (setup->meta_description);
g_free (setup->meta_keywords);
- g_free (setup->border_style);
g_free (setup->site_title);
g_free (setup->add_copyright);
g_free (setup->favicon_file);
g_free (setup->favicon_type);
- g_free (setup->thumbnail_dir);
- g_free (setup->img_big_dir);
- g_free (setup->img_orig_dir);
- g_free (setup->thumbnail_name_format);
g_free (setup->feed_filename);
g_free (setup->feed_title);
g_free (setup->feed_base_url);
+ g_free (setup->footer);
+ free_design_setup_data (setup->design);
g_free (setup);
}
}
+
+static void
+free_image_size_data (TImageSize *image_size)
+{
+ if (image_size) {
+ g_free (image_size->name);
+ g_free (image_size);
+ }
+}
+
+static void
+free_design_theme_data (TGalleryDesignTheme *theme)
+{
+ if (theme) {
+ g_free (theme->index_template);
+ g_free (theme->index_filename);
+ g_free (theme->album_template);
+ g_free (theme->album_filename);
+ g_free (theme->album_image_size);
+ g_free (theme->picture_template);
+ g_free (theme->picture_filename);
+ g_free (theme->picture_image_size);
+ g_strfreev (theme->supplemental_files);
+ g_free (theme);
+ }
+}
+
+/*
+ * free_design_setup_data: free allocated design setup data
+ */
+void
+free_design_setup_data (TGalleryDesign *design)
+{
+ if (design) {
+ g_list_foreach (design->image_sizes, (GFunc) free_image_size_data, NULL);
+ g_list_free (design->image_sizes);
+ g_list_foreach (design->themes, (GFunc) free_design_theme_data, NULL);
+ g_list_free (design->themes);
+ g_strfreev (design->supplemental_files);
+ g_free (design);
+ }
+}
diff --git a/src/setup.h b/src/setup.h
index 3bc3b3f..69e92b6 100644
--- a/src/setup.h
+++ b/src/setup.h
@@ -23,16 +23,16 @@
G_BEGIN_DECLS
-/* Directory names */
-#define DEFAULT_THUMBNAIL_DIR "_thumb"
-#define DEFAULT_IMG_BIG_DIR "_big"
-#define DEFAULT_IMG_ORIG_DIR "_orig"
-#define DEFAULT_THUMBNAIL_NAME_FORMAT "thn_%d_%s"
+#define DEFAULT_INDEX_FILENAME "index.html"
+#define THUMBNAIL_NAME_FORMAT "%.3d_%s"
+#define TARGET_IMAGE_DIR_PREFIX "_"
#define SETUP_XML "setup.xml"
-#define DEFAULT_INDEX_FILENAME "index.html"
+/* forward declaration */
+typedef struct TGalleryDesign TGalleryDesign;
+
typedef enum {
THUMBNAIL_SQUARE_TYPE_NONE,
THUMBNAIL_SQUARE_TYPE_SIMPLE
@@ -43,67 +43,81 @@ typedef enum {
typedef struct {
gboolean verbose;
gboolean update_mode;
- gchar *real_templates_dir;
-
+ gboolean override_nofullsize;
gchar *setup_xml_path;
- gchar *templates_path;
- gchar *template_index;
- gchar *template_album;
- gchar *template_photo;
- gchar **template_files;
- gboolean support_files_use_common_root;
- gchar *index_file_name;
- gchar *thumbnail_dir;
- gchar *img_big_dir;
- gchar *img_orig_dir;
- gchar *thumbnail_name_format;
- ThumbnailSquareType squared_thumbnail_type;
+ TGalleryDesign *design;
- gchar *footer;
- gchar *meta_author;
- gchar *meta_author_email;
- gchar *meta_description;
- gchar *meta_keywords;
- gboolean use_title_as_meta;
-
- int thumbnail_quality;
- unsigned long thumbnail_landscape_width;
- unsigned long thumbnail_landscape_height;
- unsigned long thumbnail_portrait_width;
- unsigned long thumbnail_portrait_height;
- unsigned long thumbnail_square_size;
-
- int preview_quality;
- unsigned long preview_landscape_width;
- unsigned long preview_landscape_height;
- unsigned long preview_portrait_width;
- unsigned long preview_portrait_height;
+ /* design section */
+ gchar *design_setup_file;
+ gboolean supplemental_files_use_common_root;
+ /* images section */
gchar *border_style;
- gboolean nofullsize;
- gboolean override_nofullsize;
-
gboolean preload;
gboolean use_iptc_exif;
gboolean erase_exif_thumbnail;
+ gboolean nofullsize;
+ ThumbnailSquareType squared_thumbnail_type;
+ /* meta section */
+ gchar *meta_author;
+ gchar *meta_author_email;
+ gchar *meta_description;
+ gchar *meta_keywords;
+ gboolean use_title_as_meta;
gchar *site_title;
gchar *add_copyright;
+ gchar *favicon_file;
+ gchar *favicon_type;
+
+ /* navigation section */
gboolean use_inpage_links;
gboolean show_go_up;
gboolean show_exif_table;
- gchar *favicon_file;
- gchar *favicon_type;
-
+ /* feed section */
gboolean feed_enabled;
gchar *feed_filename;
gchar *feed_title;
gchar *feed_base_url;
+
+ /* footer section */
+ gchar *footer;
} TGallerySetup;
+typedef struct {
+ gchar *name;
+ int landscape_width;
+ int landscape_height;
+ int portrait_width;
+ int portrait_height;
+ int square_size;
+ int quality;
+ gboolean no_resize;
+} TImageSize;
+
+typedef struct {
+ gboolean enabled;
+ gchar *index_template;
+ gchar *index_filename;
+ gchar *album_template;
+ gchar *album_filename;
+ gchar *album_image_size;
+ gchar *picture_template;
+ gchar *picture_filename;
+ gchar *picture_image_size;
+ gchar **supplemental_files;
+} TGalleryDesignTheme;
+
+struct TGalleryDesign {
+ GList *image_sizes;
+ GList *themes;
+ gchar **supplemental_files;
+};
+
+
/*
* find_setup_xml: try to find setup.xml in standard paths
@@ -116,15 +130,30 @@ TGallerySetup * find_setup_xml ();
TGallerySetup * parse_setup_xml (const gchar *filename);
/*
+ * parse_design_setup_xml: XML parser for design.xml file
+ */
+TGalleryDesign * parse_design_setup_xml (const gchar *filename);
+
+/*
+ * validate_design_setup: validate design.xml file setup
+ */
+gboolean validate_design_setup (TGalleryDesign *design);
+
+/*
* free_setup_data: free allocated setup data
*/
void free_setup_data (TGallerySetup *setup);
/*
- * find_templates_directory: absolute/relative path checks, trying to find templates directory
- * - returned string should be freed
+ * free_design_setup_data: free allocated design setup data
+ */
+void free_design_setup_data (TGalleryDesign *design);
+
+/*
+ * find_design_directory: try to find design templates directory
+ * - returned string should be freed
*/
-gchar * find_templates_directory (TGallerySetup *setup);
+gchar * find_design_directory (TGallerySetup *setup);
G_END_DECLS
diff --git a/templates/Makefile.am b/templates/Makefile.am
index 45c3baf..8826487 100644
--- a/templates/Makefile.am
+++ b/templates/Makefile.am
@@ -3,11 +3,12 @@ NULL =
templatesdir = $(datadir)/cgg
templates_DATA = \
+ default.xml \
+ template_album.html \
+ template_index.html \
+ template_picture.html \
scripts-general.js \
styles.css \
- template-album.tmpl \
- template-index.tmpl \
- template-view_photo.tmpl \
$(NULL)
EXTRA_DIST = $(templates_DATA)
diff --git a/templates/default.xml b/templates/default.xml
new file mode 100644
index 0000000..67470c0
--- /dev/null
+++ b/templates/default.xml
@@ -0,0 +1,97 @@
+<?xml version="1.0" encoding="utf-8"?>
+<design_setup>
+
+ <!-- image size definitions -->
+ <image_sizes>
+ <!-- "original", "preview" and "thumbnail" sizes are somewhat special here
+ in order to keep compatibility with previous versions. In case when
+ "original" size is not available due to <nofullsize> tag present,
+ the "preview" size will be used instead. -->
+
+ <!-- Meaning of "original" is shifted here from previous versions;
+ it's considered more like a bigger preview size for large screens now. -->
+ <!-- corresponds with mandatory <item src> tag in album source file -->
+ <size name="original">
+ <landscape w="1200" h="800" />
+ <portrait w="1024" h="1024" />
+ <quality value="97" />
+ <!-- With presence of the "no_resize" tag, no resizing will be done and
+ image file will be copied as is (this is a default for backwards
+ compatibility). -->
+ <no_resize />
+ </size>
+
+ <!-- corresponds with optional <item preview> tag in album source file -->
+ <size name="preview">
+ <landscape w="1067" h="600" />
+ <portrait w="800" h="800" />
+ <quality value="95" />
+ </size>
+
+ <!-- Thumbnail section is mandatory. -->
+ <!-- corresponds with optional <item thumbnail> tag in album source file -->
+ <size name="thumbnail">
+ <landscape w="180" h="120" />
+ <portrait w="120" h="180" />
+ <square size="180" />
+ <quality value="80" />
+ </size>
+
+ <!-- Here you can define custom sizes which will be generated from the file
+ defined in <item src> tag. Currently, there's no way how to supply custom
+ sized images from album source file (might be changed in the future). -->
+ <size name="mobile">
+ <landscape w="320" h="240" />
+ <portrait w="240" h="320" />
+ <quality value="90" />
+ </size>
+ </image_sizes>
+
+ <!-- Global support files, common files used by several themes. -->
+ <supplemental_files><![CDATA[
+ ]]></supplemental_files>
+
+
+ <!-- particular design setup -->
+ <theme enabled="yes">
+ <!-- When the <index> structure is missing, album design will be used for
+ both list of albums and list of pictures. -->
+ <index>
+ <template>template_index.html</template>
+ <target_filename>index.html</target_filename>
+ </index>
+
+ <!-- This is mandatory. -->
+ <album>
+ <template>template_album.html</template>
+ <target_filename>index.html</target_filename>
+ <!-- which picture size to use for XXX tags (TODO) -->
+ <picture_size>preview</picture_size>
+ </album>
+
+ <!-- When the <picture> structure is missing, no pages for the particular
+ images will be generated. Images are processed in either case, for use
+ with album alone. -->
+ <picture>
+ <template>template_picture.html</template>
+ <!-- '%s' will be replaced with actual picture filename -->
+ <target_filename>%s.html</target_filename>
+ <!-- which picture size to use -->
+ <picture_size>preview</picture_size>
+ </picture>
+
+ <!-- support files for current theme -->
+ <!-- should include all used CSS styles, images, scripts... -->
+ <!-- subdirectories are allowed and will be mirrored to destination -->
+ <supplemental_files><![CDATA[
+ styles.css
+ scripts-general.js
+ ]]></supplemental_files>
+ </theme>
+
+ <!-- Here you can define another theme, with different templates etc.
+ The purpose is to allow switching between them or as a result of
+ device capabilities autodetection. Don't forget to change target
+ filenames to avoid conflicts. -->
+
+</design_setup>
diff --git a/templates/template-album.tmpl b/templates/template_album.html
index 9f31fb3..9f31fb3 100644
--- a/templates/template-album.tmpl
+++ b/templates/template_album.html
diff --git a/templates/template-index.tmpl b/templates/template_index.html
index 01de113..01de113 100644
--- a/templates/template-index.tmpl
+++ b/templates/template_index.html
diff --git a/templates/template-view_photo.tmpl b/templates/template_picture.html
index 7557846..413d348 100644
--- a/templates/template-view_photo.tmpl
+++ b/templates/template_picture.html
@@ -33,7 +33,7 @@
<!-- ## Image -->
<div class="img_preview">
- <a href="$(LINK_NEXT)"><img src="$(IMG_SRC_BIG)" width="$(IMG_SIZE_BIG_W)" height="$(IMG_SIZE_BIG_H)" alt="" id="$(IMG_BORDER_STYLE)" /></a>
+ <a href="$(LINK_NEXT)"><img src="$(IMG_SRC)" width="$(IMG_SIZE_W)" height="$(IMG_SIZE_H)" alt="" id="$(IMG_BORDER_STYLE)" /></a>
<!-- $(BEGIN_IMG_FULLSIZE_LINK) -->
<div class="img_preview_full">
<a href="$(IMG_SRC_FULL)">See original size (<!-- $(IMG_SIZE_ORIG_W) -->x<!-- $(IMG_SIZE_ORIG_H) -->)</a>