File Coverage

blib/lib/XML/OPML/SimpleGen.pm
Criterion Covered Total %
statement 46 79 58.2
branch 0 6 0.0
condition n/a
subroutine 10 15 66.6
pod 8 8 100.0
total 64 108 59.2


line stmt bran cond sub pod time code
1             package XML::OPML::SimpleGen;
2              
3 3     3   155986 use strict;
  3         5  
  3         79  
4 3     3   13 use warnings;
  3         4  
  3         79  
5              
6 3     3   12 use base 'Class::Accessor';
  3         4  
  3         1526  
7              
8 3     3   7280 use DateTime;
  3         892226  
  3         135  
9              
10 3     3   21 use POSIX qw(setlocale LC_TIME LC_CTYPE);
  3         3  
  3         22  
11              
12             __PACKAGE__->mk_accessors(qw|groups xml_options outline group xml_head xml_outlines xml|);
13              
14             # Version set by dist.ini; do not change here.
15             our $VERSION = '0.06_01'; # VERSION
16              
17             sub new {
18 3     3 1 1844 my $class = shift;
19 3         8 my @args = @_;
20              
21 3         59 my $args = {
22             groups => {},
23              
24             xml => {
25             version => '1.1',
26             @args,
27             },
28              
29             # XML::Simple options
30             xml_options => {
31             RootName => 'opml',
32             XMLDecl => '<?xml version="1.0" encoding="utf-8" ?>',
33             AttrIndent => 1,
34             },
35              
36             # default values for nodes
37             outline => {
38             type => 'rss',
39             version => 'RSS',
40             text => '',
41             title => '',
42             description => '',
43             },
44              
45             group => {
46             isOpen => 'true',
47             },
48              
49             xml_head => {},
50             xml_outlines => [],
51              
52             id => 1,
53             };
54              
55 3         7 my $self = bless $args, $class;
56              
57             # Force locale to 'C' rather than local, then reset after setting times.
58             # Fixes RT51000. Thanks to KAPPA for the patch.
59 3         18 my $old_loc = POSIX::setlocale(LC_TIME, "C");
60 3         242 my $ts_ar = [ localtime() ];
61 3         15 $self->head(
62             title => '',
63             $self->_date( dateCreated => $ts_ar ),
64             $self->_date( dateModified => $ts_ar ),
65             );
66 3         16 POSIX::setlocale(LC_TIME,$old_loc);
67              
68 3         12 return $self;
69             }
70              
71             sub _date {
72 8     8   1172 my $self = shift;
73 8         12 my $type = shift; # dateCreated or dateModified.
74 8         8 my $ts_ar = shift; # e.g [ localtime() ]
75              
76 8         9 my %arg;
77             @arg{qw(second minute hour day month year)} = (
78 8         12 @{$ts_ar}[0..3],
  8         40  
79             $ts_ar->[4]+1,
80             $ts_ar->[5]+1900 );
81 8         45 my $dt = DateTime->new( %arg );
82 8         2003 return ( $type => $dt->strftime('%a, %e %b %Y %H:%M:%S %z') );
83             }
84              
85             sub id {
86 0     0 1 0 my $self = shift;
87            
88 0         0 return $self->{id}++;
89             }
90              
91             sub head {
92 4     4 1 344 my $self = shift;
93 4         15 my $data = {@_};
94              
95             #this is necessary, otherwise XML::Simple will just generate attributes
96 4         6 while (my ($key,$value) = each %{ $data }) {
  15         118  
97 11         29 $self->xml_head->{$key} = [ $value ];
98             }
99             }
100              
101             sub add_group {
102 0     0 1 0 my $self = shift;
103 0         0 my %defaults = %{$self->group};
  0         0  
104 0         0 my $data = {
105             id => $self->id,
106             %defaults,
107             @_ };
108            
109 0 0       0 die "Need to define 'text' attribute" unless defined $data->{text};
110              
111 0         0 $data->{outline} = [];
112              
113 0         0 push @{$self->xml_outlines}, $data;
  0         0  
114 0         0 $self->groups->{$data->{text}} = $data->{outline};
115             }
116              
117             sub insert_outline {
118 0     0 1 0 my $self = shift;
119 0         0 my %defaults = %{$self->outline};
  0         0  
120 0         0 my $data = {
121             id => $self->id,
122             %defaults,
123             @_};
124              
125 0         0 my $parent = $self->xml_outlines;
126              
127 0 0       0 if (exists $data->{group}) {
128 0 0       0 if (exists $self->groups->{$data->{group}}) {
129 0         0 $parent = $self->groups->{$data->{group}};
130 0         0 delete($data->{group});
131             }
132             else {
133 0         0 $self->add_group('text' => $data->{group});
134 0         0 $self->insert_outline(%$data);
135 0         0 return;
136             }
137             }
138              
139 0         0 push @{$parent}, $data;
  0         0  
140             }
141              
142             sub add_outline {
143 0     0 1 0 my $self = shift;
144 0         0 $self->insert_outline(@_);
145             }
146              
147             sub as_string {
148 2     2 1 11 my $self = shift;
149              
150 2         1550 require XML::Simple;
151 2         12560 my $xs = XML::Simple->new();
152              
153 2         85 return $xs->XMLout( $self->_mk_hashref, %{$self->xml_options} );
  2         9  
154             }
155              
156             sub _mk_hashref {
157 2     2   5 my $self = shift;
158              
159             my $hashref = {
160 2         3 %{$self->xml},
  2         8  
161             head => $self->xml_head,
162             body => { outline => $self->xml_outlines },
163             };
164              
165 2         46 return $hashref;
166             }
167              
168             sub save {
169 0     0 1   my $self = shift;
170 0           my $filename = shift;
171              
172 0           require XML::Simple;
173 0           my $xs = XML::Simple->new();
174              
175 0           $xs->XMLout( $self->_mk_hashref, %{$self->xml_options}, OutputFile => $filename );
  0            
176             }
177              
178             1;
179              
180             # ABSTRACT: create OPML using XML::Simple
181              
182             __END__
183              
184             =pod
185              
186             =head1 NAME
187              
188             XML::OPML::SimpleGen - create OPML using XML::Simple
189              
190             =head1 VERSION
191              
192             version 0.06_01
193              
194             =head1 SYNOPSIS
195              
196             require XML::OPML::SimpleGen;
197              
198             my $opml = new XML::OPML::SimpleGen();
199              
200             $opml->head(
201             title => 'FIFFS Subscriptions',
202             );
203              
204             $opml->insert_outline(
205             group => 'news', # groups will be auto generated
206             text => 'some feed',
207             xmlUrl => 'http://www.somepage.org/feed.xml',
208             );
209              
210             # insert_outline and add_outline are the same
211              
212             $opml->add_group( text => 'myGroup' ); # explicitly create groups
213            
214             print $opml->to_string;
215              
216             $opml->save('somefile.opml');
217              
218             $opml->xml_options( $hashref ); # XML::Simple compatible options
219              
220             # See XML::OPML's synopsis for more knowledge
221              
222             =head1 DESCRIPTION
223              
224             XML::OPML::SimpleGen lets you simply generate OPML documents
225             without having too much to worry about.
226             It is a drop-in replacement for XML::OPML
227             in regards of generation.
228             As this module uses XML::Simple it is rather
229             generous in regards of attribute or element names.
230              
231             =head1 NAME
232              
233             XML::OPML::SimpleGen - create OPML using XML::Simple
234              
235             =head1 COMMON METHODS
236              
237             =over
238              
239             =item new( key => value )
240              
241             Creates a new XML::OPML::SimpleGen instance. All key values will be
242             used as attributes for the <atom> element. The only thing you might
243             want to use here is the version => '1.1', which is default anyway.
244              
245             =item head( key => value )
246              
247             XML::OPML compatible head method to change header values.
248              
249             =item id ( )
250              
251             Returns (and increments) a counter.
252              
253             =item add_group ( text => 'name' )
254              
255             Method to explicitly create a group which can hold multiple outline
256             elements.
257              
258             =item insert_outline ( key => value )
259              
260             XML::OPML compatible method to add an outline element. See
261             L<XML::OPML> for details. The group key is used to put elements in a
262             certain group. Non existent groups will be created automagically.
263              
264             =item add_outline ( key => value )
265              
266             Alias to insert_outline for XML::OPML compatibility.
267              
268             =item as_string
269              
270             Returns the given OPML XML data as a string
271              
272             =item save ( $filename )
273              
274             Saves the OPML data to a file
275              
276             =back
277              
278             =head1 ADVANCED METHODS
279              
280             =over
281              
282             =item xml_options ( $hashref )
283              
284             $hashref may contain any XML::Simple options.
285              
286             =item outline ( $hashref )
287              
288             The outline method defines the 'template' for any new outline
289             element. You can preset key value pairs here to be used
290             in all outline elements that will be generated by XML::OPML::SimpleGen.
291              
292             =item group ( $hashref )
293              
294             This method is similar to outline, it defines the template for a
295             grouping outline element.
296              
297             =back
298              
299             =head1 MAINTAINER
300              
301             Stephen Cardie C<< <stephenca@cpan.org> >>
302              
303             =head1 REPOSITORY
304              
305             L<https://github.com/stephenca/XML-OPML-SimpleGen>
306              
307             =head1 CONTRIBUTORS
308              
309             =over 4
310              
311             =item KAPPA C<< <kappa@cpan.org> >> contributed a patch to close RT51000
312             L<https://rt.cpan.org/Public/Bug/Display.html?id=51000>
313              
314             =item gregoa@debian.org contributed a patch to close RT77725
315             L<https://rt.cpan.org/Public/Bug/Display.html?id=77725>
316              
317             =back
318              
319             =head1 REPO
320              
321             The git repository for this module is at
322             L<https://github.com/stephenca/XML-OPML-SimpleGen>
323              
324             =head1 BUGS
325              
326             Please report any bugs or feature requests to
327             C<bug-xml-opml-simlegen@rt.cpan.org>, or through the web interface at
328             L<http://rt.cpan.org/NoAuth/ReportBug.html?Queue=XML-OPML-SimleGen>.
329             I will be notified, and then you'll automatically be notified of progress on
330             your bug as I make changes.
331              
332             =head1 SEE ALSO
333              
334             L<XML::OPML> L<XML::Simple>
335              
336             =head1 AUTHOR
337              
338             Marcus Theisen <marcus@thiesen.org>
339              
340             =head1 COPYRIGHT AND LICENSE
341              
342             This software is copyright (c) 2013 by Marcus Thiesen.
343              
344             This is free software; you can redistribute it and/or modify it under
345             the same terms as the Perl 5 programming language system itself.
346              
347             =cut