├── README.md ├── openweather.coffee ├── openweather.js └── package.json /README.md: -------------------------------------------------------------------------------- 1 | node-openweathermap 2 | =================== 3 | 4 | A small abstraction layer for the openweathermap API 5 | 6 | ### install 7 | 8 | $ npm install openweathermap 9 | 10 | ### methods 11 | 12 | # set defaults 13 | defaults(cfg) 14 | 15 | # return the weather right now 16 | now(cfg, callback) 17 | 18 | # get a 7 days every 3h forecast 19 | forecast(cfg, callback) 20 | 21 | # get up to 14 days daily forecast 22 | # cfg 23 | # cnt:int(number of days for forecast) 24 | daily(cfg, callback) 25 | 26 | # get history for a city 27 | history(cfg, callback) 28 | 29 | # find 30 | # cnt, beginns from 0, cnt 0 returns 1 item, cnt 1 returns 2 items 31 | find(cfg, callback) 32 | 33 | ### (defaults) 34 | 35 | units: ('metric'|'imperial'|'internal') 36 | lang: ('en'|'ru'|'it'|'sp'|'ua'|'de'|'pt'|'ro'|'pl'|'fi'|'nl'|'fr'|'bg'|'se'|'zh_tw'|zh_cn') 37 | mode: 'json' // for now only json support 38 | q: 'City Name e.g. London,UK or Berlin,Germany' 39 | cnt: Number(forecast:number of days, find: 0..) 40 | id: Number(city id) 41 | 42 | # history 43 | type: ('tick'|'hour'|'day') 44 | start: Number(unix timestamp) 45 | end: Number(unix timestamp) 46 | cnt: Number(list count) 47 | 48 | attribute \ function | defaults | now | daily | history | find | forecast 49 | --------------------:|:--------:|:---:|:-----:|:-------:|:----:|:--------: 50 | q | x | x | x | - | x | x 51 | id | x | x | x | x | - | x 52 | cnt | x | - | x | x | x | - 53 | start | x | - | - | x | - | - 54 | end | x | - | - | x | - | - 55 | units | x | x | x | x | x | x 56 | 57 | ### opts 58 | 59 | weather.ops({port:8080}) 60 | 61 | sets the port to 8080 for all following requests. The opts method is chainable. 62 | Generally you can set all http.get [Node.js options](http://nodejs.org/api/http.html#http_http_request_options_callback). 63 | 64 | ### Examples 65 | 66 | weather = require 'openweathermap' 67 | 68 | # set defaults 69 | weather.defaults {units:'metric', lang:'de', mode:'json'} 70 | 71 | # id is Cologne, Germany 72 | weather.now {id:2886242}, (err, json) -> 73 | console.dir json 74 | 75 | # 2 days forecast 76 | weather.daily {id:2886242, cnt:2}, (err, json) -> 77 | console.dir json 78 | 79 | # history for 3 hours 80 | weather.history {type:'hour', id:2886242, cnt:3}, (err, json) -> 81 | console.dir json 82 | 83 | # find 3 berlins 84 | weather.find {q:'berlin', cnt:2}, (err, json) -> 85 | console.dir json 86 | 87 | # forecast for Okemos, MI 88 | weather.forecast {id: 5004359}, (err, json) -> 89 | console.dir json 90 | 91 | more infos about openweathermap.org at 92 | 93 | ### changelog 94 | 95 | #### 1.0.0 96 | * added error handling: Use node.js style Error-First Callbacks #5 (many thanks to @sweetpi) 97 | * release v1.0.0 98 | * release npm v1.0.0 99 | 100 | #### 0.2.1 101 | * fixes issue #4 bug: Return invalid json 102 | 103 | #### 0.2.0 104 | * node-openweathermap is now browserifiable, #2 (many thanks to @MikkoH) 105 | * set http options via opts() eg. port ... 106 | 107 | #### 0.1.1 108 | * fixed #1 109 | * resonse now in flow mode 110 | * use 111 | 112 | #### 0.0.3 113 | * added city history 114 | 115 | #### 0.0.2 116 | * added find 117 | 118 | #### 0.0.1 119 | * inital release 120 | -------------------------------------------------------------------------------- /openweather.coffee: -------------------------------------------------------------------------------- 1 | 2 | http = require 'http' 3 | opts = hostname:'api.openweathermap.org', port: 80, withCredentials: false 4 | imgPath = 'http://openweathermap.org/img/w/' 5 | def = '' 6 | 7 | exports.defaults = (cfg) -> 8 | objs = [] 9 | objs.push "#{i}=#{n}" for i,n of cfg 10 | def = objs.join '&' 11 | 12 | exports.opts = (optsIn = {}) -> 13 | opts[i] = optsIn[i] for i,n of optsIn 14 | this 15 | 16 | 17 | exports.find = (cfg, cb) -> 18 | opts.path = "/data/2.5/find?#{buildPath(cfg)}" 19 | 20 | getWeather opts, (err, json) -> 21 | return cb(err) if err? 22 | item.weather[0].iconUrl = "#{imgPath}#{item.weather[0].icon}.png" for item in json.list 23 | cb null, json 24 | 25 | 26 | exports.now = (cfg, cb) -> 27 | opts.path = "/data/2.5/weather?#{buildPath(cfg)}" 28 | 29 | getWeather opts, (err, json) -> 30 | return cb(err) if err? 31 | json.weather[0].iconUrl = "#{imgPath}#{json.weather[0].icon}.png" if 200 is Number json.cod 32 | cb null, json 33 | 34 | 35 | exports.forecast = (cfg, cb) -> 36 | opts.path = "/data/2.5/forecast?#{buildPath(cfg)}" 37 | 38 | getWeather opts, (err, json) -> 39 | return cb(err) if err? 40 | item.weather[0].iconUrl = "#{imgPath}#{item.weather[0].icon}.png" for item in json.list 41 | cb null, json 42 | 43 | 44 | exports.daily = (cfg, cb) -> 45 | opts.path = "/data/2.5/forecast/daily?#{buildPath(cfg)}" 46 | 47 | getWeather opts, (err, json) -> 48 | return cb(err) if err? 49 | item.weather[0].iconUrl = "#{imgPath}#{item.weather[0].icon}.png" for item in json.list 50 | cb null, json 51 | 52 | 53 | exports.history = (cfg, cb) -> 54 | opts.path = "/data/2.5/history/city?#{buildPath(cfg)}" 55 | 56 | getWeather opts, (err, json) -> 57 | return cb(err) if err? 58 | item.weather[0].iconUrl = "#{imgPath}#{item.weather[0].icon}.png" for item in json.list 59 | cb null, json 60 | 61 | 62 | buildPath = (cfg) -> 63 | objs = [] 64 | objs.push "#{i}=#{n}" for i,n of cfg 65 | 66 | return "#{def}&#{objs.join('&')}" 67 | 68 | 69 | getWeather = (opts, cb) -> 70 | http.get opts, (res) -> 71 | buffer = '' 72 | 73 | res.on 'data', (data) -> buffer += data 74 | res.on 'error', (error) -> cb(error) 75 | res.on 'end', () -> 76 | try json = JSON.parse buffer catch error then return cb(error) 77 | json.list = [] if ! json.list? 78 | cb null, json 79 | -------------------------------------------------------------------------------- /openweather.js: -------------------------------------------------------------------------------- 1 | // Generated by CoffeeScript 1.9.1 2 | (function() { 3 | var buildPath, def, getWeather, http, imgPath, opts; 4 | 5 | http = require('http'); 6 | 7 | opts = { 8 | hostname: 'api.openweathermap.org', 9 | port: 80, 10 | withCredentials: false 11 | }; 12 | 13 | imgPath = 'http://openweathermap.org/img/w/'; 14 | 15 | def = ''; 16 | 17 | exports.defaults = function(cfg) { 18 | var i, n, objs; 19 | objs = []; 20 | for (i in cfg) { 21 | n = cfg[i]; 22 | objs.push(i + "=" + n); 23 | } 24 | return def = objs.join('&'); 25 | }; 26 | 27 | exports.opts = function(optsIn) { 28 | var i, n; 29 | if (optsIn == null) { 30 | optsIn = {}; 31 | } 32 | for (i in optsIn) { 33 | n = optsIn[i]; 34 | opts[i] = optsIn[i]; 35 | } 36 | return this; 37 | }; 38 | 39 | exports.find = function(cfg, cb) { 40 | opts.path = "/data/2.5/find?" + (buildPath(cfg)); 41 | return getWeather(opts, function(err, json) { 42 | var item, j, len, ref; 43 | if (err != null) { 44 | return cb(err); 45 | } 46 | ref = json.list; 47 | for (j = 0, len = ref.length; j < len; j++) { 48 | item = ref[j]; 49 | item.weather[0].iconUrl = "" + imgPath + item.weather[0].icon + ".png"; 50 | } 51 | return cb(null, json); 52 | }); 53 | }; 54 | 55 | exports.now = function(cfg, cb) { 56 | opts.path = "/data/2.5/weather?" + (buildPath(cfg)); 57 | return getWeather(opts, function(err, json) { 58 | if (err != null) { 59 | return cb(err); 60 | } 61 | if (200 === Number(json.cod)) { 62 | json.weather[0].iconUrl = "" + imgPath + json.weather[0].icon + ".png"; 63 | } 64 | return cb(null, json); 65 | }); 66 | }; 67 | 68 | exports.forecast = function(cfg, cb) { 69 | opts.path = "/data/2.5/forecast?" + (buildPath(cfg)); 70 | return getWeather(opts, function(err, json) { 71 | var item, j, len, ref; 72 | if (err != null) { 73 | return cb(err); 74 | } 75 | ref = json.list; 76 | for (j = 0, len = ref.length; j < len; j++) { 77 | item = ref[j]; 78 | item.weather[0].iconUrl = "" + imgPath + item.weather[0].icon + ".png"; 79 | } 80 | return cb(null, json); 81 | }); 82 | }; 83 | 84 | exports.daily = function(cfg, cb) { 85 | opts.path = "/data/2.5/forecast/daily?" + (buildPath(cfg)); 86 | return getWeather(opts, function(err, json) { 87 | var item, j, len, ref; 88 | if (err != null) { 89 | return cb(err); 90 | } 91 | ref = json.list; 92 | for (j = 0, len = ref.length; j < len; j++) { 93 | item = ref[j]; 94 | item.weather[0].iconUrl = "" + imgPath + item.weather[0].icon + ".png"; 95 | } 96 | return cb(null, json); 97 | }); 98 | }; 99 | 100 | exports.history = function(cfg, cb) { 101 | opts.path = "/data/2.5/history/city?" + (buildPath(cfg)); 102 | return getWeather(opts, function(err, json) { 103 | var item, j, len, ref; 104 | if (err != null) { 105 | return cb(err); 106 | } 107 | ref = json.list; 108 | for (j = 0, len = ref.length; j < len; j++) { 109 | item = ref[j]; 110 | item.weather[0].iconUrl = "" + imgPath + item.weather[0].icon + ".png"; 111 | } 112 | return cb(null, json); 113 | }); 114 | }; 115 | 116 | buildPath = function(cfg) { 117 | var i, n, objs; 118 | objs = []; 119 | for (i in cfg) { 120 | n = cfg[i]; 121 | objs.push(i + "=" + n); 122 | } 123 | return def + "&" + (objs.join('&')); 124 | }; 125 | 126 | getWeather = function(opts, cb) { 127 | return http.get(opts, function(res) { 128 | var buffer; 129 | buffer = ''; 130 | res.on('data', function(data) { 131 | return buffer += data; 132 | }); 133 | res.on('error', function(error) { 134 | return cb(error); 135 | }); 136 | return res.on('end', function() { 137 | var error, json; 138 | try { 139 | json = JSON.parse(buffer); 140 | } catch (_error) { 141 | error = _error; 142 | return cb(error); 143 | } 144 | if (json.list == null) { 145 | json.list = []; 146 | } 147 | return cb(null, json); 148 | }); 149 | }); 150 | }; 151 | 152 | }).call(this); 153 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "openweathermap", 3 | "description": "A small abstraction layer for the openweathermap API", 4 | "keywords": [ 5 | "weather", 6 | "openweathermap", 7 | "openweather", 8 | "API" 9 | ], 10 | "version": "1.0.0", 11 | "author": { 12 | "name": "Manuel Baesler", 13 | "email": "baslr.at.github@gmail.com" 14 | }, 15 | "repository": { 16 | "type": "git", 17 | "url": "http://github.com/baslr/node-openweathermap.git" 18 | }, 19 | "bugs": { 20 | "url": "http://github.com/baslr/node-openweathermap/issues" 21 | }, 22 | "devDependencies": { 23 | "coffee-script": ">=1.7.1" 24 | }, 25 | "main": "./openweather.js", 26 | "homepage": "http://github.com/baslr/node-openweathermap/", 27 | 28 | "engines": { 29 | "node": ">=0.10.x" 30 | }, 31 | "licenses": [ 32 | { 33 | "type": "AGPLv3", 34 | "url": "https://www.gnu.org/licenses/agpl-3.0.de.html" 35 | } 36 | ], 37 | "readmeFilename": "Readme.md" 38 | } 39 | --------------------------------------------------------------------------------