From ee95c38bf3bf018c1303fae83645ed13dbe52831 Mon Sep 17 00:00:00 2001
From: echicken <echicken@bbs.electronicchicken.com>
Date: Tue, 21 Feb 2023 20:47:17 +0000
Subject: [PATCH] Cache stuff. Rearranged some things. Stuff like that.

---
 xtrn/wttr.in/readme.txt  | 17 +++++++++----
 xtrn/wttr.in/wttr-lib.js | 52 ++++++++++++++++++++++++++++++++++++++++
 xtrn/wttr.in/wttr.js     | 35 +++++++++++++--------------
 3 files changed, 82 insertions(+), 22 deletions(-)
 create mode 100644 xtrn/wttr.in/wttr-lib.js

diff --git a/xtrn/wttr.in/readme.txt b/xtrn/wttr.in/readme.txt
index 416a59957f..80a18a5eaa 100644
--- a/xtrn/wttr.in/readme.txt
+++ b/xtrn/wttr.in/readme.txt
@@ -33,10 +33,19 @@ Contents
 
 3) Customization
 
-	Any arguments that you pass on the command line will be treated as an
-	alternate URL to query. For example:
+	The default query URL is https://wttr.in/?AFn for ANSI, no 'Follow' line,
+	and narrow output. You can override this by supplying an alternate URL on
+	the command line, such as:
 
 		Command Line	?wttr.js https://wttr.in/?m0AFn
 
-	The default is URL is 'https://wttr.in/?AFn' for ANSI, no 'Follow' line,
-	and narrow output.
+	Responses are cached in your OS temp directory and remain valid for 3600
+	seconds (one hour). You can override this default cache TTL by supplying
+	a numeric value (in seconds) on the command line, such as:
+
+		Command Line	?wttr.js 1800
+
+	You can combine the parameters in whichever order you prefer:
+
+		Command Line 	?wttr.js https://wttr.in/?m0AFn 1800
+		Command Line 	?wttr.js 1800 https://wttr.in/?m0AFn
diff --git a/xtrn/wttr.in/wttr-lib.js b/xtrn/wttr.in/wttr-lib.js
new file mode 100644
index 0000000000..0515c3ac55
--- /dev/null
+++ b/xtrn/wttr.in/wttr-lib.js
@@ -0,0 +1,52 @@
+require('http.js', 'HTTPRequest');
+const locator = load({}, js.exec_dir + 'locator.js');
+const xterm = load({}, js.exec_dir + 'xterm-colors.js');
+
+function uReplace(str) {
+	return str.replace(/\xE2\x9A\xA1/g, '\x01+\x01h\x01yZ \x01-'); // U+26A1 Lightning bolt
+}
+
+function getCacheName(qs, addr) {
+	const cfn = format('wttr.in_%s_%s.ans', qs, addr || '').replace(/[^0-9a-z\.]+/ig, '_');
+	return system.temp_path + cfn;
+}
+
+function readCache(qs, addr, ttl) {
+	const cfn = getCacheName(qs, addr);
+	const f = new File(cfn);
+	if (!f.exists) return;
+	if (time() - file_date(cfn) > ttl) return;
+	if (!f.open('r')) return;
+	const cache = f.read();
+	f.close();
+	return cache;
+}
+
+function writeCache(qs, addr, ans) {
+	const cfn = getCacheName(qs, addr);
+	const f = new File(cfn);
+	if (!f.open('w')) return;
+	f.write(ans);
+	f.close();
+}
+
+function fetchWeather(qs, addr) {
+	const http = new HTTPRequest();
+	if (addr !== undefined) http.extra_headers = { 'X-Forwarded-For': addr };
+	const body = http.Get(qs);
+	if (http.response_code !== 200) throw new Error('wttr.in response had status ' + http.response_code);
+	return body;
+}
+
+function getWeather(qs, ttl) {
+	const addr = locator.getAddress();
+	const cachedWeather = readCache(qs, addr, ttl);
+	if (cachedWeather !== undefined) return cachedWeather;
+	const weather = fetchWeather(qs, addr);
+	const text = uReplace(weather);
+	const ansi = xterm.convertColors(text);
+	writeCache(qs, addr, ansi);
+	return ansi;
+}
+
+this;
\ No newline at end of file
diff --git a/xtrn/wttr.in/wttr.js b/xtrn/wttr.in/wttr.js
index ccc724c7ed..7453385970 100644
--- a/xtrn/wttr.in/wttr.js
+++ b/xtrn/wttr.in/wttr.js
@@ -1,26 +1,25 @@
 require('sbbsdefs.js', 'P_UTF8');
-require('http.js', 'HTTPRequest');
-const xterm = load({}, js.exec_dir + 'xterm-colors.js');
-const locator = load({}, js.exec_dir + 'locator.js');
+const wttr = load({}, js.exec_dir + 'wttr-lib.js');
 
-function uReplace(str) {
-	return str.replace(/\xE2\x9A\xA1/g, '/ '); // U+26A1 Lightning bolt
-}
-
-function fetchWeather(addr) {
-	const qs = argc > 0 ? argv.join('') : 'https://wttr.in/?AFn';
-	const http = new HTTPRequest();
-	if (addr !== undefined) http.extra_headers = { 'X-Forwarded-For': addr };
-	const body = http.Get(qs);
-	if (http.response_code !== 200) throw new Error('wttr.in response had status ' + http.response_code);
-	return body;
+function parseArgs() {
+	const ret = {
+		qs: 'https://wttr.in/?AFn',
+		ttl: 3600, // Seconds
+	};
+	for (var n = 0; n < argc; n++) {
+		const arg = parseInt(argv[n], 10);
+		if (isNaN(arg)) {
+			ret.qs = arg;
+		} else {
+			ret.ttl = arg;
+		}
+	}
+	return ret;
 }
 
 function main() {
-	const addr = locator.getAddress();
-	const weather = fetchWeather(addr);
-	const text = uReplace(weather);
-	const ansi = xterm.convertColors(text);
+	const args = parseArgs();
+	const ansi = wttr.getWeather(args.qs, args.ttl);
 	const attr = console.attributes;
 	console.clear(BG_BLACK|LIGHTGRAY);
 	console.putmsg(ansi, P_UTF8);
-- 
GitLab