/********************************************************************** * * pageaction.cpp -- * 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. * *********************************************************************/ // Changelog: // 11th July 2003: // Added 3 functions to deal with the collection style // A deciding function and then 2 functions that actually // do the work for us, either images or pulldown. #include "OIDtools.h" #include "pageaction.h" #include "receptionist.h" #include "fileutil.h" #include "gsdltools.h" #include "querytools.h" #include pageaction::pageaction () { status_disabled = true; collector_disabled = true; depositor_disabled = true; translator_disabled = true; gliapplet_disabled = true; recpt = NULL; // this action uses cgi variables "a", "p", and "hp" cgiarginfo arg_ainfo; arg_ainfo.shortname = "a"; arg_ainfo.longname = "action"; arg_ainfo.multiplechar = true; arg_ainfo.defaultstatus = cgiarginfo::weak; arg_ainfo.argdefault = "p"; arg_ainfo.savedarginfo = cgiarginfo::must; argsinfo.addarginfo (NULL, arg_ainfo); arg_ainfo.shortname = "p"; arg_ainfo.longname = "page"; arg_ainfo.multiplechar = true; arg_ainfo.defaultstatus = cgiarginfo::weak; arg_ainfo.argdefault = "home"; arg_ainfo.savedarginfo = cgiarginfo::must; argsinfo.addarginfo (NULL, arg_ainfo); arg_ainfo.shortname = "hp"; arg_ainfo.longname = "html page"; arg_ainfo.multiplechar = true; arg_ainfo.defaultstatus = cgiarginfo::weak; arg_ainfo.argdefault = g_EmptyText; arg_ainfo.savedarginfo = cgiarginfo::mustnot; argsinfo.addarginfo (NULL, arg_ainfo); arg_ainfo.shortname = "bp"; arg_ainfo.longname = "set preferences button"; arg_ainfo.multiplechar = true; arg_ainfo.defaultstatus = cgiarginfo::weak; arg_ainfo.argdefault = g_EmptyText; arg_ainfo.savedarginfo = cgiarginfo::mustnot; argsinfo.addarginfo (NULL, arg_ainfo); // the "u" argument will disable the search facility, remove links to the // home and preferences pages, and disable the DocumentButton buttons // (for use when generating static html versions of collections) arg_ainfo.shortname = "u"; arg_ainfo.longname = "static page"; arg_ainfo.multiplechar = false; arg_ainfo.defaultstatus = cgiarginfo::weak; arg_ainfo.argdefault = "0"; arg_ainfo.savedarginfo = cgiarginfo::mustnot; argsinfo.addarginfo (NULL, arg_ainfo); arg_ainfo.shortname = "book"; arg_ainfo.longname = "book switch"; arg_ainfo.multiplechar = true; arg_ainfo.defaultstatus = cgiarginfo::weak; arg_ainfo.argdefault = "off"; arg_ainfo.savedarginfo = cgiarginfo::must; argsinfo.addarginfo (NULL, arg_ainfo); } pageaction::~pageaction () { } bool pageaction::check_cgiargs (cgiargsinfoclass &/*argsinfo*/, cgiargsclass &args, recptprotolistclass * /*protos*/, ostream &/*logout*/) { if (args["p"] == "preferences" && !args["bp"].empty()) { if (args["hd"] != "0") args["hd"] = args["hdn"]; } return true; } void pageaction::get_cgihead_info (cgiargsclass &/*args*/, recptprotolistclass * /*protos*/, response_t &response,text_t &response_data, ostream &/*logout*/) { response = content; response_data = "text/html"; } // This function helps decide whether we want a // images or pulldown style collection display // We refer to the macro files for the options // for images or pulldown menu and use that to // switch to the appropriate function to do the job // Aly Dharshi // 11th July 2003 void pageaction::homepagestyle(displayclass &disp, recptprotolistclass *protos, cgiargsclass &args, ostream &logout) { const recptconf &configinfo = recpt->get_configinfo(); if (configinfo.HomePageType == "images") { home_images(disp, protos, args, configinfo, logout); } else { home_pulldown(disp, protos, args, configinfo, logout); } } // This function allows for the Greenstone // collection to be displayed in a pull down // menu similar to that in documentaction.cpp // Aly Dharshi // 11th July 2003 void pageaction::home_pulldown(displayclass &disp, recptprotolistclass *protos, cgiargsclass &args, const recptconf &configinfo, ostream &logout) { text_t homeextra = "
\n"; homeextra += "\n"; homeextra += "
\n"; disp.setmacro ("homeextra", "home", homeextra); } // originally called set_homeextra_macro // this function displays the Greenstone // main page as usual with the graphics for // the collections. // Aly Dharshi // 11th July 2003 void pageaction::home_images(displayclass &disp, recptprotolistclass *protos, cgiargsclass &args, const recptconf &configinfo, ostream &logout) { text_t homeextra = "\n"; bool found_valid_col = false; recptprotolistclass::iterator rprotolist_here = protos->begin(); recptprotolistclass::iterator rprotolist_end = protos->end(); while (rprotolist_here != rprotolist_end) { if ((*rprotolist_here).p != NULL) { text_tarray collist; comerror_t err; (*rprotolist_here).p->get_collection_list (collist, err, logout); if (err == noError) { text_tarray::iterator collist_here = collist.begin(); text_tarray::iterator collist_end = collist.end(); int count = 0; while (collist_here != collist_end) { ColInfoResponse_t *cinfo = recpt->get_collectinfo_ptr ((*rprotolist_here).p, *collist_here, logout); text_t arg_g = args["g"]; text_t colname_dir = *collist_here; if (arg_g.empty()) { // normal top-level home page text_t::const_iterator begin = colname_dir.begin(); text_t::const_iterator end = colname_dir.end(); if (findchar(begin,end,'/')!=end) { // no g argument, so generating top level home page // => if colname_dir has "/" in collection name, filter it out ++collist_here; continue; } } else { // show only collections in the named group if (colname_dir == arg_g) { // display about this collect text text_t collectionextra = cinfo->get_collectionmeta("collectionextra", args["l"]); if (!collectionextra.empty()) { // prepend text on at start homeextra = "

" + collectionextra + "

" + homeextra; } ++collist_here; continue; } // => filter out anything that does not start with the group prefix if (!starts_with(colname_dir,arg_g + "/")) { ++collist_here; continue; } } if (cinfo != NULL) { if (cinfo->isPublic && ((cinfo->buildDate > 0)) || (cinfo->isCollectGroup)) { found_valid_col = true; text_t collectionname = *collist_here; text_t alt = cinfo->get_collectionmeta("collectionname", args["l"]); if (alt.empty()) { alt = collectionname; } comerror_t err; text_t optsite = g_EmptyText; text_t site_name = (*rprotolist_here).p->get_site_name (err); if (!site_name.empty()) { optsite = "site="+site_name+"&"; } text_t link; if (cinfo->isCollectGroup) { link = ""; } else { link = ""; } if (!cinfo->receptionist.empty()) link = "receptionist + "\">"; // url to image: try iconcollectionsmall, then iconcollection text_t iconurl = cinfo->get_collectionmeta("iconcollectionsmall", args["l"]); if (iconurl.empty()) { iconurl = cinfo->get_collectionmeta("iconcollection", args["l"]); } if (!iconurl.empty()) { // check to see URL is local to colserver text_t::iterator iconurl_head = iconurl.begin(); text_t iconhead = substr(iconurl_head,iconurl_head+16); if (iconhead=="_httpcollection_") { // local and using _httpcollection_ text_t icontail = substr(iconurl_head+16,iconurl.end()); iconurl = "http://" + cinfo->httpdomain + cinfo->httpprefix + "/collect/" + *collist_here + "/" + icontail; } else if (iconurl[0]=='/') { // local but with full path iconurl = "http://" + cinfo->httpdomain + iconurl; } collectionname = link + "\""" + ""; } else { collectionname = "

"; collectionname += alt + "

"; collectionname = link + collectionname + ""; } if (count%configinfo.HomePageCols == 0) homeextra += "\n"; homeextra += "\n"; ++count; if (count%configinfo.HomePageCols == 0) homeextra += "\n"; } } ++collist_here; } // Finish off the last row, if necessary if (count%configinfo.HomePageCols != 0) { while (count%configinfo.HomePageCols != 0) { homeextra += "\n"; ++count; } homeextra += "\n"; } } } ++rprotolist_here; } if (!found_valid_col) { homeextra += "\n"; } homeextra += "
" + collectionname + "
_textnocollections_
\n"; disp.setmacro ("homeextra", "home", homeextra); } void pageaction::set_collectionlist_macro (displayclass &disp, recptprotolistclass *protos, cgiargsclass &args, ostream &logout) { text_t collectionlist; int count = 0; recptprotolistclass::iterator rprotolist_here = protos->begin(); recptprotolistclass::iterator rprotolist_end = protos->end(); while (rprotolist_here != rprotolist_end) { if ((*rprotolist_here).p != NULL) { text_tarray collist; comerror_t err; (*rprotolist_here).p->get_collection_list (collist, err, logout); if (err == noError) { text_tarray::iterator collist_here = collist.begin(); text_tarray::iterator collist_end = collist.end(); while (collist_here != collist_end) { ColInfoResponse_t *cinfo = recpt->get_collectinfo_ptr ((*rprotolist_here).p, *collist_here, logout); if (cinfo != NULL) { if (cinfo->isPublic && (cinfo->buildDate > 0)) { ++count; text_t collectionname = cinfo->get_collectionmeta("collectionname", args["l"]); if (collectionname.empty()) { collectionname = *collist_here; } comerror_t err; text_t optsite = g_EmptyText; text_t site_name = (*rprotolist_here).p->get_site_name (err); if (!site_name.empty()) { optsite = "site="+site_name+"&"; } text_t link = ""; if (!cinfo->receptionist.empty()) link = "receptionist + "\">"; collectionlist += "
  • " + link + collectionname + "\n"; } } ++collist_here; } } } ++rprotolist_here; } if (count == 1) { collectionlist = "

    _text1coll_\n

    \n"; } else if (count > 1) { collectionlist = "

    _textmorecolls_(" + text_t(count) + ")\n

    \n"; } disp.setmacro ("collectionlist", "homehelp", collectionlist); } void pageaction::set_documentation_macro (displayclass &disp) { text_t documentation; text_t docsdir = filename_cat(gsdlhome, "docs"); if (file_exists(filename_cat(docsdir, "User.pdf"))) { documentation += "_iconpdf_" "_textuserguide_"; } if (file_exists(filename_cat(docsdir, "Install.pdf"))) { documentation += "_iconpdf_" "_textinstallerguide_"; } if (file_exists(filename_cat(docsdir, "Develop.pdf"))) { documentation += "_iconpdf_" "_textdeveloperguide_"; } if (file_exists(filename_cat(docsdir, "Paper.pdf"))) { documentation += "_iconpdf_" "_textpaperguide_"; } if (file_exists(filename_cat(docsdir, "Organize.pdf"))) { documentation += "_iconpdf_" "_textorganizerguide_"; } if (!documentation.empty()) { disp.setmacro("documentation", "docs", "

    \n\n" + documentation + "\n
    \n"); } } void pageaction::set_macro_to_file_contents (displayclass &disp, const text_t ¯oname, const text_t &packagename, const text_t &filename) { text_t filecontent; char *filenamec = filename.getcstr(); ifstream file_in (filenamec); delete []filenamec; if (file_in) { char c; file_in.get(c); while (!file_in.eof ()) { if (c == '\n') filecontent += "
    "; filecontent.push_back(c); file_in.get(c); } file_in.close(); } disp.setmacro (macroname, packagename, dm_safe(filecontent)); } void pageaction::set_language_encoding_macros(displayclass &disp, cgiargsclass &args, recptprotolistclass *protos, ColInfoResponse_t *cinfo, ostream &logout) { // _languageoption_ // Create the "interface language" selection box for the preferences // pages. You can use something like "format PreferenceLanguages // en|fr|zn" from within a collect.cfg file to use only a subset of // the available languages for any given collection (for // collection-specific preferences pages). This facility is kind of // ugly though and should be replaced by something better when the // configuration files are tidied up (as should all the other // "format Preference..." options). text_t &arg_l = args["l"]; const recptconf &configinfo = recpt->get_configinfo(); // put languages in another map to sort them by longname text_tmap languages; languageinfo_tmap::const_iterator thislang = configinfo.languages.begin(); languageinfo_tmap::const_iterator endlang = configinfo.languages.end(); while (thislang != endlang) { languages[(*thislang).second.longname] = (*thislang).first; ++thislang; } text_tmap::iterator tlang = languages.begin(); text_tmap::iterator elang = languages.end(); text_t languageoption; bool collection_specific = false; if (cinfo != NULL) { text_tmap::const_iterator it = cinfo->format.find ("PreferenceLanguages"); if ((it != cinfo->format.end()) && (!(*it).second.empty())) { collection_specific = true; text_tset pref_langs; splitchar ((*it).second.begin(), (*it).second.end(), '|', pref_langs); if (pref_langs.size() > 1) { while (tlang != elang) { if (pref_langs.find((*tlang).second) != pref_langs.end()) { languageoption += "

    _textbadcollection_

    "); return; } else { text_tmap::iterator check = cinfo->format.find("QueryInterface"); if(check != cinfo->format.end()){ if((*check).second=="DateSearch"){ text_t current = "_datesearch_"; disp.setmacro("optdatesearch","query",current); } } check = cinfo->format.find("Usability"); if(check != cinfo->format.end()){ disp.setmacro("usability", displayclass::defaultpackage, "_usablink_"); disp.setmacro("usabinterface", displayclass::defaultpackage, ("_usab"+(*check).second+"_")); disp.setmacro("usabilityscript", displayclass::defaultpackage, "_usabshowscript_"); } } } if (arg_p == "home" || arg_p == "homehelp") { if (status_disabled) disp.setmacro ("textgoadmin", "home", ""); if (collector_disabled) disp.setmacro ("textgocollector", "home", ""); if (depositor_disabled) disp.setmacro ("textgodepositor", "home", ""); if (translator_disabled) disp.setmacro ("textgotranslator", "home", ""); if (arg_p == "home") { homepagestyle (disp, protos, args, logout); } else if (arg_p == "homehelp") { set_collectionlist_macro (disp, protos, args, logout); } } else if (arg_p == "gli") { if (gliapplet_disabled) disp.setmacro ("gliapplet", "gli", ""); } else if (arg_p == "homepref") { // set _languageoption_ and _encodingoption_ set_language_encoding_macros(disp, args, protos, cinfo, logout); } else if (arg_p == "preferences") { if (cinfo == NULL) { disp.setmacro("cvariable", displayclass::defaultpackage, arg_c); disp.setmacro("content", arg_p, "

    _textbadcollection_

    "); return; } if (collectproto == NULL) {return;} // set _languageoption_ and _encodingoption_ set_language_encoding_macros(disp, args, protos, cinfo, logout); // _collectionoption_ if ((args["ccs"] == "1") && (cinfo->ccsCols.size() > 1)) { text_t collectionoption = "_textcollectionoption_"; text_tarray::const_iterator col_here = cinfo->ccsCols.begin(); text_tarray::const_iterator col_end = cinfo->ccsCols.end(); int count = 0; while (col_here != col_end) { text_t colname; if (*col_here == arg_c) { colname = cinfo->get_collectionmeta("collectionname", args["l"]); } else { ColInfoResponse_t *this_cinfo = recpt->get_collectinfo_ptr (collectproto, *col_here, logout); if (this_cinfo == NULL) {++col_here; continue;} colname = this_cinfo->get_collectionmeta("collectionname", args["l"]); } if (colname.empty()) { colname = *col_here; } ++count; collectionoption += " " + colname + "
    \n"; ++col_here; } if (count > 1) disp.setmacro ("collectionoption", "preferences", collectionoption); } // _htmloptions_ text_tmap::const_iterator it = cinfo->format.find ("DocumentUseHTML"); if ((it != cinfo->format.end()) && ((*it).second == "true")) { disp.setmacro ("htmloptions", "preferences", "_htmloptionson_"); // _PreferenceDocsFromWeb_ it = cinfo->format.find ("PreferenceDocsFromWeb"); if ((it == cinfo->format.end()) || ((*it).second == "true")) disp.setmacro ("PreferenceDocsFromWeb", "preferences", "1"); } // _prefschanged_ if (!args["bp"].empty()) { disp.setmacro ("prefschanged", "preferences", "_textprefschanged_"); } } else if (arg_p == "about" || arg_p == "help") { if (collectproto == NULL) return; comerror_t err; bool has_search_button = true; collectproto->is_searchable(args["c"], has_search_button, err, logout); if (err != noError) has_search_button = true; // _textbrowseoptions_ and _numbrowseoptions_ FilterResponse_t response; text_tset metadata; metadata.insert ("Title"); //**************** metadata.insert ("childtype"); //**************** bool getParents = false; get_children ("", args["c"], args["l"], metadata, getParents, collectproto, response, logout); int numbrowseoptions = response.docInfo.size(); if (has_search_button) numbrowseoptions += 1; disp.setmacro ("numbrowseoptions", "help", numbrowseoptions); ResultDocInfo_tarray::iterator here = response.docInfo.begin(); ResultDocInfo_tarray::iterator end = response.docInfo.end(); text_t helptext; if (has_search_button) { helptext = "

    \n"; disp.setmacro ("textbrowseoptions", "help", helptext); if (arg_p == "help") { // do we need to add in the datesearch help?? text_tmap::iterator check = cinfo->format.find("QueryInterface"); if(check != cinfo->format.end()){ if((*check).second=="DateSearch"){ text_t current = "_datesearch_"; disp.setmacro("optdatesearchhelp","help","_datesearchhelp_"); disp.setmacro("optdatesearchhelpcontents","help","_datesearchhelpcontents_"); } } } if (arg_p == "about") { // _textsubcollections_ if (args["ccs"] == "1" && (cinfo->ccsCols.size() > 1)) { text_t textsubcollections = "_textsubcols1_(" + text_t(cinfo->ccsCols.size()) + ")"; text_tarray::const_iterator here = cinfo->ccsCols.begin(); text_tarray::const_iterator end = cinfo->ccsCols.end(); bool first = true; int count = 0; while (here != end) { if (*here == arg_c) { if (!first) textsubcollections += "
    "; textsubcollections += "\n" + cinfo->get_collectionmeta("collectionname", args["l"]) + "\n"; } else { ColInfoResponse_t *this_cinfo = recpt->get_collectinfo_ptr (collectproto, *here, logout); if (this_cinfo == NULL) {++here; continue;} if (!first) textsubcollections += "
    "; textsubcollections += "\n" + this_cinfo->get_collectionmeta("collectionname", args["l"]) + "\n"; } ++count; first = false; ++here; } textsubcollections += "_textsubcols2_"; if (count > 1) { disp.setmacro ("textsubcollections", "about", textsubcollections); } } comerror_t err; bool issearchable = true; collectproto->is_searchable(args["c"], issearchable, err, logout); if (err != noError) issearchable = true; outconvertclass t; if (!issearchable ) { disp.setmacro ("aboutqueryform", "about", ""); } } } else if (arg_p == "docs") { set_documentation_macro (disp); } else if (arg_p == "bsummary" && !arg_c.empty()) { set_macro_to_file_contents (disp, "importlog", "bsummary", filename_cat(gsdlhome, "collect", arg_c, "etc", "import.log")); set_macro_to_file_contents (disp, "faillog", "bsummary", filename_cat(gsdlhome, "collect", arg_c, "etc", "fail.log")); set_macro_to_file_contents (disp, "buildlog", "bsummary", filename_cat(gsdlhome, "collect", arg_c, "etc", "build.log")); } } bool pageaction::do_action (cgiargsclass &args, recptprotolistclass * /*protos*/, browsermapclass * /*browsers*/, displayclass &disp, outconvertclass &outconvert, ostream &textout, ostream &/*logout*/) { text_t &arg_p = args["p"]; textout << outconvert << disp << ("_" + arg_p + ":header_\n") << ("_" + arg_p + ":content_\n") << ("_" + arg_p + ":footer_\n"); return true; } void pageaction::configure (const text_t &key, const text_tarray &cfgline) { if ((key == "status") && (cfgline.size() == 1) && (cfgline[0] == "true" || cfgline[0] == "on" || cfgline[0] == "enabled")) { status_disabled = false; } else if ((key == "collector") && (cfgline.size() == 1) && (cfgline[0] == "true" || cfgline[0] == "on" || cfgline[0] == "enabled")) { collector_disabled = false; } else if ((key == "depositor") && (cfgline.size() == 1) && (cfgline[0] == "true" || cfgline[0] == "on" || cfgline[0] == "enabled")) { depositor_disabled = false; } else if ((key == "translator") && (cfgline.size() == 1) && (cfgline[0] == "true" || cfgline[0] == "on" || cfgline[0] == "enabled")) { translator_disabled = false; } else if ((key == "gliapplet") && (cfgline.size() == 1) && (cfgline[0] == "true" || cfgline[0] == "on" || cfgline[0] == "enabled")) { gliapplet_disabled = false; } else { // call the parent class to deal with the things which // are not dealt with here action::configure (key, cfgline); } }