class Storyblok::Client

Constants

DEFAULT_CONFIGURATION

Attributes

cache_version[RW]
configuration[R]
logger[R]

Public Class Methods

new(given_configuration = {}) click to toggle source

@param [Hash] given_configuration @option given_configuration [String] :token Required if oauth_token is not set @option given_configuration [String] :oauth_token Required if token is not set @option given_configuration [String] :api_url @option given_configuration [Proc] :component_resolver @option given_configuration [Number] :api_version @option given_configuration [false, ::Logger] :logger @option given_configuration [::Logger::DEBUG, ::Logger::INFO, ::Logger::WARN, ::Logger::ERROR] :log_level

# File lib/storyblok/client.rb, line 34
def initialize(given_configuration = {})
  @configuration = default_configuration.merge(given_configuration)
  @cache_version = '0'
  validate_configuration!

  if configuration[:oauth_token]
    @rest_client = RestClient::Resource.new(base_url, :headers => {
      :authorization => configuration[:oauth_token]
    })
  end

  @renderer = Richtext::HtmlRenderer.new
  @renderer.set_component_resolver(@configuration[:component_resolver])
  setup_logger
end

Public Instance Methods

cached_get(request, bypass_cache = false) click to toggle source
# File lib/storyblok/client.rb, line 173
def cached_get(request, bypass_cache = false)
  endpoint = base_url + request.url
  query = request_query(request.query)
  query_string = build_nested_query(query)

  if cache.nil? || bypass_cache || query[:version] == 'draft'
    result = run_request(endpoint, query_string)
  else
    cache_key = 'storyblok:' + configuration[:token] + ':v:' + query[:cv] + ':' + request.url + ':' + Base64.encode64(query_string)

    result = cache.cache(cache_key) do
      run_request(endpoint, query_string)
    end
  end

  JSON.parse(result)
end
datasource_entries(query = {}) click to toggle source

Gets a collection of datasource entries

@param [Hash] query

@return [Hash]

# File lib/storyblok/client.rb, line 93
def datasource_entries(query = {})
  Request.new(self, '/cdn/datasource_entries', query).get
end
datasources(query = {}) click to toggle source

Gets a collection of datasources

@param [Hash] query

@return [Hash]

# File lib/storyblok/client.rb, line 102
def datasources(query = {})
  Request.new(self, '/cdn/datasources', query).get
end
delete(path, additional_headers = {}) click to toggle source
# File lib/storyblok/client.rb, line 141
def delete(path, additional_headers = {})
  run_management_request(:delete, path, nil, additional_headers)
end
flush() click to toggle source
# File lib/storyblok/client.rb, line 191
def flush
  unless cache.nil?
    cache.set('storyblok:' + configuration[:token] + ':version', space['data']['space']['version'])
  end
end
get(path, additional_headers = {}) click to toggle source
# File lib/storyblok/client.rb, line 145
def get(path, additional_headers = {})
  run_management_request(:get, path, nil, additional_headers)
end
get_from_cdn(slug, query = {}, id = nil) click to toggle source

Dynamic cdn endpoint call

@param [String] id @param [Hash] query

@return [Hash]

# File lib/storyblok/client.rb, line 56
def get_from_cdn(slug, query = {}, id = nil)
  Request.new(self, "/cdn/#{slug}", query, id).get
end
post(path, payload, additional_headers = {}) click to toggle source
# File lib/storyblok/client.rb, line 133
def post(path, payload, additional_headers = {})
  run_management_request(:post, path, payload, additional_headers)
end
put(path, payload, additional_headers = {}) click to toggle source
# File lib/storyblok/client.rb, line 137
def put(path, payload, additional_headers = {})
  run_management_request(:put, path, payload, additional_headers)
end
render(data) click to toggle source

Returns html from richtext field data

@param [Hash] :data

@return [String]

# File lib/storyblok/client.rb, line 202
def render data
  @renderer.render(data)
end
run_management_request(action, path, payload = {}, additional_headers = {}) click to toggle source
# File lib/storyblok/client.rb, line 149
def run_management_request(action, path, payload = {}, additional_headers = {})
  logger.info(request: { path: path, action: action }) if logger
  retries_left = 3

  begin
    if [:post, :put].include?(action)
      res = @rest_client[path].send(action, payload, additional_headers)
    else
      res = @rest_client[path].send(action, additional_headers)
    end
  rescue RestClient::TooManyRequests
    if retries_left != 0
      retries_left -= 1
      logger.info("Too many requests. Retry nr. #{(3 - retries_left).to_s} of max. 3 times.") if logger
      sleep(0.5)
      retry
    end

    raise
  end

  parse_result(res)
end
set_component_resolver(component_resolver) click to toggle source

Sets component resolver

@param [Proc] :component_resolver

@return [nil]

# File lib/storyblok/client.rb, line 211
def set_component_resolver component_resolver
  @renderer.set_component_resolver(component_resolver)
end
space(query = {}) click to toggle source

Gets the space info

@param [Hash] query

@return [Hash]

# File lib/storyblok/client.rb, line 65
def space(query = {})
  Request.new(self, '/cdn/spaces/me', query, nil, true).get
end
stories(query = {}) click to toggle source

Gets a collection of stories

@param [Hash] query

@return [Hash]

# File lib/storyblok/client.rb, line 74
def stories(query = {})
  Request.new(self, '/cdn/stories', query).get
end
story(id, query = {}) click to toggle source

Gets a specific story

@param [String] id @param [Hash] query

@return [Hash]

# File lib/storyblok/client.rb, line 84
def story(id, query = {})
  Request.new(self, '/cdn/stories', query, id).get
end
tags(query = {}) click to toggle source

Gets a collection of tags

@param [Hash] query

@return [Hash]

# File lib/storyblok/client.rb, line 111
def tags(query = {})
  Request.new(self, '/cdn/tags', query).get
end
tree(query = {}) click to toggle source

Gets a link tree

@param [Hash] query

@return [Hash]

# File lib/storyblok/client.rb, line 129
def tree(query = {})
  Links.new(Request.new(self, '/cdn/links', query).get).as_tree
end

Private Instance Methods

base_url() click to toggle source

Returns the base url for all of the client's requests

# File lib/storyblok/client.rb, line 264
def base_url
  "http#{configuration[:secure] ? 's' : ''}://#{configuration[:api_url]}/v#{configuration[:api_version]}"
end
build_nested_query(value, prefix = nil) click to toggle source
# File lib/storyblok/client.rb, line 287
def build_nested_query(value, prefix = nil)
  case value
  when Array
    value.map { |v|
      build_nested_query(v, "#{prefix}[]")
    }.join("&")
  when Hash
    value.map { |k, v|
      build_nested_query(v, prefix ? "#{prefix}[#{URI.encode_www_form_component(k)}]" : URI.encode_www_form_component(k))
    }.reject(&:empty?).join('&')
  when nil
    prefix
  else
    raise ArgumentError, "value must be a Hash" if prefix.nil?
    "#{prefix}=#{URI.encode_www_form_component(value)}"
  end
end
cache() click to toggle source
# File lib/storyblok/client.rb, line 272
def cache
  configuration[:cache]
end
default_configuration() click to toggle source
# File lib/storyblok/client.rb, line 268
def default_configuration
  DEFAULT_CONFIGURATION.dup
end
parse_result(res) click to toggle source
# File lib/storyblok/client.rb, line 217
def parse_result(res)
  {'headers' => res.headers, 'data' => JSON.parse(res.body)}
end
request_query(query) click to toggle source

Patches a query hash with the client configurations for queries

# File lib/storyblok/client.rb, line 250
def request_query(query)
  query[:token] = configuration[:token] if query[:token].nil?
  query[:version] = configuration[:version] if query[:version].nil?

  unless cache.nil?
    query[:cv] = (cache.get('storyblok:' + configuration[:token] + ':version') or cache_version) if query[:cv].nil?
  else
    query[:cv] = cache_version if query[:cv].nil?
  end

  query
end
run_request(endpoint, query_string) click to toggle source
# File lib/storyblok/client.rb, line 221
def run_request(endpoint, query_string)
  logger.info(request: { endpoint: endpoint, query: query_string }) if logger

  retries_left = 3

  begin
    res = RestClient.get "#{endpoint}?#{query_string}"
  rescue RestClient::TooManyRequests
    if retries_left != 0
      retries_left -= 1
      logger.info("Too many requests. Retry nr. #{(3 - retries_left).to_s} of max. 3 times.") if logger
      sleep(0.5)
      retry
    end

    raise
  end

  body = JSON.parse(res.body)
  self.cache_version = body['cv'] if body['cv']

  unless cache.nil?
    cache.set('storyblok:' + configuration[:token] + ':version', cache_version)
  end

  {'headers' => res.headers, 'data' => body}.to_json
end
setup_logger() click to toggle source
# File lib/storyblok/client.rb, line 276
def setup_logger
  @logger = configuration[:logger]
  logger.level = configuration[:log_level] if logger
end
validate_configuration!() click to toggle source
# File lib/storyblok/client.rb, line 281
def validate_configuration!
  fail ArgumentError, 'You will need to initialize a client with an :token or :oauth_token' if !configuration[:token] and !configuration[:oauth_token]
  fail ArgumentError, 'The client configuration needs to contain an :api_url' if configuration[:api_url].empty?
  fail ArgumentError, 'The :api_version must be a positive number' unless configuration[:api_version].to_i >= 0
end