cloudfactory 0.6.4 → 0.7

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.
@@ -0,0 +1,18 @@
1
+ module Cf
2
+ module BadgeYamlValidator
3
+
4
+ def validate(yaml_path)
5
+ errors = []
6
+ badge = YAML::load(File.read(yaml_path).strip)
7
+ if badge.class == Hash
8
+ errors << "Form for the badge is missing" unless badge["form"]
9
+ errors << "Name of the badge is missing" unless badge["name"]
10
+ errors << "Description for the badge is missing" unless badge["description"]
11
+ errors << "Known answers for the badge must be array of hashes" unless badge["known_answers"].class == Array
12
+ else
13
+ errors << "badge mut be hash"
14
+ end
15
+ errors
16
+ end
17
+ end
18
+ end
@@ -239,20 +239,14 @@ module Cf # :nodoc: all
239
239
  number = worker['num_workers']
240
240
  reward = worker['reward']
241
241
  worker_type = worker['worker_type']
242
+
243
+ ##### Add badge to the station ########
244
+
242
245
  if worker_type == "human"
243
- skill_badges = worker['skill_badges']
246
+ badges = station_file['station']['badges']
244
247
  stat_badge = worker['stat_badge']
245
- if stat_badge.nil?
246
- human_worker = CF::HumanWorker.new({:station => s, :number => number, :reward => reward})
247
- else
248
- human_worker = CF::HumanWorker.new({:station => s, :number => number, :reward => reward, :stat_badge => stat_badge})
249
- end
250
248
 
251
- if worker['skill_badges'].present?
252
- skill_badges.each do |badge|
253
- human_worker.badge = badge
254
- end
255
- end
249
+ human_worker = CF::HumanWorker.new({:station => s, :number => number, :reward => reward, :badge => badges, :stat_badge => stat_badge})
256
250
 
257
251
  say_status "worker", "#{number} Cloud #{pluralize(number, "Worker")} with reward of #{reward} #{pluralize(reward, "cent")}"
258
252
  display_error(line_title, "#{human_worker.errors}") if human_worker.errors.present?
@@ -266,6 +260,7 @@ module Cf # :nodoc: all
266
260
  display_error(line_title, "Invalid worker type: #{worker_type}")
267
261
  end
268
262
 
263
+
269
264
  # Creation of Form
270
265
  # Creation of TaskForm
271
266
  if station_file['station']['task_form'].present?
@@ -298,6 +293,15 @@ module Cf # :nodoc: all
298
293
  display_error(line_title, "#{form.errors}") if form.errors.present?
299
294
  end
300
295
 
296
+ # print if the badge for the station exist NOTE: addition of the badge is done above.
297
+ # it is printed here for better UI
298
+ if badges
299
+ say "Adding Badges For Station#{index}", :green
300
+ badges.each do |name|
301
+ say_status "-", "#{name}"
302
+ end
303
+ end
304
+
301
305
  #check the presence of gold standard and create goldstandards for the station
302
306
  gold_standards = station_file['station']['gold_standards']
303
307
  if gold_standards
@@ -323,29 +327,6 @@ module Cf # :nodoc: all
323
327
  end
324
328
  end
325
329
  end
326
-
327
- #######create badge #########
328
- badges = station_file['station']['badges']
329
- if badges
330
- say "Adding Badges to station", :green
331
- badges.each do |s_badge|
332
- if s_badge.length == 1 && s_badge.keys.include?("name")
333
- else
334
- form = s_badge["test_attributes"]["form_attributes"]
335
- unless form.blank?
336
- if form["type"] == "CustomTaskForm"
337
- file = File.read("#{line_source}/#{form["file"]}") || File.read("#{line_source}/badges/station#{station_file['station']['station_index']}.html")
338
- s_badge["test_attributes"]["form_attributes"].merge!({:raw_html => file, :_type =>"CustomTaskForm" })
339
- else
340
- s_badge["test_attributes"]["form_attributes"].merge!({:_type =>"TaskForm" })
341
- end
342
- end
343
- end
344
- badge = CF::Badge.new(s_badge.merge({:line => line,:station => s }))
345
- say_status "Badge","'#{s_badge["name"] }'"
346
- display_error(line_title, "#{badge.errors}") if badge.errors.present?
347
- end
348
- end
349
330
  end
350
331
  end
351
332
 
@@ -370,17 +351,17 @@ module Cf # :nodoc: all
370
351
  end
371
352
  end
372
353
  if gold_standards.class == Hash#gold_standards["file"]
373
- gold_standard = CF::GoldStandard.new(gold_standards.merge!({:line => line}))
374
- say_status "GoldStandard from file", "'#{gold_standards[:file]}'"
375
- display_error(line_title, "#{gold_standard.errors}") if gold_standard.errors.present?
376
- else
377
- gold_standards.each do |gold_options|
378
- gold_standard = CF::GoldStandard.new(gold_options.merge(:line => line))
379
- say_status "GoldStandard", "'#{gold_options["name"]}'"
354
+ gold_standard = CF::GoldStandard.new(gold_standards.merge!({:line => line}))
355
+ say_status "GoldStandard from file", "'#{gold_standards[:file]}'"
380
356
  display_error(line_title, "#{gold_standard.errors}") if gold_standard.errors.present?
357
+ else
358
+ gold_standards.each do |gold_options|
359
+ gold_standard = CF::GoldStandard.new(gold_options.merge(:line => line))
360
+ say_status "GoldStandard", "'#{gold_options["name"]}'"
361
+ display_error(line_title, "#{gold_standard.errors}") if gold_standard.errors.present?
362
+ end
381
363
  end
382
364
  end
383
- end
384
365
 
385
366
  say " ☁ ☁ ☁ ☁ ☁ ☁ ☁ ☁ ☁ ☁ ☁ ☁ ☁ ☁ ☁ ☁ ☁ ☁ ☁ ☁ ☁ ☁ ☁ ☁ ☁ ☁ ☁ ☁ ☁ ☁ ☁ ☁ ☁ ☁ ☁ ☁ ☁ ☁ ☁ ☁", :white
386
367
  say "Line was successfully created.", :green
@@ -194,7 +194,7 @@ module Cf # :nodoc: all
194
194
  no_tasks do
195
195
  def display_success_run(run)
196
196
  say("Run created successfully.", :green)
197
- say("View your production at:\n\thttp://#{CF.account_name}.#{CF.api_url.split("/")[-2]}/runs/#{CF.account_name}/#{run.title}/workerpool_preview\n", :green)
197
+ say("View your production at:\n\thttp://#{CF.account_name}.#{CF.api_url.split("/")[-2]}/runs/#{CF.account_name}/#{run.title}\n", :green)
198
198
  end
199
199
  end
200
200
 
@@ -0,0 +1,38 @@
1
+
2
+ # name of the badge that you want to create
3
+ name: <%= name %>
4
+
5
+ # description of the badge
6
+ description: This badge allow to do the tasks for <%= name %>.
7
+
8
+ # numbers of worker who can take the badge
9
+ max_badge_assignments: 5
10
+
11
+ # number of retries that the worker get at the time of taking the badge
12
+ retries_allowed: 5
13
+
14
+ # the value in percentage that the worker must score to pass the test
15
+ pass_percentage: 80
16
+
17
+ # time assigned for badge test
18
+ assignment_duration: 3600
19
+
20
+ # checking badge answers that worker has submitted
21
+ check_manually: false
22
+
23
+ # number of day after which the worker can again take the badge exam
24
+ allow_retake_after: 30
25
+
26
+ # form for the badge. It should be html format if it is a custom form
27
+ form: form.html
28
+
29
+ # the hash of question and answers for the badge
30
+ known_answers:
31
+ - input:
32
+ image_url: http://www.crystalinks.com/newton.jpg
33
+ expected_output:
34
+ gender: Male
35
+ - input:
36
+ image_url: http://www.sportosporto.pl/Hobby/Witryny3b_07/Vinci/images/7la.jpg
37
+ expected_output:
38
+ gender: Female
@@ -64,7 +64,7 @@
64
64
  <h2>Instructions:</h2>
65
65
  <ul>
66
66
  <li><img src="{{image_url}}" /></li>
67
- <li>Then enter the url of hottest date found</li>
67
+ <li>Determine the gender for the given image.</li>
68
68
  </ul>
69
69
  </div>
70
70
 
@@ -72,38 +72,12 @@
72
72
  <div id = "field-panel">
73
73
  <p>
74
74
  <form>
75
-
76
75
  <label>Gender</label><br />
77
76
  <select id="gender_option" name="output[gender]">
78
77
  <option value="Male">Male</option>
79
78
  <option value="Female">Female</option>
80
79
  </select>
81
80
  <br />
82
-
83
- <label>How rich?</label><br />
84
- <select id="rich_option" name="output[rich]">
85
- <option value="1">1</option>
86
- <option value="2">2</option>
87
- <option value="3">3</option>
88
- </select>
89
- <br />
90
-
91
- <label>How Kind?</label><br />
92
- <select id="kind_option" name="output[kind]">
93
- <option value="1">1</option>
94
- <option value="2">2</option>
95
- <option value="3">3</option>
96
- </select>
97
- <br />
98
-
99
- <label>How Attractive?</label><br />
100
- <select id="attractive_option" name="output[attractive]">
101
- <option value="1">1</option>
102
- <option value="2">2</option>
103
- <option value="3">3</option>
104
- </select>
105
- <br />
106
-
107
81
  <input type="submit" value="submit" />
108
82
 
109
83
  </form>
@@ -28,8 +28,10 @@ stations:
28
28
  # Worker (see http://cloudfactory.com/developers/resources/worker.html)
29
29
  worker:
30
30
  worker_type: human # "human" or name of robot (google_translate_robot, etc)
31
- num_workers: 2
31
+ num_workers: 1
32
32
  reward: 2
33
+ badges:
34
+ - Web Research
33
35
  custom_task_form:
34
36
  form_title: Clink a link and paste in url
35
37
  instruction: Look through search results and find the best date
@@ -59,7 +59,7 @@ module CF
59
59
  :body =>
60
60
  {
61
61
  :api_key => CF.api_key,
62
- :form => {:title => form_content["form_title"], :instruction => form_content["instruction"], :_type => "CustomTaskForm", :raw_html => form_content["html"]},
62
+ :form => {:title => form_content["title"], :instruction => form_content["instruction"], :_type => "CustomTaskForm", :raw_html => form_content["raw_html"]},
63
63
  :station_index => station_index
64
64
  }
65
65
  }
@@ -26,37 +26,37 @@ Login
26
26
 
27
27
  Form:
28
28
  Usage:
29
- cf form generate --fields=key:value --labels=LABELS --station=N # generates a custom task form at <line-title>/<form-title>.html and its associated css and js files
30
- cf form preview -s, --station=N # generates a html file to preview the custom task form
29
+ cf form generate --fields=key:value --labels=LABELS --station=N # Generates a custom task form at <line-title>/<form-title>.html and its associated css and js files
30
+ cf form preview -s, --station=N # Generates a html file to preview the custom task form
31
31
  Description:
32
32
  Commands to generate custom task forms. For more info, cf form help
33
33
  More:
34
- cf form help [sub-command] #list all help related to form subcommands
34
+ cf form help [sub-command] # List all help related to form subcommands
35
35
 
36
36
  Line:
37
37
  Usage:
38
- cf line create # takes the line.yml and creates a new line at http://cloudfactory.com
39
- cf line delete # delete the current line at http://cloudfactory.com
40
- cf line details # list the details of the line
41
- cf line generate LINE-TITLE # generates a line template at <line-title>/line.yml
38
+ cf line create # Takes the line.yml and creates a new line at http://cloudfactory.com
39
+ cf line delete # Delete the current line at http://cloudfactory.com
40
+ cf line details # List the details of the line
41
+ cf line generate LINE-TITLE # Generates a line template at <line-title>/line.yml
42
42
  cf line list # List your lines
43
43
  Description:
44
44
  Commands to manage the Lines. For more info, cf line help
45
45
  More:
46
- cf line help [sub-command] #list all help related to line subcommands
46
+ cf line help [sub-command] # List all help related to line subcommands
47
47
 
48
48
  Production:
49
49
  Usage:
50
- cf production add_units -i, --input-data=INPUT_DATA -t, --run-title=RUN_TITLE # add units to already existing production run
50
+ cf production add_units -i, --input-data=INPUT_DATA -t, --run-title=RUN_TITLE # Add units to already existing production run
51
51
  cf production delete -t, --run-title=RUN_TITLE # Deletes created Production Run
52
- cf production list # list the production runs
53
- cf production resume -r, --run-title=RUN_TITLE # resume a paused production run
54
- cf production start <run-title> # creates a production run with input data file at input/<run-title>.csv
55
- cf production start_test <run-title> -g<number-of-goldstandrds-to-be-added> # creates a production run with given line goldstandards as units
52
+ cf production list # List the production runs
53
+ cf production resume -r, --run-title=RUN_TITLE # Resume a paused production run
54
+ cf production start <run-title> # Creates a production run with input data file at input/<run-title>.csv
55
+ cf production start_test <run-title> -g<number-of-goldstandrds-to-be-added> # Creates a production run with given line gold_standards as units
56
56
  Description:
57
57
  Commands to create production runs. For more info, cf production help
58
58
  More:
59
- cf production help [sub-command] #list all help related to production subcommands
59
+ cf production help [sub-command] # List all help related to production subcommands
60
60
 
61
61
  Output:
62
62
  Usage:
@@ -64,4 +64,16 @@ Output:
64
64
  Description:
65
65
  Get the output of run. For more info, cf output help
66
66
  More:
67
- cf output help [sub-command] #list all help related to output subcommands
67
+ cf output help [sub-command] # List all help related to output subcommands
68
+
69
+ Badge:
70
+ Usage:
71
+ cf badge create <badge_name> # Takes the badge.yml from badge_name directory and create a badge
72
+ cf badge delete <badge name> # Delete the given badge within your account.
73
+ cf badge generate <badge_name> # Generate a new badge template.
74
+ cf badge list # List all badges associated within your account. Use 'cf badge list <badge_name>' for single badge.
75
+ cf badge update <badge_name> # Takes the badge.yml from badge_name directory and update the badge
76
+ Description:
77
+ Commands to manage the badges.
78
+ More:
79
+ cf help [COMMAND] # Describe subcommands or one specific subcommand
@@ -45,7 +45,7 @@ module CF
45
45
  attr_accessor :errors
46
46
 
47
47
  # Badge setting for "worker" object
48
- attr_accessor :badge
48
+ attr_accessor :badges
49
49
 
50
50
  # ==Initializes a new "worker" object
51
51
  # ==Usage of HumanWorker.new(hash):
@@ -72,34 +72,26 @@ module CF
72
72
  @station = options[:station]
73
73
  @number = options[:number].nil? ? 1 : options[:number]
74
74
  @reward = options[:reward]
75
- @stat_badge = options[:stat_badge].nil? ? nil : options[:stat_badge]
75
+ @stat_badge = options[:stat_badge]
76
+ @badges = options[:badge]
76
77
  if @station
77
- if options[:stat_badge].nil?
78
- request =
79
- {
80
- :body =>
81
- {
82
- :api_key => CF.api_key,
83
- :worker => {:number => @number, :reward => @reward, :type => "HumanWorker"}
84
- }
85
- }
86
- else
87
- request =
78
+ request =
79
+ {
80
+ :body =>
88
81
  {
89
- :body =>
90
- {
91
- :api_key => CF.api_key,
92
- :worker => {:number => @number, :reward => @reward, :type => "HumanWorker"},
93
- :stat_badge => options[:stat_badge]
94
- }
82
+ :api_key => CF.api_key,
83
+ :worker => {:number => @number, :reward => @reward, :type => "HumanWorker"},
84
+ :badge => options[:badge],
85
+ :stat_badge => options[:stat_badge]
95
86
  }
96
- end
87
+ }
97
88
  resp = HTTParty.post("#{CF.api_url}#{CF.api_version}/lines/#{CF.account_name}/#{@station.line['title'].downcase}/stations/#{@station.index}/workers.json",request)
98
89
 
99
90
  self.id = resp.parsed_response['id']
100
91
  self.number = resp.parsed_response['number']
101
92
  self.reward = resp.parsed_response['reward']
102
93
  self.stat_badge = resp.parsed_response['stat_badge']
94
+ self.badges = resp.parsed_response['badges']
103
95
 
104
96
  if resp.code != 200
105
97
  self.errors = resp.parsed_response['error']['message']
@@ -109,52 +101,8 @@ module CF
109
101
  end
110
102
  end
111
103
 
112
- # ==Creation a new "worker" object with Badge
113
- # ==Usage Example:
114
- # ==In Plain Ruby way
115
- # badge_settings =
116
- # {
117
- # :title => 'Football Fanatic',
118
- # :description => "This qualification allows you to perform work at stations which have this badge.",
119
- # :max_badges => 3,
120
- # :test =>
121
- # {
122
- # :input => {:name => "Lionel Andres Messi", :country => "Argentina"},
123
- # :expected_output =>
124
- # [
125
- # {:birthplace => "Rosario, Santa Fe, Argentina",:match_options => {:tolerance => 10, :ignore_case => true }},
126
- # {:position => "CF",:match_options => {:tolerance => 1 }},
127
- # {:"current-club" => "Barcelona",:match_options => {:tolerance => 1, :ignore_case => false }}
128
- # ]
129
- # }
130
- # }
131
- # line = CF::Line.new("human_worker", "Digitization")
132
- # input_format = CF::InputFormat.new({:name => "image_url", :required => true, :valid_type => "url"})
133
- # line.input_formats input_format
134
- #
135
- # station = CF::Station.new({:type => "work"})
136
- # line.stations station
137
- #
138
- # worker = CF::HumanWorker.new({:number => 2, :reward => 20, :skill_badge => skill_badge})
139
- # line.stations.first.worker = worker
140
- #
141
- # line.stations.first.worker.badge = badge_settings
142
- def badge=(badge)
143
- request =
144
- {
145
- :body =>
146
- {
147
- :api_key => CF.api_key,
148
- :skill_badge => badge
149
- }
150
- }
151
- resp = HTTParty.post("#{CF.api_url}#{CF.api_version}/lines/#{CF.account_name}/#{@station.line['title'].downcase}/stations/#{@station.index}/workers/#{self.id}/badge.json",request)
152
- self.errors = resp['error']['message'] if resp.code != 200
153
- self.skill_badges << resp.parsed_response['skill_badges']
154
- end
155
-
156
104
  def to_s # :nodoc:
157
- "{:id => => #{self.id}, :number => #{self.number}, :reward => #{self.reward}, :stat_badge => #{self.stat_badge}, :errors => #{self.errors}}"
105
+ "{:id => => #{self.id}, :number => #{self.number}, :reward => #{self.reward}, :stat_badge => #{self.stat_badge}, :errors => #{self.errors},:badges =>#{self.badges}}"
158
106
  end
159
107
  end
160
108
  end
@@ -179,32 +179,26 @@ module CF
179
179
  number = worker_instance.number
180
180
  reward = worker_instance.reward
181
181
  stat_badge = worker_instance.stat_badge
182
- if stat_badge.nil?
183
- request =
184
- {
185
- :body =>
186
- {
187
- :api_key => CF.api_key,
188
- :worker => {:number => number, :reward => reward, :type => "HumanWorker"}
189
- }
190
- }
191
- else
192
- request =
182
+ badges = worker_instance.badges
183
+
184
+ request =
185
+ {
186
+ :body =>
193
187
  {
194
- :body =>
195
- {
196
- :api_key => CF.api_key,
197
- :worker => {:number => number, :reward => reward, :type => "HumanWorker"},
198
- :stat_badge => stat_badge
199
- }
188
+ :api_key => CF.api_key,
189
+ :worker => {:number => number, :reward => reward, :type => "HumanWorker"},
190
+ :stat_badge => stat_badge,
191
+ :badge => badges
200
192
  }
201
- end
193
+ }
194
+
202
195
  resp = HTTParty.post("#{CF.api_url}#{CF.api_version}/lines/#{CF.account_name}/#{self.line_title.downcase}/stations/#{self.index}/workers.json",request)
203
196
  worker = CF::HumanWorker.new({})
204
197
  worker.id = resp.parsed_response['id']
205
198
  worker.number = resp.parsed_response['number']
206
199
  worker.reward = resp.parsed_response['reward']
207
200
  worker.stat_badge = resp.parsed_response['stat_badge']
201
+ worker.badges = resp.parsed_response['badges']
208
202
  if resp.code != 200
209
203
  worker.errors = resp.parsed_response['error']['message']
210
204
  end
@@ -374,45 +368,5 @@ module CF
374
368
  def gold_standards=(gold_standard) # :nodoc:
375
369
  @gold_standards << gold_standard
376
370
  end
377
-
378
- #specify the badges for the station
379
- # ===Usage Example:
380
- # CF::Badge.new({:line => line, :station => s,:name => "Tomb Digitizer", :description => "This badge qualifies you to work on tomb digitization tasks.",:max_badges => 100,:gold_standards => ["#{@gold_standard.settings[:name]}"],:test_attributes =>{:type => "default",:retries => 10,:pass_percentage => 100,:check_manually => true}})
381
- def badges badge = nil
382
- line_title = line["title"] || line.title
383
- if badge
384
- if badge.settings[:test_attributes] && badge.settings[:test_attributes][:form_attributes].present?
385
- form = badge.settings[:test_attributes][:form_attributes]
386
- if( form[:type] == "CustomTaskForm" && form[:file])
387
- raw_html = ""
388
- File.open("#{form[:file]}").each_line do |line|
389
- raw_html += line
390
- end
391
- badge.settings[:test_attributes][:form_attributes].merge!({:raw_html => raw_html,:_type =>"CustomTaskForm"})
392
- end
393
- badge.settings[:test_attributes][:form_attributes].merge!({:_type =>"TaskForm"}) if form[:type] == "TaskForm"
394
- end
395
- request =
396
- {
397
- :body =>
398
- {
399
- :api_key => CF.api_key,
400
- :badge => badge.settings
401
- }
402
- }
403
- resp = HTTParty.post("#{CF.api_url}#{CF.api_version}/lines/#{CF.account_name}/#{line_title.downcase}/stations/#{self.index}/badges.json",request)
404
- badge = CF::Badge.new()
405
- badge.settings.merge!(resp.to_hash)
406
- self.errors = resp.parsed_response['error']['message'] if resp.code != 200
407
- @badges << badge
408
- else
409
- @badges
410
- end
411
- end
412
-
413
- def badges=(badge)
414
- @badges << badge
415
- end
416
-
417
371
  end
418
372
  end