File Coverage

blib/lib/EBook/Gutenberg/Get.pm
Criterion Covered Total %
statement 26 42 61.9
branch 0 8 0.0
condition 0 5 0.0
subroutine 9 10 90.0
pod 2 2 100.0
total 37 67 55.2


line stmt bran cond sub pod time code
1             package EBook::Gutenberg::Get;
2 3     3   144577 use 5.016;
  3         12  
3             our $VERSION = '1.00';
4 3     3   41 use strict;
  3         5  
  3         95  
5 3     3   14 use warnings;
  3         4  
  3         157  
6              
7 3     3   15 use Exporter 'import';
  3         6  
  3         227  
8             our @EXPORT = qw(gutenberg_link gutenberg_get);
9              
10 3     3   653 use File::Copy;
  3         7544  
  3         225  
11 3     3   794 use File::Fetch;
  3         125644  
  3         98  
12 3     3   19 use File::Spec;
  3         5  
  3         82  
13 3     3   18 use File::Temp qw(tempdir);
  3         5  
  3         2433  
14              
15             our %FORMATS = (
16             'html' => {
17             link => sub {
18             "https://www.gutenberg.org/ebooks/$_[0].html.images"
19             },
20             suffix => 'html',
21             },
22             'epub3' => {
23             link => sub {
24             "https://www.gutenberg.org/ebooks/$_[0].epub3.images"
25             },
26             suffix => 'epub',
27             },
28             'epub' => {
29             link => sub {
30             "https://www.gutenberg.org/ebooks/$_[0].epub.images"
31             },
32             suffix => 'epub',
33             },
34             'epub-noimages' => {
35             link => sub {
36             "https://www.gutenberg.org/ebooks/$_[0].epub.noimages"
37             },
38             suffix => 'epub',
39             },
40             'kindle' => {
41             link => sub {
42             "https://www.gutenberg.org/ebooks/$_[0].kf8.images"
43             },
44             suffix => 'azw3',
45             },
46             'mobi' => {
47             link => sub {
48             "https://www.gutenberg.org/ebooks/$_[0].kindle.images"
49             },
50             suffix => 'mobi',
51             },
52             'text' => {
53             link => sub {
54             "https://www.gutenberg.org/ebooks/$_[0].txt.utf-8"
55             },
56             suffix => 'txt',
57             },
58             'zip' => {
59             link => sub {
60             "https://www.gutenberg.org/cache/epub/$_[0]/pg$_[0]-h.zip"
61             },
62             suffix => 'zip',
63             },
64             );
65              
66             sub gutenberg_link {
67              
68 8     8 1 263421 my $id = shift;
69 8         18 my $fmt = shift;
70              
71 8         38 return $FORMATS{ $fmt }->{ link }($id);
72              
73             }
74              
75             sub gutenberg_get {
76              
77 0     0 1   my $id = shift;
78 0           my $param = shift;
79              
80 0 0         unless ($id =~ /^\d+$/) {
81 0           die "id must be an integar\n";
82             }
83              
84 0   0       my $fmt = $param->{ fmt } // 'epub3';
85 0   0       my $to = $param->{ to } // "$id.*";
86              
87 0           $to =~ s/\.\*$/\.$FORMATS{ $fmt }->{ suffix }/;
88              
89 0 0         if (-d $to) {
90 0           die "Cannot download file to $to: is a directory\n";
91             }
92              
93 0           my $link = gutenberg_link($id, $fmt);
94              
95 0           my $tmp = tempdir(CLEANUP => 1);
96              
97 0           my $ff = File::Fetch->new(uri => $link);
98              
99 0 0         my $fetch = $ff->fetch(to => $tmp)
100             or die $ff->error;
101              
102 0 0         move($fetch, $to)
103             or die "Failed to move $fetch to $to: $!\n";
104              
105 0           rmdir $tmp;
106              
107 0           return $to;
108              
109             }
110              
111             1;
112              
113             =head1 NAME
114              
115             EBook::Gutenberg::Get - Fetch ebooks from Project Gutenberg
116              
117             =head1 SYNOPSIS
118              
119             use EBook::Gutenberg::Get;
120              
121             my $ebook = gutenberg_get($id);
122              
123             =head1 DESCRIPTION
124              
125             B is a module that provides some subroutines related to
126             downloading ebooks from Project Gutenberg. This is developer documentation,
127             for L user documentation you should consult its manual.
128              
129             Note that this module is not designed to perform bulk downloading/scraping.
130             Attempting to use this module to do so may result in Project Gutenberg banning
131             you from their site. You have been warned.
132              
133             =head1 SUBROUTINES
134              
135             The following subroutines are exported by C
136             automatically.
137              
138             =over 4
139              
140             =item $get = gutenberg_get($id, [\%param])
141              
142             Fetches an ebook from Project Gutenberg. C<$id> is the ID of the ebook to
143             fetch. C<\%params> is a hash ref of extra parameters to configure the download
144             process.
145              
146             The following are valid parameters:
147              
148             =over 4
149              
150             =item to
151              
152             Path to write downloaded file to. Defaults to C<'$id.*'>. If the provided path
153             has a C<'.*'> suffix, the C<'.*'> will be substituted by the ebook format's
154             file suffix.
155              
156             =item fmt
157              
158             Format of ebook to download. The following are valid options:
159              
160             =over 4
161              
162             =item html
163              
164             =item epub3
165              
166             =item epub
167              
168             =item epub-noimages
169              
170             =item kindle
171              
172             =item mobi
173              
174             =item text
175              
176             =item zip
177              
178             =back
179              
180             Defaults to C<'epub3'>.
181              
182             =back
183              
184             =item $link = gutenberg_link($id, $fmt)
185              
186             Returns the download link of an ebook. C<$id> is the ID of the ebook. C<$fmt>
187             is the ebook format.
188              
189             =back
190              
191             =head1 GLOBAL VARIABLES
192              
193             =over 4
194              
195             =item %EBook::Gutenberg::FORMATS
196              
197             Hash of valid ebook formats and a hash ref of some format data. See the
198             documentation for C in C for a list of ebook formats.
199              
200             The format hash ref has this format:
201              
202             =over 4
203              
204             =item link
205              
206             Subroutine reference that, when given an ebook ID, returns a download link to
207             that ebook.
208              
209             =item suffix
210              
211             The default file suffix to use with the format.
212              
213             =back
214              
215             =back
216              
217             =head1 AUTHOR
218              
219             Written by Samuel Young, Esamyoung12788@gmail.comE.
220              
221             This project's source can be found on its
222             L. Comments and pull
223             requests are welcome!
224              
225             =head1 COPYRIGHT
226              
227             Copyright (C) 2025 Samuel Young
228              
229             This program is free software: you can redistribute it and/or modify
230             it under the terms of the GNU General Public License as published by
231             the Free Software Foundation, either version 3 of the License, or
232             (at your option) any later version.
233              
234             =head1 SEE ALSO
235              
236             L, L
237              
238             =cut
239              
240             # vim: expandtab shiftwidth=4