File Coverage

blib/lib/Novel/Robot/Packer.pm
Criterion Covered Total %
statement 45 84 53.5
branch 7 32 21.8
condition 3 21 14.2
subroutine 12 15 80.0
pod 2 8 25.0
total 69 160 43.1


line stmt bran cond sub pod time code
1             # ABSTRACT: pack novel/bbs content to ebook
2             package Novel::Robot::Packer;
3 2     2   20 use strict;
  2         6  
  2         97  
4 2     2   12 use warnings;
  2         5  
  2         57  
5 2     2   13 use utf8;
  2         5  
  2         11  
6 2     2   919 use Encode::Locale;
  2         6061  
  2         125  
7 2     2   14 use Encode;
  2         4  
  2         153  
8 2     2   13 use File::Temp qw/tempfile /;
  2         4  
  2         88  
9 2     2   1043 use Template;
  2         38470  
  2         24  
10              
11             #our $VERSION = 0.21;
12              
13             sub new {
14 2     2 1 98 my ( $self, %opt ) = @_;
15              
16 2   50     9 $opt{type} ||= 'html';
17              
18 2         31 bless {%opt}, __PACKAGE__;
19             }
20              
21             sub set_type {
22 1     1 0 5 my ( $self, $output, $o ) = @_;
23              
24 1 50 33     8 if ( exists $o->{type} ) {
    50          
25 0         0 return $o->{type};
26             } elsif ( defined $output
27             and ( !exists $o->{output_scalar} ) ) {
28 0         0 ( $o->{type} ) = $output =~ m#\.([^.]+)$#;
29             } else {
30 1         3 $o->{type} = 'html';
31             }
32              
33 1         3 return $o->{type};
34             }
35              
36             sub detect_writer_book_type {
37 0     0 0 0 my ( $self, $input, $o ) = @_;
38              
39 0         0 $input = decode( locale => $input );
40 0         0 my ( $writer, $book, $type ) = $input =~ /([^\\\/]+?)-([^\\\/]+?)\.([^.\\\/]+)$/;
41              
42 0 0       0 $writer = $o->{writer} if ( defined $o->{writer} );
43 0   0     0 $writer //= '';
44              
45 0 0       0 $book = $o->{book} if ( defined $o->{book} );
46 0   0     0 $book //= '';
47              
48 0         0 return ( $writer, $book, $type );
49             }
50              
51             sub convert_novel {
52 0     0 0 0 my ( $self, $input, $output, $o ) = @_;
53              
54 0 0 0     0 return $input unless ( -f $input and -s $input );
55              
56 0         0 my ( $writer, $book, $in_type ) = $self->detect_writer_book_type( $input, $o );
57              
58 0 0       0 if ( !defined $output ) {
59 0         0 $output = $input;
60 0         0 $output =~ s/\.([^.]+)$/.$o->{type}/;
61             }
62 0 0       0 return $input if ( $output eq $input );
63              
64 0         0 my ( $out_type ) = $output =~ m#\.([^.]+)$#;
65              
66 0         0 my %conv = (
67             'authors' => $writer,
68             'author-sort' => $writer,
69             'title' => $book,
70             'chapter-mark' => "none",
71             'page-breaks-before' => "/",
72             'max-toc-links' => 0,
73             );
74              
75 0         0 my $conv_str = join( " ", map { qq[--$_ "$conv{$_}"] } keys( %conv ) );
  0         0  
76 0 0       0 if ( $o->{type} =~ /\.epub$/ ) {
    0          
77 0         0 $conv_str .= " --dont-split-on-page-breaks ";
78             } elsif ( $o->{type} =~ /\.mobi$/ ) {
79 0         0 $conv_str .= " --mobi-keep-original-images ";
80             }
81              
82 0         0 $conv_str = encode( locale => $conv_str );
83 0         0 my $cmd = qq[ebook-convert "$input" "$output" $conv_str];
84              
85             #system( $cmd);
86 0         0 `$cmd`;
87              
88 0         0 return $output;
89             } ## end sub convert_novel
90              
91             sub main {
92 1     1 1 22 my ( $self, $book_ref, $o ) = @_;
93              
94 1         8 $self->set_type( $o->{output}, $o );
95 1         23 $self->format_item_output( $book_ref, $o );
96              
97 1 50 33     6 if ( $o->{type} ne 'html' and ( !exists $o->{output_scalar} ) ) {
98 0         0 my ( $fh, $html_f ) = tempfile( "run_novel-html-XXXXXXXXXXXXXX", TMPDIR => 1, SUFFIX => ".html" );
99 0         0 $self->process_html_template( $book_ref, $html_f, $o );
100 0         0 $self->convert_novel( $html_f, $o->{output}, { type => $o->{type}, writer => $book_ref->{writer}, book => $book_ref->{book} } );
101             } else {
102 1         5 $self->process_html_template( $book_ref, $o->{output}, $o );
103             }
104              
105 1         75 return $o->{output};
106             }
107              
108             sub format_item_output {
109 1     1 0 3 my ( $self, $book_ref, $o ) = @_;
110 1 50       5 if ( !$o->{output} ) {
111 1         2 my $html = '';
112             $o->{output} =
113             exists $o->{output_scalar}
114 1 50       5 ? \$html
115             : $self->format_default_filename( $book_ref, $o );
116             }
117 1         2 return $o->{output};
118             }
119              
120             sub format_default_filename {
121 0     0 0 0 my ( $self, $r, $o ) = @_;
122              
123 0         0 my $item_info = '';
124 0 0 0     0 if ( exists $o->{min_item_num} and $o->{min_item_num} > 1 ) {
    0 0        
125 0         0 $item_info = "-$o->{min_item_num}";
126             } elsif ( exists $o->{min_page_num} and $o->{min_page_num} > 1 ) {
127 0         0 $item_info = "-$o->{min_page_num}";
128             }
129 0         0 my $f = "$r->{writer}-$r->{book}$item_info." . $o->{type};
130 0         0 $f =~ s{[\[\]/><\\`;'\$^*\(\)\%#@!"&:\?|\s^,~]}{}g;
131 0         0 return encode( locale => $f );
132             }
133              
134             sub process_html_template {
135 1     1 0 3 my ( $self, $book_ref, $dst, $o ) = @_;
136              
137             my $toc = $o->{with_toc}
138 1 50       5 ? qq{
139             [% FOREACH r IN item_list %]
140             [% IF r.content %]
  • [% r.id %]. [% r.writer %] [% r.title %]
  • [% END %]
    141             [% END %]
    142            
    143             }
    144             : '';
    145              
    146 1         7 my $txt = <<__HTML__;
    147            
    148            
    149              
    150            
    151            
    152            
    153            
    154             [% writer %] 《 [% book %] 》
    155            
    173            
    174              
    175            
    176            
    177             $toc
    178            
    179             [% FOREACH r IN item_list %]
    180             [% IF r.content %]
    181            
    182            
    [% r.id %]. [% r.writer %] [% r.title %] [% r.time %]
    183            
    [% r.content %]
    184             [% END %]
    185             [% END %]
    186            
    187            
    188            
    189             __HTML__
    190 1         32 my $tt = Template->new();
    191 1 50       24770 $tt->process( \$txt, $book_ref, $dst, { binmode => ':utf8' } ) || die $tt->error(), "\n";
    192 1         49917 return $dst;
    193             } ## end sub process_html_template
    194              
    195             1;
    196