00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
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
00037
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
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
00059
00060
00061 private:
00062 bookmark_tree _categories;
00063
00064 istring recurse_on_node(inner_mark_tree *nod);
00065
00066
00067
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
00098 int spaces = 4 * node->depth();
00099 output += istring(' ', spaces);
00100
00101
00102 output += "<dl> <p>";
00103 output += log_base::platform_ending();
00104
00105
00106 spaces = 4 * (node->depth() + 1);
00107 output += istring(' ', spaces);
00108
00109
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
00120 int spaces = 4 * (depth + 1);
00121 output += istring(' ', spaces);
00122
00123
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
00133
00134 if (!linko._url) {
00135
00136
00137 if (!linko._description) return;
00138
00139
00140
00141
00142
00143
00144
00145
00146
00147
00148
00149
00150 return;
00151 }
00152
00153
00154 int spaces = 4 * (node->depth() + 2);
00155 output += istring(' ', spaces);
00156
00157
00158 output += "<dt> ";
00159 output += "<a href=\"";
00160
00161 output += linko._url;
00162 output += "\">";
00163
00164 output += linko._description;
00165
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);
00176 istring input_filename;
00177 istring output_filename;
00178 istring template_filename;
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
00209 write_category_start(nod, to_return);
00210
00211
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
00218 for (int i = 0; i < nod->branches(); i++) {
00219 to_return += recurse_on_node((inner_mark_tree *)nod->branch(i));
00220 }
00221
00222
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
00233
00234
00235 long_string += "\
00236 <!DOCTYPE NETSCAPE-Bookmark-file-1>\n\
00237 <!-- This file was automatically generated by ";
00238
00239
00240 long_string += filename(__argv[0]).basename();
00241 long_string += ".\n";
00242
00243
00244 long_string += " It was generated on ";
00245 long_string += timestamp(true, true);
00246 long_string += "\n";
00247
00248
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
00256 inner_mark_tree *top = (inner_mark_tree *)&_categories.access_root();
00257 long_string += recurse_on_node(top);
00258
00259
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
00264 output_file.write(long_string);
00265 output_file.close();
00266
00267
00268
00269
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
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