cloudfactory 0.5.6 → 0.6

Sign up to get free protection for your applications and to get access to all the features.
data/CHANGELOG.md CHANGED
@@ -1,3 +1,6 @@
1
+ ## 0.6 (2012-06-06)
2
+ * Badge creation, update, deletion and listing added
3
+
1
4
  ## 0.5.6 (2012-05-17)
2
5
  * Priority field added in the line
3
6
 
data/lib/cf/badge.rb CHANGED
@@ -13,45 +13,132 @@ module CF
13
13
  attr_accessor :description
14
14
 
15
15
  # number of badge provided to the worker
16
- attr_accessor :max_badges
16
+ attr_accessor :max_badge_assignments
17
+
18
+ attr_accessor :allow_retake_after
17
19
 
18
20
  # Contains error message
19
21
  attr_accessor :errors
20
22
 
21
23
  def initialize(options={})
22
24
  options.symbolize_keys!
23
- if options[:test_attributes] && options[:test_attributes][:form_attributes]
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"})
25
+ #if the form is provided as a file then explicitly add title and raw_html for the form
26
+ if options[:form] && options[:form].class != Hash && File.exist?(options[:form])
27
+ file_type = IO.popen(["file", "--brief", "--mime-type", options[:form]], in: :close, err: :close).read.chomp
28
+ if file_type == "text/html"
29
+ options[:form] = {:title => "#{options[:name]}_form",:_type => "CustomTaskForm", :raw_html => File.read(options[:form])}
30
+ else
31
+ @errors = ["Wrong type of file for the form."]
32
+ return @errors
33
+ exit(1)
31
34
  end
32
- options[:test_attributes][:form_attributes].merge!({:_type =>"TaskForm"}) if form[:type] == "TaskForm"
33
35
  end
36
+
37
+ #known_answers of the badge get customize because to if unique identifier doesn't present then array of hashs returns the last hash for Httparty and get all key value merge into one in rest client/ rack
38
+ options[:known_answers] = self.class.customize_known_answers(options[:known_answers], options[:name]) if options[:known_answers].present?
39
+
34
40
  @settings = options
35
- @station = options.delete(:station)
36
- @line = options.delete(:line)
37
- if @line.present? && @station.present?
38
- request =
41
+ @name = options[:name]
42
+ @description = options[:description]
43
+ @allow_retake_after = options[:allow_retake_after]
44
+
45
+ request =
46
+ {
47
+ :body =>
39
48
  {
40
- :body =>
41
- {
42
- :api_key => CF.api_key,
43
- :badge => options
44
- }
49
+ :api_key => CF.api_key,
50
+ :badge => options
45
51
  }
52
+ }
46
53
 
47
- resp = HTTParty.post("#{CF.api_url}#{CF.api_version}/lines/#{CF.account_name}/#{@line.title.downcase}/stations/#{@station.index}/badges.json",request)
48
- @station.badges = self
49
- self.errors = resp.parsed_response['error']['message'] if resp.code != 200
54
+ resp = HTTParty.post("#{CF.api_url}#{CF.api_version}/accounts/#{CF.account_name}/badges.json",request)
55
+ begin
56
+ self.errors = resp["error"]["message"] if resp.code != 200
57
+ return resp
58
+ rescue
59
+ self.errors = ["Unexpected error found. Confirm that you are in correct path and try again."]
50
60
  end
51
61
  end
52
62
 
53
63
  def self.create(*args)
54
64
  Badge.new(args.first)
55
65
  end
66
+
67
+ def self.update(badge_name, update_params)
68
+ badge_name = badge_name.parameterize
69
+ update_params.symbolize_keys!
70
+ if update_params[:form] && update_params[:form].class != Hash && File.exist?(update_params[:form])
71
+ file_type = IO.popen(["file", "--brief", "--mime-type", update_params[:form]], in: :close, err: :close).read.chomp
72
+ if file_type == "text/html"
73
+ update_params[:form] = {:title => "#{update_params[:name]}_form",:_type => "CustomTaskForm", :raw_html => File.read(update_params[:form])}
74
+ else
75
+ return
76
+ end
77
+ end
78
+
79
+ update_params[:known_answers] = customize_known_answers(update_params[:known_answers], update_params[:name]) if update_params[:known_answers].present?
80
+
81
+ request =
82
+ {
83
+ :body =>
84
+ {
85
+ :api_key => CF.api_key,
86
+ :badge => update_params
87
+ }
88
+ }
89
+ resp = HTTParty.put("#{CF.api_url}#{CF.api_version}/accounts/#{CF.account_name}/badges/#{badge_name}.json",request)
90
+ return resp
91
+ end
92
+
93
+ def self.destroy(*args)
94
+ name = args[0].parameterize
95
+ options = args[1].nil? ? {} : args[1]
96
+ decendents = check_for_decendents(name)
97
+ if decendents
98
+ response = delete("/accounts/#{CF.account_name}/badges/#{name}.json") if options.force
99
+ else
100
+ response = delete("/accounts/#{CF.account_name}/badges/#{name}.json")
101
+ end
102
+ @errors = response['error']['message'] if response['code'] != 200
103
+ return response
104
+ end
105
+
106
+ #list all badges with in the account if name is not provided else it will return list all values of the given badge
107
+ def self.list(name = nil)
108
+ response = get("/accounts/#{CF.account_name}/badges.json", :name => name)
109
+ @errors = response['error']['message'] if response['code'] != 200
110
+ return response
111
+ end
112
+
113
+ protected
114
+
115
+ #insert name to the goldstandard/known_answer if name is not provided
116
+ def self.customize_known_answers(known_answers, badge_name)
117
+ index = 1
118
+ known_answers.each do |known_answer|
119
+ unless known_answer["name"].present?
120
+ known_answer.merge!("name" => "#{badge_name}_answer_#{index}")
121
+ index +=1
122
+ end
123
+ end
124
+ end
125
+
126
+
127
+ #list the decendents for the badges like worker_associated, line_associated, number of tasks associated with the badge
128
+ def self.check_for_decendents(name)
129
+ response = get("/accounts/#{CF.account_name}/badges.json", :name => name)
130
+ @errors = response["error"]["message"] unless response["code"] == 200
131
+ unless @errors
132
+ lines = response["badges"].first["line_associated"]
133
+ workers = response["badges"].first["workers"]
134
+ tasks = response["badges"].first["num_of_tasks"]
135
+ #if the lines of worker count is greater then 0 then return true else return lines and worker count
136
+ if lines > 0 || workers > 0
137
+ {:lines_count => lines, :workers_count => workers, :tasks => tasks }
138
+ else
139
+ false
140
+ end
141
+ end
142
+ end
56
143
  end
57
144
  end
data/lib/cf/cli.rb CHANGED
@@ -17,12 +17,15 @@ require 'active_support/core_ext/object/blank'
17
17
 
18
18
  cli_directory = File.expand_path("../cf/cli", File.dirname(__FILE__))
19
19
  require "#{cli_directory}/config"
20
+ require "#{cli_directory}/badge_yaml_validator"
21
+ require "#{cli_directory}/badge"
20
22
  require "#{cli_directory}/line_yaml_validator"
21
23
  require "#{cli_directory}/line"
22
24
  require "#{cli_directory}/form"
23
25
  require "#{cli_directory}/production"
24
26
 
25
27
 
28
+
26
29
  if ENV['TEST']
27
30
  require 'pry'
28
31
  end
@@ -33,9 +36,9 @@ module Cf # :nodoc: all
33
36
  include Cf::Config
34
37
 
35
38
  def help(*args)
36
- File.open(File.expand_path(File.dirname(__FILE__)+"/help.txt")).each_line{ |s|
37
- say s
38
- }
39
+ File.open(File.expand_path(File.dirname(__FILE__)+"/help.txt")).each_line{ |s|
40
+ say s
41
+ }
39
42
  end
40
43
 
41
44
  map "-v" => :version
@@ -59,7 +62,7 @@ module Cf # :nodoc: all
59
62
 
60
63
  no_tasks do
61
64
  def ask_password(message)
62
- ::HighLine.new.ask(message) do |q|
65
+ ::HighLine.new.ask(message) do |q|
63
66
  q.echo = '*'
64
67
  end
65
68
  end
@@ -103,6 +106,9 @@ module Cf # :nodoc: all
103
106
  # later it can be replaced with hacked millisami-thor version of the thor library with run-time dependency via Bundler
104
107
  subcommand "production", Cf::Production
105
108
 
109
+ desc "badge", "Commands to manage Badges. For more info cf badge help"
110
+ subcommand "badge", Cf::Badge
111
+
106
112
  desc "output <run-title>", "Get the output of run. For more info, cf output help"
107
113
  method_option :run_title, :type => :string, :required => true, :aliases => "-t", :desc => "the index of the station"
108
114
  method_option :station_index, :type => :numeric, :aliases => "-s", :desc => "the index of the station"
@@ -128,7 +134,7 @@ module Cf # :nodoc: all
128
134
  output = CF::Run.final_output(run_title)
129
135
  end
130
136
  if !output.empty?
131
- output.each
137
+ output.each
132
138
  csv_str = CSVHash(output,output.first.keys)
133
139
  csv_str = csv_str.gsub("\"\"", '"')
134
140
  FileUtils.mkdir("#{line_source}/output") unless Dir.exist?("#{line_source}/output") if RUBY_VERSION > "1.9"
@@ -0,0 +1,234 @@
1
+ require 'thor/group'
2
+
3
+ module Cf # :nodoc: all
4
+ class NewBadge < Thor::Group # :nodoc: all
5
+ include Thor::Actions
6
+ include Cf::Config
7
+ source_root File.expand_path('../templates', __FILE__)
8
+
9
+ def generate
10
+ badge_destination = "#{Dir.pwd}/badges"
11
+ FileUtils.mkdir(badge_destination)
12
+ copy_file("sample-line/badge.yml", "#{badge_destination}/badge.yml")
13
+ end
14
+ end
15
+ end
16
+
17
+ module Cf # :nodoc: all
18
+ class Badge < Thor
19
+ include Cf::Config
20
+ include Cf::BadgeYamlValidator
21
+
22
+
23
+ desc "badge generate", "Generate a new badge template at badges/badge.yml"
24
+ method_option :force, :type => :boolean, :default => false, :aliases => "-f", :desc => "force to overwrite the files if already exists, default is false"
25
+ def generate
26
+ yaml_destination = "#{Dir.pwd}/badges/badge.yml"
27
+ FileUtils.rm_rf("#{Dir.pwd}/badges", :verbose => true) if options.force?
28
+ if File.exist?(yaml_destination)
29
+ say "Skipping #{yaml_destination} because it already exists.", :red
30
+ else
31
+ say "Generating a new badge template #{yaml_destination}", :green
32
+ Cf::NewBadge.start()
33
+ say "Badge template generated successfully.", :green
34
+ say "Modify the #{yaml_destination} file and create badge with: cf badge create", :yellow
35
+ end
36
+ end
37
+
38
+
39
+
40
+ desc "badge create", "Create badges that are in badge.yml"
41
+ def create
42
+ badge_source = "#{Dir.pwd}/badges"
43
+ yaml_source = "#{badge_source}/badge.yml"
44
+
45
+ unless File.exist?(yaml_source)
46
+ say "The badge.yml file does not exist in this directory.", :red
47
+ return
48
+ end
49
+ errors = validate(yaml_source)
50
+ unless errors.present?
51
+ set_target_uri(false)
52
+ set_api_key(yaml_source)
53
+ CF.account_name = CF::Account.info['name']
54
+
55
+ badge_dump = YAML::load(File.read(yaml_source).strip)
56
+ badge_dump["badge"].each do |badge_hash|
57
+ name = badge_hash["name"]
58
+ do_exist = CF::Badge.list(name.parameterize)
59
+ if do_exist && do_exist["code"]==200
60
+ say "A badge named #{name} already exists.", :yellow
61
+ override = agree("Do you want to override ? [y/n] ")
62
+ override == true ? badge_hash.merge!(:confirmed => true) : ((say "Badge creation aborted!", :red) and exit(1))
63
+ end
64
+ say "Creating badge '#{name}'"
65
+ badge = CF::Badge.new(badge_hash)
66
+ if badge.errors.present?
67
+ say "Errors: \n", :red
68
+ badge.errors.each do |error|
69
+ say(error, :red)
70
+ end
71
+ exit(1)
72
+ else
73
+ say "A new badge named '#{name}' created sucessfully!"
74
+ end
75
+ end
76
+ else
77
+ say "Following errors has been encountered in your badge.yml file: #{errors}" , :red
78
+ end
79
+ end
80
+
81
+
82
+
83
+ desc "badge update <badge_name>", "Updates the given badge within your account. Use 'cf badge update' to update all badges in badge.yml"
84
+ def update(badge_name = nil)
85
+ badge_source = "#{Dir.pwd}/badges"
86
+ yaml_source = "#{badge_source}/badge.yml"
87
+
88
+ unless File.exist?(yaml_source)
89
+ say "The badge.yml file does not exist in this directory", :red
90
+ return
91
+ end
92
+ errors = validate(yaml_source)
93
+ unless errors.present?
94
+ set_target_uri(false)
95
+ set_api_key(yaml_source)
96
+ CF.account_name = CF::Account.info['name']
97
+
98
+ badge_dump = YAML::load(File.read(yaml_source).strip)
99
+
100
+ badges = badge_dump["badge"]
101
+
102
+ #check whether the given badge_name is present in badge.yml file and if present then take the given badge_hash for update
103
+ if badge_name
104
+ selected_badge = badges.select {|f| f["name"].parameterize == badge_name.parameterize }
105
+ if selected_badge.present?
106
+ badges = selected_badge
107
+ else
108
+ say "Could not find badge named '#{badge_name}' in your badge.yml file", :red
109
+ exit(1)
110
+ end
111
+ end
112
+
113
+ badges.each do |badge_hash|
114
+ previous_name = badge_hash["name"]["from"] || badge_hash["name"]
115
+ badge_hash["name"] = badge_hash["name"]["to"] || badge_hash["name"]
116
+ do_exist = CF::Badge.list(previous_name.parameterize)
117
+ #check whetether the badge do exist and has its decendents if do then retain_current_worker_badge = true so that worker and lines associated get retain if the badge get updated other wise the badge act as a new badge
118
+ if do_exist && do_exist["code"]==200
119
+ descendents = CF::Badge.check_for_decendents(previous_name.parameterize)
120
+ if descendents
121
+ say("\n!!! Warning !!!\n The badge '#{previous_name}' has the following number of tasks, lines and workers asscociated with it.\n", :yellow)
122
+ badge_table = table do |t|
123
+ t.headings = [ 'Tasks', 'Lines', 'Workers']
124
+ t << [ descendents[:tasks], descendents[:lines_count], descendents[:workers_count]]
125
+ end
126
+ say(badge_table)
127
+ say("\n!!! Warning !!!\n Retaining the workers will keep the workers associated with the badge.\n", :yellow)
128
+ update_forcefully = agree("Do you want to retain the workers? [y/n] ")
129
+ badge_hash.merge!(:retain_workers => false) if update_forcefully == false
130
+ end
131
+
132
+ #now update the badge
133
+ say "Updating badge named '#{previous_name}'"
134
+ badge = CF::Badge.update(previous_name,badge_hash)
135
+ if badge && badge.code == 200
136
+ say "A badge named '#{previous_name}' updated sucessfully!"
137
+ else
138
+ if badge.code == 422
139
+ say badge["error"]["message"]
140
+ else
141
+ say "A badge named '#{previous_name}' can not be updated", :red
142
+ end
143
+ exit(1)
144
+ end
145
+ else
146
+ say "A badge named '#{previous_name}' does not exist!", :red
147
+ exit(1)
148
+ end
149
+ end
150
+ else
151
+ say "Following errors has been encountered in your badge.yml file: #{errors}" , :red
152
+ end
153
+ end
154
+
155
+
156
+
157
+ desc "badge delete <badge name>", "Delete the given badge within your account"
158
+ method_option :force, :type => :boolean, :aliases => "-f", :default => false, :desc => "force delete the badge"
159
+ def delete(name = nil)
160
+ #set badge basic credentials
161
+ line_source = Dir.pwd
162
+ yaml_source = "#{line_source}/line.yml"
163
+ set_target_uri(false)
164
+ set_api_key(yaml_source)
165
+ set_target_uri(false)
166
+ CF.account_name = CF::Account.info['name']
167
+
168
+ #list all badges if name is not present else list the specific badge
169
+ if name
170
+ badge_decendents = CF::Badge.check_for_decendents(name)
171
+ if badge_decendents
172
+ say("\n!!! Warning !!!\n The badge #{name} has following number of tasks, lines and workers asscociated with it.\n", :yellow)
173
+ badge_table = table do |t|
174
+ t.headings = [ 'Tasks', 'Lines', 'Workers']
175
+ t << [ badge_decendents[:tasks], badge_decendents[:lines_count], badge_decendents[:workers_count]]
176
+ end
177
+ say(badge_table)
178
+
179
+ delete_forcefully = agree("Do you still want to delete this badge? [y/n] ")
180
+ if delete_forcefully
181
+ badge_resp = CF::Badge.destroy(name,options.merge(:force => true))
182
+ else
183
+ say "Badge deletion aborted!", :yellow
184
+ exit(1)
185
+ end
186
+ else
187
+ say "Deleting badge named '#{name}'"
188
+ badge_resp = CF::Badge.destroy(name)
189
+ end
190
+ badge_resp["code"] == 200 ? (say "A badge named #{name} deleted sucessfully!", :green) : (say badge_resp["error"]["message"], :red)
191
+ else
192
+ say "Name of the badge for deletion is missing.", :red
193
+ end
194
+ end
195
+
196
+
197
+
198
+ desc "badge list ", "List all badges asscociated with your account. Use 'cf badge list <badge_name>' for single badge"
199
+ def list(name = nil)
200
+ #set badge basic credentials
201
+ line_source = Dir.pwd
202
+ yaml_source = "#{line_source}/line.yml"
203
+ set_target_uri(false)
204
+ set_api_key(yaml_source)
205
+ set_target_uri(false)
206
+ CF.account_name = CF::Account.info['name']
207
+
208
+ #list all badges if name is not present else list the specific badge
209
+ if name
210
+ badge_resp = CF::Badge.list(name)
211
+ else
212
+ badge_resp = CF::Badge.list
213
+ end
214
+
215
+ #show list of badges in the tabular view
216
+ if badges = badge_resp["badges"]
217
+ say "Listing badges within your account" , :green
218
+ badges.sort! { |a, b| a['name'] <=> b['name'] }
219
+ badge_table = table do |t|
220
+ t.headings = ["Name", 'Number oF Tasks', 'Lines Associates', 'Workers', 'description']
221
+ badges.each do |badge|
222
+ badge = Hashie::Mash.new(badge)
223
+ t << [badge.name, badge.num_of_tasks, badge.line_associated, badge.workers, badge.description]
224
+ end
225
+ end
226
+ say(badge_table)
227
+ else
228
+ say badge_resp["error"]["message"], :red
229
+ end
230
+ end
231
+
232
+
233
+ end
234
+ end