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