[ This patch fixes a small problem in the one posted about an hour earlier. ]
According to me...
> Really, though, this had been nagging at me for a while, so I finally
> decided to tackle it. I sorted through the old messages, and the patch
> archive. Joe had archived one of Mike's early attempts, from April 1,
> 1999, but didn't have the more recent April 6, 1999 patch. I grabbed
> that one, which I had fortunately saved, and fixed the header that
> BeroList had mangled so I could extract it. It was a patch for 3.1.1,
> but it applied to 3.1.5.
>
> Mike had gotten something functional working, and had planned for a lot
> of user input contingencies, but never seemed to get the changes into
> createURL and setVariables to pass on the parameters. In subsequent
> discussions he got bogged down in how to set up select lists for input
> parameters, and in the end he never posted a patch for propagating the
> start and end date parameters to subsequent search forms. Setting up
> select lists is easy, now, with the build_select_lists attribute, so I
> just added code to propagate the simple numeric parameters.
>
> I also added a number of fixes, some of which had been discussed prior
> to Mike's patch, but never implemented, and added a bit of documentation.
> The fixes are: using server's local time zone, initialising the structures
> fully, handling 2 digit years, setting the end time to the last second of
> the given day, and correctly handling Feb. 29. The code now depends on a
> working mktime() function in your C library. If you don't have it, C code
> for it exists in htlib/mktime.c, but this isn't compiled by the Makefile.
>
> The patch can be applied in the main htdig-3.1.5 source directory using
> "patch -p0 < this-file". I don't have a sample search form, but that
> should be easy to figure out. I'll try to adapt this for 3.2.0b3 once
> I can get the latest snapshot and build it. Be aware that in 3.1.x,
> the date range selection will trigger the same slowdown as sorting by
> date or a non-zero backlink_factor or date_factor, when there are lots
> of initial matches to process, as explained in FAQ 5.10.
>
> I hope many people find this useful. My thanks to Mike Grommet for
> his early work on this, and to all who prodded me into updating and
> finishing it.
OK, I said I'd do it, so here it is. This patch can be applied in the
main htdig-3.2.0b3-021501 source directory using "patch -p0 < this-file".
It includes doc patches, so maybe it's not too late for the 3.2.0b3
release (Geoff's call).
Thu Feb 22 11:56:56 2001 Gilles Detillieux <[EMAIL PROTECTED]>
* htsearch/htsearch.cc (main), htsearch/Display.cc (setVariables,
createURL, buildMatchList), htdoc/hts_form.html,
htdoc/hts_templates.html: Add Mike Grommet's date range search
feature.
--- htdoc/hts_form.html.nodrange Thu Feb 15 11:11:20 2001
+++ htdoc/hts_form.html Thu Feb 22 09:00:41 2001
@@ -147,6 +147,19 @@
make this item a drop down menu so the user can select the
type of sort at search time.
</dd>
+ <dt>
+ <strong>startyear</strong>, <strong>startmonth</strong>,
+<strong>startday</strong>,
+ <strong>endyear</strong>, <strong>endmonth</strong>,
+<strong>endday</strong>
+ </dt>
+ <dd>
+ These values specify the allowed range of document
+ modification dates allowed in the search results.
+ They can be used to restrict the search
+ to particular "ages" of documents, new or old.<br>
+ The default is the full range of documents in the database.
+ These values can also be specified by configuration attributes
+ of the same names in the configuration file.
+ </dd>
</dl>
<hr size="4" noshade>
--- htdoc/hts_templates.html.nodrange Thu Feb 15 11:11:21 2001
+++ htdoc/hts_templates.html Thu Feb 22 08:58:50 2001
@@ -381,6 +381,14 @@
the right.
</dd>
<dt>
+ <strong>STARTYEAR</strong>, <strong>STARTMONTH</strong>,
+<strong>STARTDAY</strong>,
+ <strong>ENDYEAR</strong>, <strong>ENDMONTH</strong>,
+<strong>ENDDAY</strong>
+ </dt>
+ <dd>
+ The currently specified date range for restricting search
+ results.
+ </dd>
+ <dt>
<strong>SYNTAXERROR</strong>
</dt>
<dd>
--- htsearch/htsearch.cc.nodrange Thu Oct 19 22:40:59 2000
+++ htsearch/htsearch.cc Thu Feb 22 08:55:18 2001
@@ -223,6 +223,27 @@ for (int cInd=0; errorMsg == NULL && cIn
if (input.exists("sort"))
config.Add("sort", input["sort"]);
+ // Changes added 3-31-99, by Mike Grommet
+ // Check form entries for starting date, and ending date
+ // Each date consists of a month, day, and year
+
+ if (input.exists("startmonth"))
+ config.Add("startmonth", input["startmonth"]);
+ if (input.exists("startday"))
+ config.Add("startday", input["startday"]);
+ if (input.exists("startyear"))
+ config.Add("startyear", input["startyear"]);
+
+ if (input.exists("endmonth"))
+ config.Add("endmonth", input["endmonth"]);
+ if (input.exists("endday"))
+ config.Add("endday", input["endday"]);
+ if (input.exists("endyear"))
+ config.Add("endyear", input["endyear"]);
+
+ // END OF CHANGES BY MIKE GROMMET
+
+
minimum_word_length = config.Value("minimum_word_length", minimum_word_length);
StringList form_vars(config["allow_in_form"], " \t\r\n");
--- htsearch/Display.cc.nodrange Mon Jan 15 17:49:38 2001
+++ htsearch/Display.cc Thu Feb 22 09:22:26 2001
@@ -445,6 +445,12 @@ Display::setVariables(int pageNumber, Li
} else {
vars.Add("CGI", new String(getenv("SCRIPT_NAME")));
}
+ vars.Add("STARTYEAR", new String(config["startyear"]));
+ vars.Add("STARTMONTH", new String(config["startmonth"]));
+ vars.Add("STARTDAY", new String(config["startday"]));
+ vars.Add("ENDYEAR", new String(config["endyear"]));
+ vars.Add("ENDMONTH", new String(config["endmonth"]));
+ vars.Add("ENDDAY", new String(config["endday"]));
String *str;
char *format = input->get("format");
@@ -778,6 +784,18 @@ Display::createURL(String &url, int page
url << "keywords=" << encodeInput("keywords") << ';';
if (input->exists("words"))
url << "words=" << encodeInput("words") << ';';
+ if (input->exists("startyear"))
+ url << "startyear=" << encodeInput("startyear") << ';';
+ if (input->exists("startmonth"))
+ url << "startmonth=" << encodeInput("startmonth") << ';';
+ if (input->exists("startday"))
+ url << "startday=" << encodeInput("startday") << ';';
+ if (input->exists("endyear"))
+ url << "endyear=" << encodeInput("endyear") << ';';
+ if (input->exists("endmonth"))
+ url << "endmonth=" << encodeInput("endmonth") << ';';
+ if (input->exists("endday"))
+ url << "endday=" << encodeInput("endday") << ';';
StringList form_vars(config["allow_in_form"], " \t\r\n");
for (i= 0; i < form_vars.Count(); i++)
{
@@ -1136,6 +1154,180 @@ Display::buildMatchList()
double date_score = 0;
double base_score = 0;
+
+ // Additions made here by Mike Grommet ...
+
+ tm startdate; // structure to hold the startdate specified by the user
+ tm enddate; // structure to hold the enddate specified by the user
+
+ time_t eternity = ~(1<<(sizeof(time_t)*8-1)); // will be the largest value
+holdable by a time_t
+ tm *endoftime; // the time_t eternity will be converted into a tm, held by
+this variable
+
+ time_t timet_startdate;
+ time_t timet_enddate;
+ int monthdays[] = {31,28,31,30,31,30,31,31,30,31,30,31};
+
+ // boolean to test to see if we need to build date information or not
+ int dategiven = ((config.Value("startmonth")) ||
+ (config.Value("startday")) ||
+ (config.Value("startyear")) ||
+ (config.Value("endmonth")) ||
+ (config.Value("endday")) ||
+ (config.Value("endyear")));
+
+ // find the end of time
+ endoftime = gmtime(&eternity);
+
+ if(dategiven) // user specified some sort of date information
+ {
+ time_t now = time((time_t *)0); // fill in all fields for mktime
+ tm *lt = localtime(&now); // - Gilles's fix
+ startdate = *lt;
+ enddate = *lt;
+
+ // set up the startdate structure
+ // see man mktime for details on the tm structure
+ startdate.tm_sec = 0;
+ startdate.tm_min = 0;
+ startdate.tm_hour = 0;
+ startdate.tm_yday = 0;
+ startdate.tm_wday = 0;
+
+ // The concept here is that if a user did not specify a part of a date,
+ // then we will make assumtions...
+ // For instance, suppose the user specified Feb, 1999 as the start
+ // range, we take steps to make sure that the search range date starts
+ // at Feb 1, 1999,
+ // along these same lines: (these are in MM-DD-YYYY format)
+ // Startdates: Date Becomes
+ // 01-01 01-01-1970
+ // 01-1970 01-01-1970
+ // 04-1970 04-01-1970
+ // 1970 01-01-1970
+ // These things seem to work fine for start dates, as all months have
+ // the same first day however the ending date can't work this way.
+
+ if(config.Value("startmonth")) // form input specified a start month
+ {
+ startdate.tm_mon = config.Value("startmonth") - 1;
+ // tm months are zero based. They are passed in as 1 based
+ }
+ else startdate.tm_mon = 0; // otherwise, no start month, default to 0
+
+ if(config.Value("startday")) // form input specified a start day
+ {
+ startdate.tm_mday = config.Value("startday");
+ // tm days are 1 based, they are passed in as 1 based
+ }
+ else startdate.tm_mday = 1; // otherwise, no start day, default to 1
+
+ // year is handled a little differently... the tm_year structure
+ // wants the tm_year in a format of year - 1900.
+ // since we are going to convert these dates to a time_t,
+ // a time_t value of zero, the earliest possible date
+ // occurs Jan 1, 1970. If we allow dates < 1970, then we
+ // could get negative time_t values right???
+ // (barring minor timezone offsets west of GMT, where Epoch is 12-31-69)
+
+ if(config.Value("startyear")) // form input specified a start year
+ {
+ startdate.tm_year = config.Value("startyear") - 1900;
+ if (startdate.tm_year < 69-1900) // correct for 2-digit years 00-68
+ startdate.tm_year += 2000; // - Gilles's fix
+ if (startdate.tm_year < 0) // correct for 2-digit years 69-99
+ startdate.tm_year += 1900;
+ }
+ else startdate.tm_year = 1970-1900;
+ // otherwise, no start day, specify start at 1970
+
+ // set up the enddate structure
+ enddate.tm_sec = 59; // allow up to last second of end day
+ enddate.tm_min = 59; // - Gilles's fix
+ enddate.tm_hour = 23;
+ enddate.tm_yday = 0;
+ enddate.tm_wday = 0;
+
+ if(config.Value("endmonth")) // form input specified an end month
+ {
+ enddate.tm_mon = config.Value("endmonth") - 1;
+ // tm months are zero based. They are passed in as 1 based
+ }
+ else enddate.tm_mon = 11; // otherwise, no end month, default to 11
+
+ if(config.Value("endyear")) // form input specified a end year
+ {
+ enddate.tm_year = config.Value("endyear") - 1900;
+ if (enddate.tm_year < 69-1900) // correct for 2-digit years 00-68
+ enddate.tm_year += 2000; // - Gilles's fix
+ if (enddate.tm_year < 0) // correct for 2-digit years 69-99
+ enddate.tm_year += 1900;
+ }
+ else enddate.tm_year = endoftime->tm_year;
+ // otherwise, no end year, specify end at the end of time allowable
+
+ // Months have different number of days, and this makes things more
+ // complicated than the startdate range.
+ // Following the example above, here is what we want to happen:
+ // Enddates: Date Becomes
+ // 04-31 04-31-endoftime->tm_year
+ // 05-1999 05-31-1999, may has 31 days... we want to
+search until the end of may so...
+ // 1999 12-31-1999, search until the end of the year
+
+ if(config.Value("endday")) // form input specified an end day
+ {
+ enddate.tm_mday = config.Value("endday");
+ // tm days are 1 based, they are passed in as 1 based
+ }
+ else
+ {
+ // otherwise, no end day, default to the end of the month
+ enddate.tm_mday = monthdays[enddate.tm_mon];
+ if (enddate.tm_mon == 1) // February, so check for leap year
+ if (((enddate.tm_year+1900) % 4 == 0 &&
+ (enddate.tm_year+1900) % 100 != 0) ||
+ (enddate.tm_year+1900) % 400 == 0)
+ enddate.tm_mday += 1; // Feb. 29 - Gilles's fix
+ }
+
+ // Convert the tm values into time_t values.
+ // Web servers specify modification times in GMT, but htsearch
+ // displays these modification times in the server's local time zone.
+ // For consistency, we would prefer to select based on this same
+ // local time zone. - Gilles's fix
+
+ timet_startdate = mktime(&startdate);
+ timet_enddate = mktime(&enddate);
+
+ // I'm not quite sure what behavior I want to happen if
+ // someone reverses the start and end dates, and one of them is invalid.
+ // for now, if there is a completely invalid date on the start or end
+ // date, I will force the start date to time_t 0, and the end date to
+ // the maximum that can be handled by a time_t.
+
+ if(timet_startdate < 0)
+ timet_startdate = 0;
+ if(timet_enddate < 0)
+ timet_enddate = eternity;
+
+ // what if the user did something really goofy like choose an end date
+ // that's before the start date
+
+ if(timet_enddate < timet_startdate) // if so, then swap them so they are in
+order
+ {
+ time_t timet_temp = timet_enddate;
+ timet_enddate = timet_startdate;
+ timet_startdate = timet_temp;
+ }
+ }
+ else // no date was specifed, so plug in some defaults
+ {
+ timet_startdate = 0;
+ timet_enddate = eternity;
+ }
+
+ // ... MG
+
+
URLSeedScore adjustments(config);
// If we knew where to pass it, this would be a good place to pass
@@ -1181,6 +1373,14 @@ Display::buildMatchList()
continue;
}
+ // Code added by Mike Grommet for date search ranges
+ // check for valid date range. toss it out if it isn't relevant.
+ if ((timet_startdate > 0 || enddate.tm_year < endoftime->tm_year) &&
+ (thisRef->DocTime() < timet_startdate || thisRef->DocTime() >
+timet_enddate))
+ {
+ delete thisRef;
+ continue;
+ }
thisMatch = ResultMatch::create();
thisMatch->setID(id);
--
Gilles R. Detillieux E-mail: <[EMAIL PROTECTED]>
Spinal Cord Research Centre WWW: http://www.scrc.umanitoba.ca/~grdetil
Dept. Physiology, U. of Manitoba Phone: (204)789-3766
Winnipeg, MB R3E 3J7 (Canada) Fax: (204)789-3930
_______________________________________________
htdig-general mailing list <[EMAIL PROTECTED]>
To unsubscribe, send a message to <[EMAIL PROTECTED]> with a
subject of unsubscribe
FAQ: http://htdig.sourceforge.net/FAQ.html