File Coverage

blib/lib/AnnoCPAN/Perldoc/SyncDB.pm
Criterion Covered Total %
statement 38 72 52.7
branch 12 40 30.0
condition 3 11 27.2
subroutine 7 7 100.0
pod 2 2 100.0
total 62 132 46.9


line stmt bran cond sub pod time code
1             package AnnoCPAN::Perldoc::SyncDB;
2              
3 1     1   64489 use warnings;
  1         2  
  1         33  
4 1     1   5 use strict;
  1         2  
  1         32  
5 1     1   1115 use LWP::UserAgent;
  1         131218  
  1         38  
6 1     1   14 use File::Spec;
  1         2  
  1         26  
7 1     1   6 use Carp;
  1         3  
  1         1336  
8              
9             our $VERSION = '0.11';
10              
11             # Default URL, can be overridden via package method
12             my $baseurl = 'http://annocpan.org/annopod.db';
13              
14             =head1 NAME
15              
16             AnnoCPAN::Perldoc::SyncDB - Download the AnnoCPAN database
17              
18             =head1 LICENSE
19              
20             Copyright Clotho Advanced Media Inc.
21              
22             This software is released by Clotho Advanced Media, Inc. under the same
23             terms as Perl itself. That means that it is dual-licensed under the
24             Artistic license and the GPL, and that you can redistribute it and/or
25             modify it under the terms of either or both of those licenses. See
26             the "LICENSE" file, or visit http://www.clotho.com/code/Perl
27              
28             The definitive source of Clotho Advanced Media software is
29             http://www.clotho.com/code/
30              
31             All of our software is also available under commercial license. If
32             the Artisic license or the GPL does not meet the needs of your
33             project, please contact us at info@clotho.com or visit the above URL.
34              
35             We release open source software to help the world. We hope that you
36             will enjoy this software, and we also hope and that you will hire us.
37             As authors of this software, we are best able to help you integrate it
38             into your project and to assist you with any problems.
39              
40             =head1 SYNOPSIS
41              
42             use AnnoCPAN::Perldoc::SyncDB;
43             AnnoCPAN::Perldoc::SyncDB->run(
44             dest => "$ENV{HOME}/.annopod.db",
45             verbose => 1,
46             );
47              
48             =head1 DESCRIPTION
49              
50             This module provides a simple interface to mirror the
51             L content to a local machine. In conjunction
52             with the L module, this allows one to get all the
53             benefits of the AnnoCPAN website in one's local C command.
54              
55             Recommended usage: 1) Install this module and AnnoCPAN::Perldoc, 2)
56             set up a weekly process to run the C command included in
57             this distribution, 3) Put the following in your shell configuration:
58             C.
59              
60             =head1 FUNCTIONS
61              
62             =over
63              
64             =item $pkg->baseurl()
65              
66             =item $pkg->baseurl($newurl)
67              
68             Returns the default URL for the annopod.db file. If there is an
69             argument, it sets the default URL to that value before returning.
70              
71             =cut
72              
73             sub baseurl
74             {
75 3     3 1 2002204 my $pkg = shift;
76 3 100       13 if (@_ > 0)
77             {
78 2         6 $baseurl = shift;
79             }
80 3         14 return $baseurl;
81             }
82              
83             =item $pkg->run([OPTS])
84              
85             Mirrors the annopod.db file from the net. The behavior can be altered
86             via hash-like options:
87              
88             =over
89              
90             =item dest => filename
91              
92             Specifies the filename where the downloaded file should be stored.
93              
94             Defaults to the same location used by AnnoCPAN::Perldoc, or if that fails C<$HOME/.annopod.db> (C<$HOME\annopod.db> on Windows).
95              
96             =item src => url
97              
98             Specifies the net resource that should be mirrored.
99              
100             Defaults to the baseurl property of this module.
101              
102             =item timeout => seconds
103              
104             Specifies the LWP::UserAgent timeout. Defaults to 30 seconds.
105              
106             =item compress => flag
107              
108             Specifies which version of the database to download. The options are
109             C, C, the empty string (i.e. no compression) or C,
110             which means autodetection. The autodetect mode checks if you have
111             Compress::Bzip2 or Compress::Zlib installed before picking the best of
112             the other flag values.
113              
114             Defaults to C (that is, autodetect mode).
115              
116             =item verbose => boolean
117              
118             Defaults to a false value. If set to true, this method prints status messages to the output filehandle.
119              
120             =back
121              
122             =cut
123              
124             sub run
125             {
126 1     1 1 3 my $pkg = shift;
127 1 50       6 if (@_ % 2)
128             {
129 0         0 croak("Error: odd number of arguments");
130             }
131 1         7 my %opts = @_;
132 1   33     7 $opts{src} ||= $baseurl;
133 1   50     10 $opts{timeout} ||= 30;
134              
135 1 50       4 if (!$opts{dest})
136             {
137             # This algorithm is duplicated from AnnoCPAN::Perldoc
138             # Future versions should access that module's algorithm directly
139 0         0 DIR: foreach my $dir (@ENV{qw(HOME USERPROFILE ALLUSERSPROFILE)},
140             '/var/annocpan')
141             {
142 0 0 0     0 if ($dir && -d $dir)
143             {
144 0         0 foreach my $file ('annopod.db', '.annopod.db')
145             {
146 0         0 my $path = File::Spec->catfile($dir, $file);
147 0 0       0 if (-w $path)
148             {
149 0         0 $opts{dest} = $path;
150 0         0 last DIR;
151             }
152             }
153             }
154             }
155             }
156              
157 1 50 33     7 if (!$opts{dest} && $ENV{HOME})
158             {
159 0 0       0 $opts{dest} = File::Spec->catfile($ENV{HOME},
160             ($^O eq 'MSWin32' ? '' : '.') .
161             'annopod.db');
162             }
163            
164 1 50       4 if (!$opts{dest})
165             {
166 0         0 croak('No destination file specified');
167             }
168              
169 1 50       6 if (!defined $opts{compress})
170             {
171 0         0 $opts{compress} = '';
172 0         0 local $SIG{__WARN__} = 'DEFAULT';
173 0         0 local $SIG{__DIE__} = 'DEFAULT';
174 0         0 eval 'use Compress::Bzip2';
175 0 0       0 if (!$@)
176             {
177 0         0 $opts{compress} = 'bz2';
178             }
179             else
180             {
181 0         0 eval 'use Compress::Zlib';
182 0 0       0 if (!$@)
183             {
184 0         0 $opts{compress} = 'gz';
185             }
186             }
187             }
188              
189 1 50       5 my $ext = $opts{compress} ? ".$opts{compress}" : '';
190 1         3 my $url = $opts{src}.$ext;
191 1         3 my $dest = $opts{dest};
192              
193 1 50       4 print "Downloading $url --> $dest$ext\n" if ($opts{verbose});
194              
195 1         11 my $ua = LWP::UserAgent->new();
196 1         5908 $ua->timeout($opts{timeout});
197 1         72 $ua->env_proxy;
198 1 50       36449 $ua->mirror($url, $dest.$ext)
199             || croak("Failed to mirror $url");
200              
201 1 50       47834 if ($opts{compress})
202             {
203 0 0       0 print "Uncompressing $dest$ext --> $dest\n" if ($opts{verbose});
204 0 0       0 open(my $out, "> $dest")
205             || croak("Failed to write to $dest");
206 0         0 my $buf;
207 0 0       0 if ($opts{compress} eq 'bz2')
    0          
208             {
209 0         0 my $bz = Compress::Bzip2->new();
210 0         0 $bz->bzopen($dest.$ext, "r");
211 0         0 while ($bz->bzread($buf) > 0)
212             {
213 0         0 print $out $buf;
214             }
215 0         0 $bz->bzclose();
216             }
217             elsif ($opts{compress} eq 'gz')
218             {
219 0         0 my $gz = Compress::Zlib::gzopen($dest.$ext, "r");
220 0         0 while ($gz->gzread($buf) > 0)
221             {
222 0         0 print $out $buf;
223             }
224 0         0 $gz->gzclose();
225             }
226             else
227             {
228 0         0 carp('Compression option not understood. Skipping uncompress step.');
229             }
230 0         0 close $out;
231             }
232 1 50       37 print "Done\n" if ($opts{verbose});
233             }
234              
235             1;
236             __END__