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

Revision 1741 (checked in by miyagawa, 12 years ago)

merge from hackathon-summary

Line 
1 package Plagger::Plugin::Search::Grep;
2 use strict;
3 use base qw( Plagger::Plugin );
4
5 use Encode;
6 use File::Grep ();
7 use File::Spec;
8 use YAML;
9
10 sub init {
11     my $self = shift;
12     $self->SUPER::init(@_);
13
14     _mkdir($self->conf->{dir});
15 }
16
17 sub register {
18     my($self, $context) = @_;
19     $context->register_hook(
20         $self,
21         'publish.entry' => \&entry,
22         'searcher.search'  => \&search,
23     );
24 }
25
26 sub entry {
27     my($self, $context, $args) = @_;
28
29     my $dir = File::Spec->catfile($self->conf->{dir}, $args->{feed}->id_safe);
30     _mkdir($dir);
31
32     my $yaml = File::Spec->catfile($dir, 'config.yaml');
33     my $config = -e $yaml ? YAML::LoadFile($yaml) : {};
34     for my $entry ($args->{feed}->entries) {
35         next unless $entry->permalink;
36
37         my $id = $entry->id_safe;
38         my $path = File::Spec->catfile($dir, "$id.txt");
39         $context->log(info => "Going to index entry " . $entry->permalink);
40
41         $config->{$id} = {
42             link   => $entry->link,
43             author => _u($entry->author || ''),
44             date   => $entry->date ? $entry->date->format('W3CDTF') : '',
45             title  => _u($entry->title->plaintext),
46             body   => _u($entry->body->plaintext) || '',
47         };
48
49         open my $out, '>', $path or $context->error("$path: $!");
50         print $out join("\n", $entry->permalink, _u($entry->author || ''), _u($entry->title_text || ''), _u($entry->body_text));
51         close $out;
52     }
53
54     YAML::DumpFile($yaml, $config);
55 }
56
57 sub search {
58     my($self, $context, $args) = @_;
59
60     my $path = File::Spec->catfile($self->conf->{dir}, '*', '*.txt');
61     my $query = _u($args->{query});
62     return unless $query;
63
64     my $feed = Plagger::Feed->new;
65     $feed->type('search:Grep');
66     $feed->title("Search: $query");
67
68     my $config_cache = {};
69     my @matchs = grep { $_->{count} } File::Grep::fgrep { /$query/i } glob $path;
70     for my $match (@matchs) {
71         my ($drive, $dir, $file) = File::Spec->splitpath($match->{filename});
72         $file =~ s/\.txt$//;
73
74         my $yaml = File::Spec->catpath($drive, $dir, 'config.yaml');
75         unless ($config_cache->{$yaml}) {
76             $config_cache->{$yaml} = YAML::LoadFile($yaml);
77         }
78         my $config = $config_cache->{$yaml}->{$file};
79         next unless $config;
80
81         my $entry = Plagger::Entry->new;
82         for my $key (qw( link author date title body )) {
83             $entry->$key( $config->{$key} );
84         }
85         $feed->add_entry($entry);
86     }
87
88     return $feed;
89 }
90
91 sub _u {
92     my $str = shift;
93     Encode::_utf8_off($str);
94     $str;
95 }
96
97 sub _mkdir {
98     my $dir = shift;
99     unless (-e $dir && -d _) {
100         mkdir $dir, 0755 or Plagger->context->error("mkdir $dir: $!");
101     }
102 }
103
104 1;
105
106 __END__
107
108 =head1 NAME
109
110 Plagger::Plugin::Search::Grep - Search entries using File::Grep
111
112 =head1 SYNOPSIS
113
114   - module: Search::Grep
115     config:
116       dir: /home/yappo/plagger-grep
117
118 =head1 DESCRIPTION
119
120 This plugin uses L<File::Grep>
121 it's simple search interface!
122
123 =head1 AUTHOR
124
125 Kazuhiro Osawa
126
127 =head1 SEE ALSO
128
129 L<Plagger>, L<File::Grep>
130
131 =cut
Note: See TracBrowser for help on using the browser.