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__ |