File Coverage

lib/Google/Merchant/AtomFeed.pm
Criterion Covered Total %
statement 12 12 100.0
branch n/a
condition n/a
subroutine 4 4 100.0
pod n/a
total 16 16 100.0


line stmt bran cond sub pod time code
1             # Copyrights 2013-2014 by [Mark Overmeer].
2             # For other contributors see ChangeLog.
3             # See the manual pages for details on the licensing terms.
4             # Pod stripped from pm file by OODoc 2.01.
5 2     2   1330 use warnings;
  2         4  
  2         67  
6 2     2   10 use strict;
  2         4  
  2         95  
7              
8             package Google::Merchant::AtomFeed;
9 2     2   19 use vars '$VERSION';
  2         3  
  2         122  
10             $VERSION = '0.15';
11              
12 2     2   10 use base 'Google::Merchant';
  2         9  
  2         810  
13              
14             use Log::Report 'google-merchant';
15              
16             use Google::Merchant::Util qw/:ns10/;
17             use XML::Compile::Util qw/XMLNS/;
18             use Encode qw/encode/;
19              
20              
21             sub init($)
22             { my ($self, $args) = @_;
23             $self->SUPER::init($args);
24              
25             my $title = $args->{title} || panic "feed title required";
26             my $site = $args->{website} || panic "feed website required";
27              
28             # Google only supports these three, it seems
29             my @globs;
30             push @globs, +{title => $title};
31             push @globs, +{link => +{rel => 'self', href => $site}};
32             push @globs, +{updated => ($args->{updated} || time) };
33              
34             { no strict; # in devel, $VERSION undeclared
35             push @globs, +{generator => __PACKAGE__ . ' '. ($VERSION || 'undef')}
36             }
37             push @globs, +{entry => ($self->{GMA_entries} = []) };
38              
39             my $feed = $self->feed;
40             $feed->{cho_author} = \@globs;
41             $feed->{base} = $args->{base} || $site;
42             $feed->{lang} = $args->{language};
43              
44             $self;
45             }
46              
47             sub _loadSchemas()
48             { my $self = shift;
49             my $schemas = $self->SUPER::_loadSchemas();
50              
51             $schemas->addPrefixes('' => NS_ATOM_2005);
52             $self->_loadXSD($schemas, 'atom-2005.xsd');
53             $schemas->importDefinitions(XMLNS);
54             $schemas->declare
55             ( WRITER => 'feed'
56             , mixed_elements => 'STRUCTURAL'
57             , hook =>
58             [ +{ type => 'textType'
59             , replace => sub {$self->_write_texttype(@_) }
60             }
61             , +{ type => 'entryType'
62             , replace => sub {$self->_write_entrytype(@_)}
63             }
64             ]
65             );
66              
67             $schemas;
68             }
69              
70             #---------
71              
72             sub addItem(%)
73             { my ($self, %args) = @_;
74              
75             my $title = delete $args{title} or panic "entry title required";
76             my $page = delete $args{webpage} or panic "entry webpage required";
77             my $descr = delete $args{description};
78              
79             my @glob;
80             push @glob, +{title => $title};
81             push @glob, +{link => +{href => $page}};
82             push @glob, +{summary => $descr};
83             my $entry = +{cho_author => \@glob, _base => $self->_baseItem(\%args)};
84              
85             push @{$self->{GMA_entries}}, $entry;
86             $entry;
87             }
88              
89             #----------------
90              
91             sub _write($$)
92             { my ($self, $fn, $args) = @_;
93             my $format = $args->{beautify} || 0;
94             my $doc = $args->{doc};
95              
96             my $root = $self->schemas->writer('feed')->($doc, $args->{feed});
97             $root->setNamespace(NS_GOOGLE_BASE10, 'g', 0);
98             $root->setNamespace(NS_GOOGLE_CUSTOM10, 'c', 0);
99             $doc->setDocumentElement($root);
100             $doc->setCompression($args->{gzip}) if defined $args->{gzip};
101             $doc->toFile($fn, $format);
102             $self;
103             }
104              
105             # Hook, because textType is mixed!
106             sub _write_texttype($$$$$)
107             { my ($self, $doc, $val, $path, $tag, $r) = @_;
108             my ($text, %attr);
109             if(ref $val eq 'HASH')
110             { %attr = %$val;
111             $text = delete $attr{_};
112             }
113             else
114             { $text = $val;
115             }
116              
117             # Clean to use 'type' in atom elements, however the google server
118             # confuses this with its own "type" attributes.
119             # $attr{type} ||= lc $self->stringFormat;
120              
121             my $xml = $r->($doc, \%attr);
122             $xml->appendText(encode 'utf8', $text);
123             $xml;
124             }
125              
126             sub _write_entrytype($$$$$)
127             { my ($self, $doc, $val, $path, $tag, $r) = @_;
128             my $base = $self->_write_base_entry($doc, delete $val->{_base});
129             my $node = $r->($doc, $val);
130             $node->appendChild($_) for $base->childNodes;
131              
132             # The xmlns:g is lost here, added globally
133             $node;
134             }
135              
136             1;