File Coverage

blib/lib/Amazon/Sites.pm
Criterion Covered Total %
statement 38 38 100.0
branch 6 6 100.0
condition 6 6 100.0
subroutine 7 7 100.0
pod n/a
total 57 57 100.0


line stmt bran cond sub pod time code
1             =head1 NAME
2              
3             Amazon::Sites - A class to represent Amazon sites
4              
5             =head1 SYNOPSIS
6              
7             use Amazon::Sites;
8              
9             my $sites = Amazon::Sites->new;
10             my @sites = $sites->sites;
11             my %sites = $sites->sites_hash;
12             my @codes = $sites->codes;
13              
14             my $site = $sites->site('UK');
15             say $site->currency; # GBP
16             say $site->tldn; # co.uk
17             # etc
18              
19             my %urls = $sites->asin_urls('XXXXXXX');
20             say $urls{UK}; # https://amazon.co.uk/dp/XXXXXXX
21             # etc
22              
23             =head1 DESCRIPTION
24              
25             A simple class that encapsulates information about Amazon sites.
26              
27             =cut
28              
29 5     5   652314 use strict;
  5         13  
  5         189  
30 5     5   59 use warnings;
  5         10  
  5         282  
31              
32 5     5   14279 use Feature::Compat::Class;
  5         1912  
  5         24  
33              
34 5     5   928 use feature 'signatures';
  5         11  
  5         180  
35 5     5   23 no warnings 'experimental::signatures';
  5         10  
  5         374  
36              
37             class Amazon::Sites;
38              
39             our $VERSION = '0.1.10';
40              
41 5     5   1943 use Amazon::Site ();
  5         13  
  5         3815  
42              
43             field $include :param = [];
44             field $exclude :param = [];
45             field $assoc_codes :param = {};
46             field %sites = _init_sites($assoc_codes, $include, $exclude);
47              
48             ADJUST {
49             if (@$include and @$exclude) {
50             die "You can't specify both include and exclude";
51             }
52             }
53              
54             =head1 METHODS
55              
56             =head2 new
57              
58             Creates a new Amazon::Sites object.
59              
60             my $sites = Amazon::Sites->new;
61              
62             You can also specify a list of sites to include or exclude:
63              
64             # Only include the US site
65             my $sites = Amazon::Sites->new(include => [ 'US' ]);
66             # Exclude the US site
67             my $sites = Amazon::Sites->new(exclude => [ 'US' ]);
68              
69             At most one of `include` or `exclude` can be specified.
70              
71             You can also specify a hash of associate codes:
72              
73             my $sites = Amazon::Sites->new(assoc_codes => {
74             UK => 'My Associate Code',
75             });
76              
77             =head2 sites_hash
78              
79             Returns a hash where the keys are the two-letter country codes and the values are
80             L objects.
81              
82             =cut
83              
84             method sites_hash { return %sites }
85              
86             =head2 site($code)
87              
88             Given a two-letter country code, returns the corresponding L object.
89              
90             =cut
91              
92             method site ($code) { return $sites{$code} }
93              
94             =head2 sites
95              
96             Returns a list of L objects, sorted by the sort order.
97              
98             =cut
99              
100             method sites {
101             my @sites = sort {
102             $a->sort <=> $b->sort;
103             } values %sites;
104              
105             return @sites;
106             }
107              
108 5     5   13 sub _init_sites($assoc_codes, $include, $exclude) {
  5         10  
  5         10  
  5         8  
  5         8  
109 5         10 my %sites;
110 5         21 my @cols = qw[code country tldn currency sort];
111              
112 5         14 my $where = tell DATA;
113              
114 5         63 while () {
115 110         182 chomp;
116 110         221 my %site;
117 110         451 @site{@cols} = split /\t/;
118              
119 110 100 100     259 next if @$include and not grep { $site{code} eq $_ } @$include;
  44         272  
120 68 100 100     151 next if @$exclude and grep { $site{code} eq $_ } @$exclude;
  23         132  
121              
122 67 100       134 $site{assoc_code} = $assoc_codes->{$site{code}} if $assoc_codes->{$site{code}};
123              
124 67         535 $sites{$site{code}} = Amazon::Site->new(%site);
125             }
126              
127 5         37 seek DATA, $where, 0;
128              
129 5         88 return %sites;
130             }
131              
132             =head2 codes
133              
134             Returns a list of the two-letter country codes, sorted by the sort order.
135              
136             =cut
137              
138             method codes {
139             return sort keys %sites;
140             }
141              
142             =head2 asin_urls
143              
144             Given an ASIN, returns a hash where the keys are the two-letter country
145             codes and the values are the corresponding ASIN URLs.
146              
147             =cut
148              
149             method asin_urls ($asin) {
150             my %urls;
151             for my $site ($self->sites) {
152             $urls{$site->code} = $site->asin_url($asin);
153             }
154              
155             return %urls;
156             }
157              
158             1;
159              
160             =head1 COPYRIGHT
161              
162             Copyright 2024, Dave Cross. All rights reserved.
163              
164             =head1 LICENCE
165              
166             This program is free software; you can redistribute it and/or modify it under
167             the terms of either:
168              
169             =over 4
170              
171             =item * the GNU General Public License as published by the Free Software
172             Foundation; either version 1, or (at your option) any later version, or
173              
174             =item * the Artistic License version 2.0.
175              
176             =back
177              
178             =cut
179              
180             __DATA__