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

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

minor modifications to get web library compiling under VC++ 6.0

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