root/main/trunk/greenstone2/runtime-src/src/recpt/pageaction.cpp @ 28888

Revision 28888, 34.4 KB (checked in by ak19, 4 years ago)

First security commit. 1. Introducing the new securitools.h and .cpp files, which port the functions necessary to implement security in Greenstone from OWASP-ESAPI for Java, since OWASP's C++ version is largely not yet implemented, even though their code compiles. The newly added runtime-src/packages/security which contains OWASP ESAPI for C++ will therefore be removed again shortly. 2. receptionist.cpp now sets various web-encoded variants for each cgiarg macro, such as HTML entity encoded, attr encoded, javascript encoded (and css encoded variants). These are now used in the macro files based on which variant is suited to the context. 3. This commit further contains the minimum changes to protect the c, d, and p cgi variables.

  • Property svn:executable set to *
  • Property svn:keywords set to Author Date Id Revision
Line 
1/**********************************************************************
2 *
3 * pageaction.cpp --
4 * Copyright (C) 1999  The New Zealand Digital Library Project
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// Changelog:
27
28// 11th July 2003:
29
30//   Added 3 functions to deal with the collection style
31//   A deciding function and then 2 functions that actually
32//   do the work for us, either images or pulldown.
33
34
35#include "pageaction.h"
36#include "receptionist.h"
37#include "recptprototools.h"
38#include "fileutil.h"
39#include "gsdltools.h"
40#include "querytools.h"
41#include <time.h>
42
43pageaction::pageaction () {
44
45  status_disabled = true;
46  collector_disabled = true;
47  depositor_disabled = true;
48  translator_disabled = true;
49  gliapplet_disabled = true;
50  recpt = NULL;
51
52  // this action uses cgi variables "a", "p", and "hp"
53  cgiarginfo arg_ainfo;
54  arg_ainfo.shortname = "a";
55  arg_ainfo.longname = "action";
56  arg_ainfo.multiplechar = true;
57  arg_ainfo.multiplevalue = false;
58  arg_ainfo.defaultstatus = cgiarginfo::weak;
59  arg_ainfo.argdefault = "p";
60  arg_ainfo.savedarginfo = cgiarginfo::must;
61  argsinfo.addarginfo (NULL, arg_ainfo);
62
63  arg_ainfo.shortname = "p";
64  arg_ainfo.longname = "page";
65  arg_ainfo.multiplechar = true;
66  arg_ainfo.multiplevalue = false;
67  arg_ainfo.defaultstatus = cgiarginfo::weak;
68  arg_ainfo.argdefault = "home";
69  arg_ainfo.savedarginfo = cgiarginfo::must;
70  argsinfo.addarginfo (NULL, arg_ainfo);
71
72  arg_ainfo.shortname = "hp";
73  arg_ainfo.longname = "html page";
74  arg_ainfo.multiplechar = true;
75  arg_ainfo.multiplevalue = false;
76  arg_ainfo.defaultstatus = cgiarginfo::weak;
77  arg_ainfo.argdefault = g_EmptyText;
78  arg_ainfo.savedarginfo = cgiarginfo::mustnot;
79  argsinfo.addarginfo (NULL, arg_ainfo);
80
81  arg_ainfo.shortname = "bp";
82  arg_ainfo.longname = "set preferences button";
83  arg_ainfo.multiplechar = true;
84  arg_ainfo.multiplevalue = false;
85  arg_ainfo.defaultstatus = cgiarginfo::weak;
86  arg_ainfo.argdefault = g_EmptyText;
87  arg_ainfo.savedarginfo = cgiarginfo::mustnot;
88  argsinfo.addarginfo (NULL, arg_ainfo);
89
90  // the "u" argument will disable the search facility, remove links to the
91  // home and preferences pages, and disable the DocumentButton buttons
92  // (for use when generating static html versions of collections)
93  arg_ainfo.shortname = "u";
94  arg_ainfo.longname = "static page";
95  arg_ainfo.multiplechar = false;
96  arg_ainfo.multiplevalue = false;
97  arg_ainfo.defaultstatus = cgiarginfo::weak;
98  arg_ainfo.argdefault = "0";
99  arg_ainfo.savedarginfo = cgiarginfo::mustnot;
100  argsinfo.addarginfo (NULL, arg_ainfo);
101
102  arg_ainfo.shortname = "book";
103  arg_ainfo.longname = "book switch";
104  arg_ainfo.multiplechar = true;
105  arg_ainfo.multiplevalue = false;
106  arg_ainfo.defaultstatus = cgiarginfo::weak;
107  arg_ainfo.argdefault = "off";
108  arg_ainfo.savedarginfo = cgiarginfo::must;
109  argsinfo.addarginfo (NULL, arg_ainfo);
110
111  arg_ainfo.shortname = "talkback";
112  arg_ainfo.longname = "DL talkback";
113  arg_ainfo.multiplechar = false;
114  arg_ainfo.multiplevalue = false;
115  arg_ainfo.defaultstatus = cgiarginfo::weak;
116  arg_ainfo.argdefault = "0";
117  arg_ainfo.savedarginfo = cgiarginfo::must;
118  argsinfo.addarginfo (NULL, arg_ainfo);
119
120}
121
122pageaction::~pageaction () {
123}
124
125bool pageaction::check_cgiargs (cgiargsinfoclass &/*argsinfo*/, cgiargsclass &args,
126                recptprotolistclass * /*protos*/, ostream &/*logout*/) {
127
128  if (args["p"] == "preferences" && !args["bp"].empty()) {
129    if (args["hd"] != "0") args["hd"] = args["hdn"];
130  }
131
132  return true;
133}
134
135void pageaction::get_cgihead_info (cgiargsclass &/*args*/, recptprotolistclass * /*protos*/,
136                   response_t &response,text_t &response_data,
137                   ostream &/*logout*/) {
138  response = content;
139  response_data = "text/html";
140}
141
142// This function helps decide whether we want a
143// images or pulldown style collection display
144// We refer to the macro files for the options
145// for images or pulldown menu and use that to
146// switch to the appropriate function to do the job
147
148// Aly Dharshi
149// 11th July 2003
150
151void pageaction::homepagestyle(displayclass &disp, recptprotolistclass *protos,
152                   cgiargsclass &args, ostream &logout)
153{
154
155  const recptconf &configinfo = recpt->get_configinfo();
156
157  if (configinfo.HomePageType == "images") {
158     home_images(disp, protos, args, configinfo, logout);
159
160  } else
161     {
162    home_pulldown(disp, protos, args, configinfo, logout);
163     }
164}
165
166// This function allows for the Greenstone
167// collection to be displayed in a pull down
168// menu similar to that in documentaction.cpp
169
170// Aly Dharshi
171// 11th July 2003
172
173void pageaction::home_pulldown(displayclass &disp, recptprotolistclass *protos,
174                   cgiargsclass &args, const recptconf &configinfo,
175                   ostream &logout) {
176
177   text_t homeextra = "<form method=\"get\" name=\"browse\">\n";
178   homeextra += "<select name=\"collections\" onChange=\"location.href=";
179   homeextra += "document.browse.collections.options[document.browse.collections.selectedIndex].value\">\n";
180   homeextra += "<option value=\"\">_textdescrselcol_</option>\n";
181   
182  recptprotolistclass::iterator rprotolist_here = protos->begin();
183  recptprotolistclass::iterator rprotolist_end = protos->end();
184  while (rprotolist_here != rprotolist_end) {
185    if ((*rprotolist_here).p != NULL) {
186
187      text_tarray collist;
188      comerror_t err;
189      (*rprotolist_here).p->get_collection_list (collist, err, logout);
190      if (err == noError) {
191    text_tarray::iterator collist_here = collist.begin();
192    text_tarray::iterator collist_end = collist.end();
193
194    int count = 0;
195    bool first = true;
196    while (collist_here != collist_end) {
197
198      ColInfoResponse_t *cinfo = recpt->get_collectinfo_ptr ((*rprotolist_here).p, *collist_here, logout);
199     
200      if (cinfo != NULL) {
201        if (cinfo->isPublic && (cinfo->buildDate > 0)) {
202
203          text_t collectionname = cinfo->get_collectionmeta("collectionname", args["l"]);
204          if (collectionname.empty()) {
205        collectionname = *collist_here;
206          }
207         
208          comerror_t err;
209          text_t optsite = g_EmptyText;
210          text_t site_name = (*rprotolist_here).p->get_site_name (err);
211          if (!site_name.empty()) { optsite = "site="+site_name+"&amp;"; }
212         
213          text_t link = "_gwcgi_?"+optsite+"a=p&amp;p=about&amp;c=" + *collist_here;
214          link += "&amp;l=" + args["l"] + "&amp;w=" + args["w"];
215
216          // We are "dynamically" overriding so to speak the
217          // link to the collection aka receptionist.
218         
219          if (!cinfo->receptionist.empty())
220         link = cinfo->receptionist;
221         
222         
223          homeextra += "<option value=\"" + link + "\"";
224          homeextra += ">" + collectionname + "</option>\n";
225               
226        }
227
228        ++collist_here;
229        }
230       
231      }
232      }
233    ++rprotolist_here;
234    }
235   
236    }
237  homeextra += "</select>\n";
238  homeextra += "</form>\n";
239 
240  disp.setmacro ("homeextra", "home", homeextra);
241}
242 
243// originally called set_homeextra_macro
244// this function displays the Greenstone
245// main page as usual with the graphics for
246// the collections.
247
248// Aly Dharshi
249// 11th July 2003
250
251void pageaction::home_images(displayclass &disp, recptprotolistclass *protos,
252                 cgiargsclass &args, const recptconf &configinfo,
253                 ostream &logout) {
254 
255  text_t homeextra = "<table class=\"collections\">\n";
256  bool found_valid_col = false;
257  recptprotolistclass::iterator rprotolist_here = protos->begin();
258  recptprotolistclass::iterator rprotolist_end = protos->end();
259  while (rprotolist_here != rprotolist_end) {
260    if ((*rprotolist_here).p != NULL) {
261
262      text_tarray collist;
263      comerror_t err;
264      (*rprotolist_here).p->get_collection_list (collist, err, logout);
265      if (err == noError) {
266    text_tarray::iterator collist_here = collist.begin();
267    text_tarray::iterator collist_end = collist.end();
268
269    int count = 0;
270    while (collist_here != collist_end) {
271
272      ColInfoResponse_t *cinfo = recpt->get_collectinfo_ptr ((*rprotolist_here).p, *collist_here, logout);
273
274      text_t arg_g = args["g"];
275      text_t colname_dir = *collist_here;
276     
277      if (arg_g.empty()) {
278        // normal top-level home page
279        text_t::const_iterator begin = colname_dir.begin();
280        text_t::const_iterator end = colname_dir.end();
281
282        if (findchar(begin,end,'/')!=end) {
283          // no g argument, so generating top level home page
284          // => if colname_dir has "/" in collection name, filter it out
285
286          ++collist_here;
287          continue;
288        }
289      }
290      else {
291        // show only collections in the named group
292
293       
294        if (colname_dir == arg_g) {
295          // display about this collect text
296
297          text_t collectionextra = cinfo->get_collectionmeta("collectionextra", args["l"]);
298          if (!collectionextra.empty()) {
299        // prepend text on at start
300        homeextra = "<p>" + collectionextra + "</p>" + homeextra;
301          }
302
303          ++collist_here;
304          continue;
305        }
306
307
308        // => filter out anything that does not start with the group prefix
309       
310        if (!starts_with(colname_dir,arg_g + "/")) {
311          ++collist_here;
312          continue;
313        }
314      }
315
316
317      if (cinfo != NULL) {
318        if (cinfo->isPublic && ((cinfo->buildDate > 0)) || (cinfo->isCollectGroup)) {
319
320          found_valid_col = true;
321          text_t collectionname = *collist_here;
322          text_t alt = cinfo->get_collectionmeta("collectionname", args["l"]);
323          if (alt.empty()) {
324        alt = collectionname;
325          }
326
327
328          comerror_t err;
329          text_t optsite = g_EmptyText;
330          text_t site_name = (*rprotolist_here).p->get_site_name (err);
331          if (!site_name.empty()) { optsite = "site="+site_name+"&amp;"; }
332
333          text_t link;
334
335          if (cinfo->isCollectGroup) {
336        link = "<a class=\"collectiontitle\" href=\"_gwcgi_?"+optsite+"a=p&amp;p=home&amp;g=" + *collist_here;
337        link += "&amp;l=" + args["l"] + "&amp;w=" + args["w"] + "\">";
338          }
339          else {
340        link = "<a class=\"collectiontitle\" href=\"_gwcgi_?"+optsite+"a=p&amp;p=about&amp;c=" + *collist_here;
341        link += "&amp;l=" + args["l"] + "&amp;w=" + args["w"] + "\">";
342          }
343         
344          if (!cinfo->receptionist.empty())
345        link = "<a class=\"collectiontitle\" href=\"" + cinfo->receptionist + "\">";
346         
347         
348          // url to image: try iconcollectionsmall, then iconcollection
349          text_t iconurl = cinfo->get_collectionmeta("iconcollectionsmall", args["l"]);
350          if (iconurl.empty()) {
351        iconurl = cinfo->get_collectionmeta("iconcollection", args["l"]);
352          }
353         
354          if (!iconurl.empty()) {
355       
356        // check to see URL is local to colserver
357        text_t::iterator iconurl_head = iconurl.begin();
358        text_t iconhead = substr(iconurl_head,iconurl_head+16);
359        if (iconhead=="_httpcollection_") {
360         
361          // local and using _httpcollection_
362          text_t icontail = substr(iconurl_head+16,iconurl.end());
363          iconurl = "http://" + cinfo->httpdomain
364            + cinfo->httpprefix + "/collect/"
365            + *collist_here + "/" + icontail;
366        }
367        else if (iconurl[0]=='/') {
368         
369          // local but with full path
370          iconurl = "http://" + cinfo->httpdomain + iconurl;
371        }
372       
373        collectionname
374          = link + "<img width=\"150\" src=\"" + iconurl + "\" alt=\"" + alt + "\">" + "</a>";
375          } else {     
376
377        collectionname = "<div class=\"collecttitle\" style=\"width: 150px; border: 1px solid; \"><p class=\"collectiontitle\" style=\"font-size: 18px; width: 150px; white-space:normal; text-align: left;\">";
378        collectionname += alt + "</p></div>";
379
380        collectionname = link + collectionname + "</a>";
381
382          }
383         
384          if (count%configinfo.HomePageCols == 0)
385        homeextra += "<tr valign=\"top\">\n";         
386
387          homeextra += "<td align=\"center\">" + collectionname + "</td>\n";
388         
389          ++count;
390          if (count%configinfo.HomePageCols == 0)
391        homeextra += "</tr>\n";
392        }
393      }
394      ++collist_here;
395    }
396
397    // Finish off the last row, if necessary
398    if (count%configinfo.HomePageCols != 0) {
399      while (count%configinfo.HomePageCols != 0) {
400        homeextra += "<td></td>\n";
401        ++count;
402      }
403      homeextra += "</tr>\n";
404    }
405      }
406    }
407    ++rprotolist_here;
408  }
409
410  if (!found_valid_col) {
411    homeextra += "<tr><td>_textnocollections_</td></tr>\n";
412  }
413  homeextra += "</table>\n";
414  disp.setmacro ("homeextra", "home", homeextra);
415}
416
417void pageaction::set_collectionlist_macro (displayclass &disp,
418                       recptprotolistclass *protos,
419                       cgiargsclass &args,
420                       ostream &logout) {
421
422  text_t collectionlist;
423  int count = 0;
424 
425  recptprotolistclass::iterator rprotolist_here = protos->begin();
426  recptprotolistclass::iterator rprotolist_end = protos->end();
427  while (rprotolist_here != rprotolist_end) {
428    if ((*rprotolist_here).p != NULL) {
429
430      text_tarray collist;
431      comerror_t err;
432      (*rprotolist_here).p->get_collection_list (collist, err, logout);
433      if (err == noError) {
434    text_tarray::iterator collist_here = collist.begin();
435    text_tarray::iterator collist_end = collist.end();
436
437    while (collist_here != collist_end) {
438      ColInfoResponse_t *cinfo = recpt->get_collectinfo_ptr ((*rprotolist_here).p, *collist_here, logout);
439     
440      if (cinfo != NULL) {
441        if (cinfo->isPublic && (cinfo->buildDate > 0)) {
442
443          ++count;
444
445          text_t collectionname = cinfo->get_collectionmeta("collectionname", args["l"]);
446          if (collectionname.empty()) {
447        collectionname = *collist_here;
448          }
449         
450          comerror_t err;
451          text_t optsite = g_EmptyText;
452          text_t site_name = (*rprotolist_here).p->get_site_name (err);
453          if (!site_name.empty()) { optsite = "site="+site_name+"&amp;"; }
454
455          text_t link = "<a href=\"_gwcgi_?"+optsite+"a=p&p=about&c=" + *collist_here + "\">";
456
457          if (!cinfo->receptionist.empty())
458        link = "<a href=\"" + cinfo->receptionist + "\">";
459         
460         collectionlist += "<li>" + link + collectionname + "</a>\n";
461        }
462      }
463      ++collist_here;
464    }
465      }
466    }
467    ++rprotolist_here;
468  }
469
470  if (count == 1) {
471    collectionlist = "<p>_text1coll_\n<ul>" +
472      collectionlist + "</ul>\n";
473  } else if (count > 1) {
474    collectionlist = "<p>_textmorecolls_(" + text_t(count) +
475      ")\n<ul>" + collectionlist + "</ul>\n";
476  }
477
478  disp.setmacro ("collectionlist", "homehelp", collectionlist);
479}
480
481void pageaction::set_documentation_macro (displayclass &disp) {
482
483  text_t documentation;
484  text_t docsdir = filename_cat(gsdlhome, "docs");
485 
486  if (file_exists(filename_cat(docsdir, "User.pdf"))) {
487    documentation += "<tr valign=middle><td><a href=\"_httpdocs_/User.pdf\">_iconpdf_"
488      "</a></td><td>_textuserguide_</td></tr>";
489  }
490 
491  if (file_exists(filename_cat(docsdir, "Install.pdf"))) {
492    documentation += "<tr valign=middle><td><a href=\"_httpdocs_/Install.pdf\">_iconpdf_"
493      "</a></td><td>_textinstallerguide_</td></tr>";
494  }
495 
496  if (file_exists(filename_cat(docsdir, "Develop.pdf"))) {
497    documentation += "<tr valign=middle><td><a href=\"_httpdocs_/Develop.pdf\">_iconpdf_"
498      "</a></td><td>_textdeveloperguide_</td></tr>";
499  }
500 
501  if (file_exists(filename_cat(docsdir, "Paper.pdf"))) {
502    documentation += "<tr valign=middle><td><a href=\"_httpdocs_/Paper.pdf\">_iconpdf_"
503      "</a></td><td>_textpaperguide_</td></tr>";
504  }
505 
506  if (file_exists(filename_cat(docsdir, "Organize.pdf"))) {
507    documentation += "<tr valign=middle><td><a href=\"_httpdocs_/Organize.pdf\">_iconpdf_"
508      "</a></td><td>_textorganizerguide_</td></tr>";
509  }
510
511  if (!documentation.empty()) {
512    disp.setmacro("documentation", "docs", "<p>\n<table border=0>\n" + documentation + "\n</table>\n");
513  }
514}
515
516void pageaction::set_macro_to_file_contents (displayclass &disp, const text_t &macroname,
517                         const text_t &packagename, const text_t &filename) {
518
519  text_t filecontent;
520  char *filenamec = filename.getcstr();
521  ifstream file_in (filenamec);
522  delete []filenamec;
523  if (file_in) {
524    char c;
525    file_in.get(c);
526    while (!file_in.eof ()) {
527      if (c == '\n') filecontent += "<br>";
528      filecontent.push_back(c);
529      file_in.get(c);
530    }
531    file_in.close();
532  }
533  disp.setmacro (macroname, packagename, dm_safe(filecontent));
534}
535
536void pageaction::set_language_encoding_macros(displayclass &disp, cgiargsclass &args,
537                          recptprotolistclass *protos, ColInfoResponse_t *cinfo,
538                          ostream &logout) {
539  // _languageoption_
540  // Create the "interface language" selection box for the preferences
541  // pages.  You can use something like "format PreferenceLanguages
542  // en|fr|zn" from within a collect.cfg file to use only a subset of
543  // the available languages for any given collection (for
544  // collection-specific preferences pages). This facility is kind of
545  // ugly though and should be replaced by something better when the
546  // configuration files are tidied up (as should all the other
547  // "format Preference..." options).
548  text_t &arg_l = args["l"];
549  const recptconf &configinfo = recpt->get_configinfo();
550  // put languages in another map to sort them by longname
551  text_tmap languages;
552  languageinfo_tmap::const_iterator thislang = configinfo.languages.begin();
553  languageinfo_tmap::const_iterator endlang = configinfo.languages.end();
554  while (thislang != endlang) {
555    languages[(*thislang).second.longname] = (*thislang).first;
556    ++thislang;
557  }
558  text_tmap::iterator tlang = languages.begin();
559  text_tmap::iterator elang = languages.end();
560
561  text_t languageoption;
562  bool collection_specific = false;
563
564  if (cinfo != NULL) {
565    text_tmap::const_iterator it = cinfo->format.find ("PreferenceLanguages");
566    if ((it != cinfo->format.end()) && (!(*it).second.empty())) {
567      collection_specific = true;
568      text_tset pref_langs;
569      splitchar ((*it).second.begin(), (*it).second.end(), '|', pref_langs);
570      if (pref_langs.size() > 1) {
571    while (tlang != elang) {
572      if (pref_langs.find((*tlang).second) != pref_langs.end()) {
573        languageoption += "<option value=\"" + (*tlang).second + "\"";
574        if ((*tlang).second == arg_l) languageoption += " selected";
575        languageoption += ">" + (*tlang).first + "</option>\n";
576      }
577      ++tlang;
578    }
579      }
580    }
581  }
582
583  if (!collection_specific) {
584    while (tlang != elang) {
585      languageoption += "<option value=\"" + (*tlang).second + "\"";
586      if ((*tlang).second == arg_l) languageoption += " selected";
587      languageoption += ">" + (*tlang).first + "</option>\n";
588      ++tlang;
589    }
590  }
591
592  if (!languageoption.empty()) {
593    languageoption = "<select name=\"l\" onChange=\"updatel();\">\n" + languageoption;
594    languageoption += "</select>\n";
595    disp.setmacro ("languageoption", args["p"], languageoption);
596  }
597
598  // _encodingoption_
599  // create the "encoding" selection box for the preferences page
600  if (configinfo.encodings.size() > 1) {
601    text_t &arg_w = args["w"];
602    text_t encodingoption;
603    text_tmap::const_iterator thisenc = configinfo.encodings.begin();
604    text_tmap::const_iterator endenc = configinfo.encodings.end();
605    while (thisenc != endenc) {
606      encodingoption += "<option value=\"" + (*thisenc).second + "\"";
607      if ((*thisenc).second == arg_w) encodingoption += " selected";
608      encodingoption += ">" + (*thisenc).first + "</option>\n";
609      ++thisenc;
610    }
611
612    encodingoption = "<select name=\"w\" onChange=\"updatew();\">\n" + encodingoption;
613    encodingoption += "</select>\n";
614    disp.setmacro ("encodingoption", args["p"], encodingoption);
615  } else if (configinfo.encodings.size() == 1) {
616    text_t encodingoption;
617    text_tmap::const_iterator thisenc = configinfo.encodings.begin();
618    encodingoption = (*thisenc).first;
619    disp.setmacro ("encodingoption", args["p"], encodingoption);
620  } else { // size == 0. shouldn't really happen, but allow it
621    disp.setmacro ("encodingoption", args["p"], "None");
622  }
623
624}
625
626
627void pageaction::define_internal_macros (displayclass &disp, cgiargsclass &args,
628                     recptprotolistclass *protos, ostream &logout) {
629
630  // define_internal_macros sets the following macros:
631
632  // _numdocs_             the number of documents in the collection
633
634  // _builddate_           the date last built
635
636  // if page is "home"
637  // _homeextra_           this is the list of available collections and collection info
638  //                       to be displayed on the home page
639
640
641  // if page is "preferences"
642  // _collectionoption_    collections to search/browse (if cross-collection-searching is on)
643
644  // _htmloptions_         set to _htmloptionson_ if DocumentUseHTML is set
645
646  // _PreferencesDocsFromWeb_ set to 1 if corresponding format option is set
647
648
649  // if page is "preferences" or "homepref"
650  // _languageoption_      interface languages to select from (dependant on PreferenceLanguages)
651
652  // _encodingoption_      encodings to select from
653
654
655  // if page is "about"
656  // _textsubcollections_  the text on which subcollections make up the collection (if
657  //                       cross-collection searching is being used
658
659  // _textbrowseoptions_   the 'how to find information' text in the about and help pages
660
661  // _numbrowseoptions_    the number of browsing options
662
663  // _prefschanged_        will be set to _textprefschanged_ if the "set preferences" button
664  //                       was pressed
665
666  // _aboutqueryform_      will be set to "" if the collection isn't searchable
667
668  // if page is "help"
669  // _textbrowseoptions_   the 'how to find information' text in the about and help pages
670
671  // _numbrowseoptions_    the number of browsing options
672
673  // _topicreadingdocs_    this section of the help text differs depending on what type of
674  // _textreadingdocs_     collection it is (e.g. html collection, bibliographic collection etc.)
675  // _texthelpreadingdocs_
676
677  // if page is "home" or "homehelp"
678  // _textgocollector_     set to "" if collector is disabled in main.cfg
679  // _textgodepositor_     set to "" if depositor is disabled in main.cfg
680  // _textgoadmin_         set to "" if status is disabled in main.cfg
681  // _textgotranslator_    set to "" if translator is disabled in main.cfg
682  // _textgogliapplet_     set to "" if gliapplet is disabled in main.cfg
683
684
685  // if page is "homehelp"
686  // _collectionlist_      list of available collections to be displayed on the homehelp page
687
688 
689  // if page is "docs"
690  // _documentation_       links to PDF documents if they're available
691
692
693  // if page is "bsummary"
694  // _importlog_           set to contents of collections import.log file
695  // _faillog_             set to contents of collections fail.log file
696  //_buildlog_             set to contents of collections build.log file
697 
698  if (recpt == NULL) {
699    logout << "ERROR (pageaction::define_internal_macros): This action does not contain\n"
700       << "      information about any receptionists. The method set_receptionist was\n"
701       << "      probably not called from the module which instantiated this action.\n";
702    return;
703  }
704  // _versionnnum_   greenstone version number (hard-coded)
705  disp.setmacro("versionnum", displayclass::defaultpackage, GSDL_VERSION);
706
707  text_t &arg_p = args["p"];
708  text_t &arg_c = args["c"];
709  ColInfoResponse_t *cinfo = NULL;
710
711  recptproto* collectproto = protos->getrecptproto (arg_c, logout);
712  if (collectproto != NULL) {
713    cinfo = recpt->get_collectinfo_ptr (collectproto, arg_c, logout);
714   
715    //set the tidyoption
716    if (cinfo->useBook == false)
717    {
718        disp.setmacro ("tidyoption", displayclass::defaultpackage, "untidy");
719    }
720    else
721    {
722        disp.setmacro ("tidyoption", displayclass::defaultpackage, "tidy");
723    }
724   
725    disp.setmacro ("numdocs", displayclass::defaultpackage, cinfo->numDocs);
726    disp.setmacro ("numsections", displayclass::defaultpackage, cinfo->numSections);
727    disp.setmacro ("numwords", displayclass::defaultpackage, cinfo->numWords);
728    unsigned long current_time = time(NULL);
729    unsigned long builddate = (current_time - cinfo->buildDate) / 86400;
730    disp.setmacro ("builddate", displayclass::defaultpackage, builddate);
731   
732    text_t numbytes;
733    if ((cinfo->numBytes/(1024*1024)) > 1) {
734      numbytes = (text_t)(cinfo->numBytes/(1024*1024)) + " Mb";
735    } else if ((cinfo->numBytes/1024) > 1) {
736      numbytes = (text_t)(cinfo->numBytes/1024) + " kb";
737    } else {
738      numbytes = (text_t)cinfo->numBytes + " bytes";
739    }
740    disp.setmacro("numbytes", displayclass::defaultpackage, numbytes);
741
742    // set up ct, qt, qto, sqlqto
743    set_query_type_args(cinfo, args);
744    // set up ks, ss, afs
745    set_stem_index_args(cinfo, args);
746 
747  }
748 
749  //setting _queryformcontent_ so that the query interface is consistent.
750  //also adding usability button if necessary
751  if (arg_p == "about") {
752    if (cinfo == NULL) {
753      disp.setmacro("cvariable", displayclass::defaultpackage, encodeForHTML(arg_c));
754      disp.setmacro("content", arg_p, "<p>_textbadcollection_<p>");
755      return;
756    }
757    else {
758
759      text_tmap::iterator check = cinfo->format.find("QueryInterface");
760      if(check != cinfo->format.end()){
761    if((*check).second=="DateSearch"){
762      text_t current = "_datesearch_";
763      disp.setmacro("optdatesearch","query",current);
764    }
765      }
766      check = cinfo->format.find("Usability");
767      if(check != cinfo->format.end()){
768    disp.setmacro("usability", displayclass::defaultpackage, "_usablink_");
769    disp.setmacro("usabinterface", displayclass::defaultpackage, ("_usab"+(*check).second+"_"));
770    disp.setmacro("usabilityscript", displayclass::defaultpackage, "_usabshowscript_");
771      }
772    }
773  }
774 
775 
776  if (arg_p == "home" || arg_p == "homehelp") {
777    if (status_disabled) disp.setmacro ("textgoadmin", "home", "");
778    if (collector_disabled) disp.setmacro ("textgocollector", "home", "");
779    if (depositor_disabled) disp.setmacro ("textgodepositor", "home", "");
780    if (translator_disabled) disp.setmacro ("textgotranslator", "home", "");
781
782    if (arg_p == "home") {
783      homepagestyle (disp, protos, args, logout);
784    } else if (arg_p == "homehelp") {
785      set_collectionlist_macro (disp, protos, args, logout);
786    }
787
788  } else if (arg_p == "gli") {
789    if (gliapplet_disabled) disp.setmacro ("gliapplet", "gli", "");
790
791  } else if (arg_p == "homepref") {
792 
793    // set _languageoption_ and _encodingoption_
794    set_language_encoding_macros(disp, args, protos, cinfo, logout);
795
796  } else if (arg_p == "preferences") {
797 
798    if (cinfo == NULL) {
799      disp.setmacro("cvariable", displayclass::defaultpackage, encodeForHTML(arg_c));
800      disp.setmacro("content", arg_p, "<p>_textbadcollection_<p>");
801      return;
802    }
803
804    if (collectproto == NULL) {return;}
805   
806    // set _languageoption_ and _encodingoption_
807    set_language_encoding_macros(disp, args, protos, cinfo, logout);
808
809    // _collectionoption_
810    if ((args["ccs"] == "1") && (cinfo->ccsCols.size() > 1)) {
811      text_t collectionoption = "_textcollectionoption_";
812      text_tarray::const_iterator col_here = cinfo->ccsCols.begin();
813      text_tarray::const_iterator col_end = cinfo->ccsCols.end();
814      int count = 0;
815      while (col_here != col_end) {
816    text_t colname;
817    if (*col_here == arg_c) {
818        colname = cinfo->get_collectionmeta("collectionname", args["l"]);
819    } else {
820      ColInfoResponse_t *this_cinfo = recpt->get_collectinfo_ptr (collectproto, *col_here, logout);
821      if (this_cinfo == NULL) {++col_here; continue;}
822      colname = this_cinfo->get_collectionmeta("collectionname", args["l"]);
823    }
824    if (colname.empty()) {
825      colname = *col_here;
826    }
827    ++count;
828    collectionoption += "<input type=checkbox name=\"cc\" value=\"" +
829      *col_here + "\" onClick=\"updatecc(\'" + *col_here + "\');\"> " +
830      colname + "<br>\n";
831    ++col_here;
832      }
833     
834      if (count > 1)
835    disp.setmacro ("collectionoption", "preferences", collectionoption);
836    }
837
838    // _htmloptions_
839   
840    text_tmap::const_iterator it = cinfo->format.find ("DocumentUseHTML");
841    if ((it != cinfo->format.end()) && ((*it).second == "true")) {
842      disp.setmacro ("htmloptions", "preferences", "_htmloptionson_");
843
844
845      // _PreferenceDocsFromWeb_
846
847      it = cinfo->format.find ("PreferenceDocsFromWeb");
848      if ((it == cinfo->format.end()) || ((*it).second == "true"))
849    disp.setmacro ("PreferenceDocsFromWeb", "preferences", "1");
850    }
851
852    // _prefschanged_
853    if (!args["bp"].empty()) {
854      disp.setmacro ("prefschanged", "preferences", "_textprefschanged_");
855    }
856   
857  } else if (arg_p == "about" || arg_p == "help") {
858    if (collectproto == NULL) return;
859
860    comerror_t err;
861    bool has_search_button = true;
862    collectproto->is_searchable(args["c"], has_search_button, err, logout);
863    if (err != noError) has_search_button = true;
864   
865    // _textbrowseoptions_ and _numbrowseoptions_
866   
867    FilterResponse_t response;
868    text_tset metadata;
869    metadata.insert ("Title");
870    //****************
871    metadata.insert ("childtype");
872    //****************
873    bool getParents = false;
874    get_children ("", args["c"], args["l"], metadata, getParents, collectproto, response, logout);
875
876    int numbrowseoptions = response.docInfo.size();
877    if (has_search_button) numbrowseoptions += 1;
878    disp.setmacro ("numbrowseoptions", "help", numbrowseoptions);
879
880    ResultDocInfo_tarray::iterator here = response.docInfo.begin();
881    ResultDocInfo_tarray::iterator end = response.docInfo.end();
882
883    text_t helptext;
884    if (has_search_button) {
885      helptext = "<ul><li>_textSearchhelp_\n";
886    }
887
888    // ********************************     
889    int classifiernumber = 0;
890    bool collage = false;
891
892    while (here != end) {
893     
894      ++classifiernumber;
895      text_t childtype = (*here).metadata["childtype"].values[0];
896      if (childtype == "Collage" && arg_p == "about") {
897    // get the classifier number
898    disp.setmacro ("classifier", "about", classifiernumber);
899    disp.setmacro ("aboutCollage", "about", "_collageapplet_");
900    collage = true;
901      }
902      ++here;
903    }
904    if (! collage)
905      disp.setmacro ("aboutCollage", "about", "_collageempty_");
906   
907    // ********************************
908     
909    here = response.docInfo.begin();
910
911    while (here != end) {
912     
913      text_t title = (*here).metadata["Title"].values[0];
914   
915      text_t stext;
916      disp.expandstring ("help", "_text" + title + "help_", stext);
917      if (stext == ("_text" + title + "help_")) {
918    text_t ltext, ttext;
919    disp.expandstring("Global", "_label"+title+"_", ltext);
920    if (ltext == ("_label"+title+"_")) {
921      ltext = title;
922    }
923    disp.expandstring("Global", "_text"+title+"_", ttext);
924    if (ttext == ("_text"+title+"_")) {
925      ttext = title;
926    }
927    helptext += "<li>_help:textdefaulthelp_("+ttext+","+ltext+")";
928      } else {
929    helptext += "<li>_help:text" + title + "help_";
930      }
931
932      ++here;
933    }
934    helptext += "</ul>\n";
935    disp.setmacro ("textbrowseoptions", "help", helptext);
936
937    if (arg_p == "help") {
938      // do we need to add in the datesearch help??
939      text_tmap::iterator check = cinfo->format.find("QueryInterface");
940      if(check != cinfo->format.end()){
941    if((*check).second=="DateSearch"){
942      text_t current = "_datesearch_";
943      disp.setmacro("optdatesearchhelp","help","_datesearchhelp_");
944      disp.setmacro("optdatesearchhelpcontents","help","_datesearchhelpcontents_");
945    }
946      }
947     
948    }
949   
950    if (arg_p == "about") {
951
952      // _textsubcollections_
953      if (args["ccs"] == "1" && (cinfo->ccsCols.size() > 1)) {
954    text_t textsubcollections = "_textsubcols1_(" + text_t(cinfo->ccsCols.size()) + ")";
955    text_tarray::const_iterator here = cinfo->ccsCols.begin();
956    text_tarray::const_iterator end = cinfo->ccsCols.end();
957    bool first = true;
958    int count = 0;
959    while (here != end) {
960      if (*here == arg_c) {
961        if (!first) textsubcollections += "<br>";
962        textsubcollections += "\n" + cinfo->get_collectionmeta("collectionname", args["l"]) + "\n";
963      } else {
964        ColInfoResponse_t *this_cinfo = recpt->get_collectinfo_ptr (collectproto, *here, logout);
965        if (this_cinfo == NULL) {++here; continue;}
966        if (!first) textsubcollections += "<br>";
967        textsubcollections += "\n" + this_cinfo->get_collectionmeta("collectionname", args["l"]) + "\n";
968      }
969      ++count;
970      first = false;
971      ++here;
972    }
973    textsubcollections += "_textsubcols2_";
974    if (count > 1) {
975      disp.setmacro ("textsubcollections", "about", textsubcollections);
976    }
977      }
978
979      comerror_t err;
980      bool issearchable = true;
981      collectproto->is_searchable(args["c"], issearchable, err, logout);
982      if (err != noError) issearchable = true;
983      outconvertclass t;
984      if (!issearchable ) {
985    disp.setmacro ("aboutqueryform", "about", "");
986      }
987    }
988
989  } else if (arg_p == "docs") {
990
991    set_documentation_macro (disp);
992
993  } else if (arg_p == "bsummary" && !arg_c.empty()) {
994
995    set_macro_to_file_contents (disp, "importlog", "bsummary",
996                filename_cat(collecthome, arg_c, "etc", "import.log"));
997    set_macro_to_file_contents (disp, "faillog", "bsummary",
998                filename_cat(collecthome, arg_c, "etc", "fail.log"));
999    set_macro_to_file_contents (disp, "buildlog", "bsummary",
1000                filename_cat(collecthome, arg_c, "etc", "build.log"));
1001  }
1002}
1003
1004bool pageaction::do_action (cgiargsclass &args, recptprotolistclass * /*protos*/,
1005                browsermapclass * /*browsers*/, displayclass &disp,
1006                outconvertclass &outconvert, ostream &textout,
1007                ostream &/*logout*/) {
1008
1009  text_t &arg_p = args["p"];
1010
1011  textout << outconvert << disp << ("_" + encodeForHTML(arg_p) + ":header_\n")
1012      << ("_" + encodeForHTML(arg_p) + ":content_\n")
1013      << ("_" + encodeForHTML(arg_p) + ":footer_\n");
1014
1015  return true;
1016}
1017
1018void pageaction::configure (const text_t &key, const text_tarray &cfgline) {
1019  if ((key == "status") && (cfgline.size() == 1) &&
1020      (cfgline[0] == "true" || cfgline[0] == "on" || cfgline[0] == "enabled")) {
1021    status_disabled = false;
1022  } else if ((key == "collector") && (cfgline.size() == 1) &&
1023         (cfgline[0] == "true" || cfgline[0] == "on" || cfgline[0] == "enabled")) {
1024    collector_disabled = false;
1025  }
1026 else if ((key == "depositor") && (cfgline.size() == 1) &&
1027         (cfgline[0] == "true" || cfgline[0] == "on" || cfgline[0] == "enabled")) {
1028    depositor_disabled = false;
1029  }
1030    else if ((key == "translator") && (cfgline.size() == 1) &&
1031         (cfgline[0] == "true" || cfgline[0] == "on" || cfgline[0] == "enabled")) {
1032    translator_disabled = false;
1033  } else if ((key == "gliapplet") && (cfgline.size() == 1) &&
1034         (cfgline[0] == "true" || cfgline[0] == "on" || cfgline[0] == "enabled")) {
1035    gliapplet_disabled = false;
1036  }
1037  else {
1038    // call the parent class to deal with the things which
1039    // are not dealt with here
1040    action::configure (key, cfgline);
1041  }
1042}
1043
1044
1045
1046
1047
1048
1049
1050
1051
1052
Note: See TracBrowser for help on using the browser.