summaryrefslogtreecommitdiff
path: root/web/lib
diff options
context:
space:
mode:
authorJochen Topf <jochen@topf.org>2011-03-07 18:33:34 +0100
committerJochen Topf <jochen@topf.org>2011-03-07 18:33:34 +0100
commitf3c295352f3ec814e80e204b5e785fc2505e05cd (patch)
tree73bae8cba775a70c9da5380990e19302f9a95856 /web/lib
parentc7bad4071f93e6f922c97e0d5d3c3797e3ca00ee (diff)
downloadtaginfo-f3c295352f3ec814e80e204b5e785fc2505e05cd.tar
taginfo-f3c295352f3ec814e80e204b5e785fc2505e05cd.tar.gz
add API documentation functions and start documenting the API
Diffstat (limited to 'web/lib')
-rw-r--r--web/lib/api/db.rb136
-rw-r--r--web/lib/apidoc.rb68
-rw-r--r--web/lib/utils.rb6
3 files changed, 198 insertions, 12 deletions
diff --git a/web/lib/api/db.rb b/web/lib/api/db.rb
index 4999466..d846a54 100644
--- a/web/lib/api/db.rb
+++ b/web/lib/api/db.rb
@@ -2,16 +2,40 @@
class Taginfo < Sinatra::Base
@@filters = {
- :characters_space => "characters='space'",
- :characters_problematic => "characters='problem'",
- :in_wiki => "in_wiki=1",
- :not_in_db => "count_all=0"
+ :characters_space => { :expr => "characters='space'", :doc => 'only show keys with spaces' },
+ :characters_problematic => { :expr => "characters='problem'", :doc => 'only show keys with problematic characters' },
+ :in_wiki => { :expr => "in_wiki=1", :doc => 'only show keys that appear in the wiki' },
+ :not_in_db => { :expr => "count_all=0", :doc => 'only show keys that do not appear in the database' }
}
- get '/api/2/db/keys' do
+ api(2, 'db/keys', {
+ :description => 'Get list of keys that are in the database or mentioned in any other source.',
+ :parameters => nil,
+ :paging => :optional,
+ :filter => @@filters,
+ :query => 'substring on key',
+ :sort => %w( key count_all count_nodes count_ways count_relations values_all users_all in_wiki in_josm in_potlatch length ),
+ :result => {
+ :key => :STRING,
+ :count_all => :INT,
+ :count_all_fraction => :FLOAT,
+ :count_nodes => :INT,
+ :count_nodes_fraction => :FLOAT,
+ :count_ways => :INT,
+ :count_ways_fraction => :FLOAT,
+ :count_relations => :INT,
+ :count_relations_fraction => :FLOAT,
+ :values_all => :INT,
+ :users_all => :INT,
+ :in_wiki => :BOOL,
+ :in_josm => :BOOL,
+ :in_potlatch => :BOOL
+ },
+ :example => { :page => 1, :rp => 10, :filter => 'in_wiki', :sortname => 'key', :sortorder => 'asc' }
+ }) do
if params[:filters]
- filters = params[:filters].split(',').map{ |f| @@filters[f.to_sym] }.compact
+ filters = params[:filters].split(',').map{ |f| @@filters[f.to_sym][:expr] }.compact
else
filters = []
end
@@ -113,7 +137,35 @@ class Taginfo < Sinatra::Base
}.to_json
end
- get '/api/2/db/keys/overview' do
+ api(2, 'db/keys/overview', {
+ :description => 'Show statistics for nodes, ways, relations and total for this key.',
+ :parameters => :key,
+ :paging => :no,
+ :result => {
+ :nodes => {
+ :count => :INT,
+ :count_fraction => :FLOAT,
+ :values => :INT
+ },
+ :ways => {
+ :count => :INT,
+ :count_fraction => :FLOAT,
+ :values => :INT
+ },
+ :relations => {
+ :count => :INT,
+ :count_fraction => :FLOAT,
+ :values => :INT
+ },
+ :all => {
+ :count => :INT,
+ :count_fraction => :FLOAT,
+ :values => :INT
+ },
+ :users => :INT
+ },
+ :example => { :key => 'highway' }
+ }) do
key = params[:key]
out = Hash.new
@@ -139,7 +191,12 @@ class Taginfo < Sinatra::Base
out.to_json
end
- get '/api/2/db/keys/distribution' do
+ api(2, 'db/keys/distribution', {
+ :description => 'Get map with distribution of this key in the database.',
+ :parameters => [:key],
+ :result => 'PNG image.',
+ :example => { :key => 'amenity' }
+ }) do
key = params[:key]
content_type :png
@db.select('SELECT png FROM db.key_distributions').
@@ -147,7 +204,21 @@ class Taginfo < Sinatra::Base
get_first_value()
end
- get '/api/2/db/keys/values' do
+ api(2, 'db/keys/values', {
+ :description => 'Get values used with a given key',
+ :parameters => [:key],
+ :paging => :optional,
+ :filter => {
+ :all => { :doc => 'no filter' },
+ :nodes => { :doc => 'only values on tags used on nodes' },
+ :ways => { :doc => 'only values on tags used on ways' },
+ :relations => { :doc => 'only values on tags used on relations' }
+ },
+ :sort => %w( value count_all count_nodes count_ways count_relations ),
+ :query => 'substring on value',
+ :result => { :value => :STRING, :count => :INT, :fraction => :FLOAT },
+ :example => { :key => 'highway', :page => 1, :rp => 10, :sortname => 'count_ways', :sortorder => 'desc' }
+ }) do
key = params[:key]
filter_type = get_filter()
@@ -193,7 +264,25 @@ class Taginfo < Sinatra::Base
}.to_json
end
- get '/api/2/db/keys/keys' do
+ api(2, 'db/keys/keys', {
+ :description => 'Find keys that are used together with a given key.',
+ :parameters => [:key],
+ :paging => :optional,
+ :filter => {
+ :all => { :doc => 'no filter' },
+ :nodes => { :doc => 'only values on tags used on nodes' },
+ :ways => { :doc => 'only values on tags used on ways' },
+ :relations => { :doc => 'only values on tags used on relations' }
+ },
+ :sort => %w( together_count other_key from_fraction ),
+ :result => {
+ :other_key => :STRING,
+ :together_count => :INT,
+ :to_fraction => :FLOAT,
+ :from_fraction => :FLOAT
+ },
+ :example => { :key => 'highway', :page => 1, :rp => 10, :sortname => 'together_count', :sortorder => 'desc' }
+ }) do
key = params[:key]
filter_type = get_filter()
@@ -235,7 +324,7 @@ class Taginfo < Sinatra::Base
}.to_json
end
- get '/api/2/db/popular_keys' do
+ api(2, 'db/popular_keys') do
total = @db.count('popular_keys').
condition_if("key LIKE '%' || ? || '%'", params[:query]).
get_first_value().to_i
@@ -270,7 +359,30 @@ class Taginfo < Sinatra::Base
}.to_json
end
- get '/api/2/db/tags/overview' do
+ api(2, 'db/tags/overview', {
+ :description => 'Show statistics for nodes, ways, relations and total for this tag.',
+ :parameters => [:key, :value],
+ :paging => :no,
+ :result => {
+ :nodes => {
+ :count => :INT,
+ :count_fraction => :FLOAT,
+ },
+ :ways => {
+ :count => :INT,
+ :count_fraction => :FLOAT,
+ },
+ :relations => {
+ :count => :INT,
+ :count_fraction => :FLOAT,
+ },
+ :all => {
+ :count => :INT,
+ :count_fraction => :FLOAT,
+ }
+ },
+ :example => { :key => 'highway', :value => 'residential' }
+ }) do
key = params[:key]
value = params[:value]
diff --git a/web/lib/apidoc.rb b/web/lib/apidoc.rb
new file mode 100644
index 0000000..26e4598
--- /dev/null
+++ b/web/lib/apidoc.rb
@@ -0,0 +1,68 @@
+
+class APIDoc
+
+ @@paths = {}
+
+ attr_accessor :version, :path, :parameters, :paging, :filter, :sort, :query, :result, :description, :example
+
+ 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_filter
+ return '<i>none</i>' 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
+ complete_path + '?' + params.join('&')
+ end
+
+ def show_sort
+ return '<i>none</i>' unless sort
+ sort.map{ |s| "<tt>#{s}</tt>" }.join(', ')
+ end
+
+ def show_query
+ return '<i>none</i>' unless query
+ query
+ end
+
+ def show_result
+ return '<i>unknown</i>' if result.nil?
+ return result if result.is_a?(String)
+ '<pre>' + JSON.pretty_generate(result).gsub(/"(STRING|INT|FLOAT|BOOL)"/, '\1') + '</pre>'
+ end
+
+end
+
diff --git a/web/lib/utils.rb b/web/lib/utils.rb
index 57fb46f..476d02b 100644
--- a/web/lib/utils.rb
+++ b/web/lib/utils.rb
@@ -175,6 +175,12 @@ def get!(path, &block)
end
end
+# Like the 'get' method but specific for API calls, includes documentation for API calls
+def api(version, path, doc=nil, &block)
+ APIDoc.new(version, path, doc) unless doc.nil?
+ get("/api/#{version}/#{path}", &block)
+end
+
# return the base url for this site
def base_url
request.scheme + '://' + request.host + ':' + request.port.to_s