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

Last change on this file since 822 was 822, checked in by davidb, 24 years ago

Added viewable log for collection building.

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