--- loncom/interface/lonsearchcat.pm 2004/04/21 15:48:34 1.213
+++ loncom/interface/lonsearchcat.pm 2004/04/23 17:52:55 1.216
@@ -1,7 +1,7 @@
# The LearningOnline Network with CAPA
# Search Catalog
#
-# $Id: lonsearchcat.pm,v 1.213 2004/04/21 15:48:34 matthew Exp $
+# $Id: lonsearchcat.pm,v 1.216 2004/04/23 17:52:55 matthew Exp $
#
# Copyright Michigan State University Board of Trustees
#
@@ -736,18 +736,54 @@ ENDHEADER
&Apache::loncommon::domain_select('domains',
$ENV{'form.domains'},1).
''.$/;
- $scrout .= "\n
\n
\n";
- my %dates=&Apache::lonlocal::texthash
- ('creationdatestart' => 'Creation Date After',
- 'creationdateend' => 'Creation Date Before',
- 'lastrevisiondatestart' => 'Last Revision Date After',
- 'lastrevisiondateend' => 'Last Revision Date Before');
- foreach my $field (sort keys %dates) {
- $scrout.=''.
- ''.&titlefield($dates{$field}).' | '.
- &Apache::lonhtmlcommon::date_setter('advsearch',$field,0,'',1).
- ' |
'.$/;
- }
+ $scrout .= "
\n
";
+ #
+ # Creation/Modification date limits
+ $scrout .= "\n\n";
+ my $cafter =
+ &Apache::lonhtmlcommon::date_setter('advsearch', # formname
+ 'creationdate1', # fieldname
+ 0, # current value
+ '', # special
+ 1, # includeempty
+ '', # state
+ 1, # no_hh_mm_ss
+ );
+ my $cbefore =
+ &Apache::lonhtmlcommon::date_setter('advsearch', # formname
+ 'creationdate2', # fieldname
+ 0, # current value
+ '', # special
+ 1, # includeempty
+ '', # state
+ 1, # no_hh_mm_ss
+ );
+ $scrout .= &mt('Created between | '.
+ '[_1] |
'.
+ 'and | '.
+ '[_2] |
',$cafter,$cbefore);
+ my $lafter =
+ &Apache::lonhtmlcommon::date_setter('advsearch',
+ 'revisiondate1',
+ 0, # current value
+ '', # special
+ 1, # includeempty
+ '', # state
+ 1, # no_hh_mm_ss
+ );
+ my $lbefore =
+ &Apache::lonhtmlcommon::date_setter('advsearch',
+ 'revisiondate2',
+ 0, # current value
+ '', # special
+ 1, # includeempty
+ '', # state
+ 1, # no_hh_mm_ss
+ );
+ $scrout .= &mt('Last modified between | '.
+ '[_1] |
'.
+ 'and | '.
+ '[_2] |
',$lafter,$lbefore);
$scrout.="
\n";
$scrout.=<'.$/;
+ my $countselect = &Apache::lonmeta::selectbox('show',
+ $ENV{'form.show'},
+ undef,
+ (10,20,50,100,1000,10000));
+ $scrout .= (' 'x2).&mt('[_1] Records per Page',$countselect).
+ ''.$/;
return $scrout;
}
@@ -1044,38 +1081,45 @@ Parse advanced search form and return th
######################################################################
sub parse_advanced_search {
my ($r,$closebutton,$hidden_fields)=@_;
+ my @BasicFields = ('title','author','subject','keywords','url','version',
+ 'notes','abstract','extension','language','owner',
+# 'custommetadata','customshow',
+ 'modifyinguser','standards','mime');
+
my $fillflag=0;
my $pretty_search_string = "
\n";
# Clean up fields for safety
- for my $field ('title','author','subject','keywords','url','version',
- 'creationdatestart_month','creationdatestart_day',
+ for my $field (@BasicFields,
+ 'creationdatestart_month','creationdatestart_day',
'creationdatestart_year','creationdateend_month',
'creationdateend_day','creationdateend_year',
'lastrevisiondatestart_month','lastrevisiondatestart_day',
'lastrevisiondatestart_year','lastrevisiondateend_month',
- 'lastrevisiondateend_day','lastrevisiondateend_year',
- 'notes','abstract','extension','language','owner',
- 'custommetadata','customshow','category') {
- $ENV{"form.$field"}=~s/[^\w\/\s\(\)\=\-\"\']//g;
+ 'lastrevisiondateend_day','lastrevisiondateend_year') {
+ $ENV{'form.'.$field}=~s/[^\w\/\s\(\)\=\-\"\']//g;
}
foreach ('mode','form','element') {
# is this required? Hmmm.
- next unless (exists($ENV{"form.$_"}));
- $ENV{"form.$_"}=&Apache::lonnet::unescape($ENV{"form.$_"});
- $ENV{"form.$_"}=~s/[^\w\/\s\(\)\=\-\"\']//g;
+ next if (! exists($ENV{'form.'.$_}));
+ $ENV{'form.'.$_}=&Apache::lonnet::unescape($ENV{'form.'.$_});
+ $ENV{'form.'.$_}=~s/[^\w\/\s\(\)\=\-\"\']//g;
}
# Preprocess the category form element.
$ENV{'form.category'} = 'any' if (! defined($ENV{'form.category'}) ||
ref($ENV{'form.category'}));
#
# Check to see if enough information was filled in
- for my $field ('title','author','subject','keywords','url','version',
- 'notes','abstract','category','extension','language',
- 'owner','custommetadata') {
- if (&filled($ENV{"form.$field"})) {
+ for my $field (@BasicFields) {
+ if (&filled($ENV{'form.'.$field})) {
$fillflag++;
}
}
+ for my $field ('lowestgradelevel','highestgradelevel') {
+ if ( $ENV{'form.'.$field} =~ /^\d+$/ &&
+ $ENV{'form.'.$field} > 0) {
+ $fillflag++;
+ }
+ }
if (! $fillflag) {
&output_blank_field_error($r,$closebutton,
'phase=disp_adv',$hidden_fields);
@@ -1086,8 +1130,7 @@ sub parse_advanced_search {
my @queries;
my $font = '';
# Evaluate logical expression AND/OR/NOT phrase fields.
- foreach my $field ('title','author','subject','notes','abstract','url',
- 'keywords','version','owner','standards') {
+ foreach my $field (@BasicFields) {
if ($ENV{'form.'.$field}) {
my $searchphrase = $ENV{'form.'.$field};
$pretty_search_string .= $font."$field contains ".
@@ -1119,11 +1162,6 @@ sub parse_advanced_search {
$searchphrase = join(' OR ',@extensions);
}
}
- if (exists($ENV{'form.extension'}) && $ENV{'form.extension'} !~ /^\s*$/) {
- $searchphrase .= ' OR ' if (defined($searchphrase));
- my @extensions = split(/,/,$ENV{'form.extension'});
- $searchphrase .= join(' OR ',@extensions);
- }
if (defined($searchphrase)) {
push @queries,&build_SQL_query('mime',$searchphrase);
$pretty_search_string .=$font.'mime contains '.
@@ -1131,6 +1169,22 @@ sub parse_advanced_search {
}
#
# Evaluate option lists
+ if ($ENV{'form.lowestgradelevel'} &&
+ $ENV{'form.lowestgradelevel'} ne '0' &&
+ $ENV{'form.lowestgradelevel'} =~ /^\d+$/) {
+ push(@queries,
+ '(lowestgradelevel>='.$ENV{'form.lowestgradelevel'}.')');
+ $pretty_search_string.="lowestgradelevel>=".
+ $ENV{'form.lowestgradelevel'}."
\n";
+ }
+ if ($ENV{'form.highestgradelevel'} &&
+ $ENV{'form.highestgradelevel'} ne '0' &&
+ $ENV{'form.highestgradelevel'} =~ /^\d+$/) {
+ push(@queries,
+ '(highestgradelevel<='.$ENV{'form.highestgradelevel'}.')');
+ $pretty_search_string.="highestgradelevel<=".
+ $ENV{'form.highestgradelevel'}."
\n";
+ }
if ($ENV{'form.language'} and $ENV{'form.language'} ne 'any') {
push @queries,"(language like \"$ENV{'form.language'}\")";
$pretty_search_string.=$font."language= ".
@@ -1145,27 +1199,32 @@ sub parse_advanced_search {
}
#
# Evaluate date windows
- my $datequery=&build_date_queries(
- $ENV{'form.creationdatestart_month'},
- $ENV{'form.creationdatestart_day'},
- $ENV{'form.creationdatestart_year'},
- $ENV{'form.creationdateend_month'},
- $ENV{'form.creationdateend_day'},
- $ENV{'form.creationdateend_year'},
- $ENV{'form.lastrevisiondatestart_month'},
- $ENV{'form.lastrevisiondatestart_day'},
- $ENV{'form.lastrevisiondatestart_year'},
- $ENV{'form.lastrevisiondateend_month'},
- $ENV{'form.lastrevisiondateend_day'},
- $ENV{'form.lastrevisiondateend_year'},
- );
- # Test to see if date windows are legitimate
- if ($datequery=~/^Incorrect/) {
- &output_date_error($r,$datequery,$closebutton,$hidden_fields);
- return ;
- } elsif ($datequery) {
+ my $cafter =
+ &Apache::lonhtmlcommon::get_date_from_form('creationdate1');
+ my $cbefore =
+ &Apache::lonhtmlcommon::get_date_from_form('creationdate2');
+ if ($cafter > $cbefore) {
+ my $tmp = $cafter;
+ $cafter = $cbefore;
+ $cbefore = $tmp;
+ }
+ my $mafter =
+ &Apache::lonhtmlcommon::get_date_from_form('revisiondate1');
+ my $mbefore =
+ &Apache::lonhtmlcommon::get_date_from_form('revisiondate2');
+ if ($mafter > $mbefore) {
+ my $tmp = $mafter;
+ $mafter = $mbefore;
+ $mbefore = $tmp;
+ }
+ my ($datequery,$error,$prettydate)=&build_date_queries($cafter,$cbefore,
+ $mafter,$mbefore);
+ if (defined($error)) {
+ &output_date_error($r,$error,$closebutton,$hidden_fields);
+ } elsif (defined($datequery)) {
# Here is where you would set up pretty_search_string to output
# date query information.
+ $pretty_search_string .= '
'.$prettydate.'
';
push @queries,$datequery;
}
#
@@ -1199,8 +1258,7 @@ sub parse_advanced_search {
$pretty_search_string .= $pretty_domains_string."
\n";
#
if (@queries) {
- $query=join(" AND ",@queries);
- $query="select * from metadata where $query";
+ $query="select * from metadata where ".join(" AND ",@queries);
} elsif ($customquery) {
$query = '';
}
@@ -1458,51 +1516,73 @@ Also reports errors (check for /^Incorre
######################################################################
######################################################################
sub build_date_queries {
- my ($cmonth1,$cday1,$cyear1,$cmonth2,$cday2,$cyear2,
- $lmonth1,$lday1,$lyear1,$lmonth2,$lday2,$lyear2)=@_;
- my @queries;
- if ($cmonth1 or $cday1 or $cyear1 or $cmonth2 or $cday2 or $cyear2) {
- unless ($cmonth1 and $cday1 and $cyear1 and
- $cmonth2 and $cday2 and $cyear2) {
- return "Incorrect entry for the creation date. You must specify ".
- "a starting month, day, and year and an ending month, ".
- "day, and year.";
- }
- my $cnumeric1=sprintf("%d%2d%2d",$cyear1,$cmonth1,$cday1);
- $cnumeric1+=0;
- my $cnumeric2=sprintf("%d%2d%2d",$cyear2,$cmonth2,$cday2);
- $cnumeric2+=0;
- if ($cnumeric1>$cnumeric2) {
- return "Incorrect entry for the creation date. The starting ".
- "date must occur before the ending date.";
- }
- my $cquery="(creationdate BETWEEN '$cyear1-$cmonth1-$cday1' AND '".
- "$cyear2-$cmonth2-$cday2 23:59:59')";
- push @queries,$cquery;
- }
- if ($lmonth1 or $lday1 or $lyear1 or $lmonth2 or $lday2 or $lyear2) {
- unless ($lmonth1 and $lday1 and $lyear1 and
- $lmonth2 and $lday2 and $lyear2) {
- return "Incorrect entry for the last revision date. You must ".
- "specify a starting month, day, and year and an ending ".
- "month, day, and year.";
- }
- my $lnumeric1=sprintf("%d%2d%2d",$lyear1,$lmonth1,$lday1);
- $lnumeric1+=0;
- my $lnumeric2=sprintf("%d%2d%2d",$lyear2,$lmonth2,$lday2);
- $lnumeric2+=0;
- if ($lnumeric1>$lnumeric2) {
- return "Incorrect entry for the last revision date. The ".
- "starting date must occur before the ending date.";
- }
- my $lquery="(lastrevisiondate BETWEEN '$lyear1-$lmonth1-$lday1' AND '".
- "$lyear2-$lmonth2-$lday2 23:59:59')";
- push @queries,$lquery;
+ my ($cafter,$cbefore,$mafter,$mbefore) = @_;
+ my ($result,$error,$pretty_string);
+ #
+ # Verify the input
+ if (! defined($cafter) && ! defined($cbefore) &&
+ ! defined($mafter) && ! defined($mbefore)) {
+ # This is an okay situation, so return undef for the error
+ return (undef,undef,undef);
+ }
+ if ((defined($cafter) && ! defined($cbefore)) ||
+ (defined($cbefore) && ! defined($cafter))) {
+ # This is bad, so let them know
+ $error = &mt('Incorrect entry for the creation date. '.
+ 'You must specify both the beginning and ending dates.');
+ }
+ if (! defined($error) &&
+ ((defined($mafter) && ! defined($mbefore)) ||
+ (defined($mbefore) && ! defined($mafter)))) {
+ # This is also bad, so let them know
+ $error = &mt('Incorrect entry for the last revision date. '.
+ 'You must specify both the beginning and ending dates.');
}
- if (@queries) {
- return join(" AND ",@queries);
+ if (! defined($error)) {
+ #
+ # Build the queries
+ my @queries;
+ if (defined($cbefore) && defined($cafter)) {
+ my (undef,undef,undef,$caday,$camon,$cayear) = localtime($cafter);
+ my (undef,undef,undef,$cbday,$cbmon,$cbyear) = localtime($cbefore);
+ # Correct for year being relative to 1900
+ $cayear+=1900; $cbyear+=1900;
+ my $cquery=
+ '(creationdate BETWEEN '.
+ "'".$cayear.'-'.$camon.'-'.$caday."'".
+ ' AND '.
+ "'".$cbyear.'-'.$cbmon.'-'.$cbday." 23:59:59')";
+ $pretty_string .= '
' if (defined($pretty_string));
+ $pretty_string .=
+ &mt('created between [_1] and [_2]',
+ &Apache::lonlocal::locallocaltime($cafter),
+ &Apache::lonlocal::locallocaltime($cbefore+24*60*60-1));
+ push(@queries,$cquery);
+ $pretty_string =~ s/ 00:00:00//g;
+ }
+ if (defined($mbefore) && defined($mafter)) {
+ my (undef,undef,undef,$maday,$mamon,$mayear) = localtime($mafter);
+ my (undef,undef,undef,$mbday,$mbmon,$mbyear) = localtime($mbefore);
+ # Correct for year being relative to 1900
+ $mayear+=1900; $mbyear+=1900;
+ my $mquery=
+ '(lastrevisiondate BETWEEN '.
+ "'".$mayear.'-'.$mamon.'-'.$maday."'".
+ ' AND '.
+ "'".$mbyear.'-'.$mbmon.'-'.$mbday." 23:59:59')";
+ push(@queries,$mquery);
+ $pretty_string .= '
' if (defined($pretty_string));
+ $pretty_string .=
+ &mt('last revised between [_1] and [_2]',
+ &Apache::lonlocal::locallocaltime($mafter),
+ &Apache::lonlocal::locallocaltime($mbefore+24*60*60-1));
+ $pretty_string =~ s/ 00:00:00//g;
+ }
+ if (@queries) {
+ $result .= join(" AND ",@queries);
+ }
}
- return '';
+ return ($result,$error,$pretty_string);
}
######################################################################
@@ -1801,12 +1881,37 @@ sub update_status {
$r->rflush();
}
+{
+ my $max_time = 40; # seconds for the search to complete
+ my $start_time = 0;
+ my $last_time = 0;
+
+sub reset_timing {
+ $start_time = 0;
+ $last_time = 0;
+}
+
+sub time_left {
+ if ($start_time == 0) {
+ $start_time = time;
+ }
+ my $time_left = $max_time - (time - $start_time);
+ $time_left = 0 if ($time_left < 0);
+ return $time_left;
+}
+
sub update_seconds {
- my ($r,$text) = @_;
- $text =~ s/\'/\\\'/g;
- $r->print
- ("\n");
- $r->rflush();
+ my ($r) = @_;
+ my $time = &time_left();
+ if (($last_time-$time) > 0) {
+ $r->print("\n");
+ $r->rflush();
+ }
+ $last_time = $time;
+}
+
}
######################################################################
@@ -1855,11 +1960,6 @@ sub run_search {
my $bodytag=&Apache::loncommon::bodytag(undef,undef,undef,1);
my $connection = $r->connection;
#
- # Timing variables
- #
- my $starttime = time;
- my $max_time = 30; # seconds for the search to complete
- #
# Print run_search header
#
$r->print(< 2) {
$pretty_string = join '
',(@Lines[0..2],'....
');
}
- $r->print(&mt("Search").": ".$pretty_string);
+ $r->print(&mt("Search: [_1]",$pretty_string));
$r->rflush();
#
# Determine the servers we need to contact.
@@ -1891,6 +1991,8 @@ END
@Servers_to_contact = sort(keys(%Apache::lonnet::libserv));
}
my %Server_status;
+ #
+ # Check on the mysql table we will use to store results.
my $table =$ENV{'form.table'};
if (! defined($table) || $table eq '' || $table =~ /\D/ ) {
$r->print("Unable to determine table id to store search results in.".
@@ -1935,20 +2037,18 @@ END
END
$r->rflush();
- my $time_remaining = $max_time - (time - $starttime) ;
- $time_remaining = 0 if ($time_remaining <0);
- my $last_time = $time_remaining;
- &update_seconds($r,$time_remaining);
- &update_status($r,'contacting '.$Servers_to_contact[0]);
- while (($time_remaining > 0) &&
+ &reset_timing();
+ &update_seconds($r);
+ &update_status($r,&mt('contacting [_1]',$Servers_to_contact[0]));
+ while (&time_left() &&
((@Servers_to_contact) || keys(%Server_status))) {
- $time_remaining = $max_time - (time - $starttime) ;
- &update_seconds($r,$time_remaining);
- # Send out a search request if it needs to be done.
+ &update_seconds($r);
+ #
+ # Send out a search request
if (@Servers_to_contact) {
# Contact one server
my $server = shift(@Servers_to_contact);
- &update_status($r,&mt('contacting').' '.$server);
+ &update_status($r,&mt('contacting [_1]',$server));
my $reply=&Apache::lonnet::metadata_query($query,$customquery,
$customshow,[$server]);
($server) = keys(%$reply);
@@ -1960,7 +2060,7 @@ END
# left to contact.
if (scalar (keys(%Server_status))) {
&update_status($r,
- &mt('waiting on').' '.(join(' ',keys(%Server_status))));
+ &mt('waiting on [_1]',join(' ',keys(%Server_status))));
}
sleep(1);
}
@@ -1969,12 +2069,7 @@ END
# have results from yet, looking for results.
while (my ($server,$status) = each(%Server_status)) {
last if ($connection->aborted());
- $time_remaining = $max_time - (time - $starttime) ;
- $time_remaining = 0 if ($time_remaining < 0);
- if ($last_time - $time_remaining > 0) {
- $last_time = $time_remaining;
- &update_seconds($r,$time_remaining);
- }
+ &update_seconds($r);
if ($status eq 'con_lost') {
delete ($Server_status{$server});
next;
@@ -1982,12 +2077,12 @@ END
$status=~/^([\.\w]+)$/;
my $datafile=$r->dir_config('lonDaemons').'/tmp/'.$1;
if (-e $datafile && ! -e "$datafile.end") {
- &update_status($r,&mt('Receiving results from').' '.$server);
+ &update_status($r,&mt('Receiving results from [_1]',$server));
next;
}
last if ($connection->aborted());
if (-e "$datafile.end") {
- &update_status($r,&mt('Reading results from').' '.$server);
+ &update_status($r,&mt('Reading results from [_1]',$server));
if (-z "$datafile") {
delete($Server_status{$server});
next;
@@ -2002,30 +2097,30 @@ END
# Read in the whole file.
while (my $result = <$fh>) {
last if ($connection->aborted());
- # handle custom fields? Someday we will!
+ #
+ # Records are stored one per line
chomp($result);
- next unless $result;
+ next if (! $result);
+ #
# Parse the result.
my %Fields = &parse_raw_result($result,$server);
$Fields{'hostname'} = $server;
+ #
+ # Skip based on copyright
next if (! ©right_check(\%Fields));
+ #
# Store the result in the mysql database
my $result = &Apache::lonmysql::store_row($table,\%Fields);
if (! defined($result)) {
$r->print(&Apache::lonmysql::get_error());
}
- # $r->print(&Apache::lonmysql::get_debug());
+ #
$hitcountsum ++;
- $time_remaining = $max_time - (time - $starttime) ;
- $time_remaining = 0 if ($time_remaining < 0);
- if ($last_time - $time_remaining > 0) {
- &update_seconds($r,$time_remaining);
- $last_time = $time_remaining;
- }
+ &update_seconds($r);
if ($hitcountsum % 50 == 0) {
&update_count_status($r,$hitcountsum);
}
- } # End of foreach (@results)
+ }
$fh->close();
# $server is only deleted if the results file has been
# found and (successfully) opened. This may be a bad idea.
@@ -2035,21 +2130,16 @@ END
&update_count_status($r,$hitcountsum);
}
last if ($connection->aborted());
- # Finished looping through the servers
- $starttime = time if (@Servers_to_contact);
- $time_remaining = $max_time - (time - $starttime) ;
- if ($last_time - $time_remaining > 0) {
- $last_time = $time_remaining;
- &update_seconds($r,$time_remaining);
- }
+ &update_seconds($r);
}
- &update_status($r,&mt('Search Complete').$server);
- &update_seconds($r,0);
+ &update_status($r,&mt('Search Complete [_1]',$server));
+ &update_seconds($r);
#
- &Apache::lonmysql::disconnect_from_db();
+ &Apache::lonmysql::disconnect_from_db(); # This is unneccessary
#
# We have run out of time or run out of servers to talk to and
- # results to get.
+ # results to get, so let the client know the top frame needs to be
+ # loaded from /adm/searchcat
$r->print("