File Coverage

blib/lib/WWW/Sitemap/Simple.pm
Criterion Covered Total %
statement 83 83 100.0
branch 21 24 87.5
condition 5 8 62.5
subroutine 17 17 100.0
pod 6 6 100.0
total 132 138 95.6


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