class Apipie::Extractor::Writer

Public Class Methods

compressed() click to toggle source
# File lib/apipie/extractor/writer.rb, line 7
def compressed
  Apipie.configuration.compress_examples
end
examples_file() click to toggle source
# File lib/apipie/extractor/writer.rb, line 33
def examples_file
  pure_path = Rails.root.join(
    Apipie.configuration.doc_path, 'apipie_examples.json'
  )
  zipped_path = pure_path.to_s + '.gz'
  return zipped_path if compressed
  pure_path.to_s
end
load_recorded_examples() click to toggle source
# File lib/apipie/extractor/writer.rb, line 28
def load_recorded_examples
  return {} unless File.exist?(examples_file)
  load_json_examples
end
new(collector) click to toggle source
# File lib/apipie/extractor/writer.rb, line 71
def initialize(collector)
  @collector = collector
end
update_action_description(controller, action) { |updater| ... } click to toggle source
# File lib/apipie/extractor/writer.rb, line 11
def update_action_description(controller, action)
  updater = ActionDescriptionUpdater.new(controller, action)
  yield updater
  updater.write!
rescue ActionDescriptionUpdater::ControllerNotFound
  logger.warn("REST_API: Couldn't find controller file for #{controller}")
rescue ActionDescriptionUpdater::ActionNotFound
  logger.warn("REST_API: Couldn't find action #{action} in #{controller}")
end
write_recorded_examples(examples) click to toggle source
# File lib/apipie/extractor/writer.rb, line 21
def write_recorded_examples(examples)
  FileUtils.mkdir_p(File.dirname(examples_file))
  content = serialize_examples(examples)
  content = Zlib::Deflate.deflate(content).force_encoding('utf-8') if compressed
  File.open(examples_file, 'w') { |f| f << content }
end

Protected Class Methods

deserialize_examples(examples_string) click to toggle source
# File lib/apipie/extractor/writer.rb, line 50
def deserialize_examples(examples_string)
  examples = JSON.parse(examples_string)
  return {} if examples.nil?
  examples.each_value do |records|
    records.each do |record|
      record['verb'] = record['verb'].to_sym if record['verb']
    end
  end
end
load_json_examples() click to toggle source
# File lib/apipie/extractor/writer.rb, line 60
def load_json_examples
  raw = IO.read(examples_file)
  raw = Zlib::Inflate.inflate(raw).force_encoding('utf-8') if compressed
  deserialize_examples(raw)
end
logger() click to toggle source
# File lib/apipie/extractor/writer.rb, line 66
def logger
  Extractor.logger
end
serialize_examples(examples) click to toggle source
# File lib/apipie/extractor/writer.rb, line 44
def serialize_examples(examples)
  JSON.pretty_generate(
    OrderedHash[*examples.sort_by(&:first).flatten(1)]
  )
end

Public Instance Methods

write_docs() click to toggle source
# File lib/apipie/extractor/writer.rb, line 81
def write_docs
  descriptions = @collector.finalize_descriptions
  descriptions.each do |_, desc|
    if desc[:api].empty?
      logger.warn("REST_API: Couldn't find any path for #{desc_to_s(desc)}")
      next
    end
    self.class.update_action_description(desc[:controller], desc[:action]) do |u|
      u.update_generated_description desc
    end
  end
end
write_examples() click to toggle source
# File lib/apipie/extractor/writer.rb, line 76
def write_examples
  merged_examples = merge_old_new_examples
  self.class.write_recorded_examples(merged_examples)
end

Protected Instance Methods

convert_file_value(hash) click to toggle source
# File lib/apipie/extractor/writer.rb, line 117
def convert_file_value hash
  hash.each do |k, v|
    if (v.is_a?(Rack::Test::UploadedFile) || v.is_a?(ActionDispatch::Http::UploadedFile))
      hash[k] = "<FILE CONTENT '#{v.original_filename}'>"
    elsif v.is_a?(Hash)
      hash[k] = convert_file_value(v)
    end
  end
  hash
end
deep_merge_examples(new_examples, old_examples) click to toggle source
# File lib/apipie/extractor/writer.rb, line 151
def deep_merge_examples(new_examples, old_examples)
  new_examples.map do |new_example|
    # Use ordered to get compareble output (mainly for the :query)
    new_example_ordered = ordered_call(new_example.dup)

    # Comparing verb, versions and query
    if old_example = old_examples.find{ |old_example| old_example["verb"] == new_example_ordered["verb"] && old_example["versions"] == new_example_ordered["versions"] && old_example["query"] == new_example_ordered["query"]}

      # Take the 'show in doc' attribute from the old example if it is present and the configuration requests the value to be persisted.
      new_example[:show_in_doc] = old_example["show_in_doc"] if Apipie.configuration.persist_show_in_doc && old_example["show_in_doc"].to_i > 0

      # Always take the title from the old example if it exists.
      new_example[:title] ||= old_example["title"] if old_example["title"].present?
    end
    new_example
  end
end
desc_to_s(description) click to toggle source
# File lib/apipie/extractor/writer.rb, line 98
def desc_to_s(description)
  "#{description[:controller].name}##{description[:action]}"
end
hash_nodes_count(node) click to toggle source
# File lib/apipie/extractor/writer.rb, line 216
def hash_nodes_count(node)
  case node
  when Hash
    1 + (node.values.map { |v| hash_nodes_count(v) }.reduce(:+) || 0)
  when Array
    node.map { |v| hash_nodes_count(v) }.reduce(:+) || 1
  else
    1
  end
end
load_new_examples() click to toggle source
# File lib/apipie/extractor/writer.rb, line 169
def load_new_examples
  @collector.records.reduce({}) do |h, (method, calls)|
    showed_in_versions = Set.new
    # we have already shown some example
    recorded_examples = calls.map do |call|
      method_descriptions = Apipie.get_method_descriptions(call[:controller], call[:action])
      call[:versions] = method_descriptions.map(&:version)

      if Apipie.configuration.show_all_examples
        show_in_doc = 1
      elsif call[:versions].any? { |v| ! showed_in_versions.include?(v) }
        call[:versions].each { |v| showed_in_versions << v }
        show_in_doc = 1
      else
        show_in_doc = 0
      end
      example = call.merge(:show_in_doc => show_in_doc.to_i, :recorded => true)
      example
    end
    h.update(method => recorded_examples)
  end
end
load_old_examples() click to toggle source
# File lib/apipie/extractor/writer.rb, line 192
def load_old_examples
  if File.exist?(@examples_file)
    if defined? SafeYAML
      return YAML.load_file(@examples_file, :safe=>false)
    else
      return YAML.load_file(@examples_file)
    end
  end
  return {}
end
load_recorded_examples() click to toggle source
# File lib/apipie/extractor/writer.rb, line 128
def load_recorded_examples
  self.class.load_recorded_examples
end
logger() click to toggle source
# File lib/apipie/extractor/writer.rb, line 203
def logger
  self.class.logger
end
merge_old_new_examples() click to toggle source
# File lib/apipie/extractor/writer.rb, line 132
def merge_old_new_examples
  new_examples = self.load_new_examples
  old_examples = self.load_recorded_examples
  merged_examples = []
  (new_examples.keys + old_examples.keys).uniq.each do |key|
    if new_examples.has_key?(key)
      if old_examples.has_key?(key)
        records = deep_merge_examples(new_examples[key], old_examples[key])
      else
        records = new_examples[key]
      end
    else
      records = old_examples[key]
    end
    merged_examples << [key, records.map { |r| ordered_call(r) } ]
  end
  return merged_examples
end
ordered_call(call) click to toggle source
# File lib/apipie/extractor/writer.rb, line 102
def ordered_call(call)
  call = call.stringify_keys
  ordered_call = OrderedHash.new
  %w[title verb path versions query request_data response_data code show_in_doc recorded].each do |k|
    next unless call.has_key?(k)
    ordered_call[k] = case call[k]
               when ActiveSupport::HashWithIndifferentAccess
                 convert_file_value(call[k]).to_hash
               else
                 call[k]
               end
end
  return ordered_call
end
showable_in_doc?(call) click to toggle source
# File lib/apipie/extractor/writer.rb, line 207
def showable_in_doc?(call)
  # we don't want to mess documentation with too large examples
  if hash_nodes_count(call["request_data"]) + hash_nodes_count(call["response_data"]) > 100
    return false
  else
    return 1
  end
end