1 |
# Dobrica Pavlinusic, <dpavlin@rot13.org> 02/22/07 20:30:00 CET |
2 |
|
3 |
use strict; |
4 |
use warnings; |
5 |
|
6 |
package Grep::Source; |
7 |
|
8 |
use Carp qw/verbose/; |
9 |
use Module::Pluggable search_path => 'Grep::Source', sub_name => 'sources', require => 1; |
10 |
use base qw(Class::Accessor); |
11 |
Grep::Source->mk_accessors( qw(feed uri q new_items collection) ); |
12 |
|
13 |
use Data::Dump qw/dump/; |
14 |
|
15 |
=head1 NAME |
16 |
|
17 |
Grep::Source - base class for implementation of different sources for Grep |
18 |
|
19 |
=head1 METHODS |
20 |
|
21 |
This is mostly documentation because most of methods are implemented by plugins. |
22 |
|
23 |
=head2 sources |
24 |
|
25 |
my @sources = Grep::Source->sources(); |
26 |
|
27 |
Returns all available sources. |
28 |
|
29 |
=cut |
30 |
|
31 |
Jifty->log->debug("Found source plugins: ", join(", ", __PACKAGE__->sources() ) ); |
32 |
|
33 |
=head2 new |
34 |
|
35 |
my $source = Grep::Source->new({ feed => $feed_record }); |
36 |
|
37 |
This will also setup: |
38 |
|
39 |
=head2 feed |
40 |
|
41 |
isa L<Grep::Model::Feed> |
42 |
|
43 |
=head2 search |
44 |
|
45 |
my $collection = $source->search( 'query string' ); |
46 |
|
47 |
It will also setup following accessors: |
48 |
|
49 |
=head2 q |
50 |
|
51 |
Search query |
52 |
|
53 |
=head2 uri |
54 |
|
55 |
URI of feed with embedded search query |
56 |
|
57 |
=head2 new_items |
58 |
|
59 |
Number of new items in result collection |
60 |
|
61 |
=head2 collection |
62 |
|
63 |
Actuall results which is L<Grep::Model::ItemCollection>, so following will |
64 |
work: |
65 |
|
66 |
print "and ", $self->collection->count, " total items"; |
67 |
|
68 |
|
69 |
Also setups number of new items |
70 |
|
71 |
print $source->new_items, " items new"; |
72 |
|
73 |
=cut |
74 |
|
75 |
sub search { |
76 |
my $self = shift; |
77 |
|
78 |
my $q = shift; |
79 |
|
80 |
$q ? $self->q( $q ) : $q = $self->q; |
81 |
|
82 |
die "no q?" unless ( $self->q ); |
83 |
die "no feed?" unless ( $self->feed ); |
84 |
die "feed not Grep::Model::Feed" unless ( $self->feed->isa('Grep::Model::Feed') ); |
85 |
|
86 |
my $message; |
87 |
my $uri = $self->feed->uri; |
88 |
if ($uri =~ m/%s/) { |
89 |
$uri = $self->feed->search_uri( $q ); |
90 |
$message = 'Searching'; |
91 |
} else { |
92 |
$message = 'Fetching'; |
93 |
} |
94 |
$message .= ' ' . $self->feed->title . " at $uri"; |
95 |
|
96 |
$self->uri( $uri ); |
97 |
|
98 |
Jifty->log->info( $message ); |
99 |
|
100 |
$self->collection( Grep::Model::ItemCollection->new() ); |
101 |
|
102 |
my $class = $self->feed->source || 'Grep::Source::Feed'; |
103 |
Jifty->log->debug("using $class"); |
104 |
|
105 |
$class->fetch( $self ); |
106 |
|
107 |
Grep::Search->finish if $self->new_items; |
108 |
|
109 |
return $self->collection; |
110 |
} |
111 |
|
112 |
=head2 add_record |
113 |
|
114 |
Plugins will be called with parametar C<$parent> so they can call this method to add |
115 |
record into result collection (and store in cache and index). |
116 |
|
117 |
$parent->add_record( id => 42, foo => 'bar', ... ); |
118 |
|
119 |
This will also update L</new_items> |
120 |
|
121 |
=cut |
122 |
|
123 |
sub add_record { |
124 |
my $self = shift; |
125 |
|
126 |
my $i = Grep::Model::Item->new(); |
127 |
|
128 |
my ($ok,$msg) = $i->load_or_create( @_ ); |
129 |
|
130 |
$msg ||= ''; |
131 |
|
132 |
if ( $ok ) { |
133 |
Jifty->log->debug("item ", $i->id, ": $msg"); |
134 |
$self->collection->add_record( $i ); |
135 |
|
136 |
# is new record? |
137 |
if ( $msg !~ m/^Found/ ) { |
138 |
Grep::Search->add( $i ); |
139 |
$self->new_items( ( $self->new_items || 0 ) + 1 ); |
140 |
} |
141 |
} else { |
142 |
warn "can't add entry ", dump( @_ ), "\n"; |
143 |
} |
144 |
} |
145 |
|
146 |
=head2 content_class |
147 |
|
148 |
Return class registred for particular content. |
149 |
|
150 |
my $class = $source->content_class( $content ); |
151 |
|
152 |
=cut |
153 |
|
154 |
sub content_class { |
155 |
my $self = shift; |
156 |
|
157 |
my $content = shift or die "no content?"; |
158 |
|
159 |
foreach my $s ( $self->sources ) { |
160 |
Jifty->log->debug("testing source class $s"); |
161 |
if ( $s->can('content_have') ) { |
162 |
my $regex = $s->content_have( $content ) or |
163 |
die "${s}->content_have didn't return anything"; |
164 |
die "${s}->content_have didn't return regex but ", dump( $regex ), " ref ", ref( $regex ) |
165 |
unless ( ref($regex) eq 'Regexp' ); |
166 |
if ( $content =~ $regex ) { |
167 |
Jifty->log->debug("${s}->content_have succesful"); |
168 |
return $s; |
169 |
} |
170 |
} |
171 |
} |
172 |
} |
173 |
|
174 |
1; |