]> sipb.mit.edu Git - ikiwiki.git/blob - IkiWiki/Plugin/search.pm
* Rebuilding on upgrade to this version is recommended.
[ikiwiki.git] / IkiWiki / Plugin / search.pm
1 #!/usr/bin/perl
2 # hyperestraier search engine plugin
3 package IkiWiki::Plugin::search;
4
5 use warnings;
6 use strict;
7 use IkiWiki;
8
9 sub import { #{{{
10         IkiWiki::hook(type => "checkconfig", id => "hyperestraier",
11                 call => \&checkconfig);
12         IkiWiki::hook(type => "pagetemplate", id => "hyperestraier",
13                 call => \&pagetemplate);
14         IkiWiki::hook(type => "delete", id => "hyperestraier",
15                 call => \&delete);
16         IkiWiki::hook(type => "change", id => "hyperestraier",
17                 call => \&change);
18         IkiWiki::hook(type => "cgi", id => "hyperestraier",
19                 call => \&cgi);
20 } # }}}
21
22 sub checkconfig () { #{{{
23         foreach my $required (qw(url cgiurl)) {
24                 if (! length $IkiWiki::config{$required}) {
25                         IkiWiki::error("Must specify $required when using the search plugin\n");
26                 }
27         }
28 } #}}}
29
30 sub pagetemplate ($$) { #{{{
31         my $page=shift;
32         my $template=shift;
33
34         # Add search box to page header.
35         $template->param(searchform => qq{
36 <form method="get" action="$IkiWiki::config{cgiurl}" id="searchform">
37 <div>
38 <input type="text" name="phrase" value="" size="16" />
39 <input type="hidden" name="enc" value="UTF-8" />
40 <input type="hidden" name="do" value="hyperestraier" />
41 </div>
42 </form>
43 });
44 } #}}}
45
46 sub delete (@) { #{{{
47         IkiWiki::debug("cleaning hyperestraier search index");
48         IkiWiki::estcmd("purge -cl");
49         IkiWiki::estcfg();
50 } #}}}
51
52 sub change (@) { #{{{
53         IkiWiki::debug("updating hyperestraier search index");
54         IkiWiki::estcmd("gather -cm -bc -cl -sd",
55                 map {
56                         $IkiWiki::config{destdir}."/".$IkiWiki::renderedfiles{IkiWiki::pagename($_)}
57                 } @_
58         );
59         IkiWiki::estcfg();
60 } #}}}
61
62 sub cgi ($) { #{{{
63         my $cgi=shift;
64
65         if (defined $cgi->param('phrase')) {
66                 # only works for GET requests
67                 chdir("$IkiWiki::config{wikistatedir}/hyperestraier") || IkiWiki::error("chdir: $!");
68                 exec("./".IkiWiki::basename($IkiWiki::config{cgiurl})) || IkiWiki::error("estseek.cgi failed");
69         }
70 } #}}}
71
72 # Easier to keep these in the IkiWiki namespace.
73 package IkiWiki;
74
75 my $configured=0;
76 sub estcfg () { #{{{
77         return if $configured;
78         $configured=1;
79         
80         my $estdir="$config{wikistatedir}/hyperestraier";
81         my $cgi=basename($config{cgiurl});
82         $cgi=~s/\..*$//;
83         open(TEMPLATE, ">$estdir/$cgi.tmpl") ||
84                 error("write $estdir/$cgi.tmpl: $!");
85         print TEMPLATE misctemplate("search", 
86                 "<!--ESTFORM-->\n\n<!--ESTRESULT-->\n\n<!--ESTINFO-->\n\n");
87         close TEMPLATE;
88         open(TEMPLATE, ">$estdir/$cgi.conf") ||
89                 error("write $estdir/$cgi.conf: $!");
90         my $template=HTML::Template->new(
91                 filename => "$config{templatedir}/estseek.conf"
92         );
93         eval q{use Cwd 'abs_path'};
94         $template->param(
95                 index => $estdir,
96                 tmplfile => "$estdir/$cgi.tmpl",
97                 destdir => abs_path($config{destdir}),
98                 url => $config{url},
99         );
100         print TEMPLATE $template->output;
101         close TEMPLATE;
102         $cgi="$estdir/".basename($config{cgiurl});
103         unlink($cgi);
104         symlink("/usr/lib/estraier/estseek.cgi", $cgi) ||
105                 error("symlink $cgi: $!");
106 } # }}}
107
108 sub estcmd ($;@) { #{{{
109         my @params=split(' ', shift);
110         push @params, "-cl", "$config{wikistatedir}/hyperestraier";
111         if (@_) {
112                 push @params, "-";
113         }
114         
115         my $pid=open(CHILD, "|-");
116         if ($pid) {
117                 # parent
118                 foreach (@_) {
119                         print CHILD "$_\n";
120                 }
121                 close(CHILD) || error("estcmd @params exited nonzero: $?");
122         }
123         else {
124                 # child
125                 open(STDOUT, "/dev/null"); # shut it up (closing won't work)
126                 exec("estcmd", @params) || error("can't run estcmd");
127         }
128 } #}}}
129
130 1