Ignore:
Timestamp:
1999-02-08T14:28:04+13:00 (25 years ago)
Author:
rjmcnab
Message:

Got the receptionist producing something using the statusaction.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/gsdl/src/recpt/receptionist.cpp

    r150 r155  
    1212/*
    1313   $Log$
     14   Revision 1.5  1999/02/08 01:28:02  rjmcnab
     15
     16   Got the receptionist producing something using the statusaction.
     17
    1418   Revision 1.4  1999/02/05 10:42:46  rjmcnab
    1519
     
    3135#include "receptionist.h"
    3236#include "fileutil.h"
     37#include "cgiutils.h"
    3338#include <assert.h>
    3439#include <time.h>
     
    6166}
    6267
    63 
    64 // sets the http address of the images directory. This is used to
    65 // speed up the access to the images which are a part of the general
    66 // interface. If this is not set the interface will have to get the
    67 // images via gwcgi which will be a lot slower (especially if the
    68 // browser does not cache the images).
    69 void receptionist::set_httpimg (const text_t &thehttpimg) {
    70   httpimg = thehttpimg;
    71 }
    72 
    73 // sets the http address of the gateway cgi program (ie. the program
    74 // that contains this receptionist).
    75 void receptionist::set_gwcgi (const text_t &thegwcgi) {
    76   gwcgi = thegwcgi;
    77 }
    78 
     68// configure_actions should be called for each line in the
     69// configuration files to configure the actions. The configuration
     70// should take place after all the actions have been added.
     71void receptionist::configure_actions (const text_t &key, const text_tarray &cfgline) {
     72  actionptrmap::iterator here = actions.begin ();
     73  actionptrmap::iterator end = actions.end ();
     74
     75  while (here != end) {
     76    assert ((*here).second.a != NULL);
     77    if ((*here).second.a != NULL)
     78      (*here).second.a->configure(key, cfgline);
     79
     80    here++;
     81  }
     82}
    7983
    8084// init should be called after setgsdhome has been called.
     
    8488// produced by the calling code.
    8589bool receptionist::init (ostream &logout) {
    86   // redirect the error output to logout
    87   //  disp.setlogout (&logout);
    88 
    89   // set default values for the configuration file
    90   //  cfg_info.defaultaction = "p";
    91   //  cfg_info.defaultpage = "about";
    92   //  cfg_info.defaultencoding = "w";
    93 
    94   // load up the default macro files, the collection directory
    95   // is searched first for the file and then the main directory
    96   //  text_t colmacrodir = filename_cat (collectdir, "macros");
    97   //  text_t gsdlmacrodir = filename_cat (gsdlhome, "macros");
    98   //  text_tarray::iterator arrhere = cfg_info.macrofiles.begin();
    99   //  text_tarray::iterator arrend = cfg_info.macrofiles.end();
    100   //  while (arrhere != arrend) {
    101   //    filename = filename_cat (colmacrodir, *arrhere);
    102   //    if (!file_exists (filename)) {
    103   //      filename = filename_cat (gsdlmacrodir, *arrhere);
    104   //    }
    105   //    disp.loaddefaultmacros(filename);
    106   //    arrhere++;
    107   //  }
    108 
    109   srand(time(NULL));
     90  // read in the macro files
     91  if (!read_macrofiles (logout)) return false;
     92
     93  // defined the main cgi arguments
     94  if (!define_mainargs (logout)) return false;
     95
     96  // add the cgi arguments from the actions
     97  actionptrmap::iterator here = actions.begin ();
     98  actionptrmap::iterator end = actions.end ();
     99  while (here != end) {
     100    assert ((*here).second.a != NULL);
     101    if ((*here).second.a != NULL) {
     102      if (!argsinfo.addarginfo (&logout, (*here).second.a->getargsinfo()))
     103    return false;
     104    }
     105    here++;
     106  }
     107
     108  // create a saveconf string if there isn't one already
     109  if (saveconf.empty())
     110    saveconf = create_save_conf_str (argsinfo, logout);
     111
     112  // check the saveconf string
     113  if (!check_save_conf_str (saveconf, argsinfo, logout))
     114    return false;
     115
     116  // set a random seed
     117  srand (time(NULL));
    110118
    111119  //  utf8outconvert.set_rzws(1);
     
    116124
    117125
    118 // produce_cgi_page will call parse_cgi_args, get_cgihead_info and
     126// parse_cgi_args parses cgi arguments into an argument class.
     127// This function should be called for each page request. It returns false
     128// if there was a major problem with the cgi arguments.
     129bool receptionist::parse_cgi_args (const text_t &argstr, cgiargsclass &args,
     130                   ostream &logout) {
     131  outconvertclass text_t2ascii;
     132
     133  // get an initial list of cgi arguments
     134  args.clear();
     135  split_cgi_args (argstr, args);
     136
     137  // expand the compressed argument (if there was one)
     138  if (!expand_save_args (argsinfo, saveconf, args, logout)) return false;
     139
     140  // add the defaults
     141  add_default_args (argsinfo, args, logout);
     142
     143  // check the main cgi arguments
     144  if (!check_mainargs (args, logout)) return false;
     145
     146  // check the arguments for the action
     147  action *a = actions.getaction (args["a"]);
     148  if (a != NULL) {
     149    if (!a->check_cgiargs (args, logout)) return false;
     150  } else {
     151    // the action was not found!!
     152    logout << text_t2ascii << "Error: the action \"" << args["a"]
     153       << "\" could not be found.\n";
     154    return false;
     155  }
     156
     157  return true;
     158}
     159
     160
     161// produce_cgi_page will call get_cgihead_info and
    119162// produce_content in the appropriate way to output a cgi header and
    120 // the page content (if needed).
    121 void receptionist::produce_cgi_page (const text_t &argstr, ostream &contentout,
     163// the page content (if needed). If a page could not be created it
     164// will return false
     165bool receptionist::produce_cgi_page (cgiargsclass &args, ostream &contentout,
    122166                     ostream &logout) {
    123   contentout << "Content-type: text/plain\n\nHello\n";
     167  outconvertclass text_t2ascii;
     168
     169  response_t response;
     170  text_t response_data;
     171
     172  // produce cgi header
     173  get_cgihead_info (args, response, response_data, logout);
     174  if (response == location) {
     175    // I've forgotten how to do this :-/
     176    return true;
     177  } else if (response == content) {
     178    // content response
     179    contentout << text_t2ascii << "Content-type: " << response_data << "\n\n";
     180  } else {
     181    // unknown response
     182    logout << "Error: get_cgihead_info returned an unknown response type.\n";
     183    return false;
     184  }
     185
     186  // produce cgi page
     187  if (!produce_content (args, contentout, logout)) return false;
     188
     189  // flush contentout
    124190  contentout << flush;
    125 }
    126 
    127 
    128 // parse_cgi_args parses cgi arguments into an argument class.
    129 // This function should be called for each page request.
    130 void receptionist::parse_cgi_args (const text_t &argstr, cgiargsclass &args,
    131                    ostream &logout) {
     191  return true;
    132192}
    133193
     
    140200void receptionist::get_cgihead_info (cgiargsclass &args, response_t &response,
    141201                     text_t &response_data, ostream &logout) {
     202  outconvertclass text_t2ascii;
     203
     204  // get the action
     205  action *a = actions.getaction (args["a"]);
     206  if (a != NULL) {
     207    a->get_cgihead_info (args, response, response_data, logout);
     208
     209  } else {
     210    // the action was not found!!
     211    logout << text_t2ascii << "Error receptionist::get_cgihead_info: the action \""
     212       << args["a"] << "\" could not be found.\n";
     213    response = content;
     214    response_data = "text/html";
     215  }
    142216}
    143217
    144218
    145219// produce the page content
    146 void receptionist::produce_content (cgiargsclass &args, ostream &contentout,
     220bool receptionist::produce_content (cgiargsclass &args, ostream &contentout,
    147221                    ostream &logout) {
     222  outconvertclass text_t2ascii;
     223
     224  // decide on the output conversion class
     225
     226  // produce the page using the desired action
     227  action *a = actions.getaction (args["a"]);
     228  if (a != NULL) {
     229    if (!a->do_action (args, text_t2ascii, contentout, logout))
     230      return false;
     231
     232  } else {
     233    // the action was not found!!
     234    logout << text_t2ascii << "Error receptionist::produce_content: the action \""
     235       << args["a"] << "\" could not be found.\n";
     236   
     237    contentout << text_t2ascii << "<html>\n";
     238    contentout << text_t2ascii << "<head>\n";
     239    contentout << text_t2ascii << "<title>Error</title>\n";
     240    contentout << text_t2ascii << "</head>\n";
     241    contentout << text_t2ascii << "<body>\n";
     242    contentout << text_t2ascii << "<h2>Oops!</h2>\n";
     243    contentout << text_t2ascii << "Undefined Page. The action \""
     244           << args["a"] << "\" could not be found.\n";
     245    contentout << text_t2ascii << "</body>\n";
     246    contentout << text_t2ascii << "</html>\n";
     247  }
     248
     249  return true;
    148250}
    149251
     
    154256  return "";
    155257}
     258
     259
     260// will read in all the macro files. If one is not found an
     261// error message will be written to logout and the method will
     262// return false.
     263bool receptionist::read_macrofiles (ostream &logout) {
     264  outconvertclass text_t2ascii;
     265
     266  // redirect the error output to logout
     267  disp.setlogout (&logout);
     268
     269  // load up the default macro files, the collection directory
     270  // is searched first for the file (if this is being used in
     271  // collection specific mode) and then the main directory
     272  text_t colmacrodir = filename_cat (collectdir, "macros");
     273  text_t gsdlmacrodir = filename_cat (gsdlhome, "macros");
     274  text_tarray::iterator arrhere = macrofiles.begin();
     275  text_tarray::iterator arrend = macrofiles.end();
     276  text_t filename;
     277  while (arrhere != arrend) {
     278    // filename is used as a flag to indicate whether
     279    // the macro file has been found
     280    filename.clear();
     281
     282    // try in the collection directory if this is being
     283    // run in collection specific mode
     284    if (!collection.empty()) {
     285      filename = filename_cat (colmacrodir, *arrhere);
     286      if (!file_exists (filename)) filename.clear ();
     287    }
     288
     289    // if we haven't found the macro file yet try in
     290    // the main macro directory
     291    if (filename.empty()) {
     292      filename = filename_cat (gsdlmacrodir, *arrhere);
     293      if (!file_exists (filename)) filename.clear ();
     294    }
     295
     296    // see if we found the file or not
     297    if (filename.empty()) {
     298      logout << text_t2ascii
     299         << "Error: the macro file \"" << *arrhere << "\" could not be found.\n";
     300      if (collection.empty()) {
     301    logout << text_t2ascii
     302           << "It should be in " << gsdlmacrodir << ".\n\n";
     303      } else {
     304    logout << text_t2ascii
     305           << "It should be in either " << colmacrodir << " or in "
     306           << gsdlmacrodir << ".\n\n";
     307      }
     308      return false;
     309
     310    } else { // found the file
     311      disp.loaddefaultmacros(filename);
     312    }
     313
     314    arrhere++;
     315  }
     316
     317  // success
     318  return true;
     319}
     320
     321
     322// Will define the main general arguments used by the receptionist.
     323// If an error occurs a message will be written to logout and the
     324// method will return false.
     325bool receptionist::define_mainargs (ostream &logout) {
     326  // create a list of cgi arguments
     327  cgiarginfo ainfo;
     328
     329  ainfo.shortname = "e";
     330  ainfo.longname = "compressed arguments";
     331  ainfo.multiplechar = true;
     332  ainfo.defaultstatus = cgiarginfo::good;
     333  ainfo.argdefault = "";
     334  ainfo.savedarginfo = cgiarginfo::mustnot;
     335  if (!argsinfo.addarginfo (&logout, ainfo)) return false;
     336
     337  ainfo.shortname = "a";
     338  ainfo.longname = "action";
     339  ainfo.multiplechar = true;
     340  ainfo.defaultstatus = cgiarginfo::none;
     341  ainfo.argdefault = "";
     342  ainfo.savedarginfo = cgiarginfo::must;
     343  if (!argsinfo.addarginfo (&logout, ainfo)) return false;
     344
     345  // w=western
     346  ainfo.shortname = "w";
     347  ainfo.longname = "encoding";
     348  ainfo.multiplechar = true;
     349  ainfo.defaultstatus = cgiarginfo::weak;
     350  ainfo.argdefault = "w";
     351  ainfo.savedarginfo = cgiarginfo::must;
     352  if (!argsinfo.addarginfo (&logout, ainfo)) return false;
     353 
     354  ainfo.shortname = "nw";
     355  ainfo.longname = "new encoding";
     356  ainfo.multiplechar = true;
     357  ainfo.defaultstatus = cgiarginfo::none;
     358  ainfo.argdefault = "";
     359  ainfo.savedarginfo = cgiarginfo::mustnot;
     360  if (!argsinfo.addarginfo (&logout, ainfo)) return false;
     361 
     362  ainfo.shortname = "c";
     363  ainfo.longname = "collection";
     364  ainfo.multiplechar = true;
     365  if (collection.empty()) {
     366    ainfo.defaultstatus = cgiarginfo::none;
     367    ainfo.argdefault = "";
     368    ainfo.savedarginfo = cgiarginfo::must;
     369  } else {
     370    ainfo.defaultstatus = cgiarginfo::good;
     371    ainfo.argdefault = collection;
     372    ainfo.savedarginfo = cgiarginfo::can;
     373  }
     374  if (!argsinfo.addarginfo (&logout, ainfo)) return false;
     375 
     376  // 0=text+graphics, 1=text
     377  ainfo.shortname = "v";
     378  ainfo.longname = "version";
     379  ainfo.multiplechar = false;
     380  ainfo.defaultstatus = cgiarginfo::weak;
     381  ainfo.argdefault = "0";
     382  ainfo.savedarginfo = cgiarginfo::can;
     383  if (!argsinfo.addarginfo (&logout, ainfo)) return false;
     384 
     385  // 0=normal, 1=big
     386  ainfo.shortname = "f";
     387  ainfo.longname = "query box size";
     388  ainfo.multiplechar = false;
     389  ainfo.defaultstatus = cgiarginfo::weak;
     390  ainfo.argdefault = "0";
     391  ainfo.savedarginfo = cgiarginfo::can;
     392  if (!argsinfo.addarginfo (&logout, ainfo)) return false;
     393 
     394  // the interface language name should use the ISO 639
     395  // standard
     396  ainfo.shortname = "l";
     397  ainfo.longname = "interface language";
     398  ainfo.multiplechar = true;
     399  ainfo.defaultstatus = cgiarginfo::weak;
     400  ainfo.argdefault = "en";
     401  ainfo.savedarginfo = cgiarginfo::must;
     402  if (!argsinfo.addarginfo (&logout, ainfo)) return false;
     403
     404  return true;
     405}
     406 
     407 
     408// check_mainargs will check all the main arguments. If a major
     409// error is found it will return false and no cgi page should
     410// be created using the arguments.
     411bool receptionist::check_mainargs (cgiargsclass &args, ostream &logout) {
     412  // if this receptionist is running in collection dependant mode
     413  // then it should always set the collection argument to the
     414  // collection
     415  if (!collection.empty()) args["c"] = collection;
     416
     417  // argument "v" can only be 0 or 1. Use the default value
     418  // if it is out of range
     419  int arg_v = args.getintarg ("v");
     420  if (arg_v != 0 && arg_v != 1) {
     421    cgiarginfo *vinfo = argsinfo.getarginfo ("v");
     422    if (vinfo != NULL) args["v"] = vinfo->argdefault;
     423  }
     424
     425  // argument "f" can only be 0 or 1. Use the default value
     426  // if it is out of range
     427  int arg_f = args.getintarg ("f");
     428  if (arg_f != 0 && arg_f != 1) {
     429    cgiarginfo *finfo = argsinfo.getarginfo ("f");
     430    if (finfo != NULL) args["f"] = finfo->argdefault;
     431  }
     432
     433  return true;
     434}
Note: See TracChangeset for help on using the changeset viewer.