cloudfactory 0.1.9 → 0.1.10

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 (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