class Apipie::Extractor::Writer

Public Class Methods

examples_file() click to toggle source
# File lib/apipie/extractor/writer.rb, line 55
def self.examples_file
  File.join(Rails.root,Apipie.configuration.doc_path,"apipie_examples.json")
end
load_recorded_examples() click to toggle source
# File lib/apipie/extractor/writer.rb, line 47
def self.load_recorded_examples
  examples_file = self.examples_file
  if File.exists?(examples_file)
    return load_json_examples
  end
  return {}
end
new(collector) click to toggle source
# File lib/apipie/extractor/writer.rb, line 7
def initialize(collector)
  @collector = collector
end
update_action_description(controller, action) { |updater| ... } click to toggle source
# File lib/apipie/extractor/writer.rb, line 29
def self.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 39
def self.write_recorded_examples(examples)
  examples_file = self.examples_file
  FileUtils.mkdir_p(File.dirname(examples_file))
  File.open(examples_file, "w") do |f|
    f << JSON.pretty_generate(OrderedHash[*examples.sort_by(&:first).flatten(1)])
  end
end

Protected Class Methods

load_json_examples() click to toggle source
# File lib/apipie/extractor/writer.rb, line 61
def self.load_json_examples
  examples = JSON.load(IO.read(examples_file))
  return {} if examples.nil?
  examples.each do |method, records|
    records.each do |record|
      record["verb"] = record["verb"].to_sym if record["verb"]
    end
  end
end
logger() click to toggle source
# File lib/apipie/extractor/writer.rb, line 180
def self.logger
  Extractor.logger
end

Public Instance Methods

write_docs() click to toggle source
# File lib/apipie/extractor/writer.rb, line 16
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 11
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 90
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 124
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 71
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 193
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 142
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 165
def load_old_examples
  if File.exists?(@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 101
def load_recorded_examples
  self.class.load_recorded_examples
end
logger() click to toggle source
# File lib/apipie/extractor/writer.rb, line 176
def logger
  self.class.logger
end
merge_old_new_examples() click to toggle source
# File lib/apipie/extractor/writer.rb, line 105
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 75
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 184
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