commit 92344a5263cfb6b9bdd5a543be3dd6ab96025537
parent 408b6fe32e00016fc65d48dc323662c603ac6853
Author: tomvig38@gmail.com <tomvig38@gmail.com>
Date: Thu, 4 Nov 2021 15:13:28 +0000
Aldonu vidita komando
Diffstat:
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 {