File Coverage

blib/lib/R/Setup/Download.pm
Criterion Covered Total %
statement 12 93 12.9
branch 0 38 0.0
condition 0 4 0.0
subroutine 5 18 27.7
pod 0 13 0.0
total 17 166 10.2


line stmt bran cond sub pod time code
1             # perl program
2             # requires: R instance with Internet connection
3             # accept: a list of package ids
4             # processes:
5             # - get index from CRAN and creates hash of id:tar
6             # - prepares the list of tars
7             # - downloads all tars if --download
8             #
9             # Copyright (C) 2015, Snehasis Sinha
10             #
11              
12             package R::Setup::Download;
13              
14 2     2   21654 use 5.010001;
  2         7  
15 2     2   10 use strict;
  2         5  
  2         49  
16 2     2   11 use warnings;
  2         4  
  2         61  
17 2     2   38352 use LWP::UserAgent;
  2         145009  
  2         124  
18              
19             our @ISA = qw();
20             our $VERSION = '0.01';
21              
22 2     2   2293 BEGIN { $| = 1 } # flush STDOUT buffer
23              
24             # package methods
25              
26             sub new {
27 0     0 0   my $class = shift;
28 0           my %params = @_;
29             my $self = {
30             _url => $params{'urlbase'} || 'http://cran.r-project.org/src',
31             _packages => $params{'packages'}, # list ref of packages
32             _tars => undef, # list reference of tarballs
33             _index => undef, # \%hash_of id:tar extracted from $param{urlbase}
34             _lwp => undef,
35 0   0       _verbose => $params{'verbose'} || 1, # default:yes
      0        
36             };
37 0           bless $self, $class;
38 0           return $self;
39             }
40              
41             # returns package id, accepts tarball
42             # package=>pkg_ver.tar.gz
43             sub p_get_package_id {
44 0     0 0   my ($self, $pkg) = (@_);
45 0           $pkg =~ s/\_.*//;
46 0           return $pkg;
47             }
48              
49             # returns tarball, accepts package name
50             # name=>pkgname
51             sub p_lookup {
52 0     0 0   my ($self, $id) = (@_);
53 0           return $self->{'_index'}->{$id};
54             }
55              
56             # pulls down list of all packages available in CRAN
57             # loads a hash with package id : tarball
58             sub p_wget_index {
59 0     0 0   my ($self) = (@_);
60            
61             # get baseurl index
62 0           $self->pr ( message=>'index' );
63 0 0         $self->p_wget (type => 'index') ? $self->pr (state=>'done') : $self->pr (state=>'failed');
64             }
65              
66             sub p_create_index {
67 0     0 0   my ($self) = (@_);
68 0           my $findex = 'index.html';
69            
70 0 0         if ( -f $findex ) {
71 0 0         open INDEX, "<".$findex or die $!;
72 0           while ( ) {
73 0           chomp;
74             # grep "\.tar\.gz" index.html |sed 's|.*href="||g'|sed 's|\">.*||g';
75 0 0         next unless m/\.tar\.gz/;
76 0           $_ =~ s/.*href="//g;
77 0           $_ =~ s/\"\>.*//g;
78              
79             # store in hash
80 0           $self->{'_index'}->{ $self->p_get_package_id ($_) } = $_;
81             }
82             #unlink $findex;
83 0           close INDEX;
84             }
85             }
86              
87             # wget implementation
88             # package=>pkg_ver.tar.gz or R-3.1.2.tar.gz
89             # type=>package index source
90             sub p_wget {
91 0     0 0   my ($self, %args) = (@_);
92 0           my $res;
93             my $filename;
94 0           my $uri = $self->{'_url'};
95              
96 0 0         if ( $args{'type'} =~ /source/ ) {
    0          
97 0           my $dir = (split /\./, $args{'package'})[0];
98 0           $uri .= '/base/'.$dir.'/'.$args{'package'};
99 0           $args{'filename'} = $args{'package'};
100             } elsif ( $args{'type'} =~ /index/ ) {
101 0           $uri .= '/contrib/';
102 0           $args{'filename'} = 'index.html';
103             } else {
104 0           $uri .= "/contrib/".$args{'package'};
105 0           $args{'filename'} = $args{'package'};
106             }
107              
108 0           $res = $self->{'_lwp'}->get ( $uri );
109              
110 0 0         if ( $res->is_success ) {
111 0 0         open TARGZ, '>'.$args{'filename'} or die $!;
112 0           print TARGZ $res->decoded_content;
113 0           close TARGZ;
114             }
115 0           return $res->is_success;
116             }
117              
118             sub p_connect {
119 0     0 0   my ($self) = (@_);
120            
121 0 0         unless (defined $self->{'_lwp'}) {
122 0           $self->{'_lwp'} = LWP::UserAgent->new;
123 0           $self->{'_lwp'}->timeout(10);
124 0 0         print "user agent connected\n" if $self->{'_verbose'};
125             }
126             }
127              
128             # converts package list to tarball list
129             sub p_create_list {
130 0     0 0   my ($self) = (@_);
131 0           my $tar;
132              
133 0           foreach my $id ( @{$self->{'_packages'}} ) {
  0            
134 0           $tar = $self->p_lookup ( $id );
135 0 0         push ( @{$self->{'_tars'}}, $tar ) if defined $tar;
  0            
136             }
137             }
138              
139             sub prepare {
140 0     0 0   my ($self, %args) = (@_);
141              
142 0           $self->p_connect;
143 0 0         $self->p_wget_index if $args{refresh};
144 0           $self->p_create_index;
145              
146 0           $self->p_create_list;
147             }
148              
149             sub dumplist {
150 0     0 0   my ($self) = (@_);
151 0           return $self->{'_tars'};
152             }
153              
154             sub pr {
155 0     0 0   my ($self, %args) = (@_);
156 0 0         return unless $self->{'_verbose'};
157 0 0         print sprintf "%-40s ... ", $args{message} if defined $args{message};
158 0 0         print sprintf " _%s_\n", $args{state} if defined $args{state};
159             }
160              
161             sub download_binary {
162 0     0 0   my ($self, %args) = (@_);
163 0           my $ret;
164            
165 0 0         if ( -f $args{'source'} ) {
166 0           $self->pr ( message=>$args{'source'}, state=>'here' );
167 0           return 1;
168             }
169              
170 0           $self->p_connect;
171 0           $self->pr ( message=>$args{'source'} );
172 0 0         $self->p_wget(type => 'source', package => $args{'source'})
173             ? $self->pr ( state=>'done' )
174             : $self->pr ( state=>'failed' );
175            
176 0           return 0;
177             }
178              
179              
180             sub download {
181 0     0 0   my ($self) = (@_);
182              
183 0           foreach my $pkg ( @{$self->{'_tars'}} ) {
  0            
184 0 0         if ( -f $pkg ) {
185 0           $self->pr ( message=>$pkg, state=>'here' );
186 0           next;
187             }
188 0           $self->pr ( message=>$pkg );
189 0 0         $self->p_wget(type => 'package', package => $pkg)
190             ? $self->pr ( state=>'done' )
191             : $self->pr ( state=>'failed' )
192             }
193             }
194              
195             1;
196              
197             __END__