vortaroboto

Log | Files | Refs | README

commit 92344a5263cfb6b9bdd5a543be3dd6ab96025537
parent 408b6fe32e00016fc65d48dc323662c603ac6853
Author: tomvig38@gmail.com <tomvig38@gmail.com>
Date:   Thu,  4 Nov 2021 15:13:28 +0000

Aldonu vidita komando
Diffstat:
MCargo.lock | 2++
MCargo.toml | 1+
Msrc/main.rs | 66+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++---
3 files changed, 66 insertions(+), 3 deletions(-)

diff --git a/Cargo.lock b/Cargo.lock @@ -137,6 +137,7 @@ dependencies = [ "libc", "num-integer", "num-traits", + "serde", "time", "winapi", ] @@ -1169,6 +1170,7 @@ version = "0.1.0" dependencies = [ "bincode", "cached", + "chrono", "futures", "irc", "log", diff --git a/Cargo.toml b/Cargo.toml @@ -17,3 +17,4 @@ simple_logger = "1.13.0" bincode = "1.3.3" snap = "1.0.5" cached = "0.26.2" +chrono = { version = "0.4.19", features = ["serde"] } diff --git a/src/main.rs b/src/main.rs @@ -2,6 +2,7 @@ use futures::prelude::*; use irc::client::prelude::*; use serde::{de::DeserializeOwned, ser::Serialize}; use std::{collections::HashMap, str::FromStr}; +use chrono::{Duration, prelude::*}; use log::{debug, info}; use simple_logger::SimpleLogger; @@ -91,7 +92,7 @@ async fn main() -> irc::error::Result<()> { }; if let Some(cmd) = msg.strip_prefix('!') { - if let Some(answer) = handle_command(cmd).await { + if let Some(answer) = handle_command(target, cmd).await { let r = match (is_channel, message.source_nickname()) { (true, Some(n)) => format!("{}:\r\n{}", n, answer), _ => answer, @@ -101,7 +102,11 @@ async fn main() -> irc::error::Result<()> { continue; } + // TODO: make this local to a channel / query tokio::task::spawn(add_words(msg.to_string())); + if let Some(nomo) = message.source_nickname() { + vidita_update(target, nomo, msg); + } // Donu bonaj respondoj ofte if msg.contains(client.current_nickname()) { @@ -180,6 +185,55 @@ fn stats() -> Result<String, String> { .join(", ")) } +const VIDITA_PATH: &'static str = "vidita.bincode"; +fn vidita_update(channel: &str, nomo: &str, msg: &str) { + let mut h: HashMap<String, HashMap<String, (String, DateTime<Utc>)>> = unpack_data(VIDITA_PATH).unwrap_or_default(); + + // Make a little dance to create the channel index if it's not here yet + let inner = if let Some(inner) = h.get_mut(channel) { + inner + } else { + h.insert(channel.to_owned(), HashMap::default()); + h.get_mut(channel).unwrap() + }; + + inner.insert(nomo.to_owned(), (msg.to_owned(), Utc::now())); + + pack_data(VIDITA_PATH, &h).unwrap(); +} + +fn formato_dauxro(dato: Duration) -> String { + let mut res = String::with_capacity(10); + let inter: Vec<(i64, &'static str)> = vec![ + (dato.num_days(), "tago"), + (dato.num_hours() % 24, "horo"), + (dato.num_minutes() % 60, "horo"), + (dato.num_seconds() % 60, "sekondo"), + ]; + + for (n, v) in inter { + if n == 1 { + res.push_str(&format!("{} {}", n, v)); + } else if n > 1 { + res.push_str(&format!("{} {}j", n, v)); + } + } + + res +} + +fn vidita_display(channel: &str, nomo: &str) -> Option<String> { + + if nomo == NICK { + return Some(format!("Eh, mi {} {}!", irc_fmt!(FormattingKind::Italics => "estas"), NICK)); + } + let h: HashMap<String, HashMap<String, (String, DateTime<Utc>)>> = unpack_data(VIDITA_PATH).ok()?; + let inner = h.get(channel)?; + let (msg, time) = inner.get(nomo)?; + + Some(format!("{} estis laste vidita antaĆ­ {}: '{}'", nomo, formato_dauxro(Utc::now() - *time), msg)) +} + macro_rules! parse_or_default { ($t:ty, $arg:ident) => { if let Some(s) = $arg.next() { @@ -199,7 +253,7 @@ macro_rules! wrap_handler { }; } -async fn handle_command(cmd: &str) -> Option<String> { +async fn handle_command(source: &str, cmd: &str) -> Option<String> { let mut splitted = cmd.split_ascii_whitespace(); match splitted.next() { Some("helpu" | "h") => Some(helpu()), @@ -234,6 +288,11 @@ async fn handle_command(cmd: &str) -> Option<String> { } } Some("satistikoj" | "stat") => stats().ok(), + Some("vidita" | "vid") => if let Some(w) = splitted.next() { + vidita_display(source, w).or_else(|| Some(format!("Neniam vidita {}.", w))) + } else { + Some(String::from("Uzo: vidita {uzanto}")) + }, Some(u) => Some(format!("Mi ne scias kiel respondi al: {}", u)), None => None, } @@ -266,7 +325,8 @@ fn helpu() -> String { &[], "Doni la etimologio de {vorto}", ), - ("statistiko", &[], &[], "Donu la 10 vortoj plej uzataj.."), + ("statistiko", &[], &[], "Donu la 10 vortoj plej uzataj."), + ("vidita", &["unzanto"], &[], "Donu la lasta fojo uzanto estas vidita."), ]; fn format_args(am: &[&str], left: char, right: char, c: ColorKind) -> String {