File Coverage

blib/lib/WWW/Sitemap/Simple.pm
Criterion Covered Total %
statement 81 81 100.0
branch 19 22 86.3
condition 5 8 62.5
subroutine 16 16 100.0
pod 5 5 100.0
total 126 132 95.4


line stmt bran cond sub pod time code
1             package WWW::Sitemap::Simple;
2 4     4   173717 use strict;
  4         7  
  4         134  
3 4     4   18 use warnings;
  4         8  
  4         121  
4 4     4   17 use Carp qw/croak/;
  4         11  
  4         241  
5 4     4   18 use Digest::MD5 qw/md5_hex/;
  4         5  
  4         172  
6 4     4   1422 use IO::File;
  4         15191  
  4         473  
7             use Class::Accessor::Lite (
8 4         28 rw => [qw/ urlset indent fatal /],
9             ro => [qw/ url /],
10 4     4   1898 );
  4         3377  
11              
12             our $VERSION = '0.04';
13              
14             my $DEFAULT_XMLNS = 'http://www.sitemaps.org/schemas/sitemap/0.9';
15             my $DEFAULT_INDENT = "\t";
16             my @KEYS = qw/ loc lastmod changefreq priority /;
17              
18             our $LIMIT_URL_COUNT = 50000;
19             our $LIMIT_URL_SIZE = 10_485_760; # byte
20              
21             sub new {
22 13     13 1 9807 my $class = shift;
23 13         23 my %args = @_;
24              
25 13         88 bless {
26             urlset => {
27             xmlns => $DEFAULT_XMLNS,
28             },
29             indent => $DEFAULT_INDENT,
30             fatal => 1,
31             %args,
32             count => 0,
33             url => +{},
34             }, $class;
35             }
36              
37             sub add {
38 28     28 1 95 my ($self, $url, $params) = @_;
39              
40 28         43 my $id = $self->get_id($url);
41              
42 28 50       163 $self->url->{$id} = {
43 28         28 %{$params || +{}},
44             loc => $url,
45             };
46              
47 28         164 $self->{count}++;
48 28 100 66     48 if ($self->fatal && $self->{count} > $LIMIT_URL_COUNT) {
49 1         151 croak "too many URL added: no more than $LIMIT_URL_COUNT URLs";
50             }
51              
52              
53 27         169 return $id;
54             }
55              
56             sub add_params {
57 2     2 1 11 my ($self, $id, $params) = @_;
58              
59 2 50       6 croak "key is not exists: $id" unless exists $self->{url}{$id};
60              
61 2         4 for my $key (@KEYS) {
62 8 100       24 $self->url->{$id}{$key} = $params->{$key} if exists $params->{$key};
63             }
64             }
65              
66             sub get_id {
67 28     28 1 29 my ($self, $url) = @_;
68              
69 28         106 return md5_hex(__PACKAGE__ . $url);
70             }
71              
72             sub write {
73 11     11 1 3224 my ($self, $file) = @_;
74              
75 11         23 my $xml = $self->_get_xml;
76              
77 11 100 66     24 if ($self->fatal && length $xml > $LIMIT_URL_SIZE) {
78 1         81 croak "too large xml: no more than $LIMIT_URL_SIZE bytes";
79             }
80              
81 10         77 $self->_write($file => $xml);
82             }
83              
84             sub _write {
85 10     10   13 my ($self, $file, $xml) = @_;
86              
87 10 100       24 if (!$file) {
    100          
88 5         21 STDOUT->print($xml);
89             }
90             elsif (my $re = ref $file) {
91 3 100       7 if ($re eq 'GLOB') {
92 1         7 print $file $xml;
93             }
94             else {
95 2         9 $file->print($xml);
96             }
97             }
98             else {
99 2         5 $self->_write_file($file, $xml);
100             }
101             }
102              
103             sub _write_file {
104 2     2   2 my ($self, $file, $xml) = @_;
105              
106 2         3 my $fh;
107 2 100       7 if ($file =~ m!\.gz$!i) {
108 1         6 require IO::Zlib;
109 1         7 IO::Zlib->import;
110 1         22 $fh = IO::Zlib->new($file => 'wb9');
111             }
112             else {
113 1         7 $fh = IO::File->new($file => 'w');
114             }
115 2 50       1640 croak "Could not create '$file'" unless $fh;
116 2         16 $fh->print($xml);
117 2         201 $fh->close;
118             }
119              
120             sub _get_xml {
121 11     11   14 my $self = shift;
122              
123 11   50     28 my $indent = $self->{indent} || '';
124              
125 11         28 my $xml = $self->_write_xml_header;
126              
127 11         13 for my $id (
  11         68  
128 11         22 sort { $self->url->{$a}{loc} cmp $self->url->{$b}{loc} } keys %{$self->url}
129             ) {
130 17         73 my $item = "$indent\n";
131 17         23 for my $key (@KEYS) {
132 68 100       197 if ( my $value = $self->url->{$id}{$key} ) {
133 21         122 $item .= "$indent$indent<$key>$value\n";
134             }
135             }
136 17         99 $xml .= "$item$indent\n";
137             }
138              
139 11         26 $xml .= $self->_write_xml_footer;
140              
141 11         17 return $xml;
142             }
143              
144             sub _write_xml_header {
145 11     11   10 my ($self) = @_;
146              
147 11         11 my $urlset_attr = '';
148 11         13 for my $key (sort keys %{$self->urlset}) {
  11         33  
149 13         76 my $value = $self->urlset->{$key};
150 13         67 $urlset_attr .= qq| $key="$value"|;
151             }
152 11         23 my $header = <<"_XML_";
153            
154            
155             _XML_
156 11         18 return $header;
157             }
158              
159             sub _write_xml_footer {
160 11     11   46 my ($self) = @_;
161              
162 11         12 my $footer = <<"_XML_";
163            
164             _XML_
165 11         19 return $footer;
166             }
167              
168             1;
169              
170             __END__