From 960a39f5937a50b4d999a3fc5e7465412eb377a0 Mon Sep 17 00:00:00 2001 From: Jochen Topf Date: Thu, 21 Aug 2014 14:38:23 +0200 Subject: Add new 'projects' source. Any kind of project using OSM tags can create a json-formatted taginfo project file and after its URL is added to the taginfo config, taginfo will integrate this data into its database. --- web/lib/api/v4/project.rb | 66 ++++++++++++++++++++++++++++++++++++++++++++++ web/lib/api/v4/projects.rb | 53 +++++++++++++++++++++++++++++++++++++ web/lib/api/v4/tag.rb | 63 +++++++++++++++++++++++++++++++++++++++++++ web/lib/projects.rb | 51 +++++++++++++++++++++++++++++++++++ web/lib/ui/projects.rb | 31 ++++++++++++++++++++++ web/lib/ui/taginfo.rb | 7 +++++ 6 files changed, 271 insertions(+) create mode 100644 web/lib/api/v4/project.rb create mode 100644 web/lib/api/v4/projects.rb create mode 100644 web/lib/projects.rb create mode 100644 web/lib/ui/projects.rb (limited to 'web/lib') diff --git a/web/lib/api/v4/project.rb b/web/lib/api/v4/project.rb new file mode 100644 index 0000000..94eeadc --- /dev/null +++ b/web/lib/api/v4/project.rb @@ -0,0 +1,66 @@ +# web/lib/api/v4/project.rb +class Taginfo < Sinatra::Base + + api(4, 'project/tags', { + :description => 'Get list of all keys/tags used by a project.', + :parameters => { :project => 'Project ID' }, + :paging => :optional, + :sort => %w( tag ), + :result => paging_results([ + [:key, :STRING, 'Key'], + [:value, :STRING, 'Value'], + [:description, :STRING, 'Description'], + [:doc_url, :STRING, 'Documentation URL'], + [:icon_url, :STRING, 'Icon URL'] + ]), + :example => { :page => 1, :rp => 10, :sortname => 'key', :sortorder => 'asc' }, + :ui => '/projects/id_editor' + }) do + project_id = params[:project] + + q = like_contains(params[:query]) + total = @db.count('projects.project_tags'). + condition("project_id=?", project_id). + condition_if("key LIKE ? ESCAPE '@' OR value LIKE ? ESCAPE '@'", q, q). + get_first_value().to_i + + res = @db.select('SELECT * FROM projects.project_tags'). + condition("project_id=?", project_id). + condition_if("key LIKE ? ESCAPE '@' OR value LIKE ? ESCAPE '@'", q, q). + order_by(@ap.sortname, @ap.sortorder) { |o| + o.tag :key + o.tag :value + }. + paging(@ap). + execute() + + return JSON.generate({ + :page => @ap.page, + :rp => @ap.results_per_page, + :total => total, + :url => request.url, + :data => res.map{ |row| { + :key => row['key'], + :value => row['value'], + :description => row['description'], + :doc_url => row['doc_url'], + :icon_url => row['icon_url'] + }} + }, json_opts(params[:format])) + end + + api(4, 'project/icon', { + :description => 'Access logo icon for project.', + :parameters => { :project => 'Project ID' }, + :result => 'PNG image.', + :example => { :project => 'osmcoastline' }, + :ui => '/projects' + }) do + project_id = params[:project] + content_type :png + @db.select('SELECT icon FROM projects.projects'). + condition('id = ?', project_id). + get_first_value() + end + +end diff --git a/web/lib/api/v4/projects.rb b/web/lib/api/v4/projects.rb new file mode 100644 index 0000000..2cbb7fb --- /dev/null +++ b/web/lib/api/v4/projects.rb @@ -0,0 +1,53 @@ +# web/lib/api/v4/projects.rb +class Taginfo < Sinatra::Base + + api(4, 'projects/all', { + :description => 'Get list of all projects using OSM tags known to taginfo.', + :parameters => { :status => 'Only show projects with given status (default is "OK")', :query => 'Only show projects matching this query (substring match, optional).' }, + :paging => :optional, + :sort => %w( name ), + :result => paging_results([ + [:id, :STRING, 'Project id'], + [:name, :STRING, 'Project name'], + [:url, :STRING, 'Project URL'], + [:description, :STRING, 'Project description'] + ]), + :example => { :page => 1, :rp => 10, :sortname => 'name', :sortorder => 'asc' }, + :ui => '/projects' + }) do + if params[:status] + status = params[:status] + else + status = 'OK' + end + + q = like_contains(params[:query]) + total = @db.count('projects.projects'). + condition("fetch_result=?", status). + condition_if("name LIKE ? ESCAPE '@' OR description LIKE ? ESCAPE '@'", q, q). + get_first_value().to_i + + res = @db.select('SELECT * FROM projects.projects'). + condition("fetch_result=?", status). + condition_if("name LIKE ? ESCAPE '@' OR description LIKE ? ESCAPE '@'", q, q). + order_by(@ap.sortname, @ap.sortorder) { |o| + o.name 'lower(name)' + }. + paging(@ap). + execute() + + return JSON.generate({ + :page => @ap.page, + :rp => @ap.results_per_page, + :total => total, + :url => request.url, + :data => res.map{ |row| { + :id => row['id'], + :name => row['name'], + :url => row['project_url'], + :description => row['description'], + }} + }, json_opts(params[:format])) + end + +end diff --git a/web/lib/api/v4/tag.rb b/web/lib/api/v4/tag.rb index 152569a..f2ca53b 100644 --- a/web/lib/api/v4/tag.rb +++ b/web/lib/api/v4/tag.rb @@ -248,4 +248,67 @@ class Taginfo < Sinatra::Base return get_wiki_result(res) end + api(4, 'tag/projects', { + :description => 'Get projects using a given key or tag.', + :parameters => { + :key => 'Tag key (required).', + :value => 'Tag value (optional).', + :query => 'Only show results where the value matches this query (substring match, optional).' + }, + :paging => :optional, + :sort => %w( project_name key value ), + :result => paging_results([ + [:project_id, :STRING, 'Project ID'], + [:project_name, :STRING, 'Project name'], + [:key, :STRING, 'Key'], + [:value, :STRING, 'Value'], + [:description, :STRING, 'Description'], + [:doc_url, :STRING, 'Documentation URL'], + [:icon_url, :STRING, 'Icon URL'] + ]), + :example => { :key => 'highway', :value => 'residential', :page => 1, :rp => 10, :sortname => 'project_name', :sortorder => 'asc' }, + :ui => '/keys/highway=residential#projects' + }) do + key = params[:key] + value = params[:value] + q = like_contains(params[:query]) + total = @db.select('SELECT count(*) FROM projects.projects p, projects.project_tags t ON p.id=t.project_id'). + condition('key = ?', key). + condition_if('value = ? OR VALUE IS NULL', value). + condition_if("value LIKE ? ESCAPE '@' OR name LIKE ? ESCAPE '@'", q, q). + get_first_value().to_i + + res = @db.select('SELECT t.project_id, p.name, t.key, t.value, t.description, t.doc_url, t.icon_url FROM projects.projects p, projects.project_tags t ON p.id=t.project_id'). + condition('key = ?', key). + condition_if('value = ? OR VALUE IS NULL', value). + condition_if("value LIKE ? ESCAPE '@' OR name LIKE ? ESCAPE '@'", q, q). + order_by(@ap.sortname, @ap.sortorder) { |o| + o.project_name 'p.name' + o.project_name :key + o.project_name :value + o.key :key + o.key :value + o.value :value + o.value :key + }. + paging(@ap). + execute() + + return JSON.generate({ + :page => @ap.page, + :rp => @ap.results_per_page, + :total => total.to_i, + :url => request.url, + :data => res.map{ |row| { + :project_id => row['project_id'], + :project_name => row['name'], + :key => row['key'], + :value => row['value'], + :description => row['description'], + :doc_url => row['doc_url'], + :icon_url => row['icon_url'] + } } + }, json_opts(params[:format])) + end + end diff --git a/web/lib/projects.rb b/web/lib/projects.rb new file mode 100644 index 0000000..01536a2 --- /dev/null +++ b/web/lib/projects.rb @@ -0,0 +1,51 @@ +# web/lib/projects.rb +class Project + + @@projects = Array.new + + @@attrs = [:id, :json_url, :fetch_date, :fetch_status, :fetch_json, :fetch_result, :data_format, :data_updated, :data_url, :name, :project_url, :doc_url, :icon_url, :description, :contact_name, :contact_email] + + @@attrs.each do |attr| + attr_reader attr + end + + # Enumerate all available projects + def self.each + @@projects.each do |project| + yield project + end + end + + # Enumerate all available projects + def self.each_with_index + @@projects.each_with_index do |project, n| + yield project, n + end + end + + # The number of available sources + def self.size + @@projects.size + end + + def self.init + db = SQL::Database.new.attach_sources + + db.select("SELECT * FROM projects.projects").execute() do |row| + @@projects << Project.new(row) + end + + db.close + end + + def self.get(id) + @@projects.select{ |p| p.id == id }[0] + end + + def initialize(row) + @@attrs.each do |s| + instance_variable_set("@#{s}", row[s.to_s]) + end + end + +end diff --git a/web/lib/ui/projects.rb b/web/lib/ui/projects.rb new file mode 100644 index 0000000..b2eec53 --- /dev/null +++ b/web/lib/ui/projects.rb @@ -0,0 +1,31 @@ +# web/lib/ui/projects.rb +class Taginfo < Sinatra::Base + + get '/projects' do + @title = t.taginfo.projects + javascript_for(:flexigrid) + javascript "#{ r18n.locale.code }/projects" + erb :projects + end + + get %r{^/projects/(.*)} do |project| + if params[:project].nil? + @project_id = project + else + @project_id = params[:project] + end + + @project = Project.get(@project_id) + + if @project + @title = [h(@project.name), t.taginfo.projects] + end + + section :projects + + javascript_for(:flexigrid) + javascript "#{ r18n.locale.code }/project" + erb :project + end + +end diff --git a/web/lib/ui/taginfo.rb b/web/lib/ui/taginfo.rb index 2d3d6e6..710f48f 100644 --- a/web/lib/ui/taginfo.rb +++ b/web/lib/ui/taginfo.rb @@ -106,4 +106,11 @@ class Taginfo < Sinatra::Base erb :'taginfo/apidoc' end + get '/taginfo/projects' do + @title = t.taginfo.projects + @section = 'taginfo' + @section_title = t.taginfo.meta + erb :'taginfo/projects' + end + end -- cgit v1.2.3