diff --git a/imports/api/ActiveFires/server/countFires.js b/imports/api/ActiveFires/server/countFires.js index dc65ab4..39008da 100644 --- a/imports/api/ActiveFires/server/countFires.js +++ b/imports/api/ActiveFires/server/countFires.js @@ -29,7 +29,25 @@ const findFiresInRegion = (zone) => { return result; }; -const countFires = (regions, stringsToRemove) => { +export const countRealFires = (firesCursor) => { + const realFires = []; + firesCursor.forEach((fire) => { + const union = firesUnion([fire]); + const falsePos = whichAreFalsePositives(FalsePositives, union); + const industries = whichAreFalsePositives(Industries, union); + if (falsePos.count() === 0 && industries.count() === 0) { + realFires.push(fire); + } + }); + // group fires + const realUnion = firesUnion(realFires); + const unionCount = realUnion[0] && + realUnion[0].geometry && + realUnion[0].geometry.coordinates ? realUnion[0].geometry.coordinates.length : 0; + return unionCount; +}; + +const countFiresInRegions = (regions, stringsToRemove) => { let total = 0; const fireStats = {}; @@ -41,25 +59,9 @@ const countFires = (regions, stringsToRemove) => { const fires = findFiresInRegion(region); // TODO Also check neighbour fires (when better implementation of that part) const initialCount = fires.count(); - let count = initialCount; - if (count > 0) { - const realFires = []; - fires.forEach((fire) => { - const union = firesUnion([fire]); - const falsePos = whichAreFalsePositives(FalsePositives, union); - const industries = whichAreFalsePositives(Industries, union); - if (falsePos.count() === 0 && industries.count() === 0) { - realFires.push(fire); - } else { - count -= 1; - } - }); - // group fires - const realUnion = firesUnion(realFires); - const unionCount = realUnion[0] && - realUnion[0].geometry && - realUnion[0].geometry.coordinates ? realUnion[0].geometry.coordinates.length : 0; - if (debug) console.log(`${regionName} initial: ${initialCount}, first calc: ${count} union calc: ${unionCount}`); + if (initialCount > 0) { + const unionCount = countRealFires(fires); + if (debug) console.log(`${regionName} initial: ${initialCount}, union calc: ${unionCount}`); if (unionCount > 0) { total += unionCount; fireStats[regionName] = { count: unionCount, code: regionCode }; @@ -72,4 +74,4 @@ const countFires = (regions, stringsToRemove) => { return { total, fires: fireStats }; }; -export default countFires; +export default countFiresInRegions; diff --git a/imports/api/ActiveFires/server/tweetFiresInZone.js b/imports/api/ActiveFires/server/tweetFiresInZone.js index d88ef85..74d40fb 100644 --- a/imports/api/ActiveFires/server/tweetFiresInZone.js +++ b/imports/api/ActiveFires/server/tweetFiresInZone.js @@ -4,7 +4,7 @@ import { Meteor } from 'meteor/meteor'; import tbuffer from '@turf/buffer'; import emojiFlags from 'emoji-flags'; import tweet from '/imports/modules/server/twitter'; -import countFires from './countFires'; +import countFiresInRegions from './countFires'; const debug = false; @@ -103,7 +103,7 @@ const correctTweetSize = (tweetText) => { }; const tweetEuropeFires = () => { - const resultEu = countFires(europe, [[' ', '']]); + const resultEu = countFiresInRegions(europe, [[' ', '']]); if (resultEu.total > 0) { let tweetText = `${tweetHeaders[0].trim()} ${composeEuropeTweet(resultEu.total, resultEu.fires, false)}. More info: https://fires.comunes.org/fires`; @@ -126,8 +126,8 @@ const tweetEuropeFires = () => { }; const tweetIberiaFires = () => { - const resultEs = countFires(autonomies, stringsToRemoveIberia); - const resultPt = countFires(portugal, stringsToRemoveIberia); + const resultEs = countFiresInRegions(autonomies, stringsToRemoveIberia); + const resultPt = countFiresInRegions(portugal, stringsToRemoveIberia); const fires = Object.assign(resultEs.fires, resultPt.fires); const total = resultEs.total + resultPt.total; diff --git a/imports/startup/server/rest.js b/imports/startup/server/rest.js index b6f63a9..c19edee 100644 --- a/imports/startup/server/rest.js +++ b/imports/startup/server/rest.js @@ -2,9 +2,12 @@ /* eslint-disable import/no-absolute-path */ import { Meteor } from 'meteor/meteor'; +import { NumberBetween } from '/imports/modules/server/other-checks'; import Fires from '/imports/api/Fires/Fires'; +import { check } from 'meteor/check'; import SiteSettings from '/imports/api/SiteSettings/SiteSettings'; import ActiveFiresCollection from '/imports/api/ActiveFires/ActiveFires'; +import { countRealFires } from '/imports/api/ActiveFires/server/countFires'; Meteor.startup(() => { const uptime = new Date(); @@ -19,7 +22,7 @@ Meteor.startup(() => { // Generates: POST on /api/users and GET, DELETE /api/users/:id for // Meteor.users collection /* apiV1.addCollection(Meteor.users, { - * excludedEndpoints: ['getAll', 'put'], + * excludedEndpoints: ['getAll', 'put', 'delete', 'patch', 'get'], * routeOptions: { * authRequired: true * }, @@ -75,4 +78,40 @@ Meteor.startup(() => { return { ms: new Date() - uptime }; } }); + + // Maps to: /api/v1/fires-in/:lat/:lng/:km + // Ex: http://127.0.0.1:3000/api/v1/fires-in/38.736946/-9.142685/100 + apiV1.addRoute('fires-in/:token/:lat/:lng/:km', { authRequired: false }, { + get: function get() { + const lat = Number(this.urlParams.lat); + const lng = Number(this.urlParams.lng); + const km = Number(this.urlParams.km); + const { token } = this.urlParams; + check(lng, NumberBetween(-180, 180)); + check(lat, NumberBetween(-90, 90)); + check(km, NumberBetween(0, 100)); + check(token, String); + + console.log(`Query for fires in ${lat}, ${lng} in ${km} km radius`); + + if (token !== Meteor.settings.private.internalApiToken) { + return {}; + } + + const fires = ActiveFiresCollection.find({ + ourid: { + $near: { + $geometry: { + type: 'Point', + coordinates: [lng, lat] + }, + $maxDistance: km * 1000, + $minDistance: 0 + } + } + }); + + return { total: fires.count(), real: countRealFires(fires) }; + } + }); }); diff --git a/settings-development-sample.json b/settings-development-sample.json index 1ba68f8..9aa3ae3 100644 --- a/settings-development-sample.json +++ b/settings-development-sample.json @@ -33,6 +33,7 @@ }, "proxies_count": 0, "ironPassword": "SomePasswordAlLeast32LongYouKnowHowToCount", + "internalApiToken": "someSimilarPasswordForUseOurAPIinternally", "cron": { "debug": false },