gopad 1.0.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,429 @@
1
+ # Gopad OpenAPI
2
+ #
3
+ # API definition for Gopad, Etherpad for markdown with go
4
+ #
5
+ # The version of the OpenAPI document: 1.0.0-alpha1
6
+ # Contact: gopad@webhippie.de
7
+ # Generated by: https://openapi-generator.tech
8
+ # Generator version: 7.6.0
9
+ #
10
+
11
+ require 'date'
12
+ require 'json'
13
+ require 'logger'
14
+ require 'tempfile'
15
+ require 'time'
16
+ require 'faraday'
17
+ require 'faraday/multipart' if Gem::Version.new(Faraday::VERSION) >= Gem::Version.new('2.0')
18
+ require 'marcel'
19
+
20
+ module Gopad
21
+ class ApiClient
22
+ # The Configuration object holding settings to be used in the API client.
23
+ attr_accessor :config
24
+
25
+ # Defines the headers to be used in HTTP requests of all API calls by default.
26
+ #
27
+ # @return [Hash]
28
+ attr_accessor :default_headers
29
+
30
+ # Initializes the ApiClient
31
+ # @option config [Configuration] Configuration for initializing the object, default to Configuration.default
32
+ def initialize(config = Configuration.default)
33
+ @config = config
34
+ @user_agent = 'gopad-ruby/1.0.0-alpha1'
35
+ @default_headers = {
36
+ 'Content-Type' => 'application/json',
37
+ 'User-Agent' => @user_agent
38
+ }
39
+ end
40
+
41
+ def self.default
42
+ @@default ||= ApiClient.new
43
+ end
44
+
45
+ # Call an API with given options.
46
+ #
47
+ # @return [Array<(Object, Integer, Hash)>] an array of 3 elements:
48
+ # the data deserialized from response body (could be nil), response status code and response headers.
49
+ def call_api(http_method, path, opts = {})
50
+ stream = nil
51
+ begin
52
+ response = connection(opts).public_send(http_method.to_sym.downcase) do |req|
53
+ request = build_request(http_method, path, req, opts)
54
+ stream = download_file(request) if opts[:return_type] == 'File' || opts[:return_type] == 'Binary'
55
+ end
56
+
57
+ if config.debugging
58
+ config.logger.debug "HTTP response body ~BEGIN~\n#{response.body}\n~END~\n"
59
+ end
60
+
61
+ unless response.success?
62
+ if response.status.zero? && response.respond_to?(:return_message)
63
+ # Errors from libcurl will be made visible here
64
+ raise ApiError.new(code: 0,
65
+ message: response.return_message)
66
+ else
67
+ raise ApiError.new(code: response.status,
68
+ response_headers: response.headers,
69
+ response_body: response.body),
70
+ response.reason_phrase
71
+ end
72
+ end
73
+ rescue Faraday::TimeoutError
74
+ raise ApiError.new('Connection timed out')
75
+ rescue Faraday::ConnectionFailed
76
+ raise ApiError.new('Connection failed')
77
+ end
78
+
79
+ data = if opts[:return_type] == 'File' || opts[:return_type] == 'Binary'
80
+ deserialize_file(response, stream)
81
+ elsif opts[:return_type]
82
+ deserialize(response, opts[:return_type])
83
+ end
84
+ [data, response.status, response.headers]
85
+ end
86
+
87
+ # Builds the HTTP request
88
+ #
89
+ # @param [String] http_method HTTP method/verb (e.g. POST)
90
+ # @param [String] path URL path (e.g. /account/new)
91
+ # @option opts [Hash] :header_params Header parameters
92
+ # @option opts [Hash] :query_params Query parameters
93
+ # @option opts [Hash] :form_params Query parameters
94
+ # @option opts [Object] :body HTTP body (JSON/XML)
95
+ # @return [Faraday::Request] A Faraday Request
96
+ def build_request(http_method, path, request, opts = {})
97
+ url = build_request_url(path, opts)
98
+ http_method = http_method.to_sym.downcase
99
+
100
+ header_params = @default_headers.merge(opts[:header_params] || {})
101
+ query_params = opts[:query_params] || {}
102
+ form_params = opts[:form_params] || {}
103
+
104
+ update_params_for_auth! header_params, query_params, opts[:auth_names]
105
+
106
+ if %i[post patch put delete].include?(http_method)
107
+ req_body = build_request_body(header_params, form_params, opts[:body])
108
+ if config.debugging
109
+ config.logger.debug "HTTP request body param ~BEGIN~\n#{req_body}\n~END~\n"
110
+ end
111
+ end
112
+ request.headers = header_params
113
+ request.body = req_body
114
+
115
+ # Overload default options only if provided
116
+ request.options.params_encoder = config.params_encoder if config.params_encoder
117
+ request.options.timeout = config.timeout if config.timeout
118
+
119
+ request.url url
120
+ request.params = query_params
121
+ request
122
+ end
123
+
124
+ # Builds the HTTP request body
125
+ #
126
+ # @param [Hash] header_params Header parameters
127
+ # @param [Hash] form_params Query parameters
128
+ # @param [Object] body HTTP body (JSON/XML)
129
+ # @return [String] HTTP body data in the form of string
130
+ def build_request_body(header_params, form_params, body)
131
+ # http form
132
+ if header_params['Content-Type'] == 'application/x-www-form-urlencoded'
133
+ data = URI.encode_www_form(form_params)
134
+ elsif header_params['Content-Type'] == 'multipart/form-data'
135
+ data = {}
136
+ form_params.each do |key, value|
137
+ data[key] = case value
138
+ when ::File, ::Tempfile
139
+ Faraday::FilePart.new(value.path, Marcel::MimeType.for(Pathname.new(value.path)))
140
+ when ::Array, nil
141
+ # let Faraday handle Array and nil parameters
142
+ value
143
+ else
144
+ value.to_s
145
+ end
146
+ end
147
+ elsif body
148
+ data = body.is_a?(String) ? body : body.to_json
149
+ else
150
+ data = nil
151
+ end
152
+ data
153
+ end
154
+
155
+ def download_file(request)
156
+ stream = []
157
+
158
+ # handle streaming Responses
159
+ request.options.on_data = proc do |chunk, _overall_received_bytes|
160
+ stream << chunk
161
+ end
162
+ stream
163
+ end
164
+
165
+ def deserialize_file(response, stream)
166
+ body = response.body
167
+ if @config.return_binary_data == true
168
+ # return byte stream
169
+ encoding = body.encoding
170
+ stream.join.force_encoding(encoding)
171
+ else
172
+ # return file instead of binary data
173
+ content_disposition = response.headers['Content-Disposition']
174
+ if content_disposition && content_disposition =~ /filename=/i
175
+ filename = content_disposition[/filename=['"]?([^'"\s]+)['"]?/, 1]
176
+ prefix = sanitize_filename(filename)
177
+ else
178
+ prefix = 'download-'
179
+ end
180
+ prefix += '-' unless prefix.end_with?('-')
181
+ encoding = body.encoding
182
+ tempfile = Tempfile.open(prefix, @config.temp_folder_path, encoding: encoding)
183
+ tempfile.write(stream.join.force_encoding(encoding))
184
+ tempfile.close
185
+ config.logger.info "Temp file written to #{tempfile.path}, please copy the file to a proper folder " \
186
+ "with e.g. `FileUtils.cp(tempfile.path, '/new/file/path')` otherwise the temp file " \
187
+ "will be deleted automatically with GC. It's also recommended to delete the temp file " \
188
+ 'explicitly with `tempfile.delete`'
189
+ tempfile
190
+ end
191
+ end
192
+
193
+ def connection(opts)
194
+ opts[:header_params]['Content-Type'] == 'multipart/form-data' ? connection_multipart : connection_regular
195
+ end
196
+
197
+ def connection_multipart
198
+ @connection_multipart ||= build_connection do |conn|
199
+ conn.request :multipart
200
+ conn.request :url_encoded
201
+ end
202
+ end
203
+
204
+ def connection_regular
205
+ @connection_regular ||= build_connection
206
+ end
207
+
208
+ def build_connection
209
+ Faraday.new(url: config.base_url, ssl: ssl_options, proxy: config.proxy) do |conn|
210
+ basic_auth(conn)
211
+ config.configure_middleware(conn)
212
+ yield(conn) if block_given?
213
+ conn.adapter(Faraday.default_adapter)
214
+ config.configure_connection(conn)
215
+ end
216
+ end
217
+
218
+ def ssl_options
219
+ {
220
+ ca_file: config.ssl_ca_file,
221
+ verify: config.ssl_verify,
222
+ verify_mode: config.ssl_verify_mode,
223
+ client_cert: config.ssl_client_cert,
224
+ client_key: config.ssl_client_key
225
+ }
226
+ end
227
+
228
+ def basic_auth(conn)
229
+ if config.username && config.password
230
+ if Gem::Version.new(Faraday::VERSION) >= Gem::Version.new('2.0')
231
+ conn.request(:authorization, :basic, config.username, config.password)
232
+ else
233
+ conn.request(:basic_auth, config.username, config.password)
234
+ end
235
+ end
236
+ end
237
+
238
+ # Check if the given MIME is a JSON MIME.
239
+ # JSON MIME examples:
240
+ # application/json
241
+ # application/json; charset=UTF8
242
+ # APPLICATION/JSON
243
+ # */*
244
+ # @param [String] mime MIME
245
+ # @return [Boolean] True if the MIME is application/json
246
+ def json_mime?(mime)
247
+ (mime == '*/*') || !(mime =~ %r{^Application/.*json(?!p)(;.*)?}i).nil?
248
+ end
249
+
250
+ # Deserialize the response to the given return type.
251
+ #
252
+ # @param [Response] response HTTP response
253
+ # @param [String] return_type some examples: "User", "Array<User>", "Hash<String, Integer>"
254
+ def deserialize(response, return_type)
255
+ body = response.body
256
+ return nil if body.nil? || body.empty?
257
+
258
+ # return response body directly for String return type
259
+ return body.to_s if return_type == 'String'
260
+
261
+ # ensuring a default content type
262
+ content_type = response.headers['Content-Type'] || 'application/json'
263
+
264
+ raise "Content-Type is not supported: #{content_type}" unless json_mime?(content_type)
265
+
266
+ begin
267
+ data = JSON.parse("[#{body}]", symbolize_names: true)[0]
268
+ rescue JSON::ParserError => e
269
+ if %w[String Date Time].include?(return_type)
270
+ data = body
271
+ else
272
+ raise e
273
+ end
274
+ end
275
+
276
+ convert_to_type data, return_type
277
+ end
278
+
279
+ # Convert data to the given return type.
280
+ # @param [Object] data Data to be converted
281
+ # @param [String] return_type Return type
282
+ # @return [Mixed] Data in a particular type
283
+ def convert_to_type(data, return_type)
284
+ return nil if data.nil?
285
+
286
+ case return_type
287
+ when 'String'
288
+ data.to_s
289
+ when 'Integer'
290
+ data.to_i
291
+ when 'Float'
292
+ data.to_f
293
+ when 'Boolean'
294
+ data == true
295
+ when 'Time'
296
+ # parse date time (expecting ISO 8601 format)
297
+ Time.parse data
298
+ when 'Date'
299
+ # parse date time (expecting ISO 8601 format)
300
+ Date.parse data
301
+ when 'Object'
302
+ # generic object (usually a Hash), return directly
303
+ data
304
+ when /\AArray<(.+)>\z/
305
+ # e.g. Array<Pet>
306
+ sub_type = ::Regexp.last_match(1)
307
+ data.map { |item| convert_to_type(item, sub_type) }
308
+ when /\AHash<String, (.+)>\z/
309
+ # e.g. Hash<String, Integer>
310
+ sub_type = ::Regexp.last_match(1)
311
+ {}.tap do |hash|
312
+ data.each { |k, v| hash[k] = convert_to_type(v, sub_type) }
313
+ end
314
+ else
315
+ # models (e.g. Pet) or oneOf
316
+ klass = Gopad.const_get(return_type)
317
+ klass.respond_to?(:openapi_one_of) ? klass.build(data) : klass.build_from_hash(data)
318
+ end
319
+ end
320
+
321
+ # Sanitize filename by removing path.
322
+ # e.g. ../../sun.gif becomes sun.gif
323
+ #
324
+ # @param [String] filename the filename to be sanitized
325
+ # @return [String] the sanitized filename
326
+ def sanitize_filename(filename)
327
+ filename.split(%r{[/\\]}).last
328
+ end
329
+
330
+ def build_request_url(path, opts = {})
331
+ # Add leading and trailing slashes to path
332
+ path = "/#{path}".gsub(%r{/+}, '/')
333
+ @config.base_url(opts[:operation]) + path
334
+ end
335
+
336
+ # Update header and query params based on authentication settings.
337
+ #
338
+ # @param [Hash] header_params Header parameters
339
+ # @param [Hash] query_params Query parameters
340
+ # @param [String] auth_names Authentication scheme name
341
+ def update_params_for_auth!(header_params, query_params, auth_names)
342
+ Array(auth_names).each do |auth_name|
343
+ auth_setting = @config.auth_settings[auth_name]
344
+ next unless auth_setting
345
+
346
+ case auth_setting[:in]
347
+ when 'header' then header_params[auth_setting[:key]] = auth_setting[:value]
348
+ when 'query' then query_params[auth_setting[:key]] = auth_setting[:value]
349
+ else raise ArgumentError, 'Authentication token must be in `query` or `header`'
350
+ end
351
+ end
352
+ end
353
+
354
+ # Sets user agent in HTTP header
355
+ #
356
+ # @param [String] user_agent User agent (e.g. openapi-generator/ruby/1.0.0)
357
+ def user_agent=(user_agent)
358
+ @user_agent = user_agent
359
+ @default_headers['User-Agent'] = @user_agent
360
+ end
361
+
362
+ # Return Accept header based on an array of accepts provided.
363
+ # @param [Array] accepts array for Accept
364
+ # @return [String] the Accept header (e.g. application/json)
365
+ def select_header_accept(accepts)
366
+ return nil if accepts.nil? || accepts.empty?
367
+
368
+ # use JSON when present, otherwise use all of the provided
369
+ json_accept = accepts.find { |s| json_mime?(s) }
370
+ json_accept || accepts.join(',')
371
+ end
372
+
373
+ # Return Content-Type header based on an array of content types provided.
374
+ # @param [Array] content_types array for Content-Type
375
+ # @return [String] the Content-Type header (e.g. application/json)
376
+ def select_header_content_type(content_types)
377
+ # return nil by default
378
+ return if content_types.nil? || content_types.empty?
379
+
380
+ # use JSON when present, otherwise use the first one
381
+ json_content_type = content_types.find { |s| json_mime?(s) }
382
+ json_content_type || content_types.first
383
+ end
384
+
385
+ # Convert object (array, hash, object, etc) to JSON string.
386
+ # @param [Object] model object to be converted into JSON string
387
+ # @return [String] JSON string representation of the object
388
+ def object_to_http_body(model)
389
+ return model if model.nil? || model.is_a?(String)
390
+
391
+ if model.is_a?(Array)
392
+ model.map { |m| object_to_hash(m) }
393
+ else
394
+ object_to_hash(model)
395
+ end.to_json
396
+ end
397
+
398
+ # Convert object(non-array) to hash.
399
+ # @param [Object] obj object to be converted into JSON string
400
+ # @return [String] JSON string representation of the object
401
+ def object_to_hash(obj)
402
+ if obj.respond_to?(:to_hash)
403
+ obj.to_hash
404
+ else
405
+ obj
406
+ end
407
+ end
408
+
409
+ # Build parameter value according to the given collection format.
410
+ # @param [String] collection_format one of :csv, :ssv, :tsv, :pipes and :multi
411
+ def build_collection_param(param, collection_format)
412
+ case collection_format
413
+ when :csv
414
+ param.join(',')
415
+ when :ssv
416
+ param.join(' ')
417
+ when :tsv
418
+ param.join("\t")
419
+ when :pipes
420
+ param.join('|')
421
+ when :multi
422
+ # return the array directly as typhoeus will handle it as expected
423
+ param
424
+ else
425
+ raise "unknown collection format: #{collection_format.inspect}"
426
+ end
427
+ end
428
+ end
429
+ end
@@ -0,0 +1,56 @@
1
+ # Gopad OpenAPI
2
+ #
3
+ # API definition for Gopad, Etherpad for markdown with go
4
+ #
5
+ # The version of the OpenAPI document: 1.0.0-alpha1
6
+ # Contact: gopad@webhippie.de
7
+ # Generated by: https://openapi-generator.tech
8
+ # Generator version: 7.6.0
9
+ #
10
+
11
+ module Gopad
12
+ class ApiError < StandardError
13
+ attr_reader :code, :response_headers, :response_body
14
+
15
+ # Usage examples:
16
+ # ApiError.new
17
+ # ApiError.new("message")
18
+ # ApiError.new(:code => 500, :response_headers => {}, :response_body => "")
19
+ # ApiError.new(:code => 404, :message => "Not Found")
20
+ def initialize(arg = nil)
21
+ if arg.is_a? Hash
22
+ if arg.key?(:message) || arg.key?('message')
23
+ super(arg[:message] || arg['message'])
24
+ else
25
+ super
26
+ end
27
+
28
+ arg.each do |k, v|
29
+ instance_variable_set "@#{k}", v
30
+ end
31
+ else
32
+ super
33
+ @message = arg
34
+ end
35
+ end
36
+
37
+ # Override to_s to display a friendly error message
38
+ def to_s
39
+ message
40
+ end
41
+
42
+ def message
43
+ msg = if @message.nil?
44
+ 'Error message: the server returns an error'
45
+ else
46
+ @message
47
+ end
48
+
49
+ msg += "\nHTTP status code: #{code}" if code
50
+ msg += "\nResponse headers: #{response_headers}" if response_headers
51
+ msg += "\nResponse body: #{response_body}" if response_body
52
+
53
+ msg
54
+ end
55
+ end
56
+ end