/* Cataract - Static web photo gallery generator * Copyright (C) 2008 Tomas Bzatek * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; either version 2 * of the License, or any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #include #include #include #include #include #include #include #include #include #include #include "setup.h" #include "job-manager.h" #include "stats.h" #include "atom-writer.h" #include "gallery-utils.h" /* Commandline arguments */ static gchar *source_dir = NULL; static gchar *dst_dir = NULL; static gboolean verbose = FALSE; static gboolean update = FALSE; static gboolean fullsize = FALSE; static int jobs = 1; /* * parse_cmd: parse commandline and fill global variable parameters */ gboolean parse_cmd (int argc, char *argv[]) { static GOptionEntry entries[] = { { "verbose", 'v', 0, G_OPTION_ARG_NONE, &verbose, "Be verbose", NULL }, { "source", 's', 0, G_OPTION_ARG_STRING, &source_dir, "Specifies a path to source structure", NULL }, { "output", 'o', 0, G_OPTION_ARG_STRING, &dst_dir, "Generate files to the specified directory instead of current", NULL }, { "jobs", 'j', 0, G_OPTION_ARG_INT, &jobs, "Allow N jobs at once (default=1)", NULL }, { "update", 'u', 0, G_OPTION_ARG_NONE, &update, "Update the output structure", NULL }, { "fullsize", 'f', 0, G_OPTION_ARG_NONE, &fullsize, "Override the nofullsize switch and generate full gallery", NULL }, { NULL } }; GError *error = NULL; GOptionContext *context; gchar *s1; g_set_prgname ("cgg"); context = g_option_context_new ("- web gallery generator"); s1 = g_strdup_printf ("cgg v%s [%s] %s", VERSION, APP_BUILD_DATE, APP_COPYRIGHT_STRING); g_option_context_set_summary (context, s1); g_free (s1); g_option_context_add_main_entries (context, entries, NULL); if (argc == 1) { s1 = g_option_context_get_help (context, TRUE, NULL); g_print ("%s", s1); g_free (s1); g_option_context_free (context); return FALSE; } if (! g_option_context_parse (context, &argc, &argv, &error)) { g_print ("option parsing failed: %s\n", error->message); s1 = g_option_context_get_help (context, TRUE, NULL); g_print ("%s", s1); g_free (s1); g_option_context_free (context); return FALSE; } g_option_context_free (context); return TRUE; } int main (int argc, char* argv[]) { TGallerySetup *setup; time_t time_start = time (NULL); time_t time_stop; gchar *s; gchar *templates_basedir; TPathInfo *path_info; /* * this initialize the library and check potential ABI mismatches * between the version it was compiled for and the actual shared * library used. */ LIBXML_TEST_VERSION; g_thread_init (NULL); /* Initialize ImageMagick at this point, for multithreading safety */ MagickWandGenesis(); /* Parse commandline */ if (! parse_cmd (argc, argv)) return -1; if (! source_dir || access (source_dir, R_OK)) { fprintf (stderr, "error: source directory must be specified and pointing to valid structure\n"); return -4; } if (! dst_dir) { fprintf (stderr, "error: target directory must be specified\n"); return -5; } /* Read gallery settings */ setup = find_setup_xml (); if (! setup) { 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; templates_basedir = find_design_directory (setup); if (templates_basedir == NULL) { fprintf (stderr, "error: could not determine design templates directory\n"); return -3; } stats_errors = 0; stats_dirs = 0; stats_images = 0; /* Print banner */ if (verbose) { printf ("cgg v%s [%s]\n\n", VERSION, APP_BUILD_DATE); printf ("Using setup file \"%s\"\n", setup->setup_xml_path); } /* Setup feeds */ news_feed = NULL; if (setup->feed_enabled) { news_feed = atom_writer_new (); atom_writer_set_title (news_feed, setup->feed_title ? setup->feed_title : setup->site_title); } /* Start building the gallery tree */ setup->verbose = verbose; setup->update_mode = update; 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); path_info->dest_dir = g_strdup (dst_dir); path_info->album_path = g_strdup ("/"); build_tree (setup, path_info, NULL, -1, jobs); free_path_info (path_info); /* Write feeds */ if (news_feed) { if (verbose) printf ("Writing Atom feed: %s\n", setup->feed_filename); if (setup->location_base_url == NULL || strlen (setup->location_base_url) == 0) log_error ("Error: feed base URL not defined!\n"); else if (setup->feed_filename == NULL || strlen (setup->feed_filename) == 0) log_error ("Error: feed file name not defined!\n"); else { atom_writer_set_base_url (news_feed, setup->location_base_url); s = g_build_filename (setup->location_base_url, setup->feed_filename, NULL); atom_writer_set_feed_url (news_feed, s); g_free (s); s = g_strdup_printf ("%s/%s", dst_dir, setup->feed_filename); atom_writer_write_to_file (news_feed, s, setup); g_free (s); } atom_writer_free (news_feed); } /* Write stats */ if (verbose) { time_stop = time (NULL); printf ("\nProcessed %d images in %d albums, elapsed time = %dm %ds\n", stats_images, stats_dirs, (int) ((time_stop - time_start) / 60), (int) ((time_stop - time_start) % 60)); if (stats_errors == 1) printf ("%d error occured.\n", stats_errors); if (stats_errors > 1) printf ("%d errors occured.\n", stats_errors); } MagickWandTerminus(); /* Cleanup function for the XML library. */ xmlCleanupParser(); g_free (source_dir); g_free (dst_dir); free_setup_data (setup); return 0; }