source: wiki-toolkit/trunk/lib/Wiki/Toolkit/Feed/Listing.pm @ 424

Revision 424, 6.9 KB checked in by dom, 6 years ago (diff)

whitespace-only change to fix some POD bugs and generally make things read
more nicely. Tab-damage fixing still todo...

Line 
1package Wiki::Toolkit::Feed::Listing;
2
3use strict;
4use Carp qw( croak );
5
6=item B<fetch_recently_changed_nodes>
7
8Based on the supplied criteria, fetch a list of the recently changed nodes
9
10=cut
11
12sub fetch_recently_changed_nodes {
13    my ($self, %args) = @_;
14
15    my $wiki = $self->{wiki};
16
17    my %criteria = (
18                   ignore_case => 1,
19                   );
20
21    # If we're not passed any parameters to limit the items returned,
22    #  default to 15.
23    $args{days} ? $criteria{days}           = $args{days}
24                : $criteria{last_n_changes} = $args{items} || 15;
25 
26    $criteria{metadata_wasnt} = { major_change => 0 }     if $args{ignore_minor_edits};
27    $criteria{metadata_was}   = $args{filter_on_metadata} if $args{filter_on_metadata};
28
29    my @changes = $wiki->list_recent_changes(%criteria);
30
31    return @changes;
32}
33
34=item B<fetch_oldest_for_recently_changed>
35
36Based on the supplied criteria (but not using all of those used by
37B<fetch_recently_changed_nodes>), find the newest node from the recently
38changed nodes set. Normally used for dating the whole of a Feed.
39
40=cut
41
42sub fetch_newest_for_recently_changed {
43    my ($self, %args) = @_;
44
45    my %criteria = (ignore_case => 1);
46
47    $args{days} ? $criteria{days}           = $args{days}
48                : $criteria{last_n_changes} = $args{items} || 15;
49
50    $criteria{metadata_wasnt} = { major_change => 0 }     if $args{ignore_minor_edits};
51    $criteria{metadata_was}   = $args{filter_on_metadata} if $args{filter_on_metadata};
52
53    my @changes = $self->{wiki}->list_recent_changes(%criteria);
54
55    return $changes[0];
56}
57
58
59=item B<fetch_node_all_versions>
60
61For a given node (name or ID), return all the versions there have been,
62including all metadata required for it to go into a "recent changes"
63style listing.
64
65=cut
66
67sub fetch_node_all_versions {
68    my ($self, %args) = @_;
69
70    # Check we got the right options
71    unless($args{'name'}) {
72        return ();
73    }
74
75    # Do the fetch
76    my @nodes = $self->{wiki}->list_node_all_versions(
77                        name => $args{'name'},
78                        with_content => 0,
79                        with_metadata => 1,
80    );
81
82    # Ensure that all the metadata fields are arrays and not strings
83    foreach my $node (@nodes) {
84        foreach my $mdk (keys %{$node->{'metadata'}}) {
85            unless(ref($node->{'metadata'}->{$mdk}) eq "ARRAY") {
86                $node->{'metadata'}->{$mdk} = [ $node->{'metadata'}->{$mdk} ];
87            }
88        }
89    }
90
91    return @nodes;
92}
93
94
95=item B<recent_changes>
96
97Build an Atom Feed of the recent changes to the Wiki::Toolkit instance,
98using any supplied parameters to narrow the results.
99
100If the argument "also_return_timestamp" is supplied, it will return an
101array of the feed, and the feed timestamp. Otherwise it just returns the feed.
102
103=cut
104
105sub recent_changes
106{
107    my ($self, %args) = @_;
108
109    my @changes = $self->fetch_recently_changed_nodes(%args);
110    my $feed_timestamp = $self->feed_timestamp(
111                              $self->fetch_newest_for_recently_changed(%args)
112    );
113
114    my $feed = $self->generate_node_list_feed($feed_timestamp, @changes);
115
116    if($args{'also_return_timestamp'}) {
117        return ($feed,$feed_timestamp);
118    } else {
119        return $feed;
120    }
121}
122
123
124=item B<node_all_versions>
125
126Build an Atom Feed of all the different versions of a given node.
127
128If the argument "also_return_timestamp" is supplied, it will return an
129array of the feed, and the feed timestamp. Otherwise it just returns the feed.
130
131=cut
132
133sub node_all_versions
134{
135    my ($self, %args) = @_;
136
137    my @all_versions = $self->fetch_node_all_versions(%args);
138    my $feed_timestamp = $self->feed_timestamp( $all_versions[0] );
139
140    my $feed = $self->generate_node_list_feed($feed_timestamp, @all_versions);
141
142    if($args{'also_return_timestamp'}) {
143        return ($feed,$feed_timestamp);
144    } else {
145        return $feed;
146    }
147} 
148
149=item B<format_geo>
150
151Using the geo and space xml namespaces, format the supplied node metadata
152into geo: and space: tags, suitable for inclusion in a feed with those
153namespaces imported.
154
155=cut
156
157sub format_geo {
158    my ($self, @args) = @_;
159
160    my %metadata;
161    if(ref($args[0]) eq "HASH") {
162        %metadata = %{$_[1]};
163    } else {
164        %metadata = @args;
165    }
166
167    my %mapping = (
168            "os_x" => "space:os_x",
169            "os_y" => "space:os_y",
170            "latitude"  => "geo:lat",
171            "longitude" => "geo:long",
172            "distance"  => "space:distance",
173    );
174
175    my $feed = "";
176
177    foreach my $geo (keys %metadata) {
178        my $geo_val = $metadata{$geo};
179        if(ref($geo_val) eq "ARRAY") {
180            $geo_val = $geo_val->[0];
181        }
182
183        if($mapping{$geo}) {
184            my $tag = $mapping{$geo};
185            $feed .= "  <$tag>$geo_val</$tag>\n";
186        }
187    }
188
189    return $feed;
190}
191
192#item B<handle_supply_one_of>
193# Utility method, to help with argument passing where one of a list of
194#  arguments must be supplied
195#
196#=cut
197
198sub handle_supply_one_of {
199    my ($self,$mref,$aref) = @_;
200    my %mustoneof = %{$mref};
201    my %args = %{$aref};
202
203    foreach my $oneof (keys %mustoneof) {
204        my $val = undef;
205        foreach my $poss (@{$mustoneof{$oneof}}) {
206            unless($val) {
207                if($args{$poss}) { $val = $args{$poss}; }
208            }
209        }
210        if($val) {
211            $self->{$oneof} = $val;
212        } else {
213            croak "No $oneof supplied, or one of its equivalents (".join(",", @{$mustoneof{$oneof}}).")";
214        }
215    }
216}
217
218
219# The following are methods that any feed renderer must provide
220
221=item B<feed_timestamp>
222
223All implementing feed renderers must implement a method to produce a
224feed specific timestamp, based on the supplied node
225
226=cut
227
228sub feed_timestamp          { die("Not implemented by feed renderer!"); }
229
230=item B<generate_node_list_feed>
231
232All implementing feed renderers must implement a method to produce a
233feed from the supplied list of nodes
234
235=cut
236
237sub generate_node_list_feed { die("Not implemented by feed renderer!"); }
238
239=item B<generate_node_name_distance_feed>
240
241All implementing feed renderers must implement a method to produce a
242stripped down feed from the supplied list of node names, and optionally
243locations and distance from a reference point.
244
245=cut
246
247sub generate_node_name_distance_feed { die("Not implemented by feed renderer!"); }
248
249=item B<parse_feed_timestamp>
250
251Take a feed_timestamp and return a Time::Piece object.
252
253=cut
254
255sub parse_feed_timestamp { die("Not implemented by feed renderer!"); }
256
2571;
258
259__END__
260
261=head1 NAME
262
263Wiki::Toolkit::Feed::Listing - parent class for Feeds from Wiki::Toolkit.
264
265=head1 DESCRIPTION
266
267Handles common data fetching tasks, so that child classes need only
268worry about formatting the feeds.
269
270Also enforces some common methods that must be implemented.
271
272=head1 MAINTAINER
273
274The Wiki::Toolkit team, http://www.wiki-toolkit.org/.
275
276=head1 COPYRIGHT AND LICENSE
277
278Copyright 2006 the Wiki::Toolkit team.
279
280This module is free software; you can redistribute it and/or modify it
281under the same terms as Perl itself.
282
283=cut
Note: See TracBrowser for help on using the repository browser.