From 4f31859b839ad238878dc497d337e799ddf2edfd Mon Sep 17 00:00:00 2001 From: gauravano Date: Sat, 13 Jan 2018 06:25:15 +0530 Subject: [PATCH 1/6] function added --- app/api/srch/search.rb | 23 +++++++++++++++++++++++ app/services/search_service.rb | 26 ++++++++++++++++++++++++++ doc/API.md | 1 + 3 files changed, 50 insertions(+) diff --git a/app/api/srch/search.rb b/app/api/srch/search.rb index 12f034eeb9..e647e3ae86 100644 --- a/app/api/srch/search.rb +++ b/app/api/srch/search.rb @@ -115,6 +115,29 @@ class Search < Grape::API sresult end + # Request URL should be /api/srch/locations?srchString=QRY[&seq=KEYCOUNT&showCount=NUM_ROWS&pageNum=PAGE_NUM] + # Note: Query(QRY as above) must have latitude and longitude as srchString=lat,lon + desc 'Perform a search of documents having nearby latitude and longitude tag values', + hidden: false, + is_array: false, + nickname: 'srchGetLocations' + params do + requires :srchString, type: String, documentation: { example: 'Spec' } + optional :seq, type: Integer, documentation: { example: 995 } + optional :showCount, type: Integer, documentation: { example: 3 } + optional :pageNum, type: Integer, documentation: { example: 0 } + end + get :locations do + sresult = DocList.new + unless params[:srchString].nil? || params[:srchString] == 0 || !(params[:srchString].include? ",") + sservice = SearchService.new + sresult = sservice.nearbyNodes(params[:srchString]) + end + sparms = SearchRequest.fromRequest(params) + sresult.srchParams = sparms + sresult + end + # end endpoint definitions end end diff --git a/app/services/search_service.rb b/app/services/search_service.rb index 5673bd1bd0..981a24b63f 100644 --- a/app/services/search_service.rb +++ b/app/services/search_service.rb @@ -183,4 +183,30 @@ def textSearch_questions(srchString) end sresult end + + def nearbyNodes(srchString) + sresult = DocList.new + coordinates = srchString.split(",") + lat = coordinates[0] + lon = coordinates[1] + + nids = NodeTag.joins(:tag) + .where('name LIKE ?', 'lat:' + lat[0..lat.length - 2] + '%') + .collect(&:nid) + + nids = nids || [] + + items = Node.includes(:tag) + .references(:node, :term_data) + .where('node.nid IN (?) AND term_data.name LIKE ?', nids, 'lon:' + lon[0..lon.length - 2] + '%') + .limit(200) + .order('node.nid DESC') + + items.each do |match| + doc = DocResult.fromSearch(match.nid, 'coordinates', match.path(:items), match.title, 0, match.answers.length.to_i) + sresult.addDoc(doc) + end + sresult + end + end diff --git a/doc/API.md b/doc/API.md index 673a8a0458..7256dfab3b 100644 --- a/doc/API.md +++ b/doc/API.md @@ -10,6 +10,7 @@ Per-model API endpoints are: * Questions: https://publiclab.org/api/srch/questions?srchString=foo * Tags: https://publiclab.org/api/srch/tags?srchString=foo * Notes: https://publiclab.org/api/srch/notes?srchString=foo +* Locations: https://publiclab.org/api/srch/locations?srchString=lat,lon We also provide RSS feeds for tags and authors, in the format: From 6f3473f9d809c4def11d2b8edd6b03def269267b Mon Sep 17 00:00:00 2001 From: gauravano Date: Sun, 14 Jan 2018 13:10:18 +0530 Subject: [PATCH 2/6] initiated test --- test/functional/search_api_test.rb | 25 ++++++++++++++++++++++++- 1 file changed, 24 insertions(+), 1 deletion(-) diff --git a/test/functional/search_api_test.rb b/test/functional/search_api_test.rb index 496cb6312d..75a0c50b29 100644 --- a/test/functional/search_api_test.rb +++ b/test/functional/search_api_test.rb @@ -10,7 +10,6 @@ def app test 'search notes functionality' do get '/api/srch/notes?srchString=Blog' assert last_response.ok? - # Expected search pattern pattern = { srchParams: { @@ -31,4 +30,28 @@ def app end + test 'search nearby nodes functionality' do + get '/api/srch/locations?srchString=71.00,52.00' + assert last_response.ok? + # + # # Expected search pattern + # pattern = { + # srchParams: { + # srchString: '71.00,52.00', + # seq: nil, + # }.ignore_extra_keys! + # }.ignore_extra_keys! + # + # matcher = JsonExpressions::Matcher.new(pattern) + # + # json = JSON.parse(last_response.body) + # + # assert_equal nodes(:map).path, json['items'][0]['docUrl'] + # assert_equal "A map page", json['items'][0]['docTitle'] + # assert_equal 12, json['items'][0]['docId'] + # + # assert matcher =~ json + # + end + end From c94eecbe9b83edacc00dc9ec9a0fb19e68b0d1fa Mon Sep 17 00:00:00 2001 From: gauravano Date: Tue, 16 Jan 2018 23:15:16 +0530 Subject: [PATCH 3/6] latitude and longitude added in items --- app/models/doc_result.rb | 17 ++++++++++++++++- app/services/search_service.rb | 6 +++--- 2 files changed, 19 insertions(+), 4 deletions(-) diff --git a/app/models/doc_result.rb b/app/models/doc_result.rb index 5b30a57a63..ad111cf66b 100644 --- a/app/models/doc_result.rb +++ b/app/models/doc_result.rb @@ -1,6 +1,6 @@ # A DocResult is an individual return item for a document (web page) search class DocResult - attr_accessor :docId, :docType, :docUrl, :docTitle, :docSummary, :docScore + attr_accessor :docId, :docType, :docUrl, :docTitle, :docSummary, :docScore, :latitude,:longitude def initialize; end @@ -15,6 +15,19 @@ def self.fromSearch(idval, typeval, urlval, titleval, sumval, scoreval) obj end + def self.fromLocationSearch(idval, typeval, urlval, titleval, sumval, scoreval,latitude,longitude) + obj = new + obj.docId = idval + obj.docType = typeval + obj.docUrl = urlval + obj.docTitle = titleval + obj.docSummary = sumval + obj.docScore = scoreval + obj.latitude = latitude + obj.longitude = longitude + obj + end + # This subclass is used to auto-generate the RESTful data structure. It is generally not useful for internal Ruby usage # but must be included for full RESTful functionality. class Entity < Grape::Entity @@ -24,5 +37,7 @@ class Entity < Grape::Entity expose :docTitle, documentation: { type: 'String', desc: 'Title or primary descriptor of the linked result.' } expose :docSummary, documentation: { type: 'String', desc: 'If available, first paragraph or descriptor of the linked document.' } expose :docScore, documentation: { type: 'Float', desc: "If calculated, the relevance of the document result to the search request; i.e. the 'matching score'" } + expose :latitude, documentation: {type: 'String',desc: "Returns the latitude associated with node"} + expose :longitude, documentation: {type: 'String',desc: "Returns the longitude associated with node"} end end diff --git a/app/services/search_service.rb b/app/services/search_service.rb index 981a24b63f..55eda6a24c 100644 --- a/app/services/search_service.rb +++ b/app/services/search_service.rb @@ -184,6 +184,7 @@ def textSearch_questions(srchString) sresult end + #Search nearby nodes with respect to given latitude and longitude def nearbyNodes(srchString) sresult = DocList.new coordinates = srchString.split(",") @@ -201,9 +202,8 @@ def nearbyNodes(srchString) .where('node.nid IN (?) AND term_data.name LIKE ?', nids, 'lon:' + lon[0..lon.length - 2] + '%') .limit(200) .order('node.nid DESC') - - items.each do |match| - doc = DocResult.fromSearch(match.nid, 'coordinates', match.path(:items), match.title, 0, match.answers.length.to_i) +items.each do |match| + doc = DocResult.fromLocationSearch(match.nid, 'coordinates', match.path(:items), match.title, 0, match.answers.length.to_i,match.lat,match.lon) sresult.addDoc(doc) end sresult From 101be0d44ac28e58549702cf97fddfd8a97991b3 Mon Sep 17 00:00:00 2001 From: gauravano Date: Wed, 17 Jan 2018 02:39:53 +0530 Subject: [PATCH 4/6] location blurred or not added --- app/models/doc_result.rb | 5 +++-- app/services/search_service.rb | 9 ++++++++- 2 files changed, 11 insertions(+), 3 deletions(-) diff --git a/app/models/doc_result.rb b/app/models/doc_result.rb index ad111cf66b..c603066995 100644 --- a/app/models/doc_result.rb +++ b/app/models/doc_result.rb @@ -1,6 +1,6 @@ # A DocResult is an individual return item for a document (web page) search class DocResult - attr_accessor :docId, :docType, :docUrl, :docTitle, :docSummary, :docScore, :latitude,:longitude + attr_accessor :docId, :docType, :docUrl, :docTitle, :docSummary, :docScore, :latitude, :longitude, :blurred def initialize; end @@ -15,7 +15,7 @@ def self.fromSearch(idval, typeval, urlval, titleval, sumval, scoreval) obj end - def self.fromLocationSearch(idval, typeval, urlval, titleval, sumval, scoreval,latitude,longitude) + def self.fromLocationSearch(idval, typeval, urlval, titleval, sumval, scoreval,latitude,longitude,blurred) obj = new obj.docId = idval obj.docType = typeval @@ -25,6 +25,7 @@ def self.fromLocationSearch(idval, typeval, urlval, titleval, sumval, scoreval,l obj.docScore = scoreval obj.latitude = latitude obj.longitude = longitude + obj.blurred = blurred obj end diff --git a/app/services/search_service.rb b/app/services/search_service.rb index 55eda6a24c..9e10a3f572 100644 --- a/app/services/search_service.rb +++ b/app/services/search_service.rb @@ -203,7 +203,14 @@ def nearbyNodes(srchString) .limit(200) .order('node.nid DESC') items.each do |match| - doc = DocResult.fromLocationSearch(match.nid, 'coordinates', match.path(:items), match.title, 0, match.answers.length.to_i,match.lat,match.lon) + blurred=false + match.node_tags.each do |tag| + if tag.name=="location:blurred" + blurred=true + break + end + end + doc = DocResult.fromLocationSearch(match.nid, 'coordinates', match.path(:items), match.title, 0, match.answers.length.to_i,match.lat,match.lon,blurred) sresult.addDoc(doc) end sresult From f3cf939ae59664145bb418115df52c95dee64194 Mon Sep 17 00:00:00 2001 From: gauravano Date: Wed, 17 Jan 2018 03:07:45 +0530 Subject: [PATCH 5/6] Functional test added --- test/functional/search_api_test.rb | 40 +++++++++++++++--------------- 1 file changed, 20 insertions(+), 20 deletions(-) diff --git a/test/functional/search_api_test.rb b/test/functional/search_api_test.rb index 75a0c50b29..1c7695906c 100644 --- a/test/functional/search_api_test.rb +++ b/test/functional/search_api_test.rb @@ -25,7 +25,7 @@ def app assert_equal nodes(:blog).path, json['items'][0]['docUrl'] assert_equal "Blog post", json['items'][0]['docTitle'] assert_equal 13, json['items'][0]['docId'] - + assert matcher =~ json end @@ -33,25 +33,25 @@ def app test 'search nearby nodes functionality' do get '/api/srch/locations?srchString=71.00,52.00' assert last_response.ok? - # - # # Expected search pattern - # pattern = { - # srchParams: { - # srchString: '71.00,52.00', - # seq: nil, - # }.ignore_extra_keys! - # }.ignore_extra_keys! - # - # matcher = JsonExpressions::Matcher.new(pattern) - # - # json = JSON.parse(last_response.body) - # - # assert_equal nodes(:map).path, json['items'][0]['docUrl'] - # assert_equal "A map page", json['items'][0]['docTitle'] - # assert_equal 12, json['items'][0]['docId'] - # - # assert matcher =~ json - # + + # Expected search pattern + pattern = { + srchParams: { + srchString: '71.00,52.00', + seq: nil, + }.ignore_extra_keys! + }.ignore_extra_keys! + + matcher = JsonExpressions::Matcher.new(pattern) + + json = JSON.parse(last_response.body) + + assert_equal nodes(:blog).path, json['items'][0]['docUrl'] + assert_equal "Blog post", json['items'][0]['docTitle'] + assert_equal 13, json['items'][0]['docId'] + + assert matcher =~ json + end end From 46f3d43a73f727a547f737a401ae76411d3c2ef6 Mon Sep 17 00:00:00 2001 From: gauravano Date: Wed, 17 Jan 2018 20:39:00 +0530 Subject: [PATCH 6/6] Small changes --- app/models/doc_result.rb | 7 ++++--- app/services/search_service.rb | 15 +++++++++------ 2 files changed, 13 insertions(+), 9 deletions(-) diff --git a/app/models/doc_result.rb b/app/models/doc_result.rb index c603066995..1ceb188432 100644 --- a/app/models/doc_result.rb +++ b/app/models/doc_result.rb @@ -15,7 +15,7 @@ def self.fromSearch(idval, typeval, urlval, titleval, sumval, scoreval) obj end - def self.fromLocationSearch(idval, typeval, urlval, titleval, sumval, scoreval,latitude,longitude,blurred) + def self.fromLocationSearch(idval, typeval, urlval, titleval, sumval, scoreval, latitude, longitude, blurred) obj = new obj.docId = idval obj.docType = typeval @@ -38,7 +38,8 @@ class Entity < Grape::Entity expose :docTitle, documentation: { type: 'String', desc: 'Title or primary descriptor of the linked result.' } expose :docSummary, documentation: { type: 'String', desc: 'If available, first paragraph or descriptor of the linked document.' } expose :docScore, documentation: { type: 'Float', desc: "If calculated, the relevance of the document result to the search request; i.e. the 'matching score'" } - expose :latitude, documentation: {type: 'String',desc: "Returns the latitude associated with node"} - expose :longitude, documentation: {type: 'String',desc: "Returns the longitude associated with node"} + expose :latitude, documentation: { type: 'String', desc: "Returns the latitude associated with the node." } + expose :longitude, documentation: { type: 'String', desc: "Returns the longitude associated with the node." } end + end diff --git a/app/services/search_service.rb b/app/services/search_service.rb index 9e10a3f572..b34dbc1b0e 100644 --- a/app/services/search_service.rb +++ b/app/services/search_service.rb @@ -184,7 +184,7 @@ def textSearch_questions(srchString) sresult end - #Search nearby nodes with respect to given latitude and longitude + # Search nearby nodes with respect to given latitude and longitude def nearbyNodes(srchString) sresult = DocList.new coordinates = srchString.split(",") @@ -202,15 +202,18 @@ def nearbyNodes(srchString) .where('node.nid IN (?) AND term_data.name LIKE ?', nids, 'lon:' + lon[0..lon.length - 2] + '%') .limit(200) .order('node.nid DESC') -items.each do |match| - blurred=false + + items.each do |match| + blurred = false + match.node_tags.each do |tag| - if tag.name=="location:blurred" - blurred=true + if tag.name == "location:blurred" + blurred = true break end end - doc = DocResult.fromLocationSearch(match.nid, 'coordinates', match.path(:items), match.title, 0, match.answers.length.to_i,match.lat,match.lon,blurred) + + doc = DocResult.fromLocationSearch(match.nid, 'coordinates', match.path(:items), match.title, 0, match.answers.length.to_i, match.lat, match.lon, blurred) sresult.addDoc(doc) end sresult