marks_maker_moz.cpp

Go to the documentation of this file.
00001 /*****************************************************************************\
00002 *                                                                             *
00003 *  Name   : marks_maker_mozilla                                               *
00004 *  Author : Chris Koeritz                                                     *
00005 *                                                                             *
00006 *  Purpose:                                                                   *
00007 *                                                                             *
00008 *    Turns a link database in HOOPLE format into a web page in the style of   *
00009 *  Mozilla's bookmark export.  This should allow the created web page to be   *
00010 *  imported back into the Mozilla bookmarks manager.                          *
00011 *                                                                             *
00012 *******************************************************************************
00013 * Copyright (c) 2006-$now By Author.  This program is free software; you can  *
00014 * redistribute it and/or modify it under the terms of the GNU General Public  *
00015 * License as published by the Free Software Foundation; either version 2 of   *
00016 * the License or (at your option) any later version.  This is online at:      *
00017 *     http://www.fsf.org/copyleft/gpl.html                                    *
00018 * Please send any updates to: fred@gruntose.com                               *
00019 \*****************************************************************************/
00020 
00021 #include "bookmark_tree.cpp"
00022 
00023 #include <basis/function.h>
00024 #include <basis/guards.h>
00025 #include <basis/istring.h>
00026 #include <opsystem/application_shell.h>
00027 #include <opsystem/byte_filer.h>
00028 #include <opsystem/command_line.h>
00029 #include <loggers/file_logger.h>
00030 #include <opsystem/filename.h>
00031 #include <data_struct/static_memory_gremlin.h>
00032 #include <textual/list_parsing.h>
00033 
00034 using namespace nodes;
00035 
00036 //#define DEBUG_MARKS
00037   // uncomment to have more debugging noise.
00038 
00039 #undef BASE_LOG
00040 #define BASE_LOG(s) program_wide_logger().log(s)
00041 #undef LOG
00042 #define LOG(s) CLASS_EMERGENCY_LOG(program_wide_logger(), s)
00043 
00044 const int MAX_FILE_SIZE = 4 * MEGABYTE;
00045   // the largest file we'll read.
00046 
00048 
00049 class marks_maker_mozilla : public application_shell
00050 {
00051 public:
00052   marks_maker_mozilla() : application_shell(static_class_name()) {}
00053   IMPLEMENT_CLASS_NAME("marks_maker_mozilla");
00054   virtual int execute();
00055   int print_instructions(const filename &program_name);
00056 
00057   int write_marks_page(const istring &output_filename);
00058     // given a tree of links, this writes out a mozilla bookmark format
00059     // web page to "output_filename".
00060 
00061 private:
00062   bookmark_tree _categories;  // our tree of categories.
00063 
00064   istring recurse_on_node(inner_mark_tree *nod);
00065     // the main recursive method that spiders down the tree.
00066 
00067   // these handle outputting text for categories and links.
00068   void write_category_start(inner_mark_tree *node, istring &output);
00069   void write_category_end(int depth, istring &output);
00070   void write_link(inner_mark_tree *node, const link_record &linko,
00071          istring &output);
00072 };
00073 
00075 
00076 int marks_maker_mozilla::print_instructions(const filename &program_name)
00077 {
00078   isprintf to_show("%s:\n\
00079 This program needs two filenames as command line parameters.  The -i flag\n\
00080 is used to specify the input filename and the -o flag specifies the web page\n\
00081 to be created.  The input file is expected to be in the HOOPLE link database\n\
00082 format.  The output file will be created from the template file by finding\n\
00083 the phrase $INSERT_LINKS_HERE in it and replacing that with html formatted\n\
00084 link and categories from the input file.  Another tag of $TODAYS_DATE will\n\
00085 be replaced with the date when the output file is regenerated.\n\
00086 The HOOPLE link format is documented here:\n\
00087     http://hoople.org/guides/link_database/format_manifesto.txt\n\
00088 ", program_name.basename().raw().s(), program_name.basename().raw().s());
00089   program_wide_logger().log(to_show.s());
00090   return 12;
00091 }
00092 
00093 void marks_maker_mozilla::write_category_start(inner_mark_tree *node,
00094     istring &output)
00095 {
00096   FUNCDEF("write_category_start");
00097   // add spaces to indent appropriately...
00098   int spaces = 4 * node->depth();
00099   output += istring(' ', spaces);
00100 
00101   // add the beginning of the category stuff.
00102   output += "<dl> <p>";
00103   output += log_base::platform_ending();
00104 
00105   // add more spaces for the indent.
00106   spaces = 4 * (node->depth() + 1);
00107   output += istring(' ', spaces);
00108 
00109   // then add the category heading.
00110   output += "<dt> <h3>";
00111   output += node->name();
00112   output += "</h3>";
00113   output += log_base::platform_ending();
00114 }
00115 
00116 void marks_maker_mozilla::write_category_end(int depth, istring &output)
00117 {
00118   FUNCDEF("write_category_end");
00119   // add spaces to indent appropriately...
00120   int spaces = 4 * (depth + 1);
00121   output += istring(' ', spaces);
00122 
00123   // add the beginning of the category stuff.
00124   output += "</dl> <p>";
00125   output += log_base::platform_ending();
00126 }
00127 
00128 void marks_maker_mozilla::write_link(inner_mark_tree *node,
00129     const link_record &linko, istring &output)
00130 {
00131   FUNCDEF("write_link");
00132   // write an html link definition.
00133 
00134   if (!linko._url) {
00135     // this just appears to be a comment line.
00136 
00137     if (!linko._description) return;  // it's a nothing line.
00138 
00139 //not done yet.
00140 /*
00141     int spaces = 4 * node->depth();
00142     output += istring(' ', spaces);
00143 
00144     output += "<dt> ";
00145     output += "<a href=\"";
00146     output += linko._description;
00147     output += "<br>";
00148     output += log_base::platform_ending();
00149 */
00150     return;
00151   }
00152 
00153   // add spaces to push things out to right indentation.
00154   int spaces = 4 * (node->depth() + 2);
00155   output += istring(' ', spaces);
00156 
00157   // print out the link formatting.
00158   output += "<dt> ";
00159   output += "<a href=\"";
00160   // drop in the URL.
00161   output += linko._url;
00162   output += "\">";
00163   // put the description in also.
00164   output += linko._description;
00165   // close the link formatting.
00166   output += "</a>";
00167   output += log_base::platform_ending();
00168 }
00169 
00170 int marks_maker_mozilla::execute()
00171 {
00172   FUNCDEF("execute");
00173   SET_DEFAULT_COMBO_LOGGER;
00174 
00175   command_line cmds(__argc, __argv);  // process the command line parameters.
00176   istring input_filename;  // we'll store our link database name here.
00177   istring output_filename;  // where the web page we're creating goes.
00178   istring template_filename;  // the wrapper html code that we'll stuff.
00179   if (!cmds.get_value('i', input_filename, false))
00180     return print_instructions(cmds.program_name());
00181   if (!cmds.get_value('o', output_filename, false))
00182     return print_instructions(cmds.program_name());
00183 
00184   BASE_LOG(istring("input file: ") + input_filename);
00185   BASE_LOG(istring("output file: ") + output_filename);
00186 
00187   filename outname(output_filename);
00188   if (outname.exists()) {
00189     non_continuable_error(class_name(), func, istring("the output file ")
00190         + output_filename + " already exists.  It would be over-written if "
00191         "we continued.");
00192   }
00193 
00194   int ret = _categories.read_csv_file(input_filename);
00195   if (ret) return ret;
00196 
00197   ret = write_marks_page(output_filename);
00198   if (ret) return ret;
00199   
00200   return 0;
00201 }
00202 
00203 istring marks_maker_mozilla::recurse_on_node(inner_mark_tree *nod)
00204 {
00205   FUNCDEF("recurse_on_node");
00206   istring to_return;
00207 
00208   // print out the category on this node.
00209   write_category_start(nod, to_return);
00210 
00211   // print the link for all of the ones stored at this node.
00212   for (int i = 0; i < nod->_links.elements(); i++) {
00213     link_record *lin = nod->_links.borrow(i);
00214     write_link(nod, *lin, to_return);
00215   }
00216 
00217   // zoom down into sub-categories.
00218   for (int i = 0; i < nod->branches(); i++) {
00219     to_return += recurse_on_node((inner_mark_tree *)nod->branch(i));
00220   }
00221 
00222   // finish this category.
00223   write_category_end(nod->depth(), to_return);
00224 
00225   return to_return;
00226 }
00227 
00228 int marks_maker_mozilla::write_marks_page(const istring &output_filename)
00229 {
00230   FUNCDEF("write_marks_page");
00231   istring long_string;
00232     // this is our accumulator of links and html formatting.
00233 
00234   // create the header piece 
00235   long_string += "\
00236 <!DOCTYPE NETSCAPE-Bookmark-file-1>\n\
00237 <!-- This file was automatically generated by ";
00238 
00239   // add the program name that's generating this.
00240   long_string += filename(__argv[0]).basename();
00241   long_string += ".\n";
00242 
00243   // add a generation time to the comments.
00244   long_string += "    It was generated on ";
00245   long_string += timestamp(true, true);
00246   long_string += "\n";
00247 
00248   // tack on some more html formatting, including the title and first header.
00249   long_string += "\
00250 -->\n\
00251 <META HTTP-EQUIV=\"Content-Type\" CONTENT=\"text/html; charset=UTF-8\">\n\
00252 <TITLE>Generated Bookmarks</TITLE>\n\
00253 <H1>Generated Bookmarks</H1>\n";
00254 
00255   // now traverse the tree of bookmarks in postfix order.
00256   inner_mark_tree *top = (inner_mark_tree *)&_categories.access_root();
00257   long_string += recurse_on_node(top);
00258 
00259   // write the output file from the accumulated string.
00260   byte_filer output_file(output_filename, "w");
00261   if (!output_file.good())
00262     non_continuable_error(class_name(), func, "the output file could not be opened");
00263   // write the newly generated web page out now.
00264   output_file.write(long_string);
00265   output_file.close();
00266 
00267 // show the tree.
00268 //  BASE_LOG("");
00269 //  BASE_LOG(_categories.access_root().text_form());
00270 
00271   BASE_LOG(isprintf("wrote %d links in %d categories.",
00272       _categories.link_count(), _categories.category_count()));
00273   BASE_LOG("");
00274 
00275   return 0;
00276 }
00277 
00279 
00280 HOOPLE_MAIN(marks_maker_mozilla, )
00281 
00282 #ifdef __BUILD_STATIC_APPLICATION__
00283   // static dependencies found by buildor_gen_deps.sh:
00284   #include <basis/array.cpp>
00285   #include <basis/byte_array.cpp>
00286   #include <basis/callstack_tracker.cpp>
00287   #include <basis/chaos.cpp>
00288   #include <basis/convert_utf.cpp>
00289   #include <basis/definitions.cpp>
00290   #include <basis/earth_time.cpp>
00291   #include <basis/guards.cpp>
00292   #include <basis/istring.cpp>
00293   #include <basis/log_base.cpp>
00294   #include <basis/memory_checker.cpp>
00295   #include <basis/mutex.cpp>
00296   #include <basis/object_base.cpp>
00297   #include <basis/outcome.cpp>
00298   #include <basis/packable.cpp>
00299   #include <basis/portable.cpp>
00300   #include <basis/sequence.cpp>
00301   #include <basis/set.cpp>
00302   #include <basis/utility.cpp>
00303   #include <basis/version_record.cpp>
00304   #include <data_struct/amorph.cpp>
00305   #include <data_struct/bit_vector.cpp>
00306   #include <data_struct/byte_hasher.cpp>
00307   #include <data_struct/configurator.cpp>
00308   #include <data_struct/hash_table.cpp>
00309   #include <data_struct/pointer_hash.cpp>
00310   #include <data_struct/stack.cpp>
00311   #include <data_struct/static_memory_gremlin.cpp>
00312   #include <data_struct/string_hash.cpp>
00313   #include <data_struct/string_hasher.cpp>
00314   #include <data_struct/string_table.cpp>
00315   #include <data_struct/symbol_table.cpp>
00316   #include <data_struct/table_configurator.cpp>
00317   #include <loggers/console_logger.cpp>
00318   #include <loggers/file_logger.cpp>
00319   #include <loggers/locked_logger.cpp>
00320   #include <loggers/null_logger.cpp>
00321   #include <loggers/program_wide_logger.cpp>
00322   #include <nodes/node.cpp>
00323   #include <nodes/path.cpp>
00324   #include <nodes/symbol_tree.cpp>
00325   #include <nodes/tree.cpp>
00326   #include <opsystem/application_base.cpp>
00327   #include <opsystem/application_shell.cpp>
00328   #include <opsystem/byte_filer.cpp>
00329   #include <opsystem/command_line.cpp>
00330   #include <opsystem/critical_events.cpp>
00331   #include <opsystem/directory.cpp>
00332   #include <opsystem/filename.cpp>
00333   #include <opsystem/ini_config.cpp>
00334   #include <opsystem/ini_parser.cpp>
00335   #include <opsystem/path_configuration.cpp>
00336   #include <opsystem/rendezvous.cpp>
00337   #include <textual/byte_format.cpp>
00338   #include <textual/list_parsing.cpp>
00339   #include <textual/parser_bits.cpp>
00340   #include <textual/string_manipulation.cpp>
00341   #include <textual/tokenizer.cpp>
00342 #endif // __BUILD_STATIC_APPLICATION__
00343 

Generated on Fri Nov 28 04:28:49 2008 for HOOPLE Libraries by  doxygen 1.5.1