File Coverage

blib/lib/Doit/Lwp.pm
Criterion Covered Total %
statement 50 52 96.1
branch 30 32 93.7
condition 7 8 87.5
subroutine 7 7 100.0
pod 1 3 33.3
total 95 102 93.1


line stmt bran cond sub pod time code
1             # -*- perl -*-
2              
3             #
4             # Author: Slaven Rezic
5             #
6             # Copyright (C) 2017,2018 Slaven Rezic. All rights reserved.
7             # This package is free software; you can redistribute it and/or
8             # modify it under the same terms as Perl itself.
9             #
10             # Mail: slaven@rezic.de
11             # WWW: http://www.rezic.de/eserte/
12             #
13              
14             package Doit::Lwp; # Convention: all commands here should be prefixed with 'lwp_'
15              
16 2     2   15 use strict;
  2         4  
  2         77  
17 2     2   9 use warnings;
  2         2  
  2         135  
18             our $VERSION = '0.012';
19              
20 2     2   12 use Doit::Log;
  2         3  
  2         1421  
21              
22 2     2 0 21 sub new { bless {}, shift }
23 2     2 0 6 sub functions { qw(lwp_mirror) }
24              
25             {
26             my $ua; # XXX cache in object?
27             sub _get_cached_ua {
28 4     4   10 my($self) = @_;
29 4 100       22 return $ua if $ua;
30 1         770 require LWP::UserAgent;
31 1         58801 $ua = LWP::UserAgent->new; # XXX options?
32             }
33             }
34              
35             sub lwp_mirror {
36 13     13 1 58 my($self, $url, $filename, %opts) = @_;
37 13 100       62 if (!defined $url) { error "url is mandatory" }
  1         3  
38 12 100       31 if (!defined $filename) { error "filename is mandatory" }
  1         3  
39 11   100     60 my $refresh = delete $opts{refresh} || 'always';
40 11 100       81 if ($refresh !~ m{^(always|never)$}) { error "refresh may be 'always' or 'never'" }
  1         6  
41 10         21 my $debug = delete $opts{debug};
42 10         17 my $ua = delete $opts{ua};
43 10 100       30 error "Unhandled options: " . join(" ", %opts) if %opts;
44              
45 9 100 100     302 if (-e $filename && $refresh eq 'never') {
46 1         20 info "$url -> $filename already exists, do not refresh";
47 1         115 return 0;
48             }
49              
50 8   66     60 $ua ||= _get_cached_ua;
51              
52 8 50       2816 if ($self->is_dry_run) {
53 0         0 info "mirror $url -> $filename (dry-run)";
54             } else {
55 8         56 info "mirror $url -> $filename";
56 8         815 my $resp = $ua->mirror($url, $filename);
57 8 100       369106 if (ref $ua eq 'HTTP::Tiny') {
58 4 100       18 if ($debug) {
59 2         741 require Data::Dumper;
60 2         7822 info "Response: " . Data::Dumper->new([$resp],[qw()])->Indent(1)->Useqq(1)->Sortkeys(1)->Terse(1)->Dump;
61             }
62 4 100       741 if (!$resp->{success}) {
    100          
63 2         6 my $msg = "mirroring failed: $resp->{status} $resp->{reason}";
64 2 100       8 if ($resp->{status} == 599) {
65 1         3 $msg .= ": $resp->{content}";
66             }
67 2         28 error $msg;
68             } elsif ($resp->{status} == 304) {
69 1         17 return 0;
70             } else {
71 1         15 return 1;
72             }
73             } else {
74 4 100       12 if ($debug) {
75 1         13 info "Response: " . $resp->as_string;
76             }
77 4 100       89 if ($resp->code == 304) {
    100          
    50          
78 1         18 return 0;
79             } elsif (!$resp->is_success) {
80 1         36 error "mirroring failed: " . $resp->status_line;
81             } elsif ($resp->header('X-Died')) {
82 0         0 error "mirroring failed: " . $resp->header('X-Died');
83             } else {
84 2         183 return 1;
85             }
86             }
87             }
88             }
89              
90             1;
91              
92             __END__