/********************************************************************** * * buildaction.cpp -- building collections * Copyright (C) 1999 The New Zealand Digital Library Project * * A component of the Greenstone digital library software * from the New Zealand Digital Library Project at the * University of Waikato, New Zealand. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. * *********************************************************************/ #include "OIDtools.h" #include "fileutil.h" #include "htmlutils.h" #include "gsdltools.h" #include "buildaction.h" /////////////// // buildaction /////////////// buildaction::buildaction () { // this action uses cgi variable "a" cgiarginfo arg_ainfo; arg_ainfo.shortname = "a"; arg_ainfo.longname = "action"; arg_ainfo.multiplechar = true; arg_ainfo.defaultstatus = cgiarginfo::weak; arg_ainfo.argdefault = "bc"; // build collection arg_ainfo.savedarginfo = cgiarginfo::must; argsinfo.addarginfo (NULL, arg_ainfo); // "bca" arg_ainfo.shortname = "bca"; arg_ainfo.longname = "build collection action"; arg_ainfo.multiplechar = true; arg_ainfo.defaultstatus = cgiarginfo::weak; arg_ainfo.argdefault = "editcol"; arg_ainfo.savedarginfo = cgiarginfo::mustnot; argsinfo.addarginfo (NULL, arg_ainfo); // "mess" arg_ainfo.shortname = "mess"; arg_ainfo.longname = "macro name of text for the message page"; arg_ainfo.multiplechar = true; arg_ainfo.defaultstatus = cgiarginfo::weak; arg_ainfo.argdefault = ""; arg_ainfo.savedarginfo = cgiarginfo::mustnot; argsinfo.addarginfo (NULL, arg_ainfo); // "head" arg_ainfo.shortname = "head"; arg_ainfo.longname = "macro name of text to use as header for the message page"; arg_ainfo.multiplechar = true; arg_ainfo.defaultstatus = cgiarginfo::weak; arg_ainfo.argdefault = ""; arg_ainfo.savedarginfo = cgiarginfo::mustnot; argsinfo.addarginfo (NULL, arg_ainfo); } bool buildaction::check_cgiargs (cgiargsinfoclass &/*argsinfo*/, cgiargsclass &args, ostream &/*logout*/) { text_t &arg_bca = args["bca"]; if (!((arg_bca == "buildstatus") || (arg_bca == "collog") || (arg_bca == "blankpage") || ((arg_bca == "buildcol") && (args["wizard"] == "buildexec")))) { // authenticate the user if authentication is avaiable args["uan"] = 1; args["ug"] = "colbuilder"; } return true; } void buildaction::get_cgihead_info (cgiargsclass &/*args*/, recptprotolistclass * /*protos*/, response_t &response,text_t &response_data, ostream &/*logout*/) { response = content; response_data = "text/html"; } void buildaction::define_internal_macros (displayclass &disp, cgiargsclass &args, recptprotolistclass *protos, ostream &logout) { // make sure we know about a receptionist if (recpt == NULL) { logout << "The build action does not contain information\n" << "about any receptionists. The method set_receptionist\n" << "was probably not called from the module which instantiated\n" << "this build action.\n"; return; } recptprotolistclass *rprotolist = recpt->get_recptprotolist_ptr (); if (rprotolist == NULL) return; // build up javascript and HTML code useful in web forms text_t first_dirname = ""; text_t fullnamelist = "var fullnamelist = new Array("; text_t dirnamelist = "var dirnamelist = new Array("; text_t fullnamemenu = "\n"; fullnamemenu += "\n"; rprotolist_here ++; } if ((args["bca"]=="newcol") || (args["bca"]=="editcol")) { disp.setmacro ("fullnamelist", "build", fullnamelist); } if ((args["bca"]=="delcol") || (args["bca"]=="editcol") || (args["bca"]=="buildcol") || (args["bca"]=="collog")) { disp.setmacro ("dirnamelist", "build", dirnamelist); disp.setmacro ("fullnamemenu", "build", fullnamemenu); disp.setmacro ("bcargfullnameindex", "build", starting_fullname_index); } // define special "wizard" form value so webform building process can // keep track of which page it is on text_t wizard_value = (args["wizard"] == "") ? (text_t)"textinfo" : args["wizard"]; text_t hiddenargs = "\n"; disp.setmacro ("hiddenargs", "build", hiddenargs); disp.setmacro ("wizard", "build", wizard_value); // cache any cgi arguments starting "newcol:" (from previous webform) cgiargsclass::const_iterator args_here = args.begin(); cgiargsclass::const_iterator args_end = args.end(); while (args_here != args_end) { // define macro if args came from a previous col building webpage text_t args_entry = (*args_here).first; if (substr(args_entry.begin(),args_entry.begin()+3) == "bc1") { text_t bc1name = substr(args_entry.begin()+3,args_entry.end()); text_t cached_cgiarg = "bcarg" + bc1name; disp.setmacro(cached_cgiarg, "build", dm_safe(args[args_entry])); } args_here++; } // set macro cfgperm based on whether config file can be read or no text_t dirname = (args["bc1dirname"] == "") ? first_dirname : args["bc1dirname"]; text_t cfg_fname = filename_cat(gsdlhome, "collect", dirname, "etc", "collect.cfg"); text_t cfgperm = (file_writable(cfg_fname)) ? text_t("read/write") : text_t("readonly"); disp.setmacro("cfgperm","build",cfgperm); // if edit collection, read in collect.cfg file if (args["bca"]=="editcol") { text_t dirname = (args["bc1dirname"] == "") ? first_dirname : args["bc1dirname"]; // read in collect.cfg text_t cfg_fname = filename_cat(gsdlhome, "collect", dirname, "etc", "collect.cfg"); #ifdef GSDL_USE_IOS_H ifstream cfg_ifs (cfg_fname.getcstr(), ios::in | ios::nocreate); #else ifstream cfg_ifs (cfg_fname.getcstr(), ios::in); #endif if (cfg_ifs) { // read in collect.cfg text_t cfg_text = ""; char c; cfg_ifs.get(c); while (!cfg_ifs.eof ()) { cfg_text.push_back(c); if (c=='\\') { cfg_text.push_back('\\'); } cfg_ifs.get(c); } cfg_ifs.close(); if (cfgperm=="readonly") cfg_text = html_safe(cfg_text); // define it as a macro disp.setmacro("cfgfile","build",cfg_text); } else { text_t error_mess = "Unable to read configuration file: "+cfg_fname; disp.setmacro("cfgfile","build",error_mess); } } // if view log, read in collect.bld file if (args["bca"]=="collog") { text_t dirname = (args["bc1dirname"] == "") ? first_dirname : args["bc1dirname"]; // read in collect.bld text_t bld_fname = filename_cat(gsdlhome, "etc", dirname+ ".bld"); #ifdef GSDL_USE_IOS_H ifstream bld_ifs (bld_fname.getcstr(), ios::in | ios::nocreate); #else ifstream bld_ifs (bld_fname.getcstr(), ios::in); #endif if (bld_ifs) { text_t bld_text = ""; char c; bld_ifs.get(c); while (!bld_ifs.eof ()) { bld_text.push_back(c); if (c=='\\') { bld_text.push_back('\\'); } bld_ifs.get(c); } bld_ifs.close(); bld_text = html_safe(bld_text); // define it as a macro disp.setmacro("bldfile","build",bld_text); } else { text_t error_mess = "Log file currently empty."; disp.setmacro("bldfile","build",error_mess); } } } bool buildaction::do_action (cgiargsclass &args, recptprotolistclass * /*protos*/, browsermapclass * /*browsers*/, displayclass &disp, outconvertclass &outconvert, ostream &textout, ostream &logout) { // make sure we know about a receptionist if (recpt == NULL) { logout << "The page action does not contain information\n" << "about any receptionists. The method set_receptionist\n" << "was probably not called from the module which instantiated\n" << "this page action.\n"; return false; } if (args["bca"] == "newcol") { return do_newcol (args, disp, outconvert, textout, logout); } else if (args["bca"] == "editcol") { return do_editcol (args, disp, outconvert, textout, logout); } else if (args["bca"] == "buildcol") { return do_buildcol (args, disp, outconvert, textout, logout); } else if (args["bca"] == "buildstatus") { return do_buildstatus (args, disp, outconvert, textout, logout); } else if (args["bca"] == "delcol") { return do_delcol (args, disp, outconvert, textout, logout); } else if (args["bca"] == "collog") { return do_collog (args, disp, outconvert, textout, logout); } else if (args["bca"] == "mess") { return do_mess (args, disp, outconvert, textout, logout); } // default (bca == blankpage) textout << outconvert << "\n"; return true; } bool buildaction::do_newcol (cgiargsclass &args, displayclass &disp, outconvertclass &outconvert, ostream &textout, ostream &/*logout*/) { text_tarray wizard_split; const text_t& wizard = (args["wizard"] == "") ? (text_t)"textinfo" : args["wizard"]; splitchar(wizard.begin(),wizard.end(),':',wizard_split); const text_t& wizard_last = wizard_split.back(); text_t content = "_build:content" + wizard_last + "_\n"; text_t headmess = "_build:header_(_build:headmess" + wizard_last + "_)\n"; textout << outconvert << disp << (headmess) << (content) << ("_build:wizardfooter_\n"); return true; } bool buildaction::do_editcol (cgiargsclass &/*args*/, displayclass &disp, outconvertclass &outconvert, ostream &textout, ostream &/*logout*/) { textout << outconvert << disp << ("_build:header_(_build:headmesseditcol_)\n") << ("_build:contenteditcol_\n") << ("_build:wizardfooter_\n"); return true; } bool buildaction::do_buildcol (cgiargsclass &args, displayclass &disp, outconvertclass &outconvert, ostream &textout, ostream &logout) { text_tarray wizard_split; const text_t wizard = (args["wizard"].empty()) ? "buildcol" : args["wizard"]; splitchar(wizard.begin(),wizard.end(),':',wizard_split); const text_t wizard_last = wizard_split.back(); if (wizard_last != "buildframe") { text_t headmess = "_build:header_(_build:headmess" + wizard_last + "_)\n"; text_t content = "_build:content" + wizard_last + "_\n"; textout << outconvert << disp << headmess << content << "_build:wizardfooter_\n"; } else { text_t dirname = (args["bc1dirname"] == "") ? "unknown" : args["bc1dirname"]; text_t tmpname = dirname+"_XXXXXX"; char *cstr_tmpname = tmpname.getcstr(); if (GSDL_MKTEMP (cstr_tmpname)==NULL) logout << "Failed to create temporary filename" << endl; delete cstr_tmpname; disp.setmacro("bcargtmpname","build",tmpname); text_t headmess = "_build:frameheader_(_build:headmess" + wizard_last + "_)\n"; text_t content = "_build:content" + wizard_last + "_\n"; textout << outconvert << disp << headmess << content << "_build:framefooter_\n"; text_t cmd = "perl \"" + filename_cat(gsdlhome, "cgi-bin", "webpage_buildcol.pl") + "\""; cmd += " \"httpbuild="+args["httpbuild"]+"\""; cmd += " \"bc1copydata="+args["bc1copydata"]+"\""; cmd += " \"bc1doimport="+args["bc1doimport"]+"\""; cmd += " \"bc1dobuild="+args["bc1dobuild"]+"\""; cmd += " \"bc1dirname="+args["bc1dirname"]+"\" \"bc1tmpname="+tmpname+"\""; // run webpage_buildcol.pl in background on unix systems #if !defined (__WIN32__) cmd += " &"; #endif char *cstr_cmd = cmd.getcstr(); #if defined (__WIN32__) gsdl_system (cstr_cmd, logout); #else system (cstr_cmd); #endif delete cstr_cmd; } return true; } bool buildaction::do_buildstatus (cgiargsclass &args, displayclass &disp, outconvertclass &outconvert, ostream &textout, ostream &/*logout*/) { disp.setmacro("contentpara","buildstatus", args["mess"]); textout << outconvert << disp << ("_buildstatus:header_\n") << ("_buildstatus:content_\n") << ("_buildstatus:footer_\n"); return true; } bool buildaction::do_delcol (cgiargsclass &/*args*/, displayclass &disp, outconvertclass &outconvert, ostream &textout, ostream &/*logout*/) { textout << outconvert << disp << ("_build:header_(_build:headmessdelcol_)\n") << ("_build:contentdelcol_\n") << ("_build:footer_\n"); return true; } bool buildaction::do_collog (cgiargsclass &/*args*/, displayclass &disp, outconvertclass &outconvert, ostream &textout, ostream &/*logout*/) { textout << outconvert << disp << ("_build:header_(_build:headmesscollog_)\n") << ("_build:contentcollog_\n") << ("_build:wizardfooter_\n"); return true; } bool buildaction::do_mess (cgiargsclass &args, displayclass &disp, outconvertclass &outconvert, ostream &textout, ostream &/*logout*/) { disp.setmacro("contentpara","buildmess", args["mess"]); disp.setmacro("headmess","buildmess", args["head"]); textout << outconvert << disp << ("_build:header_(_buildmess:headmess_)\n") << ("_buildmess:content_\n") << ("_build:footer_\n"); return true; }