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

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

modifications for windows port of GCC

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