summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTomas Bzatek <tbzatek@users.sourceforge.net>2011-05-29 19:00:44 +0200
committerTomas Bzatek <tbzatek@users.sourceforge.net>2011-05-29 19:00:44 +0200
commit75bb13e531654a561dc7baa2f2bc594aa4a8fc52 (patch)
tree0b80f48e53d969292b2ffd401cb06470a1156bff
parenteb3092f8bd30d065c4e6f4bf0159309e1a960156 (diff)
downloadcataract-75bb13e531654a561dc7baa2f2bc594aa4a8fc52.tar.xz
Introduce new theming system
This extends current templating system to another dimension, bringing the possibility to have multiple themes generated at once. The purpose is to be able to switch between multiple designs, from PC to mobile, classic vs. flat view, slideshow, etc. For the moment, only the classic theme is available. Rules: * for switching between themes, place a link inside your template manually - it's not a cgg concern, only your theming infrastructure * don't forget to define different file names for index and album pages across different themes * it's recommended to keep default theme named as "index.*" to avoid showing directory listing on webserver Notes: * some TODOs will be fixed when we have new theme using these advanced features (e.g. pictures in album pages) * TODO: introduce tag/block conditional system, allow custom user defines for each theme/page * TODO: deprecate <show_go_up>, <show_exif_table> and <border style> in favor of conditionals (these tags belong to theming)
-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>