File Coverage

blib/lib/Net/Amazon/MechanicalTurk/BulkSupport.pm
Criterion Covered Total %
statement 18 100 18.0
branch 0 40 0.0
condition 0 3 0.0
subroutine 5 20 25.0
pod 0 13 0.0
total 23 176 13.0


line stmt bran cond sub pod time code
1             package Net::Amazon::MechanicalTurk::BulkSupport;
2 2     2   12 use strict;
  2         3  
  2         68  
3 2     2   9 use warnings;
  2         6  
  2         53  
4 2     2   1237 use Net::Amazon::MechanicalTurk::Template::ReplacementTemplate;
  2         7  
  2         64  
5 2     2   1268 use Net::Amazon::MechanicalTurk::DelimitedWriter;
  2         8  
  2         3179  
6              
7             our $VERSION = '1.00';
8              
9             =head1 NAME
10              
11             Net::Amazon::MechanicalTurk::BulkSupport - Common code for bulk HIT operations
12              
13             =cut
14              
15             #
16             # The purpose of these alias mappings is to support
17             # the names used by the JavaSDK which don't quite match
18             # the names actually used by the web service.
19             #
20              
21             my $CREATE_HITTYPE_PROPERTY_ALIASES = reverseLookup({
22             Title => [qw{ title }],
23             Description => [qw{ description }],
24             Keywords => [qw{ keywords }],
25             AutoApprovalDelayInSeconds => [qw{ autoapprovaldelayinseconds autoapprovaldelay }],
26             AssignmentDurationInSeconds => [qw{ assignmentdurationinseconds assignmentduration }],
27             Reward => [qw{ reward }],
28             QualificationRequirements => [qw{ qualificationrequirements }]
29             });
30              
31             my $CREATE_HIT_PROPERTY_ALIASES = reverseLookup({
32             LifetimeInSeconds => [qw{ lifetimeinseconds hitlifetime }],
33             MaxAssignments => [qw{ maxassignments assignments }],
34             RequesterAnnotation => [qw{ requesterannotation annotation }]
35             });
36              
37             sub progressBlock {
38 0     0 0 0 my ($progress) = @_;
39 0 0       0 if (!defined($progress)) {
    0          
    0          
40 0         0 return $progress;
41             }
42             elsif (UNIVERSAL::isa($progress, "CODE")) {
43 0         0 return $progress;
44             }
45             elsif (UNIVERSAL::isa($progress, "GLOB")) {
46             return sub {
47 0     0   0 print $progress @_, "\n";
48 0         0 };
49             }
50             else {
51 0         0 Carp::croak("The progress parameters should be an IO handle or a subroutine.");
52             }
53             }
54              
55 0     0 0 0 sub defaultSuccessBlock {}
56              
57             sub defaultFailBlock {
58 0     0 0 0 my %params = @_;
59 0         0 die $params{error};
60             }
61              
62             sub successBlock {
63 0     0 0 0 my ($success) = @_;
64 0 0       0 if (!defined($success)) {
    0          
65 0         0 return \&defaultSuccessBlock;
66             }
67             elsif (UNIVERSAL::isa($success, "CODE")) {
68 0         0 return $success;
69             }
70             else {
71 0         0 return createSuccessBlock($success);
72             }
73             }
74              
75             sub createSuccessBlock {
76 0     0 0 0 my ($file) = @_;
77 0         0 my $out;
78 0         0 my $rowNumber = 0;
79 0 0       0 if (UNIVERSAL::isa($file, "GLOB")) {
    0          
80 0         0 $out = Net::Amazon::MechanicalTurk::DelimitedWriter->new(
81             output => $file,
82             fieldSeparator => "\t"
83             );
84             }
85             elsif (UNIVERSAL::isa($file, "Net::Amazon::MechanicalTurk::DelimitedWriter")) {
86 0         0 $out = $file;
87             }
88             else {
89 0 0       0 my $fs = ($file =~ /\.csv$/i) ? "," : "\t";
90 0         0 $out = Net::Amazon::MechanicalTurk::DelimitedWriter->new(
91             lazy => 1,
92             file => $file,
93             fieldSeparator => $fs,
94             autoflush => 1
95             );
96             }
97             return sub {
98 0     0   0 my %params = @_;
99 0 0       0 if ($rowNumber++ == 0) {
100 0         0 $out->write(qw{ HITId HITTypeId });
101             }
102 0         0 $out->write($params{HITId}, $params{HITTypeId});
103 0         0 };
104             }
105              
106             sub failBlock {
107 0     0 0 0 my ($fail) = @_;
108 0 0       0 if (!defined($fail)) {
    0          
109 0         0 return \&defaultFailBlock;
110             }
111             elsif (UNIVERSAL::isa($fail, "CODE")) {
112 0         0 return $fail;
113             }
114             else {
115 0         0 return createFailBlock($fail);
116             }
117             }
118              
119             sub createFailBlock {
120 0     0 0 0 my ($file) = @_;
121 0         0 my $out;
122 0         0 my $rowNumber = 0;
123 0 0       0 if (UNIVERSAL::isa($file, "GLOB")) {
    0          
124 0         0 $out = Net::Amazon::MechanicalTurk::DelimitedWriter->new(
125             output => $file,
126             fieldSeparator => "\t"
127             );
128             }
129             elsif (UNIVERSAL::isa($file, "Net::Amazon::MechanicalTurk::DelimitedWriter")) {
130 0         0 $out = $file;
131             }
132             else {
133 0 0       0 my $fs = ($file =~ /\.csv$/i) ? "," : "\t";
134 0         0 $out = Net::Amazon::MechanicalTurk::DelimitedWriter->new(
135             lazy => 1,
136             file => $file,
137             fieldSeparator => $fs,
138             autoflush => 1
139             );
140             }
141             return sub {
142 0     0   0 my %params = @_;
143 0         0 my $fields = $params{fields};
144 0 0       0 if ($rowNumber++ == 0) {
145 0         0 $out->write($fields);
146             }
147             # Have to use the field names to preserve order of columns
148 0         0 my @row;
149 0         0 for (my $i=0; $i<=$#{$fields}; $i++) {
  0         0  
150 0         0 push(@row, $params{row}{$fields->[$i]});
151             }
152 0         0 $out->write(@row);
153 0         0 };
154             }
155              
156             sub formatDataStructure {
157 0     0 0 0 my ($ds, $indent) = @_;
158 0         0 my $text = Net::Amazon::MechanicalTurk::DataStructure->toString($ds);
159 0         0 my $out = '';
160 0         0 foreach my $line (split /\r?\n/s, $text) {
161 0         0 $out .= ' ' x $indent;
162 0         0 $out .= $line . "\n";
163             }
164 0         0 return $out;
165             }
166              
167             sub createHITType {
168 0     0 0 0 my ($mturk, $createHITTypeProperties, $properties, $progress) = @_;
169            
170 0         0 my $hitTypeId = $mturk->RegisterHITType($createHITTypeProperties)->{HITTypeId}[0];
171 0 0       0 $progress->(" Registered HITType $hitTypeId.") if $progress;
172            
173             # Properties have notification specs
174 0 0       0 if (exists $properties->{Notification}) {
175 0         0 $mturk->SetHITTypeNotification(
176             HITTypeId => $hitTypeId,
177             Active => 'true',
178             Notification => $properties->{Notification}
179             );
180 0 0       0 $progress->("SetHITTypeNotification on $hitTypeId.") if $progress;
181             }
182            
183 0         0 return $hitTypeId;
184             }
185              
186             sub getCreateHITTypeProperties {
187 0     0 0 0 my ($properties) = @_;
188 0         0 my $createHITTypeProperties = extractAliasProperties($properties, $CREATE_HITTYPE_PROPERTY_ALIASES);
189             # Special handling for reward specified as only a dollar amount in properties file
190 0 0 0     0 if (exists $createHITTypeProperties->{Reward} and
191             !ref($createHITTypeProperties->{Reward}))
192             {
193 0         0 $createHITTypeProperties->{Reward} = {
194             Amount => $createHITTypeProperties->{Reward},
195             CurrencyCode => 'USD'
196             };
197             }
198 0         0 return $createHITTypeProperties;
199             }
200              
201             sub getCreateHITProperties {
202 0     0 0 0 my ($properties) = @_;
203             # Some of the properties for a hit may have values that come from the input data.
204 0         0 my $createHITProperties = extractAliasProperties($properties, $CREATE_HIT_PROPERTY_ALIASES);
205 0         0 foreach my $key (keys %$createHITProperties) {
206 0         0 $createHITProperties->{$key} = Net::Amazon::MechanicalTurk::Template::ReplacementTemplate->new(
207             templateSource => $createHITProperties->{$key}
208             );
209             }
210 0         0 return $createHITProperties;
211             }
212              
213             sub extractAliasProperties {
214 0     0 0 0 my ($properties, $aliases) = @_;
215 0         0 my $result = {};
216 0         0 while (my ($prop,$value) = each %$properties) {
217 0         0 $prop = $aliases->{lc($prop)};
218 0 0       0 if (defined($prop)) {
219 0         0 $result->{$prop} = $value;
220             }
221             }
222 0         0 return $result;
223             }
224              
225             sub reverseLookup {
226 4     4 0 7 my $inHash = shift;
227 4         10 my $outHash = {};
228 4         22 while (my ($key,$array) = each %$inHash) {
229 20         31 foreach my $value (@$array) {
230 30         4504 $outHash->{lc($value)} = $key;
231             }
232             }
233 4         9 return $outHash;
234             }
235              
236             return 1;