File Coverage

blib/lib/XML/GSA.pm
Criterion Covered Total %
statement 24 81 29.6
branch 0 18 0.0
condition 0 11 0.0
subroutine 8 20 40.0
pod 12 12 100.0
total 44 142 30.9


line stmt bran cond sub pod time code
1             package XML::GSA;
2              
3 1     1   62789 use strict;
  1         5  
  1         95  
4 1     1   7 use warnings;
  1         2  
  1         46  
5              
6 1     1   2355 use XML::Writer;
  1         25375  
  1         224  
7 1     1   1444 use Data::Dumper;
  1         10576  
  1         93  
8 1     1   10 use Carp;
  1         3  
  1         63  
9 1     1   1534 use DateTime ();
  1         232889  
  1         56  
10 1     1   996 use Date::Parse ();
  1         9983  
  1         33  
11 1     1   809 use XML::GSA::Group;
  1         4  
  1         879  
12              
13             sub new {
14 0     0 1   my $class = shift;
15              
16 0   0       return bless {
17             'type' => 'incremental',
18             'datasource' => 'web',
19             @_,
20             'groups' => [],
21             'encoding' => 'UTF-8', #read-only
22             },
23             ref $class || $class;
24             }
25              
26             #encoding is read-only
27             sub encoding {
28 0     0 1   my $self = shift;
29              
30 0           return $self->{'encoding'};
31             }
32              
33             #getters
34             sub xml {
35 0     0 1   my $self = shift;
36              
37 0           return $self->{'xml'};
38             }
39              
40             sub to_string {
41 0     0 1   my $self = shift;
42              
43 0           return $self->{'xml'};
44             }
45              
46             sub writer {
47 0     0 1   my $self = shift;
48              
49 0           return $self->{'writer'};
50             }
51              
52             #getters and setters
53             sub type {
54 0     0 1   my ( $self, $value ) = @_;
55              
56 0 0 0       $self->{'type'} = $value
57             if $value && $value =~ /(incremental|full|metadata-and-url)/;
58              
59 0           return $self->{'type'};
60             }
61              
62             sub datasource {
63 0     0 1   my ( $self, $value ) = @_;
64              
65 0 0         $self->{'datasource'} = $value
66             if $value;
67              
68 0           return $self->{'datasource'};
69             }
70              
71             sub base_url {
72 0     0 1   my ( $self, $value ) = @_;
73              
74 0 0         $self->{'base_url'} = $value
75             if $value;
76              
77 0           return $self->{'base_url'};
78             }
79              
80             sub groups {
81 0     0 1   my $self = shift;
82              
83 0   0       return $self->{'groups'} || [];
84             }
85              
86             sub add_group {
87 0     0 1   my ( $self, $value ) = @_;
88              
89 0 0 0       unless ( ref $value eq 'HASH' || ref $value eq 'XML::GSA::Group' ) {
90 0           carp("Must receive an HASH ref or an XML::GSA::Group object");
91 0           return;
92             }
93              
94 0 0         my $group
95             = ref $value eq 'HASH'
96             ? XML::GSA::Group->new(
97             'action' => $value->{'action'},
98             'records' => $value->{'records'}
99             )
100             : $value;
101              
102 0           push @{ $self->groups }, $group;
  0            
103             }
104              
105             #empties the group arrayref
106             sub clear_groups {
107 0     0 1   my $self = shift;
108              
109 0           $self->{'groups'} = [];
110             }
111              
112             sub create {
113 0     0 1   my ( $self, $data ) = @_;
114              
115             #use $self->groups
116 0 0         if ( !defined $data ) {
117 0           $data = $self->groups();
118             }
119             else { #add each structure as new group, emptying the existing groups
120 0 0         unless ( ref $data eq 'ARRAY' ) {
121 0           carp("An array data structure must be passed as parameter");
122 0           return;
123             }
124              
125 0           $self->clear_groups();
126             }
127              
128 0           my $writer = XML::Writer->new( OUTPUT => 'self', 'UNSAFE' => 1 );
129 0           $self->{'writer'} = $writer;
130              
131 0           $self->writer->xmlDecl( $self->encoding );
132 0           $self->writer->doctype( "gsafeed", '-//Google//DTD GSA Feeds//EN', "" );
133              
134 0           $self->writer->startTag('gsafeed');
135 0           $self->writer->startTag('header');
136 0           $self->writer->dataElement( 'datasource', $self->datasource() );
137 0           $self->writer->dataElement( 'feedtype', $self->type() );
138 0           $self->writer->endTag('header');
139              
140 0 0         for my $group ( @{ $data || [] } ) {
  0            
141              
142             #if not group, add it as one
143 0 0         unless ( ref $group eq 'XML::GSA::Group' ) {
144              
145 0           $group = XML::GSA::Group->new(
146             'action' => $group->{'action'},
147             'records' => $group->{'records'}
148             );
149             }
150 0           $group->create($self);
151              
152 0           $self->writer->raw( $group->to_string );
153             }
154              
155 0           $self->writer->endTag('gsafeed');
156              
157 0           my $xml = $self->writer->to_string;
158              
159             #gsa needs utf8 encoding
160 0           utf8::encode($xml);
161              
162 0           $self->{'xml'} = $xml;
163 0           return $xml;
164             }
165              
166             1;
167              
168             =head1 NAME
169              
170             XML::GSA - Creates xml in google search appliance (GSA) format
171              
172             =head1 VERSION
173              
174             Version 0.07
175              
176             =cut
177              
178             our $VERSION = '0.07';
179              
180             =head1 SYNOPSIS
181              
182             This is a lib that allows one to create xml in Google Search Appliance (GSA) format.
183              
184             You can use this lib in the following way:
185              
186             use XML::GSA;
187              
188             my $gsa = XML::GSA->new('base_url' => 'http://foo.bar');
189             my $xml = $gsa->create(
190             [ { 'action' => 'add',
191             'records' => [
192             { 'url' => '/aaa',
193             'mimetype' => 'text/plain',
194             'action' => 'delete',
195             },
196             { 'url' => '/bbb',
197             'mimetype' => 'text/plain',
198             'metadata' => [
199             { 'name' => 'og:title', 'content' => 'BBB' },
200             ],
201             }
202             ],
203             },
204             ]
205             );
206             print $xml;
207              
208             Which will output:
209              
210            
211            
212            
213            
214             Source
215             incremental
216            
217            
218            
219            
220            
221            
222            
223            
224            
225            
226              
227             =head1 METHODS
228              
229             =head2 new( C<$params> )
230              
231             Create a new XML::GSA object:
232              
233             my $gsa = XML::GSA->new('base_url' => 'http://foo.bar');
234              
235             Arguments of this method are an anonymous hash of parameters:
236              
237             =head3 datasource
238              
239             Defines the datasource to be included in the header of the xml.
240              
241             =head3 type
242              
243             Defines the type of the feed. This attribute tells the feed what kind of attributes the records are able to receive.
244              
245             =head3 base_url
246              
247             Defines a base url to be preppended to all records' urls.
248              
249             =cut
250              
251             =head2 type( C<$value> )
252              
253             Getter/setter for the type attribute of GSA feed. By default it is 'incremental'.
254             Possible values are 'incremental', 'full' or 'metadata-and-url'
255              
256             =cut
257              
258             =head2 datasource( C<$value> )
259              
260             Getter/setter for the datasource attribute of GSA feed. By default it is 'web'.
261              
262             =cut
263              
264             =head2 base_url( C<$value> )
265              
266             Getter/setter for the base_url attribute of GSA feed. This is an url that will be preppended to all record urls. If a base_url is not defined, one must pass full urls in the records data structure.
267              
268             =cut
269              
270             =head2 create( C<$data> )
271              
272             Receives an arrayref data structure where each entry represents a group in the xml, generates an xml in GSA format and returns it as a string.
273             Important note: All data passed to create must be in unicode! This class will utf-8 encode it making it compatible with GSA.
274              
275             One can have has many group has one wants, and a group is an hashref with an optional key 'action' and a mandatory key 'records'. The key 'action' can have the values of 'add' or 'delete' and the 'records' key is an array of hashrefs.
276              
277             Each hashref in the array corresponding to 'records' can have the following keys:
278              
279             * Mandatory
280             * url
281             * mimetype => (text/plain|text/html) - in the future it will also support other mimetype
282             * Optional
283             * action => (add|delete)
284             * lock => (true|false)
285             * displayurl => an url
286             * last-modified => a well formatted date as string
287             * authmethod => (none|httpbasic|ntlm|httpsso)
288             * pagerank => an int number
289             * crawl-immediately => (true|false)
290             * crawl-once => (true|false)
291              
292             =cut
293              
294             =head2 create
295              
296             Creates the xml using the groups already added to the object.
297              
298             =head2 add_group( C<$group> )
299              
300             Receives an hashref data structure representing a group and adds it to the current feed - you must call the `create` method with no arguments to have the xml updated. A group is an hashref with an optional key 'action' and a mandatory key 'records'. The key 'action' can have the values of 'add' or 'delete' and the 'records' key is an array of hashrefs.
301              
302             Each hashref in the array corresponding to 'records' can have the following keys:
303              
304             * Mandatory
305             * url
306             * mimetype => (text/plain|text/html) - in the future it will also support other mimetype
307             * Optional
308             * action => (add|delete)
309             * lock => (true|false)
310             * displayurl => an url
311             * last-modified => a well formatted date as string
312             * authmethod => (none|httpbasic|ntlm|httpsso)
313             * pagerank => an int number
314             * crawl-immediately => (true|false)
315             * crawl-once => (true|false)
316              
317             Important note: All data passed must be in unicode! This class will utf-8 encode it making it compatible with GSA.
318              
319             =head2 add_group( C<$group> )
320              
321             Receives an instance of the class XML::GSA::Group and adds it to the current feed - you must call the `create` method with no arguments to have the xml updated.
322              
323             =head2 clear_groups
324              
325             Empties the property `groups` of this class.
326              
327             =head2 xml
328              
329             Getter for the xml generated by the `create` method.
330              
331             =head2 to_string
332              
333             Getter for the xml generated by the `create` method.
334              
335             =head2 encoding
336              
337             Getter for the encoding used in this class
338              
339             =head2 groups
340              
341             Getter for the array of groups added to this class
342              
343             =head2 writer
344              
345             Getter for the XML::Writer object used in this class to create the xml
346              
347             =cut
348              
349             =head1 AUTHOR
350              
351             Shemahmforash, C<< >>
352              
353             =head1 BUGS
354              
355             Please report any bugs or feature requests to C, or through
356             the web interface at L. I will be notified, and then you'll
357             automatically be notified of progress on your bug as I make changes.
358              
359              
360              
361              
362             =head1 SUPPORT
363              
364             You can find documentation for this module with the perldoc command.
365              
366             perldoc XML::GSA
367              
368              
369             You can also look for information at:
370              
371             =over 4
372              
373             =item * RT: CPAN's request tracker (report bugs here)
374              
375             L
376              
377             =item * AnnoCPAN: Annotated CPAN documentation
378              
379             L
380              
381             =item * CPAN Ratings
382              
383             L
384              
385             =item * Search CPAN
386              
387             L
388              
389             =item * Github Repository
390              
391             L
392              
393             =back
394              
395             =head1 LICENSE AND COPYRIGHT
396              
397             Copyright 2013-2014 Shemahmforash.
398              
399             This program is free software: you can redistribute it and/or modify
400             it under the terms of the GNU General Public License as published by
401             the Free Software Foundation, either version 3 of the License, or
402             (at your option) any later version.
403              
404             This program is distributed in the hope that it will be useful,
405             but WITHOUT ANY WARRANTY; without even the implied warranty of
406             MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
407             GNU General Public License for more details.
408              
409             You should have received a copy of the GNU General Public License
410             along with this program. If not, see L.
411              
412              
413             =cut