root/trunk/plagger/lib/Plagger/Plugin/Search/Estraier.pm

Revision 1186 (checked in by miyagawa, 14 years ago)
  • Unit test for Search::Estraier
  • Implemented searcher.search in Search::Estraier. Refs #62
  • Added test_requires_command in t::TestPlagger?
Line 
1 package Plagger::Plugin::Search::Estraier;
2 use strict;
3 use base qw( Plagger::Plugin );
4
5 use Encode;
6 use Search::Estraier;
7
8 sub init {
9     my $self = shift;
10     $self->SUPER::init(@_);
11
12     $self->conf->{url}      ||= "http://localhost:1978/node/plagger";
13     $self->conf->{username} ||= "admin";
14     $self->conf->{password} ||= "admin";
15     $self->conf->{timeout}  ||= 30;
16
17     $self->{node} = Search::Estraier::Node->new(
18         url => $self->conf->{url},
19     );
20     $self->{node}->set_auth($self->conf->{username}, $self->conf->{password});
21     $self->{node}->set_timeout($self->conf->{timeout});
22 }
23
24 sub register {
25     my($self, $context) = @_;
26     $context->register_hook(
27         $self,
28         'publish.entry' => \&entry,
29         'searcher.search'  => \&search,
30     );
31 }
32
33 sub entry {
34     my($self, $context, $args) = @_;
35
36     return unless $args->{entry}->permalink;
37
38     my $id  = $self->{node}->uri_to_id($args->{entry}->permalink);
39     $context->log(info => "Going to index entry " . $args->{entry}->permalink . ($id ? " with id=$id" : ""));
40
41     my $doc = Search::Estraier::Document->new;
42     $doc->add_attr('@uri' => $args->{entry}->permalink);
43     $doc->add_attr('@title' => _u($args->{entry}->title));
44     $doc->add_attr('@cdate' => $args->{entry}->date->format('W3CDTF')) if $args->{entry}->date;
45     $doc->add_attr('@author' => _u($args->{entry}->author)) if $args->{entry}->author;
46
47     $doc->add_text(_u($args->{entry}->body_text));
48     $doc->add_hidden_text(_u($args->{entry}->title));
49
50     $doc->add_attr('@id' => $id) if $id; # update mode
51
52     $self->{node}->put_doc($doc) or $context->error("Put failure: " . $self->{node}->status);
53 }
54
55 sub search {
56     my($self, $context, $args) = @_;
57
58     my $cond = Search::Estraier::Condition->new;
59     $cond->set_phrase( encode_utf8($args->{query}) );
60
61     my $nres = $self->{node}->search($cond, 0);
62     defined $nres or $context->error("search failed: " . $self->{node}->status);
63
64     my $feed = Plagger::Feed->new;
65     $feed->type('search:Estraier');
66     $feed->title("Search: $args->{query}");
67
68     for my $i ( 0 .. $nres->doc_num - 1 ) {
69         my $doc = $nres->get_doc($i);
70         my $entry = Plagger::Entry->new;
71
72         $entry->link( $doc->attr('@uri') );
73         $entry->title( decode_utf8($doc->attr('@title')) );
74         $entry->date( $doc->attr('@cdate') )    if $doc->attr('@cdate');
75         $entry->author( decode_utf8($doc->attr('@author')) ) if $doc->attr('@author');
76         $entry->body( decode_utf8($doc->snippet) );
77
78         $feed->add_entry($entry);
79     }
80
81
82     return $feed;
83 }
84
85 sub _u {
86     my $str = shift;
87     Encode::_utf8_off($str);
88     $str;
89 }
90
91 1;
92
93 __END__
94
95 =head1 NAME
96
97 Plagger::Plugin::Search::Estraier - Search entries using Hyper Estraier P2P
98
99 =head1 SYNOPSIS
100
101   - module: Search::Estraier
102     config:
103       url: http://localhost:1978/node/plagger
104       username: foobar
105       password: p4ssw0rd
106
107 =head1 DESCRIPTION
108
109 This plugin uses Hyper Estraier
110 (L<http://hyperestraier.sourceforge.net/>) and its P2P Node API to
111 search feed entries aggregated by Plagger.
112
113 =head1 AUTHOR
114
115 Tatsuhiko Miyagawa
116
117 =head1 SEE ALSO
118
119 L<Plagger>, L<http://hyperestraier.sourceforge.net/>, L<Search::Estraier>
120
121 =cut
Note: See TracBrowser for help on using the browser.