Socket
Socket
Sign inDemoInstall

yr.no-forecast

Package Overview
Dependencies
27
Maintainers
1
Versions
12
Alerts
File Explorer

Advanced tools

Install Socket

Detect and block malicious and high-risk dependencies

Install

Comparing version 0.0.3 to 0.0.4

LICENSE

161

index.js

@@ -24,66 +24,8 @@ // Copyright 2013 Evan Shortiss

// Could do with improving, see schema for api.
var DETAILED_FIELDS = [{
tagname: 'temperature',
id: 'TTT',
valueSelector: 'value',
name: 'temperature'
}, {
tagname: 'windSpeed',
id: 'ff',
valueSelector: 'mps',
name: 'windSpeed'
}, {
tagname: 'windSpeed',
valueSelector: 'beaufort',
name: 'beaufort',
id: 'ff'
}, {
tagname: 'windDirection',
name: 'windBearing',
id: 'dd',
valueSelector: 'deg'
}, {
tagname: 'cloudiness',
name: 'cloudCover',
id: 'NN',
valueSelector: 'percent'
}, {
tagname: 'humidity',
name: 'humidity',
id: '',
valueSelector: 'value'
}, {
tagname: 'pressure',
name: 'pressure',
id: 'pr',
valueSelector: 'value'
}, {
tagname: 'dewpointTemperature',
id: 'TD',
name: 'dewpointTemperature',
valueSelector: 'value'
}, {
tagname: 'fog',
id: 'FOG',
valueSelector: 'percent',
name: 'fog',
}, {
tagname: 'highClouds',
id: 'HIGH',
name: 'highClouds',
valueSelector: 'percent'
}, {
tagname: 'mediumClouds',
id: 'MEDIUM',
name: 'mediumClouds',
valueSelector: 'percent'
}, {
tagname: 'lowClouds',
id: 'LOW',
name: 'lowClouds',
valueSelector: 'percent'
}];
/**
* @constructor
* @param {String} xml
* @param {Function} callback
*/
function LocationForecast(xml, callback) {

@@ -112,6 +54,3 @@ this.xml = xml;

var self = this;
var json = this.json;
var current = json['weatherdata']['product']['time'][0];
current.symbol = json['weatherdata']['product']['time'][1]['symbol'];

@@ -157,2 +96,3 @@ async.forEach(json['weatherdata']['product']['time'], function(time, cb) {

var curDate = moment.utc().hours(12);
curDate.set('minutes', 0);

@@ -182,3 +122,3 @@ // Create 5 days of dates

}
return callback(null, res);

@@ -204,15 +144,8 @@ });

if (!basic) {
return callback('No weather basic for time ' + time.toJSON(), null);
return callback(null, {});
}
var res = {
icon: basic['location']['symbol']['id'],
to: basic['to'],
from: basic['from'],
rain: (basic['location']['precipitation']['value'] + ' ' + basic['location']['precipitation']['unit'])
};
getDetailForTime(time, self.detail, function(err, detail) {
if (detail) {
return callback(null, buildDetail(detail, res));
return callback(null, buildDetail(detail, basic));
}

@@ -241,3 +174,3 @@ return callback(null, res);

function buildDetail(detail, obj) {
function buildDetail(detail, basic) {
// <location altitude="48" latitude="59.3758" longitude="10.7814">

@@ -257,15 +190,32 @@ // <temperature id="TTT" unit="celcius" value="6.3"/>

var obj = {
icon: basic['location']['symbol']['id'],
to: basic['to'],
from: basic['from'],
rain: (basic['location']['precipitation']['value'] + ' ' + basic['location']['precipitation']['unit'])
};
// Corresponds to XML 'location' element
var location = detail.location;
var cur = null;
for (var key in location) {
cur = location[key];
DETAILED_FIELDS.forEach(function(field) {
var item = location[field.tagname];
// If the field exists, add it and it's value to the object
if (item) {
obj[field.name] = location[field.tagname][field.valueSelector];
} else {
obj[field.name] = null;
// Based on field type build the response
// Type 1: Has "value" and "unit", combine for result
// Type 2: Has only "percent"
// Type 3: Has multiple properties where the name is the value
if (cur.hasOwnProperty('value')) {
obj[key] = cur['value'] + ' ' + cur['unit'];
} else if (cur.hasOwnProperty('percent')) {
obj[key] = cur['percent'] + '%';
} else if (typeof cur === 'object') {
obj[key] = {};
for (var nestedKey in cur) {
if (nestedKey != 'id') {
obj[key][nestedKey] = cur[nestedKey];
}
}
}
});
}

@@ -297,2 +247,32 @@ return obj;

/**
* Used when no matching element is found for a time of a day.
* @param {Date} time
* @param {Array} collection
* @param {Function} callback
*/
function fallbackSelector(time, collection, callback) {
time = moment(time);
// Find out is time before or after collection range
var isBefore = false;
async.each(collection, function(item, cb) {
if(time.isBefore(moment(item.to))) {
isBefore = true;
return cb(true);
}
cb();
}, function() {
// Take earlist time possbile
if(isBefore == true) {
return callback(null, collection[0]);
}
// Take latest time possible
return callback(null, collection[collection.length-1]);
});
}
/**
* Get detailed items for a time.

@@ -323,2 +303,6 @@ * Find nearest hour on same day, or no result.

}, function() {
if(res == null) {
return fallbackSelector(date, detail, callback);
}
return callback(null, res);

@@ -329,2 +313,3 @@ });

/**

@@ -365,2 +350,6 @@ * Get basic items for a time.

}, function() {
if(res == null) {
return fallbackSelector(date, basic, callback);
}
return callback(null, res);

@@ -367,0 +356,0 @@ });

{
"name": "yr.no-forecast",
"version": "0.0.3",
"version": "0.0.4",
"description": "Module to easily retrieve simple weather forecast for a given time and location.",

@@ -15,2 +15,3 @@ "main": "./index.js",

},
"license": "MIT",
"repository": {

@@ -17,0 +18,0 @@ "type": "git",

@@ -8,3 +8,3 @@ yr.no-forecast

###Usage
Use the ```getWeather(queryStringParams, callback|stream, [VERSION])``` function to get a LocationForecast object. This object has functions that take a callback as parameter and are detailed in the example below.
Use the ```getWeather(queryStringParams, callback|stream, [VERSION])``` function to get a LocationForecast object, where version represents the version of the "locationforecast" service to use. This object has functions that take a callback as parameter and are detailed in the example below.

@@ -26,21 +26,23 @@ ```

### Weather JSON Format
Format is inspired by that of [forecast.io](https://developer.forecast.io/) service. Not all fields will always be available. Fields that no data was retrieved for contain the null value;
Format is somewhat inspired by that of [forecast.io](https://developer.forecast.io/) service. Not all fields will always be available. Fields that no data was retrieved for contain the null value;
```
{
icon: 'PARTLYCLOUD',
to: '2013-11-08T14:00:00Z',
from: '2013-11-08T13:00:00Z',
{
icon: 'PARTLYCLOUD',
to: '2013-11-15T18:00:00Z',
from: '2013-11-15T12:00:00Z',
rain: '0.0 mm',
temperature: '10.0',
windSpeed: '5.0m/s',
windBearing: '188.3',
beaufort: '3',
cloudCover: '77.0',
humidity: '80.6%',
pressure: '1006.3 hPa'
lowCloud: null,
highCloud: null
temperature: '9.7 celcius',
windDirection: { deg: '220.2', name: 'SW' },
windSpeed: { mps: '2.7', beaufort: '2', name: 'Svak vind' },
humidity: '27.9 percent',
pressure: '1021.0 hPa',
cloudiness: '0.0%',
fog: '0.0%',
lowClouds: '0.0%',
mediumClouds: '0.0%',
highClouds: '0.0%',
dewpointTemperature: '-8.3 celcius',
...
}
```
var assert = require('assert'),
moment = require('moment'),
lib = require('../index.js');

@@ -34,3 +35,3 @@

it('Should return an object with LocationForecast methods', function(done) {
it('getWeather: Should return an object with LocationForecast methods', function(done) {
lib.getWeather(LOCATIONS.DUBLIN, function(err, weather) {

@@ -46,3 +47,3 @@ assert(!err);

it('Should return array with 5 weather objects', function(done) {
it('getFiveDaySummary: Should return array with 5 weather objects', function(done) {
lib.getWeather(LOCATIONS.DUBLIN, function(err, weather) {

@@ -61,3 +62,3 @@ assert(!err);

it('Should return array with 5 weather objects', function(done) {
it('getFiveDaySummary: Should return array with 5 weather objects', function(done) {
lib.getWeather(LOCATIONS.NICE, function(err, weather) {

@@ -74,3 +75,3 @@ weather.getFiveDaySummary(function(err, summary) {

it('Should return array with 5 weather objects', function(done) {
it('getFiveDaySummary: Should return array with 5 weather objects', function(done) {
lib.getWeather(LOCATIONS.LA, function(err, weather) {

@@ -87,3 +88,3 @@ weather.getFiveDaySummary(function(err, summary) {

it('Should return array with 5 weather objects', function(done) {
it('getFiveDaySummary: Should return array with 5 weather objects', function(done) {
lib.getWeather(LOCATIONS.RYGGE, function(err, weather) {

@@ -100,3 +101,3 @@ weather.getFiveDaySummary(function(err, summary) {

it('Should return an object with info fields', function(done) {
it('getCurrentSummary: Should return an object with info fields', function(done) {
lib.getWeather(LOCATIONS.DUBLIN, function(err, weather) {

@@ -113,3 +114,3 @@ weather.getCurrentSummary(function(err, summary) {

it('Should return an object with info fields', function(done) {
it('getCurrentSummary: Should return an object with info fields', function(done) {
lib.getWeather(LOCATIONS.LA, function(err, weather) {

@@ -126,3 +127,3 @@ weather.getCurrentSummary(function(err, summary) {

it('Should return an object with info fields', function(done) {
it('getCurrentSummary: Should return an object with info fields', function(done) {
lib.getWeather(LOCATIONS.NICE, function(err, weather) {

@@ -139,3 +140,3 @@ weather.getCurrentSummary(function(err, summary) {

it('Should return an object with info fields', function(done) {
it('getCurrentSummary: Should return an object with info fields', function(done) {
lib.getWeather(LOCATIONS.RYGGE, function(err, weather) {

@@ -150,2 +151,36 @@ weather.getCurrentSummary(function(err, summary) {

});
});
});
describe('Test retrieval for various times', function() {
this.timeout(10000);
it('Should get weather for earliest time possible today by requesting some time yesterday', function(done) {
var time = moment();
time.set('hours', (time.hours() - time.hours() - 4) );
lib.getWeather(LOCATIONS.DUBLIN, function(err, weather) {
assert(!err);
assert(weather);
weather.getForecastForTime(time, function(err, forecast) {
assert(!err);
assert(forecast);
done();
});
});
});
it('Should get weather for 9:20 PM (21:20) tonight', function(done) {
var time = moment();
time.set('hours', 21);
time.set('minutes', 20);
lib.getWeather(LOCATIONS.DUBLIN, function(err, weather) {
assert(!err);
assert(weather);
weather.getForecastForTime(time, function(err, forecast) {
assert(!err);
assert(forecast);
done();
});
});
});
})
SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc