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

Last change on this file since 723 was 723, checked in by davidb, 25 years ago

Support for building collections through web pages
and internal and external links in collection documents

  • Property svn:keywords set to Author Date Id Revision
File size: 14.7 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 "buildaction.h"
31
32///////////////
33// buildaction
34///////////////
35
36buildaction::buildaction () {
37 // this action uses cgi variable "a"
38 cgiarginfo arg_ainfo;
39 arg_ainfo.shortname = "a";
40 arg_ainfo.longname = "action";
41 arg_ainfo.multiplechar = true;
42 arg_ainfo.defaultstatus = cgiarginfo::weak;
43 arg_ainfo.argdefault = "bc"; // build collection
44 arg_ainfo.savedarginfo = cgiarginfo::must;
45 argsinfo.addarginfo (NULL, arg_ainfo);
46
47 // "bca"
48 arg_ainfo.shortname = "bca";
49 arg_ainfo.longname = "build collection action";
50 arg_ainfo.multiplechar = true;
51 arg_ainfo.defaultstatus = cgiarginfo::weak;
52 arg_ainfo.argdefault = "editcol";
53 arg_ainfo.savedarginfo = cgiarginfo::mustnot;
54 argsinfo.addarginfo (NULL, arg_ainfo);
55
56
57 // "mess"
58 arg_ainfo.shortname = "mess";
59 arg_ainfo.longname = "macro name of text for the message page";
60 arg_ainfo.multiplechar = true;
61 arg_ainfo.defaultstatus = cgiarginfo::weak;
62 arg_ainfo.argdefault = "";
63 arg_ainfo.savedarginfo = cgiarginfo::mustnot;
64 argsinfo.addarginfo (NULL, arg_ainfo);
65
66 // "head"
67 arg_ainfo.shortname = "head";
68 arg_ainfo.longname = "macro name of text to use as header for the message page";
69 arg_ainfo.multiplechar = true;
70 arg_ainfo.defaultstatus = cgiarginfo::weak;
71 arg_ainfo.argdefault = "";
72 arg_ainfo.savedarginfo = cgiarginfo::mustnot;
73 argsinfo.addarginfo (NULL, arg_ainfo);
74
75}
76
77bool buildaction::check_cgiargs (cgiargsinfoclass &/*argsinfo*/, cgiargsclass &args,
78 ostream &/*logout*/) {
79 if (args["bca"] != "buildstatus")
80 {
81 // authenticate the user if authentication is avaiable
82 args["uan"] = 1;
83 args["ug"] = "colbuilder";
84 }
85 return true;
86}
87
88void buildaction::get_cgihead_info (cgiargsclass &/*args*/, response_t &response,
89 text_t &response_data, ostream &/*logout*/) {
90
91 response = content;
92 response_data = "text/html";
93}
94
95void buildaction::define_internal_macros (const ColInfoResponse_t &/*collectinfo*/, displayclass &disp,
96 cgiargsclass &args, recptproto * /*collectproto*/,
97 ostream &logout) {
98
99 // make sure we know about a receptionist
100 if (recpt == NULL) {
101 logout << "The page action does not contain information\n"
102 << "about any receptionists. The method set_receptionist\n"
103 << "was probably not called from the module which instantiated\n"
104 << "this page action.\n";
105 return;
106 }
107
108 recptprotolistclass *rprotolist = recpt->get_recptprotolist_ptr ();
109 if (rprotolist == NULL) return;
110
111 const recptconf &rcinfo = recpt->get_configinfo ();
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 = rprotolist->begin();
126 recptprotolistclass::iterator rprotolist_end = rprotolist->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(rcinfo.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"))
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 // if edit collection, read in collect.cfg file
275 if (args["bca"]=="editcol")
276 {
277 text_t dirname
278 = (args["bc1dirname"] == "") ? first_dirname : args["bc1dirname"];
279
280 // read in collect.cfg
281 text_t cfg_fname
282 = filename_cat(rcinfo.gsdlhome,"collect",dirname,"etc","collect.cfg");
283 ifstream cfg_ifs (cfg_fname.getcstr(), ios::in | ios::nocreate);
284 if (cfg_ifs)
285 {
286 text_t cfg_text = "";
287
288 char c;
289 cfg_ifs.get(c);
290 while (!cfg_ifs.eof ()) {
291 cfg_text.push_back(c);
292 cfg_ifs.get(c);
293 }
294
295 cfg_ifs.close();
296
297 // define it as a macro
298 disp.setmacro("cfgfile","build",cfg_text);
299 }
300 else
301 {
302 text_t error_mess = "Unable to read configuration file: "+cfg_fname;
303 disp.setmacro("cfgfile","build",error_mess);
304 }
305 }
306}
307
308void buildaction::define_external_macros (const ColInfoResponse_t &/*collectinfo*/, displayclass &/*disp*/,
309 cgiargsclass &/*args*/, recptproto * /*collectproto*/,
310 ostream &/*logout*/) {
311}
312
313bool buildaction::do_action (cgiargsclass &args, const ColInfoResponse_t &/*collectinfo*/,
314 recptproto *collectproto, displayclass &disp,
315 outconvertclass &outconvert, ostream &textout,
316 ostream &logout) {
317
318
319
320
321 if (args["bca"] == "newcol") {
322 return do_newcol (args, collectproto, disp, outconvert, textout, logout);
323 }
324 else if (args["bca"] == "editcol") {
325 return do_editcol (args, collectproto, disp, outconvert, textout, logout);
326 }
327 else if (args["bca"] == "buildcol") {
328 return do_buildcol (args, collectproto, disp, outconvert, textout, logout);
329 }
330 else if (args["bca"] == "buildstatus") {
331 return do_buildstatus (args, collectproto, disp, outconvert, textout, logout);
332 }
333 else if (args["bca"] == "delcol") {
334 return do_delcol (args, collectproto, disp, outconvert, textout, logout);
335 }
336 else if (args["bca"] == "mess") {
337 return do_mess (args, collectproto, disp, outconvert, textout, logout);
338 }
339
340 // default (bca == blankpage)
341 textout << outconvert << "<html><body bgcolor=#ffffff></body></html>\n";
342
343 return true;
344}
345
346
347
348bool buildaction::do_newcol (cgiargsclass &args, recptproto */*collectproto*/,
349 displayclass &disp, outconvertclass &outconvert,
350 ostream &textout, ostream &/*logout*/) {
351
352 text_tarray wizard_split;
353 const text_t& wizard = (args["wizard"] == "") ? (text_t)"textinfo" : args["wizard"];
354 splitchar(wizard.begin(),wizard.end(),':',wizard_split);
355 const text_t& wizard_last = wizard_split.back();
356
357 text_t content = "_build:content" + wizard_last + "_\n";
358 text_t headmess = "_build:header_(_build:headmess" + wizard_last + "_)\n";
359
360 textout << outconvert << disp << (headmess) << (content) << ("_build:wizardfooter_\n");
361
362 return true;
363}
364
365
366bool buildaction::do_editcol (cgiargsclass &/*args*/, recptproto */*collectproto*/,
367 displayclass &disp, outconvertclass &outconvert,
368 ostream &textout, ostream &/*logout*/) {
369
370 textout << outconvert << disp << ("_build:header_(_build:headmesseditcol_)\n")
371 << ("_build:contenteditcol_\n")
372 << ("_build:wizardfooter_\n");
373
374 return true;
375}
376
377bool buildaction::do_buildcol (cgiargsclass &args, recptproto */*collectproto*/,
378 displayclass &disp, outconvertclass &outconvert,
379 ostream &textout, ostream &logout) {
380
381
382 text_tarray wizard_split;
383 const text_t& wizard = (args["wizard"]=="") ? (text_t)"buildcol" : args["wizard"];
384 splitchar(wizard.begin(),wizard.end(),':',wizard_split);
385 const text_t& wizard_last = wizard_split.back();
386
387 if (wizard_last != "buildframe")
388 {
389 text_t headmess = "_build:header_(_build:headmess" + wizard_last + "_)\n";
390 text_t content = "_build:content" + wizard_last + "_\n";
391
392 textout << outconvert << disp << headmess << content << "_build:wizardfooter_\n";
393 }
394 else
395 {
396 text_t dirname = (args["bc1dirname"] == "") ? (text_t)"unknown" : args["bc1dirname"];
397 text_t tmpname = dirname+"_XXXXXX";
398 if (mktemp(tmpname.getcstr())==NULL)
399 {
400 logout << "Failed to create temporary filename" << endl;
401 }
402 disp.setmacro("bcargtmpname","build",tmpname);
403
404
405 text_t headmess = "_build:frameheader_(_build:headmess" + wizard_last + "_)\n";
406 text_t content = "_build:content" + wizard_last + "_\n";
407
408 textout << outconvert << disp << headmess << content << "_build:framefooter_\n";
409
410 const recptconf &rcinfo = recpt->get_configinfo ();
411 text_t cmd = filename_cat(rcinfo.gsdlhome,"cgi-bin","webpage_buildcol.pl");
412 cmd += " gsdlhome=\""+args["gsdlhome"]+"\" httpbuild=\""+args["httpbuild"]+"\"";
413 cmd += " bc1copydata=\""+args["bc1copydata"]+"\"";
414 cmd += " bc1doimport=\""+args["bc1doimport"]+"\"";
415 cmd += " bc1dobuild=\""+args["bc1dobuild"]+"\"";
416 cmd += " bc1dirname=\""+args["bc1dirname"]+"\" bc1tmpname=\""+tmpname+"\" &";
417
418 system(cmd.getcstr());
419 }
420
421 return true;
422}
423
424bool buildaction::do_buildstatus (cgiargsclass &args, recptproto */*collectproto*/,
425 displayclass &disp, outconvertclass &outconvert,
426 ostream &textout, ostream &/*logout*/) {
427
428 disp.setmacro("contentpara","buildstatus", args["mess"]);
429
430 textout << outconvert << disp << ("_buildstatus:header_\n")
431 << ("_buildstatus:content_\n")
432 << ("_buildstatus:footer_\n");
433
434 return true;
435}
436
437bool buildaction::do_delcol (cgiargsclass &/*args*/, recptproto */*collectproto*/,
438 displayclass &disp, outconvertclass &outconvert,
439 ostream &textout, ostream &/*logout*/) {
440
441 textout << outconvert << disp << ("_build:header_(_build:headmessdelcol_)\n")
442 << ("_build:contentdelcol_\n")
443 << ("_build:footer_\n");
444
445 return true;
446}
447
448
449bool buildaction::do_mess (cgiargsclass &args, recptproto */*collectproto*/,
450 displayclass &disp, outconvertclass &outconvert,
451 ostream &textout, ostream &/*logout*/) {
452
453 disp.setmacro("contentpara","buildmess", args["mess"]);
454 disp.setmacro("headmess","buildmess", args["head"]);
455 textout << outconvert << disp << ("_build:header_(_buildmess:headmess_)\n")
456 << ("_buildmess:content_\n")
457 << ("_build:footer_\n");
458
459 return true;
460}
Note: See TracBrowser for help on using the repository browser.