cloudfactory 0.0.13

Sign up to get free protection for your applications and to get access to all the features.
Files changed (116) hide show
  1. data/.gitignore +11 -0
  2. data/.rspec +1 -0
  3. data/Gemfile +10 -0
  4. data/README.md +44 -0
  5. data/Rakefile +40 -0
  6. data/bin/cf +8 -0
  7. data/cf.gemspec +76 -0
  8. data/example/google_translate_app/Gemfile +12 -0
  9. data/example/google_translate_app/config.ru +7 -0
  10. data/example/google_translate_app/google_translate_input.csv +4 -0
  11. data/example/google_translate_app/google_translator_app.rb +53 -0
  12. data/example/google_translate_app/views/index.haml +2 -0
  13. data/example/google_translate_app/views/layout.haml +7 -0
  14. data/example/google_translate_app/views/run.haml +4 -0
  15. data/example/google_translate_app/views/style.sass +2 -0
  16. data/example/human_worker_app/Gemfile +12 -0
  17. data/example/human_worker_app/config.ru +7 -0
  18. data/example/human_worker_app/human_worker_app.rb +55 -0
  19. data/example/human_worker_app/human_worker_input.csv +5 -0
  20. data/example/human_worker_app/public/app.js +12 -0
  21. data/example/human_worker_app/temp.csv +3 -0
  22. data/example/human_worker_app/views/index.haml +15 -0
  23. data/example/human_worker_app/views/layout.haml +10 -0
  24. data/example/human_worker_app/views/result.haml +18 -0
  25. data/example/human_worker_app/views/run.haml +12 -0
  26. data/example/human_worker_app/views/style.sass +25 -0
  27. data/example/sample_yaml_files/concept_tagging_robot.yaml +18 -0
  28. data/example/sample_yaml_files/content_scraping_robot.yaml +19 -0
  29. data/example/sample_yaml_files/entity_extraction_robot.yaml +18 -0
  30. data/example/sample_yaml_files/google_translate_robot.yaml +20 -0
  31. data/example/sample_yaml_files/image_processing_robot.yaml +20 -0
  32. data/example/sample_yaml_files/keyword_matching_and_text_extraction_robot.yaml +26 -0
  33. data/example/sample_yaml_files/mailer_robot.yaml +21 -0
  34. data/example/sample_yaml_files/media_converter_robot.yaml +21 -0
  35. data/example/sample_yaml_files/media_splitting_robot.yaml +20 -0
  36. data/example/sample_yaml_files/multiple_skill_badge.yaml +75 -0
  37. data/example/sample_yaml_files/sentiment_robot.yaml +19 -0
  38. data/example/sample_yaml_files/skill_badge.yaml +56 -0
  39. data/example/sample_yaml_files/stat_badge.yaml +40 -0
  40. data/example/sample_yaml_files/term_extraction_robot.yaml +20 -0
  41. data/example/sample_yaml_files/tournament_station_and_form_fields.yaml +40 -0
  42. data/features/form_generation.feature +46 -0
  43. data/features/form_preview.feature +98 -0
  44. data/features/line_creation.feature +99 -0
  45. data/features/line_deletion.feature +50 -0
  46. data/features/line_generation.feature +57 -0
  47. data/features/run.feature +141 -0
  48. data/features/support/cli_steps.rb +16 -0
  49. data/features/support/env.rb +23 -0
  50. data/features/target_url.feature +82 -0
  51. data/fixtures/api_credentials_example.yml +4 -0
  52. data/fixtures/input_data/media_converter_robot.csv +2 -0
  53. data/fixtures/input_data/test.csv +2 -0
  54. data/lib/cf.rb +94 -0
  55. data/lib/cf/account.rb +32 -0
  56. data/lib/cf/cli.rb +52 -0
  57. data/lib/cf/cli/config.rb +87 -0
  58. data/lib/cf/cli/form.rb +82 -0
  59. data/lib/cf/cli/line.rb +237 -0
  60. data/lib/cf/cli/production.rb +62 -0
  61. data/lib/cf/cli/templates/css_file.css.erb +22 -0
  62. data/lib/cf/cli/templates/form_preview.html.erb +17 -0
  63. data/lib/cf/cli/templates/html_file.html.erb +21 -0
  64. data/lib/cf/cli/templates/js_file.js.erb +18 -0
  65. data/lib/cf/cli/templates/line.tt +55 -0
  66. data/lib/cf/cli/templates/sample-line/form.css +27 -0
  67. data/lib/cf/cli/templates/sample-line/form.html +26 -0
  68. data/lib/cf/cli/templates/sample-line/form.js +7 -0
  69. data/lib/cf/cli/templates/sample-line/line.yml.erb +67 -0
  70. data/lib/cf/cli/templates/sample-line/sample-line.csv +3 -0
  71. data/lib/cf/client.rb +56 -0
  72. data/lib/cf/custom_task_form.rb +136 -0
  73. data/lib/cf/department.rb +24 -0
  74. data/lib/cf/final_output.rb +20 -0
  75. data/lib/cf/form_field.rb +62 -0
  76. data/lib/cf/human_worker.rb +67 -0
  77. data/lib/cf/input_format.rb +134 -0
  78. data/lib/cf/line.rb +231 -0
  79. data/lib/cf/robot_worker.rb +31 -0
  80. data/lib/cf/run.rb +158 -0
  81. data/lib/cf/station.rb +340 -0
  82. data/lib/cf/task_form.rb +147 -0
  83. data/lib/cf/version.rb +3 -0
  84. data/lib/generators/cf/form/form_generator.rb +55 -0
  85. data/lib/generators/cf/form/templates/cf_form.html.erb +11 -0
  86. data/lib/generators/cf/install/install_generator.rb +22 -0
  87. data/lib/generators/cf/install/templates/README +13 -0
  88. data/lib/generators/cf/install/templates/cloud_factory.rb +7 -0
  89. data/spec/account_spec.rb +11 -0
  90. data/spec/badge_spec.rb +88 -0
  91. data/spec/concept_tagging_robot_spec.rb +54 -0
  92. data/spec/config_spec.rb +20 -0
  93. data/spec/content_scraping_robot_spec.rb +58 -0
  94. data/spec/custom_task_form_spec.rb +190 -0
  95. data/spec/department_spec.rb +14 -0
  96. data/spec/entity_extraction_robot_spec.rb +56 -0
  97. data/spec/form_field_spec.rb +126 -0
  98. data/spec/generators/form_generator_spec.rb +60 -0
  99. data/spec/generators/install_generator_spec.rb +35 -0
  100. data/spec/google_translate_robot_spec.rb +64 -0
  101. data/spec/human_worker_spec.rb +118 -0
  102. data/spec/image_processing_robot_spec.rb +56 -0
  103. data/spec/input_format_spec.rb +113 -0
  104. data/spec/keyword_matching_and_text_extraction_robot_spec.rb +73 -0
  105. data/spec/line_spec.rb +338 -0
  106. data/spec/mailer_robot_spec.rb +62 -0
  107. data/spec/media_converter_robot_spec.rb +72 -0
  108. data/spec/media_splitting_robot_spec.rb +62 -0
  109. data/spec/run_spec.rb +298 -0
  110. data/spec/sentiment_robot_spec.rb +56 -0
  111. data/spec/spec_helper.rb +39 -0
  112. data/spec/station_spec.rb +256 -0
  113. data/spec/task_form_spec.rb +96 -0
  114. data/spec/term_extraction_robot_spec.rb +58 -0
  115. data/spec/text_appending_robot_spec.rb +86 -0
  116. metadata +472 -0
@@ -0,0 +1,26 @@
1
+ <div id="station_2_instructions" class="station_2 cf_form_instruction">
2
+ <ul>
3
+ <!-- <li>Sample bullet list of instruction</li> -->
4
+ <li>Find study information of the following CEO</li>
5
+ </ul>
6
+ </div>
7
+
8
+ <div id="station_2_form" class="station_2 cf_form_content">
9
+ <label>{{ceo-name}}</label>
10
+ <label>{{company}}</label>
11
+
12
+ <div id = "field-panel">
13
+ <p>
14
+ <label>Qualification</label>
15
+ <select id="qualification" name="output[qualification]">
16
+ <option>Masters</option>
17
+ <option>Bachelors</option>
18
+ <option>Other</option>
19
+ </select>
20
+ </p>
21
+ <p>
22
+ <label>University</label>
23
+ <input id="university" type="text" name="output[university]" data-valid-type="general" />
24
+ </p>
25
+ </div>
26
+ </div>
@@ -0,0 +1,7 @@
1
+ <script src="http://code.jquery.com/jquery-latest.js"></script>
2
+
3
+ <script type="text/javascript">
4
+ $(document).ready(function(){
5
+ $('<p class="appended_para">I paragraph, appended here via jquery</p>').appendTo("#field-panel");
6
+ });
7
+ </script>
@@ -0,0 +1,67 @@
1
+ # ☁ ☁ ☁ ☁ ☁ ☁ ☁ ☁ ☁ ☁ ☁ ☁ ☁ ☁ ☁ ☁ ☁ ☁ ☁ ☁ ☁ ☁ ☁ ☁ ☁ ☁ ☁ ☁ ☁ ☁ ☁ ☁ ☁ ☁ ☁ ☁ ☁ ☁ ☁ ☁
2
+ # Assembly Line: <%= title.underscore.dasherize %>
3
+ # ☁ ☁ ☁ ☁ ☁ ☁ ☁ ☁ ☁ ☁ ☁ ☁ ☁ ☁ ☁ ☁ ☁ ☁ ☁ ☁ ☁ ☁ ☁ ☁ ☁ ☁ ☁ ☁ ☁ ☁ ☁ ☁ ☁ ☁ ☁ ☁ ☁ ☁ ☁ ☁
4
+ # See docs at http://developers.cloudfactory.com/lines/yaml.html
5
+ # See examples at http://developers.cloudfactory.com/lines/examples.html
6
+ # Fill in your API key below! (See http://developers.cloudfactory.com/account#settings)
7
+ api_key: fill_in_your_api_key
8
+ title: <%= title.underscore.dasherize %>
9
+ description: A sample line generated via CLI to use both standard and custom form.
10
+ department: Data Processing # Digitization, Web Research, etc
11
+
12
+ # Line Input Formats (see http://developers.cloudfactory.com/lines/yaml.html#line-input-formats)
13
+ # input_formats:
14
+ # - name: company
15
+ # required: true
16
+ # valid_type: general # general, url, date, email, ...
17
+
18
+ # Stations (see http://developers.cloudfactory.com/lines/yaml.html#stations)
19
+ # stations:
20
+ # # Sample Station #1: Human Worker
21
+ # - station:
22
+ # station_index: 1
23
+ # station_type: work # work, improve, tournament
24
+ # # Worker (see http://developers.cloudfactory.com/lines/yaml.html#workers)
25
+ # worker:
26
+ # worker_type: human # "human" or name of robot (google_translate_robot, etc)
27
+ # num_workers: 2
28
+ # reward: 5
29
+ # # Task Form (see http://developers.cloudfactory.com/lines/yaml.html#task-forms)
30
+ # task_form:
31
+ # form_title: Research to find CEO of a company.
32
+ # instruction: Enter name and email of the CEO for the company below
33
+ # form_fields:
34
+ # - label: CEO Name
35
+ # field_type: short_answer
36
+ # required: true
37
+ # - label: CEO Email
38
+ # field_type: email
39
+ # required: true
40
+
41
+ # # Sample Station #2: Robot Worker
42
+ # - station:
43
+ # station_index: 2
44
+ # station_type: work # work, improve, tournament
45
+ # # Worker (see http://developers.cloudfactory.com/lines/yaml.html#workers)
46
+ # worker:
47
+ # worker_type: google_translate_robot # "human" or name of robot (content_scraper_robot, etc)
48
+ # # Robot Settings (see http://developers.cloudfactory.com/robots/)
49
+ # settings:
50
+ # data: ["{sentence}"]
51
+ # from: en
52
+ # to: fr
53
+ #
54
+ # # Sample Station #3: Tournament
55
+ # - station:
56
+ # station_index: 3
57
+ # station_type: tournament
58
+ # worker:
59
+ # worker_type: human
60
+ # num_workers: 2
61
+ # reward: 3
62
+ # custom_task_form:
63
+ # form_title: Get study background
64
+ # instruction: Find qualification info of given CEO
65
+ # html: form.html
66
+ # css: form.css
67
+ # js: form.js
@@ -0,0 +1,3 @@
1
+ company,website
2
+ Apple,http://apple.com
3
+ Google,http://google.com
data/lib/cf/client.rb ADDED
@@ -0,0 +1,56 @@
1
+ module CF
2
+ module Client
3
+
4
+ extend ActiveSupport::Concern
5
+
6
+ module ClassMethods
7
+ def default_params
8
+ {:api_key => CF.api_key}
9
+ end
10
+
11
+ def get(*args)
12
+ handle_response RestClient.get("#{CF.api_url}#{CF.api_version}#{args.first}", :params => default_params, :accept => 'json'){ |response, request, result| response }
13
+ end
14
+
15
+ def post(*args)
16
+ handle_response RestClient.post("#{CF.api_url}#{CF.api_version}#{args.first}", args.last.merge!(default_params), :accept => 'json'){ |response, request, result| response }
17
+ end
18
+
19
+ def put(*args)
20
+ handle_response RestClient.put("#{CF.api_url}#{CF.api_version}#{args.first}", args.last.merge!(default_params), :accept => 'json'){ |response, request, result| response }
21
+ end
22
+
23
+ def delete(*args)
24
+ handle_response RestClient.delete("#{CF.api_url}#{CF.api_version}#{args.first}?api_key=#{CF.api_key}", :accept => 'json'){ |response, request, result| response }
25
+ end
26
+
27
+ def handle_response(response)
28
+ # FIX: raise the exception along with the response error message
29
+ # Ref: http://www.simonecarletti.com/blog/2009/12/inside-ruby-on-rails-rescuable-and-rescue_from/
30
+ # case response.code
31
+ # when 401; raise Unauthorized.new
32
+ # when 403; raise RateLimitExceeded.new
33
+ # when 404; raise ::CF::NotFound.new(response)
34
+ # when 400...500; raise ClientError.new
35
+ # when 500...600; raise ServerError.new(response.code)
36
+ # else; response
37
+ # end
38
+ unless response.length == 2
39
+ parsed_response = JSON.load(response)
40
+ if parsed_response.is_a?(Array)
41
+ parsed_response.map{|item| Hashie::Mash.new(item)}
42
+ else
43
+ parsed_resp = parsed_response.merge("code" => response.code)
44
+ new_response = parsed_resp.inject({ }) do |x, (k,v)|
45
+ x[k.sub(/\A_/, '')] = v
46
+ x
47
+ end
48
+ Hashie::Mash.new(new_response)
49
+ end
50
+ else
51
+ response
52
+ end
53
+ end
54
+ end
55
+ end
56
+ end
@@ -0,0 +1,136 @@
1
+ module CF
2
+ class CustomTaskForm
3
+ include Client
4
+
5
+ # Title of "custom_instruction" object, e.g. :title => "title_name of custom_instruction"
6
+ attr_accessor :title
7
+
8
+ # Description of "custom_instruction" object, e.g. :description => "description for title of custom_instruction"
9
+ attr_accessor :instruction
10
+
11
+ # raw_html is an attribute to store the custom html contents
12
+ attr_accessor :raw_html
13
+
14
+ # raw_css is an attribute to store the custom css contents
15
+ attr_accessor :raw_css
16
+
17
+ # raw_javascript is an attribute to store the custom javascript contents
18
+ attr_accessor :raw_javascript
19
+
20
+ # station attribute is required for association with custom_from object
21
+ attr_accessor :station
22
+
23
+ # ==Initializes a new CustomForm
24
+ # ==Usage custom_instruction.new(hash):
25
+ #
26
+ # attrs = {:title => "Enter text from a business card image",
27
+ # :description => "Describe"}
28
+ #
29
+ # instruction = CustomForm.new(attrs)
30
+ def initialize(options={})
31
+ @station = options[:station]
32
+ @title = options[:title]
33
+ @instruction = options[:instruction]
34
+ @raw_html = options[:raw_html]
35
+ @raw_css = options[:raw_css]
36
+ @raw_javascript = options[:raw_javascript]
37
+ if @station
38
+ @resp = self.class.post("/lines/#{CF.account_name}/#{@station.line_title.downcase}/stations/#{@station.index}/form.json", :form => {:title => @title, :instruction => @instruction, :_type => "CustomTaskForm", :raw_html => @raw_html, :raw_css => @raw_css, :raw_javascript => @raw_javascript})
39
+
40
+ # custom task form response not well formatted
41
+ # @id = @resp.from.id
42
+ custom_form = CF::CustomTaskForm.new({})
43
+ @resp.to_hash.each_pair do |k,v|
44
+ custom_form.send("#{k}=",v) if custom_form.respond_to?(k)
45
+ end
46
+ custom_form.station = @station
47
+ @station.form = custom_form
48
+ end
49
+ end
50
+
51
+ # ==Initializes a new CustomForm within block using Variable
52
+ # ==Usage of custom_instruction.create(instruction):
53
+ # ===Creating CustomForm using block variable
54
+ # attrs = {:title => "Enter text from a business card image",
55
+ # :description => "Describe"}
56
+ #
57
+ # html_content = '<div>.........</div>'
58
+ #
59
+ # css_content = 'body {background:#fbfbfb;}
60
+ # #instructions{
61
+ # text-align:center;
62
+ # }.....'
63
+ #
64
+ # javascript_content = '<script>.........</script>'
65
+ #
66
+ # instruction = CustomForm.create(instruction) do |i|
67
+ # i.html = html_content
68
+ # i.css = css_content
69
+ # i.javascript = javascript_content
70
+ # end
71
+ #
72
+ # ===OR without block variable
73
+ # instruction = CustomForm.create(instruction) do
74
+ # html html_content
75
+ # css css_content
76
+ # javascript javascript_content
77
+ # end
78
+ def self.create(form)
79
+ instruction = CustomTaskForm.new(form)
80
+ # if block.arity >= 1
81
+ # block.call(instruction)
82
+ # else
83
+ # instruction.instance_eval &block
84
+ # end
85
+ # instruction
86
+ end
87
+
88
+ # ==Usage of instruction.html:
89
+ # html_content = '<div>.........</div>'
90
+ #
91
+ # instruction.html = html_content
92
+ #
93
+ def html html_content = nil
94
+ if html_content
95
+ @html_content = html_content
96
+ else
97
+ @html_content
98
+ end
99
+ end
100
+ def html=(html_content) # :nodoc:
101
+ @html_content = html_content
102
+ end
103
+
104
+ # ==Usage of instruction.css:
105
+ # css_content = 'body {background:#fbfbfb;}
106
+ # #instructions{
107
+ # text-align:center;
108
+ # }.....'
109
+ #
110
+ # instruction.css = css_content
111
+ def css css_content = nil
112
+ if css_content
113
+ @css_content = css_content
114
+ else
115
+ @css_content
116
+ end
117
+ end
118
+ def css=(css_content) # :nodoc:
119
+ @css_content = css_content
120
+ end
121
+ # ==Usage of instruction.javascript:
122
+ # javascript_content = '<script>.........</script>'
123
+ #
124
+ # instruction.html = javascript_content
125
+ def javascript javascript_content = nil
126
+ if javascript_content
127
+ @javascript_content = javascript_content
128
+ else
129
+ @javascript_content
130
+ end
131
+ end
132
+ def javascript=(javascript_content) # :nodoc:
133
+ @javascript_content = javascript_content
134
+ end
135
+ end
136
+ end
@@ -0,0 +1,24 @@
1
+ module CF
2
+ class Department
3
+ include Client
4
+
5
+ # Id of the specific Category
6
+ attr_accessor :department_name
7
+
8
+ # Category name
9
+ attr_accessor :name
10
+
11
+ # ==Returns all Department
12
+ # ===Usage example
13
+ # categories = CF::Department.all
14
+ def self.all
15
+ response = get("/departments.json")
16
+ end
17
+
18
+ # Returns all lines of a specific Department
19
+ def self.get_lines_of_department(department_name)
20
+ @department_name = department_name
21
+ get("/departments/#{@department_name}.json")
22
+ end
23
+ end
24
+ end
@@ -0,0 +1,20 @@
1
+ module CF
2
+ class FinalOutput
3
+ include Client
4
+ attr_accessor :meta_data, :final_outputs, :unit_id, :final_output, :output
5
+
6
+ # def self.get_result(run_id)
7
+ # resp = get("/runs/#{run_id}/results.json")
8
+ #
9
+ # @final_output =[]
10
+ # resp.each do |r|
11
+ # result = self.new()
12
+ # r.to_hash.each_pair do |k,v|
13
+ # result.send("#{k}=",v) if result.respond_to?(k)
14
+ # end
15
+ # @results << result
16
+ # end
17
+ # return @results
18
+ # end
19
+ end
20
+ end
@@ -0,0 +1,62 @@
1
+ module CF
2
+ class FormField
3
+ require 'httparty'
4
+ include Client
5
+
6
+ # Label for "form_field" object, e.g. :label => "First Name"
7
+ attr_accessor :label
8
+
9
+ # field_type for "form_field" object, e.g. :field_type => "SA"
10
+ attr_accessor :field_type
11
+
12
+ # required boolean either true or false, e.g. :required => "true" & if false then you don't need to mention
13
+ attr_accessor :required
14
+
15
+ # ID of form field
16
+ attr_accessor :id
17
+
18
+ # station id attribute required for API Calls
19
+ attr_accessor :station_id
20
+ attr_accessor :form_field_params, :errors
21
+
22
+ # ==Initializes a new "form_field" object
23
+ # ==Usage of form_field.new(hash):
24
+ # line = CF::Line.create("Digitize", "Survey") do |l|
25
+ # CF::Station.create({:line => l, :type => "work"}) do |s|
26
+ # CF::StandardInstruction.create({:station => s, :title => "Enter text from a business card image", :description => "Describe"}) do |i|
27
+ # CF::FormField.new({:form => i, :label => "First Name", :field_type => "SA", :required => "true"})
28
+ # end
29
+ # end
30
+ # end
31
+ def initialize(options={})
32
+ @form = options[:form]
33
+ @label = options[:label]
34
+ @field_type = options[:field_type]
35
+ @required = options[:required]
36
+
37
+ if !@form.nil?
38
+ options.delete(:form)
39
+ party_param =
40
+ {
41
+ :body =>
42
+ {
43
+ :api_key => CF.api_key,
44
+ :form_field => options
45
+ }
46
+ }
47
+ resp = HTTParty.post("#{CF.api_url}#{CF.api_version}/lines/#{CF.account_name}/#{@form.station.line['title'].downcase}/stations/#{@form.station.index}/form_fields.json",party_param)
48
+ resp.parsed_response.each_pair do |k,v|
49
+ self.send("#{k}=",v) if self.respond_to?(k)
50
+ end
51
+ if resp.code != 200
52
+ self.errors = resp.parsed_response['error']['message']
53
+ end
54
+ self.form_field_params = options
55
+ @form.station.form.form_fields = self
56
+ return self
57
+ else
58
+ @form_field_params = options
59
+ end
60
+ end
61
+ end
62
+ end
@@ -0,0 +1,67 @@
1
+ module CF
2
+ class HumanWorker
3
+ include Client
4
+ require 'httparty'
5
+ extend ActiveSupport::Concern
6
+
7
+ attr_accessor :id, :number, :reward, :station, :stat_badge, :skill_badges, :errors, :badge
8
+
9
+ def initialize(options={})
10
+ @skill_badges = []
11
+ @station = options[:station]
12
+ @number = options[:number].nil? ? 1 : options[:number]
13
+ @reward = options[:reward]
14
+ @badge = options[:skill_badge].nil? ? nil : options[:skill_badge]
15
+ @stat_badge = options[:stat_badge].nil? ? nil : options[:stat_badge]
16
+ if @station
17
+ if options[:skill_badge].nil? && options[:stat_badge].nil?
18
+ request =
19
+ {
20
+ :body =>
21
+ {
22
+ :api_key => CF.api_key,
23
+ :worker => {:number => @number, :reward => @reward, :type => "HumanWorker"}
24
+ }
25
+ }
26
+ else
27
+ request =
28
+ {
29
+ :body =>
30
+ {
31
+ :api_key => CF.api_key,
32
+ :worker => {:number => @number, :reward => @reward, :type => "HumanWorker"},
33
+ :skill_badge => @badge,
34
+ :stat_badge => options[:stat_badge]
35
+ }
36
+ }
37
+ end
38
+ resp = HTTParty.post("#{CF.api_url}#{CF.api_version}/lines/#{CF.account_name}/#{@station.line['title'].downcase}/stations/#{@station.index}/workers.json",request)
39
+
40
+ self.id = resp.parsed_response['id']
41
+ self.number = resp.parsed_response['number']
42
+ self.reward = resp.parsed_response['reward']
43
+ self.stat_badge = resp.parsed_response['stat_badge']
44
+ @skill_badges << resp.parsed_response['skill_badges']
45
+
46
+ if resp.code != 200
47
+ self.errors = resp.parsed_response['error']['message']
48
+ end
49
+ self.station = options[:station]
50
+ self.station.worker = self
51
+ end
52
+ end
53
+
54
+ def badge=(badge)
55
+ request =
56
+ {
57
+ :body =>
58
+ {
59
+ :api_key => CF.api_key,
60
+ :skill_badge => badge
61
+ }
62
+ }
63
+ 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)
64
+ self.skill_badges << resp.parsed_response['skill_badges']
65
+ end
66
+ end
67
+ end