npolar-api-client-ruby 0.2.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,298 @@
1
+ require "optparse"
2
+
3
+ # @todo Dir[glob] support
4
+ #Dir[glob].select {|f|
5
+ # f is json?
6
+ #}.map {|filename|
7
+ #}
8
+ # #{CMD} -XPUT -iv -XPUT /endpoint/id -d@-
9
+
10
+ module Npolar::Api::Client
11
+
12
+ class NpolarApiCommand
13
+
14
+ # Delegate HTTP methods to Npolar::ApiClient::JsonApiClient
15
+ extend Forwardable # http://www.ruby-doc.org/stdlib-1.9.3/libdoc/forwardable/rdoc/Forwardable.html
16
+ def_delegators :client, :delete, :get, :head, :patch, :post, :put
17
+
18
+ CMD = "npolar-api"
19
+
20
+ PARAM = { method: "GET",
21
+ headers: false,
22
+ header: [],
23
+ level: Logger::WARN,
24
+ join: false,
25
+ uri: JsonApiClient::BASE }
26
+
27
+ attr_accessor :param, :log, :uri, :host, :data, :client
28
+
29
+ def initialize(argv=ARGV, param = PARAM)
30
+ @param = param
31
+
32
+ option_parser = OptionParser.new(argv) do |opts|
33
+
34
+ opts.version = Npolar::Api::Client::VERSION
35
+
36
+ opts.banner = "#{CMD} [options] [#{PARAM[:uri]}]/endpoint
37
+
38
+ #{CMD} /schema
39
+ #{CMD} -XPOST /endpoint --data=/file.json
40
+ #{CMD} -XPOST /endpoint --data='{\"title\":\"Title\"}'
41
+ #{CMD} -XPUT --headers http://admin:password@localhost:5984/testdb
42
+ #{CMD} -XPUT -iv -XPUT /endpoint/id -d@/path/to/id
43
+ cat id-1.json | #{CMD} -XPUT -iv -XPUT /endpoint/id-1 -d@-
44
+ #{CMD} -XDELETE /endpoint/id-1
45
+
46
+ #{CMD} is built on top of Typhoeus/libcurl.
47
+ For more information and source: https://github.com/npolar/npolar-api-ruby-client
48
+
49
+ Options:\n"
50
+
51
+ opts.on("--auth", "Force authorization") do |auth|
52
+ @param[:auth] = true
53
+ end
54
+
55
+ opts.on("--data", "-d=data", "Data (request body) for POST and PUT") do |data|
56
+ if /^([@])?-$/ =~ data
57
+ data = ARGF.read
58
+ else
59
+ if /^[@]/ =~ data
60
+ data = data.gsub(/^[@]/, "")
61
+ end
62
+ if File.exists? data
63
+ data = File.read data
64
+ end
65
+ end
66
+ @data = data
67
+ # Change default method to POST on --data
68
+ if param[:method] == "GET"
69
+ param[:method]="POST"
70
+ end
71
+ end
72
+
73
+ opts.on("--debug", "Debug (alias for --level=debug") do
74
+ @param[:level] = Logger::DEBUG
75
+ end
76
+
77
+ opts.on("--level", "-l=level", "Log level") do |level|
78
+ @param[:level] = self.class.level(level)
79
+ end
80
+
81
+ opts.on("--method", "-X=method", "HTTP method, GET is default") do |method|
82
+ param[:method] = method
83
+ end
84
+
85
+ opts.on("--header", "-H=header", "Add HTTP request header") do |header|
86
+ param[:header] << header
87
+ end
88
+
89
+ opts.on("--ids=ids", "URI that returns identifiers") do |ids|
90
+ @param[:ids] = ids
91
+ end
92
+
93
+ opts.on("--join", "Use --join with --ids to join documents into a JSON array") do |join|
94
+ @param[:join] = true
95
+ end
96
+
97
+ opts.on("--concurrency", "-c=number", "Concurrency (max)") do |c|
98
+ param[:concurrency] = c
99
+ end
100
+
101
+ opts.on("--slice", "-s=number", "Slice size on POST ") do |slice|
102
+ param[:slice] = slice
103
+ end
104
+
105
+ opts.on("--headers", "-i", "Show HTTP response headers") do
106
+ param[:headers] = true
107
+ end
108
+
109
+ opts.on("--verbose", "-v", "Verbose") do
110
+ Typhoeus::Config.verbose = true
111
+ end
112
+
113
+ end
114
+
115
+ option_parser.parse!
116
+
117
+ # URI is first argument
118
+ @uri = ARGV[0]
119
+ if uri.nil?
120
+ puts option_parser.help
121
+ exit(1)
122
+ end
123
+
124
+ @log = Logger.new(STDERR)
125
+ @log.level = param[:level]
126
+ end
127
+
128
+ # Show response headers?
129
+ def headers?
130
+ param[:headers]
131
+ end
132
+
133
+ # Request header Hash
134
+ # Merges default client headers with command line headers (-H or --header)
135
+ def header
136
+ header = client.header
137
+ param[:header].each do |h|
138
+ k, v = h.split(": ")
139
+ header[k] = v
140
+ end
141
+ header
142
+ end
143
+
144
+ # Request path (nil because base URI is already set)
145
+ # @return nil
146
+ def path
147
+ nil
148
+ end
149
+
150
+ def param=(param)
151
+ @param=param
152
+ end
153
+
154
+ # Request parameters (usually nil)
155
+ def parameters
156
+ parameters = {}
157
+ if param.key? :ids
158
+ parameters = parameters.merge({"ids" => param[:ids]})
159
+ end
160
+ parameters
161
+ end
162
+
163
+ # Execute npolar-api command
164
+ # @return [nil]
165
+ def run
166
+
167
+ @client = JsonApiClient.new(uri)
168
+ @client.log = log
169
+ @client.header = header
170
+ @client.param = parameters
171
+ if param[:concurrency]
172
+ @client.concurrency = param[:concurrency].to_i
173
+ end
174
+
175
+ if param[:slice]
176
+ @client.slice = param[:slice].to_i
177
+ end
178
+
179
+ if uri =~ /\w+[:]\w+[@]/
180
+ username, password = URI.parse(uri).userinfo.split(":")
181
+ @client.username = username
182
+ @client.password = password
183
+ end
184
+
185
+ if param[:auth]
186
+ # Force authorization
187
+ @client.authorization = true
188
+ end
189
+
190
+ method = param[:method].upcase
191
+
192
+ response = nil
193
+
194
+ case method
195
+ when "DELETE"
196
+ response = delete(path, parameters, header)
197
+ when "GET"
198
+ response = get(path)
199
+ when "HEAD"
200
+ response = head(path, parameters, header)
201
+ when "PATCH"
202
+ response = patch(path, parameters, header)
203
+ when "POST"
204
+ if data.is_a? Dir
205
+ raise "Not implemented"
206
+ else
207
+ response = post(data, path, parameters, header)
208
+ end
209
+
210
+
211
+
212
+ when "PUT"
213
+ response = put(data, path, parameters, header)
214
+ else
215
+ raise ArgumentError, "Unsupported HTTP method: #{param[:method]}"
216
+ end
217
+
218
+ #Loop dirs?
219
+ if not response.nil? and (response.respond_to? :body or response.is_a? Array)
220
+ if response.is_a? Array
221
+ responses = response
222
+ else
223
+ responses = [response]
224
+ end
225
+
226
+ i = 0
227
+ responses.each do | response |
228
+ i += 1
229
+ log.debug "#{method} #{response.uri.path} [#{i}] Total time: #{response.total_time}"+
230
+ " DNS time: #{response.namelookup_time}"+
231
+ " Connect time: #{response.connect_time}"+
232
+ " Pre-transer time: #{response.pretransfer_time}"
233
+
234
+ if "HEAD" == method or headers?
235
+ puts response.response_headers
236
+ end
237
+ unless param[:join]
238
+ puts response.body
239
+ end
240
+ end
241
+
242
+ statuses = responses.map {|r| r.code }.uniq
243
+ status = statuses.map {|code| { code => responses.select {|r| code == r.code }.size } }.to_json.gsub(/["{}\[\]]/, "")
244
+ real_responses_size = responses.select {|r| r.code >= 100 }.size
245
+
246
+ log.info "Status(es): #{status}, request(s): #{responses.size}, response(s): #{real_responses_size}"
247
+
248
+ else
249
+ raise "Invalid response: #{response}"
250
+ end
251
+
252
+ if param[:join]
253
+ joined = responses.map {|r|
254
+ JSON.parse(r.body)
255
+ }
256
+ puts joined.to_json
257
+ end
258
+
259
+ end
260
+
261
+ def action
262
+ param[:action]
263
+ end
264
+
265
+ def self.run(argv=ARGV)
266
+ begin
267
+ cmd = new(argv)
268
+ cmd.run
269
+ exit(0)
270
+ rescue => e
271
+ puts e
272
+ puts e.backtrace.join("\n")
273
+ exit(1)
274
+ end
275
+ end
276
+
277
+ protected
278
+
279
+ def self.level(level_string, fallback=Logger::INFO)
280
+
281
+ case level_string
282
+ when /debug|0/i
283
+ Logger::DEBUG
284
+ when /info|1/i
285
+ Logger::INFO
286
+ when /warn|2/i
287
+ Logger::WARN
288
+ when /error|3/i
289
+ Logger::ERROR
290
+ when /fatal|4/i
291
+ Logger::FATAL
292
+ else
293
+ fallback
294
+ end
295
+ end
296
+
297
+ end
298
+ end
@@ -0,0 +1,25 @@
1
+ # encoding: utf-8
2
+ # https://github.com/radar/guides/blob/master/gem-development.md
3
+ # require File.expand_path(File.dirname(__FILE__)+"/lib/npolar/api/client")
4
+
5
+ lib = File.expand_path('../lib/', __FILE__)
6
+ $:.unshift lib unless $:.include?(lib)
7
+
8
+ Gem::Specification.new do |s|
9
+ s.name = "npolar-api-client-ruby"
10
+ s.version = "0.2.0" # Not DRY, trouble with include Npolar::Api::Client::VERSION
11
+ s.platform = Gem::Platform::RUBY
12
+ s.authors = ["Conrad Helgeland"]
13
+ s.email = ["data*npolar.no"]
14
+ s.homepage = "http://github.com/npolar/npolar-api-client-ruby"
15
+ s.summary = "Ruby client library and command line tools for https://api.npolar.no"
16
+ s.description = "Official Ruby client for the Norwegian Polar Institute's API."
17
+ s.add_development_dependency "rspec", "~> 2.0"
18
+ s.files = Dir.glob("{lib}/**/*") + %w(README.md)
19
+ s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
20
+ s.require_paths = ["lib"]
21
+ git_files = `git ls-files`.split("\n") rescue ''
22
+ s.files = git_files # + whatever_else
23
+ s.test_files = `git ls-files -- {test,spec}/*`.split("\n")
24
+ s.require_paths = ["lib"]
25
+ end
metadata ADDED
@@ -0,0 +1,67 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: npolar-api-client-ruby
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.2.0
5
+ platform: ruby
6
+ authors:
7
+ - Conrad Helgeland
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2014-01-13 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: rspec
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - ~>
18
+ - !ruby/object:Gem::Version
19
+ version: '2.0'
20
+ type: :development
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - ~>
25
+ - !ruby/object:Gem::Version
26
+ version: '2.0'
27
+ description: Official Ruby client for the Norwegian Polar Institute's API.
28
+ email:
29
+ - data*npolar.no
30
+ executables:
31
+ - npolar-api
32
+ extensions: []
33
+ extra_rdoc_files: []
34
+ files:
35
+ - .gitignore
36
+ - Gemfile
37
+ - LICENSE
38
+ - README.md
39
+ - bin/npolar-api
40
+ - lib/npolar/api/client.rb
41
+ - lib/npolar/api/client/json_api_client.rb
42
+ - lib/npolar/api/client/npolar_api_command.rb
43
+ - npolar-api-client-ruby.gemspec
44
+ homepage: http://github.com/npolar/npolar-api-client-ruby
45
+ licenses: []
46
+ metadata: {}
47
+ post_install_message:
48
+ rdoc_options: []
49
+ require_paths:
50
+ - lib
51
+ required_ruby_version: !ruby/object:Gem::Requirement
52
+ requirements:
53
+ - - ! '>='
54
+ - !ruby/object:Gem::Version
55
+ version: '0'
56
+ required_rubygems_version: !ruby/object:Gem::Requirement
57
+ requirements:
58
+ - - ! '>='
59
+ - !ruby/object:Gem::Version
60
+ version: '0'
61
+ requirements: []
62
+ rubyforge_project:
63
+ rubygems_version: 2.2.1
64
+ signing_key:
65
+ specification_version: 4
66
+ summary: Ruby client library and command line tools for https://api.npolar.no
67
+ test_files: []