lib/crowdin-api/client/client.rb in crowdin-api-1.3.0 vs lib/crowdin-api/client/client.rb in crowdin-api-1.4.0

- old
+ new

@@ -28,10 +28,12 @@ # Processing Error Raisers modules to include them to the Client ERROR_RAISERS_MODULES.each do |module_name| Client.send(:include, Object.const_get("Crowdin::Errors::#{module_name}")) end + include Web::FetchAllExtensions + # Config instance that includes configuration options for the Client attr_reader :config # Instance with established connection through RestClient to the Crowdin API attr_reader :connection # Instance with options and headers for RestClient connection @@ -65,10 +67,93 @@ def logger_enabled? config.logger_enabled? end + # + # FetchAll options: + # * limit, Integer, default: 500 | How many records need to load per one request + # * offset, Integer, default: 0 | How many records need to skip + # * request_delay, Integer (seconds), default: 0 | Delay between requests + # + # + # Note: Please, specify project_id while Client initialization if you need to use methods that need it within FetchAll + # + # === Example + # + # @crowdin.fetch_all(:list_projects) + # + # with specified options + # + # @crowdin.fetch_all(:list_projects, { limit: 10, request_delay: 1 }) + # + # playing with response per fetch. Note: the block actually don't make any effect to finite result + # + # @crowdin.fetch_all(:list_projects, { limit: 10, request_delay: 1 }) { |response| puts response['data'] } + # + # also you can specify retry configuration to handle some exceptions + # + # Retry configuration options: + # * request_delay, Integer (seconds), default: 0 | Delay between retries + # * retries_count, Integer, default: 0 + # * error_messages, Array + # + # @crowdin.fetch_all(:list_projects, {}, { request_delay: 2, retries_count: 3, error_messages: ['401'] }) + # + # fetch all execution will be terminated if response error are same as in error_messages array + # otherwise system will retry so many times, as indicated at tries_count + # + def fetch_all(api_resource, opts = {}, retry_opts = {}) + unless Web::FetchAllExtensions::API_RESOURCES_FOR_FETCH_ALL.include?(api_resource) + raise(Errors::FetchAllProcessingError, "#{api_resource} method aren't supported for FetchAll") + end + + limit = opts[:limit] || Web::FetchAllExtensions::MAX_ITEMS_COUNT_PER_REQUEST + offset = opts[:offset] || 0 + request_delay = opts[:request_delay] || 0 + + retry_request_delay = retry_opts[:request_delay] || 0 + retries_count = retry_opts[:retries_count] || 0 + retry_error_messages = retry_opts[:error_messages] || [] + + result = [] + loop do + response = case api_resource + when :list_terms + send(api_resource, opts[:glossary_id], { limit: limit, offset: offset }.merge(opts)) + when :list_file_revisions + send(api_resource, opts[:file_id], { limit: limit, offset: offset }.merge(opts)) + else + send(api_resource, { limit: limit, offset: offset }.merge(opts)) + end + + if response.is_a?(String) && response.match('Something went wrong') + if retries_count.positive? + retry_error_messages.each do |message| + break if response.match(message) + end + + retries_count -= 1 + sleep retry_request_delay + else + raise(Errors::FetchAllProcessingError, response) + end + else + yield response if block_given? + deserialized_response = response['data'] + result.concat(deserialized_response) + offset += deserialized_response.size + break if deserialized_response.size < limit + end + + sleep request_delay + end + result + rescue StandardError => e + raise(Errors::FetchAllProcessingError, "FetchAll wasn't processed. Details - #{e.message}") + end + private def build_configuration @config = Crowdin::Configuration.new yield config if block_given? @@ -83,9 +168,10 @@ @options ||= config.options.merge(headers: config.headers) end def set_default_logger require 'logger' + @logger ||= Logger.new($stdout) update_rest_client_logger end def update_rest_client_logger