File Coverage

blib/lib/EBook/Ishmael/EBook/CB.pm
Criterion Covered Total %
statement 104 109 95.4
branch 11 20 55.0
condition 7 24 29.1
subroutine 20 23 86.9
pod 0 11 0.0
total 142 187 75.9


line stmt bran cond sub pod time code
1             package EBook::Ishmael::EBook::CB;
2 17     17   9350 use 5.016;
  17         72  
3             our $VERSION = '2.01';
4 17     17   108 use strict;
  17         33  
  17         644  
5 17     17   84 use warnings;
  17         32  
  17         994  
6              
7 17     17   169 use File::Basename;
  17         48  
  17         2143  
8 17     17   138 use File::Spec;
  17         50  
  17         476  
9 17     17   8906 use File::Which;
  17         26725  
  17         1359  
10 17     17   133 use List::Util qw(max);
  17         53  
  17         1299  
11              
12 17     17   8007 use EBook::Ishmael::Dir;
  17         53  
  17         1088  
13 17     17   8424 use EBook::Ishmael::ImageID;
  17         66  
  17         1494  
14 17     17   10714 use EBook::Ishmael::EBook::Metadata;
  17         75  
  17         929  
15 17     17   8733 use EBook::Ishmael::Unzip qw(safe_tmp_unzip);
  17         76  
  17         21595  
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   48 my $dir = shift;
25              
26 20         46 my @img;
27              
28 20         99 for my $f (dir($dir)) {
29 290 100 33     5323 if (-d $f) {
    50          
30 10         46 push @img, _images($f);
31             } elsif (-f $f and is_image_path($f)) {
32 280         614 push @img, $f;
33             }
34             }
35              
36 20         221 return @img;
37              
38             }
39              
40             sub new {
41              
42 10     10 0 21 my $class = shift;
43 10         26 my $file = shift;
44              
45 10         93 my $self = {
46             Source => undef,
47             Metadata => EBook::Ishmael::EBook::Metadata->new,
48             _images => [],
49             _tmpdir => undef,
50             };
51              
52 10         28 bless $self, $class;
53              
54 10         549 my $title = (fileparse($file, qr/\.[^.]*/))[0];
55              
56 10         401 $self->{Source} = File::Spec->rel2abs($file);
57              
58 10         54 $self->{_tmpdir} = safe_tmp_unzip;
59 10         7796 $self->extract($self->{_tmpdir});
60              
61 10         62 @{ $self->{_images} } = _images($self->{_tmpdir});
  10         51  
62              
63 10 50       26 unless (@{ $self->{_images} }) {
  10         44  
64 0         0 die "$self->{Source}: Found no images in comic book archive\n";
65             }
66              
67 10         82 $self->{Metadata}->set_title($title);
68 10         267 $self->{Metadata}->set_modified((stat $self->{Source})[9]);
69 10         78 $self->{Metadata}->set_format($self->format);
70              
71 10         63 return $self;
72              
73             }
74              
75             sub extract {
76 0     0 0 0 die sprintf "%s does not implement the extract() method\n", __PACKAGE__;
77             }
78              
79 0     0 0 0 sub format { undef }
80              
81             # Comic Book archives have no HTML
82             sub html {
83              
84 3     3 0 8 my $self = shift;
85 3         9 my $out = shift;
86              
87 3         6 my $html = '';
88              
89 3 50 0     53 open my $fh, '>', $out // \$html
      50        
90             or die sprintf "Failed to open %s for writing: $!\n", $out // 'in-memory scalar';
91              
92 3         7 print { $fh } '';
  3         9  
93              
94 3         8 close $fh;
95              
96 3   33     36 return $out // $html;
97              
98             }
99              
100             # ... or text of any kind
101             sub raw {
102              
103 3     3 0 9 my $self = shift;
104 3         7 my $out = shift;
105              
106 3         8 my $raw = '';
107              
108 3 50 0     48 open my $fh, '>', $out // \$raw
      50        
109             or die sprintf "Failed to open %s for writing: $!\n", $out // 'in-memory scalar';
110              
111 3         9 print { $fh } '';
  3         9  
112              
113 3         9 close $fh;
114              
115 3   33     58 return $out // $raw;
116              
117             }
118              
119             sub metadata {
120              
121 6     6 0 1580 my $self = shift;
122              
123 6         35 return $self->{Metadata};
124              
125             }
126              
127             sub has_cover {
128              
129 6     6 0 15 my $self = shift;
130              
131 6         9 return !! scalar @{ $self->{_images} };
  6         29  
132              
133             }
134              
135             sub cover {
136              
137 4     4 0 9 my $self = shift;
138 4         9 my $out = shift;
139              
140 4 50       10 return undef unless $self->has_cover;
141              
142 4         9 my $img;
143              
144 4 50       184 open my $rh, '<', $self->{_images}[0]
145             or die "Failed to open $self->{_images}[0] for reading: $!\n";
146 4         14 binmode $rh;
147 4 50 0     48 open my $wh, '>', $out // \$img
      50        
148             or die sprintf "Failed to open %s for writing: $!\n", $out // 'in-memory scalar';
149 4         9 binmode $wh;
150              
151 4         7 print { $wh } do { local $/ = undef; readline $rh };
  4         8  
  4         22  
  4         187  
152              
153 4         45 close $rh;
154 4         11 close $wh;
155              
156 4   33     113 return $out // $img;
157              
158             }
159              
160             sub image_num {
161              
162 58     58 0 66 my $self = shift;
163              
164 58         78 return scalar @{ $self->{_images} };
  58         200  
165              
166             }
167              
168             sub image {
169              
170 56     56 0 19542 my $self = shift;
171 56         97 my $n = shift;
172              
173 56 50       105 if ($n >= $self->image_num) {
174 0         0 return undef;
175             }
176              
177 56 50       2072 open my $fh, '<', $self->{_images}[$n]
178             or die "Failed to open $self->{_images}[$n] for reading: $!\n";
179 56         131 binmode $fh;
180 56         66 my $img = do { local $/ = undef; readline $fh };
  56         223  
  56         1989  
181 56         434 close $fh;
182              
183 56         308 return \$img;
184              
185             }
186              
187             1;