diff --git a/Changes b/Changes index 72a5311..4033577 100644 --- a/Changes +++ b/Changes @@ -1,5 +1,9 @@ Revision history for Perl extension Net::EANSearch. +1.07 Tue Nov 5 11:00:00 2024 + - add similarProductSearch() + - auto-retry API calls on 429 error code + 1.06 Wed Feb 16 01:00:00 2024 - add missing test dependency diff --git a/README.md b/README.md index 3b821e4..fbaa442 100644 --- a/README.md +++ b/README.md @@ -95,6 +95,16 @@ do { } } while (@product_list == 10); +$page = 0; +do { + $page++; + @product_list = $eansearch->similarProductSearch('Apple iPhone 16 exotic keywords white', $Net::EANSearch::ENGLISH, $page); + + foreach my $p (@product_list) { + print "EAN $p->{ean} is $p->{name}\n"; + } +} while (@product_list == 10); + my @book_list = $eansearch->categorySearch(15, 'iphone'); foreach my $p (@book_list) { diff --git a/lib/Net/EANSearch.pm b/lib/Net/EANSearch.pm index 83a2fba..ec8329a 100644 --- a/lib/Net/EANSearch.pm +++ b/lib/Net/EANSearch.pm @@ -29,7 +29,7 @@ our @EXPORT = qw( ); -our $VERSION = '1.06'; +our $VERSION = '1.07'; our $ALL_LANGUAGES = 99; our $ENGLISH = 1; @@ -53,6 +53,7 @@ our $BULGARIAN = 20; our $GREEK = 21; my $BASE_URI = 'https://api.ean-search.org/api?format=json&token='; +my $MAX_API_TRIES = 3; # retry, eg. on 429 error sub new { my $class = shift; @@ -109,6 +110,18 @@ sub productSearch { return @{ $json->{productlist} }; } +sub similarProductSearch { + my $self = shift; + my $kw = shift; + my $lang = shift || 1; + my $page = shift || 1; + + my $json_str = $self->_apiCall($self->{base_uri} . "&op=similar-product-search&page=$page&language=$lang&name=" + . URL::Encode::url_encode_utf8($kw)); + my $json = decode_json($json_str); + return @{ $json->{productlist} }; +} + sub categorySearch { my $self = shift; my $category = shift; @@ -154,14 +167,23 @@ sub verifyChecksum { sub _apiCall { my $self = shift; my $url = shift; - - my $doc = $self->{ua}->request(HTTP::Request->new(GET => $url)); - if (!defined($doc) || $doc->is_error()) { - print STDERR 'Network error: ' . (defined($doc) ? $doc->code : 'unknown') . "\n"; - return undef; - } else { - return $doc->content; + my $tries = 0; + + while ($tries < $MAX_API_TRIES) { + my $doc = $self->{ua}->request(HTTP::Request->new(GET => $url)); + $tries++; + if (!defined($doc) || $doc->is_error()) { + if ($doc->code == 429) { # auto-retry on 429 (too many requests) + sleep 1; + next; + } + print STDERR 'Network error: ' . (defined($doc) ? $doc->code : 'unknown') . "\n"; + return undef; + } else { + return $doc->content; + } } + return undef; } 1; @@ -215,7 +237,17 @@ If there are many results, you may need to page through the results to retrieve =item productSearch($name [, $language, $page]) -Search the database by product name or keyword. +Search the database by product name or keyword (exact search, all parts of the query must be found). +If you get no results, you might want to try a similarProductSearch(). + +Optionally, you can specify a preferred language for the results. + +If there are many results, you may need to page through the results to retrieve them all. Page numbers start at 1. + +=item similarProductSearch($name [, $language, $page]) + +Search the database by product name or keyword (find similar products, not all parts of the query must match). +You probably want to try an exact search (productSearch()) before you do a similarProductSearch(). Optionally, you can specify a preferred language for the results.