source: gsdl/trunk/src/recpt/wizardaction.cpp@ 16310

Last change on this file since 16310 was 16310, checked in by davidb, 16 years ago

Introduction of 'collecthome' which parallels 'gsdlhome' to allow the toplevel collect folder to be outside of the gsdlhome area

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