root/gsdl/trunk/src/recpt/wizardaction.cpp @ 15597

Revision 15597, 24.6 KB (checked in by mdewsnip, 12 years ago)

Removed "gdbm" from a couple of comments.

  • Property svn:keywords set to Author Date Id Revision
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(gsdlhome, "collect", 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 (gsdlhome, "collect", 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 (gsdlhome, "collect", 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 (gsdlhome, "collect", 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 filename_cat(gsdlhome, "collect"); 
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, gsdlhome);
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 browser.