/********************************************************************** * * queryaction.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. * * $Id: queryaction.cpp 543 1999-09-07 23:12:34Z rjmcnab $ * *********************************************************************/ /* $Log$ Revision 1.22 1999/09/07 23:08:51 rjmcnab removed some compiler warnings Revision 1.21 1999/09/07 04:56:57 sjboddie added GPL notice Revision 1.20 1999/08/25 04:47:55 sjboddie added advanced search option - other minor changes Revision 1.19 1999/08/13 04:17:24 sjboddie small change to do with new collection-level metadata Revision 1.18 1999/08/10 22:46:33 sjboddie changed format option result to QueryResults and added QueryLinks option Revision 1.17 1999/07/30 02:24:42 sjboddie added collectinfo argument to some functions Revision 1.16 1999/07/19 00:16:58 sjboddie no longer display documents that don't match all phrases in query string Revision 1.15 1999/07/16 08:33:36 rjmcnab Changed the logic for getting the results string slightly Revision 1.14 1999/07/16 03:41:29 sjboddie changed isApprox Revision 1.13 1999/07/16 00:19:01 sjboddie some changes to the way quoted queries are handled Revision 1.12 1999/07/09 02:17:55 rjmcnab Setting macros needed for a second query. Revision 1.11 1999/07/07 06:13:10 rjmcnab Added ability to combine two independant queries. Revision 1.10 1999/07/07 05:49:35 sjboddie had another crack at the format string code - created a new formattools module. It can now handle {If} and {Or} statements although there's a bug preventing nested if's and or's. Revision 1.9 1999/07/01 22:48:46 sjboddie had a go at getting a query result format string working Revision 1.8 1999/06/27 22:02:11 sjboddie author is added to queryresults if there is one Revision 1.7 1999/06/26 01:10:18 rjmcnab Made h, i, and n arguments saved in the compressed arguments. Revision 1.6 1999/06/24 05:12:25 sjboddie lots of small changes Revision 1.5 1999/06/16 04:03:48 sjboddie Now sets "cl" arg to "search" when going to a document from a search results page. This allows the close book icon (in hierarchy toc) to take you back to the results page if that's where you came from. If you got to the document page somehow other than from a classification or a search (i.e. if "cl" isn't set) then the close book icon is disabled Revision 1.4 1999/06/16 02:08:38 sjboddie got queryaction working Revision 1.3 1999/03/25 03:06:45 sjboddie altered receptionist slightly so it now passes *collectproto to define_internal_macros and define_external_macros - need it for browseaction Revision 1.2 1999/03/03 20:26:50 rjmcnab Modified stuff. Revision 1.1 1999/02/28 22:45:21 rjmcnab Initial revision. */ #include "queryaction.h" #include "querytools.h" #include "formattools.h" queryaction::queryaction () { num_phrases = 0; // 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 = "q"; arg_ainfo.savedarginfo = cgiarginfo::must; argsinfo.addarginfo (NULL, arg_ainfo); // "b" - 0 = simple, 1 = advanced arg_ainfo.shortname = "b"; arg_ainfo.longname = "query mode"; arg_ainfo.multiplechar = false; arg_ainfo.defaultstatus = cgiarginfo::weak; arg_ainfo.argdefault = "0"; arg_ainfo.savedarginfo = cgiarginfo::must; argsinfo.addarginfo (NULL, arg_ainfo); // "h" arg_ainfo.shortname = "h"; arg_ainfo.longname = "main index"; arg_ainfo.multiplechar = true; arg_ainfo.defaultstatus = cgiarginfo::weak; arg_ainfo.argdefault = ""; arg_ainfo.savedarginfo = cgiarginfo::must; argsinfo.addarginfo (NULL, arg_ainfo); // "h2" arg_ainfo.shortname = "h2"; arg_ainfo.longname = "main index for second query"; arg_ainfo.multiplechar = true; arg_ainfo.defaultstatus = cgiarginfo::weak; arg_ainfo.argdefault = ""; arg_ainfo.savedarginfo = cgiarginfo::must; argsinfo.addarginfo (NULL, arg_ainfo); // "j" arg_ainfo.shortname = "j"; arg_ainfo.longname = "sub collection index"; arg_ainfo.multiplechar = true; arg_ainfo.defaultstatus = cgiarginfo::weak; arg_ainfo.argdefault = ""; arg_ainfo.savedarginfo = cgiarginfo::must; argsinfo.addarginfo (NULL, arg_ainfo); // "j2" arg_ainfo.shortname = "j2"; arg_ainfo.longname = "sub collection index for second query"; arg_ainfo.multiplechar = true; arg_ainfo.defaultstatus = cgiarginfo::weak; arg_ainfo.argdefault = ""; arg_ainfo.savedarginfo = cgiarginfo::must; argsinfo.addarginfo (NULL, arg_ainfo); // "n" arg_ainfo.shortname = "n"; arg_ainfo.longname = "language index"; arg_ainfo.multiplechar = true; arg_ainfo.defaultstatus = cgiarginfo::weak; arg_ainfo.argdefault = ""; arg_ainfo.savedarginfo = cgiarginfo::must; argsinfo.addarginfo (NULL, arg_ainfo); // "n2" arg_ainfo.shortname = "n2"; arg_ainfo.longname = "language index for second query"; arg_ainfo.multiplechar = true; arg_ainfo.defaultstatus = cgiarginfo::weak; arg_ainfo.argdefault = ""; arg_ainfo.savedarginfo = cgiarginfo::must; argsinfo.addarginfo (NULL, arg_ainfo); // "q" arg_ainfo.shortname = "q"; arg_ainfo.longname = "query string"; arg_ainfo.multiplechar = true; arg_ainfo.defaultstatus = cgiarginfo::weak; arg_ainfo.argdefault = ""; arg_ainfo.savedarginfo = cgiarginfo::must; argsinfo.addarginfo (NULL, arg_ainfo); // "q2" arg_ainfo.shortname = "q2"; arg_ainfo.longname = "query string for second query"; arg_ainfo.multiplechar = true; arg_ainfo.defaultstatus = cgiarginfo::weak; arg_ainfo.argdefault = ""; arg_ainfo.savedarginfo = cgiarginfo::must; argsinfo.addarginfo (NULL, arg_ainfo); // "cq2" ""=don't combine, "and", "or", "not" arg_ainfo.shortname = "cq2"; arg_ainfo.longname = "combine queries"; arg_ainfo.multiplechar = true; arg_ainfo.defaultstatus = cgiarginfo::weak; arg_ainfo.argdefault = ""; arg_ainfo.savedarginfo = cgiarginfo::must; argsinfo.addarginfo (NULL, arg_ainfo); // "t" - 1 = ranked 0 = boolean arg_ainfo.shortname = "t"; arg_ainfo.longname = "search type"; arg_ainfo.multiplechar = false; arg_ainfo.defaultstatus = cgiarginfo::weak; arg_ainfo.argdefault = "1"; arg_ainfo.savedarginfo = cgiarginfo::must; argsinfo.addarginfo (NULL, arg_ainfo); // "k" arg_ainfo.shortname = "k"; arg_ainfo.longname = "casefolding"; arg_ainfo.multiplechar = false; arg_ainfo.defaultstatus = cgiarginfo::weak; arg_ainfo.argdefault = "1"; arg_ainfo.savedarginfo = cgiarginfo::must; argsinfo.addarginfo (NULL, arg_ainfo); // "s" arg_ainfo.shortname = "s"; arg_ainfo.longname = "stemming"; arg_ainfo.multiplechar = false; arg_ainfo.defaultstatus = cgiarginfo::weak; arg_ainfo.argdefault ="0"; arg_ainfo.savedarginfo = cgiarginfo::must; argsinfo.addarginfo (NULL, arg_ainfo); // "m" arg_ainfo.shortname = "m"; arg_ainfo.longname = "maximum number of documents"; arg_ainfo.multiplechar = true; arg_ainfo.defaultstatus = cgiarginfo::weak; arg_ainfo.argdefault = "50"; arg_ainfo.savedarginfo = cgiarginfo::must; argsinfo.addarginfo (NULL, arg_ainfo); // "o" arg_ainfo.shortname = "o"; arg_ainfo.longname = "hits per page"; arg_ainfo.multiplechar = true; arg_ainfo.defaultstatus = cgiarginfo::weak; arg_ainfo.argdefault = "20"; arg_ainfo.savedarginfo = cgiarginfo::must; argsinfo.addarginfo (NULL, arg_ainfo); // "r" arg_ainfo.shortname = "r"; arg_ainfo.longname = "start results from"; arg_ainfo.multiplechar = true; arg_ainfo.defaultstatus = cgiarginfo::weak; arg_ainfo.argdefault = "1"; arg_ainfo.savedarginfo = cgiarginfo::must; argsinfo.addarginfo (NULL, arg_ainfo); } void queryaction::configure (const text_t &key, const text_tarray &cfgline) { action::configure (key, cfgline); } bool queryaction::init (ostream &logout) { return action::init (logout); } bool queryaction::check_cgiargs (cgiargsinfoclass &argsinfo, cgiargsclass &args, ostream &logout) { // check t argument int arg_t = args.getintarg("t"); if (arg_t != 0 && arg_t != 1) { logout << "Warning: \"t\" argument out of range (" << arg_t << ")\n"; cgiarginfo *tinfo = argsinfo.getarginfo ("t"); if (tinfo != NULL) args["t"] = tinfo->argdefault; } // check k argument int arg_k = args.getintarg("k"); if (arg_k != 0 && arg_k != 1) { logout << "Warning: \"k\" argument out of range (" << arg_k << ")\n"; cgiarginfo *kinfo = argsinfo.getarginfo ("k"); if (kinfo != NULL) args["k"] = kinfo->argdefault; } // check s argument int arg_s = args.getintarg("s"); if (arg_s != 0 && arg_s != 1) { logout << "Warning: \"s\" argument out of range (" << arg_s << ")\n"; cgiarginfo *sinfo = argsinfo.getarginfo ("s"); if (sinfo != NULL) args["s"] = sinfo->argdefault; } // check m argument int arg_m = args.getintarg("m"); if (arg_m < 0) { logout << "Warning: \"m\" argument less than 0 (" << arg_m << ")\n"; cgiarginfo *minfo = argsinfo.getarginfo ("m"); if (minfo != NULL) args["m"] = minfo->argdefault; } // check o argument int arg_o = args.getintarg("o"); if (arg_o < 0) { logout << "Warning: \"o\" argument less than 0 (" << arg_o << ")\n"; cgiarginfo *oinfo = argsinfo.getarginfo ("o"); if (oinfo != NULL) args["o"] = oinfo->argdefault; } // check r argument int arg_r = args.getintarg("r"); if (arg_r < 1) { logout << "Warning: \"r\" argument less than 1 (" << arg_r << ")\n"; cgiarginfo *rinfo = argsinfo.getarginfo ("r"); if (rinfo != NULL) args["r"] = rinfo->argdefault; } return true; } void queryaction::get_cgihead_info (cgiargsclass &/*args*/, response_t &response, text_t &response_data, ostream &/*logout*/) { response = content; response_data = "text/html"; } void queryaction::define_internal_macros (const ColInfoResponse_t &/*collectinfo*/, displayclass &disp, cgiargsclass &args, recptproto * /*collectproto*/, ostream &/*logout*/) { // define_internal_macros sets the following macros: // _quotedquery_ the part of the query string that was quoted for post-processing // The following macros are set later (in define_query_macros) as they can't be set until // the query has been done. // _freqmsg_ the term frequency string // _resultline_ the "x documents matched the query" string // _prevfirst_ these are used when setting up the links to previous/next // _prevlast_ pages of results (_thisfirst_ and _thislast_ are used to set // _nextfirst_ the 'results x-x for query: xxxx' string in the title bar) // _nextlast_ // _thisfirst_ // _thislast_ // get the quoted bits of the query string and set _quotedquery_ text_tarray phrases; get_phrases (args["q"], phrases); text_tarray::const_iterator phere = phrases.begin(); text_tarray::const_iterator pend = phrases.end(); bool first = true; text_t quotedquery; while (phere != pend) { if (!first) if ((phere +1) == pend) quotedquery += " and "; else quotedquery += ", "; quotedquery += "\"" + *phere + "\""; first = false; phere ++; } if (args.getintarg("s")) quotedquery += "_textstemon_"; disp.setmacro ("quotedquery", "query", quotedquery); // we'll also set num_phrases here so we don't have to parse the // querystring again later (we need to know this before outputting // results so we don't include results for documents not containing // all requested phrases). num_phrases = phrases.size(); } // sets the selection box macros _hselection_, _jselection_, and _nselection_. void queryaction::set_option_macro (const text_t ¯oname, text_t current_value, const FilterOption_t &option, displayclass &disp) { if (option.validValues.size() < 2) return; text_t macrovalue = "