Index: Cargo.lock ================================================================== --- Cargo.lock +++ Cargo.lock @@ -2046,11 +2046,11 @@ "reqwest 0.9.24", ] [[package]] name = "rsstg" -version = "0.2.0" +version = "0.2.1" dependencies = [ "anyhow", "atom_syndication", "chrono", "config", Index: src/command.rs ================================================================== --- src/command.rs +++ src/command.rs @@ -67,15 +67,19 @@ Some(hash) => { if ! RE_IV_HASH.is_match(hash) { bail!("IV hash should be 14 hex digits.\nNot {:?}", hash); }; Some(*hash) - } + }, None => None, }; - if let Some(rex) = url_re { - let _url_rex = ReplaceCommand::new(rex).context("Regexp parsing error:")?; + let url_re = match url_re { + Some(re) => { + let _url_rex = ReplaceCommand::new(re).context("Regexp parsing error:")?; + Some(*re) + }, + None => None, }; let channel_id = i64::from(core.tg.send(telegram_bot::GetChat::new(telegram_bot::types::ChatRef::ChannelUsername(channel.to_string()))).await?.id()); let chan_adm = core.tg.send(telegram_bot::GetChatAdministrators::new(telegram_bot::types::ChatRef::ChannelUsername(channel.to_string()))).await .context("Sorry, I have no access to that chat.")?; let (mut me, mut user) = (false, false); @@ -87,8 +91,8 @@ 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)?; + core.send(core.update(source_id, channel, channel_id, url, iv_hash, url_re, sender).await?, Some(sender), None)?; Ok(()) } Index: src/core.rs ================================================================== --- src/core.rs +++ src/core.rs @@ -1,10 +1,9 @@ use anyhow::{anyhow, bail, Context, Result}; use atom_syndication; use chrono::DateTime; use config; -use regex::Regex; use reqwest; use sqlx::{ postgres::PgPoolOptions, Row, }; @@ -101,13 +100,18 @@ .fetch_one(&mut conn).await .with_context(|| format!("Query source:\n{:?}", &self.pool))?; drop(conn); let channel_id: i64 = row.try_get("channel_id")?; let url: &str = row.try_get("url")?; + /*let url: Cow<'a, str> = match row.try_get("url") { + Ok(x) => String::from(x).to_owned().into(), + Err(err) => bail!("Test"), + };*/ let iv_hash: Option<&str> = row.try_get("iv_hash")?; - let url_re: Option = match row.try_get("url_re")? { - Some(x) => Some(Regex::new(x)?), + //let url_re: Option = match row.try_get("url_re")? { + let url_re = match row.try_get("url_re")? { + Some(x) => Some(sedregex::ReplaceCommand::new(x)?), None => None, }; let destination = match real { true => telegram_bot::UserId::new(channel_id), false => telegram_bot::UserId::new(row.try_get("owner")?), @@ -122,12 +126,12 @@ Some(link) => { let date = match item.pub_date() { Some(feed_date) => DateTime::parse_from_rfc2822(feed_date), None => DateTime::parse_from_rfc3339(&item.dublin_core_ext().unwrap().dates()[0]), }?; - let url = link.to_string(); - posts.insert(date.clone(), url.clone()); + let url = link; + posts.insert(date.clone(), url.into()); }, None => {} } }; }, @@ -136,11 +140,11 @@ let feed = atom_syndication::Feed::read_from(&content[..]) .with_context(|| format!("Problem opening feed url:\n{}", &url))?; for item in feed.entries() { let date = item.published().unwrap(); let url = item.links()[0].href(); - posts.insert(date.clone(), url.to_string()); + posts.insert(date.clone(), url.into()); }; }, rss::Error::Eof => (), _ => bail!("Unsupported or mangled content:\n{:?}\n{:#?}\n", &url, err) } @@ -147,30 +151,27 @@ }; for (date, url) in posts.iter() { let mut conn = self.pool.acquire().await .with_context(|| format!("Check post fetch conn:\n{:?}", &self.pool))?; let row = sqlx::query("select exists(select true from rsstg_post where url = $1 and source_id = $2) as exists;") - .bind(&url) + .bind(url) .bind(*id) .fetch_one(&mut conn).await .with_context(|| format!("Check post:\n{:?}", &conn))?; let exists: bool = row.try_get("exists")?; if ! exists { if this_fetch == None || *date > this_fetch.unwrap() { this_fetch = Some(*date); }; self.tg.send( match iv_hash { - Some(x) => telegram_bot::SendMessage::new(destination, format!(" {0}", match &url_re { - Some(x) => match x.captures(&url) { - Some(x) => { - bail!("Regex hit, result:\n{:#?}", &x[0]); - &x[0] - }, - None => &url, - }, - None => &url, - }, x)), + Some(hash) => telegram_bot::SendMessage::new(destination, format!(" {0}", match url_re { + Some(x) => { + bail!("Regex hit, result:\n{:#?}", x.execute(url)); + url + }, + None => url, + }, hash)), None => telegram_bot::SendMessage::new(destination, format!("{}", url)), }.parse_mode(telegram_bot::types::ParseMode::Html)).await .context("Can't post message:")?; sqlx::query("insert into rsstg_post (source_id, posted, url) values ($1, $2, $3);") .bind(*id) @@ -203,12 +204,12 @@ .bind(source_id) .bind(owner) .execute(&mut conn).await .with_context(|| format!("Delete source rule:\n{:?}", &self.pool))? .rows_affected() { - 0 => { Ok("No data found found\\.".to_string()) }, - x => { Ok(format!("{} sources removed\\.", x)) }, + 0 => { Ok("No data found found.".to_string()) }, + x => { Ok(format!("{} sources removed.", x)) }, } } pub async fn clean(&self, source_id: &i32, owner: S) -> Result where S: Into { @@ -219,12 +220,12 @@ .bind(source_id) .bind(owner) .execute(&mut conn).await .with_context(|| format!("Clean seen posts:\n{:?}", &self.pool))? .rows_affected() { - 0 => { Ok("No data found found\\.".to_string()) }, - x => { Ok(format!("{} posts purged\\.", x)) }, + 0 => { Ok("No data found found.".to_string()) }, + x => { Ok(format!("{} posts purged.", x)) }, } } pub async fn enable(&self, source_id: &i32, owner: S) -> Result<&str> where S: Into { @@ -235,12 +236,12 @@ .bind(source_id) .bind(owner) .execute(&mut conn).await .with_context(|| format!("Enable source:\n{:?}", &self.pool))? .rows_affected() { - 1 => { Ok("Source enabled\\.") }, - 0 => { Ok("Source not found\\.") }, + 1 => { Ok("Source enabled.") }, + 0 => { Ok("Source not found.") }, _ => { Err(anyhow!("Database error.")) }, } } pub async fn disable(&self, source_id: &i32, owner: S) -> Result<&str> @@ -252,12 +253,12 @@ .bind(source_id) .bind(owner) .execute(&mut conn).await .with_context(|| format!("Disable source:\n{:?}", &self.pool))? .rows_affected() { - 1 => { Ok("Source disabled\\.") }, - 0 => { Ok("Source not found\\.") }, + 1 => { Ok("Source disabled.") }, + 0 => { Ok("Source not found.") }, _ => { Err(anyhow!("Database error.")) }, } } pub async fn update(&self, update: Option, channel: &str, channel_id: i64, url: &str, iv_hash: Option<&str>, url_re: Option<&str>, owner: S) -> Result @@ -266,11 +267,11 @@ let mut conn = self.pool.acquire().await .with_context(|| format!("Update fetch conn:\n{:?}", &self.pool))?; match match update { Some(id) => { - sqlx::query("update rsstg_source set channel_id = $2, url = $3, iv_hash = $4, owner = $5, channel = $6 where source_id = $1").bind(id) + sqlx::query("update rsstg_source set channel_id = $2, url = $3, iv_hash = $4, owner = $5, channel = $6, url_re = $7 where source_id = $1").bind(id) }, None => { sqlx::query("insert into rsstg_source (channel_id, url, iv_hash, owner, channel, url_re) values ($1, $2, $3, $4, $5, $6)") }, } @@ -280,23 +281,23 @@ .bind(owner) .bind(channel) .bind(url_re) .execute(&mut conn).await { Ok(_) => return Ok(String::from(match update { - Some(_) => "Channel updated\\.", - None => "Channel added\\.", + Some(_) => "Channel updated.", + None => "Channel added.", })), Err(sqlx::Error::Database(err)) => { match err.downcast::().routine() { Some("_bt_check_unique", ) => { - return Ok("Duplicate key\\.".to_string()) + return Ok("Duplicate key.".to_string()) }, Some(_) => { - return Ok("Database error\\.".to_string()) + return Ok("Database error.".to_string()) }, None => { - return Ok("No database error extracted\\.".to_string()) + return Ok("No database error extracted.".to_string()) }, }; }, Err(err) => { bail!("Sorry, unknown error:\n{:#?}\n", err);