File Coverage

blib/lib/Mojolicious/Command/donuts.pm
Criterion Covered Total %
statement 15 51 29.4
branch 0 16 0.0
condition 0 6 0.0
subroutine 5 14 35.7
pod 1 1 100.0
total 21 88 23.8


line stmt bran cond sub pod time code
1             package Mojolicious::Command::donuts;
2 1     1   743 use Mojo::Base 'Mojolicious::Command';
  1         2  
  1         8  
3              
4 1     1   141908 use Mojo::JSON qw(encode_json);
  1         2929  
  1         76  
5 1     1   6 use Mojo::Util qw(dumper);
  1         2  
  1         45  
6 1     1   1220 use Getopt::Long qw(GetOptionsFromArray);
  1         11777  
  1         5  
7 1     1   1097 use WWW::KrispyKreme::HotLight;
  1         154673  
  1         11  
8              
9             our $VERSION = 0.04;
10              
11             has description => 'Find fresh donuts near you!';
12              
13             has usage => <
14             USAGE:
15              
16             mojo donuts [OPTIONS]
17              
18             OPTIONS:
19              
20             --geo, -g Specify geo to be used for search (recommended)
21             --fresh, -f Filter results by stores serving fresh donuts
22             --raw, -r Print raw data structure returned from search response
23              
24             EOF
25              
26             has ua => sub { Mojo::UserAgent->new() };
27              
28             has [qw( geo fresh raw )];
29              
30             sub _mk_request {
31 0     0     my ($self, $url, $form) = @_;
32 0 0         my $tx = $form ? $self->ua->get($url) : $self->ua->post($url => form => $form);
33              
34 0 0         unless ($tx->success) {
35 0           my $err = $tx->error;
36             die join(
37             '', #
38             'Trouble finding IP address.',
39             'If problem persists, you might have to provide geo.',
40             "$url error code and response:",
41             $err->{code}, $err->{response},
42 0           );
43             }
44 0           return $tx->res;
45             }
46              
47             sub _ip2geo {
48 0     0     my ($self, $ip) = @_;
49              
50             # fetch latitude and longitude from geocodeip.com
51             my $geo = $self->_mk_request('http://www.geocodeip.com/', {IP => $ip})
52             ->dom->find('div#data_display > table.table > tr > td')
53 0     0     ->grep(sub { $_->text =~ /\b(?:Latitude|Longitude)\b/; })
54 0     0     ->map(sub { $_->following->first->text })->to_array;
  0            
55              
56 0 0 0       die 'Failed to scape geo from geocodeip.com. You may need to provide geo instead.'
      0        
57             unless $geo
58             && $geo->[0]
59             && $geo->[1];
60              
61 0           return $geo;
62             }
63              
64             sub _geocode_ip {
65 0     0     my $self = shift;
66              
67 0 0         return if $self->geo;
68              
69 0           my $ip = $self->_mk_request('http://icanhazip.com')->body;
70 0           return $self->_ip2geo($ip);
71             }
72              
73             sub run {
74 0     0 1   my ($self, @args) = @_;
75              
76             GetOptionsFromArray(
77             \@args, #
78 0     0     'geo|g=s' => sub { $self->geo([split ',', $_[1]]) },
79 0     0     'fresh|f' => sub { $self->fresh(1) },
80 0     0     'raw|r' => sub { $self->raw(1) },
81 0           );
82              
83 0           my $base_url = 'http://krispykreme.com/Locate/Location-Search';
84 0           my $hotlight_url = 'http://services.krispykreme.com/api/locationsearchresult/';
85              
86             # user may not provide geo
87 0 0         $self->geo($self->_geocode_ip) unless $self->geo;
88              
89 0           my $donuts = WWW::KrispyKreme::HotLight->new(where => $self->geo)->locations;
90              
91             # pull out the Location key of each store returned
92             my @locations =
93 0 0         grep { $self->fresh ? $_->{Hotlight} : 1 } @$donuts;
  0            
94              
95 0 0         if ($self->raw) {
96 0           say dumper \@locations;
97 0           exit 1;
98             }
99              
100             # print out some info for each store
101 0           for my $loc (@locations) {
102 0           my $addr = join ', ', grep { s/\s+$//; 1 } #
  0            
103 0           $loc->{Address1}, $loc->{City}, $loc->{Province};
104              
105 0 0         $addr .= ' [HOTLIGHT ON]' if $loc->{Hotlight};
106              
107 0           say $addr;
108             }
109             }
110              
111             1;
112             __END__