source: main/trunk/greenstone2/runtime-src/src/recpt/wizardaction.cpp@ 28949

Last change on this file since 28949 was 28949, checked in by ak19, 10 years ago

Dr Bainbridge fixed an encoding issue in the depositor, where if you enter utf8 characters into metadata on one page and then click the wizardbutton to go back to the previous page of the wizard, then the character looked wrong (split into 2 parts).

  • Property svn:keywords set to Author Date Id Revision
File size: 24.7 KB
Line 
1/**********************************************************************
2 *
3 * wizardaction.cpp --
4 * Copyright (C) 2000 The New Zealand Digital Library Project
5 *
6 * A component of the Greenstone digital library software
7 * from the New Zealand Digital Library Project at the
8 * University of Waikato, New Zealand.
9 *
10 * This program is free software; you can redistribute it and/or modify
11 * it under the terms of the GNU General Public License as published by
12 * the Free Software Foundation; either version 2 of the License, or
13 * (at your option) any later version.
14 *
15 * This program is distributed in the hope that it will be useful,
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 * GNU General Public License for more details.
19 *
20 * You should have received a copy of the GNU General Public License
21 * along with this program; if not, write to the Free Software
22 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
23 *
24 *********************************************************************/
25
26#include "gsdl_modules_cfg.h"
27#ifdef GSDL_USE_WIZARD_ACTION
28
29// note that the wizardaction relies on having direct access to a
30// collections configuration file. this breaks the separation between
31// receptionist and collection server and so is not suitable (at least
32// in its current form) for use when collection servers are separate
33// from the receptionist (e.g. when using the CORBA protocol).
34
35// following line required to get fstream.filedesc() on darwin (Mac OS X)
36#define _STREAM_COMPAT 1
37// required for utsname on solaris???
38#ifndef _XOPEN_SOURCE
39#define _XOPEN_SOURCE 1
40#endif
41// This was added for Solaris, but it makes things worse on Solaris for me...
42// #define _XOPEN_SOURCE_EXTENDED 1
43
44#include "wizardaction.h"
45#include "OIDtools.h"
46#include "fileutil.h"
47#include "cfgread.h"
48#include "gsdltools.h"
49#include "gsdltimes.h"
50#include "argdb.h"
51#include "cgiutils.h"
52#include <stdio.h>
53#include <fcntl.h>
54
55#if !defined (__WIN32__)
56#include <sys/utsname.h>
57#include <unistd.h>
58#endif
59
60wizardaction::wizardaction () {
61
62 recpt = NULL;
63 disabled = true;
64
65 macro_prefix = "";
66}
67
68wizardaction::~wizardaction () {
69}
70
71void wizardaction::configure (const text_t &key, const text_tarray &cfgline) {
72
73 const text_t& action_name = get_action_name();
74
75 if ((key == action_name) && (cfgline.size() == 1) &&
76 (cfgline[0] == "true" || cfgline[0] == "on" || cfgline[0] == "enabled")) {
77 disabled = false;
78 } else {
79 // call the parent class to deal with the things which
80 // are not dealt with here
81 action::configure (key, cfgline);
82 }
83}
84
85
86bool wizardaction::init (ostream & /*logout*/) {
87
88 return set_gsdl_env_vars(gsdlhome);
89}
90
91
92void wizardaction::get_cgihead_info (cgiargsclass &/*args*/, recptprotolistclass * /*protos*/,
93 response_t &response,text_t &response_data,
94 ostream &/*logout*/) {
95 response = content;
96 response_data = "text/html";
97}
98
99
100bool wizardaction::check_cgiargs (cgiargsinfoclass &argsinfo, cgiargsclass &args,
101 recptprotolistclass * /*protos*/, ostream &logout) {
102
103 text_t current_page = args["p"];
104
105 if (current_page != "intro" &&
106 current_page != "bildframe1" && current_page != "new" && current_page != "select") {
107 // update arguments that were saved to the harddrive
108 text_tmap saved_args;
109
110 // update the argdb database with any arguments that were set
111 // by previous page as denoted by prefix (eg. di1 or bc1)
112
113 cgiargsclass::const_iterator args_here = args.begin();
114 cgiargsclass::const_iterator args_end = args.end();
115
116 while (args_here != args_end) {
117 text_t args_name = (*args_here).first;
118
119 int prefix_len = macro_prefix.size();
120 int args_name_len = args_name.size();
121
122 if(args_name_len >= prefix_len) { // Only now can we substring args_name by prefix_len
123 text_t args_prefix;
124 if(args_name_len > prefix_len) { // substring
125 args_prefix = substr(args_name.begin(),args_name.begin()+prefix_len);
126 } else {
127 args_prefix = args_name;
128 }
129
130 if (args_prefix == macro_prefix) {
131 // the saved_args are destined to be saved in the database.
132 // our database code assumes keys and values are in unicode code-point form
133 // for e.g. 'a macron' is a code-point of 257 in utf-16, represented as a u-short
134 // and not the 2 bytes version (0xC4 0x81) which is utf-8.
135 saved_args[args_name] = to_uni(args[args_name]);
136 }
137 }
138 ++args_here;
139 }
140
141 argdb *args_on_disk = new argdb(gsdlhome,args[macro_prefix+"tmp"]);
142 if (!args_on_disk->update_args(saved_args)) {
143 // error
144 logout << "wizardaction: argdb::update_args failed\n";
145 }
146
147 // update args from argdb
148 saved_args.erase(saved_args.begin(), saved_args.end());
149 if (!args_on_disk->get_args(saved_args)) {
150 // error
151 logout << "wizardaction: argdb::get_args failed\n";
152 }
153 delete args_on_disk;
154
155 text_tmap::iterator sa_here = saved_args.begin();
156 text_tmap::iterator sa_end = saved_args.end();
157 while (sa_here != sa_end) {
158 if (!(*sa_here).second.empty()) {
159 args[(*sa_here).first] = (*sa_here).second;
160 }
161 ++sa_here;
162 } bool first = true;
163
164 }
165
166 return true;
167}
168
169// tests if collection is write protected (currently just checks if
170// collect.cfg file is writable
171bool wizardaction::collection_protected (const text_t &collection) {
172 text_t cfgfile = filename_cat(collecthome, collection, "etc", "collect.cfg");
173 if (file_writable(cfgfile)) return false;
174 return true;
175}
176
177// set the _statusline_ macro
178void wizardaction::set_statusline (displayclass &disp, cgiargsclass &args, ostream & /*logout*/) {
179
180 // the build command creates .bld.download, .bld.import, and .bld.build files (in that
181 // order) and deletes them (also in that order) when each stage is complete. the .bld
182 // file is the concatenation of all these files.
183 text_t bld_file = filename_cat (gsdlhome, "tmp", args[macro_prefix+"tmp"], args[macro_prefix+"dirname"] + ".bld");
184 text_t statusline;
185
186 if (file_exists (bld_file + ".download")) {
187 statusline = "_collector:textdownloadingfiles_<br>\n";
188 statusline += dm_safe(file_tail(bld_file + ".download", 1, 0));
189 } else if (file_exists (bld_file + ".import")) {
190 statusline = "_collector:textimportingcollection_<br>\n";
191 statusline += dm_safe(file_tail(bld_file + ".import", 1, 0));
192 } else if (file_exists (bld_file + ".build")) {
193 statusline = "_collector:textbuildingcollection_<br>\n";
194 statusline += dm_safe(file_tail(bld_file + ".build", 1, 0));
195 } else {
196 statusline += "_collector:textcreatingcollection_<br>\n";
197 statusline += dm_safe(file_tail(bld_file, 1, 0));
198 }
199
200 disp.setmacro ("statusline", "collector", statusline);
201 disp.setmacro ("statusline", "depositor", statusline);
202}
203
204
205// if sw = 0 replace all carriage returns in intext with the string "\n"
206// else replace all occurances of "\n" with a carriage return
207text_t wizardaction::carriage_replace (const text_t &intext, int sw) {
208
209 text_t outtext;
210 text_t::const_iterator here = intext.begin();
211 text_t::const_iterator end = intext.end();
212 while (here != end) {
213 if (sw == 0) {
214 if (*here == '\n') {
215 if ((here+1) != end && *(here+1) == '\r') ++here;
216 outtext += "\\n";
217 } else if (*here == '\r') {
218 if ((here+1) != end && *(here+1) == '\n') ++here;
219 outtext += "\\n";
220 } else {
221 outtext.push_back (*here);
222 }
223 } else if (*here == '\\' && (here+1) != end && *(here+1) == 'n') {
224 outtext.push_back ('\n');
225 ++here;
226 } else {
227 outtext.push_back (*here);
228 }
229 ++here;
230 }
231 return outtext;
232}
233
234
235// create a short directory name from fullname
236text_t wizardaction::get_directory_name (const text_t &fullname) {
237
238 text_t shortname;
239 if (fullname.empty()) {
240 shortname = "coll";
241
242 } else {
243
244 // first make all lowercase and remove any dodgy characters
245 // (i.e. anything not [a-z]
246 text_t::const_iterator here = fullname.begin();
247 text_t::const_iterator end = fullname.end();
248 while (here != end) {
249 if ((*here >= 'A' && *here <= 'Z') || (*here >= 'a' && *here <= 'z') ||
250 (*here == ' ')) {
251 if (*here >= 'A' && *here <= 'Z') shortname.push_back (*here+32);
252 else if (*here == ' ') {
253 while ((*(here+1)) == ' ') ++here;
254 shortname.push_back (*here);
255 } else shortname.push_back (*here);
256 }
257 ++here;
258 }
259
260 text_tarray words;
261 splitchar (shortname.begin(), shortname.end(), ' ', words);
262 int num_words = words.size();
263
264 if (num_words == 0) {
265 shortname = "coll";
266
267 } else {
268
269 shortname.clear();
270 int use_words = (num_words <= 6) ? num_words : 6;
271 unsigned int substr_len = 6 / use_words;
272
273 for (int i = 0; i < use_words; ++i) {
274 if (words[i].size() < substr_len) shortname += words[i];
275 else shortname += substr (words[i].begin(), words[i].begin()+substr_len);
276 }
277 }
278 }
279
280 // check to see if shortname is unique
281 text_t fulldirname = filename_cat (collecthome, shortname);
282 if (directory_exists (fulldirname)) {
283 int version = 0;
284 text_t newname;
285 do {
286 ++version;
287 newname = shortname;
288 newname.push_back ('v');
289 newname.appendint (version);
290 fulldirname = filename_cat (collecthome, newname);
291 } while (directory_exists (fulldirname));
292
293 shortname = newname;
294 }
295
296 return shortname;
297}
298
299// assigns a temporary directory name for this collector session
300// and creates temporary directory
301// returns false if it couldn't create the directory
302bool wizardaction::assign_tmpname (cgiargsclass &args, ostream &logout) {
303
304 int i = 0;
305 text_t tmpname = "tbuild";
306 while (directory_exists (filename_cat (gsdlhome, "tmp", tmpname + text_t(i)))) {
307 ++i;
308 }
309 tmpname.appendint (i);
310
311 text_t fulltmpdir = filename_cat (gsdlhome, "tmp", tmpname);
312 if (!mk_dir (fulltmpdir)) {
313 outconvertclass text_t2ascii;
314 logout << text_t2ascii << "wizardaction::assign_tmpname unable to create directory ("
315 << fulltmpdir << ")\n";
316 return false;
317 }
318
319 args[macro_prefix + "tmp"] = tmpname;
320 return true;
321}
322
323// set the _fullnamemenu_ macro (and _warnindex_ and _selectedindex_ if
324// we're on the "srce" page)
325void wizardaction::set_fullnamemenu (displayclass &disp, cgiargsclass &args,
326 recptprotolistclass *protos, ostream &logout) {
327
328 if (recpt == NULL) {
329 logout << "ERROR (wizardaction::set_fullnamemenu): This action does not contain\n"
330 << " information about any receptionists. The method set_receptionist was\n"
331 << " probably not called from the module which instantiated this action.\n";
332 return;
333 }
334
335 text_t &current_page = args["p"];
336 text_t currentname = args[macro_prefix+"dirname"];
337 if (current_page == "srce") currentname = args[macro_prefix + "clonecol"];
338
339 text_tarray dirnames;
340 text_tarray fullnames;
341 vector<bool> write_protected;
342 text_tarray build_type;
343
344 bool is_selected = false;
345 int selected_index = 0;
346 int index = 0;
347
348 recptprotolistclass::iterator rprotolist_here = protos->begin();
349 recptprotolistclass::iterator rprotolist_end = protos->end();
350 while (rprotolist_here != rprotolist_end) {
351 if ((*rprotolist_here).p != NULL) {
352
353 // don't include z39.50 collections
354 comerror_t err = noError;
355 if ((*rprotolist_here).p->get_protocol_name (err) == "z3950proto") {
356 ++rprotolist_here;
357 continue;
358 }
359
360 text_tarray collist;
361 (*rprotolist_here).p->get_collection_list (collist, err, logout);
362 if (err == noError) {
363 text_tarray::iterator collist_here = collist.begin();
364 text_tarray::iterator collist_end = collist.end();
365 while (collist_here != collist_end) {
366 ColInfoResponse_t *cinfo = recpt->get_collectinfo_ptr ((*rprotolist_here).p, *collist_here, logout);
367 if (cinfo != NULL) {
368 text_t collectionname = cinfo->get_collectionmeta("collectionname", args["l"]);
369 if (collectionname.empty()) {
370 collectionname = *collist_here;
371 }
372 dirnames.push_back(*collist_here);
373 fullnames.push_back(collectionname);
374 // check to see if the collection is writable
375 if (collection_protected (*collist_here)) write_protected.push_back(true);
376 else write_protected.push_back(false);
377
378 // remember build type for collection (mg, mgpp, lucene, ...)
379 // used to determine cgi arg 'ct' later on and minus option to 'build'
380 build_type.push_back(cinfo->buildType);
381
382 if (*collist_here == currentname) {
383 is_selected = true;
384 selected_index = index;
385 }
386 ++index;
387 }
388 ++collist_here;
389 }
390 }
391 }
392 ++rprotolist_here;
393 }
394
395 bool first = true;
396
397 text_t warnindex;
398 text_t fullnamemenu = "<select name=\""+macro_prefix+"dirname\" onChange=\"menuchange();\">\n";
399 text_t buildtype_jsarray = "var buildtype = new Array(";
400
401 fullnamemenu += "<option value=\"\">_textselectoption_</option>\n";
402 buildtype_jsarray += "\"\" ";
403
404 for (int i = 0; i < index; ++i) {
405 // don't want write protected collections in list on "change existing
406 // collection" page
407 if (write_protected[i] && current_page == "existing") continue;
408 fullnamemenu += "<option value=\"" + dirnames[i] + "\"";
409 if (is_selected && i == selected_index) {
410 fullnamemenu += " selected";
411 ++selected_index;
412 is_selected = false;
413 }
414 fullnamemenu.push_back ('>');
415 fullnamemenu += fullnames[i] + " ("+dirnames[i]+")";
416 fullnamemenu.push_back ('\n');
417
418 buildtype_jsarray += ", \"" + build_type[i] + "\"";
419
420 first = false;
421 }
422 fullnamemenu += "</select>\n";
423
424 buildtype_jsarray += ");";
425
426 text_t action_name = get_action_name();
427 disp.setmacro ("fullnamemenu", action_name, fullnamemenu);
428 disp.setmacro ("buildtypearray", action_name, buildtype_jsarray);
429}
430
431// checks to see if any of the plugins in pluginset occur in
432// collections configuration file
433bool wizardaction::uses_weird_plugin (const text_t &collection) {
434
435 text_tset pluginset;
436 pluginset.insert ("HBPlug");
437
438 text_t cfgfile_content;
439 text_t cfgfile_name = filename_cat (collecthome, collection, "etc", "collect.cfg");
440 text_t pluginstr, pluginname;
441
442 if (read_file (cfgfile_name, cfgfile_content)) {
443 text_t::const_iterator here = cfgfile_content.begin();
444 text_t::const_iterator end = cfgfile_content.end();
445 while (here != end) {
446 here = findchar (here, end, 'p');
447 if (here == end) break;
448 if ((here+6 < end) && (substr (here, here+6) == "plugin")) {
449 getdelimitstr (here+6, end, '\n', pluginstr);
450 text_t::const_iterator hp = pluginstr.begin();
451 text_t::const_iterator ep = pluginstr.end();
452 bool found = false;
453 // remove any leading whitespace, trailing options etc.
454 while (hp != ep) {
455 if (*hp == '\t' || *hp == ' ' || *hp == '\n') {
456 if (found) break;
457 } else {
458 pluginname.push_back (*hp);
459 found = true;
460 }
461 ++hp;
462 }
463 text_tset::const_iterator it = pluginset.find (pluginname);
464 if (it != pluginset.end()) return true; // found matching plugin
465 pluginname.clear();
466 }
467 ++here;
468 }
469 }
470 return false;
471}
472
473void wizardaction::gsdl_build (cgiargsclass &args, ostream &logout) {
474
475 outconvertclass text_t2ascii;
476
477 //check to see if the tbuild directory exists
478 text_t tmpdir = filename_cat (gsdlhome, "tmp", args[macro_prefix+"tmp"]);
479 if (!directory_exists (tmpdir)) {
480 message = "tmpfail";
481 return;
482 }
483
484 //check to see if collection name specified
485 text_t &collection = args[macro_prefix+"dirname"];
486 if (collection.empty()) {
487 message = "nocollection";
488 return;
489 }
490
491 // check for a .build file - if it exists then we've already built
492 // the collection (or are in the process of building it)
493 text_t buildfile = filename_cat (tmpdir, ".build");
494 if (file_exists (buildfile)) {
495 return;
496 } else {
497 // create the .build file (this file is just a place holder to let any future
498 // pages know that we've already been here)
499 char *buildfilec = buildfile.getcstr();
500 ofstream bfile_out (buildfilec);
501 delete []buildfilec;
502 if (bfile_out) {
503 bfile_out << "collection building\n";
504 bfile_out.close();
505 } else {
506 message = "tmpfail";
507 return;
508 }
509 }
510
511 //FLAG!
512 const recptconf &rcinfo = recpt->get_configinfo ();
513
514 // create the event header file if LogEvents, EmailEvents or
515 // EmailUserEvents options are turned on.
516 bool logevents =
517 (rcinfo.LogEvents == CollectorEvents || rcinfo.LogEvents == AllEvents ||
518 rcinfo.EmailEvents == CollectorEvents || rcinfo.EmailEvents == AllEvents ||
519 rcinfo.EmailUserEvents);
520 text_t ehead_file = filename_cat (tmpdir, "ehead.txt");
521 if (logevents) {
522 if (!create_event_header_file (ehead_file, args, logout)) {
523 logevents = false;
524 }
525 }
526
527 text_t collectdir = get_collectdir (args);
528
529 // set up build options
530 //text_t options = "-make_writable -remove_import -out \"";
531 text_t options = "-make_writable -out \"";
532 options += filename_cat (tmpdir, collection + ".bld");
533 options += "\" -collectdir \"" + collectdir + "\" -statsfile \"";
534 options += filename_cat(collectdir, collection, "etc", "import.log") + "\"";
535 // are we building in place? if so, don't install as if we have a non standard collect home it will try to copy into gsdl/collect
536 if (collectdir == collecthome) {
537 options += " -dontinstall";
538 }
539
540 if (args[macro_prefix+"esrce"] == 1) {
541 // we're adding data to an existing collection
542 options += " -save_archives";
543 if (args[macro_prefix+"cfgchanged"] !=1) { // collector, have modified cfg file as well, so need to do a full reimport.
544 options += " -append";
545 }
546 if (macro_prefix == "di1") { // depositor, always use manifest
547 options += " -manifest";
548 }
549
550 }
551
552 text_tarray inputvalues, inputtypes;
553 splitchar (args[macro_prefix+"input"].begin(), args[macro_prefix+"input"].end(), ',', inputvalues);
554 splitchar (args[macro_prefix+"inputtype"].begin(), args[macro_prefix+"inputtype"].end(), ',', inputtypes);
555 int numvalues = inputvalues.size();
556 int numtypes = inputtypes.size();
557 for (int i = 0; i < numvalues; ++i) {
558 if (!inputvalues[i].empty()) {
559 text_t type = "file://"; // default
560 if (i < numtypes) type = inputtypes[i];
561 options += " -download \"" +
562 remove_trailing_slashes(type + format_url(decode_commas(inputvalues[i]))) + "\"";
563 }
564 }
565
566 if (logevents) {
567 if (rcinfo.LogEvents == CollectorEvents || rcinfo.LogEvents == AllEvents)
568 options += " -log_events";
569 if (rcinfo.EmailEvents == CollectorEvents || rcinfo.EmailEvents == AllEvents) {
570 options += " -mail_server " + rcinfo.MailServer;
571 options += " -email_events " + rcinfo.maintainer;
572 if (rcinfo.EmailUserEvents) options += "," + args[macro_prefix+"contactemail"];
573 } else if (rcinfo.EmailUserEvents) {
574 options += " -mail_server " + rcinfo.MailServer;
575 options += " -email_events " + args[macro_prefix+"contactemail"];
576 }
577 options += " -event_header " + ehead_file;
578 }
579
580 text_t indextype = args[macro_prefix+"buildtype"];
581 if(indextype == "") {
582#ifdef ENABLE_MG
583 indextype = "mg";
584#else
585 cerr << "Unable to choose mg as the default indextype, since the Greenstone installation was not compiled with MG enabled." << endl;
586#endif
587 }
588 options += " -indextype \"" + indextype + "\"";
589
590 text_t optionfile = filename_cat (tmpdir, "build.opt");
591 char *optionfilec = optionfile.getcstr();
592 ofstream ofile_out (optionfilec);
593 delete []optionfilec;
594 if (!ofile_out) {
595 message = "tmpfail";
596 return;
597 }
598 ofile_out << text_t2ascii << options << "\n";
599 ofile_out.close();
600
601 // if we're altering an existing collection we need to kill off
602 // the existing collection server - we do this for the local library
603 // (and any other persistent version of the library) as the existing
604 // database file can't be deleted while the collection server holds it open
605 if ((args[macro_prefix+"econf"] == 1) || (args[macro_prefix+"esrce"] == 1)) {
606 remove_colservr (collection, logout);
607 }
608
609 // set up the build command - build.bat has some issues with quoting
610 // on win2k when gsdlhome contains spaces so we'll avoid using
611 // "perl -S" here in favor of calling the "build" perl script explicitly
612 text_t build_cmd = "perl \"" + filename_cat (gsdlhome, "bin", "script", "build");
613 build_cmd += "\" -optionfile \"" + optionfile + "\" " + collection;
614
615 // run build command in background (i.e. asynchronously)
616 gsdl_system (build_cmd, false, logout);
617
618}
619
620void wizardaction::gsdl_cancel_build (cgiargsclass &args, ostream &logout) {
621 // I really wanted to do what this perl script does from within the library
622 // c++ code. I ran into some problems though (like how do you write a portable
623 // "rm -r" in c++?). One day I'll spend some time sorting it out ... maybe.
624 text_t cancel_cmd = "perl -S cancel_build.pl -collectdir \"";
625 cancel_cmd += filename_cat (gsdlhome, "tmp", args[macro_prefix+"tmp"]) + "\" ";
626 cancel_cmd += args[macro_prefix+"dirname"];
627 // To be on the safe side we'll make this a synchronous call
628 // so that all tidying up is done before the user has a chance
629 // to do anything else (like start rebuilding their collection).
630 // This means that for a big collection where there's lots of
631 // stuff to delete etc. it might take a while before the "build
632 // cancelled" page appears.
633 gsdl_system (cancel_cmd, true, logout);
634}
635
636text_t wizardaction::get_collectdir (cgiargsclass &args)
637{
638 if ((args[macro_prefix+"econf"] == 1) || (args[macro_prefix+"esrce"] == 1)) {
639 // we're adding to a collection in place
640 return collecthome;
641 }
642 else {
643 return filename_cat (gsdlhome, "tmp", args[macro_prefix+"tmp"]);
644 }
645}
646
647// create and initialize a new collection server and
648// add it to the null protocol.
649void wizardaction::create_colserver (const text_t &collection, ostream &logout) {
650
651 recptprotolistclass *protos = recpt->get_recptprotolist_ptr();
652 recptprotolistclass::iterator rprotolist_here = protos->begin();
653 recptprotolistclass::iterator rprotolist_end = protos->end();
654 while (rprotolist_here != rprotolist_end) {
655 comerror_t err = noError;
656 if ((*rprotolist_here).p != NULL) {
657 if ((*rprotolist_here).p->get_protocol_name (err) == "nullproto") {
658 // create collection server and add it to nullproto
659 (*rprotolist_here).p->add_collection (collection, recpt, gsdlhome, collecthome, dbhome);
660 // make sure gsdlhome is configured
661 text_tarray tmp;
662 tmp.push_back (gsdlhome);
663 (*rprotolist_here).p->configure ("gsdlhome", tmp, err);
664 // re-initialize the null protocol
665 if (!(*rprotolist_here).p->init (err, logout)) {
666 logout << "wizardaction::create_colserver: nullproto init failed\n";
667 }
668 return;
669 }
670 }
671 ++rprotolist_here;
672 }
673
674 logout << "wizardaction::create_colserver: no valid nullproto found\n";
675}
676
677// delete a collection server from the null protocol
678void wizardaction::remove_colservr (const text_t &collection, ostream &logout) {
679
680 recpt->uncache_collection (collection);
681
682 recptprotolistclass *protos = recpt->get_recptprotolist_ptr();
683 recptprotolistclass::iterator rprotolist_here = protos->begin();
684 recptprotolistclass::iterator rprotolist_end = protos->end();
685 while (rprotolist_here != rprotolist_end) {
686 comerror_t err = noError;
687 if ((*rprotolist_here).p != NULL) {
688 if ((*rprotolist_here).p->get_protocol_name (err) == "nullproto") {
689 (*rprotolist_here).p->remove_collection (collection, logout);
690 return;
691 }
692 }
693 ++rprotolist_here;
694 }
695
696 logout << "wizardaction::create_colserver: no valid nullproto found\n";
697}
698
699bool wizardaction::create_event_header_file (const text_t &filename, cgiargsclass &args,
700 ostream &logout) {
701
702 outconvertclass text_t2ascii;
703 char *filenamec = filename.getcstr();
704 ofstream eheadfile (filenamec);
705 delete []filenamec;
706
707 if (eheadfile) {
708 eheadfile << text_t2ascii << get_event_header (args);
709 eheadfile.close();
710 return true;
711 }
712
713 logout << text_t2ascii << "wizardaction::create_event_header ERROR: Couldn't create "
714 << "Event Header file " << filename << ". Event logging disabled\n";
715 return false;
716}
717
718text_t wizardaction::get_event_header (cgiargsclass &args) {
719 text_t header = "Greenstone Username: " + args["un"] + "\n";
720 header += "Collection: " + args[macro_prefix+"dirname"] + "\n";
721 header += "Collection Creator: " + args[macro_prefix+"contactemail"] + "\n";
722 header += "GSDLHOME: " + gsdlhome + "\n";
723 header += "Build Location: " + get_collectdir(args) + "\n";
724
725 return header;
726}
727
728
729// format_url simply strips "http://", "ftp://", or "file://" off the
730// beginning of url if they're there
731text_t wizardaction::format_url (const text_t &url) {
732 text_t::const_iterator begin = url.begin();
733 text_t::const_iterator end = url.end();
734
735 if (url.size() >= 7) {
736 text_t prefix = substr(begin, begin+7);
737 if (prefix == "http://" || prefix == "file://") {
738 return substr(begin+7, end);
739 }
740 }
741 if (url.size() >= 6) {
742 if (substr(begin, begin+6) == "ftp://") {
743 return substr(begin+6, end);
744 }
745 }
746 return url;
747}
748
749text_t wizardaction::remove_trailing_slashes (text_t str) {
750
751 while (*(str.end()-1) == '\\') {
752 str.pop_back();
753 }
754 return str;
755}
756
757#endif //GSDL_USE_WIZARD_ACTION
Note: See TracBrowser for help on using the repository browser.