File Coverage

blib/lib/Mojolicious/Command/bulkget.pm
Criterion Covered Total %
statement 46 47 97.8
branch 12 22 54.5
condition n/a
subroutine 10 10 100.0
pod 1 1 100.0
total 69 80 86.2


line stmt bran cond sub pod time code
1             package Mojolicious::Command::bulkget;
2 1     1   126663 use Mojo::Base 'Mojolicious::Command';
  1         17  
  1         5  
3 1     1   15646 use Mojo::UserAgent;
  1         160185  
  1         11  
4 1     1   36 use Mojo::Promise;
  1         1  
  1         14  
5 1     1   23 use Mojo::File 'path';
  1         2  
  1         40  
6 1     1   48 use Mojo::Util qw(getopt);
  1         2  
  1         610  
7              
8             our $VERSION = '0.03';
9              
10             my $MAXREQ = 20;
11              
12             has description => 'Perform bulk get requests';
13             has usage => sub { shift->extract_usage . "\n" };
14              
15             sub run {
16 2     2 1 14634 my ($self, @args) = @_;
17 2         9 getopt \@args,
18             'v|verbose' => \my $verbose;
19 2         520 my ($urlbase, $outdir, $suffixesfile) = @args;
20 2 100       8 die $self->usage . "No URL" if !$urlbase;
21 1 50       4 die $self->usage . "$outdir: $!" if ! -d $outdir;
22 1 50       32 die $self->usage . "$suffixesfile: $!" if ! -f $suffixesfile;
23 1         15 my $ua = Mojo::UserAgent->new;
24             # Detect proxy for absolute URLs
25 1 50       14 $urlbase !~ m!^/! ? $ua->proxy->detect : $ua->server->app($self->app);
26 1         62 my $outpath = path($outdir);
27 1         13 my @suffixes = _getsuffixes($suffixesfile, $outpath);
28 1         53 my @promises = map _makepromise($urlbase, $ua, \@suffixes, $outpath, $verbose), (1..$MAXREQ);
29 1 50       8 Mojo::Promise->all(@promises)->wait if @promises;
30             }
31              
32             sub _makepromise {
33 23     23   5633 my ($urlbase, $ua, $suffixes, $outpath, $verbose) = @_;
34 23         30 my $s = shift @$suffixes;
35 23 100       52 return if !defined $s;
36 3         7 my $url = $urlbase . $s;
37 3 50       7 warn "getting $url\n" if $verbose;
38             $ua->get_p($url)->then(sub {
39 3     3   23638 my ($tx) = @_;
40 3         9 _handle_result($outpath, $tx, $s, $verbose);
41 3         428 _makepromise($urlbase, $ua, $suffixes, $outpath, $verbose);
42 3         9 });
43             }
44              
45             sub _handle_result {
46 3     3   7 my ($outpath, $tx, $s, $verbose) = @_;
47 3 50       8 if ($tx->res->is_success) {
48 3 50       53 warn "got $s\n" if $verbose;
49 3         11 $outpath->child($s)->spurt($tx->res->body);
50             } else {
51 0 0       0 warn "error $s\n" if $verbose;
52             }
53             }
54              
55             sub _getsuffixes {
56 1     1   2 my ($suffixesfile, $outpath) = @_;
57 1 50       35 open my $fh, '<', $suffixesfile or die $!;
58 1         17 grep { !-f $outpath->child($_); } map { chomp; $_ } <$fh>;
  3         84  
  3         6  
  3         6  
59             }
60              
61             1;
62              
63             =encoding utf8
64              
65             =head1 NAME
66              
67             Mojolicious::Command::bulkget - Perform bulk get requests
68              
69             =begin markdown
70              
71             # PROJECT STATUS
72              
73             | OS | Build status |
74             |:-------:|--------------:|
75             | Linux | [![Build Status](https://travis-ci.org/mohawk2/Mojolicious-Command-bulkget.svg?branch=master)](https://travis-ci.org/mohawk2/Mojolicious-Command-bulkget) |
76              
77             [![CPAN version](https://badge.fury.io/pl/Mojolicious-Command-bulkget.svg)](https://metacpan.org/pod/Mojolicious::Command::bulkget)
78              
79             =end markdown
80              
81             =head1 SYNOPSIS
82              
83             Usage: APPLICATION bulkget urlbase outdir suffixesfile
84              
85             # suffixes contains lines with 1, 2, 3
86             # fetches /pets/1, /pets/2, ...
87             # stores results in outputdir/1, outputdir/2, ...
88             mojo bulkget http://example.com/pets/ outputdir suffixes
89              
90             Options:
91             -v, --verbose Print progress information
92              
93             =head1 DESCRIPTION
94              
95             L is a command line interface for
96             bulk-fetching URLs.
97              
98             Each line of the "suffixes" file is a suffix. It gets appended to the URL
99             "base", then a non-blocking request is made. Only 20 requests will be
100             active at the same time. When ready, the result is stored in the output
101             directory with the suffix as the filename.
102              
103             This command uses the relatively new Mojolicious feature, Promises. The
104             code may be considered worth examining for lessons on what to do, and/or
105             what not to do.
106              
107             =head1 ATTRIBUTES
108              
109             =head2 description
110              
111             $str = $self->description;
112              
113             =head2 usage
114              
115             $str = $self->usage;
116              
117             =head1 METHODS
118              
119             =head2 run
120              
121             $get->run(@ARGV);
122              
123             Run this command.
124              
125             =head1 AUTHOR
126              
127             Ed J
128              
129             Based heavily on L.
130              
131             =head1 COPYRIGHT AND LICENSE
132              
133             This is free software; you can redistribute it and/or modify it under
134             the same terms as the Perl 5 programming language system itself.
135              
136             =cut