cloudfactory 0.4.4 → 0.4.5
Sign up to get free protection for your applications and to get access to all the features.
- data/CHANGELOG.md +7 -0
- data/lib/cf.rb +4 -1
- data/lib/cf/badge.rb +59 -0
- data/lib/cf/cli.rb +6 -0
- data/lib/cf/cli/line.rb +185 -132
- data/lib/cf/cli/line_yaml_validator.rb +7 -30
- data/lib/cf/cli/production.rb +63 -9
- data/lib/cf/gold_standard.rb +74 -0
- data/lib/cf/help.txt +67 -0
- data/lib/cf/human_worker.rb +45 -49
- data/lib/cf/line.rb +51 -1
- data/lib/cf/run.rb +10 -10
- data/lib/cf/station.rb +111 -29
- data/lib/cf/test_run.rb +66 -0
- data/lib/cf/version.rb +1 -1
- data/spec/account_spec.rb +1 -1
- data/spec/badges/station_1.html +135 -0
- data/spec/badges_spec.rb +288 -0
- data/spec/gold_standard_spec.rb +179 -0
- data/spec/gold_standards.csv +2 -0
- data/spec/google_translate_robot_spec.rb +1 -1
- data/spec/human_worker_spec.rb +1 -65
- data/spec/line_spec.rb +6 -39
- data/spec/robot_worker_spec.rb +1 -1
- data/spec/run_spec.rb +9 -7
- data/spec/stat_badge_spec.rb +45 -0
- data/spec/test_run_spec.rb +105 -0
- metadata +264 -218
- data/spec/badge_spec.rb +0 -88
data/CHANGELOG.md
CHANGED
data/lib/cf.rb
CHANGED
@@ -91,4 +91,7 @@ require "#{directory}/cf/run"
|
|
91
91
|
require "#{directory}/cf/department"
|
92
92
|
require "#{directory}/cf/robot_worker"
|
93
93
|
require "#{directory}/cf/version"
|
94
|
-
require "#{directory}/cf/output_format"
|
94
|
+
require "#{directory}/cf/output_format"
|
95
|
+
require "#{directory}/cf/gold_standard"
|
96
|
+
require "#{directory}/cf/badge"
|
97
|
+
require "#{directory}/cf/test_run"
|
data/lib/cf/badge.rb
ADDED
@@ -0,0 +1,59 @@
|
|
1
|
+
module CF
|
2
|
+
class Badge
|
3
|
+
require 'httparty'
|
4
|
+
include Client
|
5
|
+
|
6
|
+
# goldstandard settings
|
7
|
+
attr_accessor :settings
|
8
|
+
|
9
|
+
#Badge name
|
10
|
+
attr_accessor :name
|
11
|
+
|
12
|
+
# the description for the badge
|
13
|
+
attr_accessor :description
|
14
|
+
|
15
|
+
# number of badge provided to the worker
|
16
|
+
attr_accessor :max_badges
|
17
|
+
|
18
|
+
# Contains error message
|
19
|
+
attr_accessor :errors
|
20
|
+
|
21
|
+
def initialize(options={})
|
22
|
+
options.symbolize_keys!
|
23
|
+
if (!options.blank? && options[:test_attributes][:form_attributes].present?)
|
24
|
+
form = options[:test_attributes][:form_attributes]
|
25
|
+
if( form[:type] == "CustomTaskForm" && form[:file])
|
26
|
+
raw_html = ""
|
27
|
+
File.open("#{form[:file]}").each_line do |line|
|
28
|
+
raw_html += line
|
29
|
+
end
|
30
|
+
options[:test_attributes][:form_attributes].merge!({:raw_html => raw_html,:_type =>"CustomTaskForm"})
|
31
|
+
end
|
32
|
+
options[:test_attributes][:form_attributes].merge!({:_type =>"TaskForm"}) if form[:type] == "TaskForm"
|
33
|
+
end
|
34
|
+
@settings = options
|
35
|
+
@station = options[:station] if options[:station].nil? ? nil : options[:station]
|
36
|
+
@line = options[:line] if options[:line].nil? ? nil : options[:line]
|
37
|
+
if !@line.nil? && @station
|
38
|
+
options.delete(:station) if @settings[:station].present?
|
39
|
+
options.delete(:line)
|
40
|
+
request =
|
41
|
+
{
|
42
|
+
:body =>
|
43
|
+
{
|
44
|
+
:api_key => CF.api_key,
|
45
|
+
:badge => options
|
46
|
+
}
|
47
|
+
}
|
48
|
+
|
49
|
+
resp = HTTParty.post("#{CF.api_url}#{CF.api_version}/lines/#{CF.account_name}/#{@line.title.downcase}/stations/#{@station.index}/badges.json",request)
|
50
|
+
@station.badges = self
|
51
|
+
self.errors = resp.parsed_response['error']['message'] if resp.code != 200
|
52
|
+
end
|
53
|
+
end
|
54
|
+
|
55
|
+
def self.create(*args)
|
56
|
+
Badge.new(args.first)
|
57
|
+
end
|
58
|
+
end
|
59
|
+
end
|
data/lib/cf/cli.rb
CHANGED
@@ -34,6 +34,12 @@ module Cf # :nodoc: all
|
|
34
34
|
include Thor::Actions
|
35
35
|
include Cf::Config
|
36
36
|
|
37
|
+
def help(*args)
|
38
|
+
File.open(File.expand_path(File.dirname(__FILE__)+"/help.txt")).each_line{ |s|
|
39
|
+
say s
|
40
|
+
}
|
41
|
+
end
|
42
|
+
|
37
43
|
map "-v" => :version
|
38
44
|
|
39
45
|
desc "login", "Setup the cloudfactory credentials"
|
data/lib/cf/cli/line.rb
CHANGED
@@ -72,14 +72,14 @@ module Cf # :nodoc: all
|
|
72
72
|
if resp_line.nil?
|
73
73
|
say("Line does not exist entitled #{line_title} !!!", :red) and exit(1)
|
74
74
|
else
|
75
|
-
line = Hashie::Mash.new(resp_line)
|
75
|
+
line = Hashie::Mash.new(resp_line)
|
76
76
|
end
|
77
77
|
if line.title == line_title && !resp_line.nil?
|
78
78
|
if options.force
|
79
79
|
CF::Line.destroy(line_title, :forced => true)
|
80
80
|
say("The line #{line_title} deleted forcefully!", :yellow)
|
81
81
|
else
|
82
|
-
|
82
|
+
|
83
83
|
# Check whether this line has existing runs or not
|
84
84
|
resp_runs = CF::Run.all({:line_title => line_title})
|
85
85
|
|
@@ -154,162 +154,215 @@ module Cf # :nodoc: all
|
|
154
154
|
return
|
155
155
|
end
|
156
156
|
errors = validate(yaml_source)
|
157
|
-
|
157
|
+
|
158
158
|
if errors.present?
|
159
159
|
say("Invalid line.yml file. Correct its structure as per the errors shown below.", :red)
|
160
160
|
errors.each {|error| say(" #{error}", :cyan)}
|
161
161
|
exit(1)
|
162
162
|
end
|
163
|
-
|
163
|
+
|
164
164
|
set_target_uri(false)
|
165
165
|
set_api_key(yaml_source)
|
166
166
|
|
167
|
-
|
167
|
+
CF.account_name = CF::Account.info['name']
|
168
168
|
|
169
|
-
|
170
|
-
|
171
|
-
|
172
|
-
|
173
|
-
|
174
|
-
|
175
|
-
|
176
|
-
|
177
|
-
|
178
|
-
|
179
|
-
|
180
|
-
|
181
|
-
|
182
|
-
|
183
|
-
|
184
|
-
|
185
|
-
|
186
|
-
end
|
169
|
+
line_dump = YAML::load(File.read(yaml_source).strip)
|
170
|
+
line_title = line_dump['title'].parameterize
|
171
|
+
line_description = line_dump['description']
|
172
|
+
line_department = line_dump['department']
|
173
|
+
line_public = line_dump['public']
|
174
|
+
|
175
|
+
line = CF::Line.info(line_title)
|
176
|
+
if line['error'].blank? && options.force?
|
177
|
+
rollback(line.title)
|
178
|
+
elsif line['error'].blank?
|
179
|
+
say("This line already exist.", :yellow)
|
180
|
+
override = agree("Do you want to override? [y/n] ")
|
181
|
+
if override
|
182
|
+
say("Deleting the line forcefuly..", :yellow)
|
183
|
+
rollback(line['title'])
|
184
|
+
else
|
185
|
+
say("Line creation aborted!!", :yellow) and exit(1)
|
187
186
|
end
|
188
|
-
|
189
|
-
|
190
|
-
|
191
|
-
|
192
|
-
|
193
|
-
|
194
|
-
|
195
|
-
|
196
|
-
|
197
|
-
|
198
|
-
|
199
|
-
|
200
|
-
|
201
|
-
|
202
|
-
|
203
|
-
|
204
|
-
|
205
|
-
|
206
|
-
|
207
|
-
|
208
|
-
|
209
|
-
|
210
|
-
input_format_for_line = CF::InputFormat.new(@attrs)
|
211
|
-
input_format = line.input_formats input_format_for_line
|
212
|
-
say_status "input", "#{@attrs[:name]}"
|
213
|
-
display_error(line_title, "#{line.input_formats[index].errors}") if line.input_formats[index].errors.present?
|
187
|
+
end
|
188
|
+
line = CF::Line.new(line_title, line_department, {:description => line_description, :public => line_public})
|
189
|
+
say "Creating new assembly line: #{line.title}", :green
|
190
|
+
say("Error: #{line.errors}", :red) and exit(1) if line.errors.present?
|
191
|
+
|
192
|
+
say "Adding InputFormats", :green
|
193
|
+
|
194
|
+
# Creation of InputFormat from yaml file
|
195
|
+
input_formats = line_dump['input_formats']
|
196
|
+
input_formats.each_with_index do |input_format, index|
|
197
|
+
if input_format['valid_type']
|
198
|
+
@attrs = {
|
199
|
+
:name => input_format['name'],
|
200
|
+
:required => input_format['required'],
|
201
|
+
:valid_type => input_format['valid_type']
|
202
|
+
}
|
203
|
+
elsif input_format['valid_type'].nil?
|
204
|
+
@attrs = {
|
205
|
+
:name => input_format['name'],
|
206
|
+
:required => input_format['required'],
|
207
|
+
:valid_type => input_format['valid_type']
|
208
|
+
}
|
214
209
|
end
|
210
|
+
input_format_for_line = CF::InputFormat.new(@attrs)
|
211
|
+
input_format = line.input_formats input_format_for_line
|
212
|
+
say_status "input", "#{@attrs[:name]}"
|
213
|
+
display_error(line_title, "#{line.input_formats[index].errors}") if line.input_formats[index].errors.present?
|
214
|
+
end
|
215
|
+
|
216
|
+
# Creation of Station
|
217
|
+
stations = line_dump['stations']
|
218
|
+
stations.each_with_index do |station_file, s_index|
|
219
|
+
type = station_file['station']['station_type']
|
220
|
+
index = station_file['station']['station_index']
|
221
|
+
input_formats_for_station = station_file['station']['input_formats']
|
222
|
+
batch_size = station_file['station']['batch_size']
|
223
|
+
if type == "tournament"
|
224
|
+
jury_worker = station_file['station']['jury_worker']
|
225
|
+
auto_judge = station_file['station']['auto_judge']
|
226
|
+
acceptance_ratio = station_file['station']['acceptance_ratio']
|
227
|
+
station_params = {:line => line, :type => type, :jury_worker => jury_worker, :auto_judge => auto_judge, :input_formats => input_formats_for_station, :batch_size => batch_size, :acceptance_ratio => acceptance_ratio}
|
228
|
+
else
|
229
|
+
station_params = {:line => line, :type => type, :input_formats => input_formats_for_station, :batch_size => batch_size}
|
230
|
+
end
|
231
|
+
station = CF::Station.create(station_params) do |s|
|
232
|
+
say "Adding Station #{index}: #{s.type}", :green
|
233
|
+
display_error(line_title, "#{s.errors}") if s.errors.present?
|
234
|
+
|
235
|
+
# For Worker
|
236
|
+
worker = station_file['station']['worker']
|
237
|
+
number = worker['num_workers']
|
238
|
+
reward = worker['reward']
|
239
|
+
worker_type = worker['worker_type']
|
240
|
+
if worker_type == "human"
|
241
|
+
skill_badges = worker['skill_badges']
|
242
|
+
stat_badge = worker['stat_badge']
|
243
|
+
if stat_badge.nil?
|
244
|
+
human_worker = CF::HumanWorker.new({:station => s, :number => number, :reward => reward})
|
245
|
+
else
|
246
|
+
human_worker = CF::HumanWorker.new({:station => s, :number => number, :reward => reward, :stat_badge => stat_badge})
|
247
|
+
end
|
248
|
+
|
249
|
+
if worker['skill_badges'].present?
|
250
|
+
skill_badges.each do |badge|
|
251
|
+
human_worker.badge = badge
|
252
|
+
end
|
253
|
+
end
|
215
254
|
|
216
|
-
|
217
|
-
|
218
|
-
|
219
|
-
|
220
|
-
|
221
|
-
|
222
|
-
|
223
|
-
|
224
|
-
jury_worker = station_file['station']['jury_worker']
|
225
|
-
auto_judge = station_file['station']['auto_judge']
|
226
|
-
acceptance_ratio = station_file['station']['acceptance_ratio']
|
227
|
-
station_params = {:line => line, :type => type, :jury_worker => jury_worker, :auto_judge => auto_judge, :input_formats => input_formats_for_station, :batch_size => batch_size, :acceptance_ratio => acceptance_ratio}
|
255
|
+
say_status "worker", "#{number} Cloud #{pluralize(number, "Worker")} with reward of #{reward} #{pluralize(reward, "cent")}"
|
256
|
+
display_error(line_title, "#{human_worker.errors}") if human_worker.errors.present?
|
257
|
+
elsif worker_type =~ /robot/
|
258
|
+
settings = worker['settings']
|
259
|
+
robot_worker = CF::RobotWorker.create({:station => s, :type => worker_type, :settings => settings})
|
260
|
+
|
261
|
+
say_status "robot", "Robot worker: #{worker_type}"
|
262
|
+
display_error(line_title, "#{robot_worker.errors}") if robot_worker.errors.present?
|
228
263
|
else
|
229
|
-
|
264
|
+
display_error(line_title, "Invalid worker type: #{worker_type}")
|
230
265
|
end
|
231
|
-
|
232
|
-
|
233
|
-
|
234
|
-
|
235
|
-
|
236
|
-
|
237
|
-
|
238
|
-
|
239
|
-
|
240
|
-
|
241
|
-
|
242
|
-
|
243
|
-
|
244
|
-
|
245
|
-
|
246
|
-
|
247
|
-
|
248
|
-
|
249
|
-
if worker['skill_badges'].present?
|
250
|
-
skill_badges.each do |badge|
|
251
|
-
human_worker.badge = badge
|
252
|
-
end
|
266
|
+
|
267
|
+
# Creation of Form
|
268
|
+
# Creation of TaskForm
|
269
|
+
if station_file['station']['task_form'].present?
|
270
|
+
title = station_file['station']['task_form']['form_title']
|
271
|
+
instruction = station_file['station']['task_form']['instruction']
|
272
|
+
form = CF::TaskForm.create({:station => s, :title => title, :instruction => instruction}) do |f|
|
273
|
+
|
274
|
+
# Creation of FormFields
|
275
|
+
say_status "form", "TaskForm '#{f.title}'"
|
276
|
+
display_error(line_title, "#{f.errors}") if f.errors.present?
|
277
|
+
|
278
|
+
station_file['station']['task_form']['form_fields'].each do |form_field|
|
279
|
+
form_field_params = form_field.merge(:form => f)
|
280
|
+
field = CF::FormField.new(form_field_params.symbolize_keys)
|
281
|
+
say_status "form_field", "FormField '#{field.form_field_params}'"
|
282
|
+
display_error(line_title, field.errors) if field.errors.present?
|
253
283
|
end
|
254
284
|
|
255
|
-
|
256
|
-
|
257
|
-
|
258
|
-
|
259
|
-
|
285
|
+
end
|
286
|
+
|
287
|
+
elsif station_file['station']['custom_task_form'].present?
|
288
|
+
# Creation of CustomTaskForm
|
289
|
+
title = station_file['station']['custom_task_form']['form_title']
|
290
|
+
instruction = station_file['station']['custom_task_form']['instruction']
|
291
|
+
|
292
|
+
html_file = station_file['station']['custom_task_form']['html']
|
293
|
+
html = File.read("#{line_source}/station#{station_file['station']['station_index']}.html")
|
294
|
+
form = CF::CustomTaskForm.create({:station => s, :title => title, :instruction => instruction, :raw_html => html})
|
295
|
+
say_status "form", "CustomTaskForm '#{form.title}'"
|
296
|
+
display_error(line_title, "#{form.errors}") if form.errors.present?
|
297
|
+
end
|
260
298
|
|
261
|
-
|
262
|
-
|
299
|
+
#check the presence of gold standard and create goldstandards for the station
|
300
|
+
say "Adding Gold Standards to stations", :green
|
301
|
+
gold_standards = station_file['station']['gold_standards']
|
302
|
+
if gold_standards
|
303
|
+
if gold_standards.class == Hash#gold_standards["file"]
|
304
|
+
gold_standard = CF::GoldStandard.new(gold_standards.merge!({:line => line,:station => s }))
|
305
|
+
say_status "GoldStandard", "parameters '#{gold_standards}'"
|
306
|
+
display_error(line_title, "#{gold_standard.errors}") if gold_standard.errors.present?
|
263
307
|
else
|
264
|
-
|
308
|
+
gold_standards.each do |gold_options|
|
309
|
+
gold_standard = CF::GoldStandard.new(gold_options.merge({:line => line,:station => s }))
|
310
|
+
say_status "GoldStandard", "parameters '#{gold_options}'"
|
311
|
+
display_error(line_title, "#{gold_standard.errors}") if gold_standard.errors.present?
|
312
|
+
end
|
265
313
|
end
|
314
|
+
end
|
266
315
|
|
267
|
-
|
268
|
-
|
269
|
-
|
270
|
-
|
271
|
-
|
272
|
-
form =
|
273
|
-
|
274
|
-
|
275
|
-
|
276
|
-
|
277
|
-
|
278
|
-
|
279
|
-
form_field_params = form_field.merge(:form => f)
|
280
|
-
field = CF::FormField.new(form_field_params.symbolize_keys)
|
281
|
-
say_status "form_field", "FormField '#{field.form_field_params}'"
|
282
|
-
display_error(line_title, field.errors) if field.errors.present?
|
316
|
+
#######create badge #########
|
317
|
+
say "Adding Badges to station", :green
|
318
|
+
badges = station_file['station']['badges']
|
319
|
+
if badges
|
320
|
+
badges.each do |s_badge|
|
321
|
+
form = s_badge["test_attributes"]["form_attributes"]
|
322
|
+
unless form.blank?
|
323
|
+
if form["type"] == "CustomTaskForm"
|
324
|
+
file = File.read("#{line_source}/#{form["file"]}") || File.read("#{line_source}/badges/station#{station_file['station']['station_index']}.html")
|
325
|
+
s_badge["test_attributes"]["form_attributes"].merge!({:raw_html => file, :_type =>"CustomTaskForm" })
|
326
|
+
else
|
327
|
+
s_badge["test_attributes"]["form_attributes"].merge!({:_type =>"TaskForm" })
|
283
328
|
end
|
284
|
-
|
285
329
|
end
|
286
|
-
|
287
|
-
|
288
|
-
#
|
289
|
-
title = station_file['station']['custom_task_form']['form_title']
|
290
|
-
instruction = station_file['station']['custom_task_form']['instruction']
|
291
|
-
|
292
|
-
html_file = station_file['station']['custom_task_form']['html']
|
293
|
-
html = File.read("#{line_source}/station#{station_file['station']['station_index']}.html")
|
294
|
-
form = CF::CustomTaskForm.create({:station => s, :title => title, :instruction => instruction, :raw_html => html})
|
295
|
-
say_status "form", "CustomTaskForm '#{form.title}'"
|
296
|
-
display_error(line_title, "#{form.errors}") if form.errors.present?
|
330
|
+
badge = CF::Badge.new(s_badge.merge({:line => line,:station => s }))
|
331
|
+
say_status "Badge","parameters '#{s_badge}'"
|
332
|
+
display_error(line_title, "#{badge.errors}") if badge.errors.present?
|
297
333
|
end
|
298
|
-
|
299
334
|
end
|
300
335
|
end
|
301
|
-
|
302
|
-
|
303
|
-
|
304
|
-
|
305
|
-
|
306
|
-
|
336
|
+
end
|
337
|
+
|
338
|
+
output_formats = line_dump['output_formats'].presence
|
339
|
+
if output_formats
|
340
|
+
output_format = CF::OutputFormat.new(output_formats.merge(:line => line))
|
341
|
+
say "Adding Output Format #{output_formats}", :green
|
342
|
+
display_error(line_title, "#{output_format.errors}") if output_format.errors.present?
|
343
|
+
end
|
344
|
+
|
345
|
+
#check the presence of gold standard and create goldstandards for the line
|
346
|
+
say "Adding GoldStandards to Line", :green
|
347
|
+
gold_standards = line_dump['gold_standards'].presence
|
348
|
+
if gold_standards
|
349
|
+
if gold_standards.class == Hash#gold_standards["file"]
|
350
|
+
gold_standard = CF::GoldStandard.new(gold_standards.merge!({:line => line}))
|
351
|
+
say_status "GoldStandard", "parameters '#{gold_standards}'"
|
352
|
+
display_error(line_title, "#{gold_standard.errors}") if gold_standard.errors.present?
|
353
|
+
else
|
354
|
+
gold_standards.each do |gold_options|
|
355
|
+
gold_standard = CF::GoldStandard.new(gold_options.merge(:line => line))
|
356
|
+
say_status "GoldStandard", "parameters '#{gold_options}'"
|
357
|
+
display_error(line_title, "#{gold_standard.errors}") if gold_standard.errors.present?
|
307
358
|
end
|
308
|
-
|
309
|
-
|
310
|
-
|
311
|
-
|
312
|
-
|
359
|
+
end
|
360
|
+
end
|
361
|
+
|
362
|
+
say " ☁ ☁ ☁ ☁ ☁ ☁ ☁ ☁ ☁ ☁ ☁ ☁ ☁ ☁ ☁ ☁ ☁ ☁ ☁ ☁ ☁ ☁ ☁ ☁ ☁ ☁ ☁ ☁ ☁ ☁ ☁ ☁ ☁ ☁ ☁ ☁ ☁ ☁ ☁ ☁", :white
|
363
|
+
say "Line was successfully created.", :green
|
364
|
+
say "View your line at http://#{CF.account_name}.#{CF.api_url.split("/")[-2]}/lines/#{CF.account_name}/#{line.title}", :yellow
|
365
|
+
say "\nNow you can do production runs with: cf production start <your-run-title>", :green
|
313
366
|
end
|
314
367
|
|
315
368
|
desc "line list", "List your lines"
|