npolar-api-client-ruby 0.2.0

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,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: []