File Coverage

lib/PDF/Burst.pm
Criterion Covered Total %
statement 79 140 56.4
branch 29 76 38.1
condition 8 41 19.5
subroutine 13 15 86.6
pod 4 6 66.6
total 133 278 47.8


line stmt bran cond sub pod time code
1             package PDF::Burst;
2 5     5   90868 use strict;
  5         10  
  5         184  
3 5     5   27 use vars qw($VERSION @ISA @EXPORT_OK %EXPORT_TAGS $errstr $BURST_METHOD @BURST_METHODS %BURST_METHOD $DEBUG);
  5         10  
  5         1140  
4             @ISA = qw/Exporter/;
5             @EXPORT_OK = qw/pdf_burst pdf_burst_CAM_PDF pdf_burst_PDF_API2 pdf_burst_pdftk/;
6             $VERSION = sprintf "%d.%02d", q$Revision: 1.20 $ =~ /(\d+)/g;
7             %EXPORT_TAGS = ( all => \@EXPORT_OK );
8 5     5   27 use Exporter;
  5         19  
  5         226  
9 5     5   3849 use File::Which;
  5         4973  
  5         291  
10 5     5   27 use Carp;
  5         9  
  5         7156  
11             sub errstr;
12 0     0 0 0 sub errstr { $errstr =$_[0]; 1 }
  0         0  
13 138 50   138 0 17800 sub debug { $DEBUG and warn(" # ".__PACKAGE__.", @_\n"); 1 }
  138         403  
14              
15             %BURST_METHOD = (
16             CAM_PDF => \&pdf_burst_CAM_PDF,
17             PDF_API2 => \&pdf_burst_PDF_API2,
18             pdftk => \&pdf_burst_pdftk,
19             );
20             @BURST_METHODS= keys %BURST_METHOD;
21             $BURST_METHOD ||= 'CAM_PDF';
22              
23             #*pdf_burst = \&pdf_burst_CAM_PDF;
24             # *pdf_burst = \&pdf_burst_PDF_API2;
25              
26              
27 8     8 1 2974 sub pdf_burst { &{$BURST_METHOD{$BURST_METHOD}}(@_) }
  8         77  
28              
29              
30             sub _args {
31 12     12   90 my ($_path, $groupname, $_abs_loc)= @_;
32 12 50       62 $_path or croak('missing args');
33              
34 12 100 50     71 my($abs, $abs_loc, $filename, $filename_only, $ext ) = _path_segments($_path)
35             or warn("Cant make sense of path segments for '$_path'")
36             and return;
37            
38 10 100       42 if ($_abs_loc){
39 3 50 0     71 -d $_abs_loc
40             or $errstr="argument $_abs_loc abs loc not on disk"
41             and return;
42 3         17 $abs_loc = $_abs_loc;
43             }
44            
45              
46 10   66     73 $groupname ||= $filename_only;
47 10 50 0     87 $groupname=~/\w/
48             or warn("groupname '$groupname' makes no sense.")
49             and return;
50              
51 10 50 0     60 $ext=~/\.pdf$/i
52             or $errstr = "$abs not pdf?"
53             and return;
54            
55             ### $abs
56             ### $abs_loc
57             ### $filename
58             ### $filename_only
59             ### $ext
60            
61 10         108 return ($abs,$abs_loc,$filename,$filename_only, $ext, $groupname);
62             }
63              
64              
65              
66             # there HAS to be a more effective way of using CAM::PDF than to instance
67             # each time for each page from original doc!!1
68             sub pdf_burst_CAM_PDF {
69              
70 10 100   10 1 261 my ($abs,$abs_loc,$filename,$filename_only, $ext, $groupname) = _args(@_)
71             or return;
72              
73              
74 8         18 my @abs_page_files;
75              
76 8         15837 require CAM::PDF;
77 8 50 0     188202 my $pdfold = CAM::PDF->new($abs)
78             or $errstr="CAM_PDF: could not open $abs"
79             and return;
80              
81 8         42481 my $pagecount = $pdfold->numPages;
82 8         96 debug("CAM_PDF: pagecount $pagecount");
83 8         21 undef $pdfold;
84              
85              
86 8 50       523 if ( $pagecount == 1 ){
    50          
87 0         0 my $abs_page = "$abs_loc/$groupname\_page_0001$ext";
88 0         0 require File::Copy;
89 0         0 unlink $abs_page;
90 0 0 0     0 File::Copy::cp($abs, $abs_page)
91             or $errstr="CAM_PDF: cant copy $abs to $abs_page, $!"
92             and return;
93 0         0 return ($abs_page);
94             }
95             elsif( $pagecount == 0 ){
96 0         0 $errstr="CAM_PDF: file $abs has no pages ?!";
97 0         0 return ();
98             }
99              
100              
101 8         42 for my $index ( 0 .. ( $pagecount - 1 ) ){
102              
103 42         278 my $index_human = sprintf '%04d', ($index + 1);
104             ### $index_human
105             ### $index
106              
107 42         197 my $abs_page = "$abs_loc/$groupname\_page_$index_human$ext";
108 42         221 debug("CAM_PDF: abs page will be: '$abs_page'.. ");
109              
110              
111              
112 42 50       643 my $pdf = CAM::PDF->new($abs) or confess("Could not CAM::PDF:: new '$abs'");
113 42         356997 debug("CAM_PDF: instanced CAM::PDF, will call extractPages() .. ");
114              
115 42         285 $pdf->extractPages($index + 1); # discard all but page x
116              
117 42         8682488 debug("CAM_PDF: calling cleansave().. ");
118 42         252 $pdf->cleansave; # rebuild pdf data
119 42         7011739 $pdf->output($abs_page);
120              
121 42 50 0     59894 -f $abs_page
122             or $errstr= "CAM_PDF: could not save? !-f $abs_page"
123             and return;
124              
125 42         45676 push @abs_page_files, $abs_page;
126            
127             }
128            
129 8         101 return @abs_page_files;
130             }
131              
132             sub _path_segments {
133 12     12   36 my $_abs = shift;
134 12 50       49 $_abs or croak('missing arg');
135              
136 12         184 require Cwd;
137 12 100 33     1089 my $abs = Cwd::abs_path($_abs)
      50        
138             or $errstr="$_abs not on disk? cant resolve with Cwd::abs_path"
139             and warn("$_abs not on disk")
140             and return;
141            
142 11 100 33     547 -f $abs
      50        
143             or $errstr="Path $abs not on disk."
144             and warn("path $abs not on disk")
145             and return;
146              
147 10 50 0     179 $abs=~/^(.+)\/+([^\/]+)(\.\w{1,5})$/i
148             or $errstr="cant match abs loc and filename into '$abs'"
149             and return;
150            
151 10         410 my ($abs_loc, $filename_only, $ext, $filename) = ( $1, $2, $3, $2.$3 );
152              
153 10         538 return($abs, $abs_loc,$filename,$filename_only,$ext);
154             }
155              
156              
157             sub pdf_burst_PDF_API2 {
158 1 50   1 1 1672 my ($abs,$abs_loc,$filename,$filename_only, $ext, $groupname) = _args(@_)
159             or return;
160              
161 1         3 my @abs_pages;
162              
163 1         1145 require PDF::API2;
164 1         421479 my $pdf_src = PDF::API2->open($abs);
165 1         21622 my $pagecount = $pdf_src->pages;
166            
167 1 50       45 if ( $pagecount == 1 ){
    50          
168 0         0 my $abs_page = "$abs_loc/$groupname\_page_0001$ext";
169 0         0 require File::Copy;
170 0         0 unlink $abs_page;
171 0 0       0 unless( File::Copy::cp($abs, $abs_page) ){
172 0         0 $errstr ="PDF_API2: cant copy $abs to $abs_page, $!";
173 0         0 return;
174             }
175 0         0 return ($abs_page);
176             }
177             elsif( $pagecount == 0 ){
178 0         0 $errstr="PDF_API2: file $abs has no pages ?!";
179 0         0 return ();
180             }
181              
182 1         5 for my $i ( 1 .. $pagecount ){
183 4         41 my $pdf_out = sprintf "$abs_loc/$groupname\_page_%04d$ext", $i;
184 4         21 debug("PDF_API2: $pdf_out");
185              
186 4         6 my $pdf;
187            
188 4 50       36 unless ( $pdf = PDF::API2->new ){
189 0         0 $errstr="PDF_API2: cant instance PDF::API";
190 0         0 return;
191             }
192              
193 4 50       3260 unless( $pdf->importpage( $pdf_src, $i )){
194 0         0 $errstr="PDF_API2: cannot import page, pdf error?";
195 0         0 return;
196             }
197            
198 4         37596 $pdf->saveas( $pdf_out );
199 4         39144 push @abs_pages, $pdf_out;
200              
201             }
202 1         11 return @abs_pages;
203             }
204              
205             sub pdf_burst_pdftk {
206 1 50   1 1 310102 my ($abs,$abs_loc,$filename,$filename_only, $ext, $groupname) = _args(@_)
207             or return;
208            
209 5     5   46 no warnings;
  5         7  
  5         4753  
210              
211 1         3 my @abs_pages;
212            
213 1 50 50     7 my $bin = File::Which::which('pdftk')
214             or $errstr="pdftk: Can't find which pdftk."
215             and return;
216              
217             # HACK #
218             # have to be in cwd to be able to get doc_dat.txt later
219             # pdftk will spit out doc_dat.txt to the cwd, must be set with chdir
220 0           require Cwd;
221 0           my $cwd = Cwd::cwd(); # so we can come back later.
222 0           chdir $abs_loc;
223              
224 0           my @args = ( $bin, $abs, 'burst', 'output', "$abs_loc/$groupname\_page_%04d.pdf");
225 0 0 0       system(@args) == 0
226             or $errstr="pdftk: fails: '@args'"
227             and return;
228            
229              
230              
231 0 0 0       opendir(DIR, $abs_loc)
232             or $errstr="pdftk: can't open $abs_loc, $!"
233             and return;
234              
235 0           @abs_pages = map { "$abs_loc/$_" }
  0            
236 0           sort grep { m/$groupname\_page\_\d+\.pdf$/i } readdir DIR;
237 0           closedir DIR;
238            
239 0           my $pgcount = scalar @abs_pages;
240              
241             # HACK ########################################################
242             # if there is a ./doc_dat.txt file
243             # test it against what we have for page count
244 0           my $doc_dat = "$abs_loc/doc_data.txt";
245 0 0         if ( my $dat = _pdf_burst_doc_dat_href($doc_dat) ){
246              
247 0 0         if ( defined $dat->{NumberOfPages} ){
248            
249 0 0         if( $pgcount != $dat->{NumberOfPages} ){
250 0           warn("We burst $abs into $pgcount docs, but pdftk doc_dat.txt says we are supposed to have $dat->{NumberOfPages} pages!");
251             }
252              
253 0 0         if ($pgcount < $dat->{NumberOfPages}){
    0          
254 0           warn("docs count is less than the number of pages pdftk says we should have.");
255              
256             }
257             elsif( $pgcount > $dat->{NumberOfPages} ){
258 0           warn("docs count is higher than the number of pages pdftk says we should have. Will shorten list.");
259 0           @abs_pages = @abs_pages[0 .. ( $dat->{NumberOfPages} - 1 )];
260             }
261             else {
262 0           debug("Checked with pdftk doc_dat.txt, correct number of pages.");
263             }
264             }
265             else {
266 0           warn("did not have 'NumberOfPages' in $doc_dat, different version of pdftk? Notify PDF::Burst AUTHOR");
267             }
268             }
269             else {
270 0           debug("got no doc_data.txt");
271             }
272              
273              
274             # HACK
275             # go back to what it was
276 0           chdir $cwd;
277              
278              
279 0           debug($_) for @abs_pages;
280              
281 0           return @abs_pages;
282             }
283              
284              
285              
286             # return hash ref
287             sub _pdf_burst_doc_dat_href {
288             # this is tricky, doc data will reside wherever the heck our cwd is
289              
290              
291 0     0     my $doc_dat = shift;
292 0 0         $doc_dat or croak("missing arg");
293 0 0         -f $doc_dat or return;
294              
295 0           debug("had '$doc_dat' file on disk");
296            
297 0           my %dat;
298            
299 0 0 0       open(FILE,'<',$doc_dat)
300             or warn("Cannot open '$doc_dat' for reading, $!")
301             and return;
302 0           while(my $line= ){
303 0           chomp $line;
304 0 0 0       $line=~/^(\w+)\W+(.+)$/
305             or warn("Cant make out line '$line' into key val pair")
306             and next;
307 0           $dat{$1}= $2;
308             }
309 0           close FILE;
310            
311 0 0 0       defined %dat or warn("had nothing in '$doc_dat'?") and return;
312 0           return \%dat;
313             }
314              
315              
316              
317             1;
318              
319              
320              
321              
322