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

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

tidied up windows installation

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