Overview
Comment: | make /list work again, more fixes |
---|---|
Downloads: | Tarball | ZIP archive | SQL archive |
Timelines: | family | ancestors | descendants | both | trunk |
Files: | files | file ages | folders |
SHA3-256: |
a7f91033c0168c03ac5daca37b2aa388 |
User & Date: | arcade on 2021-11-13 10:32:19.032 |
Other Links: | manifest | tags |
Context
2021-11-13
| ||
10:50 | 0.2.1: even more errors now can reach users check-in: 4632d20d39 user: arcade tags: trunk | |
10:32 | make /list work again, more fixes check-in: a7f91033c0 user: arcade tags: trunk | |
06:58 | 0.2.0: huge inner revamp, I guess now replies should be correctly sent to users. check-in: 9171c791eb user: arcade tags: trunk | |
Changes
Modified src/command.rs
from [99ad0c237b]
to [8e69210742].
1 2 3 4 5 6 7 8 9 10 11 12 13 | use anyhow::{bail, Context, Result}; use crate::core::Core; use regex::Regex; use sedregex::ReplaceCommand; use telegram_bot; lazy_static! { static ref RE_USERNAME: Regex = Regex::new(r"^@[a-zA-Z][a-zA-Z0-9_]+$").unwrap(); static ref RE_LINK: Regex = Regex::new(r"^https?://[a-zA-Z.0-9-]+/[-_a-zA-Z.0-9/?=]+$").unwrap(); static ref RE_IV_HASH: Regex = Regex::new(r"^[a-f0-9]{14}$").unwrap(); } pub async fn start(core: &Core, sender: telegram_bot::UserId) -> Result<()> { | | | | | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 | use anyhow::{bail, Context, Result}; use crate::core::Core; use regex::Regex; use sedregex::ReplaceCommand; use telegram_bot; lazy_static! { static ref RE_USERNAME: Regex = Regex::new(r"^@[a-zA-Z][a-zA-Z0-9_]+$").unwrap(); static ref RE_LINK: Regex = Regex::new(r"^https?://[a-zA-Z.0-9-]+/[-_a-zA-Z.0-9/?=]+$").unwrap(); static ref RE_IV_HASH: Regex = Regex::new(r"^[a-f0-9]{14}$").unwrap(); } pub async fn start(core: &Core, sender: telegram_bot::UserId) -> Result<()> { core.send("We are open\\. Probably\\. Visit [channel](https://t.me/rsstg_bot_help/3) for details\\.", Some(sender), None)?; Ok(()) } pub async fn list(core: &Core, sender: telegram_bot::UserId) -> Result<()> { core.send(core.list(sender).await?, Some(sender), Some(telegram_bot::types::ParseMode::MarkdownV2))?; Ok(()) } pub async fn command(core: &Core, sender: telegram_bot::UserId, command: Vec<&str>) -> Result<()> { core.send( match &command[1].parse::<i32>() { Err(err) => format!("I need a number\\.\n{}", &err), Ok(number) => match command[0] { "/check" => core.check(&number, sender, false).await .context("Channel check failed.")?, "/clean" => core.clean(&number, sender).await?, "/enable" => core.enable(&number, sender).await? .to_string(), "/delete" => core.delete(&number, sender).await?, "/disable" => core.disable(&number, sender).await? .to_string(), _ => bail!("Command {} not handled.", &command[0]), }, }, Some(sender), None)?; Ok(()) } pub async fn update(core: &Core, sender: telegram_bot::UserId, command: Vec<&str>) -> Result<()> { let mut source_id: Option<i32> = None; let at_least = "Requires at least 3 parameters."; let first_word = command[0]; |
︙ | ︙ | |||
54 55 56 57 58 59 60 | let mut i_command = command.into_iter(); let (channel, url, iv_hash, url_re) = ( i_command.next().context(at_least)?, i_command.next().context(at_least)?, i_command.next(), i_command.next()); if ! RE_USERNAME.is_match(&channel) { | | | | | 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 | let mut i_command = command.into_iter(); let (channel, url, iv_hash, url_re) = ( i_command.next().context(at_least)?, i_command.next().context(at_least)?, i_command.next(), i_command.next()); if ! RE_USERNAME.is_match(&channel) { core.send(format!("Usernames should be something like \"@\\[a\\-zA\\-Z]\\[a\\-zA\\-Z0\\-9\\_]+\", aren't they?\nNot {:?}", &channel), Some(sender), None)?; return Ok(()) } if ! RE_LINK.is_match(&url) { core.send(format!("Link should be a link to atom/rss feed, something like \"https://domain/path\".\nNot {:?}", &url), Some(sender), None)?; return Ok(()) } let iv_hash = match iv_hash { Some(hash) => { if ! RE_IV_HASH.is_match(hash) { core.send(format!("IV hash should be 14 hex digits.\nNot {:?}", hash), Some(sender), None)?; return Ok(()) }; Some(*hash) } None => None, }; if let Some(rex) = url_re { |
︙ | ︙ | |||
88 89 90 91 92 93 94 | }; if admin.user.id == sender { user = true; }; }; if ! me { bail!("I need to be admin on that channel\\."); }; if ! user { bail!("You should be admin on that channel\\."); }; | | > | 88 89 90 91 92 93 94 95 96 97 | }; if admin.user.id == sender { user = true; }; }; if ! me { bail!("I need to be admin on that channel\\."); }; if ! user { bail!("You should be admin on that channel\\."); }; core.send(core.update(source_id, channel, channel_id, url, iv_hash, None, sender).await?, Some(sender), None)?; Ok(()) } |
Modified src/core.rs
from [ad439a6329]
to [7064860d7e].
︙ | ︙ | |||
46 47 48 49 50 51 52 | .idle_timeout(std::time::Duration::new(60, 0)) .connect_lazy(&settings.get_str("pg")?)?, sources: Arc::new(Mutex::new(HashSet::new())), }; let clone = core.clone(); tokio::spawn(async move { if let Err(err) = &clone.autofetch().await { | | | > > > > | | 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 | .idle_timeout(std::time::Duration::new(60, 0)) .connect_lazy(&settings.get_str("pg")?)?, sources: Arc::new(Mutex::new(HashSet::new())), }; let clone = core.clone(); tokio::spawn(async move { if let Err(err) = &clone.autofetch().await { if let Err(err) = clone.send(&format!("🛑 {:?}", err), None, None) { eprintln!("Autofetch error: {}", err); }; } }); Ok(core) } pub fn stream(&self) -> telegram_bot::UpdatesStream { self.tg.stream() } pub fn send<S>(&self, msg: S, target: Option<telegram_bot::UserId>, parse_mode: Option<telegram_bot::types::ParseMode>) -> Result<()> where S: Into<String> { let msg: String = msg.into(); let parse_mode = match parse_mode { Some(mode) => mode, None => telegram_bot::types::ParseMode::Html, }; self.tg.spawn(telegram_bot::SendMessage::new(match target { Some(user) => user, None => self.owner_chat, }, msg.to_owned()).parse_mode(parse_mode)); Ok(()) } pub async fn check<S>(&self, id: &i32, owner: S, real: bool) -> Result<String> where S: Into<i64> { let mut posted: i32 = 0; let owner: i64 = owner.into(); |
︙ | ︙ | |||
318 319 320 321 322 323 324 | //clone.owner_chat(UserId::new(owner)); let clone = Core { owner_chat: telegram_bot::UserId::new(owner), ..self.clone() }; tokio::spawn(async move { if let Err(err) = clone.check(&source_id, owner, true).await { | | | | 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 | //clone.owner_chat(UserId::new(owner)); let clone = Core { owner_chat: telegram_bot::UserId::new(owner), ..self.clone() }; tokio::spawn(async move { if let Err(err) = clone.check(&source_id, owner, true).await { if let Err(err) = clone.send(&format!("🛑 {:?}", err), None, None) { eprintln!("Check error: {}", err); }; }; }); } else { if next_fetch - now < delay { delay = next_fetch - now; } } }; queue.clear(); tokio::time::sleep(delay.to_std()?).await; delay = chrono::Duration::minutes(1); } } pub async fn list<S>(&self, owner: S) -> Result<String> where S: Into<i64> { let owner = owner.into(); let mut reply = vec![]; let mut conn = self.pool.acquire().await .with_context(|| format!("List fetch conn:\n{:?}", &self.pool))?; reply.push("Channels:".to_string()); let rows = sqlx::query("select source_id, channel, enabled, url, iv_hash from rsstg_source where owner = $1 order by source_id") |
︙ | ︙ | |||
360 361 362 363 364 365 366 | true => "🔄 enabled", false => "⛔ disabled", }, url)); if let Some(hash) = iv_hash { reply.push(format!("IV `{}`", hash)); } }; | | | 364 365 366 367 368 369 370 371 372 373 | true => "🔄 enabled", false => "⛔ disabled", }, url)); if let Some(hash) = iv_hash { reply.push(format!("IV `{}`", hash)); } }; Ok(reply.join("\n")) } } |
Modified src/main.rs
from [8ac82f2233]
to [2eed746c52].
1 2 3 4 5 6 | mod command; mod core; use config; use futures::StreamExt; use tokio; | < | | | | | | | | | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 | mod command; mod core; use config; use futures::StreamExt; use tokio; use telegram_bot; #[macro_use] extern crate lazy_static; use anyhow::Result; #[tokio::main] async fn main() -> Result<()> { let mut settings = config::Config::default(); settings.merge(config::File::with_name("rsstg"))?; let core = core::Core::new(settings).await?; let mut stream = core.stream(); stream.allowed_updates(&[telegram_bot::AllowedUpdate::Message]); let mut reply_to: Option<telegram_bot::UserId>; loop { reply_to = None; match stream.next().await { Some(update) => { if let Err(err) = handle(update?, &core, &mut reply_to).await { core.send(&format!("🛑 {:?}", err), reply_to, None)?; }; }, None => { core.send(&format!("🛑 None error."), None, None)?; } }; } //Ok(()) } async fn handle(update: telegram_bot::Update, core: &core::Core, mut _reply_to: &Option<telegram_bot::UserId>) -> Result<()> { match update.kind { telegram_bot::UpdateKind::Message(message) => { match message.kind { telegram_bot::MessageKind::Text { ref data, .. } => { let sender = message.from.id; let words: Vec<&str> = data.split_whitespace().collect(); match words[0] { "/check" | "/clean" | "/enable" | "/delete" | "/disable" => command::command(core, sender, words).await?, "/start" => command::start(core, sender).await?, "/list" => command::list(core, sender).await?, "/add" | "/update" => command::update(core, sender, words).await?, |
︙ | ︙ |