source: trunk/gsdl/src/recpt/buildaction.cpp@ 1458

Last change on this file since 1458 was 1458, checked in by sjboddie, 24 years ago

Made buildaction ignore z39.50 collections

  • Property svn:keywords set to Author Date Id Revision
File size: 17.0 KB
Line 
1/**********************************************************************
2 *
3 * buildaction.cpp -- building collections
4 * Copyright (C) 1999 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 "OIDtools.h"
27#include "fileutil.h"
28#include "htmlutils.h"
29#include "gsdltools.h"
30#include "buildaction.h"
31
32///////////////
33// buildaction
34///////////////
35
36buildaction::buildaction () {
37 // this action uses cgi variable "a"
38 cgiarginfo arg_ainfo;
39 arg_ainfo.shortname = "a";
40 arg_ainfo.longname = "action";
41 arg_ainfo.multiplechar = true;
42 arg_ainfo.defaultstatus = cgiarginfo::weak;
43 arg_ainfo.argdefault = "bc"; // build collection
44 arg_ainfo.savedarginfo = cgiarginfo::must;
45 argsinfo.addarginfo (NULL, arg_ainfo);
46
47 // "bca"
48 arg_ainfo.shortname = "bca";
49 arg_ainfo.longname = "build collection action";
50 arg_ainfo.multiplechar = true;
51 arg_ainfo.defaultstatus = cgiarginfo::weak;
52 arg_ainfo.argdefault = "editcol";
53 arg_ainfo.savedarginfo = cgiarginfo::mustnot;
54 argsinfo.addarginfo (NULL, arg_ainfo);
55
56
57 // "mess"
58 arg_ainfo.shortname = "mess";
59 arg_ainfo.longname = "macro name of text for the message page";
60 arg_ainfo.multiplechar = true;
61 arg_ainfo.defaultstatus = cgiarginfo::weak;
62 arg_ainfo.argdefault = "";
63 arg_ainfo.savedarginfo = cgiarginfo::mustnot;
64 argsinfo.addarginfo (NULL, arg_ainfo);
65
66 // "head"
67 arg_ainfo.shortname = "head";
68 arg_ainfo.longname = "macro name of text to use as header for the message page";
69 arg_ainfo.multiplechar = true;
70 arg_ainfo.defaultstatus = cgiarginfo::weak;
71 arg_ainfo.argdefault = "";
72 arg_ainfo.savedarginfo = cgiarginfo::mustnot;
73 argsinfo.addarginfo (NULL, arg_ainfo);
74
75}
76
77bool buildaction::check_cgiargs (cgiargsinfoclass &/*argsinfo*/, cgiargsclass &args,
78 ostream &/*logout*/) {
79
80 text_t &arg_bca = args["bca"];
81 if (!((arg_bca == "buildstatus") || (arg_bca == "collog") || (arg_bca == "blankpage")
82 || ((arg_bca == "buildcol") && (args["wizard"] == "buildexec"))))
83 {
84 // authenticate the user if authentication is avaiable
85 args["uan"] = 1;
86 args["ug"] = "colbuilder";
87 }
88 return true;
89}
90
91void buildaction::get_cgihead_info (cgiargsclass &/*args*/, recptprotolistclass * /*protos*/,
92 response_t &response,text_t &response_data,
93 ostream &/*logout*/) {
94
95 response = content;
96 response_data = "text/html";
97}
98
99void buildaction::define_internal_macros (displayclass &disp, cgiargsclass &args,
100 recptprotolistclass *protos, ostream &logout) {
101
102 // make sure we know about a receptionist
103 if (recpt == NULL) {
104 logout << "The build action does not contain information\n"
105 << "about any receptionists. The method set_receptionist\n"
106 << "was probably not called from the module which instantiated\n"
107 << "this build action.\n";
108 return;
109 }
110
111 recptprotolistclass *rprotolist = recpt->get_recptprotolist_ptr ();
112 if (rprotolist == NULL) return;
113
114 // build up javascript and HTML code useful in web forms
115 text_t first_dirname = "";
116 text_t fullnamelist = "var fullnamelist = new Array(";
117 text_t dirnamelist = "var dirnamelist = new Array(";
118 text_t fullnamemenu = "<input type=hidden name=\"bc1fullnameindex\"";
119 fullnamemenu += " value=\"_bcargfullnameindex_\">\n";
120 fullnamemenu += "<select name=\"bc1fullnamemenu\" onChange=fullnameindex_changed()>\n";
121 int rcount = 1;
122 int fcount = 1;
123 int starting_fullname_index = 0;
124 disp.setmacro("bcargfirsttime","build","false");
125
126 recptprotolistclass::iterator rprotolist_here = protos->begin();
127 recptprotolistclass::iterator rprotolist_end = protos->end();
128 while (rprotolist_here != rprotolist_end) {
129 if ((*rprotolist_here).p != NULL) {
130
131 // don't include z39.50 collection
132 if ((*rprotolist_here).p->get_protocol_name () == "z3950proto") {
133 rprotolist_here ++;
134 continue;
135 }
136
137 text_tarray collist;
138 comerror_t err;
139 (*rprotolist_here).p->get_collection_list (collist, err, logout);
140 if (err == noError) {
141 text_tarray::iterator collist_here = collist.begin();
142 text_tarray::iterator collist_end = collist.end();
143
144 if (rcount>1) { fullnamelist += ","; }
145 fullnamelist += "new Array(";
146
147 FilterResponse_t response;
148 text_tset metadata;
149 metadata.insert ("collectionname");
150
151 int ccount = 1;
152
153 while (collist_here != collist_end) {
154
155 ColInfoResponse_t *cinfo = recpt->get_collectinfo_ptr ((*rprotolist_here).p, *collist_here, logout);
156 if (cinfo != NULL) {
157 text_t collectionname = *collist_here;
158 if (!cinfo->collectionmeta["collectionname"].empty())
159 {
160 // get collection name from the collection cfg file
161 collectionname = cinfo->collectionmeta["collectionname"];
162 }
163 else
164 {
165 if (get_info ("collection", *collist_here, metadata, false, (*rprotolist_here).p,
166 response, logout))
167 {
168 // get collection name from gdbm file
169 collectionname = response.docInfo[0].metadata["collectionname"].values[0];
170 }
171 }
172
173 if (ccount>1) { fullnamelist += ","; dirnamelist += ","; }
174 fullnamelist += (text_t)"\"" + collectionname + "\"";
175 dirnamelist += (text_t)"\"" + *collist_here + "\"";
176
177 fullnamemenu += "<option value=\"" + collectionname;
178 fullnamemenu.push_back ('"');
179 if (args["bc1dirname"].empty())
180 {
181 if ((rcount==1) && (ccount==1))
182 {
183 fullnamemenu += " selected";
184 first_dirname = *collist_here;
185 starting_fullname_index = 0;
186 }
187 }
188 else
189 {
190 if (args["bc1dirname"] == *collist_here)
191 {
192 fullnamemenu += " selected";
193 first_dirname = *collist_here;
194 starting_fullname_index = fcount-1;
195 }
196 }
197 fullnamemenu += (text_t)">" + collectionname;
198
199 // check to see if the "collection" is writable
200 text_t cfg_fname
201 = filename_cat(gsdlhome, "collect", *collist_here, "etc", "collect.cfg");
202 if (!file_writable(cfg_fname))
203 {
204 fullnamemenu += " <b>(write protected)</b>";
205 }
206
207 fullnamemenu += "\n";
208
209 if (args["bca"]=="buildcol")
210 {
211 if (((args["bc1dirname"].empty()) && (rcount==1) && (ccount==1))
212 || (args["bc1dirname"]==*collist_here))
213 {
214 disp.setmacro("bcargingsdlarea","build",cinfo->building["ingsdlarea"]);
215 disp.setmacro("bcargcopydir","build",cinfo->building["copydir"]);
216
217 if (cinfo->buildDate==0) // not built
218 {
219 // assume that's because this is the first build ever for the collection
220 args["bc1copydata"]="true";
221 disp.setmacro("bcargcopydata","build","true");
222 disp.setmacro("bcargfirsttime","build","true"); // override value
223 }
224 }
225 }
226
227 ccount++;
228 fcount++;
229 }
230 collist_here ++;
231 }
232
233 fullnamelist += ")";
234 }
235 rcount ++;
236 }
237 fullnamelist += ");\n";
238 dirnamelist += ");\n";
239
240 fullnamemenu += "</select>\n";
241 rprotolist_here ++;
242 }
243
244 if ((args["bca"]=="newcol") || (args["bca"]=="editcol"))
245 {
246 disp.setmacro ("fullnamelist", "build", fullnamelist);
247 }
248
249 if ((args["bca"]=="delcol") || (args["bca"]=="editcol") ||
250 (args["bca"]=="buildcol") || (args["bca"]=="collog"))
251 {
252 disp.setmacro ("dirnamelist", "build", dirnamelist);
253 disp.setmacro ("fullnamemenu", "build", fullnamemenu);
254 disp.setmacro ("bcargfullnameindex", "build", starting_fullname_index);
255 }
256
257
258 // define special "wizard" form value so webform building process can
259 // keep track of which page it is on
260 text_t wizard_value
261 = (args["wizard"] == "") ? (text_t)"textinfo" : args["wizard"];
262 text_t hiddenargs
263 = "<input type=\"hidden\" name=\"wizard\" value=\""+wizard_value+"\">\n";
264 disp.setmacro ("hiddenargs", "build", hiddenargs);
265 disp.setmacro ("wizard", "build", wizard_value);
266
267 // cache any cgi arguments starting "newcol:" (from previous webform)
268 cgiargsclass::const_iterator args_here = args.begin();
269 cgiargsclass::const_iterator args_end = args.end();
270 while (args_here != args_end) {
271 // define macro if args came from a previous col building webpage
272 text_t args_entry = (*args_here).first;
273
274 if (substr(args_entry.begin(),args_entry.begin()+3) == "bc1")
275 {
276 text_t bc1name = substr(args_entry.begin()+3,args_entry.end());
277 text_t cached_cgiarg = "bcarg" + bc1name;
278 disp.setmacro(cached_cgiarg, "build", dm_safe(args[args_entry]));
279 }
280 args_here++;
281 }
282
283 // set macro cfgperm based on whether config file can be read or no
284 text_t dirname = (args["bc1dirname"] == "") ? first_dirname : args["bc1dirname"];
285 text_t cfg_fname = filename_cat(gsdlhome, "collect", dirname, "etc", "collect.cfg");
286 text_t cfgperm = (file_writable(cfg_fname)) ? text_t("read/write") : text_t("readonly");
287 disp.setmacro("cfgperm","build",cfgperm);
288
289 // if edit collection, read in collect.cfg file
290 if (args["bca"]=="editcol")
291 {
292 text_t dirname
293 = (args["bc1dirname"] == "") ? first_dirname : args["bc1dirname"];
294
295 // read in collect.cfg
296 text_t cfg_fname
297 = filename_cat(gsdlhome, "collect", dirname, "etc", "collect.cfg");
298
299#ifdef GSDL_USE_IOS_H
300 ifstream cfg_ifs (cfg_fname.getcstr(), ios::in | ios::nocreate);
301#else
302 ifstream cfg_ifs (cfg_fname.getcstr(), ios::in);
303#endif
304
305 if (cfg_ifs)
306 {
307 // read in collect.cfg
308 text_t cfg_text = "";
309
310 char c;
311 cfg_ifs.get(c);
312 while (!cfg_ifs.eof ()) {
313 cfg_text.push_back(c);
314 if (c=='\\') { cfg_text.push_back('\\'); }
315 cfg_ifs.get(c);
316 }
317
318 cfg_ifs.close();
319 if (cfgperm=="readonly") cfg_text = html_safe(cfg_text);
320
321 // define it as a macro
322 disp.setmacro("cfgfile","build",cfg_text);
323 }
324 else
325 {
326 text_t error_mess = "Unable to read configuration file: "+cfg_fname;
327 disp.setmacro("cfgfile","build",error_mess);
328 }
329 }
330
331 // if view log, read in collect.bld file
332 if (args["bca"]=="collog")
333 {
334 text_t dirname
335 = (args["bc1dirname"] == "") ? first_dirname : args["bc1dirname"];
336
337 // read in collect.bld
338 text_t bld_fname = filename_cat(gsdlhome, "etc", dirname+ ".bld");
339
340#ifdef GSDL_USE_IOS_H
341 ifstream bld_ifs (bld_fname.getcstr(), ios::in | ios::nocreate);
342#else
343 ifstream bld_ifs (bld_fname.getcstr(), ios::in);
344#endif
345
346 if (bld_ifs)
347 {
348 text_t bld_text = "";
349
350 char c;
351 bld_ifs.get(c);
352 while (!bld_ifs.eof ()) {
353 bld_text.push_back(c);
354 if (c=='\\') { bld_text.push_back('\\'); }
355 bld_ifs.get(c);
356 }
357
358 bld_ifs.close();
359 bld_text = html_safe(bld_text);
360
361 // define it as a macro
362 disp.setmacro("bldfile","build",bld_text);
363 }
364 else
365 {
366 text_t error_mess = "Log file currently empty.";
367 disp.setmacro("bldfile","build",error_mess);
368 }
369 }
370}
371
372bool buildaction::do_action (cgiargsclass &args, recptprotolistclass * /*protos*/,
373 browsermapclass * /*browsers*/, displayclass &disp,
374 outconvertclass &outconvert, ostream &textout,
375 ostream &logout) {
376
377 // make sure we know about a receptionist
378 if (recpt == NULL) {
379 logout << "The page action does not contain information\n"
380 << "about any receptionists. The method set_receptionist\n"
381 << "was probably not called from the module which instantiated\n"
382 << "this page action.\n";
383 return false;
384 }
385
386 if (args["bca"] == "newcol") {
387 return do_newcol (args, disp, outconvert, textout, logout);
388 }
389 else if (args["bca"] == "editcol") {
390 return do_editcol (args, disp, outconvert, textout, logout);
391 }
392 else if (args["bca"] == "buildcol") {
393 return do_buildcol (args, disp, outconvert, textout, logout);
394 }
395 else if (args["bca"] == "buildstatus") {
396 return do_buildstatus (args, disp, outconvert, textout, logout);
397 }
398 else if (args["bca"] == "delcol") {
399 return do_delcol (args, disp, outconvert, textout, logout);
400 }
401 else if (args["bca"] == "collog") {
402 return do_collog (args, disp, outconvert, textout, logout);
403 }
404 else if (args["bca"] == "mess") {
405 return do_mess (args, disp, outconvert, textout, logout);
406 }
407
408 // default (bca == blankpage)
409 textout << outconvert << "<html><body bgcolor=#ffffff></body></html>\n";
410
411 return true;
412}
413
414
415
416bool buildaction::do_newcol (cgiargsclass &args, displayclass &disp,
417 outconvertclass &outconvert, ostream &textout,
418 ostream &/*logout*/) {
419
420 text_tarray wizard_split;
421 const text_t& wizard = (args["wizard"] == "") ? (text_t)"textinfo" : args["wizard"];
422 splitchar(wizard.begin(),wizard.end(),':',wizard_split);
423 const text_t& wizard_last = wizard_split.back();
424
425 text_t content = "_build:content" + wizard_last + "_\n";
426 text_t headmess = "_build:header_(_build:headmess" + wizard_last + "_)\n";
427
428 textout << outconvert << disp << (headmess) << (content) << ("_build:wizardfooter_\n");
429
430 return true;
431}
432
433
434bool buildaction::do_editcol (cgiargsclass &/*args*/, displayclass &disp,
435 outconvertclass &outconvert, ostream &textout,
436 ostream &/*logout*/) {
437
438 textout << outconvert << disp << ("_build:header_(_build:headmesseditcol_)\n")
439 << ("_build:contenteditcol_\n")
440 << ("_build:wizardfooter_\n");
441
442 return true;
443}
444
445bool buildaction::do_buildcol (cgiargsclass &args, displayclass &disp,
446 outconvertclass &outconvert, ostream &textout,
447 ostream &logout) {
448
449 text_tarray wizard_split;
450 const text_t wizard = (args["wizard"].empty()) ? "buildcol" : args["wizard"];
451 splitchar(wizard.begin(),wizard.end(),':',wizard_split);
452 const text_t wizard_last = wizard_split.back();
453
454 if (wizard_last != "buildframe")
455 {
456 text_t headmess = "_build:header_(_build:headmess" + wizard_last + "_)\n";
457 text_t content = "_build:content" + wizard_last + "_\n";
458
459 textout << outconvert << disp << headmess << content << "_build:wizardfooter_\n";
460 }
461 else
462 {
463 text_t dirname = (args["bc1dirname"] == "") ?
464 "unknown" : args["bc1dirname"];
465
466 text_t tmpname = dirname+"_XXXXXX";
467 char *cstr_tmpname = tmpname.getcstr();
468
469 if (GSDL_MKTEMP (cstr_tmpname)==NULL)
470 logout << "Failed to create temporary filename" << endl;
471
472 delete cstr_tmpname;
473
474 disp.setmacro("bcargtmpname","build",tmpname);
475
476
477 text_t headmess = "_build:frameheader_(_build:headmess" + wizard_last + "_)\n";
478 text_t content = "_build:content" + wizard_last + "_\n";
479
480 textout << outconvert << disp << headmess << content << "_build:framefooter_\n";
481 text_t cmd = "perl \"" +
482 filename_cat(gsdlhome, "cgi-bin", "webpage_buildcol.pl") + "\"";
483 cmd += " \"httpbuild="+args["httpbuild"]+"\"";
484 cmd += " \"bc1copydata="+args["bc1copydata"]+"\"";
485 cmd += " \"bc1doimport="+args["bc1doimport"]+"\"";
486 cmd += " \"bc1dobuild="+args["bc1dobuild"]+"\"";
487 cmd += " \"bc1dirname="+args["bc1dirname"]+"\" \"bc1tmpname="+tmpname+"\"";
488 // run webpage_buildcol.pl in background on unix systems
489#if !defined (__WIN32__)
490 cmd += " &";
491#endif
492
493 char *cstr_cmd = cmd.getcstr();
494
495#if defined (__WIN32__)
496 gsdl_system (cstr_cmd, logout);
497#else
498 system (cstr_cmd);
499#endif
500
501 delete cstr_cmd;
502 }
503
504 return true;
505}
506
507bool buildaction::do_buildstatus (cgiargsclass &args, displayclass &disp,
508 outconvertclass &outconvert, ostream &textout,
509 ostream &/*logout*/) {
510
511 disp.setmacro("contentpara","buildstatus", args["mess"]);
512
513 textout << outconvert << disp << ("_buildstatus:header_\n")
514 << ("_buildstatus:content_\n")
515 << ("_buildstatus:footer_\n");
516
517 return true;
518}
519
520bool buildaction::do_delcol (cgiargsclass &/*args*/, displayclass &disp,
521 outconvertclass &outconvert, ostream &textout,
522 ostream &/*logout*/) {
523
524 textout << outconvert << disp << ("_build:header_(_build:headmessdelcol_)\n")
525 << ("_build:contentdelcol_\n")
526 << ("_build:footer_\n");
527
528 return true;
529}
530
531
532bool buildaction::do_collog (cgiargsclass &/*args*/, displayclass &disp,
533 outconvertclass &outconvert, ostream &textout,
534 ostream &/*logout*/) {
535 textout << outconvert << disp << ("_build:header_(_build:headmesscollog_)\n")
536 << ("_build:contentcollog_\n")
537 << ("_build:wizardfooter_\n");
538
539 return true;
540}
541
542bool buildaction::do_mess (cgiargsclass &args, displayclass &disp,
543 outconvertclass &outconvert, ostream &textout,
544 ostream &/*logout*/) {
545
546 disp.setmacro("contentpara","buildmess", args["mess"]);
547 disp.setmacro("headmess","buildmess", args["head"]);
548 textout << outconvert << disp << ("_build:header_(_buildmess:headmess_)\n")
549 << ("_buildmess:content_\n")
550 << ("_build:footer_\n");
551
552 return true;
553}
Note: See TracBrowser for help on using the repository browser.