7 |
Catalyst::Model |
Catalyst::Model |
8 |
/; |
/; |
9 |
use WebPAC::Store 0.08; |
use WebPAC::Store 0.08; |
10 |
use WebPAC::Search::Estraier 0.05; |
use Search::Estraier 0.04; |
11 |
use File::Slurp; |
use File::Slurp; |
12 |
use Time::HiRes qw/time/; |
use Time::HiRes qw/time/; |
13 |
use Encode qw/encode decode from_to/; |
use Encode qw/encode decode from_to/; |
74 |
$est_cfg->{database} = $defaultnode; |
$est_cfg->{database} = $defaultnode; |
75 |
} |
} |
76 |
|
|
77 |
$self->{est} = new WebPAC::Search::Estraier( %{ $est_cfg } ); |
my $url = $est_cfg->{masterurl} . '/node/' . $est_cfg->{database}; |
78 |
|
|
79 |
|
$log->info("opening Hyper Estraier index $url as $est_cfg->{'user'}"); |
80 |
|
|
81 |
|
$self->{est_node} = Search::Estraier::Node->new( |
82 |
|
url => $url, |
83 |
|
user => $est_cfg->{user}, |
84 |
|
passwd => $est_cfg->{passwd}, |
85 |
|
); |
86 |
|
|
87 |
|
$log->fatal("can't create Search::Estraier::Node $url") unless ($self->{est_node}); |
88 |
|
|
89 |
# save config parametars in object |
# save config parametars in object |
90 |
foreach my $f (qw/db_path template_path hits_on_page webpac_encoding defaultdepth/) { |
foreach my $f (qw/db_path template_path hits_on_page webpac_encoding defaultdepth/) { |
111 |
"'" |
"'" |
112 |
); |
); |
113 |
|
|
114 |
$self->{databases} = $c->config->{databases} || $log->error("can't find databases in config"); |
$self->{databases} = $c->config->{databases} || $log->fatal("can't find databases in config"); |
115 |
|
|
116 |
# create Template toolkit instance |
# create Template toolkit instance |
117 |
$self->{'tt'} = Template->new( |
$self->{'tt'} = Template->new( |
195 |
$log->warn("using default search depth $default"); |
$log->warn("using default search depth $default"); |
196 |
} |
} |
197 |
|
|
198 |
my @results = $self->{est}->search( %{ $args } ); |
$log->debug("searching for maximum $args->{max} results using depth $args->{depth}"); |
199 |
|
|
200 |
|
# |
201 |
|
# construct condition for Hyper Estraier |
202 |
|
# |
203 |
|
my $cond = Search::Estraier::Condition->new(); |
204 |
|
if ( ref($args->{add_attr}) eq 'ARRAY' ) { |
205 |
|
$log->debug("adding search attributes: " . join(", ", @{ $args->{add_attr} }) ); |
206 |
|
map { |
207 |
|
$cond->add_attr( _convert( $_ ) ); |
208 |
|
$log->debug(" + $_"); |
209 |
|
} @{ $args->{add_attr} }; |
210 |
|
}; |
211 |
|
|
212 |
|
$cond->set_phrase( $query ) if ($query); |
213 |
|
$cond->set_options( $args->{options} ) if ($args->{options}); |
214 |
|
$cond->set_order( $args->{order} ) if ($args->{order}); |
215 |
|
|
216 |
|
my $max = $args->{max} || 7; |
217 |
|
my $page = $args->{page} || 1; |
218 |
|
if ($page < 1) { |
219 |
|
$log->warn("page number $page < 1"); |
220 |
|
$page = 1; |
221 |
|
} |
222 |
|
|
223 |
$times->{est} += time() - $t; |
$times->{est} += time() - $t; |
224 |
|
|
225 |
my $hits = $#results + 1; |
$cond->set_max( $page * $max ); |
226 |
|
|
227 |
$log->debug( sprintf("search took %.6fs and returned $hits hits.", $times->{est}) ); |
my $result = $self->{est_node}->search($cond, ( $args->{depth} || 0 )); |
228 |
|
my $hits = $result->doc_num; |
229 |
|
|
230 |
# just return results? |
$log->debug( sprintf("search took %.6fs and returned $hits hits.", $times->{est}) ); |
|
return @results unless ($args->{'template'}); |
|
231 |
|
|
232 |
# |
# |
233 |
# construct HTML results |
# fetch results |
234 |
# |
# |
235 |
|
|
236 |
my @html_results; |
my @results; |
237 |
|
|
238 |
for my $i ( 0 .. $#results ) { |
for my $i ( (($page - 1) * $max) .. ( $hits - 1 ) ) { |
239 |
|
|
240 |
my ($database, $prefix, $id); |
$t = time(); |
241 |
if ( $results[$i]->{'@uri'} =~ m!/([^/]+)/([^/]+)/(\d+)$!) { |
|
242 |
($database, $prefix,$id) = ($1,$2,$3); |
#$log->debug("get_doc($i)"); |
243 |
} else { |
my $doc = $result->get_doc( $i ); |
244 |
$log->warn("can't decode database/prefix/id from " . $results[$i]->{'@uri'}); |
if (! $doc) { |
245 |
|
$log->warn("can't find result $i"); |
246 |
next; |
next; |
247 |
} |
} |
248 |
|
|
249 |
#$log->debug("load_ds( id => $id, prefix => '$prefix' )"); |
my $hash; |
|
|
|
|
$t = time(); |
|
250 |
|
|
251 |
my $ds = $self->{db}->load_ds( database => $database, prefix => $prefix, id => $id ); |
foreach my $attr (@{ $args->{get_attr} }) { |
252 |
if (! $ds) { |
my $val = $doc->attr( $attr ); |
253 |
$log->error("can't load_ds( ${database}/${prefix}/${id} )"); |
#$log->debug("attr $attr = ", $val || 'undef'); |
254 |
next; |
$hash->{$attr} = $val if (defined($val)); |
255 |
} |
} |
256 |
|
|
257 |
$times->{db} += time() - $t; |
$times->{hash} += time() - $t; |
258 |
|
|
259 |
#$log->debug( "ds = " . Dumper( \@html_results ) ); |
next unless ($hash); |
260 |
|
|
261 |
$t = time(); |
if (! $args->{'template'}) { |
262 |
|
push @results, $hash; |
263 |
|
} else { |
264 |
|
my ($database, $prefix, $id); |
265 |
|
|
266 |
my $html = $self->apply( |
if ( $hash->{'@uri'} =~ m!/([^/]+)/([^/]+)/(\d+)$!) { |
267 |
template => $template_filename, |
($database, $prefix,$id) = ($1,$2,$3); |
268 |
data => $ds, |
} else { |
269 |
record_uri => "${database}/${prefix}/${id}", |
$log->warn("can't decode database/prefix/id from " . $hash->{'@uri'}); |
270 |
config => $self->{databases}->{$database}, |
next; |
271 |
); |
} |
272 |
|
|
273 |
$times->{out} += time() - $t; |
#$log->debug("load_ds( id => $id, prefix => '$prefix' )"); |
274 |
|
|
275 |
$t = time(); |
$t = time(); |
276 |
|
|
277 |
|
my $ds = $self->{db}->load_ds( database => $database, prefix => $prefix, id => $id ); |
278 |
|
if (! $ds) { |
279 |
|
$log->error("can't load_ds( ${database}/${prefix}/${id} )"); |
280 |
|
next; |
281 |
|
} |
282 |
|
|
283 |
|
$times->{db} += time() - $t; |
284 |
|
|
285 |
$html = decode($self->{webpac_encoding}, $html); |
#$log->debug( "ds = " . Dumper( \@html_results ) ); |
286 |
|
|
287 |
push @html_results, $html; |
$t = time(); |
288 |
|
|
289 |
|
my $html = $self->apply( |
290 |
|
template => $template_filename, |
291 |
|
data => $ds, |
292 |
|
record_uri => "${database}/${prefix}/${id}", |
293 |
|
config => $self->{databases}->{$database}, |
294 |
|
); |
295 |
|
|
296 |
|
$times->{apply} += time() - $t; |
297 |
|
|
298 |
|
$t = time(); |
299 |
|
|
300 |
|
$html = decode($self->{webpac_encoding}, $html); |
301 |
|
|
302 |
|
$times->{decode} += time() - $t; |
303 |
|
|
304 |
|
push @results, $html; |
305 |
|
} |
306 |
|
|
307 |
} |
} |
308 |
|
|
309 |
#$log->debug( '@html_results = ' . Dumper( \@html_results ) ); |
$log->debug( '@results = ' . Dumper( \@results ) ); |
310 |
|
|
311 |
$log->debug( sprintf( |
$log->debug( sprintf( |
312 |
"duration breakdown: store %.6fs, apply %.6fs, total: %.6fs", |
"duration breakdown: estraier %.6fs, hash %.6fs, store %.6fs, apply %.6fs, decode %.06f, total: %.6fs", |
313 |
$times->{db}, $times->{out}, time() - $search_start_t, |
$times->{est}, $times->{hash}, $times->{db}, $times->{apply}, $times->{decode}, time() - $search_start_t, |
314 |
) ); |
) ); |
315 |
|
|
316 |
return \@html_results; |
return \@results; |
317 |
} |
} |
318 |
|
|
319 |
=head2 record |
=head2 record |
446 |
my $log = $self->{log} || die "no log?"; |
my $log = $self->{log} || die "no log?"; |
447 |
|
|
448 |
foreach my $a (qw/template data/) { |
foreach my $a (qw/template data/) { |
449 |
$log->logconfess("need $a") unless ($args->{$a}); |
$log->fatal("need $a") unless ($args->{$a}); |
450 |
} |
} |
451 |
|
|
452 |
=head3 tt_filter_type |
=head3 tt_filter_type |