File Coverage

blib/lib/App/FeedDeduplicator/Publisher.pm
Criterion Covered Total %
statement 14 14 100.0
branch n/a
condition n/a
subroutine 5 5 100.0
pod n/a
total 19 19 100.0


line stmt bran cond sub pod time code
1             =head1 NAME
2              
3             App::FeedDeduplicator::Publisher - Publisher class for App::FeedDeduplicator
4              
5             =head1 DESCRIPTION
6              
7             This module is part of the App::FeedDeduplicator application. It is
8             responsible for publishing the deduplicated entries to a specified format
9             (Atom or JSON).
10              
11             =head1 SYNOPSIS
12              
13             use App::FeedDeduplicator::Publisher;
14              
15             my $publisher = App::FeedDeduplicator::Publisher->new(
16             entries => $deduplicated_entries,
17             format => 'Atom',
18             max_entries => 10,
19             );
20              
21             $publisher->publish();
22              
23             =head1 METHODS
24              
25             =head2 new
26              
27             Creates a new instance of App::FeedDeduplicator::Publisher. The constructor
28             accepts an arrau of entries, a format (Atom or JSON), and a maximum number of
29             entries as parameters.
30              
31             The entries should be an array reference containing hash references with the
32             keys 'entry' and 'feed'.
33              
34             The 'entry' key should contain an XML::Feed::Entry object, and the 'feed' key
35             should contain a hash reference with the feed information.
36              
37             The format should be either 'Atom' or 'JSON', and the maximum number of
38             entries specifies how many entries to include in the output.
39              
40             =head2 publish
41              
42             The main method that publishes the deduplicated entries to the specified
43             format (Atom or JSON).
44              
45             It sorts the entries based on their issued, modified, updated, or date
46             attributes and limits the output to the specified maximum number of entries.
47              
48             It generates the output in the specified format and prints it to STDOUT.
49              
50             =cut
51              
52 1     1   11 use v5.40;
  1         23  
53 1     1   5 use feature 'class';
  1         1  
  1         110  
54 1     1   3 no warnings 'experimental::class';
  1         2  
  1         74  
55              
56             class App::FeedDeduplicator::Publisher {
57 1     1   4 use XML::Feed;
  1         2  
  1         21  
58 1     1   370 use JSON::MaybeXS;
  1         6803  
  1         437  
59              
60             field $entries :param;
61             field $format :param //= 'Atom';
62             field $max_entries :param //= 10;
63              
64             method publish {
65             my @sorted = sort {
66             ($b->{entry}->issued || $b->{entry}->modified || $b->{entry}->updated || $b->{entry}->date || 0)
67             <=>
68             ($a->{entry}->issued || $a->{entry}->modified || $a->{entry}->updated || $a->{entry}->date || 0)
69             } @$entries;
70              
71             if (@sorted > $max_entries) {
72             $#sorted = $max_entries - 1;
73             }
74              
75             if ($format eq 'json') {
76             say encode_json([ map { {
77             title => $_->{entry}->title,
78             link => $_->{entry}->link,
79             summary => $_->{entry}->summary->body,
80             issued => $_->{entry}->issued && $_->{entry}->issued->iso8601,
81             source_name => $_->{feed}{name},
82             source_url => $_->{feed}{web},
83             } } @sorted ]);
84             } else {
85             my $feed = XML::Feed->new($format);
86             $feed->title("Deduplicated Feed");
87             $feed->add_entry($_) for @sorted;
88             say $feed->as_xml;
89             }
90             }
91             }
92              
93             =head1 AUTHOR
94              
95             Dave Cross <dave@perlhacks.com>
96              
97             =head1 COPYRIGHT AND LICENSE
98              
99             This software is copyright (c) 2025 Magnum Solutions Ltd.
100             All rights reserved.
101              
102             This program is free software; you can redistribute it and/or modify it under
103             the same terms as Perl itself.
104              
105             See L<http://dev.perl.org/licenses/artistic.html> for more details.
106              
107             =cut
108              
109             1;