File Coverage

blib/lib/EBook/Ishmael/EBook/CB.pm
Criterion Covered Total %
statement 100 105 95.2
branch 11 20 55.0
condition 4 14 28.5
subroutine 20 23 86.9
pod 0 11 0.0
total 135 173 78.0


line stmt bran cond sub pod time code
1             package EBook::Ishmael::EBook::CB;
2 17     17   9221 use 5.016;
  17         64  
3             our $VERSION = '2.03';
4 17     17   99 use strict;
  17         33  
  17         707  
5 17     17   113 use warnings;
  17         45  
  17         1012  
6              
7 17     17   128 use File::Basename;
  17         49  
  17         2268  
8 17     17   110 use File::Spec;
  17         37  
  17         542  
9 17     17   8873 use File::Which;
  17         26609  
  17         1240  
10 17     17   144 use List::Util qw(max);
  17         35  
  17         1164  
11              
12 17     17   10910 use EBook::Ishmael::Dir;
  17         1654  
  17         1300  
13 17     17   8697 use EBook::Ishmael::ImageID qw(image_path_id);
  17         79  
  17         1603  
14 17     17   11239 use EBook::Ishmael::EBook::Metadata;
  17         79  
  17         908  
15 17     17   9898 use EBook::Ishmael::Unzip qw(safe_tmp_unzip);
  17         72  
  17         20791  
16              
17             # Not an ebook format itself, just a base class from which actual comic book
18             # archives derive themselves.
19              
20 0     0 0 0 sub heuristic { 0 }
21              
22             sub _images {
23              
24 20     20   53 my $dir = shift;
25              
26 20         36 my @img;
27              
28 20         92 for my $f (dir($dir)) {
29 290 100       5440 if (-d $f) {
    50          
30 10         45 push @img, _images($f);
31             } elsif (-f $f) {
32 280         756 my $format = image_path_id($f);
33 280 50       563 next if not defined $format;
34 280         755 push @img, [ $f, $format ];
35             }
36             }
37              
38 20         133 return @img;
39              
40             }
41              
42             sub new {
43              
44 10     10 0 23 my $class = shift;
45 10         25 my $file = shift;
46              
47 10         113 my $self = {
48             Source => undef,
49             Metadata => EBook::Ishmael::EBook::Metadata->new,
50             _images => [],
51             _tmpdir => undef,
52             };
53              
54 10         26 bless $self, $class;
55              
56 10         481 my $title = (fileparse($file, qr/\.[^.]*/))[0];
57              
58 10         397 $self->{Source} = File::Spec->rel2abs($file);
59              
60 10         63 $self->{_tmpdir} = safe_tmp_unzip;
61 10         5850 $self->extract($self->{_tmpdir});
62              
63 10         64 @{ $self->{_images} } = _images($self->{_tmpdir});
  10         55  
64              
65 10 50       24 unless (@{ $self->{_images} }) {
  10         77  
66 0         0 die "$self->{Source}: Found no images in comic book archive\n";
67             }
68              
69 10         103 $self->{Metadata}->set_title($title);
70 10         262 $self->{Metadata}->set_modified((stat $self->{Source})[9]);
71 10         97 $self->{Metadata}->set_format($self->format);
72              
73 10         63 return $self;
74              
75             }
76              
77             sub extract {
78 0     0 0 0 die sprintf "%s does not implement the extract() method\n", __PACKAGE__;
79             }
80              
81 0     0 0 0 sub format { undef }
82              
83             # Comic Book archives have no HTML
84             sub html {
85              
86 3     3 0 7 my $self = shift;
87 3         8 my $out = shift;
88              
89 3         9 my $html = '';
90              
91 3 50 0     58 open my $fh, '>', $out // \$html
      50        
92             or die sprintf "Failed to open %s for writing: $!\n", $out // 'in-memory scalar';
93              
94 3         9 print { $fh } '';
  3         13  
95              
96 3         13 close $fh;
97              
98 3   33     510 return $out // $html;
99              
100             }
101              
102             # ... or text of any kind
103             sub raw {
104              
105 3     3 0 7 my $self = shift;
106 3         8 my $out = shift;
107              
108 3         8 my $raw = '';
109              
110 3 50 0     44 open my $fh, '>', $out // \$raw
      50        
111             or die sprintf "Failed to open %s for writing: $!\n", $out // 'in-memory scalar';
112              
113 3         8 print { $fh } '';
  3         7  
114              
115 3         11 close $fh;
116              
117 3   33     25 return $out // $raw;
118              
119             }
120              
121             sub metadata {
122              
123 6     6 0 1607 my $self = shift;
124              
125 6         38 return $self->{Metadata};
126              
127             }
128              
129             sub has_cover {
130              
131 4     4 0 1322 my $self = shift;
132              
133 4         9 return !! scalar @{ $self->{_images} };
  4         29  
134              
135             }
136              
137             sub cover {
138              
139 2     2 0 6 my $self = shift;
140              
141 2 50       9 return (undef, undef) unless $self->has_cover;
142              
143 2 50       137 open my $fh, '<', $self->{_images}[0][0]
144             or die "Failed to open $self->{_images}[0][0] for reading: $!\n";
145 2         11 binmode $fh;
146 2         4 my $img = do { local $/; readline $fh };
  2         14  
  2         94  
147 2         28 close $fh;
148              
149 2         19 return ($img, $self->{_images}[0][1]);
150              
151             }
152              
153             sub image_num {
154              
155 58     58 0 1044 my $self = shift;
156              
157 58         140 return scalar @{ $self->{_images} };
  58         290  
158              
159             }
160              
161             sub image {
162              
163 56     56 0 32694 my $self = shift;
164 56         117 my $n = shift;
165              
166 56 50       192 if ($n >= $self->image_num) {
167 0         0 return (undef, undef);
168             }
169              
170 56 50       3375 open my $fh, '<', $self->{_images}[$n][0]
171             or die "Failed to open $self->{_images}[$n][0] for reading: $!\n";
172 56         205 binmode $fh;
173 56         103 my $img = do { local $/; readline $fh };
  56         299  
  56         4144  
174 56         999 close $fh;
175              
176 56         707 return ($img, $self->{_images}[$n][1]);
177              
178             }
179              
180             1;