File Coverage

blib/lib/EBook/EPUB/Metadata.pm
Criterion Covered Total %
statement 4 6 66.6
branch n/a
condition n/a
subroutine 2 2 100.0
pod n/a
total 6 8 75.0


line stmt bran cond sub pod time code
1             # Copyright (c) 2009, 2010 Oleksandr Tymoshenko <gonzo@bluezbox.com>
2             # All rights reserved.
3              
4             # Redistribution and use in source and binary forms, with or without
5             # modification, are permitted provided that the following conditions
6             # are met:
7             # 1. Redistributions of source code must retain the above copyright
8             # notice, this list of conditions and the following disclaimer.
9             # 2. Redistributions in binary form must reproduce the above copyright
10             # notice, this list of conditions and the following disclaimer in the
11             # documentation and/or other materials provided with the distribution.
12              
13             # THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
14             # ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
15             # IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
16             # ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
17             # FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
18             # DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
19             # OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
20             # HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
21             # LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
22             # OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
23             # SUCH DAMAGE.
24             package EBook::EPUB::Metadata;
25 1     1   2100 use Carp;
  1         3  
  1         90  
26 1     1   499 use Moose;
  0            
  0            
27             use EBook::EPUB::Metadata::DCItem;
28             use EBook::EPUB::Metadata::Item;
29              
30             has items => (
31             is => 'ro',
32             isa => 'ArrayRef[Object]',
33             default => sub { [] },
34             );
35              
36             has id_counter => (
37             is => 'rw',
38             isa => 'Int',
39             default => 0,
40             );
41              
42             has _book_id_item => (
43             is => 'rw',
44             isa => 'Ref',
45             );
46              
47             sub encode
48             {
49             my ($self, $writer) = @_;
50             $writer->startTag("metadata",
51             'xmlns:dc' => 'http://purl.org/dc/elements/1.1/',
52             'xmlns:opf' => 'http://www.idpf.org/2007/opf',
53             );
54            
55             foreach my $item (@{$self->items()}) {
56             $item->encode($writer);
57             }
58             my $id_item = $self->_book_id_item;
59             croak('No BookId specified by set_book_id') if (!defined($id_item));
60             $id_item->encode($writer);
61             $writer->endTag("metadata");
62             }
63              
64             sub add_title
65             {
66             my ($self, $title) = @_;
67             $self->add_meta_dcitem('title', $title);
68             }
69              
70             sub add_contributor
71             {
72             my ($self, $name, %opts) = @_;
73             my @args = ();
74             my $formal = $opts{'fileas'};
75             my $role = $opts{'role'};
76             if (defined($formal)) {
77             push @args, 'opf:file-as', $formal;
78             }
79             if (defined($role)) {
80             push @args, 'opf:role', $role;
81             }
82              
83             $self->add_meta_dcitem('contributor', $name, @args);
84             }
85              
86             sub add_creator
87             {
88             my ($self, $name, %opts) = @_;
89             my @args = ();
90             my $formal = $opts{'fileas'};
91             my $role = $opts{'role'};
92             if (defined($formal)) {
93             push @args, 'opf:file-as', $formal;
94             }
95             if (defined($role)) {
96             push @args, 'opf:role', $role;
97             }
98              
99             $self->add_meta_dcitem('creator', $name, @args);
100             }
101              
102             sub add_author
103             {
104             my ($self, $author, $formal) = @_;
105             $self->add_creator($author, fileas => $formal, role => 'aut');
106             }
107              
108             sub add_translator
109             {
110             my ($self, $name, $formal) = @_;
111             $self->add_creator($name, fileas => $formal, role => 'trl');
112             }
113              
114             sub add_subject
115             {
116             my ($self, $subject) = @_;
117             $self->add_meta_dcitem('subject', $subject);
118             }
119              
120             sub add_description
121             {
122             my ($self, $description) = @_;
123             $self->add_meta_dcitem('description', $description);
124             }
125              
126             sub add_date
127             {
128             # Todo: handle date format here
129             # http://www.idpf.org/2007/opf/OPF_2.0_final_spec.html#Section2.2.7
130             my ($self, $date, $event) = @_;
131             my @attr;
132             if (defined($event)) {
133             push @attr, "opf:event", $event;
134             }
135             $self->add_meta_dcitem('date', $date, @attr);
136             }
137              
138             sub add_type
139             {
140             my ($self, $type) = @_;
141             $self->add_meta_dcitem('type', $type);
142             }
143              
144             sub add_format
145             {
146             my ($self, $format) = @_;
147             $self->add_meta_dcitem('format', $format);
148             }
149              
150             sub add_publisher
151             {
152             my ($self, $publisher) = @_;
153             $self->add_meta_dcitem('publisher', $publisher);
154             }
155              
156             sub add_coverage
157             {
158             my ($self, $coverage) = @_;
159             $self->add_meta_dcitem('coverage', $coverage);
160             }
161              
162             sub set_book_id
163             {
164             my ($self, $book_id) = @_;
165             my @attr = ('id', 'BookId');
166             my $dcitem = EBook::EPUB::Metadata::DCItem->new(
167             name => "dc:identifier",
168             value => $book_id,
169             attributes => \@attr);
170              
171             $self->_book_id_item($dcitem);
172              
173             }
174              
175             sub add_identifier
176             {
177             my ($self, $ident, $scheme) = @_;
178             my $id = 'BookId';
179             # if it's urn:uuid - it should be BookId, otherwise include counter
180             if ($ident !~ /^urn:uuid/i) {
181             $id .= $self->id_counter;
182             $self->id_counter($self->id_counter + 1);
183             }
184              
185             my @attr = ('id', $id);
186             if (defined($scheme)) {
187             push @attr, "opf:scheme", $scheme;
188             }
189             $self->add_meta_dcitem('identifier', $ident, @attr);
190             }
191              
192             sub add_source
193             {
194             my ($self, $source) = @_;
195             $self->add_meta_dcitem('source', $source);
196             }
197              
198             sub add_language
199             {
200             # TODO: filter language?
201             my ($self, $lang) = @_;
202             $self->add_meta_dcitem('language', $lang);
203             }
204              
205             sub add_relation
206             {
207             my ($self, $relation) = @_;
208             $self->add_meta_dcitem('relation', $relation);
209             }
210              
211             sub add_rights
212             {
213             my ($self, $rights) = @_;
214             $self->add_meta_dcitem('rights', $rights);
215             }
216              
217             sub add_meta_dcitem
218             {
219             my ($self, $name, $value, @attributes) = @_;
220             my $dcitem = EBook::EPUB::Metadata::DCItem->new(
221             name => "dc:$name",
222             value => $value,
223             attributes => \@attributes);
224             push @{$self->items()}, $dcitem;
225             }
226              
227             sub add_meta_item
228             {
229             my ($self, $name, $value) = @_;
230             my $item = EBook::EPUB::Metadata::Item->new(
231             name => $name,
232             value => $value,
233             );
234             push @{$self->items()}, $item;
235             }
236              
237             no Moose;
238             __PACKAGE__->meta->make_immutable;
239              
240             1;
241              
242             __END__
243              
244             =head1 NAME
245              
246             EBook::EPUB::Metadata
247              
248             =head1 SYNOPSIS
249              
250             Class that represents B<metadata> element of OPF document. Provides information
251             about the publication as a whole
252              
253             =head1 SUBROUTINES/METHODS
254              
255             =over 4
256              
257             =item new()
258              
259             Create new object
260              
261             =item encode($xmlwriter)
262              
263             Encode object to XML form using XML::Writer instance
264              
265             =item add_author($name, [$formal_name])
266              
267             Add author of the document. For details see add_contributor.
268              
269             =item add_creator($name, [fileas =E<gt> $formal_name, role =E<gt> $role])
270              
271             Add primary creator or author of the publication of the publication. See
272             add_contributor for details
273              
274              
275             =item add_contributor($name, [fileas =E<gt> $formal_name, role =E<gt>])
276              
277             Add person/organization that contributed to publication. $name is the name in
278             human-readable form, e.g. "Arthur Conan Doyle", $formal_name is in form,
279             suitable for machine processing, e.g. "Doyle, Arthur Conan". $role reflects
280             kind of contribution to document. See Section 2.2.6 of OPF specification for
281             list of possible values L<http://www.idpf.org/2007/opf/OPF_2.0_final_spec.html#Section2.2.6>
282              
283              
284             =item add_coverage($coverage)
285              
286             The extent or scope of the content of the resource.
287              
288             =item add_date($date, [$event])
289              
290             Date of publication, in the format defined by "Date and Time Formats" at
291             http://www.w3.org/TR/NOTE-datetime and by ISO 8601 on which it is based. In
292             particular, dates without times are represented in the form YYYY[-MM[-DD]]: a
293             required 4-digit year, an optional 2-digit month, and if the month is given, an
294             optional 2-digit day of month. $event is an optional description of event that
295             date refers to. Possible values may include: creation, publication, and
296             modification.
297              
298             =item add_description($description)
299              
300             Add description of the publication content
301              
302             =item add_identifier($ident, [$scheme])
303              
304             Add unique identifier of the publication. $scheme is an optional paramater to
305             specify identification system of this particular identifier. e.g. ISBN, DOI
306              
307             =item add_meta_item($name, $value)
308              
309             Add metadata item that does not belong to Dublin Core specification. Metadata
310             is set by simple name/value pair.
311              
312             =item add_format($format)
313              
314             The media type or dimensions of the resource. Best practice is to use a value from a controlled vocabulary (e.g. MIME media types).
315              
316             =item add_language($lang)
317              
318             Add language of the content of the publication. $lang must comply with RFC 3066
319             (see http://www.ietf.org/rfc/rfc3066.txt)
320              
321             =item add_publisher($publisher)
322              
323             An entity responsible for making the resource available
324              
325             =item add_relation($relation)
326              
327             An identifier of an auxiliary resource and its relationship to the publication.
328              
329             =item add_rights($rights)
330              
331             A statement about rights, or a reference to one. In this specification, the copyright notice and any further rights description should appear directly.
332              
333             =item add_source($source)
334              
335             Information regarding a prior resource from which the publication was derived
336              
337             =item add_subject($subject)
338              
339             Add subject of the publication
340              
341             =item add_title($title)
342              
343             Add title of the publication
344              
345             =item add_translator($name, [$formal_name])
346              
347             Add translator of the document. $name is in human-readable form, e.g. "Arthur
348             Conan Doyle", $formal_name is in form, suitable for machine processing, e.g.
349             "Doyle, Arthur Conan"
350              
351             =item add_type($type)
352              
353             type includes terms describing general categories, functions, genres, or
354             aggregation levels for content. The advised best practice is to select a value
355             from a controlled vocabulary.
356              
357             =back
358              
359             =head1 AUTHOR
360              
361             Oleksandr Tymoshenko, E<lt>gonzo@bluezbox.comE<gt>
362              
363             =head1 BUGS
364              
365             Please report any bugs or feature requests to E<lt>gonzo@bluezbox.comE<gt>
366              
367             =head1 LICENSE AND COPYRIGHT
368              
369             Copyright 2009, 2010 Oleksandr Tymoshenko.
370              
371             L<http://bluezbox.com>
372              
373             This module is free software; you can redistribute it and/or
374             modify it under the terms of the BSD license. See the F<LICENSE> file
375             included with this distribution.