addax 0.10.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (6) hide show
  1. data/Rakefile +16 -0
  2. data/VERSION +1 -0
  3. data/bin/addax +7 -0
  4. data/lib/addax.rb +80 -0
  5. data/lib/addax/commands.rb +236 -0
  6. metadata +119 -0
@@ -0,0 +1,16 @@
1
+ begin
2
+ require 'jeweler'
3
+ Jeweler::Tasks.new do |gemspec|
4
+ gemspec.name = "addax"
5
+ gemspec.summary = "Command-line tool for accessing TIMA-SLS's ADDAX webservice."
6
+ gemspec.email = "guillaume.godetbar@gmail.com"
7
+ gemspec.homepage = "http://tima-sls.imag.fr/addax"
8
+ gemspec.authors = ["Guillaume Godet-Bar"]
9
+ gemspec.files = FileList["lib/**/*", "bin/*", "Rakefile", "VERSION"]
10
+ gemspec.executables = ['addax']
11
+ gemspec.add_dependency 'rest-client'
12
+ gemspec.add_dependency 'json'
13
+ end
14
+ rescue LoadError
15
+ puts "Jeweler not available. Install it with: gem install jeweler"
16
+ end
data/VERSION ADDED
@@ -0,0 +1 @@
1
+ 0.10.0
@@ -0,0 +1,7 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ $LOAD_PATH.unshift File.join(File.dirname(__FILE__), '../lib')
4
+ require 'addax'
5
+
6
+ opts = Addax::Exec.new(ARGV)
7
+ opts.parse!
@@ -0,0 +1,80 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require 'rest_client'
4
+ require 'json'
5
+ require 'readline'
6
+ require 'base64'
7
+ require 'tempfile'
8
+ require 'pp'
9
+
10
+ require File.join(File.dirname(__FILE__), 'addax/commands')
11
+
12
+ module Addax
13
+ USAGE = <<END
14
+ Addax, a command line tool for connecting with the Addax Webservice.
15
+
16
+ Usage
17
+
18
+ addax <Action>
19
+
20
+ Actions
21
+
22
+ [list | l] <object_type> - lists all available objects, which should be either 'oses|operating_systems', 'drivers', 'platforms'
23
+ <object_type> <id> - displays the data associated with the object instance, e.g. 'addax driver 1'
24
+ [fetch | f] <object_type> <id> <path> - returns the file associated with a driver or a platform
25
+ [generate | g] <id> <path> - downloads the generated sources for the driver associated with <id> into <path>
26
+ [create | c] <object_type> <param>=<value> [<param>=<value>]*
27
+ - creates a new instance of the object type, with the list of parameters provided.
28
+ [update | u] <object_type> <id> <param>=<value> [<param>=<value>]*
29
+ - modifies the object identified by <id> with the list of parameters provided.
30
+ [destroy | d] [-f] <object_type> <id> - destroys the object identified by <id>. -f to destroy without asking for confirmation.
31
+
32
+ END
33
+
34
+ SERVER_URL = 'http://tima-sls.imag.fr/addax'
35
+
36
+ class Exec
37
+
38
+ def initialize(args)
39
+ @args = args
40
+ end
41
+
42
+ def parse!
43
+ begin
44
+ parse
45
+ rescue ArgumentError
46
+ $stderr.puts USAGE
47
+ end
48
+ end
49
+
50
+ def parse
51
+ if ARGV.size == 2 && %w(l list).include?(ARGV[0]) && %w(operating_systems oses platforms drivers strategies).include?(ARGV[1])
52
+ Addax::Commands.list(ARGV[1])
53
+ elsif ARGV.size == 2 && %w(operating_system os driver platform).include?(ARGV[0])
54
+ Addax::Commands.show(ARGV[0], ARGV[1])
55
+ elsif ARGV.size == 3 && %w(g generate).include?(ARGV[0])
56
+ Addax::Commands.generate(ARGV[1], ARGV[2])
57
+ elsif ARGV.size > 2 && %w(c create).include?(ARGV[0]) && %w(operating_system os platform driver).include?(ARGV[1])
58
+ Addax::Commands.send("create_#{ARGV[1]}".to_sym, ARGV[2..-1])
59
+ elsif ARGV.size == 4 && %w(f fetch).include?(ARGV[0]) && %w(driver platform).include?(ARGV[1])
60
+ Addax::Commands.send("fetch_#{ARGV[1]}".to_sym, ARGV[2], ARGV[3])
61
+ elsif ARGV.size > 3 && %w(u update).include?(ARGV[0]) && %w(operating_system os platform driver).include?(ARGV[1])
62
+ Addax::Commands.update(ARGV[1], ARGV[2], ARGV[3..-1])
63
+ elsif ARGV.size >= 3 && %w(d destroy).include?(ARGV[0])
64
+ if ARGV[1] == '-f'
65
+ Addax::Commands.destroy(ARGV[2], ARGV[3])
66
+ else
67
+ begin
68
+ puts "Please confirm that you wish to destroy this resource (Y/n)"
69
+ line = Readline.readline()
70
+ end while !%w(Y n).include?(line)
71
+ if line == 'Y'
72
+ Addax::Commands.destroy(ARGV[1], ARGV[2])
73
+ end
74
+ end
75
+ else
76
+ raise ArgumentError
77
+ end
78
+ end
79
+ end
80
+ end
@@ -0,0 +1,236 @@
1
+ module Addax
2
+ module Commands
3
+
4
+ OUTPUTS = {
5
+ :generic_error => "ERROR. Something went wrong with the server.",
6
+ :not_found => "ERROR. Resource not found.",
7
+ :platform_data_missing => "ERROR. Platform data file (format: zip) is missing.",
8
+ :created_resource => "Successfully created resource.",
9
+ :updated_resource => "Successfully updated resource.",
10
+ :destroyed_resource => "Successfully destroyed resource.",
11
+ :security_tokens_error => "ERROR. Could not fetch security tokens from the server."
12
+ }
13
+
14
+ def self.list(type)
15
+ type = type == 'oses' ? 'operating_systems' : type
16
+ begin
17
+ response = RestClient.get "#{SERVER_URL}/#{type}.json"
18
+ rescue => e
19
+ abort OUTPUTS[:generic_error]
20
+ else
21
+ format(response.body)
22
+ end
23
+ end
24
+
25
+ def self.show(model, id)
26
+ type = type == 'os' ? 'operating_system' : type
27
+ begin
28
+ response = RestClient.get "#{SERVER_URL}/#{model}s/#{id}.json"
29
+ rescue => e
30
+ case e.response.code
31
+ when 404 then
32
+ abort OUTPUTS[:not_found]
33
+ else
34
+ abort OUTPUTS[:generic_error]
35
+ end
36
+ else
37
+ format(response.body)
38
+ end
39
+ end
40
+
41
+ def self.generate(driver_id, file_path)
42
+ begin
43
+ response = RestClient.post "#{SERVER_URL}/drivers/#{driver_id}/generate_sources", {}
44
+ rescue => e
45
+ case e.response.code
46
+ when 404 then
47
+ abort OUTPUTS[:not_found]
48
+ else
49
+ abort OUTPUTS[:generic_error]
50
+ end
51
+ else
52
+ file_name = response.headers[:content_disposition].scan(/filename="(.+)"/)[0][0] + ".zip"
53
+ File.open File.join(file_path, file_name), "w" do |f|
54
+ f.write(response.body)
55
+ end
56
+ puts "File was written to #{File.join(file_path, file_name)}"
57
+ end
58
+ end
59
+
60
+ def self.fetch_driver(object_id, file_path)
61
+ begin
62
+ response = RestClient.get "#{SERVER_URL}/drivers/#{object_id}/show_attachment"
63
+ rescue => e
64
+ case e.response.code
65
+ when 404 then
66
+ abort OUTPUTS[:not_found]
67
+ else
68
+ abort OUTPUTS[:generic_error]
69
+ end
70
+ else
71
+ file_name = response.headers[:content_disposition].scan(/filename="(.+)"/)[0][0] + ".xml"
72
+ File.open File.join(file_path, file_name), "w" do |f|
73
+ f.write(response.body)
74
+ end
75
+ puts "File was written to #{File.join file_path, file_name}"
76
+ end
77
+ end
78
+
79
+ def self.fetch_platform(object_id, file_path)
80
+ abort "ERROR: Platform data fetch not implemented yet!"
81
+ end
82
+
83
+ def self.create_platform(params)
84
+ param_hash = normalize_params(params)
85
+
86
+ authenticity_token, cookie = security_tokens
87
+
88
+ # The params should at least have a platform_data param
89
+ platform_data = param_hash.delete(:platform_data)
90
+ unless platform_data
91
+ abort OUTPUTS[:platform_data_missing]
92
+ end
93
+
94
+ begin
95
+ load_platform_data_response = RestClient.post "#{SERVER_URL}/platforms/load_file.json",
96
+ {:platform_data => File.new(platform_data, 'rb'), :authenticity_token => authenticity_token},
97
+ {:cookies => cookie}
98
+ rescue => e
99
+ abort OUTPUTS[:generic_error] + '\n' + format_error(e.response.body)
100
+ end
101
+
102
+ encoded_cache_name = load_platform_data_response.body
103
+
104
+ if param_hash[:root_component]
105
+ begin
106
+ create_platform_response = RestClient.post "#{SERVER_URL}/platforms.json?cache=#{encoded_cache_name}",
107
+ {:platform => param_hash, :authenticity_token => authenticity_token},
108
+ {:cookies => cookie}
109
+ rescue => e
110
+ abort OUTPUTS[:generic_error] + '\n' + format_error(e.response.body)
111
+ else
112
+ puts OUTPUTS[:created_resource]
113
+ format(create_platform_response.body)
114
+ end
115
+ else
116
+ abort "ERROR: Root component choice not yet implemented!"
117
+ end
118
+ end
119
+
120
+ def self.create_driver(params)
121
+ param_hash = normalize_params(params)
122
+
123
+ authenticity_token, cookie = security_tokens
124
+
125
+ begin
126
+ response = RestClient.post "#{SERVER_URL}/drivers.json",
127
+ {:driver => param_hash, :authenticity_token => authenticity_token},
128
+ {:cookies => cookie}
129
+ rescue => e
130
+ abort OUTPUTS[:generic_error] + '\n' + format_error(e.response.body)
131
+ else
132
+ puts OUTPUTS[:updated_resource]
133
+ format(response.body)
134
+ end
135
+ end
136
+
137
+ def self.create_operating_system(params)
138
+ param_hash = normalize_params(params)
139
+
140
+ authenticity_token, cookie = security_tokens
141
+
142
+ begin
143
+ response = RestClient.post "#{SERVER_URL}/operating_systems.json",
144
+ {:operating_system => param_hash,:authenticity_token => authenticity_token},
145
+ {:cookies => cookie}
146
+ rescue => e
147
+ abort OUTPUTS[:generic_error] + '\n' + format_error(e.response.body)
148
+ else
149
+ puts OUTPUTS[:created_resource]
150
+ format(response.body)
151
+ end
152
+ end
153
+
154
+ def self.update(object_type, object_id, params)
155
+ object_type = object_type == "os" ? "operating_system" : object_type
156
+ param_hash = normalize_params(params)
157
+
158
+ begin
159
+ response = RestClient.put "#{SERVER_URL}/#{object_type}s/#{object_id}.json",
160
+ {object_type.to_sym => param_hash}
161
+ rescue => e
162
+ abort OUTPUTS[:generic_error] + '\n' + format_error(e.response.body)
163
+ else
164
+ puts OUTPUTS[:updated_resource]
165
+ format(response.body)
166
+ end
167
+ end
168
+
169
+ def self.destroy(object_type, object_id)
170
+ authenticity_token, cookie = security_tokens
171
+ begin
172
+ response = RestClient.delete "#{SERVER_URL}/#{object_type}s/#{object_id}.json", {:cookies => cookie}
173
+ rescue => e
174
+ case e.response.code
175
+ when 404 then
176
+ abort OUTPUTS[:not_found]
177
+ else
178
+ abort OUTPUTS[:generic_error]
179
+ end
180
+ else
181
+ puts OUTPUTS[:destroyed_resource]
182
+ end
183
+ end
184
+
185
+ class << self
186
+ alias :create_os :create_operating_system
187
+ end
188
+
189
+ private
190
+ def self.security_tokens
191
+ begin
192
+ new_response = RestClient.get "#{SERVER_URL}/drivers/new.html" # Any form would do
193
+ rescue => e
194
+ abort OUTPUTS[:security_tokens_error]
195
+ else
196
+ authenticity_token = new_response.body.scan(/<meta name="csrf-token" content="(.*)"\/>/)[0][0]
197
+ cookie = new_response.cookies
198
+ [authenticity_token, cookie]
199
+ end
200
+ end
201
+
202
+ def self.normalize_params(param_array)
203
+ param_hash = param_array.inject({}){|acc, p| pieces = p.split('='); acc[pieces[0].to_sym] = pieces[1]; acc}
204
+ param_hash.delete(:id)
205
+ param_hash.delete(:created_at)
206
+ param_hash.delete(:updated_at)
207
+
208
+ param_hash
209
+ end
210
+
211
+ def self.format(json)
212
+ content = json.is_a?(String) ? JSON::parse(json) : json
213
+ if content.is_a?(Array)
214
+ content.each do |el|
215
+ format(el)
216
+ end
217
+ else
218
+ puts content.values[0].delete('name') + ":"
219
+ data = content.values[0]
220
+ data.each do |k, v|
221
+ puts "\t" + k + ": " + v.to_s #.gsub('_', ' ').capitalize + ": " + v.to_s
222
+ end
223
+
224
+ end
225
+ end
226
+
227
+ def self.format_error(json)
228
+ content = json.is_a?(String) ? JSON::parse(json) : json
229
+ if content.is_a?(Hash)
230
+ content.collect do |k, v|
231
+ "\t" + k + ' ' + v
232
+ end.join('\n')
233
+ end
234
+ end
235
+ end
236
+ end
metadata ADDED
@@ -0,0 +1,119 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: addax
3
+ version: !ruby/object:Gem::Version
4
+ prerelease: false
5
+ segments:
6
+ - 0
7
+ - 10
8
+ - 0
9
+ version: 0.10.0
10
+ platform: ruby
11
+ authors:
12
+ - Guillaume Godet-Bar
13
+ autorequire:
14
+ bindir: bin
15
+ cert_chain: []
16
+
17
+ date: 2011-02-15 00:00:00 +01:00
18
+ default_executable: addax
19
+ dependencies:
20
+ - !ruby/object:Gem::Dependency
21
+ name: json
22
+ requirement: &id001 !ruby/object:Gem::Requirement
23
+ none: false
24
+ requirements:
25
+ - - ">="
26
+ - !ruby/object:Gem::Version
27
+ segments:
28
+ - 0
29
+ version: "0"
30
+ type: :runtime
31
+ prerelease: false
32
+ version_requirements: *id001
33
+ - !ruby/object:Gem::Dependency
34
+ name: rest-client
35
+ requirement: &id002 !ruby/object:Gem::Requirement
36
+ none: false
37
+ requirements:
38
+ - - ">="
39
+ - !ruby/object:Gem::Version
40
+ segments:
41
+ - 0
42
+ version: "0"
43
+ type: :runtime
44
+ prerelease: false
45
+ version_requirements: *id002
46
+ - !ruby/object:Gem::Dependency
47
+ name: rest-client
48
+ requirement: &id003 !ruby/object:Gem::Requirement
49
+ none: false
50
+ requirements:
51
+ - - ">="
52
+ - !ruby/object:Gem::Version
53
+ segments:
54
+ - 0
55
+ version: "0"
56
+ type: :runtime
57
+ prerelease: false
58
+ version_requirements: *id003
59
+ - !ruby/object:Gem::Dependency
60
+ name: json
61
+ requirement: &id004 !ruby/object:Gem::Requirement
62
+ none: false
63
+ requirements:
64
+ - - ">="
65
+ - !ruby/object:Gem::Version
66
+ segments:
67
+ - 0
68
+ version: "0"
69
+ type: :runtime
70
+ prerelease: false
71
+ version_requirements: *id004
72
+ description:
73
+ email: guillaume.godetbar@gmail.com
74
+ executables:
75
+ - addax
76
+ extensions: []
77
+
78
+ extra_rdoc_files: []
79
+
80
+ files:
81
+ - Rakefile
82
+ - VERSION
83
+ - bin/addax
84
+ - lib/addax.rb
85
+ - lib/addax/commands.rb
86
+ has_rdoc: true
87
+ homepage: http://tima-sls.imag.fr/addax
88
+ licenses: []
89
+
90
+ post_install_message:
91
+ rdoc_options: []
92
+
93
+ require_paths:
94
+ - lib
95
+ required_ruby_version: !ruby/object:Gem::Requirement
96
+ none: false
97
+ requirements:
98
+ - - ">="
99
+ - !ruby/object:Gem::Version
100
+ segments:
101
+ - 0
102
+ version: "0"
103
+ required_rubygems_version: !ruby/object:Gem::Requirement
104
+ none: false
105
+ requirements:
106
+ - - ">="
107
+ - !ruby/object:Gem::Version
108
+ segments:
109
+ - 0
110
+ version: "0"
111
+ requirements: []
112
+
113
+ rubyforge_project:
114
+ rubygems_version: 1.3.7
115
+ signing_key:
116
+ specification_version: 3
117
+ summary: Command-line tool for accessing TIMA-SLS's ADDAX webservice.
118
+ test_files: []
119
+