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

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

gsdlhome now comes from gsdlsite.cfg

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