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

Last change on this file since 12019 was 12019, checked in by davidb, 18 years ago

Minor improvements to depositor action.

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