File Coverage

blib/lib/Net/EANSearch.pm
Criterion Covered Total %
statement 24 105 22.8
branch 0 8 0.0
condition 0 27 0.0
subroutine 7 18 38.8
pod 10 11 90.9
total 41 169 24.2


line stmt bran cond sub pod time code
1             package Net::EANSearch;
2              
3 1     1   150454 use strict;
  1         3  
  1         46  
4 1     1   7 use warnings;
  1         2  
  1         67  
5              
6 1     1   855 use LWP;
  1         81588  
  1         53  
7 1     1   1137 use JSON;
  1         14811  
  1         9  
8 1     1   838 use URL::Encode;
  1         6563  
  1         57  
9 1     1   690 use MIME::Base64 qw(decode_base64);
  1         1154  
  1         2154  
10              
11             require Exporter;
12              
13             our @ISA = qw(Exporter);
14              
15             # Items to export into callers namespace by default. Note: do not export
16             # names by default without a very good reason. Use EXPORT_OK instead.
17             # Do not simply export all your public functions/methods/constants.
18              
19             # This allows declaration use Net::EANSearch ':all';
20             # If you do not need this, moving things directly into @EXPORT or @EXPORT_OK
21             # will save memory.
22             our %EXPORT_TAGS = ( 'all' => [ qw(
23            
24             ) ] );
25              
26             our @EXPORT_OK = ( @{ $EXPORT_TAGS{'all'} } );
27              
28             our @EXPORT = qw(
29            
30             );
31              
32             our $VERSION = '1.20';
33              
34             our $ALL_LANGUAGES = 99;
35             our $ENGLISH = 1;
36             our $DANISH = 2;
37             our $GERMAN = 3;
38             our $SPANISH = 4;
39             our $FINISH = 5;
40             our $FRENCH = 6;
41             our $HUNGARIAN = 7;
42             our $ITALIAN = 8;
43             our $JAPANESE = 9;
44             our $DUTCH = 10;
45             our $NORWEGIAN = 11;
46             our $POLISH = 12;
47             our $PORTGUESE = 13;
48             our $SWEDISH = 15;
49             our $CHECH = 16;
50             our $CROATIAN = 18;
51             our $ROMAINAN = 19;
52             our $BULGARIAN = 20;
53             our $GREEK = 21;
54              
55             my $BASE_URI = 'https://api.ean-search.org/api?format=json&token=';
56             my $MAX_API_TRIES = 3; # retry, eg. on 429 error
57              
58             sub new {
59 1     1 1 242955 my $class = shift;
60 1         3 my $token = shift;
61              
62 1         16 my $ua = LWP::UserAgent->new(agent => "perl-eansearch/$VERSION");
63 1         4511 $ua->timeout(30);
64              
65 1         30 my $self = bless { base_uri => $BASE_URI . $token, ua => $ua, remaining => -1 }, $class;
66              
67 1         4 return $self;
68             }
69              
70             sub barcodeLookup {
71 0     0 1   my $self = shift;
72 0           my $ean = shift;
73 0   0       my $lang = shift || 1;
74              
75 0           my $json_str = $self->_apiCall($self->{base_uri} . "&op=barcode-lookup&ean=$ean&language=$lang");
76 0           my $json = decode_json($json_str);
77 0           return $json->[0];
78             }
79              
80             sub isbnLookup {
81 0     0 1   my $self = shift;
82 0           my $isbn = shift;
83 0   0       my $lang = shift || 1;
84              
85 0           my $json_str = $self->_apiCall($self->{base_uri} . "&op=barcode-lookup&isbn=$isbn&language=$lang");
86 0           my $json = decode_json($json_str);
87 0           return $json->[0];
88             }
89              
90             sub barcodePrefixSearch {
91 0     0 1   my $self = shift;
92 0           my $prefix = shift;
93 0   0       my $lang = shift || 1;
94 0   0       my $page = shift || 0;
95              
96 0           my $json_str = $self->_apiCall($self->{base_uri} . "&op=barcode-prefix-search&page=$page&language=$lang&prefix=$prefix");
97 0           my $json = decode_json($json_str);
98 0           return @{ $json->{productlist} };
  0            
99             }
100              
101             sub productSearch {
102 0     0 1   my $self = shift;
103 0           my $kw = shift;
104 0   0       my $lang = shift || 1;
105 0   0       my $page = shift || 0;
106              
107 0           my $json_str = $self->_apiCall($self->{base_uri} . "&op=product-search&page=$page&language=$lang&name="
108             . URL::Encode::url_encode_utf8($kw));
109 0           my $json = decode_json($json_str);
110 0           return @{ $json->{productlist} };
  0            
111             }
112              
113             sub similarProductSearch {
114 0     0 1   my $self = shift;
115 0           my $kw = shift;
116 0   0       my $lang = shift || 1;
117 0   0       my $page = shift || 0;
118              
119 0           my $json_str = $self->_apiCall($self->{base_uri} . "&op=similar-product-search&page=$page&language=$lang&name="
120             . URL::Encode::url_encode_utf8($kw));
121 0           my $json = decode_json($json_str);
122 0           return @{ $json->{productlist} };
  0            
123             }
124              
125             sub categorySearch {
126 0     0 1   my $self = shift;
127 0           my $category = shift;
128 0           my $kw = shift;
129 0   0       my $lang = shift || 1;
130 0   0       my $page = shift || 0;
131              
132 0           my $json_str = $self->_apiCall($self->{base_uri} . "&op=category-search&category=$category"
133             . "&page=$page&language=$lang&name=" . URL::Encode::url_encode_utf8($kw));
134 0           my $json = decode_json($json_str);
135 0           return @{ $json->{productlist} };
  0            
136             }
137              
138             sub issuingCountry {
139 0     0 1   my $self = shift;
140 0           my $ean = shift;
141              
142 0           my $json_str = $self->_apiCall($self->{base_uri} . "&op=issuing-country&ean=$ean");
143 0           my $json = decode_json($json_str);
144 0           return $json->[0]->{issuingCountry};
145             }
146              
147             sub barcodeImage {
148 0     0 1   my $self = shift;
149 0           my $ean = shift;
150 0   0       my $width = shift || 102;
151 0   0       my $height = shift || 50;
152              
153 0           my $json_str = $self->_apiCall($self->{base_uri} . "&op=barcode-image&ean=$ean&width=$width&height=$height");
154 0           my $json = decode_json($json_str);
155 0           return decode_base64($json->[0]->{barcode});
156             }
157              
158             sub verifyChecksum {
159 0     0 1   my $self = shift;
160 0           my $ean = shift;
161              
162 0           my $json_str = $self->_apiCall($self->{base_uri} . "&op=verify-checksum&ean=$ean");
163 0           my $json = decode_json($json_str);
164 0           return $json->[0]->{valid} + 0;
165             }
166              
167             sub creditsRemaining {
168 0     0 0   my $self = shift;
169              
170 0 0         if ($self->{remaining} < 0) {
171 0           $self->_apiCall($self->{base_uri} . "&op=account-status");
172             }
173 0           return $self->{remaining};
174             }
175              
176             sub _apiCall {
177 0     0     my $self = shift;
178 0           my $url = shift;
179 0           my $tries = 0;
180              
181 0           while ($tries < $MAX_API_TRIES) {
182 0           my $response = $self->{ua}->request(HTTP::Request->new(GET => $url));
183 0           $tries++;
184 0 0 0       if (!defined($response) || $response->is_error()) {
185 0 0         if ($response->code == 429) { # auto-retry on 429 (too many requests)
186 0           sleep 1;
187 0           next;
188             }
189 0 0         print STDERR 'Network error: ' . (defined($response) ? $response->code : 'unknown') . "\n";
190 0           return undef;
191             } else {
192 0           $self->{remaining} = $response->header('X-Credits-Remaining');
193 0           return $response->content;
194             }
195             }
196 0           return undef;
197             }
198              
199             1;
200              
201             __END__