File Coverage

blib/lib/WE_Frontend/Indexer/Htdig.pm
Criterion Covered Total %
statement 6 154 3.9
branch 0 74 0.0
condition 0 17 0.0
subroutine 2 7 28.5
pod 1 4 25.0
total 9 256 3.5


line stmt bran cond sub pod time code
1             # -*- perl -*-
2              
3             #
4             # $Id: Htdig.pm,v 1.18 2006/12/01 10:12:56 cmuellermeta Exp $
5             # Author: Slaven Rezic
6             #
7             # Copyright (C) 2002 Slaven Rezic. All rights reserved.
8             # This package is free software; you can redistribute it and/or
9             # modify it under the same terms as Perl itself.
10             #
11             # Mail: slaven@rezic.de
12             # WWW: http://www.rezic.de/eserte/
13             #
14              
15             package WE_Frontend::Indexer::Htdig;
16              
17 1     1   1062 use strict;
  1         1  
  1         30  
18 1     1   4 use vars qw($VERSION);
  1         2  
  1         1870  
19             $VERSION = sprintf("%d.%02d", q$Revision: 1.18 $ =~ /(\d+)\.(\d+)/);
20              
21             ## XXX Maybe some day ...
22             # sub new {
23             # my $class = shift;
24             # my(%args) = @_;
25             # my $self = {};
26             # if ($args{-searchengine}) {
27             # WEsiteinfo::SearchEngine
28             # }
29             # }
30              
31             sub conf {
32 0     0 0   my($conf, $lang) = @_;
33 0           $conf =~ s/%\{lang\}/$lang/g;
34 0           $conf;
35             }
36              
37             sub conf_is_lang_dependent {
38 0     0 0   my($conf) = @_;
39 0 0         $conf =~ /%\{lang\}/ ? 1 : 0;
40             }
41              
42             sub search {
43 0     0 1   my(%args) = @_;
44 0   0       my $words = delete $args{-words} || die "No words specified";
45 0           my $conf = delete $args{-conf};
46 0           my $lang = delete $args{-lang};
47 0           my $query = delete $args{-query};
48 0           my $debug = delete $args{-debug};
49 0           my $https_hack = delete $args{-httpshack};
50 0           my $transform = delete $args{-transform};
51 0           my $method = delete $args{-method};
52              
53 0 0         if (keys %args) { warn "Unknown arguments: " . join(", ", %args) } # XXXdie?
  0            
54              
55 0           local %ENV = %ENV;
56 0           delete $ENV{REQUEST_METHOD}; # security barrier in htsearch
57             # Location of htdig in the standard FreeBSD port, after a normal
58             # unaltered install and a Debian 3.0 install. Sometimes $ENV{PATH} is
59             # empty, so supply additional reasonable defaults.
60 0           local $ENV{PATH} .= ":/usr/local/share/apache/cgi-bin:/opt/www/cgi-bin:/usr/lib/cgi-bin:/usr/bin:/bin";
61              
62 0 0         if ($debug) {
63 0           warn "Current path is $ENV{PATH}";
64             }
65              
66 0           require CGI;
67 0           my $q = CGI::new($query);
68 0           $q->param("words", $words);
69 0           $q->param("format", "perl");
70 0 0         $q->param("method", $method) if defined $method;
71              
72 0 0         my $conf_path = conf($conf, $lang) if defined $conf;
73 0 0         my @htsearch_cmd = ("htsearch",
74             (defined $conf ? ("-c", $conf_path) : ()),
75             $q->query_string);
76 0 0         open(HTSEARCH, "-|") or do {
77 0 0         if ($debug) {
78 0           warn "Execute: @htsearch_cmd";
79             }
80 0           exec @htsearch_cmd;
81 0           die "Can't execute htsearch command (@htsearch_cmd), PATH is $ENV{PATH}: $!";
82             };
83              
84             # overread header
85 0           while() {
86 0           chomp;
87 0 0         last if /^\r?$/;
88             }
89              
90             # slurp generated perl data dump
91 0           local $/ = undef;
92 0           my $perlcode = ;
93             #warn $perlcode;
94              
95 0           require Safe;
96 0           my $cpt = Safe->new;
97 0           my $obj = $cpt->reval($perlcode);
98              
99 0           my $nr = 0;
100 0           die "Error while evaluating perl code result from htsearch call:\n@htsearch_cmd.\n" .
101 0 0         "Code: " . join("\n", map { sprintf "%4d %s", ++$nr, $_ }
    0          
102             split /\n/, $perlcode) . "\n" .
103             "Error: $@\n" .
104             (defined $conf ? "Configuration file is $conf_path\n" : "Using standard configuration file\n")
105             if !$obj;
106              
107 0           while(my($key,$val) = each %$obj) {
108 0 0         if ($key =~ /(.*)_urlenc$/) {
    0          
109 0           my $real_key = $1;
110 0           $obj->{$real_key} = CGI::unescape($val);
111             } elsif ($key eq 'list') {
112 0           for my $obj (@$val) {
113 0           while(my($key,$val) = each %$obj) {
114 0 0         if ($key =~ /(.*)_urlenc$/) {
115 0           $obj->{$1} = CGI::unescape($val);
116             }
117             }
118             }
119             }
120             }
121              
122             my $parse_href = sub {
123 0     0     my $href = shift;
124 0           my($pageurl, $pagenumber);
125 0 0         if (my($url, $querystring) = $href =~ /^(.*?)\?(.*)$/) {
126 0           my $q = CGI->new($querystring);
127 0 0 0       if (defined $lang && !defined $q->param("lang")) {
128 0           $q->param("lang", $lang);
129             }
130 0 0         if (!defined $q->param("page")) {
131 0           warn "Can't get page parameter from $href";
132 0           $pagenumber = undef;
133             } else {
134 0           $pagenumber = $q->param("page");
135             }
136 0           my $new_href = "$url?" . $q->query_string;
137 0           $pageurl = $new_href;
138             } else {
139 0           warn "Can't parse URL $href";
140             }
141 0           ($pageurl, $pagenumber);
142 0           };
143              
144 0 0         if ($obj->{"pagelist"}) {
145 0           my @pageurllist;
146             my @pagenumberlist;
147 0           my @hrefs = $obj->{"pagelist"} =~ m{href="(.*?)"}g;
148 0           for my $href (@hrefs) {
149 0           my($pageurl, $pagenumber) = $parse_href->($href);
150 0 0         if (defined $pageurl) {
151 0           push @pageurllist, $pageurl;
152 0           push @pagenumberlist, $pagenumber;
153             }
154             }
155             # Add this page
156 0 0         if ($pagenumberlist[0] != 1) {
157 0           unshift @pageurllist, undef; # undef means: this page
158 0           unshift @pagenumberlist, 1;
159             } else {
160             SEARCH: {
161 0           for my $i (0 .. $#pagenumberlist) {
  0            
162 0 0         if ($i+1 != $pagenumberlist[$i]) {
163             # current page is in the middle of the list
164 0           splice @pagenumberlist, $i, 0, $i+1;
165 0           splice @pageurllist, $i, 0, undef;
166 0           last SEARCH;
167             }
168             }
169             # otherwise it's the last page
170 0           push @pageurllist, undef;
171 0           push @pagenumberlist, $#pagenumberlist+2;
172             }
173             }
174 0           $obj->{pageurllist} = \@pageurllist;
175 0           $obj->{pagenumberlist} = \@pagenumberlist;
176             }
177              
178 0           for my $dir (qw(prev next)) {
179 0 0         if ($obj->{$dir."page"}) {
180 0           my($href) = $obj->{$dir."page"} =~ m{href="(.*?)"};
181 0           my($pageurl, $pagenumber) = $parse_href->($href);
182 0 0         if (defined $pageurl) {
183 0           $obj->{$dir."pageurl"} = $pageurl;
184 0           $obj->{$dir."pagenumber"} = $pagenumber;
185             }
186             }
187             }
188              
189 0 0 0       if ($https_hack && $obj->{list}) {
190 0           for my $hit (@{ $obj->{list} }) {
  0            
191 0           $hit->{url} =~ s{^http://}{https://};
192             }
193             }
194              
195             # words is documented, but not available?
196 0 0         if (!exists $obj->{words}) {
197 0           $obj->{words} = $words;
198             }
199              
200 0 0         if ($transform) {
201 0           $transform->($obj);
202             }
203              
204 0           $obj;
205             }
206              
207             sub generate_conf {
208 0     0 0   my($c, %args) = @_;
209              
210 0           my $debug = $args{-debug};
211              
212 0           my $lang = $args{-lang};
213              
214 0   0       my $tpl = $args{-htdigconftemplate} || $c->searchengine->htdigconftemplate;
215 0   0       my $conf = $args{-htdigconf} || $c->searchengine->htdigconf;
216 0           my $lang_conf = conf($conf, $lang);
217 0 0         if (conf_is_lang_dependent($lang_conf)) {
218 0           die "-lang should be supplied for language independent conf specification $conf";
219             }
220              
221 0 0         if (!defined $tpl) {
222 0 0         if ($debug) {
223 0           warn "No template config defined, we're done with $lang_conf.\n";
224             }
225 0           return $lang_conf;
226             }
227              
228 0           my @dependents;
229 0 0         if ($args{-dependents}) {
230 0           @dependents = @{ $args{-dependents} };
  0            
231             } else {
232 0           (my $pkgfile = __PACKAGE__) =~ s{::}{/}g;
233             # XXX what if module is named WEsiteinfo_project.pm and WEprojectinfo_project.pm?
234 0           push @dependents,
235             $INC{"WEsiteinfo.pm"}, $INC{"WEprojectinfo.pm"},
236             $tpl,
237             $INC{"$pkgfile.pm"};
238             }
239              
240             # is the configuration file current?
241 0           my $conf_is_old = 0;
242 0 0         if (!-e $lang_conf) {
243 0           $conf_is_old = 1;
244             } else {
245 0           for my $dep (grep { defined $_ } @dependents) {
  0            
246 0 0 0       if (!-e $lang_conf || -M $dep < -M $lang_conf) {
247 0           $conf_is_old = 1;
248 0           last;
249             }
250             }
251             }
252              
253 0 0         if (!$conf_is_old) {
254 0           warn "htdig config file $lang_conf is current, we're done.\n";
255 0           return $lang_conf;
256             }
257              
258 0           my $long_lang;
259 0 0         if (defined $lang) {
260 0           $long_lang = {en => "english",
261             de => "german",
262             it => "italian",
263             fr => "french",
264             kr => "korean",
265             ru => "russian",
266             es => "spanish",
267             pt => "portugese",
268             hu => "hungarian",
269             }->{$lang};
270 0 0         warn "long_lang is not defined for $lang"
271             if !defined $long_lang;
272             }
273              
274             # regenerate conf file
275 0           require Template;
276             # XXX Don't duplicate this --- already found in we_search.cgi and
277             # we_redisys.cgi
278 0           my $t = Template->new
279             (ABSOLUTE => 1,
280             POST_CHOMP => 0,
281             INCLUDE_PATH => [$c->paths->site_templatebase,
282             $c->paths->we_templatebase,
283             ],
284             EVAL_PERL => 1,
285             PLUGIN_BASE => ["WE_" . $c->project->name . "::Plugin",
286             "WE_Frontend::Plugin"]
287             );
288 0 0         if ($debug) {
289 0           warn "Create config file $lang_conf from $tpl.\n";
290             }
291 0           my $conf_header = <
292             # DO NOT EDIT THIS FILE!
293             # Generated automatically by:
294 0           # module: @{[ __PACKAGE__ ]}
  0            
295 0           # user: @{[ (getpwuid($<))[0] ]}
296             # date: @{[ scalar localtime ]}
297             EOF
298 0           $t->process
299             ($tpl,
300             {c => $c,
301             config => $c, # for compatibility
302             lang => $lang,
303             longlang => $long_lang,
304             # strip dash from args keys
305 0 0         args => [map { (substr($_, 1) => $args{$_}) } keys(%args)],
306             conf_header => $conf_header,
307             }, $lang_conf)
308             or die $t->error;
309              
310 0           return $lang_conf;
311             }
312              
313             1;
314              
315             __END__