318 lines
10 KiB
JavaScript
318 lines
10 KiB
JavaScript
|
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 };
|