File Coverage

blib/lib/App/Rssfilter/Feed/Storage.pm
Criterion Covered Total %
statement 60 67 89.5
branch 15 28 53.5
condition 3 6 50.0
subroutine 19 20 95.0
pod n/a
total 97 121 80.1


line stmt bran cond sub pod time code
1 17     17   9284 use strict;
  17         48  
  17         855  
2 17     17   109 use warnings;
  17         37  
  17         1378  
3              
4             # ABSTRACT: load and save RSS feeds as files
5              
6              
7             package App::Rssfilter::Feed::Storage;
8             {
9             $App::Rssfilter::Feed::Storage::VERSION = '0.07';
10             }
11              
12 17     17   2517 use Method::Signatures;
  17         229214  
  17         167  
13 17     17   17393 use Moo;
  17         76027  
  17         156  
14             with 'App::Rssfilter::Logger';
15 17     17   76811 use Mojo::DOM;
  17         290889  
  17         532  
16 17     17   19644 use Path::Class::File 0.26;
  17         730864  
  17         1109  
17 17     17   250 use Path::Class::Dir;
  17         41  
  17         394  
18 17     17   20154 use HTTP::Date;
  17         46850  
  17         4572  
19              
20              
21              
22             has path => (
23             is => 'ro',
24             default => sub { Path::Class::Dir->new() },
25             coerce => sub {
26             return $_[0] if 'Path::Class::Dir' eq ref $_[0];
27             if ( 1 == @_ && 'Array' eq ref $_[0] ) {
28             @_ = @{ $_[0] };
29             }
30             Path::Class::Dir->new( @_ )
31             },
32             );
33              
34              
35 17     17   2063174 method path_push( @paths ) {
  0     0   0  
  0         0  
36 0         0 return App::Rssfilter::Feed::Storage->new(
37             path => $self->path->subdir( @paths ),
38             name => $self->name,
39             );
40             }
41              
42              
43             has name => (
44             is => 'ro',
45             );
46              
47              
48 17 50   17   40069 method set_name( $new_name ) {
  2 50   2   3941  
  2         9  
  2         5  
  2         7  
49 2 50 33     32 return $self if defined($self->name) && defined($new_name) ? $self->name eq $new_name : ! defined($self->name) && ! defined($new_name);
    100 66        
50 1         28 return App::Rssfilter::Feed::Storage->new(
51             name => $new_name,
52             path => $self->path,
53             );
54             }
55              
56             has _file_path => (
57             is => 'lazy',
58             init_arg => undef,
59             );
60              
61 17 50   17   12358 method _build__file_path {
  1     1   444  
  1         6  
62 1 50       8 die "no name" if not defined $self->name;
63 1 50       5 die "no path" if not defined $self->path;
64 1         11 $self->path->file( $self->name .'.rss' );
65             }
66              
67              
68             has last_modified => (
69             is => 'lazy',
70             init_arg => undef,
71             clearer => '_clear_last_modified',
72             );
73              
74 17 50   17   11433 method _build_last_modified {
  1     1   596  
  1         5  
75 1 50       6 if ( my $stat = $self->_file_path->stat ) {
76 1         410 return time2str $stat->mtime;
77             }
78 0         0 return time2str 0;
79             }
80              
81              
82 17 50   17   16728 method load_existing {
  1     1   9064  
  1         18  
83 1         8 $self->logger->debugf( 'loading '. $self->_file_path );
84 1         160 my $stat = $self->_file_path->stat;
85              
86 1 50       206 return Mojo::DOM->new if not defined $stat;
87              
88 1         5 $self->_clear_last_modified;
89 1         462 return Mojo::DOM->new( scalar $self->_file_path->slurp );
90             }
91              
92              
93 17 50   17   39626 method save_feed( $feed ) {
  1 50   1   3913  
  1         5  
  1         4  
  1         5  
94 1         5 $self->logger->debugf( 'writing out new filtered feed to '. $self->_file_path );
95 1         126 my $target_dir = $self->_file_path->dir;
96 1 50       24 if( not defined $target_dir->stat ) {
97 0         0 $self->logger->debug( "no $target_dir directory! making one" );
98 0         0 $target_dir->mkpath;
99             }
100 1         194 $self->_file_path->spew( $feed->to_xml );
101 0           $self->_clear_last_modified;
102             }
103              
104             1;
105              
106             __END__
107              
108             =pod
109              
110             =encoding UTF-8
111              
112             =head1 NAME
113              
114             App::Rssfilter::Feed::Storage - load and save RSS feeds as files
115              
116             =head1 VERSION
117              
118             version 0.07
119              
120             =head1 SYNOPSIS
121              
122             use App::Rssfilter::Feed::Storage;
123              
124             my $fs = App::Rssfilter::Feed::Storage->new(
125             path => 'Hi-type feeds',
126             name => 'Hello',
127             );
128              
129             print 'last update of feed was ', $fs->last_modified, "\n";
130             print 'what we got last time: ', $fs->load_existing, "\n";
131              
132             $fs->save_feed( Mojo::DOM->new( "<hi>hello</hi>" ) );
133             print 'now it is: ', $fs->load_existing, "\n";
134              
135             =head1 DESCRIPTION
136              
137             This module saves and loads RSS feeds to and from files, where the file name is based on a group and feed name. It is the default implementation used by L<App::Rssfilter::Feed> for storing & retreiving feeds.
138              
139             It consumes the L<App::Rssfilter::Logger> role.
140              
141             =head1 ATTRIBUTES
142              
143             =head2 logger
144              
145             This is a object used for logging; it defaults to a L<Log::Any> object. It is provided by the L<App::Rssfilter::Logger> role.
146              
147             =head2 path
148              
149             This is the directory path to the stored feed file. If not specified, the current working directory will be used. It is coerced into a L<Path::Class::Dir> object, if it is a string specifying an absolute or relative directory path, or an array or arrayref of directory names (which will be joined to form a directory path).
150              
151             =head2 name
152              
153             This is the name of the feed, and will be used as the filename to store the feed under.
154              
155             =head2 last_modified
156              
157             This is the last time the stored RSS feed was saved, as a HTTP date string suitable for use in a C<Last-Modified> header. If the feed has never been saved, returns C<Thu, 01 Jan 1970 00:00:00 GMT>. It cannot be set from the constructor.
158              
159             =head1 METHODS
160              
161             =head2 path_push
162              
163             my $new_fs = $fs->path_push( @paths );
164              
165             Returns a clone of this object whose path has had C<@paths> appended to it.
166              
167             =head2 set_name
168              
169             my $new_fs = $fs->set_name( $new_name );
170              
171             Returns this object if its name is already C<$new_name>, else returns a clone of this object with its name set to C<$name>.
172              
173             =head2 load_existing
174              
175             print $fs->load_existing->to_xml;
176              
177             Returns a L<Mojo::DOM> object initialised with the content of the previously-saved feed. If the feed has never been saved, returns a L<Mojo::DOM> object initialised with an empty string.
178              
179             =head2 save_feed
180              
181             $fs->save_feed( Mojo::DOM->new( '<rss> ... </rss>' ) );
182              
183             Saves a L<Mojo::DOM> object (or anything with a C<to_xml> method), and updates C<last_modified()>.
184              
185             =head1 AUTHOR
186              
187             Daniel Holz <dgholz@gmail.com>
188              
189             =head1 COPYRIGHT AND LICENSE
190              
191             This software is copyright (c) 2013 by Daniel Holz.
192              
193             This is free software; you can redistribute it and/or modify it under
194             the same terms as the Perl 5 programming language system itself.
195              
196             =cut