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

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

Explicitly request the feed timestamp at the same time as the feed, to avoid Wiki::Toolkit having to do the node fetch twice. The feed_timestamp method on OpenGuides::Feed should no longer be used, as it requires another fetch, and only makes sense if you only ever deal with recent changes

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