File Coverage

blib/lib/Aws/Polly/Select.pm
Criterion Covered Total %
statement 69 71 97.1
branch 8 12 66.6
condition n/a
subroutine 20 22 90.9
pod 1 13 7.6
total 98 118 83.0


line stmt bran cond sub pod time code
1             #!/usr/bin/perl
2             #-------------------------------------------------------------------------------
3             # Select AWS Polly speakers with specified characteristics
4             # Philip R Brenan at gmail dot com, Appa Apps Ltd, 2017
5             #-------------------------------------------------------------------------------
6              
7             package Aws::Polly::Select;
8             require v5.16.0;
9 1     1   630 use warnings FATAL => qw(all);
  1         7  
  1         37  
10 1     1   13 use strict;
  1         4  
  1         31  
11 1     1   15 use Carp;
  1         3  
  1         89  
12 1     1   839 use Data::Table::Text qw(:all);
  1         69860  
  1         372  
13 1     1   7 use Data::Dump qw(dump);
  1         2  
  1         31  
14 1     1   4 use utf8;
  1         2  
  1         4  
15              
16             our $VERSION = '20171217';
17              
18             BEGIN
19 1     1   151 {my @fields = qw(Gender Id LanguageCode LanguageName Name Written Country); # Field names
20              
21 1         2 for my $field(@fields) # Generate methods to get attributes from each speaker
22             {package Aws::Polly::Select::Speaker;
23 7         596 Data::Table::Text::genLValueScalarMethods($field);
24             }
25              
26 1         86 for my $field(@fields) # Generate methods that get all the values of each attribute of each speaker
27 7         15 {my $s = <<'END';
28             sub XXX {&fieldValues("XXX")}
29             END
30 7         42 $s =~ s(XXX) ($field)gs;
31 7     0 0 331 eval $s;
  0     1 0 0  
  1     1 0 6  
  1     1 0 5  
  1     1 0 7  
  1     0 0 4  
  0     1 0 0  
  1         7  
32 7 50       1344 $@ and confess $@;
33             }
34             }
35              
36             sub fieldValues($) # All the values a specified field can take
37 5     5 0 14 {my ($field) = @_;
38 5         10 my %l;
39 5         8 my @s = @{&speakerDetails};
  5         10  
40 5         19 for my $speaker(@s)
41 260 50       449 {if (my $v = $speaker->{$field})
42 260         431 {$l{$v}++
43             }
44             }
45 5         321 sort keys %l;
46             }
47              
48             #-------------------------------------------------------------------------------
49             # Select speakers
50             #-------------------------------------------------------------------------------
51              
52             sub speaker(@) # Select speakers by fields
53 5     5 0 13 {my (%selection) = @_; # Selection fields: name=>"regular expression" where the field of that name must match the regular expression regardless of case
54 5         10 my @s;
55 5         7 for my $speaker(@{&speakerDetails}) # Check each speaker
  5         5  
56 260         268 {my $m = 1; # Speaker matches so far
57 260         344 for my $field(keys %selection) # Continue with the speaker as long as they match on all the supplied fields - these fields are our shorter simpler names not AWS's longer more complicated names
58 458 100       605 {last unless $m;
59 342         356 my $r = $selection{$field}; # Regular expression to match
60 342         359 my $v = $speaker->{$field}; # Value of this field for this speaker
61 342 50       425 confess "No such field: $field" unless $v;
62 342         690 $m = $v =~ m/$r/; # Case insensitive
63             }
64 260 100       423 push @s, $speaker if $m; # Exclude potential speaker unless they match all valid fields
65             }
66 5         129 sort {$a->Id cmp $b->Id} @s
  52         933  
67             }
68              
69             #-------------------------------------------------------------------------------
70             # Blessed speaker details
71             #-------------------------------------------------------------------------------
72              
73             sub speakerDetails
74 12     12 0 22 {my $s = &speakerDetailsFromAWS;
75 12         35 for(@$s)
76             {package Aws::Polly::Select::Speaker;
77 624         12259 bless $_;
78 624         8555 ($_->Written) = split /-/, $_->LanguageCode; # Add written code
79             }
80             $s
81 12         279 }
82              
83             #-------------------------------------------------------------------------------
84             # Speaker ids as a hash
85             #-------------------------------------------------------------------------------
86              
87             sub speakerIds
88 2     2 1 5 {my $s = speakerDetails;
89 2         3 +{map{$_->Id => $_} @$s}
  104         1582  
90             }
91              
92             #-------------------------------------------------------------------------------
93             # Speaker details from AWS via:
94             # renewSpeakerDetailsButOnlyWhenAWSChangesTheListOfSpeakers()
95             #-------------------------------------------------------------------------------
96              
97             sub speakerDetailsFromAWS
98             {[
99 12     12 0 835 { Gender => "Female",
100             Id => "Gwyneth",
101             LanguageCode => "cy-GB",
102             LanguageName => "Welsh",
103             Name => "Gwyneth",
104             },
105             {
106             Gender => "Female",
107             Id => "Naja",
108             LanguageCode => "da-DK",
109             LanguageName => "Danish",
110             Name => "Naja",
111             },
112             {
113             Gender => "Male",
114             Id => "Mads",
115             LanguageCode => "da-DK",
116             LanguageName => "Danish",
117             Name => "Mads",
118             },
119             {
120             Gender => "Female",
121             Id => "Vicki",
122             LanguageCode => "de-DE",
123             LanguageName => "German",
124             Name => "Vicki",
125             },
126             {
127             Gender => "Female",
128             Id => "Marlene",
129             LanguageCode => "de-DE",
130             LanguageName => "German",
131             Name => "Marlene",
132             },
133             {
134             Gender => "Male",
135             Id => "Hans",
136             LanguageCode => "de-DE",
137             LanguageName => "German",
138             Name => "Hans",
139             },
140             {
141             Gender => "Male",
142             Id => "Russell",
143             LanguageCode => "en-AU",
144             LanguageName => "Australian English",
145             Name => "Russell",
146             },
147             {
148             Gender => "Female",
149             Id => "Nicole",
150             LanguageCode => "en-AU",
151             LanguageName => "Australian English",
152             Name => "Nicole",
153             },
154             {
155             Gender => "Female",
156             Id => "Emma",
157             LanguageCode => "en-GB",
158             LanguageName => "British English",
159             Name => "Emma",
160             },
161             {
162             Gender => "Male",
163             Id => "Brian",
164             LanguageCode => "en-GB",
165             LanguageName => "British English",
166             Name => "Brian",
167             },
168             {
169             Gender => "Female",
170             Id => "Amy",
171             LanguageCode => "en-GB",
172             LanguageName => "British English",
173             Name => "Amy",
174             },
175             {
176             Gender => "Male",
177             Id => "Geraint",
178             LanguageCode => "en-GB-WLS",
179             LanguageName => "Welsh English",
180             Name => "Geraint",
181             },
182             {
183             Gender => "Female",
184             Id => "Aditi",
185             LanguageCode => "en-IN",
186             LanguageName => "Indian English",
187             Name => "Aditi",
188             },
189             {
190             Gender => "Female",
191             Id => "Raveena",
192             LanguageCode => "en-IN",
193             LanguageName => "Indian English",
194             Name => "Raveena",
195             },
196             {
197             Gender => "Female",
198             Id => "Joanna",
199             LanguageCode => "en-US",
200             LanguageName => "US English",
201             Name => "Joanna",
202             },
203             {
204             Gender => "Female",
205             Id => "Salli",
206             LanguageCode => "en-US",
207             LanguageName => "US English",
208             Name => "Salli",
209             },
210             {
211             Gender => "Male",
212             Id => "Matthew",
213             LanguageCode => "en-US",
214             LanguageName => "US English",
215             Name => "Matthew",
216             },
217             {
218             Gender => "Female",
219             Id => "Kimberly",
220             LanguageCode => "en-US",
221             LanguageName => "US English",
222             Name => "Kimberly",
223             },
224             {
225             Gender => "Female",
226             Id => "Kendra",
227             LanguageCode => "en-US",
228             LanguageName => "US English",
229             Name => "Kendra",
230             },
231             {
232             Gender => "Male",
233             Id => "Justin",
234             LanguageCode => "en-US",
235             LanguageName => "US English",
236             Name => "Justin",
237             },
238             {
239             Gender => "Male",
240             Id => "Joey",
241             LanguageCode => "en-US",
242             LanguageName => "US English",
243             Name => "Joey",
244             },
245             {
246             Gender => "Female",
247             Id => "Ivy",
248             LanguageCode => "en-US",
249             LanguageName => "US English",
250             Name => "Ivy",
251             },
252             {
253             Gender => "Male",
254             Id => "Enrique",
255             LanguageCode => "es-ES",
256             LanguageName => "Castilian Spanish",
257             Name => "Enrique",
258             },
259             {
260             Gender => "Female",
261             Id => "Conchita",
262             LanguageCode => "es-ES",
263             LanguageName => "Castilian Spanish",
264             Name => "Conchita",
265             },
266             {
267             Gender => "Female",
268             Id => "Penelope",
269             LanguageCode => "es-US",
270             LanguageName => "US Spanish",
271             Name => "Penélope,",
272             },
273             {
274             Gender => "Male",
275             Id => "Miguel",
276             LanguageCode => "es-US",
277             LanguageName => "US Spanish",
278             Name => "Miguel",
279             },
280             {
281             Gender => "Female",
282             Id => "Chantal",
283             LanguageCode => "fr-CA",
284             LanguageName => "Canadian French",
285             Name => "Chantal",
286             },
287             {
288             Gender => "Male",
289             Id => "Mathieu",
290             LanguageCode => "fr-FR",
291             LanguageName => "French",
292             Name => "Mathieu",
293             },
294             {
295             Gender => "Female",
296             Id => "Celine",
297             LanguageCode => "fr-FR",
298             LanguageName => "French",
299             Name => "Céline",
300             },
301             {
302             Gender => "Male",
303             Id => "Karl",
304             LanguageCode => "is-IS",
305             LanguageName => "Icelandic",
306             Name => "Karl",
307             },
308             {
309             Gender => "Female",
310             Id => "Dora",
311             LanguageCode => "is-IS",
312             LanguageName => "Icelandic",
313             Name => "Dóra",
314             },
315             {
316             Gender => "Male",
317             Id => "Giorgio",
318             LanguageCode => "it-IT",
319             LanguageName => "Italian",
320             Name => "Giorgio",
321             },
322             {
323             Gender => "Female",
324             Id => "Carla",
325             LanguageCode => "it-IT",
326             LanguageName => "Italian",
327             Name => "Carla",
328             },
329             {
330             Gender => "Male",
331             Id => "Takumi",
332             LanguageCode => "ja-JP",
333             LanguageName => "Japanese",
334             Name => "Takumi",
335             },
336             {
337             Gender => "Female",
338             Id => "Mizuki",
339             LanguageCode => "ja-JP",
340             LanguageName => "Japanese",
341             Name => "Mizuki",
342             },
343             {
344             Gender => "Female",
345             Id => "Seoyeon",
346             LanguageCode => "ko-KR",
347             LanguageName => "Korean",
348             Name => "Seoyeon",
349             },
350             {
351             Gender => "Female",
352             Id => "Liv",
353             LanguageCode => "nb-NO",
354             LanguageName => "Norwegian",
355             Name => "Liv",
356             },
357             {
358             Gender => "Male",
359             Id => "Ruben",
360             LanguageCode => "nl-NL",
361             LanguageName => "Dutch",
362             Name => "Ruben",
363             },
364             {
365             Gender => "Female",
366             Id => "Lotte",
367             LanguageCode => "nl-NL",
368             LanguageName => "Dutch",
369             Name => "Lotte",
370             },
371             {
372             Gender => "Female",
373             Id => "Maja",
374             LanguageCode => "pl-PL",
375             LanguageName => "Polish",
376             Name => "Maja",
377             },
378             {
379             Gender => "Male",
380             Id => "Jan",
381             LanguageCode => "pl-PL",
382             LanguageName => "Polish",
383             Name => "Jan",
384             },
385             {
386             Gender => "Female",
387             Id => "Ewa",
388             LanguageCode => "pl-PL",
389             LanguageName => "Polish",
390             Name => "Ewa",
391             },
392             {
393             Gender => "Male",
394             Id => "Jacek",
395             LanguageCode => "pl-PL",
396             LanguageName => "Polish",
397             Name => "Jacek",
398             },
399             {
400             Gender => "Female",
401             Id => "Vitoria",
402             LanguageCode => "pt-BR",
403             LanguageName => "Brazilian Portuguese",
404             Name => "Vitória",
405             },
406             {
407             Gender => "Male",
408             Id => "Ricardo",
409             LanguageCode => "pt-BR",
410             LanguageName => "Brazilian Portuguese",
411             Name => "Ricardo",
412             },
413             {
414             Gender => "Female",
415             Id => "Ines",
416             LanguageCode => "pt-PT",
417             LanguageName => "Portuguese",
418             Name => "Inês",
419             },
420             {
421             Gender => "Male",
422             Id => "Cristiano",
423             LanguageCode => "pt-PT",
424             LanguageName => "Portuguese",
425             Name => "Cristiano",
426             },
427             {
428             Gender => "Female",
429             Id => "Carmen",
430             LanguageCode => "ro-RO",
431             LanguageName => "Romanian",
432             Name => "Carmen",
433             },
434             {
435             Gender => "Female",
436             Id => "Tatyana",
437             LanguageCode => "ru-RU",
438             LanguageName => "Russian",
439             Name => "Tatyana",
440             },
441             {
442             Gender => "Male",
443             Id => "Maxim",
444             LanguageCode => "ru-RU",
445             LanguageName => "Russian",
446             Name => "Maxim",
447             },
448             {
449             Gender => "Female",
450             Id => "Astrid",
451             LanguageCode => "sv-SE",
452             LanguageName => "Swedish",
453             Name => "Astrid",
454             },
455             {
456             Gender => "Female",
457             Id => "Filiz",
458             LanguageCode => "tr-TR",
459             LanguageName => "Turkish",
460             Name => "Filiz",
461             },
462             ];
463             }
464              
465             #-------------------------------------------------------------------------------
466             # Test
467             #-------------------------------------------------------------------------------
468              
469             sub test
470 1 50   1 0 514 {eval join('', ) || die $@
  1     1   53139  
  1         7  
  1         187  
471             }
472              
473             test unless caller();
474              
475             # Documentation
476             #extractDocumentation unless caller;
477              
478             #-------------------------------------------------------------------------------
479             # Export
480             #-------------------------------------------------------------------------------
481              
482             require Exporter;
483              
484 1     1   6 use vars qw(@ISA @EXPORT @EXPORT_OK %EXPORT_TAGS);
  1         2  
  1         105  
485              
486             @ISA = qw(Exporter);
487             @EXPORT = qw();
488             @EXPORT_OK = qw();
489             %EXPORT_TAGS = (all=>[@EXPORT, @EXPORT_OK]);
490              
491             1;
492              
493             =pod
494              
495             =encoding utf-8
496              
497             =head1 Name
498              
499             Aws::Polly::Select - Select AWS Polly speakers with specified characteristics
500              
501             =head1 Synopsis
502              
503             use Aws::Polly::Select;
504              
505             my ($speaker) = Aws::Polly::Select::speaker
506             LanguageCode => qr(us)i,
507             Gender => qr(female)i,
508             LanguageName => qr(Spanish)i;
509              
510             ok $speaker->Id eq q(Penelope);
511              
512             =head1 Description
513              
514             Aws::Polly::Select::speaker(key=>qr(value), ...)
515              
516             Returns zero or more Amazon Web Services Polly speaker definitions which match
517             the hash of characteristics provided. Each hash B must name one of the
518             Bs given below, the value for the key should be a regular expression to
519             select against the possible B listed beside each key. Please take care
520             with the case of the values or use B to make the selection case
521             insensitive.
522              
523             KEY VALUES
524              
525             Gender Female Male
526              
527             Id Aditi Amy Astrid Brian Carla Carmen Celine Chantal Conchita
528             Cristiano Dora Emma Enrique Ewa Filiz Geraint Giorgio Gwyneth Hans Ines Ivy
529             Jacek Jan Joanna Joey Justin Karl Kendra Kimberly Liv Lotte Mads Maja Marlene
530             Mathieu Matthew Maxim Miguel Mizuki Naja Nicole Penelope Raveena Ricardo Ruben
531             Russell Salli Seoyeon Takumi Tatyana Vicki Vitoria
532              
533             LanguageCode cy-GB da-DK de-DE en-AU en-GB en-GB-WLS en-IN en-US es-ES es-US
534             fr-CA fr-FR is-IS it-IT ja-JP ko-KR nb-NO nl-NL pl-PL pt-BR pt-PT ro-RO ru-RU
535             sv-SE tr-TR
536              
537             LanguageName Australian English Brazilian Portuguese British English Canadian
538             French Castilian Spanish Danish Dutch French German Icelandic Indian English
539             Italian Japanese Korean Norwegian Polish Portuguese Romanian Russian Swedish
540             Turkish US English US Spanish Welsh Welsh English
541              
542             Written cy da de en es fr is it ja ko nb nl pl pt ro ru sv tr
543              
544             The above Bs can be used as methods to get the corresponding B's
545             from each speaker defintion returned by L.
546              
547             ok $speaker->LanguageCode eq q(es-US);
548              
549             =head2 speakerIds()
550              
551             Use speakerIds() to get a hash of speaker details by speaker id:
552              
553             my $speaker = Aws::Polly::Select::speakerIds->{Vicki};
554              
555             is_deeply $speaker,
556             {Gender => "Female",
557             Id => "Vicki",
558             LanguageCode => "de-DE",
559             LanguageName => "German",
560             Name => "Vicki",
561             Written => "de",
562             };
563              
564             Each of the fields describing a speaker may be accessed as a method, for example:
565              
566             ok $speaker->Gender eq "Female";
567             ok $speaker->LanguageName eq "German";
568             ok $speaker->Written eq "de";
569              
570             =head1 Installation
571              
572             Standard Module::Build process for building and installing modules:
573              
574             perl Build.PL
575             ./Build
576             ./Build test
577             ./Build install
578              
579             =head1 Author
580              
581             philiprbrenan@gmail.com
582              
583             http://www.appaapps.com
584              
585             =head1 Copyright
586              
587             Copyright (c) 2017 Philip R Brenan.
588              
589             This module is free software. It may be used, redistributed and/or modified
590             under the same terms as Perl itself.
591              
592             =cut
593              
594             __DATA__