sprout-ruby-aws 1.2.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (70) hide show
  1. data/History.txt +38 -0
  2. data/LICENSE.txt +202 -0
  3. data/Manifest.txt +69 -0
  4. data/NOTICE.txt +4 -0
  5. data/README.txt +105 -0
  6. data/Rakefile +20 -0
  7. data/bin/ruby-aws +9 -0
  8. data/lib/amazon/util.rb +10 -0
  9. data/lib/amazon/util/binder.rb +44 -0
  10. data/lib/amazon/util/data_reader.rb +157 -0
  11. data/lib/amazon/util/filter_chain.rb +79 -0
  12. data/lib/amazon/util/hash_nesting.rb +93 -0
  13. data/lib/amazon/util/lazy_results.rb +59 -0
  14. data/lib/amazon/util/logging.rb +23 -0
  15. data/lib/amazon/util/paginated_iterator.rb +70 -0
  16. data/lib/amazon/util/proactive_results.rb +116 -0
  17. data/lib/amazon/util/threadpool.rb +129 -0
  18. data/lib/amazon/util/user_data_store.rb +100 -0
  19. data/lib/amazon/webservices/mechanical_turk.rb +117 -0
  20. data/lib/amazon/webservices/mechanical_turk_requester.rb +340 -0
  21. data/lib/amazon/webservices/mturk/mechanical_turk_error_handler.rb +136 -0
  22. data/lib/amazon/webservices/mturk/question_generator.rb +58 -0
  23. data/lib/amazon/webservices/util/amazon_authentication_relay.rb +64 -0
  24. data/lib/amazon/webservices/util/command_line.rb +156 -0
  25. data/lib/amazon/webservices/util/convenience_wrapper.rb +90 -0
  26. data/lib/amazon/webservices/util/filter_proxy.rb +45 -0
  27. data/lib/amazon/webservices/util/mock_transport.rb +70 -0
  28. data/lib/amazon/webservices/util/request_signer.rb +42 -0
  29. data/lib/amazon/webservices/util/rest_transport.rb +108 -0
  30. data/lib/amazon/webservices/util/soap_simplifier.rb +48 -0
  31. data/lib/amazon/webservices/util/soap_transport.rb +38 -0
  32. data/lib/amazon/webservices/util/soap_transport_header_handler.rb +27 -0
  33. data/lib/amazon/webservices/util/unknown_result_exception.rb +27 -0
  34. data/lib/amazon/webservices/util/validation_exception.rb +55 -0
  35. data/lib/amazon/webservices/util/xml_simplifier.rb +61 -0
  36. data/lib/ruby-aws.rb +21 -0
  37. data/lib/ruby-aws/version.rb +8 -0
  38. data/samples/mturk/best_image/BestImage.rb +61 -0
  39. data/samples/mturk/best_image/best_image.properties +39 -0
  40. data/samples/mturk/best_image/best_image.question +82 -0
  41. data/samples/mturk/blank_slate/BlankSlate.rb +63 -0
  42. data/samples/mturk/blank_slate/BlankSlate_multithreaded.rb +67 -0
  43. data/samples/mturk/helloworld/MTurkHelloWorld.rb +56 -0
  44. data/samples/mturk/helloworld/mturk.yml +8 -0
  45. data/samples/mturk/reviewer/Reviewer.rb +103 -0
  46. data/samples/mturk/reviewer/mturk.yml +8 -0
  47. data/samples/mturk/simple_survey/SimpleSurvey.rb +90 -0
  48. data/samples/mturk/simple_survey/simple_survey.question +30 -0
  49. data/samples/mturk/site_category/SiteCategory.rb +87 -0
  50. data/samples/mturk/site_category/externalpage.htm +71 -0
  51. data/samples/mturk/site_category/site_category.input +6 -0
  52. data/samples/mturk/site_category/site_category.properties +45 -0
  53. data/samples/mturk/site_category/site_category.question +9 -0
  54. data/test/mturk/test_changehittypeofhit.rb +130 -0
  55. data/test/mturk/test_error_handler.rb +135 -0
  56. data/test/mturk/test_mechanical_turk_requester.rb +178 -0
  57. data/test/mturk/test_mock_mechanical_turk_requester.rb +205 -0
  58. data/test/test_ruby-aws.rb +22 -0
  59. data/test/unit/test_binder.rb +89 -0
  60. data/test/unit/test_data_reader.rb +135 -0
  61. data/test/unit/test_exceptions.rb +32 -0
  62. data/test/unit/test_hash_nesting.rb +93 -0
  63. data/test/unit/test_lazy_results.rb +89 -0
  64. data/test/unit/test_mock_transport.rb +132 -0
  65. data/test/unit/test_paginated_iterator.rb +58 -0
  66. data/test/unit/test_proactive_results.rb +108 -0
  67. data/test/unit/test_question_generator.rb +54 -0
  68. data/test/unit/test_threadpool.rb +50 -0
  69. data/test/unit/test_user_data_store.rb +80 -0
  70. metadata +177 -0
@@ -0,0 +1,61 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ # Copyright:: Copyright (c) 2007 Amazon Technologies, Inc.
4
+ # License:: Apache License, Version 2.0
5
+
6
+ begin ; require 'rubygems' ; rescue LoadError ; end
7
+
8
+ # The Best Image sample application will create a HIT asking a worker
9
+ # to choose the best of three images, given a set of criteria.
10
+ #
11
+ # The following concepts are covered:
12
+ # - Using the <FormattedContent> functionality in QuestionForm
13
+ # - File-based QuestionForm and HIT properties HIT loading
14
+ # - Using a basic system qualification
15
+
16
+ require 'ruby-aws'
17
+ @mturk = Amazon::WebServices::MechanicalTurkRequester.new :Host => :Sandbox
18
+
19
+ # Use this line instead if you want to talk to Prod
20
+ #@mturk = Amazon::WebServices::MechanicalTurkRequester.new :Host => :Production
21
+
22
+
23
+ # Check to see if your account has sufficient funds
24
+ def hasEnoughFunds?
25
+ available = @mturk.availableFunds
26
+ puts "Got account balance: %.2f" % available
27
+ return available > 0.055
28
+ end
29
+
30
+ def getHITUrl( hitTypeId )
31
+ if @mturk.host =~ /sandbox/
32
+ "http://workersandbox.mturk.com/mturk/preview?groupId=#{hitTypeId}" # Sandbox Url
33
+ else
34
+ "http://mturk.com/mturk/preview?groupId=#{hitTypeId}" # Production Url
35
+ end
36
+ end
37
+
38
+ # Create the BestImage HIT
39
+ def createBestImage
40
+
41
+ # Defining the location of the file containing the QuestionForm and the properties of the HIT
42
+ rootDir = File.dirname $0;
43
+ questionFile = rootDir + "/best_image.question";
44
+ propertiesFile = rootDir + "/best_image.properties";
45
+
46
+ # Loading configuration properties from a HIT properties file.
47
+ # In this sample, the qualification is defined in the properties file.
48
+ props = Amazon::Util::DataReader.load( propertiesFile, :Properties )
49
+ props[:Reward] = { :Amount => 0.05, :CurrencyCode => 'USD'}
50
+ # Loading the question (QuestionForm) file.
51
+ question = File.read( questionFile )
52
+ # no validation
53
+ result = @mturk.createHIT( {:Question => question}.merge(props) )
54
+ puts "Created HIT: #{result[:HITId]}"
55
+ puts "Url: #{getHITUrl( result[:HITTypeId] )}"
56
+
57
+ # save the HIT Id to a file so we don't lose it...
58
+ Amazon::Util::DataReader.save( File.join( rootDir, "hits_created" ), [{:HITId => result[:HITId] }], :Tabular )
59
+ end
60
+
61
+ createBestImage if hasEnoughFunds?
@@ -0,0 +1,39 @@
1
+ ######################################
2
+ ## Basic HIT Properties
3
+ ######################################
4
+
5
+ Title:Select the best image for a given topic
6
+ Description:The task is to select one image out of three that best represents the provided topic given a set of evaluation criteria.
7
+ Keywords:sample, SDK, best, image
8
+ Reward.Amount:0
9
+ Reward.CurrencyCode:USD
10
+ MaxAssignments:1
11
+ RequesterAnnotation:sample#image
12
+
13
+ ######################################
14
+ ## HIT Timing Properties
15
+ ######################################
16
+
17
+ # this Assignment Duration value is 60 * 60 = 1 hour
18
+ AssignmentDurationInSeconds:3600
19
+
20
+ # this HIT Lifetime value is 60*60 = 1 hour
21
+ LifetimeInSeconds:3600
22
+
23
+ # this Auto Approval period is 60*60 = 1 hour
24
+ AutoApprovalDelayInSeconds:3600
25
+
26
+ ######################################
27
+ ## Qualification Properties
28
+ ######################################
29
+
30
+ # Qualifications can be defined in the properties file instead of in code.
31
+ # You can add multiple qualifications for this HIT by simply increasing the # suffix.
32
+ # i.e. qualification.2: XXXXX
33
+ # qualification.comparator.2:greaterthan
34
+
35
+ # this is a built-in qualification -- user must have an approval rate of 25% or greater
36
+ QualificationRequirement.1.QualificationTypeId:000000000000000000L0
37
+ QualificationRequirement.1.Comparator:GreaterThan
38
+ QualificationRequirement.1.IntegerValue:25
39
+ QualificationRequirement.1.RequiredToPreview:false
@@ -0,0 +1,82 @@
1
+ <?xml version="1.0"?>
2
+ <QuestionForm xmlns="http://mechanicalturk.amazonaws.com/AWSMechanicalTurkDataSchemas/2005-10-01/QuestionForm.xsd">
3
+ <Overview>
4
+ <FormattedContent><![CDATA[
5
+ <h1 align="center">Select the best image</h1>
6
+ <h2>Instructions</h2>
7
+ Your task is to select <strong>one</strong> image out of <strong>three</strong> that best represents the provided topic given the evaluation criteria defined below.
8
+ <br/>It is possible that none of the images can satisfy all the evaluation criteria. Your goal is to select the best image of the three.
9
+ <br/>
10
+ <h3>Evaluation Criteria</h3>
11
+ <ul>
12
+ <li>The image should be a representation of the provided topic (i.e. If the topic is Ferris Wheel, you should not select images that are not related to a Ferris Wheel.)</li>
13
+ <li>The image should be in focus. (i.e. not blurry)</li>
14
+ <li>The image should have good color balance. (i.e. not tinted)</li>
15
+ <li>The image should be properly exposed. (i.e. not overexposed/underexposed)</li>
16
+ <li>The image should be composed well. (i.e. not skewed)</li>
17
+ <li>Please refer to the following <a href="http://s3.amazonaws.com/mturk/samples/bestimage/best-image-instructions.html" target="_blank" >link</a> for visual examples of the above criteria.</li>
18
+ </ul>
19
+ <h2>Task</h2>
20
+ ]]></FormattedContent>
21
+ </Overview>
22
+ <Question>
23
+ <QuestionIdentifier>best_image</QuestionIdentifier>
24
+ <IsRequired>true</IsRequired>
25
+ <QuestionContent>
26
+ <FormattedContent><![CDATA[
27
+ <font size="4" color="darkblue" >Select the image below that best represents: Houses of Parliament, London, England</font>
28
+ ]]></FormattedContent>
29
+ </QuestionContent>
30
+ <AnswerSpecification>
31
+ <SelectionAnswer>
32
+ <StyleSuggestion>radiobutton</StyleSuggestion>
33
+ <Selections>
34
+ <Selection>
35
+ <SelectionIdentifier>sample-bestimage-image1.jpg</SelectionIdentifier>
36
+ <Binary>
37
+ <MimeType>
38
+ <Type>image</Type>
39
+ <SubType>jpg</SubType>
40
+ </MimeType>
41
+ <DataURL>http://s3.amazonaws.com/mturk/samples/bestimage/sample-bestimage-image1.jpg</DataURL>
42
+ <AltText>sample-bestimage-image1.jpg</AltText>
43
+ </Binary>
44
+ </Selection>
45
+ <Selection>
46
+ <SelectionIdentifier>sample-bestimage-image2.jpg</SelectionIdentifier>
47
+ <Binary>
48
+ <MimeType>
49
+ <Type>image</Type>
50
+ <SubType>jpg</SubType>
51
+ </MimeType>
52
+ <DataURL>http://s3.amazonaws.com/mturk/samples/bestimage/sample-bestimage-image2.jpg</DataURL>
53
+ <AltText>sample-bestimage-image2.jpg</AltText>
54
+ </Binary>
55
+ </Selection>
56
+ <Selection>
57
+ <SelectionIdentifier>sample-bestimage-image3.jpg</SelectionIdentifier>
58
+ <Binary>
59
+ <MimeType>
60
+ <Type>image</Type>
61
+ <SubType>jpg</SubType>
62
+ </MimeType>
63
+ <DataURL>http://s3.amazonaws.com/mturk/samples/bestimage/sample-bestimage-image3.jpg</DataURL>
64
+ <AltText>sample-bestimage-image3.jpg</AltText>
65
+ </Binary>
66
+ </Selection>
67
+ </Selections>
68
+ </SelectionAnswer>
69
+ </AnswerSpecification>
70
+ </Question>
71
+ <Question>
72
+ <QuestionIdentifier>comments</QuestionIdentifier>
73
+ <QuestionContent>
74
+ <Text>Please help us improve this HIT by including any Questions and/or Comments (optional):</Text>
75
+ </QuestionContent>
76
+ <AnswerSpecification>
77
+ <FreeTextAnswer>
78
+ <NumberOfLinesSuggestion>10</NumberOfLinesSuggestion>
79
+ </FreeTextAnswer>
80
+ </AnswerSpecification>
81
+ </Question>
82
+ </QuestionForm>
@@ -0,0 +1,63 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ # Copyright:: Copyright (c) 2007 Amazon Technologies, Inc.
4
+ # License:: Apache License, Version 2.0
5
+
6
+ begin ; require 'rubygems' ; rescue LoadError ; end
7
+
8
+ # The BlankSlate sample application disposes all of your HITs on sandbox
9
+
10
+ require 'ruby-aws'
11
+ @mturk = Amazon::WebServices::MechanicalTurkRequester.new :Host => :Sandbox
12
+
13
+ def forceExpire(id)
14
+ print "Ensuring HIT #{id} is expired: "
15
+ begin
16
+ @mturk.forceExpireHIT( :HITId => id )
17
+ rescue => e
18
+ raise e unless e.message == 'AWS.MechanicalTurk.InvalidHITState'
19
+ end
20
+ puts "OK"
21
+ end
22
+
23
+ def approveRemainingAssignments(id)
24
+ print "Approving remaining assignments for HIT #{id}: "
25
+ count = 0
26
+ @mturk.getAssignmentsForHITAll( :HITId => id ).each do |assignment|
27
+ @mturk.approveAssignment :AssignmentId => assignment[:AssignmentId] if assignment[:AssignmentStatus] == 'Submitted'
28
+ count += 1
29
+ end
30
+ puts "OK (Approved #{count})"
31
+ end
32
+
33
+ def dispose(id)
34
+ print "Disposing HIT #{id}: "
35
+ @mturk.disposeHIT( :HITId => id )
36
+ puts "OK"
37
+ end
38
+
39
+ def purge
40
+ hit_ids = @mturk.searchHITsAll.collect {|hit| hit[:HITId] }
41
+ puts "Found #{hit_ids.size} HITs"
42
+
43
+ return false if hit_ids.size == 0
44
+
45
+ hit_ids.each do |id|
46
+ begin
47
+ forceExpire id
48
+ approveRemainingAssignments id
49
+ dispose id
50
+ rescue Exception => e
51
+ raise e if e.is_a? Interrupt
52
+ puts e.inspect
53
+ end
54
+ end
55
+
56
+ return true
57
+ end
58
+
59
+ while purge
60
+ puts 'Ensuring there are no more hits...'
61
+ end
62
+
63
+ puts 'You now have a blank slate'
@@ -0,0 +1,67 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ # Copyright:: Copyright (c) 2007 Amazon Technologies, Inc.
4
+ # License:: Apache License, Version 2.0
5
+
6
+ begin ; require 'rubygems' ; rescue LoadError ; end
7
+
8
+ # The BlankSlate sample application disposes all of your HITs on sandbox
9
+
10
+ require 'ruby-aws'
11
+ @mturk = Amazon::WebServices::MechanicalTurkRequester.new :Host => :Sandbox
12
+ require 'amazon/util/threadpool'
13
+
14
+ def forceExpire(id)
15
+ @mturk.forceExpireHIT( :HITId => id )
16
+ rescue
17
+ end
18
+
19
+ def approveRemainingAssignments(id)
20
+ @mturk.getAssignmentsForHITAll( :HITId => id ).each do |assignment|
21
+ begin
22
+ @mturk.approveAssignment :AssignmentId => assignment[:AssignmentId] if assignment[:AssignmentStatus] == 'Submitted'
23
+ rescue
24
+ end
25
+ end
26
+ end
27
+
28
+ def dispose(id)
29
+ @mturk.disposeHIT( :HITId => id )
30
+ end
31
+
32
+ def purge
33
+ puts "*** starting purge ***"
34
+ hit_ids = @mturk.searchHITsAllProactive.collect {|hit| hit[:HITId] }
35
+ puts "Found #{hit_ids.size} HITs"
36
+
37
+ return false if hit_ids.size == 0
38
+
39
+ threadpool = Amazon::Util::ThreadPool.new(12)
40
+
41
+ puts "*** loading work ***"
42
+ hit_ids.each do |hid|
43
+ threadpool.addWork(hid) do |id|
44
+ begin
45
+ puts "starting #{id}"
46
+ forceExpire id
47
+ approveRemainingAssignments id
48
+ dispose id
49
+ puts "cleared #{id}"
50
+ rescue Exception => e
51
+ raise e if e.is_a? Interrupt
52
+ puts e.inspect
53
+ end
54
+ end
55
+ end
56
+ puts "*** finished adding to queue ***"
57
+
58
+ threadpool.finish
59
+
60
+ return true
61
+ end
62
+
63
+ while purge
64
+ puts 'Ensuring there are no more hits...'
65
+ end
66
+
67
+ puts 'You now have a blank slate'
@@ -0,0 +1,56 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ # Copyright:: Copyright (c) 2007 Amazon Technologies, Inc.
4
+ # License:: Apache License, Version 2.0
5
+
6
+ begin ; require 'rubygems' ; rescue LoadError ; end
7
+
8
+ # The MTurk Hello World sample application creates a simple HIT via Libraries for Amazon Web Services.
9
+
10
+ require 'ruby-aws'
11
+ @mturk = Amazon::WebServices::MechanicalTurkRequester.new :Config => File.join( File.dirname(__FILE__), 'mturk.yml' )
12
+
13
+ require 'amazon/webservices/mturk/question_generator'
14
+ include Amazon::WebServices::MTurk
15
+
16
+ def createHelloWorld
17
+ title = "Answer a question"
18
+ desc = "This is a HIT created by the Amazon Mechanical Turk SDK for Ruby. Please answer the question."
19
+ keywords = "sample, SDK, hello"
20
+ numAssignments = 1
21
+ rewardAmount = 0.05 # 5 cents
22
+
23
+ question = QuestionGenerator.build(:Basic) do |q|
24
+ q.ask "What is the weather like right now in Seattle, WA?"
25
+ end
26
+
27
+ puts question
28
+
29
+ result = @mturk.createHIT( :Title => title,
30
+ :Description => desc,
31
+ :MaxAssignments => numAssignments,
32
+ :Reward => { :Amount => rewardAmount, :CurrencyCode => 'USD' },
33
+ :Question => question,
34
+ :Keywords => keywords )
35
+
36
+ puts "Created HIT: #{result[:HITId]}"
37
+ puts "Url: #{getHITUrl( result[:HITTypeId] )}"
38
+ end
39
+
40
+ def getHITUrl( hitTypeId )
41
+ if @mturk.host =~ /sandbox/
42
+ "http://workersandbox.mturk.com/mturk/preview?groupId=#{hitTypeId}" # Sandbox Url
43
+ else
44
+ "http://mturk.com/mturk/preview?groupId=#{hitTypeId}" # Production Url
45
+ end
46
+ end
47
+
48
+ # Check to see if your account has sufficient funds
49
+ def hasEnoughFunds?
50
+ available = @mturk.availableFunds
51
+ puts "Got account balance: %.2f" % available
52
+ return available > 0.055
53
+ end
54
+
55
+
56
+ createHelloWorld if hasEnoughFunds?
@@ -0,0 +1,8 @@
1
+ # Your AWSAccessKeyId ( leave commented to use global default )
2
+ # AWSAccessKeyId: <need access key id>
3
+
4
+ # Your AWSAccessKey ( leave commented to use global default )
5
+ # AWSAccessKey: <need access key>
6
+
7
+ # Host to talk to ( Prod or Sandbox )
8
+ Host: Sandbox
@@ -0,0 +1,103 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ # Copyright:: Copyright (c) 2007 Amazon Technologies, Inc.
4
+ # License:: Apache License, Version 2.0
5
+
6
+ begin ; require 'rubygems' ; rescue LoadError ; end
7
+
8
+ # The Reviewer sample application will retrieve the completed assignments for a given HIT,
9
+ # output the results and approve the assignment.
10
+ #
11
+ # mturk.yml is used to configure default settings ( must be in the same directory as Reviewer.rb )
12
+ # You will need to have the HIT ID of an existing HIT that has been accepted, completed and
13
+ # submitted by a worker.
14
+ # Or you can use the .success file generated from bulk loading several HITs (i.e. Site Category sample application).
15
+ #
16
+ # The following concepts are covered:
17
+ # - Retrieve results for a HIT
18
+ # - Output results for several HITs to a file
19
+ # - Approve assignments
20
+
21
+ require 'ruby-aws'
22
+ @mturk = Amazon::WebServices::MechanicalTurkRequester.new :Config => File.join( File.dirname(__FILE__), 'mturk.yml' )
23
+
24
+ # Prints the submitted results of HITs when provided with a .success file.
25
+ # successFile:: The .success file containing the HIT ID and HIT Type ID
26
+ # outputFile:: The output file to write the submitted results to
27
+ def printResults( successFile, outputFile)
28
+
29
+ # Loads the .success file containing the HIT IDs and HIT Type IDs of HITs to be retrieved.
30
+ success = Amazon::Util::DataReader.load( successFile, :Tabular )
31
+
32
+ # Retrieves the submitted results of the specified HITs from Mechanical Turk
33
+ results = @mturk.getHITResults(success)
34
+
35
+ # parse answers to they're easier to digest
36
+ results.each { |assignment| assignment[:Answers] = @mturk.simplifyAnswer( assignment[:Answer] ) }
37
+
38
+ # Writes the submitted results to the defined output file.
39
+ # The output file is a tab delimited file containing all relevant details
40
+ # of the HIT and assignments. The submitted results are included as the last set of fields
41
+ # and are represented as tab separated question/answer pairs
42
+ Amazon::Util::DataReader.save( outputFile, results, :Tabular )
43
+ puts "Results have been written to: #{outputFile}"
44
+
45
+ end
46
+
47
+ # Prints the submitted results of a HIT when provided with a HIT ID.
48
+ # hitId:: The HIT ID of the HIT to be retrieved.
49
+ def reviewAnswers( hitId )
50
+ assignments = @mturk.getAssignmentsForHITAll( :HITId => hitId, :AssignmentStatus => 'Submitted')
51
+
52
+ puts "--[Reviewing HITs]----------"
53
+ puts " HIT Id: #{hitId}"
54
+
55
+ assignments.each do |assignment|
56
+
57
+ # By default, answers are specified in XML
58
+ answerXML = assignment[:Answer]
59
+
60
+ # Calling a convenience method that will parse the answer XML and extract out the question/answer pairs.
61
+ answers = @mturk.simplifyAnswer( answerXML )
62
+
63
+ answers.each do |id,answer|
64
+ assignmentId = assignment[:AssignmentId]
65
+ puts "Got an answer \"#{answer}\" for \"#{id}\" from worker #{assignment[:WorkerId]}"
66
+ end
67
+
68
+ # Approving the assignment
69
+ @mturk.approveAssignment(:AssignmentId => assignment[:AssignmentId], :RequesterFeedback => "Well Done!")
70
+ puts "Approved."
71
+
72
+ end
73
+ puts "--[End Reviewing HITs]----------"
74
+ end
75
+
76
+ require 'optparse'
77
+ hitsToReview = []
78
+ opts = OptionParser.new
79
+ opts.on( '--review HITId', 'Review Answers for a single HIT ( can be specified multiple times)') {|hit| hitsToReview << hit ; @review = true }
80
+ opts.on( '--results', 'Print Results using input and output files') { @getResults = true }
81
+ opts.on( '--input FILE', 'Input File to get results') {|file| @inputFile = file }
82
+ opts.on( '--output FILE', 'Output File to save results') {|file| @outputFile = file }
83
+
84
+ begin
85
+ opts.parse ARGV
86
+ raise "Please, either --review or --results, not both" if @review && @getResults
87
+ raise "Pick something to do ( either --review or --results )" unless @review || @getResults
88
+ if @getResults
89
+ raise "missing input file" unless @inputFile
90
+ raise "missing output file" unless @outputFile
91
+ raise "input file does not exist: #{@inputFile}" unless File.exists? @inputFile
92
+ end
93
+ rescue => e
94
+ puts e.message
95
+ puts opts.to_s
96
+ exit
97
+ end
98
+
99
+ if @getResults
100
+ printResults( @inputFile, @outputFile )
101
+ elsif @review
102
+ hitsToReview.each {|h| reviewAnswers(h) }
103
+ end