From ebb3c67ef0795f2ae916b0a054443b3d42efea27 Mon Sep 17 00:00:00 2001
From: mcmlxxix <>
Date: Wed, 15 May 2019 20:22:33 +0000
Subject: [PATCH] added forecast command

---
 exec/ircbots/weather/weather_commands.js  | 62 ++++++++++++++
 exec/ircbots/weather/weather_functions.js | 99 ++++++++++++++++++++++-
 2 files changed, 160 insertions(+), 1 deletion(-)

diff --git a/exec/ircbots/weather/weather_commands.js b/exec/ircbots/weather/weather_commands.js
index 8cfb5e4646..0aed4850da 100644
--- a/exec/ircbots/weather/weather_commands.js
+++ b/exec/ircbots/weather/weather_commands.js
@@ -39,3 +39,65 @@ Bot_Commands["WEATHER"].command = function (target, onick, ouh, srv, lvl, cmd) {
 
     return true;
 }
+
+Bot_Commands["FORECAST"] = new Bot_Command(0,false,false);
+Bot_Commands["FORECAST"].command = function (target, onick, ouh, srv, lvl, cmd) {
+
+    // Remove empty cmd args
+    for (var i = 1; i < cmd.length; i++) {
+        if (cmd[i].search(/^\s*$/) == 0) {
+            cmd.splice(i, 1);
+            i--;
+        }
+    }
+    cmd.shift();
+
+    try {
+        const params = get_params(cmd, onick, srv);
+        if (!params) { 
+			throw("error parsing parameters");
+		}
+		const res = owm.call_api('forecast', params);
+		if(!res || res.cod != 200) {
+			throw(JSON.stringify(res));
+		}
+		
+		var output = [];
+		srv.o(target,ctrl_a_to_mirc('Forecast for \1h\1c' + res.city.name + ' \1n\1m(\1h\1mProvided by OpenWeatherMap.org\1n\1m)\1n\1r:'));
+		//output.push('\0010\1n\1rForecast for \1h\1c' + res.city.name + ' \1n\1m(\1h\1mProvided by OpenWeatherMap.org\1n\1m)\1n\1r:');
+		for(var d=0; d<res.list.length; d+=8) {
+			var day_forecast = res.list.slice(d,d+8);
+			if(day_forecast.length > 0) {
+				output.push(get_day_forecast_rows(day_forecast));
+			}
+			writeln(d + ": " + JSON.stringify(day_forecast));
+			// output.push(
+				// '\0010\1h\1c ' + days[forecast_date.getDay()] + '\1n\1r, \1h\1c' + months[forecast_date.getMonth()] + ' ' + forecast_date.getDate() + '\1n\1r: '
+				// + '\1h\1c' + day_forecast.weather[0].main + ' \1n\1r(\1c' + day_forecast.weather[0].description + '\1r), '
+				// + '\1h\1c' + day_forecast.clouds.all + '% cloudy\1n\1r, '
+				// + 'Min temp: \1h\1c' + temperature_str(day_forecast.main.temp_min) + '\1n\1r, '
+				// + 'Max temp: \1h\1c' + temperature_str(day_forecast.main.temp_max) + '\1n\1r, '
+				// + 'Wind: \1h\1c' + day_forecast.wind.speed + ' KM/h ' + owm.wind_direction(day_forecast.wind.deg) + '\1n\1r, '
+				// + 'Humidity: \1h\1c' + day_forecast.main.humidity + '%\1n\1r, '
+				// + 'Pressure: \1h\1c' + day_forecast.main.pressure + ' hPa'
+			// );
+		}
+		// while(output.length > 0) {
+			// srv.o(target, ctrl_a_to_mirc(output.shift()));
+		// }
+		for(var r=0;r<output[0].length;r++) {
+			var row_string = "";
+			for(var o=0;o<output.length;o++) {
+				row_string += ctrl_a_to_mirc('\0010' + output[o][r]);
+			}
+			srv.o(target,row_string);
+		}
+		
+    } catch (err) {
+        log(LOG_DEBUG, 'Failed to display weather conditions: ' + err);
+        srv.o(target, 'Failed to fetch weather conditions: ' + err);
+    }
+
+    return true;
+}
+
diff --git a/exec/ircbots/weather/weather_functions.js b/exec/ircbots/weather/weather_functions.js
index ad48b07416..9fde61ad87 100644
--- a/exec/ircbots/weather/weather_functions.js
+++ b/exec/ircbots/weather/weather_functions.js
@@ -3,6 +3,8 @@ if (!js.global.get_nicklocation) js.global.load(js.global, "nicklocate.js");
 if (!js.global.OpenWeatherMap) js.global.load(js.global, 'openweathermap.js');
 
 var owm = new OpenWeatherMap();
+var short_months = ["Jan","Feb","Mar","Apr","May","Jun","Jul","Aug","Sep","Oct","Nov","Dec"];
+var short_days = ["Sun","Mon","Tue","Wed","Thu","Fri","Sat"];
 
 function locate_user(nick, srv) {
     const ret = { units: 'metric' };
@@ -61,5 +63,100 @@ function get_params(cmd, nick, srv) {
 }
 
 function temperature_str(n) {
-    return n + '\xC2\xB0C \1n\1r(\1h\1c' + owm.c_to_f(n) + '\xC2\xB0F\1n\1r)';
+    return Math.round(n) + '\xC2\xB0C \1n\1r(\1h\1c' + owm.c_to_f(n) + '\xC2\xB0F\1n\1r)';
+}
+
+function temperature_str_plain(n) {
+    return Math.round(n) + '\xC2\xB0C (' + owm.c_to_f(n) + '\xC2\xB0F)';
+}
+
+function get_day_forecast_rows(forecasts) {
+	var bar = [
+		format_graph_row(get_forecast_day(forecasts),20),
+		format_graph_row(get_avg_weather(forecasts),20),
+		format_graph_row(get_low_temp(forecasts),26),
+		format_graph_row(get_high_temp(forecasts),26),
+		format_graph_row(get_avg_wind(forecasts),24)//,
+		// format_graph_row(get_avg_humidity(forecasts),16),
+		// format_graph_row(get_avg_pressure(forecasts),16)
+	];
+	return bar;
+}
+
+function get_low_temp(forecasts) {
+	var low = undefined;
+	for(var f=0;f<forecasts.length;f++) {
+		var weather = forecasts[f].main;
+		if(low === undefined || weather.temp_min < low) {
+			low = weather.temp_min;
+		}
+	}
+	return "\1n\1wL:\1h\1c " + temperature_str_plain(low);
+}
+
+function get_high_temp(forecasts) {
+	var high = undefined;
+	for(var f=0;f<forecasts.length;f++) {
+		var weather = forecasts[f].main;
+		if(high === undefined || weather.temp_max > high) {
+			high = weather.temp_max;
+		}
+	}
+	return "\1n\1wH:\1n\1r " + temperature_str_plain(high);
+}
+
+function get_forecast_day(forecasts) {
+	var forecast_utc = forecasts[0].dt * 1000;
+	var forecast_date = new Date(forecast_utc);
+	var day_str = days[forecast_date.getDay()] + ', ' + months[forecast_date.getMonth()] + ' ' + forecast_date.getDate();
+	return "\1n\1w" + day_str;
+}
+
+function get_avg_weather(forecasts) {
+    var modeMap = {};
+    var maxEl = forecasts[0], maxCount = 1;
+    for(var i = 0; i < forecasts.length; i++)
+    {
+        var el = forecasts[i].weather[0].main;
+        if(modeMap[el] == null)
+            modeMap[el] = 1;
+        else
+            modeMap[el]++;  
+        if(modeMap[el] > maxCount)
+        {
+            maxEl = forecasts[i];
+            maxCount = modeMap[el];
+        }
+    }
+    return "\1h\1y" + maxEl.weather[0].main;
+}
+
+function get_avg_wind(forecasts) {
+	var total_wind = 0;
+	var total_dir = 0;
+	for(var f=0;f<forecasts.length;f++) {
+		total_wind += forecasts[f].wind.speed;
+		total_dir += forecasts[f].wind.deg
+	}
+	return "\1n\1wW:\1h\1y " + Math.round(total_wind/forecasts.length) + ' KM/h ' + owm.wind_direction(Math.round(total_dir/forecasts.length))
+}
+
+function get_avg_humidity(forecasts) {
+	var total_hum = 0;
+	for(var f=0;f<forecasts.length;f++) {
+		total_hum += forecasts[f].main.humidity;
+	}
+	return "\1n\1wH:\1h\1y " + Math.round(total_hum/forecasts.length) + '%';
+}
+
+function get_avg_pressure(forecasts) {
+	var total_press = 0;
+	for(var f=0;f<forecasts.length;f++) {
+		total_press += forecasts[f].main.pressure;
+	}
+	return "\1n\1wP:\1h\1y " + Math.round(total_press/forecasts.length) + ' hPa';
+}
+
+function format_graph_row(str, len) {
+	return format("%-*s",len,str);
 }
-- 
GitLab