Inital commit

This commit is contained in:
2022-03-06 18:36:36 +01:00
commit bedd69436b
175 changed files with 9965 additions and 0 deletions

View File

@ -0,0 +1,2 @@
DROP TABLE IF EXISTS `airspy`
CREATE TABLE IF NOT EXISTS `airspy` ( `id` BIGINT unsigned NOT NULL AUTO_INCREMENT, `name` TEXT CHARACTER SET utf8 COLLATE utf8_bin NOT NULL, `description` TEXT CHARACTER SET utf8 COLLATE utf8_bin NOT NULL, `source_id` TEXT CHARACTER SET utf8 COLLATE utf8_bin NOT NULL, `loc` POINT NOT NULL, `protocol_id` SMALLINT unsigned NOT NULL, `link` TEXT CHARACTER SET utf8 COLLATE utf8_bin NOT NULL, UNIQUE (id));

View File

@ -0,0 +1,13 @@
DROP TABLE IF EXISTS `airspy`
#NL
CREATE TABLE IF NOT EXISTS `airspy` (
`id` BIGINT unsigned NOT NULL AUTO_INCREMENT,
`name` TEXT CHARACTER SET utf8 COLLATE utf8_bin NOT NULL,
`description` TEXT CHARACTER SET utf8 COLLATE utf8_bin NOT NULL,
`source_id` TEXT CHARACTER SET utf8 COLLATE utf8_bin NOT NULL,
`loc` POINT NOT NULL,
`protocol_id` SMALLINT unsigned NOT NULL,
`link` TEXT CHARACTER SET utf8 COLLATE utf8_bin NOT NULL,
UNIQUE (id)
);
#NL

View File

@ -0,0 +1,157 @@
const fs = require("fs");
const bent = require("bent");
const mysql = require("mysql");
const tools = require("../../functions");
let con = undefined;
function initialize(conection) {
con = conection;
// Prepare all of the tables needed
const array = fs
.readFileSync("./apiHandler/airspydirectory/db_table_config.sql")
.toString()
.split("\n");
for (i in array) {
con.query(array[i], function (err, result) {
tools.handleMysqlErrors(err, getModuleMeta().title);
console.log("Table created for AirspyDirectory");
});
}
const airspyDirectoryApiUrl = "https://airspy.com/directory/status.json";
const mysqlQuery =
"INSERT INTO airspy (name, description, loc, source_id, protocol_id, link) VALUES ( ?, ?, POINT(?,?), ?, ?, ?)";
// Request API and save into table
const request = bent(airspyDirectoryApiUrl, "GET", "json", 200);
request().then(function(body){
console.log("[AirSpyDirectory] Request done");
for (let c = 0; c < body.servers.length; c++) {
const elm = body.servers[c];
con.query(
mysqlQuery,
[
elm.deviceType,
elm.generalDescription +
"<br> Adress: " +
elm.streamingHost +
":" +
elm.streamingPort +
"<br>" +
"Owned by: " +
elm.ownerName,
elm.antennaLocation.lat,
elm.antennaLocation.long,
0,
0,
"https://airspy.com/directory/status.json",
],
function (err, result) {
tools.handleMysqlErrors(err, getModuleMeta().title);
}
);
}
console.log("[AirSpyDirectory] Insert into Database done!");
},
function (err) {
console.warn(
"[" +
getModuleMeta().title +
"] Was unable to resolve request with error: " +
err
);
});
}
function queryData(boundNorthEastLatLng, boundSouthWestLatLng, minimal) {
// Create a new promise to return, DBs are slow.
return new Promise(function (resolve, reject) {
// The Promise constructor should catch any errors thrown on
// this tick. Alternately, try/catch and reject(err) on catch.
let elementsToQuery = "*";
if (minimal) {
elementsToQuery = "id,loc,source_id";
}
// This is taken from https://stackoverflow.com/questions/21208697/select-all-geospatial-points-inside-a-bounding-box
const sqlQuery = " \
SELECT " + elementsToQuery + " \
FROM airspy \
WHERE MBRContains( \
GeomFromText( 'LINESTRING(? ?,? ?)' ), \
loc)";
con.query(sqlQuery, [boundNorthEastLatLng.lat, boundNorthEastLatLng.lng, boundSouthWestLatLng.lat, boundSouthWestLatLng.lng], function (err, rows, fields) {
// Call reject on error states,
// call resolve with results
if (err) {
return reject(err); // Probably bad for PROD
}
const results = [];
for (let e = 0; e < rows.length; e++) {
const currentRow = rows[e];
let element = {
type: "general-poi",
source: "AirSpyDirectory",
titel: currentRow.name,
description: currentRow.description,
url: currentRow.link,
uid: "airspydirectory_" + currentRow.id,
location: currentRow.loc,
icon: "signalIcon",
};
if (minimal) {
const stripableElements = ["title", "description", "url", "type"];
for (h in stripableElements) {
delete element[stripableElements[h]];
}
}
results.push(element);
}
resolve(results);
});
});
}
function queryItem(uid) {
const uidParts = uid.split("_");
const sqlQuery = "SELECT * FROM airspy WHERE id=?";
return new Promise(function (resolve, reject) {
con.query(sqlQuery, [parseInt(uidParts[1])], function (err, rows, fields) {
if (err) {
return reject(err);
}
const results = [];
for (let e = 0; e < rows.length; e++) {
const currentRow = rows[e];
const element = {
type: "general-poi",
source: "AirSpyDirectory",
titel: currentRow.name,
description: currentRow.description,
url: currentRow.link,
uid: "airspydirectory_" + currentRow.id,
location: currentRow.loc,
icon: "signalIcon",
};
results.push(element);
}
resolve(results);
});
});
}
function getModuleMeta() {
return {
title: "AirSpyDirectory",
exactName: "airspydirectory",
country: ["*"],
tags: ["RF"],
features: ["tags"],
limited: false,
};
}
module.exports = { initialize, queryData, getModuleMeta, queryItem };

View File

@ -0,0 +1,4 @@
DROP TABLE IF EXISTS `autobahn`
DROP TABLE IF EXISTS `source`
CREATE TABLE IF NOT EXISTS `source` ( `source_id` INT unsigned NOT NULL AUTO_INCREMENT, `source_name` TEXT CHARACTER SET utf8 COLLATE utf8_bin NOT NULL, `source_live` BIT NOT NULL, `source_link` TEXT CHARACTER SET utf8 COLLATE utf8_bin NOT NULL, `source_type` TEXT CHARACTER SET utf8 COLLATE utf8_bin NOT NULL, `source_area` TEXT CHARACTER SET utf8 COLLATE utf8_bin NOT NULL, UNIQUE (source_id));
CREATE TABLE IF NOT EXISTS `autobahn` ( `id` BIGINT unsigned NOT NULL AUTO_INCREMENT, `name` TEXT CHARACTER SET utf8 COLLATE utf8_bin NOT NULL, `source_id` TEXT CHARACTER SET utf8 COLLATE utf8_bin NOT NULL, `loc` POINT NOT NULL, `protocol_id` SMALLINT unsigned NOT NULL, `link` TEXT CHARACTER SET utf8 COLLATE utf8_bin NOT NULL, UNIQUE (id));

View File

@ -0,0 +1,24 @@
DROP TABLE IF EXISTS `autobahn`
#NL
DROP TABLE IF EXISTS `source`
#NL
CREATE TABLE IF NOT EXISTS `source` (
`source_id` INT unsigned NOT NULL AUTO_INCREMENT,
`source_name` TEXT CHARACTER SET utf8 COLLATE utf8_bin NOT NULL,
`source_live` BIT NOT NULL,
`source_link` TEXT CHARACTER SET utf8 COLLATE utf8_bin NOT NULL,
`source_type` TEXT CHARACTER SET utf8 COLLATE utf8_bin NOT NULL,
`source_area` TEXT CHARACTER SET utf8 COLLATE utf8_bin NOT NULL,
UNIQUE (source_id)
);
#NL
CREATE TABLE IF NOT EXISTS `autobahn` (
`id` BIGINT unsigned NOT NULL AUTO_INCREMENT,
`name` TEXT CHARACTER SET utf8 COLLATE utf8_bin NOT NULL,
`source_id` TEXT CHARACTER SET utf8 COLLATE utf8_bin NOT NULL,
`loc` POINT NOT NULL,
`protocol_id` SMALLINT unsigned NOT NULL,
`link` TEXT CHARACTER SET utf8 COLLATE utf8_bin NOT NULL,
UNIQUE (id)
);
#NL

188
apiHandler/autobahn/main.js Normal file
View File

@ -0,0 +1,188 @@
var fs = require("fs");
const bent = require("bent");
const mysql = require("mysql");
const tools = require("../../functions");
let con = undefined;
function initialize(connection) {
con = connection;
var array = fs
.readFileSync("./apiHandler/autobahn/db_table_config.sql")
.toString()
.split("\n");
for (i in array) {
con.query(array[i], function (err, result) {
tools.handleMysqlErrors(err, getModuleMeta().title);
console.log("Table created for autobahn");
});
}
const roadURL = "https://verkehr.autobahn.de/o/autobahn/";
const baseURL = "https://verkehr.autobahn.de/o/autobahn/#/services/webcam";
var hws = [];
var index_count_cams = 0;
console.log(
"[" +
getModuleMeta().title +
"] Starting requests"
);
const roadRequest = bent(roadURL, "GET", "json", 200);
roadRequest().then(
function (body) {
hws = body.roads;
for (h in hws) {
if (!hws[h].includes("/")) {
let camRequest = bent(
baseURL.replace("#", hws[h]),
"GET",
"json",
200
);
camRequest().then(
function (body) {
for (var i in body.webcam) {
var q =
"INSERT INTO autobahn (name, source_id, loc, protocol_id, link) VALUES (?, ?, POINT(?, ?), 0, ?)"
if (body.webcam[i].linkurl != "") {
index_count_cams += 1;
con.query(q, [body.webcam[i].title, getModuleMeta().exactName, body.webcam[i].coordinate.lat, body.webcam[i].coordinate.long, body.webcam[i].linkurl], function (err, result) {
tools.handleMysqlErrors(err, getModuleMeta().title);
});
}
}
},
function (err) {
console.warn(
"[" +
getModuleMeta().title +
"] Was unable to resolve request with error: " +
err
);
}
);
}
}
},
function (err) {
console.warn(
"[" +
getModuleMeta().title +
"] Was unable to resolve request with error: " +
err
);
}
);
console.log(
"[" +
getModuleMeta().title +
"] Done"
);
}
function queryData(boundNorthEastLatLng, boundSouthWestLatLng, minimal) {
/*
radius in km
*/
return new Promise(function (resolve, reject) {
// The Promise constructor should catch any errors thrown on
// this tick. Alternately, try/catch and reject(err) on catch.
var connection = con;
let elementsToQuery = "*";
if (minimal) {
elementsToQuery = "id,loc,source_id";
}
const sqlQuery = " \
SELECT " + elementsToQuery + " \
FROM autobahn \
WHERE MBRContains( \
GeomFromText( 'LINESTRING(? ?,? ?)' ), \
loc)";
connection.query(
sqlQuery,
[boundNorthEastLatLng.lat, boundNorthEastLatLng.lng, boundSouthWestLatLng.lat, boundSouthWestLatLng.lng],
function (err, rows, fields) {
// Call reject on error states,
// call resolve with results
if (err) {
return reject(err);
}
let results = [];
for (let e = 0; e < rows.length; e++) {
const currentRow = rows[e];
element = {
type: "webcam-iframe",
source: "Autobahn",
titel: currentRow.name,
description: "An example webcam with a url",
url: currentRow.link,
uid: currentRow.source_id + "_" + currentRow.id,
location: currentRow.loc,
icon: "cctvIcon",
};
if (minimal) {
const stripableElements = ["title", "description", "url", "type"];
for (h in stripableElements) {
delete element[stripableElements[h]];
}
}
results.push(element);
}
resolve(results);
}
);
});
}
function queryItem(uid) {
const uidParts = uid.split("_");
const sqlQuery = "SELECT * FROM " + getModuleMeta().exactName + " WHERE id=?";
return new Promise(function (resolve, reject) {
con.query(sqlQuery, [parseInt(uidParts[1])], function (err, rows, fields) {
if (err) {
return reject(err);
}
const results = [];
for (let e = 0; e < rows.length; e++) {
const currentRow = rows[e];
const element = {
type: "webcam-iframe",
source: "Autobahn",
titel: currentRow.name,
description: "An example webcam with a url",
url: currentRow.link,
uid: currentRow.source_id + "_" + currentRow.id,
location: currentRow.loc,
icon: "cctvIcon",
};
results.push(element);
}
resolve(results);
});
});
}
function getModuleMeta() {
return {
title: "Autobahn",
exactName: "autobahn",
country: ["DEU"],
tags: ["webcam"],
limited: false,
};
}
module.exports = { initialize, queryData, getModuleMeta, queryItem };

View File

@ -0,0 +1,2 @@
DROP TABLE IF EXISTS `customWebcams`
CREATE TABLE IF NOT EXISTS `customWebcams` ( `id` BIGINT unsigned NOT NULL AUTO_INCREMENT, `name` TEXT CHARACTER SET utf8 COLLATE utf8_bin NOT NULL, `source_id` TEXT CHARACTER SET utf8 COLLATE utf8_bin NOT NULL, `loc` POINT NOT NULL, `protocol_id` TEXT CHARACTER SET utf8 COLLATE utf8_bin NOT NULL, `link` TEXT CHARACTER SET utf8 COLLATE utf8_bin NOT NULL, UNIQUE (id));

View File

@ -0,0 +1,12 @@
DROP TABLE IF EXISTS `customWebcams`
#NL
CREATE TABLE IF NOT EXISTS `customWebcams` (
`id` BIGINT unsigned NOT NULL AUTO_INCREMENT,
`name` TEXT CHARACTER SET utf8 COLLATE utf8_bin NOT NULL,
`source_id` TEXT CHARACTER SET utf8 COLLATE utf8_bin NOT NULL,
`loc` POINT NOT NULL,
`protocol_id` TEXT CHARACTER SET utf8 COLLATE utf8_bin NOT NULL,
`link` TEXT CHARACTER SET utf8 COLLATE utf8_bin NOT NULL,
UNIQUE (id)
);
#NL

View File

@ -0,0 +1,145 @@
var fs = require("fs");
const bent = require("bent");
const mysql = require("mysql");
const tools = require("../../functions");
let con = undefined;
function initialize(connection) {
con = connection;
var array = fs
.readFileSync("./apiHandler/customWebcams/db_table_config.sql")
.toString()
.split("\n");
for (i in array) {
con.query(array[i], function (err, result) {
tools.handleMysqlErrors(err, getModuleMeta().title);
console.log("Table created for customWebcam");
});
}
console.log("[" + getModuleMeta().title + "] Starting requests");
const data = fs.readFileSync("./apiHandler/customWebcams/webcams.json");
const webcams = JSON.parse(data);
for (var i in webcams.cams) {
var q =
"INSERT INTO customWebcams (name, source_id, loc, protocol_id, link) VALUES (?, ?, POINT(?,?), ?, ?)"
con.query(q, [webcams.cams[i].title, getModuleMeta().exactName, webcams.cams[i].loc.lat, webcams.cams[i].loc.lng, webcams.cams[i].embedType, webcams.cams[i].url], function (err, result) {
tools.handleMysqlErrors(err, getModuleMeta().title);
});
}
console.log("[" + getModuleMeta().title + "] Done");
}
function queryData(boundNorthEastLatLng, boundSouthWestLatLng, minimal) {
return new Promise(function (resolve, reject) {
// The Promise constructor should catch any errors thrown on
// this tick. Alternately, try/catch and reject(err) on catch.
var connection = con;
let elementsToQuery = "*";
if (minimal) {
elementsToQuery = "id,loc,source_id";
}
const sqlQuery = " \
SELECT " + elementsToQuery + " \
FROM customWebcams \
WHERE MBRContains( \
GeomFromText( 'LINESTRING(? ?,? ?)' ), \
loc)";
con.query(sqlQuery, [boundNorthEastLatLng.lat, boundNorthEastLatLng.lng, boundSouthWestLatLng.lat, boundSouthWestLatLng.lng], function (err, rows, fields) {
// Call reject on error states,
// call resolve with results
if (err) {
return reject(err);
}
let results = [];
for (let e = 0; e < rows.length; e++) {
const currentRow = rows[e];
let ty = "";
if (currentRow.protocol_id == "IFRAME") {
ty = "webcam-iframe";
} else if (currentRow.protocol_id == "IMAGE") {
ty = "webcam-image";
}
element = {
type: ty,
source: "customWebcam",
titel: currentRow.name,
description: "An example webcam with a url",
url: currentRow.link,
uid: currentRow.source_id + "_" + currentRow.id,
location: currentRow.loc,
icon: "cctvIcon",
};
if (minimal) {
const stripableElements = ["title", "description", "url", "type"];
for (h in stripableElements) {
delete element[stripableElements[h]];
}
}
results.push(element);
}
resolve(results);
}
);
});
}
function queryItem(uid) {
const uidParts = uid.split("_");
const sqlQuery = "SELECT * FROM " + getModuleMeta().exactName + " WHERE id=?";
return new Promise(function (resolve, reject) {
con.query(sqlQuery, [parseInt(uidParts[1])], function (err, rows, fields) {
if (err) {
return reject(err);
}
const results = [];
for (let e = 0; e < rows.length; e++) {
const currentRow = rows[e];
let ty = "";
if (currentRow.protocol_id == "IFRAME") {
ty = "webcam-iframe";
} else if (currentRow.protocol_id == "IMAGE") {
ty = "webcam-image";
}
element = {
type: ty,
source: "customWebcam",
titel: currentRow.name,
description: "A web cam read from a file",
url: currentRow.link,
uid: currentRow.source_id + "_" + currentRow.id,
location: {
lat: currentRow.loc_lat,
lng: currentRow.loc_lng,
},
icon: "cctvIcon",
};
results.push(element);
}
resolve(results);
});
});
}
function getModuleMeta() {
return {
title: "custom webcams",
exactName: "customWebcams",
country: ["*"],
tags: ["webcam"],
limited: false,
};
}
module.exports = { initialize, queryData, getModuleMeta, queryItem };

View File

@ -0,0 +1,11 @@
{"cams": [
{
"title": "Blick auf den Großenbroder Südstrand",
"loc": {
"lat": 54.35780113081485,
"lng": 11.087519716842067
},
"url":"https://www.grossenbrode.de/webcamImage.php?secretmagickey=HEdqH9cwfqt2q35uuj75j5qdDdx3F7",
"embedType": "IMAGE"
}
]}

View File

114
apiHandler/example/main.js Normal file
View File

@ -0,0 +1,114 @@
const fs = require("fs");
const request = require("request");
const mysql = require("mysql");
const tools = require("../../functions");
let con = undefined;
function initialize(conection) {
console.error("!! THE EXAMPLE MODULE HAS BEEN ENABLED, NEVER ENABLE TO EXAMPLE MODULE !!")
con = conection;
const filePath = "./apiHandler/" + getModuleMeta().exactName + "/db_table_config.sql"
const array = fs
.readFileSync(filePath)
.toString()
.split("\n");
for (i in array) {
con.query(array[i], function (err, result) {
if (err) throw err;
console.log("Table created for " + getModuleMeta().title);
});
}
const requestURL = "https://example.com/api.json";
const mysqlQuery = "INSERT INTO " + getModuleMeta().exactName + " (" + getModuleMeta().exactName + "_id, " + getModuleMeta().exactName + "_name, " + getModuleMeta().exactName + "_description, source_id, " + getModuleMeta().exactName + "_loc_lat, " + getModuleMeta().exactName + "_loc_lng, " + getModuleMeta().exactName + "_protocol_id, " + getModuleMeta().exactName + "_link) VALUES (?, ?, ?, ?, ?, ?, ?, ?)";
request(requestURL, { json: true }, (err, res2, body) => {
if (err) {
throw err;
}
console.log("[" + getModuleMeta().title + "] Request done")
for (let c = 0; c < body.length; c++) {
const elm = body[c];
con.query(mysqlQuery, [c, elm.name, "", 0, elm.currentLocation.coordinates[1], elm.currentLocation.coordinates[0], 0, "https://api.opensensemap.org/boxes/" + elm._id], function (err, result) {
if (err) { throw (err) }
})
}
console.log("[" + getModuleMeta().title + "] Insert into Database done!")
});
}
function queryData(lat, lng, radius, minimal) {
/*
radius in km
*/
return new Promise(function (resolve, reject) {
// The Promise constructor should catch any errors thrown on
// this tick. Alternately, try/catch and reject(err) on catch.
let elementsToQuery = "*";
if (minimal) {
elementsToQuery = "id,loc_lat,loc_lng,source_id";
}
const sqlQuery =
"SELECT \
" +
elementsToQuery +
", \
( 6371 \
* acos( cos( radians(?) ) \
* cos( radians( " + getModuleMeta().exactName + "_loc_lat ) ) \
* cos( radians( " + getModuleMeta().exactName + "_loc_lng ) - radians(?) ) \
+ sin( radians(?) ) \
* sin( radians( " + getModuleMeta().exactName + "_loc_lat ) ) \
) \
) \
AS distance \
FROM " + getModuleMeta().exactName + " \
HAVING distance < ? \
ORDER BY distance";
con.query(sqlQuery, [lat, lng, lat, radius], function (err, rows, fields) {
// Call reject on error states,
// call resolve with results
if (err) {
return reject(err);
}
const results = [];
for (let e = 0; e < rows.length; e++) {
const currentRow = rows[e]
const element = {
"type": "request-info",
"source": getModuleMeta().title,
"titel": currentRow.example_name,
"description": "",
"url": currentRow.example_link,
"distance": currentRow.distance,
"location": {
"lat": currentRow.example_loc_lat,
"lng": currentRow.example_loc_lng
}
}
results.push(element)
}
resolve(results);
});
});
}
function getModuleMeta() {
return {
title: "Example",
exactName: "example",
country: ["*"],
limited: false,
};
}
module.exports = { initialize, queryData, getModuleMeta };

View File

@ -0,0 +1,2 @@
DROP TABLE IF EXISTS `freifunk`
CREATE TABLE IF NOT EXISTS `freifunk` ( `id` BIGINT unsigned NOT NULL AUTO_INCREMENT, `name` TEXT CHARACTER SET utf8mb4 COLLATE utf8mb4_bin NOT NULL, `description` TEXT CHARACTER SET utf8mb4 COLLATE utf8mb4_bin NOT NULL, `source_id` TEXT CHARACTER SET utf8mb4 COLLATE utf8mb4_bin NOT NULL, `loc` POINT NOT NULL, `protocol_id` SMALLINT unsigned NOT NULL, `link` TEXT CHARACTER SET utf8mb4 COLLATE utf8mb4_bin NOT NULL, UNIQUE (id));

View File

@ -0,0 +1,13 @@
DROP TABLE IF EXISTS `freifunk`
#NL
CREATE TABLE IF NOT EXISTS `freifunk` (
`id` BIGINT unsigned NOT NULL AUTO_INCREMENT,
`name` TEXT CHARACTER SET utf8mb4 COLLATE utf8mb4_bin NOT NULL,
`description` TEXT CHARACTER SET utf8mb4 COLLATE utf8mb4_bin NOT NULL,
`source_id` TEXT CHARACTER SET utf8mb4 COLLATE utf8mb4_bin NOT NULL,
`loc` POINT NOT NULL,
`protocol_id` SMALLINT unsigned NOT NULL,
`link` TEXT CHARACTER SET utf8mb4 COLLATE utf8mb4_bin NOT NULL,
UNIQUE (id)
);
#NL

146
apiHandler/freifunk/main.js Normal file
View File

@ -0,0 +1,146 @@
const fs = require("fs");
const bent = require('bent')
const mysql = require("mysql");
const tools = require("../../functions");
let con = undefined;
function initialize(connection) {
con = connection;
const array = fs
.readFileSync("./apiHandler/freifunk/db_table_config.sql")
.toString()
.split("\n");
for (i in array) {
con.query(array[i], function (err, result) {
tools.handleMysqlErrors(err, getModuleMeta().title);
console.log("Table created for freifunk");
});
}
const freifunkDataUrl = "https://www.freifunk-karte.de/data.php";
const mysqlQuery =
"INSERT INTO freifunk (name, description, source_id, loc, protocol_id, link) VALUES (?, ?, ?, POINT(?, ?), ?, ?)";
const resulter = bent(freifunkDataUrl, 'GET', 'json', 200);
resulter().then(function(body){
console.log("[Freifunk] Request done");
for (let c = 0; c < body.allTheRouters.length; c++) {
const elm = body.allTheRouters[c];
con.query(
mysqlQuery,
[
elm.name,
elm.community,
getModuleMeta().exactName,
elm.lat,
elm.long,
0,
"https://www.freifunk-karte.de/",
],
function (err, result) {
tools.handleMysqlErrors(err, getModuleMeta().title);
}
);
}
console.log("[Freifunk] Insert into Database done!");
}, function(err){
console.warn("[" + getModuleMeta().title + "] Was unable to resolve request with error: " + err)
});
}
function queryData(boundNorthEastLatLng, boundSouthWestLatLng, minimal) {
return new Promise(function (resolve, reject) {
// The Promise constructor should catch any errors thrown on
// this tick. Alternately, try/catch and reject(err) on catch.
let elementsToQuery = "*";
if (minimal) {
elementsToQuery = "id,loc,source_id";
}
const sqlQuery = " \
SELECT " + elementsToQuery + " \
FROM freifunk \
WHERE MBRContains( \
GeomFromText( 'LINESTRING(? ?,? ?)' ), \
loc)";
con.query(sqlQuery, [boundNorthEastLatLng.lat, boundNorthEastLatLng.lng, boundSouthWestLatLng.lat, boundSouthWestLatLng.lng], function (err, rows, fields) {
// Call reject on error states,
// call resolve with results
if (err) {
return reject(err);
}
const results = [];
for (let e = 0; e < rows.length; e++) {
const currentRow = rows[e];
const element = {
type: "general-poi",
source: "Freifunk",
titel: currentRow.name,
description:
"This is an AP by the " +
currentRow.description +
" Freifunk Comunity",
url: currentRow.link,
uid: "freifunk_" + currentRow.id,
location: currentRow.loc,
icon: "wifiIcon"
};
if (minimal) {
const stripableElements = ["title", "description", "url", "type"];
for (h in stripableElements) {
delete element[stripableElements[h]];
}
}
results.push(element);
}
resolve(results);
});
});
}
function queryItem(uid){
const uidParts = uid.split("_");
const sqlQuery = "SELECT * FROM " + getModuleMeta().exactName + " WHERE id=?"
return new Promise(function (resolve, reject) {
con.query(sqlQuery, [parseInt(uidParts[1])], function (err, rows, fields) {
if (err) {
return reject(err);
}
const results = [];
for (let e = 0; e < rows.length; e++) {
const currentRow = rows[e];
const element = {
type: "general-poi",
source: "Freifunk",
titel: currentRow.name,
description:
"This is an AP by the " +
currentRow.description +
" Freifunk Comunity",
url: currentRow.link,
uid: "freifunk_" + currentRow.id,
location: currentRow.loc,
icon: "wifiIcon"
};
results.push(element);
}
resolve(results)
});
});
}
function getModuleMeta() {
return {
title: "Freifunk",
exactName: "freifunk",
country: ["*"],
tags: ["AP"],
limited: false,
};
}
module.exports = { initialize, queryData, getModuleMeta, queryItem };

View File

@ -0,0 +1,2 @@
DROP TABLE IF EXISTS `opensensemap`
CREATE TABLE IF NOT EXISTS `opensensemap` ( `id` BIGINT unsigned NOT NULL AUTO_INCREMENT, `name` TEXT CHARACTER SET utf8mb4 COLLATE utf8mb4_bin NOT NULL, `description` TEXT CHARACTER SET utf8mb4 COLLATE utf8mb4_bin NOT NULL, `source_id` TEXT CHARACTER SET utf8mb4 COLLATE utf8mb4_bin NOT NULL, `loc` POINT NOT NULL, `protocol_id` SMALLINT unsigned NOT NULL, `link` TEXT CHARACTER SET utf8mb4 COLLATE utf8mb4_bin NOT NULL, UNIQUE (id));

View File

@ -0,0 +1,13 @@
DROP TABLE IF EXISTS `opensensemap`
#NL
CREATE TABLE IF NOT EXISTS `opensensemap` (
`id` BIGINT unsigned NOT NULL AUTO_INCREMENT,
`name` TEXT CHARACTER SET utf8mb4 COLLATE utf8mb4_bin NOT NULL,
`description` TEXT CHARACTER SET utf8mb4 COLLATE utf8mb4_bin NOT NULL,
`source_id` TEXT CHARACTER SET utf8mb4 COLLATE utf8mb4_bin NOT NULL,
`loc` POINT NOT NULL,
`protocol_id` SMALLINT unsigned NOT NULL,
`link` TEXT CHARACTER SET utf8mb4 COLLATE utf8mb4_bin NOT NULL,
UNIQUE (id)
);
#NL

View File

@ -0,0 +1,145 @@
const fs = require("fs");
const mysql = require("mysql");
const bent = require('bent')
const tools = require("../../functions");
let con = undefined;
function initialize(conection) {
con = conection;
const filePath =
"./apiHandler/" + getModuleMeta().exactName + "/db_table_config.sql";
const array = fs.readFileSync(filePath).toString().split("\n");
for (i in array) {
con.query(array[i], function (err, result) {
if (err) throw err;
console.log("Table created for " + getModuleMeta().title);
});
}
const requestURL = "https://api.opensensemap.org/boxes";
const mysqlQuery =
"INSERT INTO opensensemap (name, description, source_id, loc, protocol_id, link) VALUES (?, ?, ?, POINT(?, ?), ?, ?)";
const res = bent(requestURL, 'GET', 'json', 200);
res().then(function(response){
body = response
console.log("[" + getModuleMeta().title + "] Request done");
for (let c = 0; c < body.length; c++) {
const elm = body[c];
con.query(
mysqlQuery,
[
elm.name,
"",
getModuleMeta().exactName,
elm.currentLocation.coordinates[1],
elm.currentLocation.coordinates[0],
0,
"https://sensebox.github.io/opensensemap-widget/iframe.html?senseboxId=" + elm._id,
],
function (err, result) {
tools.handleMysqlErrors(err, getModuleMeta().title);
}
);
}
console.log("[" + getModuleMeta().title + "] Insert into Database done!");
}, function(err){
console.warn("[" + getModuleMeta().title + "] Was unable to resolve request with error: " + err)
});
}
function queryData(boundNorthEastLatLng, boundSouthWestLatLng, minimal) {
return new Promise(function (resolve, reject) {
// The Promise constructor should catch any errors thrown on
// this tick. Alternately, try/catch and reject(err) on catch.
let elementsToQuery = "*";
if (minimal) {
elementsToQuery = "id,loc,source_id";
}
// This is taken from https://stackoverflow.com/questions/21208697/select-all-geospatial-points-inside-a-bounding-box
const sqlQuery = " \
SELECT " + elementsToQuery + " \
FROM opensensemap \
WHERE MBRContains( \
GeomFromText( 'LINESTRING(? ?,? ?)' ), \
loc)";
con.query(sqlQuery, [boundNorthEastLatLng.lat, boundNorthEastLatLng.lng, boundSouthWestLatLng.lat, boundSouthWestLatLng.lng], function (err, rows, fields) {
// Call reject on error states,
// call resolve with results
if (err) {
return reject(err);
}
const results = [];
for (let e = 0; e < rows.length; e++) {
const currentRow = rows[e];
const element = {
type: "iframe",
source: getModuleMeta().exactName,
titel: currentRow.name,
description: "",
url: currentRow.link,
uid: "opensensemap_" + currentRow.id,
location: currentRow.loc,
icon: "temperatureIcon"
};
if (minimal) {
const stripableElements = ["title", "description", "url", "type"];
for (h in stripableElements) {
delete element[stripableElements[h]];
}
}
results.push(element);
}
resolve(results);
});
});
}
function queryItem(uid){
const uidParts = uid.split("_");
const sqlQuery = "SELECT * FROM `" + getModuleMeta().exactName + "` WHERE id=?"
return new Promise(function (resolve, reject) {
con.query(sqlQuery, [parseInt(uidParts[1])], function (err, rows, fields) {
if (err) {
return reject(err);
}
console.log()
const results = [];
for (let e = 0; e < rows.length; e++) {
const currentRow = rows[e];
const element = {
type: "iframe",
source: getModuleMeta().exactName,
titel: currentRow.name,
description: "",
url: currentRow.link,
uid: "opensensemap_" + currentRow.id,
distance: tools.roundOff(currentRow.distance, 4),
location: currentRow.loc,
icon: "temperatureIcon"
};
results.push(element);
}
resolve(results)
});
});
}
function getModuleMeta() {
return {
title: "OpenSensemap",
exactName: "opensensemap",
tags: ["temperature", "envoriment"],
country: ["*"],
limited: false,
};
}
module.exports = { initialize, queryData, getModuleMeta, queryItem };

View File

@ -0,0 +1,2 @@
DROP TABLE IF EXISTS `opentopia`
CREATE TABLE IF NOT EXISTS `opentopia` ( `id` BIGINT unsigned NOT NULL AUTO_INCREMENT, `name` TEXT CHARACTER SET utf8 COLLATE utf8_bin NOT NULL, `source_id` TEXT CHARACTER SET utf8 COLLATE utf8_bin NOT NULL, `loc` POINT NOT NULL, `protocol_id` SMALLINT unsigned NOT NULL, `link` TEXT CHARACTER SET utf8 COLLATE utf8_bin NOT NULL, UNIQUE (id), UNIQUE (`link`));

View File

@ -0,0 +1,13 @@
DROP TABLE IF EXISTS `opentopia`
#NL
CREATE TABLE IF NOT EXISTS `opentopia` (
`id` BIGINT unsigned NOT NULL AUTO_INCREMENT,
`name` TEXT CHARACTER SET utf8 COLLATE utf8_bin NOT NULL,
`source_id` TEXT CHARACTER SET utf8 COLLATE utf8_bin NOT NULL,
`loc` POINT NOT NULL,
`protocol_id` SMALLINT unsigned NOT NULL,
`link` TEXT CHARACTER SET utf8 COLLATE utf8_bin NOT NULL,
UNIQUE (id),
UNIQUE (`link`)
);
#NL

View File

@ -0,0 +1,317 @@
var fs = require("fs");
const bent = require("bent");
const mysql = require("mysql");
const tools = require("../../functions");
const _ = require("underscore");
let con = undefined;
let config;
function requestWithPromise(n) {
const listURL =
"http://www.opentopia.com/hiddencam.php?showmode=standard&country=%2A&seewhat=highlyrated&p=";
return new Promise(function (resolve, reject) {
const request = bent(listURL + n, "GET", 200);
request().then(
function (body) {
body.text().then(function (text) {
resolve(text);
});
},
function (err) {
console.warn(
"[" +
getModuleMeta().title +
"] Was unable to resolve request with error: " +
err
);
}
);
});
}
function initialize(connection, configL, replaceOld = false) {
con = connection;
config = configL;
if(!fs.existsSync("./apiHandler/opentopia/FLAG")){
fs.writeFileSync("./apiHandler/opentopia/FLAG", "")
replaceOld = true
}
if (replaceOld) { // Just do it once, calling that API ain't cheap
var array = fs
.readFileSync("./apiHandler/opentopia/db_table_config.sql")
.toString()
.split("\n");
for (i in array) {
con.query(array[i], function (err, result) {
tools.handleMysqlErrors(err, getModuleMeta().title + "L32");
console.log("Table created for " + getModuleMeta().title);
});
}
let allProms = [];
for (let n = 0; n < 26; n++) {
allProms.push(requestWithPromise(n));
}
const mysqlQuery =
"INSERT INTO opentopia (name, source_id, loc, protocol_id, link) VALUES (?, ?, POINT(?, ?), ?, ?)";
Promise.all(allProms).then(function (res) {
for (l in res) {
const baseurl = "http://www.opentopia.com/webcam/";
let allResults = [];
// Process the pages
let part = res[l].split("<body>")[1];
part = part.split("/webcam/");
part.shift();
for (h in part) {
part[h] = part[h].replace("\t", "");
part[h] = part[h]
.split('target="_self">')[0]
.replace('"', "")
.split(">")[0];
}
pages = part;
camProms = [];
for (let pI = 0; pI < pages.length; pI++) {
camProms.push(
new Promise(function (resolve, reject) {
const url = baseurl + pages[pI] + "?viewmode=livevideo";
_.throttle(function () {
setTimeout(function () {
const request = bent(url, "GET", 200);
request().then(
function (body) {
body.text().then(function (text) {
let pre;
let result = {
name: "",
url: "",
location: { lat: 0, lng: 0 },
};
try {
const body = text;
let part = body.split("<body>")[1];
camPart = part.split('<div class="big">')[1];
camPart = camPart.split('<img src="')[1];
camPart = camPart.split('"')[0];
result.url = camPart;
part = part.split("Facility")[1];
part = part.split("Rating")[0];
part = part.split('<label class="right">')[1];
pre = part;
result.name = part.split("</label></div>")[0];
result.name = result.name
.replaceAll("\t", "")
.replaceAll(" ", "");
part = part.split('<label class="right geo">')[1];
part = part.split('<span class="latitude">')[1];
result.location.lat = parseFloat(
part.split("</span>")[0]
);
part = part.split('<span class="longitude">')[1];
result.location.lng = parseFloat(
part.split("</span>")[0]
);
resolve(result);
} catch (ex) {
if (pre == undefined) {
resolve([]);
} else {
let reqPart1;
let reqPart2;
try {
reqPart1 = pre
.split('locality">')[1]
.split("</label>")[0];
} catch (error) {
reqPart1 = pre
.split('region">')[1]
.split("</label>")[0];
}
reqPart2 = pre
.split('country-name">')[1]
.split("</label>")[0];
const geoCoderReq = bent(
"https://open.mapquestapi.com/geocoding/v1/address?key=" +
config.mapquest +
"&location=" +
reqPart1 +
"," +
reqPart2,
"GET",
"json",
200
);
geoCoderReq().then(function (body) {
result.location.lat =
body.results[0].locations[0].latLng.lat;
result.location.lng =
body.results[0].locations[0].latLng.lng;
resolve(result);
});
console.log(reqPart1 + "," + reqPart2);
}
}
});
},
function (err) {
console.warn(
"[" +
getModuleMeta().title +
"] Was unable to resolve request with error: " +
err
);
}
);
}, Math.floor(Math.random() * 500));
}, 200)();
})
);
let globalI = 0;
Promise.all(camProms).then(function (result) {
// console.log(result);
for (elm in result) {
const row = result[elm];
globalI++;
try {
con.query(
mysqlQuery,
[
row.name,
getModuleMeta().exactName,
row.location.lat,
row.location.lng,
0,
row.url,
],
function (err, result) {
if (err) {
if (err.code == "ER_DUP_ENTRY") {
//console.warn("[Opentopia] Skipped duplicate webcam");
} else {
tools.handleMysqlErrors(
err,
getModuleMeta().title + "L128"
);
}
}
}
);
} catch (error) {
/*console.warn(
"[Opentopia] Experienced an issue adding element to DB, error was: " +
error
);*/
}
}
});
}
}
});
}
}
function queryData(boundNorthEastLatLng, boundSouthWestLatLng, minimal) {
return new Promise(function (resolve, reject) {
// The Promise constructor should catch any errors thrown on
// this tick. Alternately, try/catch and reject(err) on catch.
var connection = con;
let elementsToQuery = "*";
if (minimal) {
elementsToQuery = "id,loc,source_id";
}
const sqlQuery = " \
SELECT " + elementsToQuery + " \
FROM opentopia \
WHERE MBRContains( \
GeomFromText( 'LINESTRING(? ?,? ?)' ), \
loc)";
con.query(sqlQuery, [boundNorthEastLatLng.lat, boundNorthEastLatLng.lng, boundSouthWestLatLng.lat, boundSouthWestLatLng.lng], function (err, rows, fields) {
// Call reject on error states,
// call resolve with results
if (err) {
tools.handleMysqlErrors(err, getModuleMeta().title + "-L187");
return reject(err);
}
let results = [];
for (let e = 0; e < rows.length; e++) {
const currentRow = rows[e];
element = {
type: "webcam-iframe",
source: "Opentopia",
titel: currentRow.name,
description: "An example webcam with a url",
url: currentRow.link,
uid: "opentopia_" + currentRow.id,
location: currentRow.loc,
icon: "cctvIcon",
};
if (minimal) {
const stripableElements = ["title", "description", "url", "type"];
for (h in stripableElements) {
delete element[stripableElements[h]];
}
}
results.push(element);
}
resolve(results);
}
);
});
}
function queryItem(uid) {
const uidParts = uid.split("_");
const sqlQuery = "SELECT * FROM " + getModuleMeta().exactName + " WHERE id=?";
return new Promise(function (resolve, reject) {
con.query(sqlQuery, [parseInt(uidParts[1])], function (err, rows, fields) {
if (err) {
tools.handleMysqlErrors(err, getModuleMeta().title + "L230");
return reject(err);
}
const results = [];
for (let e = 0; e < rows.length; e++) {
const currentRow = rows[e];
const element = {
type: "webcam-iframe",
source: "Opentopia",
titel: currentRow.name,
description: "An example webcam with a url",
url: currentRow.link,
uid: "opentopia_" + currentRow.id,
location: currentRow.loc,
icon: "cctvIcon",
};
results.push(element);
}
resolve(results);
});
});
}
function getModuleMeta() {
return {
title: "Opentopia",
exactName: "opentopia",
country: ["*"],
tags: ["webcam"],
limited: false,
};
}
module.exports = { initialize, queryData, getModuleMeta, queryItem };

View File

View File

@ -0,0 +1 @@

28
apiHandler/stub/main.js Normal file
View File

@ -0,0 +1,28 @@
let con = undefined;
function initialize(connection) {
con = connection;
// Do nothing and die.
}
function queryData(lat, lng, radius, minimal) {
// Does nothing.
return new Promise(function (resolve, reject) {resolve([]);});
}
function queryItem(uid) {
// Does nothing.
return new Promise(function (resolve, reject) {resolve([]);});
}
function getModuleMeta() {
return {
title: "Stub",
exactName: "stub",
country: [""],
tags: [""],
limited: true,
};
}
module.exports = { initialize, queryData, getModuleMeta, queryItem };

View File

@ -0,0 +1,2 @@
DROP TABLE IF EXISTS `ttnantenna`
CREATE TABLE IF NOT EXISTS `ttnantenna` ( `id` BIGINT unsigned NOT NULL AUTO_INCREMENT, `name` TEXT CHARACTER SET utf8mb4 COLLATE utf8mb4_bin NOT NULL, `description` TEXT CHARACTER SET utf8mb4 COLLATE utf8mb4_bin NOT NULL, `source_id` TEXT CHARACTER SET utf8mb4 COLLATE utf8mb4_bin NOT NULL, `loc` POINT NOT NULL, `protocol_id` SMALLINT unsigned NOT NULL, `link` TEXT CHARACTER SET utf8mb4 COLLATE utf8mb4_bin NOT NULL, UNIQUE (id));

View File

@ -0,0 +1,13 @@
DROP TABLE IF EXISTS `ttnantenna`
#NL
CREATE TABLE IF NOT EXISTS `ttnantenna` (
`id` BIGINT unsigned NOT NULL AUTO_INCREMENT,
`name` TEXT CHARACTER SET utf8mb4 COLLATE utf8mb4_bin NOT NULL,
`description` TEXT CHARACTER SET utf8mb4 COLLATE utf8mb4_bin NOT NULL,
`source_id` TEXT CHARACTER SET utf8mb4 COLLATE utf8mb4_bin NOT NULL,
`loc` POINT NOT NULL,
`protocol_id` SMALLINT unsigned NOT NULL,
`link` TEXT CHARACTER SET utf8mb4 COLLATE utf8mb4_bin NOT NULL,
UNIQUE (id)
);
#NL

View File

@ -0,0 +1,175 @@
const fs = require("fs");
const bent = require("bent");
const mysql = require("mysql");
const tools = require("../../functions");
let con = undefined;
function initialize(connection) {
con = connection;
const array = fs
.readFileSync("./apiHandler/ttnantennas/db_table_config.sql")
.toString()
.split("\n");
for (i in array) {
con.query(array[i], function (err, result) {
if (err) throw err;
console.log("Table created for ttnantenna");
});
}
const ttnGateways =
"https://www.thethingsnetwork.org/gateway-data/";
const mysqlQuery =
"INSERT INTO ttnantenna (name, description, source_id, loc, protocol_id, link) VALUES (?, ?, ?, POINT(?, ?), ?, ?)";
const ttnGateRequest = bent(ttnGateways, "GET", "json", 200);
ttnGateRequest().then(function(body){
console.log("[TheThingsnetwork Gateways] Request done");
let i = 0;
for (const key in body) {
const elm = body[key];
if (elm.location != undefined) {
if(elm.attributes == undefined){
elm.attributes = {frequency_plan: "Unknown", placement: "Unknown"}
}else{
if(elm.attributes.frequency_plan == undefined){
elm.attributes.frequency_plan = "Unknown"
}
if(elm.attributes.placement == undefined){
elm.attributes.placement = "Unknown"
}
}
if (
elm.location.latitude != undefined &&
elm.location.longitude != undefined
) {
con.query(
mysqlQuery,
[
key,
elm.description +
"<br>Frequency plan: " +
elm.attributes.frequency_plan +
"<br> Altitude: " +
elm.location.altitude
+ "<br>Placement: " + elm.attributes.placement,
getModuleMeta().exactName,
elm.location.latitude,
elm.location.longitude,
0,
"",
],
function (err, result) {
tools.handleMysqlErrors(err, getModuleMeta().title);
}
);
i++
}
}
}
console.log("[TheThingsnetwork Gateways] Insert into Database done!");
},
function (err) {
console.warn(
"[" +
getModuleMeta().title +
"] Was unable to resolve request with error: " +
err
);
});
}
function queryData(boundNorthEastLatLng, boundSouthWestLatLng, minimal) {
return new Promise(function (resolve, reject) {
// The Promise constructor should catch any errors thrown on
// this tick. Alternately, try/catch and reject(err) on catch.
var connection = con;
let elementsToQuery = "*";
if (minimal) {
elementsToQuery = "id,loc,source_id";
}
const sqlQuery = " \
SELECT " + elementsToQuery + " \
FROM ttnantenna \
WHERE MBRContains( \
GeomFromText( 'LINESTRING(? ?,? ?)' ), \
loc)";
con.query(sqlQuery, [boundNorthEastLatLng.lat, boundNorthEastLatLng.lng, boundSouthWestLatLng.lat, boundSouthWestLatLng.lng], function (err, rows, fields) {
// Call reject on error states,
// call resolve with results
if (err) {
return reject(err);
}
const results = [];
for (let e = 0; e < rows.length; e++) {
const currentRow = rows[e];
const element = {
type: "general-poi",
source: "ttnantennas",
titel: currentRow.name,
description: currentRow.description,
url: currentRow.link,
uid: "ttnantennas_" + currentRow.id,
location: currentRow.loc,
icon: "signalIcon"
};
if (minimal) {
const stripableElements = ["title", "description", "url", "type"];
for (h in stripableElements) {
delete element[stripableElements[h]];
}
}
results.push(element);
}
resolve(results);
});
});
}
function queryItem(uid) {
const uidParts = uid.split("_");
const sqlQuery = "SELECT * FROM ttnantenna WHERE id=?";
return new Promise(function (resolve, reject) {
con.query(sqlQuery, [parseInt(uidParts[1])], function (err, rows, fields) {
if (err) {
return reject(err);
}
const results = [];
for (let e = 0; e < rows.length; e++) {
const currentRow = rows[e];
const element = {
type: "general-poi",
source: "ttnantennas",
titel: currentRow.name,
description: currentRow.description,
url: currentRow.link,
uid: "ttnantennas_" + currentRow.id,
location: {
lat: currentRow.loc_lat,
lng: currentRow.loc_lng,
},
};
results.push(element);
}
resolve(results);
});
});
}
function getModuleMeta() {
return {
title: "TheThingsnetwork Gateways",
exactName: "ttnantennas",
country: ["*"],
limited: false,
};
}
module.exports = { initialize, queryData, getModuleMeta, queryItem };

View File

@ -0,0 +1,2 @@
DROP TABLE IF EXISTS `ttncomms`
CREATE TABLE IF NOT EXISTS `ttncomms` ( `id` BIGINT unsigned NOT NULL AUTO_INCREMENT, `name` TEXT CHARACTER SET utf8 COLLATE utf8_bin NOT NULL, `description` TEXT CHARACTER SET utf8 COLLATE utf8_bin NOT NULL, `source_id` TEXT CHARACTER SET utf8 COLLATE utf8_bin NOT NULL, `loc` POINT NOT NULL, `protocol_id` SMALLINT unsigned NOT NULL, `link` TEXT CHARACTER SET utf8 COLLATE utf8_bin NOT NULL, UNIQUE (id));

View File

@ -0,0 +1,13 @@
DROP TABLE IF EXISTS `ttncomms`
#NL
CREATE TABLE IF NOT EXISTS `ttncomms` (
`id` BIGINT unsigned NOT NULL AUTO_INCREMENT,
`name` TEXT CHARACTER SET utf8 COLLATE utf8_bin NOT NULL,
`description` TEXT CHARACTER SET utf8 COLLATE utf8_bin NOT NULL,
`source_id` TEXT CHARACTER SET utf8 COLLATE utf8_bin NOT NULL,
`loc` POINT NOT NULL,
`protocol_id` SMALLINT unsigned NOT NULL,
`link` TEXT CHARACTER SET utf8 COLLATE utf8_bin NOT NULL,
UNIQUE (id)
);
#NL

165
apiHandler/ttncomms/main.js Normal file
View File

@ -0,0 +1,165 @@
const fs = require("fs");
const bent = require('bent')
const tools = require("../../functions");
let con = undefined;
function initialize(connection) {
con = connection;
const array = fs
.readFileSync("./apiHandler/ttncomms/db_table_config.sql")
.toString()
.split("\n");
for (i in array) {
con.query(array[i], function (err, result) {
if (err) throw err;
console.log("Table created for ttncomms");
});
}
const ttnCommUrl =
"https://www.thethingsnetwork.org/community.json";
const mysqlQuery =
"INSERT INTO ttncomms (name, description, source_id, loc, protocol_id, link) VALUES (?, ?, ?, POINT(?, ?), ?, ?)";
const res = bent(ttnCommUrl, 'GET', 'json', 200);
res().then(function(body){
console.log("[TheThingsnetwork Communities] Request done");
for (let c = 0; c < body.length; c++) {
const elm = body[c];
if (elm.lat != null && elm.lon != null) {
con.query(
mysqlQuery,
[
"TTN Community " + elm.title,
"",
getModuleMeta().exactName,
elm.lat,
elm.lon,
0,
"https://www.thethingsnetwork.org" + elm.path,
],
function (err, result) {
if (err) {
throw err;
}
}
);
}
}
console.log("[TheThingsnetwork Communities] Insert into Database done!");
}, function(err){
console.warn("[" + getModuleMeta().title + "] Was unable to resolve request with error: " + err)
});
}
function queryData(boundNorthEastLatLng, boundSouthWestLatLng, minimal) {
// Create a new promise to return, DBs are slow.
return new Promise(function (resolve, reject) {
// The Promise constructor should catch any errors thrown on
// this tick. Alternately, try/catch and reject(err) on catch.
let elementsToQuery = "*";
if (minimal) {
elementsToQuery = "id,loc,source_id";
}
// This is taken from https://stackoverflow.com/questions/21208697/select-all-geospatial-points-inside-a-bounding-box
const sqlQuery = " \
SELECT " + elementsToQuery + " \
FROM airspy \
WHERE MBRContains( \
GeomFromText( 'LINESTRING(? ?,? ?)' ), \
loc)";
con.query(sqlQuery, [boundNorthEastLatLng.lat, boundNorthEastLatLng.lng, boundSouthWestLatLng.lat, boundSouthWestLatLng.lng], function (err, rows, fields) {
// Call reject on error states,
// call resolve with results
if (err) {
return reject(err);
}
const results = [];
for (let e = 0; e < rows.length; e++) {
const currentRow = rows[e];
const element = {
type: "general-poi",
source: "ttncomms",
titel: currentRow.name,
description: "This is a TheThingsnetwork Comunity. URL: " + currentRow.link,
url: currentRow.link,
uid: "ttncomms_" + currentRow.id,
location: currentRow.loc,
};
if (minimal) {
const stripableElements = ["title", "description", "url", "type"];
for (h in stripableElements) {
delete element[stripableElements[h]];
}
}
results.push(element);
}
resolve(results);
});
});
}
function queryItem(uid){
const uidParts = uid.split("_");
console.log("[ttncomms] Query item with uid: " + uid + " using id: " + parseInt(uidParts[1]));
const sqlQuery = "SELECT * FROM " + getModuleMeta().exactName + " WHERE id=?"
return new Promise(function (resolve, reject) {
con.query(sqlQuery, [parseInt(uidParts[1])], function (err, rows, fields) {
if (err) {
return reject(err);
}
console.log("[ttncomms] Query done, result: " + rows);
let results = [];
if(rows.length > 0){
for (let e = 0; e < rows.length; e++) {
const currentRow = rows[e];
const element = {
type: "general-poi",
source: "ttncomms",
titel: currentRow.name,
description: "This is a TheThingsnetwork Comunity. URL: " + currentRow.link,
url: currentRow.link,
uid: "ttncomms_" + currentRow.id,
location: {
lat: currentRow.loc_lat,
lng: currentRow.loc_lng,
},
};
results.push(element);
}
}/*else{
results = [{
type: "general-poi",
source: "ttncomms",
titel: "Invalid",
description: "This is broken. Something is broken.",
url: "INVALID",
uid: uid,
location: {
lat: 0,
lng: 0,
},
}];
}*/
resolve(results)
});
});
}
function getModuleMeta() {
return {
title: "TheThingsnetwork Communities",
exactName: "ttncomms",
country: ["*"],
limited: false,
};
}
module.exports = { initialize, queryData, getModuleMeta, queryItem };