cloudfactory 0.1.9 → 0.1.10

Sign up to get free protection for your applications and to get access to all the features.
Files changed (42) hide show
  1. data/cf.gemspec +1 -0
  2. data/features/error_custom_task_form.feature +117 -0
  3. data/features/error_form_field.feature +58 -0
  4. data/features/error_task_form.feature +64 -0
  5. data/features/errors.feature +192 -0
  6. data/features/run.feature +136 -121
  7. data/features/support/cli_steps.rb +44 -0
  8. data/features/support/env.rb +2 -2
  9. data/lib/cf.rb +3 -4
  10. data/lib/cf/account.rb +12 -1
  11. data/lib/cf/cli.rb +2 -2
  12. data/lib/cf/cli/config.rb +2 -2
  13. data/lib/cf/cli/form.rb +5 -5
  14. data/lib/cf/cli/line.rb +40 -16
  15. data/lib/cf/cli/production.rb +50 -18
  16. data/lib/cf/cli/templates/sample-line/form.css +41 -17
  17. data/lib/cf/cli/templates/sample-line/form.html +27 -18
  18. data/lib/cf/cli/templates/sample-line/form.js +12 -3
  19. data/lib/cf/cli/templates/sample-line/line.yml.erb +42 -32
  20. data/lib/cf/client.rb +3 -3
  21. data/lib/cf/custom_task_form.rb +21 -91
  22. data/lib/cf/department.rb +1 -10
  23. data/lib/cf/final_output.rb +2 -16
  24. data/lib/cf/form_field.rb +11 -6
  25. data/lib/cf/human_worker.rb +93 -1
  26. data/lib/cf/input_format.rb +10 -62
  27. data/lib/cf/line.rb +46 -37
  28. data/lib/cf/robot_worker.rb +63 -2
  29. data/lib/cf/run.rb +37 -66
  30. data/lib/cf/station.rb +42 -104
  31. data/lib/cf/task_form.rb +17 -56
  32. data/lib/cf/version.rb +2 -2
  33. data/lib/generators/cf/form/form_generator.rb +3 -3
  34. data/lib/generators/cf/install/install_generator.rb +3 -3
  35. data/spec/custom_task_form_spec.rb +169 -1
  36. data/spec/generators/form_generator_spec.rb +2 -2
  37. data/spec/generators/install_generator_spec.rb +2 -2
  38. data/spec/run_spec.rb +3 -3
  39. data/spec/spec_helper.rb +1 -0
  40. data/spec/station_spec.rb +13 -1
  41. data/spec/task_form_spec.rb +38 -6
  42. metadata +63 -44
@@ -14,18 +14,19 @@ module CF
14
14
  # ID of an input_format
15
15
  attr_accessor :id
16
16
 
17
- # ID of Line with which input_format is associated
17
+ # Title of Line with which input_format is associated
18
18
  attr_accessor :line_title, :errors
19
19
 
20
20
  # ==Initializes a new input_format
21
- # * Syntax for creating new input_format: <b>InputFormat.new(</b> Hash <b>)</b>
22
21
  # ===Usage Example:
23
22
  # line = CF::Line.create("Digitize", "Survey")
24
23
  #
25
- # attrs = {:line => line,
24
+ # attrs =
25
+ # {
26
26
  # :name => "image_url",
27
27
  # :required => true,
28
- # :valid_type => "url"}
28
+ # :valid_type => "url"
29
+ # }
29
30
  #
30
31
  # input_format = CF::InputFormat.new(attrs)
31
32
  # line.input_formats input_format
@@ -51,14 +52,17 @@ module CF
51
52
  end
52
53
 
53
54
  # ==Returns all the input headers of a specific line
55
+ # ===Usage Example:
54
56
  # line = CF::Line.new("Digitize Card","Survey")
55
57
  #
56
- # attrs_1 = {:line => line,
58
+ # attrs_1 =
59
+ # {
57
60
  # :name => "image_url",
58
61
  # :required => true,
59
62
  # :valid_type => "url"
60
63
  # }
61
- # attrs_2 = {:line => line,
64
+ # attrs_2 =
65
+ # {
62
66
  # :name => "text_url",
63
67
  # :required => true,
64
68
  # :valid_type => "url"
@@ -74,61 +78,5 @@ module CF
74
78
  def self.all(line)
75
79
  get("/lines/#{CF.account_name}/#{line.title.downcase}/input_formats.json")
76
80
  end
77
-
78
- # ==Returns a particular input header of a specific line
79
- # ===Usage example
80
- # line = CF::Line.new("Digitize Card","Survey")
81
- # attrs = {:line => line,
82
- # :name => "image_url_type",
83
- # :required => true,
84
- # :valid_type => "url"
85
- # }
86
- #
87
- # input_format = CF::InputFormat.new(attrs)
88
- # line.input_formats input_format
89
- # input_format = line.input_formats[0]
90
- #
91
- # got_input_format = input_format.get
92
- def get
93
- self.class.get("/lines/#{line_id}/input_formats/#{id}.json")
94
- end
95
-
96
- # ==Updates input header
97
- # ===Usage example
98
- # line = CF::Line.new("Digitize Card","Survey")
99
- # attrs = {:line => line,
100
- # :name => "image_url_type",
101
- # :required => true,
102
- # :valid_type => "url"
103
- # }
104
- #
105
- # input_format = CF::InputFormat.new(attrs)
106
- # line.input_formats input_format
107
- # input_format = line.input_formats[0]
108
- #
109
- # updated_input_format = input_format.update({:name => "jackpot", :field_type => "lottery"})
110
- def update(options={})
111
- @name = options[:name]
112
- @required = options[:required]
113
- @valid_type = options[:valid_type]
114
- self.class.put("/lines/#{line_id}/input_formats/#{id}.json", :input_format => {:name => @name, :required => @required, :valid_type => @valid_type})
115
- end
116
-
117
- # line = CF::Line.new("Digitize Card","Survey")
118
- # attrs = {:line => line,
119
- # :name => "image_url_type",
120
- # :required => true,
121
- # :valid_type => "url"
122
- # }
123
- #
124
- # input_format = CF::InputFormat.new(attrs)
125
- # line.input_formats input_format
126
- #
127
- # input_format = line.input_formats[0]
128
- # input_format.delete
129
- # deletes input header
130
- def delete
131
- self.class.delete("/lines/#{line_id}/input_formats/#{id}.json")
132
- end
133
81
  end
134
82
  end
data/lib/cf/line.rb CHANGED
@@ -6,12 +6,12 @@ module CF
6
6
  # Title of the Line
7
7
  attr_accessor :title
8
8
 
9
- # Category Name is required for the category which is categorized according to ID, e.g. "4dc8ad6572f8be0600000001"
9
+ # Department Name for Line
10
10
  attr_accessor :department_name
11
11
 
12
12
  # Public is a boolean attribute which when set to true becomes public & vice-versa
13
13
  #
14
- # Public attribute is optional
14
+ # Public attribute is optional, by default it's true
15
15
  attr_accessor :public
16
16
 
17
17
  # Description attribute describes about the line
@@ -19,22 +19,19 @@ module CF
19
19
  # Description attribute is optional
20
20
  attr_accessor :description
21
21
 
22
- # id attribute is for the line_id & is required to be stored for making Api calls
23
- attr_accessor :id
24
-
25
22
  # stations contained within line object
26
23
  attr_accessor :stations
27
24
 
28
25
  # input_formats contained within line object
29
26
  attr_accessor :input_formats
27
+
28
+ # Contains Error Messages
30
29
  attr_accessor :errors
31
- #attr_accessor :input_format_instance
32
- #attr_accessor :station_instance
33
30
 
34
31
  # ==Initializes a new line
35
32
  # ==Usage of line.new("line_name")
36
33
  #
37
- # line = Line.new("Digit", "Survey")
34
+ # line = Line.new("line_name", "Survey")
38
35
  def initialize(title, department_name, options={})
39
36
  @input_formats =[]
40
37
  @stations =[]
@@ -48,8 +45,9 @@ module CF
48
45
  end
49
46
  end
50
47
 
51
- # ==Usage of line.stations << station
52
- # line = CF::Line.new("line name")
48
+ # ==Adds station in a line
49
+ # ===Usage Example:
50
+ # line = CF::Line.new("line_name", "Department_name")
53
51
  # station = CF::Station.new({:type => "Work"})
54
52
  # line.stations station
55
53
  #
@@ -101,30 +99,23 @@ module CF
101
99
  end
102
100
  end
103
101
 
104
- def << stations #:nodoc:
105
- type = stations.type
106
- @stations << stations
107
- resp = CF::Station.post("/lines/#{self.id}/stations.json", :station => {:type => type})
108
- end
109
-
110
-
111
102
  def stations=(stations) # :nodoc:
112
103
  @stations << stations
113
- #resp = CF::Station.post("/lines/#{id}/stations.json", :station => {:type => stations.type})
114
- #@station_id = resp._id
115
104
  end
116
105
 
117
106
  # ==Initializes a new line
118
- # ==Usage of line.create("line_name") do |block|
107
+ # ===Usage Example:
108
+ #
119
109
  # ===creating Line within block using variable
120
- # Line.create("line_name") do |line|
121
- # CF::InputFormat.new({:line => line, :label => "image_url", :field_type => "text_data", :value => "http://s3.amazon.com/bizcardarmy/medium/1.jpg", :required => true, :validation_format => "url"})
110
+ # Line.create("line_name", "Department_name") do |line|
111
+ # CF::InputFormat.new({:line => line, :label => "image_url", :required => true, :valid_type => "url"})
122
112
  # CF::Station.new({:line => line, :type => "Work"})
123
113
  # end
124
114
  #
125
- # ===OR creating without variable
126
- # CF::Line.create("line_name") do
127
- # CF::InputFormat.new({:line => self, :label => "image_url", :field_type => "text_data", :value => "http://s3.amazon.com/bizcardarmy/medium/1.jpg", :required => true, :validation_format => "url"})
115
+ # ==OR
116
+ # ===creating without variable
117
+ # CF::Line.create("line_name", "Department_name") do
118
+ # CF::InputFormat.new({:line => self, :label => "image_url", :required => true, :valid_type => "url"})
128
119
  # CF::Station.new({:line => self, :type => "Work"})
129
120
  # end
130
121
  def self.create(title, department_name, options={}, &block)
@@ -139,10 +130,11 @@ module CF
139
130
  line
140
131
  end
141
132
 
142
- # ==Usage of line.input_formats(input_format)
133
+ # ==Adds input format in a line
134
+ # ===Usage Example:
143
135
  # line = Line.new("line name", "Survey")
144
136
  #
145
- # input_format = CF::InputFormat.new({:label => "image_url", :field_type => "text_data", :value => "http://s3.amazon.com/bizcardarmy/medium/1.jpg", :required => true, :validation_format => "url"})
137
+ # input_format = CF::InputFormat.new({:label => "image_url", :required => true, :valid_type => "url"})
146
138
  # line.input_formats input_format
147
139
  # * returns
148
140
  # line.input_formats as an array of input_formats
@@ -163,14 +155,17 @@ module CF
163
155
  else
164
156
  @input_formats
165
157
  end
158
+
166
159
  end
167
160
  def input_formats=(input_formats_value) # :nodoc:
168
161
  @input_formats << input_formats_value
169
162
  end
170
163
 
171
164
  # ==Returns the content of a line by making an Api call
172
- # ===Syntax for get_line method is
165
+ # ===Usage Example:
173
166
  # CF::Line.info(line)
167
+ # ==OR
168
+ # CF::Line.info("line_title")
174
169
  def self.info(line)
175
170
  if line.class == CF::Line
176
171
  resp = get("/lines/#{CF.account_name}/#{line.title.downcase}.json")
@@ -180,11 +175,18 @@ module CF
180
175
  end
181
176
 
182
177
  # ==Finds a line
183
- # ===Syntax for find method is
184
- # CF::Line.find(line.id)
185
- def self.find(line_id)
186
- get("/lines/#{line_id}.json")
178
+ # ===Usage Example:
179
+ # CF::Line.find(line)
180
+ # ==OR
181
+ # CF::Line.find("line_title")
182
+ def self.find(line)
183
+ if line.class == CF::Line
184
+ resp = get("/lines/#{CF.account_name}/#{line.title.downcase}.json")
185
+ else
186
+ resp = get("/lines/#{CF.account_name}/#{line.downcase}.json")
187
+ end
187
188
  end
189
+
188
190
  # ==Returns all the lines of an account
189
191
  # ===Syntax for all method is
190
192
  # CF::Line.all
@@ -192,11 +194,14 @@ module CF
192
194
  get("/lines/#{CF.account_name}.json")
193
195
  end
194
196
 
197
+ # ==Returns all the stations of a line
198
+ # ===Usage Example:
199
+ # CF::Line.get_stations
195
200
  def get_stations
196
201
  CF::Station.get("/lines/#{ACCOUNT_NAME}/#{self.title.downcase}/stations.json")
197
202
  end
198
- # ==Return all the lines whose public value is set true
199
- # ===Syntax for public_lines method is
203
+ # ==Return all the public lines
204
+ # ===Usage Example:
200
205
  # CF::Line.public_lines
201
206
  def self.public_lines
202
207
  get("/public_lines.json")
@@ -207,7 +212,7 @@ module CF
207
212
  # line = CF::Line.new("Digitize Card", "Survey")
208
213
  # line.update({:title => "New Title"})
209
214
  # * This changes the title of the "line" object from "Digitize Card" to "New Title"
210
- def update(options={})
215
+ def update(options={}) # :nodoc:
211
216
  old_title = self.title
212
217
  @title = options[:title]
213
218
  @department_name = options[:department_name]
@@ -217,13 +222,17 @@ module CF
217
222
  end
218
223
 
219
224
  # ==Deletes a line
220
- # ===Syantax for delete method
225
+ # ===Usage Example:
221
226
  # line = CF::Line.new("Digitize Card", "Survey")
222
- # line.delete
227
+ # line.destroy
223
228
  def destroy
224
229
  self.class.delete("/lines/#{CF.account_name}/#{self.title.downcase}.json")
225
230
  end
226
231
 
232
+ # ==Deletes a line by passing it's title
233
+ # ===Usage Example:
234
+ # line = CF::Line.new("line_title", "Survey")
235
+ # CF::Line.destroy("line_title")
227
236
  def self.destroy(title)
228
237
  delete("/lines/#{CF.account_name}/#{title.downcase}.json")
229
238
  end
@@ -3,9 +3,46 @@ module CF
3
3
  require 'httparty'
4
4
  include Client
5
5
 
6
- # type of the station, e.g. station = Station.new(line, {:type => "Work"})
7
- attr_accessor :settings, :type, :errors, :station, :number, :reward
6
+ # settings for robot worker of the station, e.g. robot_worker = CF::RobotWorker.new({:type => "sentiment_robot", :settings => {:document => ["{url}"], :sanitize => true}})
7
+ attr_accessor :settings
8
+
9
+ # Type of robot worker
10
+ attr_accessor :type
11
+
12
+ # Contains Error message if any
13
+ attr_accessor :errors
14
+
15
+ # Station attribute with which robot worker will be associated
16
+ attr_accessor :station
17
+
18
+ attr_accessor :number # :nodoc:
19
+
20
+ # Reward for the Robot Worker; Every Robot Worker have their fixed Reward by default
21
+ attr_accessor :reward
8
22
 
23
+ # ==Initialize new Robot Worker
24
+ # ===Usage Example:
25
+ #
26
+ # ===In Block DSL way
27
+ # line = CF::Line.create("sentiment_robot","Digitization") do |l|
28
+ # CF::InputFormat.new({:line => l, :name => "url", :valid_type => "url", :required => "true"})
29
+ # CF::Station.create({:line => l, :type => "work"}) do |s|
30
+ # CF::RobotWorker.new({:station => s, :settings => {:document => "{url}", :sanitize => true}, :type => "sentiment_robot"})
31
+ # end
32
+ # end
33
+ #
34
+ # ==OR
35
+ #
36
+ # ===In Plain Ruby way
37
+ # line = CF::Line.new("sentiment_robot_1","Digitization")
38
+ # input_format = CF::InputFormat.new({:name => "url", :required => true, :valid_type => "url"})
39
+ # line.input_formats input_format
40
+ #
41
+ # station = CF::Station.new({:type => "work"})
42
+ # line.stations station
43
+ #
44
+ # worker = CF::RobotWorker.new({:settings => {:document => "{url}", :sanitize => true}, :type => "sentiment_robot"})
45
+ # line.stations.first.worker = worker
9
46
  def initialize(options={})
10
47
  @type = options[:type].nil? ? nil : options[:type].camelize
11
48
  @settings = options[:settings]
@@ -24,6 +61,30 @@ module CF
24
61
  end
25
62
  end
26
63
 
64
+
65
+ # ==Create a new Robot Worker
66
+ # ===Usage Example:
67
+ #
68
+ # ===In Block DSL way
69
+ # line = CF::Line.create("sentiment_robot","Digitization") do |l|
70
+ # CF::InputFormat.new({:line => l, :name => "url", :valid_type => "url", :required => "true"})
71
+ # CF::Station.create({:line => l, :type => "work"}) do |s|
72
+ # CF::RobotWorker.create({:station => s, :settings => {:document => "{url}", :sanitize => true}, :type => "sentiment_robot"})
73
+ # end
74
+ # end
75
+ #
76
+ # ==OR
77
+ #
78
+ # ===In Plain Ruby way
79
+ # line = CF::Line.new("sentiment_robot_1","Digitization")
80
+ # input_format = CF::InputFormat.new({:name => "url", :required => true, :valid_type => "url"})
81
+ # line.input_formats input_format
82
+ #
83
+ # station = CF::Station.new({:type => "work"})
84
+ # line.stations station
85
+ #
86
+ # worker = CF::RobotWorker.create({:settings => {:document => "{url}", :sanitize => true}, :type => "sentiment_robot"})
87
+ # line.stations.first.worker = worker
27
88
  def self.create(options)
28
89
  RobotWorker.new(options)
29
90
  end
data/lib/cf/run.rb CHANGED
@@ -3,34 +3,29 @@ module CF
3
3
  require 'httparty'
4
4
  include Client
5
5
 
6
- # title of the "run" object
6
+ # Title of the "run" object
7
7
  attr_accessor :title
8
8
 
9
- # file attributes to upload
10
- attr_accessor :file, :input
9
+ # File attribute to upload for Production Run
10
+ attr_accessor :file
11
+
12
+ # Input to be passed for Production Run
13
+ attr_accessor :input
11
14
 
12
- # line attribute with which run is associated
15
+ # Line attribute with which run is associated
13
16
  attr_accessor :line
14
-
15
- attr_accessor :id, :errors
17
+
18
+ # Contains Error Message if any
19
+ attr_accessor :errors
16
20
 
17
21
  # ==Initializes a new Run
18
- # ==Usage Example:
22
+ # ===Usage Example:
19
23
  #
20
- # line = CF::Line.create("Digitize Card","Digitization") do |l|
21
- # CF::InputHeader.new({:label => "Company", :field_type => "text_data", :value => "Google", :required => true, :validation_format => "general"})
22
- # CF::InputHeader.new({:label => "Website", :field_type => "text_data", :value => "www.google.com", :required => true, :validation_format => "url"})
23
- # CF::Station.create({:line => l, :type => "work") do |s|
24
- # CF::HumanWorker.new({:station => s, :number => 1, :reward => 20)
25
- # CF::StandardInstruction.create(:station => s, :title => "Enter text from a business card image", :description => "Describe"}) do |i|
26
- # CF::FormField.new({:instruction => i, :label => "First Name", :field_type => "SA", :required => "true"})
27
- # CF::FormField.new({:instruction => i, :label => "Middle Name", :field_type => "SA"})
28
- # CF::FormField.new({:instruction => i, :label => "Last Name", :field_type => "SA", :required => "true"})
29
- # end
30
- # end
31
- # end
24
+ # run = CF::Run.new("line_title", "run name", file_path)
32
25
  #
33
- # run = CF::Run.new(line, "run name", File.expand_path("../../fixtures/input_data/test.csv", __FILE__))
26
+ # ==OR
27
+ # You can pass line object instead of passing line title:
28
+ # run = CF::Run.new(line_object, "run name", file_path)
34
29
  def initialize(line, title, input)
35
30
  if line.class == CF::Line || Hashie::Mash
36
31
  @line = line
@@ -67,44 +62,20 @@ module CF
67
62
  end
68
63
 
69
64
  # ==Creates a new Run
70
- # ==Usage Example:
65
+ # ===Usage Example:
71
66
  #
72
- # line = CF::Line.create("Digitize Card","Digitization") do |l|
73
- # CF::InputHeader.new({:line => l, :label => "Company", :field_type => "text_data", :value => "Google", :required => true, :validation_format => "general"})
74
- # CF::InputHeader.new({:line => l, :label => "Website", :field_type => "text_data", :value => "www.google.com", :required => true, :validation_format => "url"})
75
- # CF::Station.create({:line => l, :type => "work") do |s|
76
- # CF::HumanWorker.new({:station => s, :number => 1, :reward => 20)
77
- # CF::StandardInstruction.create(:station => s, :title => "Enter text from a business card image", :description => "Describe"}) do |i|
78
- # CF::FormField.new({:instruction => i, :label => "First Name", :field_type => "SA", :required => "true"})
79
- # CF::FormField.new({:instruction => i, :label => "Middle Name", :field_type => "SA"})
80
- # CF::FormField.new({:instruction => i, :label => "Last Name", :field_type => "SA", :required => "true"})
81
- # end
82
- # end
83
- # end
67
+ # run = CF::Run.new("line_title", "run name", file_path)
84
68
  #
85
- # run = CF::Run.create(line, "run name", File.expand_path("../../fixtures/input_data/test.csv", __FILE__))
69
+ # ==OR
70
+ # You can pass line object instead passing line title:
71
+ # run = CF::Run.new(line_object, "run name", file_path)
86
72
  def self.create(line, title, file)
87
73
  Run.new(line, title, file)
88
74
  end
89
75
 
90
- def get # :nodoc:
91
- self.class.get("/lines/#{@line.id}/runs/#{@id}.json")
92
- end
93
-
94
- def self.get_final_output(run_id)
95
- resp = get("/runs/#{run_id}/final_outputs.json")
96
-
97
- @final_output =[]
98
- resp.each do |r|
99
- result = FinalOutput.new()
100
- r.to_hash.each_pair do |k,v|
101
- result.send("#{k}=",v) if result.respond_to?(k)
102
- end
103
- @final_output << result
104
- end
105
- return @final_output
106
- end
107
-
76
+ # ==Returns Final Output of production Run
77
+ # ===Usage Example:
78
+ # run_object.final_output
108
79
  def final_output
109
80
  resp = self.class.get("/runs/#{CF.account_name}/#{self.title.downcase}/output.json")
110
81
  @final_output =[]
@@ -121,25 +92,18 @@ module CF
121
92
  return @final_output
122
93
  end
123
94
 
95
+ # ==Returns Final Output of production Run
96
+ # ===Usage Example:
97
+ # CF::Run.final_output("run_title")
124
98
  def self.final_output(title)
125
99
  resp = get("/runs/#{CF.account_name}/#{title.downcase}/output.json")
126
100
  return resp['output']
127
- # debugger
128
- # @final_output =[]
129
- # resp['output'].each do |r|
130
- # result = FinalOutput.new()
131
- # r.to_hash.each_pair do |k,v|
132
- # result.send("#{k}=",v) if result.respond_to?(k)
133
- # end
134
- # # if result.final_output == nil
135
- # # result.final_output = resp.output
136
- # # end
137
- # @final_output << result
138
- # end
139
- # debugger
140
- # return @final_output
141
101
  end
142
102
 
103
+ # ==Returns Output of production Run for any specific Station and for given Run Title
104
+ # ===Usage Example:
105
+ # CF::Run.output({:title => "run_title", :station => 2})
106
+ # Will return output of second station
143
107
  def self.output(options={})
144
108
  station_no = options[:station]
145
109
  title = options[:title]
@@ -147,12 +111,19 @@ module CF
147
111
  return resp['output']
148
112
  end
149
113
 
114
+ # ==Returns Output of Run object for any specific Station
115
+ # ===Usage Example:
116
+ # run_object.output(:station => 2)
117
+ # Will return output of second station
150
118
  def output(options={})
151
119
  station_no = options[:station]
152
120
  resp = self.class.get("/runs/#{CF.account_name}/#{self.title.downcase}/output/#{station_no}.json")
153
121
  return resp['output'].first.to_hash
154
122
  end
155
123
 
124
+ # ==Searches Run for the given "run_title"
125
+ # ===Usage Example:
126
+ # CF::Run.find("run_title")
156
127
  def self.find(title)
157
128
  resp = get("/runs/#{CF.account_name}/#{title.downcase}.json")
158
129
  if resp.code != 200