Friendlier weather output
This commit is contained in:
parent
7fefcbac46
commit
5e0ca7232a
2 changed files with 39 additions and 12 deletions
|
|
@ -110,7 +110,7 @@ impl Store {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn fetch_weather(location: &str) -> Result<String, String> {
|
fn fetch_weather(location: &str) -> Result<String, String> {
|
||||||
let path = format!("/{}?format=%l:+%C+%t+feels+%f+%w+%h&m", url_encode(location));
|
let path = format!("/{}?format=%l|%c|%C|%t|%f|%w|%h&m", url_encode(location));
|
||||||
let mut last = "no response".to_string();
|
let mut last = "no response".to_string();
|
||||||
for attempt in 0..3 {
|
for attempt in 0..3 {
|
||||||
if attempt > 0 {
|
if attempt > 0 {
|
||||||
|
|
@ -118,16 +118,9 @@ fn fetch_weather(location: &str) -> Result<String, String> {
|
||||||
}
|
}
|
||||||
match https_get("wttr.in", &path) {
|
match https_get("wttr.in", &path) {
|
||||||
Ok(body) => {
|
Ok(body) => {
|
||||||
let line: String = body
|
let raw = body.lines().map(str::trim).find(|l| !l.is_empty()).unwrap_or("");
|
||||||
.lines()
|
if !raw.is_empty() {
|
||||||
.map(str::trim)
|
return Ok(format_weather(raw, location));
|
||||||
.find(|l| !l.is_empty())
|
|
||||||
.unwrap_or("")
|
|
||||||
.chars()
|
|
||||||
.take(250)
|
|
||||||
.collect();
|
|
||||||
if !line.is_empty() {
|
|
||||||
return Ok(line);
|
|
||||||
}
|
}
|
||||||
last = "empty response".to_string();
|
last = "empty response".to_string();
|
||||||
}
|
}
|
||||||
|
|
@ -143,6 +136,24 @@ fn fetch_weather(location: &str) -> Result<String, String> {
|
||||||
Err(last)
|
Err(last)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn format_weather(raw: &str, location: &str) -> String {
|
||||||
|
let f: Vec<&str> = raw.split('|').map(str::trim).collect();
|
||||||
|
if f.len() >= 7 {
|
||||||
|
let temp = f[3].trim_start_matches('+');
|
||||||
|
let feels = f[4].trim_start_matches('+');
|
||||||
|
let msg = format!(
|
||||||
|
"{} {}: {}, {} (feels like {}) · 💨 {} · 💧 {}",
|
||||||
|
f[1], f[0], f[2], temp, feels, f[5], f[6]
|
||||||
|
);
|
||||||
|
return msg.chars().take(250).collect();
|
||||||
|
}
|
||||||
|
let low = raw.to_lowercase();
|
||||||
|
if low.contains("not found") || low.contains("unknown location") {
|
||||||
|
return format!("couldn't find '{location}' — try a city name or postcode");
|
||||||
|
}
|
||||||
|
raw.chars().take(250).collect()
|
||||||
|
}
|
||||||
|
|
||||||
struct HttpErr {
|
struct HttpErr {
|
||||||
msg: String,
|
msg: String,
|
||||||
retry: bool,
|
retry: bool,
|
||||||
|
|
|
||||||
|
|
@ -2,7 +2,7 @@ use std::collections::BTreeMap;
|
||||||
use std::path::PathBuf;
|
use std::path::PathBuf;
|
||||||
|
|
||||||
use rustbot::bot::module::{Action, Command, Module};
|
use rustbot::bot::module::{Action, Command, Module};
|
||||||
use rustbot::bot::modules::weather::{parse_db, to_json, Weather};
|
use rustbot::bot::modules::weather::{format_weather, parse_db, to_json, Weather};
|
||||||
|
|
||||||
fn cmd<'a>(sender: &'a str, name: &'a str, args: &'a [&'a str]) -> Command<'a> {
|
fn cmd<'a>(sender: &'a str, name: &'a str, args: &'a [&'a str]) -> Command<'a> {
|
||||||
Command { sender, reply_to: "#chan", name, args, prefix: ">", network: "test" }
|
Command { sender, reply_to: "#chan", name, args, prefix: ">", network: "test" }
|
||||||
|
|
@ -65,3 +65,19 @@ fn w_without_saved_location_hints_to_add() {
|
||||||
let r = reply(&w.on_command(&cmd("nobody", "w", &[]))).to_string();
|
let r = reply(&w.on_command(&cmd("nobody", "w", &[]))).to_string();
|
||||||
assert!(r.contains("add"), "reply: {r:?}");
|
assert!(r.contains("add"), "reply: {r:?}");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn format_weather_builds_friendly_line() {
|
||||||
|
let out = format_weather("73700|☀️ |Sunny|+23°C|+18°C|↘8km/h|45%", "73700");
|
||||||
|
assert!(out.contains("☀️"), "{out}");
|
||||||
|
assert!(out.contains("73700: Sunny"), "{out}");
|
||||||
|
assert!(out.contains("23°C") && !out.contains("+23"), "{out}");
|
||||||
|
assert!(out.contains("feels like 18°C"), "{out}");
|
||||||
|
assert!(out.contains("45%"), "{out}");
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn format_weather_friendly_not_found() {
|
||||||
|
let out = format_weather("location not found: upstream error", "zzz");
|
||||||
|
assert!(out.contains("couldn't find 'zzz'"), "{out}");
|
||||||
|
}
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue