File Coverage

blib/lib/WWW/DuckDuckGo.pm
Criterion Covered Total %
statement 22 57 38.6
branch 0 16 0.0
condition 0 9 0.0
subroutine 8 14 57.1
pod 1 5 20.0
total 31 101 30.6


line stmt bran cond sub pod time code
1             package WWW::DuckDuckGo;
2             BEGIN {
3 1     1   58060 $WWW::DuckDuckGo::AUTHORITY = 'cpan:DDG';
4             }
5             {
6             $WWW::DuckDuckGo::VERSION = '0.016';
7             }
8             # ABSTRACT: Access to the DuckDuckGo APIs
9              
10 1     1   4462 use Moo;
  1         58161  
  1         8  
11              
12 1     1   16441 use LWP::UserAgent;
  1         151821  
  1         82  
13 1     1   13 use HTTP::Request;
  1         1  
  1         28  
14 1     1   1099 use WWW::DuckDuckGo::ZeroClickInfo;
  1         5  
  1         76  
15 1     1   1837 use JSON;
  1         17594  
  1         6  
16 1     1   159 use URI;
  1         2  
  1         23  
17 1     1   3628 use URI::QueryParam;
  1         1061  
  1         939  
18              
19             our $VERSION ||= '0.0development';
20              
21             has _duckduckgo_api_url => (
22             is => 'ro',
23             lazy => 1,
24             default => sub { 'http://api.duckduckgo.com/' },
25             );
26              
27             has _duckduckgo_api_url_secure => (
28             is => 'ro',
29             lazy => 1,
30             default => sub { 'https://api.duckduckgo.com/' },
31             );
32              
33             has _zeroclickinfo_class => (
34             is => 'ro',
35             lazy => 1,
36             default => sub { 'WWW::DuckDuckGo::ZeroClickInfo' },
37             );
38              
39             has _http_agent => (
40             is => 'ro',
41             lazy => 1,
42             default => sub {
43             my $self = shift;
44             my $ua = LWP::UserAgent->new;
45             $ua->agent($self->http_agent_name);
46             return $ua;
47             },
48             );
49              
50             has http_agent_name => (
51             is => 'ro',
52             lazy => 1,
53             default => sub { __PACKAGE__.'/'.$VERSION },
54             );
55              
56             has forcesecure => (
57             is => 'ro',
58             default => sub { 0 },
59             );
60              
61             has safeoff => (
62             is => 'ro',
63             default => sub { 0 },
64             );
65              
66             has html => (
67             is => 'ro',
68             default => sub { 0 },
69             );
70              
71             # HashRef of extra params
72             has params => (
73             is => 'ro',
74             default => sub { {} },
75             );
76              
77 0     0 0   sub zci { shift->zeroclickinfo(@_) }
78              
79             sub _zeroclickinfo_request_base {
80 0     0     my ( $self, $for_uri, @query_fields ) = @_;
81 0           my $query = join(' ',@query_fields);
82 0           my $uri = URI->new($for_uri);
83 0           my %params = %{$self->params};
  0            
84 0           $uri->query_param( q => $query );
85 0           $uri->query_param( o => 'json' );
86 0 0         $uri->query_param( kp => -1 ) if $self->safeoff;
87 0           $uri->query_param( no_redirect => 1 );
88 0 0         $self->html ?
89             $uri->query_param( no_html => 0 ) :
90             $uri->query_param( no_html => 1 );
91 0           $uri->query_param($_ => $params{$_}) for keys %params;
92 0           return HTTP::Request->new(GET => $uri->as_string);
93             }
94              
95             sub zeroclickinfo_request_secure {
96 0     0 0   my ( $self, @query_fields ) = @_;
97 0 0         return if !@query_fields;
98 0           return $self->_zeroclickinfo_request_base($self->_duckduckgo_api_url_secure,@query_fields);
99             }
100              
101             sub zeroclickinfo_request {
102 0     0 0   my ( $self, @query_fields ) = @_;
103 0 0         return if !@query_fields;
104 0           return $self->_zeroclickinfo_request_base($self->_duckduckgo_api_url,@query_fields);
105             }
106              
107             sub zeroclickinfo {
108 0     0 1   my ( $self, @query_fields ) = @_;
109 0 0         return if !@query_fields;
110 0           my $query = join(' ',@query_fields);
111 0           my $res;
112 0           eval {
113 0           $res = $self->_http_agent->request($self->zeroclickinfo_request_secure(@query_fields));
114             };
115 0 0 0       if (!$self->forcesecure and ( $@ or !$res or !$res->is_success ) ) {
      0        
116 0 0 0       warn __PACKAGE__." HTTP request failed: ".$res->status_line if ($res and !$res->is_success);
117 0           warn __PACKAGE__." Can't access ".$self->_duckduckgo_api_url_secure." falling back to: ".$self->_duckduckgo_api_url;
118 0           $res = $self->_http_agent->request($self->zeroclickinfo_request(@query_fields));
119             }
120 0           return $self->zeroclickinfo_by_response($res);
121             }
122              
123             sub zeroclickinfo_by_response {
124 0     0 0   my ( $self, $response ) = @_;
125 0 0         if ($response->is_success) {
126 0           my $result = decode_json($response->content);
127 0           return $self->_zeroclickinfo_class->by($result);
128             } else {
129 0           die __PACKAGE__.' HTTP request failed: '.$response->status_line, "\n";
130             }
131             }
132              
133             1;
134              
135             __END__