Update getData and httpRequest to modern TypeScript
This commit is contained in:
@@ -14,42 +14,46 @@ var http = require( "http" ),
|
|||||||
|
|
||||||
// If location does not match GPS or PWS/ICAO, then attempt to resolve
|
// If location does not match GPS or PWS/ICAO, then attempt to resolve
|
||||||
// location using Weather Underground autocomplete API
|
// location using Weather Underground autocomplete API
|
||||||
function resolveCoordinates( location, callback ) {
|
async function resolveCoordinates( location, callback ) {
|
||||||
|
|
||||||
// Generate URL for autocomplete request
|
// Generate URL for autocomplete request
|
||||||
var url = "http://autocomplete.wunderground.com/aq?h=0&query=" +
|
var url = "http://autocomplete.wunderground.com/aq?h=0&query=" +
|
||||||
encodeURIComponent( location );
|
encodeURIComponent( location );
|
||||||
|
|
||||||
httpRequest( url, function( data ) {
|
let data;
|
||||||
|
try {
|
||||||
|
data = await getData( url );
|
||||||
|
} catch (err) {
|
||||||
|
// If the request fails, indicate no data was found.
|
||||||
|
callback( false );
|
||||||
|
}
|
||||||
|
|
||||||
// Parse the reply for JSON data
|
// Check if the data is valid
|
||||||
data = JSON.parse( data );
|
if ( typeof data.RESULTS === "object" && data.RESULTS.length && data.RESULTS[ 0 ].tz !== "MISSING" ) {
|
||||||
|
|
||||||
// Check if the data is valid
|
// If it is, reply with an array containing the GPS coordinates
|
||||||
if ( typeof data.RESULTS === "object" && data.RESULTS.length && data.RESULTS[ 0 ].tz !== "MISSING" ) {
|
callback( [ data.RESULTS[ 0 ].lat, data.RESULTS[ 0 ].lon ], moment().tz( data.RESULTS[ 0 ].tz ).utcOffset() );
|
||||||
|
} else {
|
||||||
|
|
||||||
// If it is, reply with an array containing the GPS coordinates
|
// Otherwise, indicate no data was found
|
||||||
callback( [ data.RESULTS[ 0 ].lat, data.RESULTS[ 0 ].lon ], moment().tz( data.RESULTS[ 0 ].tz ).utcOffset() );
|
callback( false );
|
||||||
} else {
|
}
|
||||||
|
|
||||||
// Otherwise, indicate no data was found
|
|
||||||
callback( false );
|
|
||||||
}
|
|
||||||
} );
|
|
||||||
}
|
}
|
||||||
|
|
||||||
function getData( url, callback ) {
|
/**
|
||||||
|
* Makes an HTTP GET request to the specified URL and parses the JSON response body.
|
||||||
httpRequest( url, function( data ) {
|
* @param url The URL to fetch.
|
||||||
try {
|
* @return A Promise that will be resolved the with parsed response body if the request succeeds, or will be rejected
|
||||||
data = JSON.parse( data );
|
* with an Error if the request or JSON parsing fails.
|
||||||
} catch (err) {
|
*/
|
||||||
callback( {} );
|
async function getData( url: string ): Promise< any > {
|
||||||
return;
|
try {
|
||||||
}
|
const data: string = await httpRequest(url);
|
||||||
callback( data );
|
return JSON.parse(data);
|
||||||
return;
|
} catch (err) {
|
||||||
} );
|
// Reject the promise if there was an error making the request or parsing the JSON.
|
||||||
|
throw err;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Retrieve data from Open Weather Map for water level calculations
|
// Retrieve data from Open Weather Map for water level calculations
|
||||||
@@ -57,34 +61,41 @@ function getOWMWateringData( location, callback ) {
|
|||||||
var OWM_API_KEY = process.env.OWM_API_KEY,
|
var OWM_API_KEY = process.env.OWM_API_KEY,
|
||||||
forecastUrl = "http://api.openweathermap.org/data/2.5/forecast?appid=" + OWM_API_KEY + "&units=imperial&lat=" + location[ 0 ] + "&lon=" + location[ 1 ];
|
forecastUrl = "http://api.openweathermap.org/data/2.5/forecast?appid=" + OWM_API_KEY + "&units=imperial&lat=" + location[ 0 ] + "&lon=" + location[ 1 ];
|
||||||
|
|
||||||
getTimeData( location, function( weather ) {
|
getTimeData( location, async function( weather ) {
|
||||||
|
|
||||||
// Perform the HTTP request to retrieve the weather data
|
// Perform the HTTP request to retrieve the weather data
|
||||||
getData( forecastUrl, function( forecast ) {
|
let forecast;
|
||||||
|
try {
|
||||||
if ( !forecast || !forecast.list ) {
|
forecast = await getData( forecastUrl );
|
||||||
callback( weather );
|
} catch (err) {
|
||||||
return;
|
// Return just the time data if retrieving the forecast fails.
|
||||||
}
|
|
||||||
|
|
||||||
weather.temp = 0;
|
|
||||||
weather.humidity = 0;
|
|
||||||
weather.precip = 0;
|
|
||||||
|
|
||||||
var periods = Math.min(forecast.list.length, 10);
|
|
||||||
for ( var index = 0; index < periods; index++ ) {
|
|
||||||
weather.temp += parseFloat( forecast.list[ index ].main.temp );
|
|
||||||
weather.humidity += parseInt( forecast.list[ index ].main.humidity );
|
|
||||||
weather.precip += ( forecast.list[ index ].rain ? parseFloat( forecast.list[ index ].rain[ "3h" ] || 0 ) : 0 );
|
|
||||||
}
|
|
||||||
|
|
||||||
weather.temp = weather.temp / periods;
|
|
||||||
weather.humidity = weather.humidity / periods;
|
|
||||||
weather.precip = weather.precip / 25.4;
|
|
||||||
weather.raining = ( forecast.list[ 0 ].rain ? ( parseFloat( forecast.list[ 0 ].rain[ "3h" ] || 0 ) > 0 ) : false );
|
|
||||||
|
|
||||||
callback( weather );
|
callback( weather );
|
||||||
} );
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Return just the time data if the forecast data is incomplete.
|
||||||
|
if ( !forecast || !forecast.list ) {
|
||||||
|
callback( weather );
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
weather.temp = 0;
|
||||||
|
weather.humidity = 0;
|
||||||
|
weather.precip = 0;
|
||||||
|
|
||||||
|
var periods = Math.min(forecast.list.length, 10);
|
||||||
|
for ( var index = 0; index < periods; index++ ) {
|
||||||
|
weather.temp += parseFloat( forecast.list[ index ].main.temp );
|
||||||
|
weather.humidity += parseInt( forecast.list[ index ].main.humidity );
|
||||||
|
weather.precip += ( forecast.list[ index ].rain ? parseFloat( forecast.list[ index ].rain[ "3h" ] || 0 ) : 0 );
|
||||||
|
}
|
||||||
|
|
||||||
|
weather.temp = weather.temp / periods;
|
||||||
|
weather.humidity = weather.humidity / periods;
|
||||||
|
weather.precip = weather.precip / 25.4;
|
||||||
|
weather.raining = ( forecast.list[ 0 ].rain ? ( parseFloat( forecast.list[ 0 ].rain[ "3h" ] || 0 ) > 0 ) : false );
|
||||||
|
|
||||||
|
callback( weather );
|
||||||
} );
|
} );
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -94,43 +105,48 @@ function getOWMWeatherData( location, callback ) {
|
|||||||
currentUrl = "http://api.openweathermap.org/data/2.5/weather?appid=" + OWM_API_KEY + "&units=imperial&lat=" + location[ 0 ] + "&lon=" + location[ 1 ],
|
currentUrl = "http://api.openweathermap.org/data/2.5/weather?appid=" + OWM_API_KEY + "&units=imperial&lat=" + location[ 0 ] + "&lon=" + location[ 1 ],
|
||||||
forecastDailyUrl = "http://api.openweathermap.org/data/2.5/forecast/daily?appid=" + OWM_API_KEY + "&units=imperial&lat=" + location[ 0 ] + "&lon=" + location[ 1 ];
|
forecastDailyUrl = "http://api.openweathermap.org/data/2.5/forecast/daily?appid=" + OWM_API_KEY + "&units=imperial&lat=" + location[ 0 ] + "&lon=" + location[ 1 ];
|
||||||
|
|
||||||
getTimeData( location, function( weather ) {
|
getTimeData( location, async function( weather ) {
|
||||||
|
|
||||||
getData( currentUrl, function( current ) {
|
let current, forecast;
|
||||||
|
try {
|
||||||
|
current = await getData( currentUrl );
|
||||||
|
forecast = await getData( forecastDailyUrl );
|
||||||
|
} catch (err) {
|
||||||
|
// Return just the time data if retrieving weather data fails.
|
||||||
|
callback( weather );
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
getData( forecastDailyUrl, function( forecast ) {
|
// Return just the time data if the weather data is incomplete.
|
||||||
|
if ( !current || !current.main || !current.wind || !current.weather || !forecast || !forecast.list ) {
|
||||||
|
callback( weather );
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
if ( !current || !current.main || !current.wind || !current.weather || !forecast || !forecast.list ) {
|
weather.temp = parseInt( current.main.temp );
|
||||||
callback( weather );
|
weather.humidity = parseInt( current.main.humidity );
|
||||||
return;
|
weather.wind = parseInt( current.wind.speed );
|
||||||
}
|
weather.description = current.weather[0].description;
|
||||||
|
weather.icon = current.weather[0].icon;
|
||||||
|
|
||||||
weather.temp = parseInt( current.main.temp );
|
weather.region = forecast.city.country;
|
||||||
weather.humidity = parseInt( current.main.humidity );
|
weather.city = forecast.city.name;
|
||||||
weather.wind = parseInt( current.wind.speed );
|
weather.minTemp = parseInt( forecast.list[ 0 ].temp.min );
|
||||||
weather.description = current.weather[0].description;
|
weather.maxTemp = parseInt( forecast.list[ 0 ].temp.max );
|
||||||
weather.icon = current.weather[0].icon;
|
weather.precip = ( forecast.list[ 0 ].rain ? parseFloat( forecast.list[ 0 ].rain || 0 ) : 0 ) / 25.4;
|
||||||
|
weather.forecast = [];
|
||||||
|
|
||||||
weather.region = forecast.city.country;
|
for ( var index = 0; index < forecast.list.length; index++ ) {
|
||||||
weather.city = forecast.city.name;
|
weather.forecast.push( {
|
||||||
weather.minTemp = parseInt( forecast.list[ 0 ].temp.min );
|
temp_min: parseInt( forecast.list[ index ].temp.min ),
|
||||||
weather.maxTemp = parseInt( forecast.list[ 0 ].temp.max );
|
temp_max: parseInt( forecast.list[ index ].temp.max ),
|
||||||
weather.precip = ( forecast.list[ 0 ].rain ? parseFloat( forecast.list[ 0 ].rain || 0 ) : 0 ) / 25.4;
|
date: parseInt( forecast.list[ index ].dt ),
|
||||||
weather.forecast = [];
|
icon: forecast.list[ index ].weather[ 0 ].icon,
|
||||||
|
description: forecast.list[ index ].weather[ 0 ].description
|
||||||
for ( var index = 0; index < forecast.list.length; index++ ) {
|
|
||||||
weather.forecast.push( {
|
|
||||||
temp_min: parseInt( forecast.list[ index ].temp.min ),
|
|
||||||
temp_max: parseInt( forecast.list[ index ].temp.max ),
|
|
||||||
date: parseInt( forecast.list[ index ].dt ),
|
|
||||||
icon: forecast.list[ index ].weather[ 0 ].icon,
|
|
||||||
description: forecast.list[ index ].weather[ 0 ].description
|
|
||||||
} );
|
|
||||||
}
|
|
||||||
|
|
||||||
callback( weather );
|
|
||||||
} );
|
} );
|
||||||
} );
|
}
|
||||||
|
|
||||||
|
callback( weather );
|
||||||
} );
|
} );
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -386,33 +402,40 @@ exports.getWateringData = function( req, res ) {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
// Generic HTTP request handler that parses the URL and uses the
|
/**
|
||||||
// native Node.js http module to perform the request
|
* Makes an HTTP GET request to the specified URL and returns the response body.
|
||||||
function httpRequest( url, callback ) {
|
* @param url The URL to fetch.
|
||||||
url = url.match( filters.url );
|
* @return A Promise that will be resolved the with response body if the request succeeds, or will be rejected with an
|
||||||
|
* Error if the request fails.
|
||||||
|
*/
|
||||||
|
async function httpRequest( url: string ): Promise< string > {
|
||||||
|
return new Promise< any >( ( resolve, reject ) => {
|
||||||
|
|
||||||
var options = {
|
const splitUrl: string[] = url.match( filters.url );
|
||||||
host: url[ 1 ],
|
|
||||||
port: url[ 2 ] || 80,
|
|
||||||
path: url[ 3 ]
|
|
||||||
};
|
|
||||||
|
|
||||||
http.get( options, function( response ) {
|
const options = {
|
||||||
var data = "";
|
host: splitUrl[ 1 ],
|
||||||
|
port: splitUrl[ 2 ] || 80,
|
||||||
|
path: splitUrl[ 3 ]
|
||||||
|
};
|
||||||
|
|
||||||
// Reassemble the data as it comes in
|
http.get( options, ( response ) => {
|
||||||
response.on( "data", function( chunk ) {
|
let data = "";
|
||||||
data += chunk;
|
|
||||||
} );
|
|
||||||
|
|
||||||
// Once the data is completely received, return it to the callback
|
// Reassemble the data as it comes in
|
||||||
response.on( "end", function() {
|
response.on( "data", ( chunk ) => {
|
||||||
callback( data );
|
data += chunk;
|
||||||
} );
|
} );
|
||||||
} ).on( "error", function() {
|
|
||||||
|
|
||||||
// If the HTTP request fails, return false
|
// Once the data is completely received, resolve the promise
|
||||||
callback( false );
|
response.on( "end", () => {
|
||||||
|
resolve( data );
|
||||||
|
} );
|
||||||
|
} ).on( "error", ( err ) => {
|
||||||
|
|
||||||
|
// If the HTTP request fails, reject the promise
|
||||||
|
reject( err );
|
||||||
|
} );
|
||||||
} );
|
} );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user