# web/lib/api.rb
class API
@@paths = {}
attr_accessor :version, :path, :parameters, :paging, :filter, :sort, :result, :description, :notes, :example, :ui
def self.paths
@@paths
end
def initialize(version, path, doc)
@version = version
@path = path
@doc = doc
doc.each_pair do |k,v|
instance_variable_set("@#{k}".to_sym, v)
end
@@paths[version] = {} unless @@paths[version]
@@paths[version][path] = self
end
def complete_path
'/api/' + version.to_s + '/' + path
end
def show_paging
paging || 'no'
end
def show_parameters
return 'none' unless parameters
list = []
parameters.keys.sort{ |a,b| a.to_s <=> b.to_s }.each do |p|
list << "#{p} — #{parameters[p]}"
end
list.join(' ')
end
def show_filter
return 'none' unless filter
list = []
filter.keys.sort{ |a,b| a.to_s <=> b.to_s }.each do |f|
list << "#{f} — #{filter[f][:doc]}"
end
list.join(' ')
end
def show_example
return '' if example.nil?
params = []
example.each_pair do |k,v|
params << "#{k}=#{v}"
end
if params.empty?
return complete_path
else
return complete_path + '?' + params.join('&')
end
end
def show_ui
return '' if example.nil?
ui
end
def show_sort
return 'none' unless sort
sort.map{ |s| "#{s}" }.join(', ')
end
def stack_results(level, stack, result)
result.each do |r|
stack.push({
:level => level,
:name => "#{r[0]}:",
:type => r[1].to_s.gsub(/_/, ' '),
:desc => r[2]
})
if r[3]
stack_results(level+1, stack, r[3])
end
end
end
def show_result
return 'unknown' if result.nil?
return result if result.is_a?(String)
# old way of documenting now only used for old API versions
# this can be removed when all API calls ' + JSON.pretty_generate(result).gsub(/"(STRING|INT|FLOAT|BOOL|ARRAY_OF_STRINGS)"/, '\1') + ''
end
stack = []
stack_results(0, stack, result)
return '
' +
stack.map{ |s| "
#{ ' ' * s[:level] }#{ s[:name] }
#{ s[:type] }
#{ s[:desc] }
" }.join("\n") +
'
'
end
def deprecated?
return !@superseded_by.nil?
end
def superseded_by
return '/api/' + @superseded_by
end
end
class APIParameters
attr_reader :page, :results_per_page, :sortorder
attr_accessor :sortname
def initialize(p)
if p[:rp].nil? || p[:rp] == '0' || p[:rp] == '' || p[:page].nil? || p[:page] == '0' || p[:page] == ''
@page = 0
@results_per_page = 0
else
if p[:rp] !~ /^[0-9]{1,3}$/
raise ArgumentError, 'results per page must be integer between 0 and 999'
end
if p[:page] !~ /^[0-9]{1,6}$/
raise ArgumentError, 'page must be integer between 0 and 999999'
end
@page = p[:page].to_i
@results_per_page = p[:rp].to_i
end
if p[:sortname].nil? || p[:sortname] == ''
@sortname = nil
else
@sortname = p[:sortname].gsub(/[^a-z_]/, '_')
end
if p[:sortorder] == 'desc' || p[:sortorder] == 'DESC'
@sortorder = 'DESC'
else
@sortorder = 'ASC'
end
end
def do_paging?
@results_per_page != 0
end
def first_result
@results_per_page * (@page - 1)
end
end