Harden bot: line cap, send throttle, panic isolation, verbose flag, weather cache, tests
This commit is contained in:
parent
1c320ad0c3
commit
9325150315
7 changed files with 165 additions and 10 deletions
|
|
@ -1,16 +1,18 @@
|
|||
use std::collections::BTreeMap;
|
||||
use std::collections::{BTreeMap, HashMap};
|
||||
use std::fs;
|
||||
use std::io::{self, Read, Write};
|
||||
use std::iter::Peekable;
|
||||
use std::net::{TcpStream, ToSocketAddrs};
|
||||
use std::path::{Path, PathBuf};
|
||||
use std::str::Chars;
|
||||
use std::time::Duration;
|
||||
use std::time::{Duration, Instant};
|
||||
|
||||
use native_tls::TlsConnector;
|
||||
|
||||
use crate::bot::module::{Action, Command, CommandSpec, Module};
|
||||
|
||||
const CACHE_TTL: Duration = Duration::from_secs(600);
|
||||
|
||||
const COMMANDS: &[CommandSpec] = &[
|
||||
CommandSpec { name: "add", usage: "add <location>", about: "save your weather location" },
|
||||
CommandSpec { name: "w", usage: "w [location]", about: "weather for your saved location" },
|
||||
|
|
@ -19,6 +21,7 @@ const COMMANDS: &[CommandSpec] = &[
|
|||
pub struct Weather {
|
||||
store: Store,
|
||||
path: PathBuf,
|
||||
cache: HashMap<String, (Instant, String)>,
|
||||
}
|
||||
|
||||
impl Weather {
|
||||
|
|
@ -32,7 +35,7 @@ impl Weather {
|
|||
}
|
||||
|
||||
pub fn with_path(path: PathBuf) -> Weather {
|
||||
Weather { store: Store::load(&path), path }
|
||||
Weather { store: Store::load(&path), path, cache: HashMap::new() }
|
||||
}
|
||||
|
||||
pub fn location_of(&self, nick: &str) -> Option<&str> {
|
||||
|
|
@ -74,8 +77,17 @@ impl Module for Weather {
|
|||
cmd.sender, cmd.prefix
|
||||
))];
|
||||
};
|
||||
let key = loc.to_lowercase();
|
||||
if let Some((at, text)) = self.cache.get(&key) {
|
||||
if at.elapsed() < CACHE_TTL {
|
||||
return vec![Action::reply(text.clone())];
|
||||
}
|
||||
}
|
||||
match fetch_weather(&loc) {
|
||||
Ok(text) => vec![Action::reply(text)],
|
||||
Ok(text) => {
|
||||
self.cache.insert(key, (Instant::now(), text.clone()));
|
||||
vec![Action::reply(text)]
|
||||
}
|
||||
Err(e) => vec![Action::reply(format!("weather unavailable: {e}"))],
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue