From 387d3cfb7c150591f167bae16ca7f7128062aed8 Mon Sep 17 00:00:00 2001 From: Jochen Topf Date: Wed, 2 Jan 2013 19:33:54 +0100 Subject: Move paging parameter handling into new class --- examples/tapi | 2 +- web/lib/api.rb | 111 +++++++++++++++++++++++++++++++++++++++++++ web/lib/api/db.rb | 36 +++++++------- web/lib/api/josm.rb | 10 ++-- web/lib/api/langtag.rb | 15 +++--- web/lib/api/reports.rb | 6 +-- web/lib/api/search.rb | 18 +++---- web/lib/api/wiki.rb | 6 +-- web/lib/apidoc.rb | 81 ------------------------------- web/lib/sql.rb | 12 ++--- web/lib/utils.rb | 2 +- web/taginfo.rb | 7 ++- web/views/taginfo/apidoc.erb | 12 ++--- 13 files changed, 173 insertions(+), 145 deletions(-) create mode 100644 web/lib/api.rb delete mode 100644 web/lib/apidoc.rb diff --git a/examples/tapi b/examples/tapi index 651b267..cb37c03 100755 --- a/examples/tapi +++ b/examples/tapi @@ -45,10 +45,10 @@ def api_call(path, params) end if result.code != '200' STDERR.puts "#{result.code} #{result.message}" + STDERR.puts result.body exit 1 end -# puts result.body puts JSON.pretty_generate(JSON.parse(result.body)) end diff --git a/web/lib/api.rb b/web/lib/api.rb new file mode 100644 index 0000000..28fe786 --- /dev/null +++ b/web/lib/api.rb @@ -0,0 +1,111 @@ + +class API + + @@paths = {} + + attr_accessor :version, :path, :parameters, :paging, :filter, :sort, :result, :description, :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 show_result + return 'unknown' if result.nil? + return result if result.is_a?(String) + '
' + JSON.pretty_generate(result).gsub(/"(STRING|INT|FLOAT|BOOL)"/, '\1') + '
' + end + +end + +class APIParameters + + attr_reader :page, :results_per_page + + 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,4}$/ + raise ArgumentError, 'page must be integer between 0 and 9999' + end + @page = p[:page].to_i + @results_per_page = p[:rp].to_i + end + end + + def do_paging? + @results_per_page != 0 + end + + def first_result + @results_per_page * (@page - 1) + end + +end + diff --git a/web/lib/api/db.rb b/web/lib/api/db.rb index e9239f4..f4f14fb 100644 --- a/web/lib/api/db.rb +++ b/web/lib/api/db.rb @@ -67,7 +67,7 @@ class Taginfo < Sinatra::Base o.length 'length(key)' o.length :key }. - paging(params[:rp], params[:page]). + paging(@ap). execute() if include_data[:wikipages] @@ -112,8 +112,8 @@ class Taginfo < Sinatra::Base end return { - :page => params[:page].to_i, - :rp => params[:rp].to_i, + :page => @ap.page, + :rp => @ap.results_per_page, :total => total, :data => res.map{ |row| h = { :key => row['key'], @@ -172,12 +172,12 @@ class Taginfo < Sinatra::Base o.count_ways o.count_relations }. - paging(params[:rp], params[:page]). + paging(@ap). execute() return { - :page => params[:page].to_i, - :rp => params[:rp].to_i, + :page => @ap.page, + :rp => @ap.results_per_page, :total => total, :data => res.map{ |row| { :key => row['skey'], @@ -378,7 +378,7 @@ class Taginfo < Sinatra::Base o.count_ways o.count_relations }. - paging(params[:rp], params[:page]). + paging(@ap). execute() # Read description for tag from wikipages, first in English then in the chosen @@ -396,8 +396,8 @@ class Taginfo < Sinatra::Base end return { - :page => params[:page].to_i, - :rp => params[:rp].to_i, + :page => @ap.page, + :rp => @ap.results_per_page, :total => total.to_i, :data => res.map{ |row| { :value => row['value'], @@ -459,12 +459,12 @@ class Taginfo < Sinatra::Base o.other_key o.from_fraction }. - paging(params[:rp], params[:page]). + paging(@ap). execute() return { - :page => params[:page].to_i, - :rp => params[:rp].to_i, + :page => @ap.page, + :rp => @ap.results_per_page, :total => total, :data => res.map{ |row| { :other_key => row['other_key'], @@ -491,12 +491,12 @@ class Taginfo < Sinatra::Base o.scale1 o.scale2 }. - paging(params[:rp], params[:page]). + paging(@ap). execute() return { - :page => params[:page].to_i, - :rp => params[:rp].to_i, + :page => @ap.page, + :rp => @ap.results_per_page, :total => total, :data => res.map{ |row| { :key => row['key'], @@ -654,12 +654,12 @@ class Taginfo < Sinatra::Base o.other_value o.from_fraction }. - paging(params[:rp], params[:page]). + paging(@ap). execute() return { - :page => params[:page].to_i, - :rp => params[:rp].to_i, + :page => @ap.page, + :rp => @ap.results_per_page, :total => total, :data => res.map{ |row| { :other_key => row['other_key'], diff --git a/web/lib/api/josm.rb b/web/lib/api/josm.rb index 11a004a..06a3a6c 100644 --- a/web/lib/api/josm.rb +++ b/web/lib/api/josm.rb @@ -26,8 +26,8 @@ class Taginfo < Sinatra::Base def get_josm_result(total, res) return { - :page => params[:page].to_i, - :rp => params[:rp].to_i, + :page => @ap.page, + :rp => @ap.results_per_page, :total => total, :data => res.map{ |row| { :k => row['k'], @@ -58,7 +58,7 @@ class Taginfo < Sinatra::Base o.v :k o.b }. - paging(params[:rp], params[:page]). + paging(@ap). execute() return get_josm_result(total, res); @@ -81,7 +81,7 @@ class Taginfo < Sinatra::Base o.v :b o.b }. - paging(params[:rp], params[:page]). + paging(@ap). execute() return get_josm_result(total, res); @@ -100,7 +100,7 @@ class Taginfo < Sinatra::Base condition('k = ?', key). condition('v = ?', value). order_by([:k, :v]). - paging(params[:rp], params[:page]). + paging(@ap). execute() return get_josm_result(total, res); diff --git a/web/lib/api/langtag.rb b/web/lib/api/langtag.rb index d48425a..2adf326 100644 --- a/web/lib/api/langtag.rb +++ b/web/lib/api/langtag.rb @@ -26,12 +26,12 @@ class Taginfo < Sinatra::Base o.key o.count_all }. - paging(params[:rp], params[:page]). + paging(@ap). execute() return { - :page => params[:page].to_i, - :rp => params[:rp].to_i, + :page => @ap.page, + :rp => @ap.results_per_page, :total => total, :data => res.map{ |row| { :key => row['key'], @@ -84,14 +84,13 @@ class Taginfo < Sinatra::Base end end - if params[:page] - start = (params[:page].to_i - 1) * params[:rp].to_i - entries = entries[start, params[:rp].to_i] + if @ap.do_paging? + entries = entries[@ap.first_result, @ap.results_per_page] end return { - :page => params[:page].to_i, - :rp => params[:rp].to_i, + :page => @ap.page, + :rp => @ap.results_per_page, :total => total, :data => entries.map{ |entry| h = { :type => entry.type.titlecase, diff --git a/web/lib/api/reports.rb b/web/lib/api/reports.rb index a0dc606..84e0306 100644 --- a/web/lib/api/reports.rb +++ b/web/lib/api/reports.rb @@ -50,7 +50,7 @@ class Taginfo < Sinatra::Base o.values_all o.users_all }. - paging(params[:rp], params[:page]). + paging(@ap). execute() reshash = Hash.new @@ -73,8 +73,8 @@ class Taginfo < Sinatra::Base end return { - :page => params[:page].to_i, - :rp => params[:rp].to_i, + :page => @ap.page, + :rp => @ap.results_per_page, :total => total, :data => res.map{ |row| { :key => row['key'], diff --git a/web/lib/api/search.rb b/web/lib/api/search.rb index eca1ed8..87d3433 100644 --- a/web/lib/api/search.rb +++ b/web/lib/api/search.rb @@ -27,12 +27,12 @@ class Taginfo < Sinatra::Base o.key o.value }. - paging(params[:rp], params[:page]). + paging(@ap). execute() return { - :page => params[:page].to_i, - :rp => params[:rp].to_i, + :page => @ap.page, + :rp => @ap.results_per_page, :total => total, :data => res.map{ |row| { :key => row['key'], @@ -63,12 +63,12 @@ class Taginfo < Sinatra::Base o.key o.value }. - paging(params[:rp], params[:page]). + paging(@ap). execute() return { - :page => params[:page].to_i, - :rp => params[:rp].to_i, + :page => @ap.page, + :rp => @ap.results_per_page, :total => total, :data => res.map{ |row| { :key => row['key'], @@ -89,12 +89,12 @@ class Taginfo < Sinatra::Base o.key o.value }. - paging(params[:rp], params[:page]). + paging(@ap). execute() return { - :page => params[:page].to_i, - :rp => params[:rp].to_i, + :page => @ap.page, + :rp => @ap.results_per_page, :total => total, :data => res.map{ |row| { :key => row['key'], diff --git a/web/lib/api/wiki.rb b/web/lib/api/wiki.rb index 7525428..6e5d9de 100644 --- a/web/lib/api/wiki.rb +++ b/web/lib/api/wiki.rb @@ -38,12 +38,12 @@ class Taginfo < Sinatra::Base order_by(params[:sortname], params[:sortorder]){ |o| o.key }. - paging(params[:rp], params[:page]). + paging(@ap). execute() return { - :page => params[:page].to_i, - :rp => params[:rp].to_i, + :page => @ap.page, + :rp => @ap.results_per_page, :total => total, :data => res.map{ |row| lang_hash = Hash.new diff --git a/web/lib/apidoc.rb b/web/lib/apidoc.rb deleted file mode 100644 index 2486e5b..0000000 --- a/web/lib/apidoc.rb +++ /dev/null @@ -1,81 +0,0 @@ - -class APIDoc - - @@paths = {} - - attr_accessor :version, :path, :parameters, :paging, :filter, :sort, :result, :description, :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 show_result - return 'unknown' if result.nil? - return result if result.is_a?(String) - '
' + JSON.pretty_generate(result).gsub(/"(STRING|INT|FLOAT|BOOL)"/, '\1') + '
' - end - -end - diff --git a/web/lib/sql.rb b/web/lib/sql.rb index 5f57fb3..55e4985 100644 --- a/web/lib/sql.rb +++ b/web/lib/sql.rb @@ -125,15 +125,9 @@ module SQL self end - def paging(results_per_page, page) - unless results_per_page.nil? || page.nil? - if results_per_page !~ /^[0-9]{1,3}$/ - raise ArgumentError, 'results per page must be integer between 0 and 999' - end - if page !~ /^[0-9]{1,4}$/ - raise ArgumentError, 'page must be integer between 0 and 9999' - end - limit(results_per_page.to_i, results_per_page.to_i * (page.to_i - 1)) + def paging(ap) + if ap.do_paging? + limit(ap.results_per_page, ap.first_result) end self end diff --git a/web/lib/utils.rb b/web/lib/utils.rb index 274b172..56a5934 100644 --- a/web/lib/utils.rb +++ b/web/lib/utils.rb @@ -172,7 +172,7 @@ 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? + API.new(version, path, doc) unless doc.nil? get("/api/#{version}/#{path}", &block) end diff --git a/web/taginfo.rb b/web/taginfo.rb index 1f74141..6beadb7 100755 --- a/web/taginfo.rb +++ b/web/taginfo.rb @@ -45,7 +45,7 @@ require 'lib/language.rb' require 'lib/sql.rb' require 'lib/sources.rb' require 'lib/reports.rb' -require 'lib/apidoc.rb' +require 'lib/api.rb' require 'lib/langtag/bcp47.rb' #------------------------------------------------------------------------------ @@ -139,6 +139,11 @@ class Taginfo < Sinatra::Base content_type :json expires next_update headers['Access-Control-Allow-Origin'] = '*' + begin + @ap = APIParameters.new(params) + rescue ArgumentError => ex + halt 412, { :error => ex.message }.to_json + end end #------------------------------------- diff --git a/web/views/taginfo/apidoc.erb b/web/views/taginfo/apidoc.erb index d3685b3..3dab6d2 100644 --- a/web/views/taginfo/apidoc.erb +++ b/web/views/taginfo/apidoc.erb @@ -7,17 +7,17 @@

This list of API calls and their descriptions are not complete!

-<% APIDoc.paths.keys.sort.each do |version| - APIDoc.paths[version].keys.sort.each do |path| - doc = APIDoc.paths[version][path] %> +<% API.paths.keys.sort.each do |version| + API.paths[version].keys.sort.each do |path| + doc = API.paths[version][path] %>

<%= doc.complete_path %>

-- cgit v1.2.3