1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
|
# 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 '<span class="empty">none</span>' unless parameters
list = []
parameters.keys.sort{ |a,b| a.to_s <=> b.to_s }.each do |p|
list << "<tt>#{p}</tt> — #{parameters[p]}"
end
list.join('<br/>')
end
def show_filter
return '<span class="empty">none</span>' unless filter
list = []
filter.keys.sort{ |a,b| a.to_s <=> b.to_s }.each do |f|
list << "<tt>#{f}</tt> — #{filter[f][:doc]}"
end
list.join('<br/>')
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 '<span class="empty">none</span>' unless sort
sort.map{ |s| "<tt>#{s}</tt>" }.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 '<span class="empty">unknown</span>' 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 <v4 are removed
if result.is_a?(Hash)
return '<pre>' + JSON.pretty_generate(result).gsub(/"(STRING|INT|FLOAT|BOOL|ARRAY_OF_STRINGS)"/, '\1') + '</pre>'
end
stack = []
stack_results(0, stack, result)
return '<table class="apiresults">' +
stack.map{ |s| "<tr><td>#{ ' ' * s[:level] }<tt>#{ s[:name] }</tt></td><td>#{ s[:type] }</td><td>#{ s[:desc] }</td></tr>" }.join("\n") +
'</table>'
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
|