* Don't sent pings if the wiki is being rebuilt.
[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=template("estseek.conf");
91         eval q{use Cwd 'abs_path'};
92         $template->param(
93                 index => $estdir,
94                 tmplfile => "$estdir/$cgi.tmpl",
95                 destdir => abs_path($config{destdir}),
96                 url => $config{url},
97         );
98         print TEMPLATE $template->output;
99         close TEMPLATE;
100         $cgi="$estdir/".basename($config{cgiurl});
101         unlink($cgi);
102         symlink("/usr/lib/estraier/estseek.cgi", $cgi) ||
103                 error("symlink $cgi: $!");
104 } # }}}
105
106 sub estcmd ($;@) { #{{{
107         my @params=split(' ', shift);
108         push @params, "-cl", "$config{wikistatedir}/hyperestraier";
109         if (@_) {
110                 push @params, "-";
111         }
112         
113         my $pid=open(CHILD, "|-");
114         if ($pid) {
115                 # parent
116                 foreach (@_) {
117                         print CHILD "$_\n";
118                 }
119                 close(CHILD) || error("estcmd @params exited nonzero: $?");
120         }
121         else {
122                 # child
123                 open(STDOUT, "/dev/null"); # shut it up (closing won't work)
124                 exec("estcmd", @params) || error("can't run estcmd");
125         }
126 } #}}}
127
128 1