lib/ElasticEmail/api_client.rb in ElasticEmail-4.0.23 vs lib/ElasticEmail/api_client.rb in ElasticEmail-4.0.24

- old
+ new

@@ -4,21 +4,22 @@ #This API is based on the REST API architecture, allowing the user to easily manage their data with this resource-based approach. Every API call is established on which specific request type (GET, POST, PUT, DELETE) will be used. The API has a limit of 20 concurrent connections and a hard timeout of 600 seconds per request. To start using this API, you will need your Access Token (available <a target=\"_blank\" href=\"https://app.elasticemail.com/marketing/settings/new/manage-api\">here</a>). Remember to keep it safe. Required access levels are listed in the given request’s description. Downloadable library clients can be found in our Github repository <a target=\"_blank\" href=\"https://github.com/ElasticEmail?tab=repositories&q=%22rest+api%22+in%3Areadme\">here</a> The version of the OpenAPI document: 4.0.0 Contact: support@elasticemail.com Generated by: https://openapi-generator.tech -OpenAPI Generator version: 6.3.0 +Generator version: 7.7.0 =end require 'date' require 'json' require 'logger' require 'tempfile' require 'time' require 'typhoeus' + module ElasticEmail class ApiClient # The Configuration object holding settings to be used in the API client. attr_accessor :config @@ -43,13 +44,14 @@ end # Call an API with given options. # # @return [Array<(Object, Integer, Hash)>] an array of 3 elements: - # the data deserialized from response body (could be nil), response status code and response headers. + # the data deserialized from response body (may be a Tempfile or nil), response status code and response headers. def call_api(http_method, path, opts = {}) request = build_request(http_method, path, opts) + tempfile = download_file(request) if opts[:return_type] == 'File' response = request.run if @config.debugging @config.logger.debug "HTTP response body ~BEGIN~\n#{response.body}\n~END~\n" end @@ -67,11 +69,13 @@ :response_body => response.body), response.status_message end end - if opts[:return_type] + if opts[:return_type] == 'File' + data = tempfile + elsif opts[:return_type] data = deserialize(response, opts[:return_type]) else data = nil end return data, response.code, response.headers @@ -123,13 +127,11 @@ if @config.debugging @config.logger.debug "HTTP request body param ~BEGIN~\n#{req_body}\n~END~\n" end end - request = Typhoeus::Request.new(url, req_opts) - download_file(request) if opts[:return_type] == 'File' - request + Typhoeus::Request.new(url, req_opts) end # Builds the HTTP request body # # @param [Hash] header_params Header parameters @@ -163,10 +165,12 @@ # The response body is written to the file in chunks in order to handle files which # size is larger than maximum Ruby String or even larger than the maximum memory a Ruby # process can use. # # @see Configuration#temp_folder_path + # + # @return [Tempfile] the tempfile generated def download_file(request) tempfile = nil encoding = nil request.on_headers do |response| content_disposition = response.headers['Content-Disposition'] @@ -177,25 +181,28 @@ prefix = 'download-' end prefix = prefix + '-' unless prefix.end_with?('-') encoding = response.body.encoding tempfile = Tempfile.open(prefix, @config.temp_folder_path, encoding: encoding) - @tempfile = tempfile end request.on_body do |chunk| chunk.force_encoding(encoding) tempfile.write(chunk) end - request.on_complete do |response| - if tempfile - tempfile.close - @config.logger.info "Temp file written to #{tempfile.path}, please copy the file to a proper folder "\ - "with e.g. `FileUtils.cp(tempfile.path, '/new/file/path')` otherwise the temp file "\ - "will be deleted automatically with GC. It's also recommended to delete the temp file "\ - "explicitly with `tempfile.delete`" - end + # run the request to ensure the tempfile is created successfully before returning it + request.run + if tempfile + tempfile.close + @config.logger.info "Temp file written to #{tempfile.path}, please copy the file to a proper folder "\ + "with e.g. `FileUtils.cp(tempfile.path, '/new/file/path')` otherwise the temp file "\ + "will be deleted automatically with GC. It's also recommended to delete the temp file "\ + "explicitly with `tempfile.delete`" + else + fail ApiError.new("Failed to create the tempfile based on the HTTP response from the server: #{request.inspect}") end + + tempfile end # Check if the given MIME is a JSON MIME. # JSON MIME examples: # application/json @@ -203,28 +210,23 @@ # APPLICATION/JSON # */* # @param [String] mime MIME # @return [Boolean] True if the MIME is application/json def json_mime?(mime) - (mime == '*/*') || !(mime =~ /Application\/.*json(?!p)(;.*)?/i).nil? + (mime == '*/*') || !(mime =~ /^Application\/.*json(?!p)(;.*)?/i).nil? end # Deserialize the response to the given return type. # # @param [Response] response HTTP response # @param [String] return_type some examples: "User", "Array<User>", "Hash<String, Integer>" def deserialize(response, return_type) body = response.body - - # handle file downloading - return the File instance processed in request callbacks - # note that response body is empty when the file is written in chunks in request on_body callback - return @tempfile if return_type == 'File' - return nil if body.nil? || body.empty? # return response body directly for String return type - return body if return_type == 'String' + return body.to_s if return_type == 'String' # ensuring a default content type content_type = response.headers['Content-Type'] || 'application/json' fail "Content-Type is not supported: #{content_type}" unless json_mime?(content_type) @@ -287,10 +289,10 @@ # e.g. ../../sun.gif becomes sun.gif # # @param [String] filename the filename to be sanitized # @return [String] the sanitized filename def sanitize_filename(filename) - filename.gsub(/.*[\/\\]/, '') + filename.split(/[\/\\]/).last end def build_request_url(path, opts = {}) # Add leading and trailing slashes to path path = "/#{path}".gsub(/\/+/, '/')