dbgrandi-ruby-aws 1.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
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 +261 -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 +158 -0
@@ -0,0 +1,10 @@
1
+ # Copyright:: Copyright (c) 2007 Amazon Technologies, Inc.
2
+ # License:: Apache License, Version 2.0
3
+
4
+ require 'amazon/util/logging'
5
+ require 'amazon/util/paginated_iterator'
6
+ require 'amazon/util/lazy_results'
7
+ require 'amazon/util/proactive_results'
8
+ require 'amazon/util/binder'
9
+ require 'amazon/util/data_reader'
10
+ require 'amazon/util/threadpool'
@@ -0,0 +1,44 @@
1
+ # Copyright:: Copyright (c) 2007 Amazon Technologies, Inc.
2
+ # License:: Apache License, Version 2.0
3
+
4
+ require 'erb'
5
+
6
+ module Amazon
7
+ module Util
8
+
9
+ # Simple class for holding eval information
10
+ # useful for feeding to ERB templates and the like
11
+ class Binder
12
+
13
+ def initialize(initial={},&block) # :yields: self
14
+ initial.each {|k,v| set(k,v) }
15
+ yield self unless block.nil?
16
+ end
17
+
18
+ def merge(hash)
19
+ hash.each {|k,v| set(k,v) }
20
+ end
21
+
22
+ def set(k,v)
23
+ self.instance_variable_set "@#{k.to_s}", "#{v.to_s}"
24
+ end
25
+
26
+ def bind
27
+ binding
28
+ end
29
+
30
+ # Helper method to simplify ERB evaluation
31
+ def erb_eval( template )
32
+ buffer = ""
33
+ c = ERB::Compiler.new("")
34
+ c.put_cmd = "buffer <<" if c.respond_to? :put_cmd=
35
+ c.insert_cmd = "buffer <<" if c.respond_to? :insert_cmd=
36
+ compiled = c.compile template
37
+ eval compiled
38
+ return buffer
39
+ end
40
+
41
+ end # Binder
42
+
43
+ end # Amazon::Util
44
+ end # Amazon
@@ -0,0 +1,157 @@
1
+ # Copyright:: Copyright (c) 2007 Amazon Technologies, Inc.
2
+ # License:: Apache License, Version 2.0
3
+
4
+ require 'yaml'
5
+ require 'csv'
6
+ require 'amazon/util/hash_nesting'
7
+
8
+ module Amazon
9
+ module Util
10
+
11
+ # DataReader is a class for loading in data files. It is used to support bulk file-based operations.
12
+ # DataReader supports a number of different formats:
13
+ # * YAML
14
+ # * Tabular
15
+ # * CSV
16
+ # * Java Properties
17
+ # By default, DataReader assumes Tabular, but load and save both support your choice of format
18
+ class DataReader
19
+
20
+ attr_accessor :data
21
+
22
+ def initialize(data=[])
23
+ @data = data
24
+ end
25
+
26
+ def [](index)
27
+ return @data[index]
28
+ end
29
+
30
+ def []=(index)
31
+ return @data[index]
32
+ end
33
+
34
+ def load( filename, format=:Tabular )
35
+ return {} unless File.exists? filename
36
+ raw_data = File.read( filename )
37
+ case format
38
+ when :Tabular
39
+ @data = parse_csv( raw_data, "\t" )
40
+ when :YAML
41
+ @data = YAML.load( raw_data ) || {}
42
+ when :CSV
43
+ @data = parse_csv( raw_data )
44
+ when :Properties
45
+ @data = parse_properties( raw_data )
46
+ else
47
+ raise "invalid format. options are :Tabular, :YAML, :CSV, :Properties"
48
+ end
49
+ end
50
+
51
+ def save( filename, format=:Tabular, force_headers=false )
52
+ return if @data.nil? or @data.empty?
53
+ existing = File.exists?( filename ) && File.size( filename ) > 0
54
+ File.open( filename, 'a+' ) {|f|
55
+ f << case format
56
+ when :Tabular
57
+ generate_csv( @data, force_headers || !existing, "\t" )
58
+ when :YAML
59
+ YAML.dump( @data )
60
+ when :CSV
61
+ generate_csv( @data, force_headers || !existing )
62
+ when :Properties
63
+ generate_properties( @data )
64
+ end
65
+ f << "\n" # adding a newline on the end, so appending is happy
66
+ }
67
+ end
68
+
69
+ def self.load( filename, format=:Tabular )
70
+ reader = DataReader.new()
71
+ reader.load( filename, format )
72
+ end
73
+
74
+ def self.save( filename, data, format=:Tabular, force_headers=false )
75
+ reader = DataReader.new( data )
76
+ reader.save( filename, format, force_headers )
77
+ end
78
+
79
+ private
80
+
81
+ def parse_csv( raw_data, delim=nil )
82
+ processed = []
83
+ rows = CSV.parse( raw_data, delim )
84
+ return parse_rows( rows )
85
+ end
86
+
87
+ def parse_rows( rows )
88
+ processed = []
89
+ headers = rows.shift
90
+ for row in rows
91
+ item = {}
92
+ headers.each_index do |i|
93
+ item[headers[i].to_sym] = correct_type(row[i]) unless row[i].nil? or row[i].empty?
94
+ end
95
+ item.extend HashNesting
96
+ processed << item.unnest
97
+ end
98
+ return processed
99
+ end
100
+
101
+ def split_data( data )
102
+ data = data.collect {|d| d.extend(HashNesting).nest }
103
+ headers = data[0].keys.sort
104
+ rows = data.collect { |item|
105
+ row = []
106
+ item.keys.each {|k|
107
+ headers << k unless headers.include? k
108
+ index = headers.index k
109
+ row[index] = item[k].to_s
110
+ }
111
+ row
112
+ }
113
+ return headers, rows
114
+ end
115
+
116
+ def generate_csv( data, dump_header, delim=nil )
117
+ return "" if data.nil? or data.empty?
118
+ headers, rows = split_data( data )
119
+ return generate_rows( headers, rows, dump_header, delim )
120
+ end
121
+
122
+ def generate_rows( headers, rows, dump_header, record_seperator=nil )
123
+ rows.unshift headers if dump_header
124
+ buff = rows.collect { |row|
125
+ CSV.generate_line( row, record_seperator )
126
+ }
127
+ return buff.join("\n")
128
+ end
129
+
130
+ def parse_properties( raw_data )
131
+ processed = {}
132
+ for line in raw_data.split(/\n\r?/)
133
+ next if line =~ /^\W*(#.*)?$/ # ignore lines beginning w/ comments
134
+ if md = /^([^:=]+)[=:](.*)/.match(line)
135
+ processed[md[1].strip] = correct_type(md[2].strip)
136
+ end
137
+ end
138
+ processed.extend HashNesting
139
+ return processed.unnest
140
+ end
141
+
142
+ def generate_properties( raw_data )
143
+ raw_data.extend HashNesting
144
+ (raw_data.nest.collect {|k,v| "#{k}:#{v}" }).join("\n")
145
+ end
146
+
147
+ # convert to integer if possible
148
+ def correct_type( str )
149
+ return str.to_f if str =~ /^\d+\.\d+$/ unless str =~ /^0\d/
150
+ return str.to_i if str =~ /^\d+$/ unless str =~ /^0\d/
151
+ return str
152
+ end
153
+
154
+ end # DataReader
155
+
156
+ end # Amazon::Util
157
+ end # Amazon
@@ -0,0 +1,79 @@
1
+ # Copyright:: Copyright (c) 2007 Amazon Technologies, Inc.
2
+ # License:: Apache License, Version 2.0
3
+
4
+ module Amazon
5
+ module Util
6
+
7
+ # A class for managing around style interceptors,
8
+ # which can be used to implement a decorator design pattern.
9
+ class FilterChain
10
+
11
+ class Filter
12
+
13
+ attr_reader :name, :filter_params, :filter_block
14
+
15
+ def initialize( name, filter_params, filter_block )
16
+ @name = name
17
+ @filter_params = filter_params
18
+ @filter_block = filter_block
19
+ end
20
+
21
+ def execute( chain, block_params )
22
+ @filter_block.call( chain, block_params, *@filter_params )
23
+ end
24
+
25
+ end
26
+
27
+ attr_reader :filters
28
+
29
+ def initialize()
30
+ @filters = []
31
+ end
32
+
33
+ def execute( *block_params, &block )
34
+ if @filters.size == 0
35
+ block.call( *block_params )
36
+ else
37
+ create_chain( @filters, 0, block, block_params ).call
38
+ end
39
+ end
40
+
41
+ def add( name=nil, *filter_params, &filter_block )
42
+ add_filter( Filter.new( name, filter_params, filter_block ) )
43
+ end
44
+
45
+ def add_filter( filter )
46
+ if !filter.name.nil?
47
+ @filters.each_with_index { |existing_filter,i|
48
+ if filter.name == existing_filter.name
49
+ @filters[i] = filter
50
+ return
51
+ end
52
+ }
53
+ end
54
+ @filters << filter
55
+ end
56
+
57
+ def remove( name )
58
+ @filters.delete_if { |filter| name == filter.name }
59
+ end
60
+
61
+ def remove_all()
62
+ @filters.clear
63
+ end
64
+
65
+ private
66
+
67
+ def create_chain( filters, pos, block, block_params )
68
+ if pos >= filters.size
69
+ return proc{ block.call( *block_params ) }
70
+ else
71
+ chain = create_chain( filters, pos+1, block, block_params )
72
+ return proc { filters[pos].execute( chain, block_params ) }
73
+ end
74
+ end
75
+
76
+ end
77
+
78
+ end # Amazon::Util
79
+ end # Amazon
@@ -0,0 +1,93 @@
1
+ # Copyright:: Copyright (c) 2007 Amazon Technologies, Inc.
2
+ # License:: Apache License, Version 2.0
3
+
4
+ module Amazon
5
+ module Util
6
+
7
+ module HashNesting
8
+
9
+ def nest
10
+ result = {}.extend HashNesting
11
+ primaryKeys.each { |key| traverse_nest( "#{key}", self[key] ) { |k,v| result[k] = v } }
12
+ result
13
+ end
14
+
15
+ def nest!
16
+ keys = primaryKeys
17
+ tmp = self.dup
18
+ self.keys.each { |k| self.delete k}
19
+ keys.each { |key| traverse_nest( "#{key}", tmp[key] ) { |k,v| self[k] = v} }
20
+ self
21
+ end
22
+
23
+ def unnest
24
+ result = {}.extend HashNesting
25
+ for key in primaryKeys
26
+ true_keys = key.to_s.split('.')
27
+ resolve_nesting( result, self[key], *true_keys)
28
+ end
29
+ result
30
+ end
31
+
32
+ def unnest!
33
+ for key in primaryKeys
34
+ true_keys = key.to_s.split('.')
35
+ value = self[key]
36
+ self.delete key
37
+ resolve_nesting( self, value, *true_keys)
38
+ end
39
+ self
40
+ end
41
+
42
+ private
43
+
44
+ # if hash has both string and symbol keys, symbol wins
45
+ def primaryKeys
46
+ sym_keys = []
47
+ str_keys = []
48
+ self.keys.each { |k|
49
+ case k
50
+ when Symbol
51
+ sym_keys << k
52
+ when String
53
+ str_keys << k
54
+ else
55
+ str_keys << k
56
+ end
57
+ }
58
+ str_keys.delete_if {|k| sym_keys.member? k.to_s.to_sym }
59
+ sym_keys + str_keys
60
+ end
61
+
62
+ def resolve_nesting( dest, data, *keys )
63
+ return data if keys.empty?
64
+ dest ||= {}
65
+ key = keys.shift.to_sym
66
+ if keys.first.to_i.to_s == keys.first
67
+ # array
68
+ index = keys.shift.to_i - 1
69
+ raise "illegal index: #{keys.join '.'} index must be >= 1" if index < 0
70
+ dest[key] ||= []
71
+ dest[key][index] = resolve_nesting( dest[key][index], data, *keys )
72
+ else
73
+ # hash
74
+ dest[key] = resolve_nesting( dest[key], data, *keys )
75
+ end
76
+ dest
77
+ end
78
+
79
+ def traverse_nest( namespace, data, &block )
80
+ case data.class.to_s
81
+ when 'Array'
82
+ data.each_with_index { |v,i| traverse_nest( "#{namespace}.#{i+1}", v, &block ) }
83
+ when 'Hash'
84
+ data.each { |k,v| traverse_nest( "#{namespace}.#{k}", v, &block ) }
85
+ else
86
+ yield namespace, data.to_s
87
+ end
88
+ end
89
+
90
+ end # HashNesting
91
+
92
+ end # Amazon::Util
93
+ end # Amazon
@@ -0,0 +1,59 @@
1
+ # Copyright:: Copyright (c) 2007 Amazon Technologies, Inc.
2
+ # License:: Apache License, Version 2.0
3
+
4
+ require 'amazon/util/paginated_iterator'
5
+
6
+ module Amazon
7
+ module Util
8
+
9
+ # This class provides a wrapper for lazy evaluation of results.
10
+ # The constructor takes a block which should accept a pagenumber
11
+ # and return a page worth of results.
12
+ class LazyResults
13
+ include Enumerable
14
+
15
+ def initialize( &feeder )
16
+ @iterator = PaginatedIterator.new( &feeder )
17
+ flush
18
+ end
19
+
20
+ # clear the result set and start over again
21
+ def flush
22
+ @truth = []
23
+ @iterator.restart
24
+ end
25
+
26
+ # iterate over entire result set, loading lazily
27
+ def each( &block ) # :yields: item
28
+ @truth.each {|e| yield e }
29
+ @iterator.each {|e| @truth << e ; yield e }
30
+ end
31
+
32
+ # index into the array set. if requested index has not been loaded, will load up to that index
33
+ def []( index )
34
+ feedme while !@iterator.done and index >= @truth.size
35
+ return @truth[index]
36
+ end
37
+
38
+ # fully populate the result set and return a true array
39
+ def to_a
40
+ feedme until @iterator.done
41
+ return @truth.dup
42
+ end
43
+
44
+ def inspect # :nodoc:
45
+ "#<Amazon::Util::LazyResults truth_size=#{@truth.size} page=#{@page} done=#{@done}>"
46
+ end
47
+
48
+ private
49
+
50
+ # fetch the next item from the iterator and stick it in @truth
51
+ def feedme
52
+ item = @iterator.next
53
+ @truth << item unless item.nil?
54
+ end
55
+
56
+ end # LazyResults
57
+
58
+ end # Amazon::Util
59
+ end # Amazon