UNPKG

weather-js

Version:

A module for obtaining weather information

124 lines (99 loc) 4.89 kB
/* * Weather * For the full copyright and license information, please view the LICENSE.txt file. */ /* jslint node: true, sub: true */ 'use strict'; var request = require('request'), qs = require('querystring'), xml2JS = require('xml2js'); // Init the module module.exports = (function() { var xmlParser = new xml2JS.Parser({charkey: 'C$', attrkey: 'A$', explicitArray: true}), defLang = 'en-US', defDegreeType = 'F', defTimeout = 10000, findUrl = 'http://weather.service.msn.com/find.aspx'; var find = function find(options, callback) { if(typeof callback !== 'function') callback = function callback(err, result) { return err || result; }; if(!options || typeof options !== 'object') return callback('invalid options'); if(!options.search) return callback('missing search input'); var result = [], lang = options.lang || defLang, degreeType = options.degreeType || defDegreeType, timeout = options.timeout || defTimeout, search = qs.escape(''+options.search), reqUrl = findUrl + '?src=outlook&weadegreetype=' + (''+degreeType) + '&culture=' + (''+lang) + '&weasearchstr=' + search; request.get({url: reqUrl, timeout: timeout}, function(err, res, body) { if(err) return callback(err); if(res.statusCode !== 200) return callback(new Error('request failed (' + res.statusCode + ')')); if(!body) return callback(new Error('failed to get body content')); // Check body content if(body.indexOf('<') !== 0) { if(body.search(/not found/i) !== -1) { return callback(null, result); } return callback(new Error('invalid body content')); } // Parse body xmlParser.parseString(body, function(err, resultJSON) { if(err) return callback(err); if(!resultJSON || !resultJSON.weatherdata || !resultJSON.weatherdata.weather) return callback(new Error('failed to parse weather data')); if(resultJSON.weatherdata.weather['A$'] && resultJSON.weatherdata.weather['A$'].errormessage) return callback(resultJSON.weatherdata.weather['A$'].errormessage); if(!(resultJSON.weatherdata.weather instanceof Array)) { return callback(new Error('missing weather info')); } // Iterate over weather data var weatherLen = resultJSON.weatherdata.weather.length, weatherItem; for(var i = 0; i < weatherLen; i++) { if(typeof resultJSON.weatherdata.weather[i]['A$'] !== 'object') continue; // Init weather item weatherItem = { location: { name: resultJSON.weatherdata.weather[i]['A$']['weatherlocationname'], zipcode: resultJSON.weatherdata.weather[i]['A$']['zipcode'], lat: resultJSON.weatherdata.weather[i]['A$']['lat'], long: resultJSON.weatherdata.weather[i]['A$']['long'], timezone: resultJSON.weatherdata.weather[i]['A$']['timezone'], alert: resultJSON.weatherdata.weather[i]['A$']['alert'], degreetype: resultJSON.weatherdata.weather[i]['A$']['degreetype'], imagerelativeurl: resultJSON.weatherdata.weather[i]['A$']['imagerelativeurl'] //url: resultJSON.weatherdata.weather[i]['A$']['url'], //code: resultJSON.weatherdata.weather[i]['A$']['weatherlocationcode'], //entityid: resultJSON.weatherdata.weather[i]['A$']['entityid'], //encodedlocationname: resultJSON.weatherdata.weather[i]['A$']['encodedlocationname'] }, current: null, forecast: null }; if(resultJSON.weatherdata.weather[i]['current'] instanceof Array && resultJSON.weatherdata.weather[i]['current'].length > 0) { if(typeof resultJSON.weatherdata.weather[i]['current'][0]['A$'] === 'object') { weatherItem.current = resultJSON.weatherdata.weather[i]['current'][0]['A$']; weatherItem.current.imageUrl = weatherItem.location.imagerelativeurl + 'law/' + weatherItem.current.skycode + '.gif'; } } if(resultJSON.weatherdata.weather[i]['forecast'] instanceof Array) { weatherItem.forecast = []; for(var k = 0; k < resultJSON.weatherdata.weather[i]['forecast'].length; k++) { if(typeof resultJSON.weatherdata.weather[i]['forecast'][k]['A$'] === 'object') weatherItem.forecast.push(resultJSON.weatherdata.weather[i]['forecast'][k]['A$']); } } // Push weather item into result result.push(weatherItem); } return callback(null, result); }); }); }; return { find: find }; })();