Index: Cargo.lock ================================================================== --- Cargo.lock +++ Cargo.lock @@ -14,10 +14,68 @@ [[package]] name = "adler" version = "1.0.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f26201604c87b1e01bd3d98f8d5d9a8fcbb815e8cedb41ffccbeb4bf593a35fe" + +[[package]] +name = "aho-corasick" +version = "1.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8e60d3430d3a69478ad0993f19238d2df97c507009a52b3c10addcd7f6bcb916" +dependencies = [ + "memchr", +] + +[[package]] +name = "anstream" +version = "0.6.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "418c75fa768af9c03be99d17643f93f79bbba589895012a80e3452a19ddda15b" +dependencies = [ + "anstyle", + "anstyle-parse", + "anstyle-query", + "anstyle-wincon", + "colorchoice", + "is_terminal_polyfill", + "utf8parse", +] + +[[package]] +name = "anstyle" +version = "1.0.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "038dfcf04a5feb68e9c60b21c9625a54c2c0616e79b72b0fd87075a056ae1d1b" + +[[package]] +name = "anstyle-parse" +version = "0.2.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c03a11a9034d92058ceb6ee011ce58af4a9bf61491aa7e1e59ecd24bd40d22d4" +dependencies = [ + "utf8parse", +] + +[[package]] +name = "anstyle-query" +version = "1.0.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a64c907d4e79225ac72e2a354c9ce84d50ebb4586dee56c82b3ee73004f537f5" +dependencies = [ + "windows-sys 0.52.0", +] + +[[package]] +name = "anstyle-wincon" +version = "3.0.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "61a38449feb7068f52bb06c12759005cf459ee52bb4adc1d5a7c4322d716fb19" +dependencies = [ + "anstyle", + "windows-sys 0.52.0", +] [[package]] name = "anyhow" version = "1.0.86" source = "registry+https://github.com/rust-lang/crates.io-index" @@ -366,10 +424,16 @@ name = "cfg-if" version = "1.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" +[[package]] +name = "colorchoice" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0b6a852b24ab71dffc585bcb46eaf7959d175cb865a7152e35b348d1b2960422" + [[package]] name = "concurrent-queue" version = "2.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4ca0197aee26d1ae37445ee532fefce43251d24cc7c166799f4d46817f1d3973" @@ -436,10 +500,33 @@ "heck", "proc-macro2", "quote", "syn 1.0.109", ] + +[[package]] +name = "env_filter" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a009aa4810eb158359dda09d0c87378e4bbb89b5a801f016885a4707ba24f7ea" +dependencies = [ + "log", + "regex", +] + +[[package]] +name = "env_logger" +version = "0.11.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "38b35839ba51819680ba087cd351788c9a3c476841207e0b8cee0b04722343b9" +dependencies = [ + "anstream", + "anstyle", + "env_filter", + "humantime", + "log", +] [[package]] name = "equivalent" version = "1.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" @@ -798,10 +885,16 @@ name = "httpdate" version = "1.0.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "df3b46402a9d5adb4c86a0cf463f42e19994e3ee891101b1841f30a545cb49a9" +[[package]] +name = "humantime" +version = "2.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9a3a5bfb195931eeb336b2a7b4d761daec841b97f947d34394601737a7bba5e4" + [[package]] name = "hyper" version = "0.14.28" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "bf96e135eb83a2a8ddf766e426a841d8ddd7449d5f00d34ea02b41d2f19eef80" @@ -903,10 +996,16 @@ name = "ipnet" version = "2.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8f518f335dce6725a761382244631d86cf0ccb2863413590b31338feb467f9c3" +[[package]] +name = "is_terminal_polyfill" +version = "1.70.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f8478577c03552c21db0e2724ffb8986a5ce7af88107e6be5d2ee6e158c12800" + [[package]] name = "itoa" version = "1.0.11" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "49f1f14873335454500d59611f1cf4a4b0f786f9ac11f4312a78e4cf2566695b" @@ -1512,10 +1611,12 @@ name = "regex" version = "1.10.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c117dbdfde9c8308975b6a18d71f3f385c89461f7b3fb054288ecf2a2058ba4c" dependencies = [ + "aho-corasick", + "memchr", "regex-automata", "regex-syntax", ] [[package]] @@ -1522,10 +1623,12 @@ name = "regex-automata" version = "0.4.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "86b83b8b9847f9bf95ef68afb0b8e6cdb80f498442f5179a29fad448fcc1eaea" dependencies = [ + "aho-corasick", + "memchr", "regex-syntax", ] [[package]] name = "regex-syntax" @@ -1853,10 +1956,11 @@ version = "0.1.0" dependencies = [ "anyhow", "async-std", "config", + "env_logger", "mail-parser", "samotop", "telegram-bot", ] @@ -2206,10 +2310,16 @@ "form_urlencoded", "idna 0.5.0", "percent-encoding", ] +[[package]] +name = "utf8parse" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "711b9620af191e0cdc7468a8d14e709c3dcdb115b36f838e601583af800a370a" + [[package]] name = "uuid" version = "0.8.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "bc5cf98d8186244414c848017f0e2676b3fcb46807f6668a97dfe67359a3c4b7" Index: Cargo.toml ================================================================== --- Cargo.toml +++ Cargo.toml @@ -6,10 +6,11 @@ [dependencies] anyhow = "*" async-std = { version = "*", features = [ "tokio1" ] } config = { version = "*", default-features = false, features = [ "toml" ] } +env_logger = "*" telegram-bot = { git = "https://github.com/telegram-rs/telegram-bot" } mail-parser = { version = "*", features = ["serde", "serde_support"] } samotop = "*" [profile.release] Index: src/main.rs ================================================================== --- src/main.rs +++ src/main.rs @@ -12,10 +12,11 @@ Prudence, }, }; use telegram_bot::{ Api, + MessageOrChannelPost, ParseMode, SendMessage, UserId, }; @@ -141,11 +142,11 @@ for line in body.lines() { reply.push(line.into()); } reply.push("```".into()); - // and let's coillect all other attachment parts + // and let's collect all other attachment parts let mut files_to_send = vec![]; /* * let's just skip html parts for now, they just duplicate text? while html_num < html_parts { files_to_send.push(mail.html_part(html_num).unwrap()); @@ -160,15 +161,15 @@ files_to_send.push(mail.attachment(file_num).unwrap()); file_num += 1; } for chat in rcpt { - core.send(chat, reply.join("\n")).await.unwrap(); + let base_post = core.send(chat, reply.join("\n")).await.unwrap(); for chunk in &files_to_send { let data = chunk.contents().to_vec(); let obj = telegram_bot::types::InputFileUpload::with_data(data, "Attachment"); - core.sendfile(chat, obj).await.unwrap(); + core.sendfile(chat, obj, Some(&base_post)).await.unwrap(); } } }, None => { core.debug("None mail.").await.unwrap(); }, }; @@ -206,30 +207,35 @@ tg, recipients, } } - pub async fn debug<'b, S>(&self, msg: S) -> Result<()> - where S: Into> { - task::sleep(Duration::from_secs(5)).await; - self.tg.send(SendMessage::new(self.recipients.get("_").unwrap(), msg) - .parse_mode(ParseMode::Markdown)).await?; - Ok(()) - } - - pub async fn send<'b, S>(&self, to: &UserId, msg: S) -> Result<()> - where S: Into> { - task::sleep(Duration::from_secs(5)).await; - self.tg.send(SendMessage::new(to, msg) - .parse_mode(ParseMode::Markdown)).await?; - Ok(()) - } - - pub async fn sendfile(&self, to: &UserId, chunk: V) -> Result<()> - where V: Into { - task::sleep(Duration::from_secs(5)).await; - self.tg.send(telegram_bot::SendDocument::new(to, chunk)).await?; + pub async fn debug<'b, S>(&self, msg: S) -> Result + where S: Into> { + task::sleep(Duration::from_secs(5)).await; + Ok(self.tg.send(SendMessage::new(self.recipients.get("_").unwrap(), msg) + .parse_mode(ParseMode::Markdown)).await?) + } + + pub async fn send<'b, S>(&self, to: &UserId, msg: S) -> Result + where S: Into> { + task::sleep(Duration::from_secs(5)).await; + Ok(self.tg.send(SendMessage::new(to, msg) + .parse_mode(ParseMode::Markdown)).await?) + } + + pub async fn sendfile(&self, to: &UserId, chunk: V, basic_mail: Option<&MessageOrChannelPost>) -> Result<()> + where V: Into { + task::sleep(Duration::from_secs(5)).await; + match basic_mail { + Some(post) => { + self.tg.send(telegram_bot::SendDocument::new(to, chunk).reply_to(post)).await?; + }, + None => { + self.tg.send(telegram_bot::SendDocument::new(to, chunk)).await?; + }, + }; Ok(()) } } #[async_std::main] @@ -245,10 +251,12 @@ let listen_on = settings.get_string("listen_on") .expect("[smtp2tg.toml] missing \"listen_on\" parameter.\n"); let core = TelegramTransport::new(settings); let sink = Builder + Name::new("smtp2tg") + DebugService + my_prudence() + MailDir::new(maildir.clone()).unwrap(); + + env_logger::init(); task::spawn(async move { loop { relay_mails(&maildir, &core).unwrap(); task::sleep(Duration::from_secs(5)).await;