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 %] |
||||||
141 | [% END %] | ||||||
142 | |||||||
143 | } | ||||||
144 | : ''; | ||||||
145 | |||||||
146 | 1 | 7 | my $txt = <<__HTML__; | ||||
147 | |||||||
148 | |||||||
149 | |||||||
150 | |||||||
151 | |||||||
152 | |||||||
153 | |||||||
154 | |
||||||
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 |