source: trunk/lib/OpenGuides/Feed.pm @ 807

Last change on this file since 807 was 807, checked in by nick, 15 years ago

Typo fix - get the feeds the right way around!

File size: 8.5 KB
Line 
1package OpenGuides::Feed;
2
3use strict;
4
5use vars qw( $VERSION );
6$VERSION = '0.01';
7
8use Wiki::Toolkit::Feed::Atom;
9use Wiki::Toolkit::Feed::RSS;
10use Time::Piece;
11use URI::Escape;
12use Carp 'croak';
13
14sub new {
15    my ($class, @args) = @_;
16    my $self = {};
17    bless $self, $class;
18    $self->_init(@args);
19}
20
21sub _init {
22    my ($self, %args) = @_;
23
24    my $wiki = $args{wiki};
25   
26    unless ( $wiki && UNIVERSAL::isa( $wiki, "Wiki::Toolkit" ) ) {
27       croak "No Wiki::Toolkit object supplied.";
28    }
29    $self->{wiki} = $wiki;
30
31    my $config = $args{config};
32
33    unless ( $config && UNIVERSAL::isa( $config, "OpenGuides::Config" ) ) {
34        croak "No OpenGuides::Config object supplied.";
35    }
36    $self->{config} = $config;
37
38    $self->{make_node_url} = sub {
39        my ($node_name, $version) = @_;
40
41        my $config = $self->{config};
42   
43        my $node_url = $config->script_url . uri_escape($config->script_name) . '?';
44        $node_url .= 'id=' if defined $version;
45        $node_url .= uri_escape($self->{wiki}->formatter->node_name_to_node_param($node_name));
46        $node_url .= ';version=' . uri_escape($version) if defined $version;
47
48        $node_url;
49      }; 
50    $self->{site_name}        = $config->site_name;
51    $self->{default_city}     = $config->default_city     || "";
52    $self->{default_country}  = $config->default_country  || "";
53    $self->{site_description} = $config->site_desc        || "";
54    $self->{og_version}       = $args{og_version};
55
56    $self;
57}
58
59sub make_feed {
60    my ($self, %args) = @_;
61   
62    my $feed_type = $args{feed_type};
63    my $feed_listing = $args{feed_listing};
64   
65    my %known_listings = (
66                          'recent_changes' => 1,
67                          'node_all_versions' => 1,
68                         );
69                     
70    croak "No feed listing specified" unless $feed_listing;
71    croak "Unknown feed listing: $feed_listing" unless $known_listings{$feed_listing};
72
73    # Fetch the right Wiki::Toolkit::Feeds::Listing instance to use
74    my $maker = $self->fetch_maker($feed_type);
75
76    # Call the appropriate feed listing from it
77    if ($feed_listing eq 'recent_changes') {
78        return $maker->recent_changes(%args);
79    }
80    elsif ($feed_listing eq 'node_all_versions') {
81        return $maker->node_all_versions(%args);
82    }
83}
84
85=item B<fetch_maker>
86For the given feed type, identify and return the maker routine for feeds
87of that type.
88
89my $maker = $feed->fetch_maker("rss");
90my $feed_contents = maker->node_all_versions(%options);
91
92Will always return something of type Wiki::Toolkit::Feed::Listing
93=cut
94sub fetch_maker {
95    my ($self,$feed_type) = @_;
96
97    my %known_types = (
98                          'atom'  => \&atom_maker,
99                          'rss' => \&rss_maker,
100                      );
101
102    croak "No feed type specified" unless $feed_type;
103    croak "Unknown feed type: $feed_type" unless $known_types{$feed_type};
104
105    return &{$known_types{$feed_type}};
106}
107
108sub atom_maker {
109    my $self = shift;
110 
111    unless ($self->{atom_maker}) {
112        $self->{atom_maker} = Wiki::Toolkit::Feed::Atom->new(
113            wiki                => $self->{wiki},
114            site_name           => $self->{site_name},
115            site_url            => $self->{config}->script_url,
116            site_description    => $self->{site_description},
117            make_node_url       => $self->{make_node_url},
118            recent_changes_link => $self->{config}->script_url . '?action=rc',
119            atom_link           => $self->{config}->script_url . '?action=rc&format=atom',
120            software_name       => 'OpenGuides',
121            software_homepage   => 'http://openguides.org/',
122            software_version    => $self->{og_version},
123        );
124    }
125   
126    $self->{atom_maker};
127}
128
129sub rss_maker {
130    my $self = shift;
131
132    unless ($self->{rss_maker}) {
133        $self->{rss_maker} = Wiki::Toolkit::Feed::RSS->new(
134            wiki                => $self->{wiki},
135            site_name           => $self->{site_name},
136            site_url            => $self->{config}->script_url,
137            site_description    => $self->{site_description},
138            make_node_url       => $self->{make_node_url},
139            recent_changes_link => $self->{config}->script_url . '?action=rc',
140            software_name       => 'OpenGuides',
141            software_homepage   => 'http://openguides.org/',
142            software_version    => $self->{og_version},
143        );
144    }
145   
146    $self->{rss_maker};
147}
148
149sub feed_timestamp {
150    my ($self, %args) = @_;
151
152    # Call the compatability timestamping method on the RSS Feed.
153    # People should really just pass in also_return_timestamp to the
154    #  feed method, and get the timestamp at the same time as their data
155    $self->rss_maker->rss_timestamp(%args);
156}
157
158=head1 NAME
159
160OpenGuides::Feed - generate data feeds for OpenGuides in various formats.
161
162=head1 DESCRIPTION
163
164Produces RSS 1.0 and Atom 1.0 feeds for OpenGuides.  Distributed and
165installed as part of the OpenGuides project, not intended for independent
166installation.  This documentation is probably only useful to OpenGuides
167developers.
168
169=head1 SYNOPSIS
170
171    use Wiki::Toolkit;
172    use OpenGuides::Config;
173    use OpenGuides::Feed;
174
175    my $wiki = Wiki::Toolkit->new( ... );
176    my $config = OpenGuides::Config->new( file => "wiki.conf" );
177    my $feed = OpenGuides::Feed->new( wiki       => $wiki,
178                                      config     => $config,
179                                      og_version => '1.0', );
180
181    # Ten most recent changes in RSS format.
182    my %args = ( items     => 10,
183                 feed_type => 'rss',
184                 also_return_timestamp => 1 );
185    my ($feed_output,$feed_timestamp) = $feed->make_feed( %args );
186
187    print "Content-Type: application/rdf+xml\n";
188    print "Last-Modified: " . $feed_timestamp . "\n\n";
189    print $feed_output;
190
191=head1 METHODS
192
193=over 4
194
195=item B<new>
196
197    my $feed = OpenGuides::Feed->new( wiki       => $wiki,
198                                      config     => $config,
199                                      og_version => '1.0', );
200
201C<wiki> must be a L<Wiki::Toolkit> object and C<config> must be an
202L<OpenGuides::Config> object.  Both of these arguments are mandatory.
203C<og_version> is an optional argument specifying the version of
204OpenGuides for inclusion in the feed.
205
206=item B<rss_maker>
207
208Returns a raw L<Wiki::Toolkit::Feed::RSS> object created with the values you
209invoked this module with.
210
211=item B<atom_maker>
212
213Returns a raw L<Wiki::Toolkit::Feed::Atom> object created with the values you
214invoked this module with.
215
216=item B<make_feed>
217
218    # Ten most recent changes in RSS format.
219    my %args = ( items     => 10,
220                 feed_type => 'rss',
221                 also_return_timestamp => 1 );
222    my ($feed_output,$feed_timestamp) = $rdf_writer->make_feed( %args );
223
224    print "Content-Type: application/rdf+xml\n";
225    print "Last-Modified: " . $feed_timestamp . "\n\n";
226    print $feed_output;
227    print $rdf_writer->make_feed( %args );
228
229
230    # All the changes made by bob in the past week, ignoring minor edits, in Atom.
231    $args{days}               = 7;
232    $args{ignore_minor_edits  = 1;
233    $args{filter_on_metadata} => { username => "bob" };
234    $args{also_return_timestamp} => 1;
235
236    my ($feed_output,$feed_timestamp) = $rdf_writer->make_feed( %args );
237    print "Content-Type: application/atom+xml\n";
238    print "Last-Modified: " . $feed_timestamp . "\n\n";
239    print $feed_output;
240
241=item B<feed_timestamp>
242
243Instead of calling this, you should instead pass in the 'also_return_timestamp'
244option. You will then get back the feed timestamp, along with the feed output.
245
246This method will be removed in future, and currently will only return
247meaningful values if your arguments relate to recent changes.
248
249    print "Last-Modified: " . $feed->feed_timestamp( %args ) . "\n\n";
250
251Returns the timestamp of something in POSIX::strftime style ("Tue, 29 Feb 2000
25212:34:56 GMT"). Takes the same arguments as make_recentchanges_rss().
253You will most likely need this to print a Last-Modified HTTP header so
254user-agents can determine whether they need to reload the feed or not.
255
256=back
257
258=head1 SEE ALSO
259
260=over 4
261
262=item * L<Wiki::Toolkit>, L<Wiki::Toolkit::Feed::RSS> and L<Wiki::Toolkit::Feed::Atom>
263
264=item * L<http://openguides.org/>
265
266=back
267
268=head1 AUTHOR
269
270The OpenGuides Project (openguides-dev@openguides.org)
271
272=head1 COPYRIGHT
273
274Copyright (C) 2003-2006 The OpenGuides Project.  All Rights Reserved.
275
276This module is free software; you can redistribute it and/or modify it
277under the same terms as Perl itself.
278
279=head1 CREDITS
280
281Written by Earle Martin, based on the original OpenGuides::RDF by Kake Pugh.
282
283=cut
284
2851;
Note: See TracBrowser for help on using the repository browser.