diff --git a/src/commands/count.rs b/src/commands/count.rs index 8868573..b0b6076 100644 --- a/src/commands/count.rs +++ b/src/commands/count.rs @@ -1,26 +1,18 @@ -use regex::Regex; use serenity::{ framework::standard::{macros::command, Args, CommandResult}, model::prelude::*, prelude::*, }; -use std::{collections::HashMap, env}; +use std::env; use tokio_postgres::NoTls; #[command] pub async fn kitna(ctx: &Context, msg: &Message, args: Args) -> CommandResult { let query: String = args.raw().collect::>().join(" "); if query == "" { - msg.reply(ctx, "bruh kitna kya?"); + msg.reply(ctx, "bruh kitna kya?").await?; + return Ok(()) } - let words: HashMap<&str, Regex> = [ - ("nword", Regex::new(r"(?i)(nig+(er|a)|nig{2,})").unwrap()), - ("acha", Regex::new(r"(?i)a((c+?h+?|6+?)a+").unwrap()), - ("sus", Regex::new(r"(?i)sus|(?i)amon??g\s??us").unwrap()), - ] - .iter() - .cloned() - .collect(); let db: String = env::var("DB_URL").expect("bhay DB_URL daal na"); let (client, conn) = tokio_postgres::connect(&db, NoTls) .await @@ -31,20 +23,187 @@ pub async fn kitna(ctx: &Context, msg: &Message, args: Args) -> CommandResult { } }); let id = msg.author.id.as_u64().to_owned().to_string(); - for (name, regex) in words { - if regex.is_match(&query) || &query == name { - let query_result = client - .query_one( - format!("SELECT count FROM user{} where name='{}'", id, name).as_str(), - &[], - ) - .await - .expect("cant select the count"); - let count: i32 = query_result.get("count"); - msg.reply(ctx, format!("{} count for you: {}", name, count)) - .await?; - break; + let mut query_helper = client + .query( + format!("select name from words where '{}' ~ reg", query).as_str(), + &[], + ) + .await + .expect("helper query to select count failed"); + if query_helper.is_empty() { + query_helper = client + .query( + format!("select name from words where name='{}'", query).as_str(), + &[], + ) + .await + .expect("helper query to select count failed"); + if query_helper.is_empty() { + msg.reply( + ctx, + format!( + "No entry for '{}' found. If you want to add it, run 'xxadd {}&'", + query, query + ), + ) + .await?; + return Ok(()); } } + let mut reply: String = if query_helper.len() == 1 { + String::new() + } else { + format!("{} patterns matched", query_helper.len()) + }; + for row in query_helper { + let name: &str = row.get(0); + let query_result: i32 = client + .query_one( + format!("select count from user{} where name='{}'", id, name).as_str(), + &[], + ) + .await + .expect("cant select the count") + .get(0); + reply = reply + &format!("\n{} count for you: {}", name, query_result); + } + msg.reply(ctx, reply).await?; + Ok(()) +} + +#[command] +pub async fn add(ctx: &Context, msg: &Message, args: Args) -> CommandResult { + let query: String = args.raw().collect::>().join(" "); + let queries = query.split("&").collect::>(); + if queries.len() != 2 { + msg.reply(ctx, "Please use the proper syntax: xxadd &\nIf you don't know what regex is, just do: xxadd &") + .await?; + return Ok(()); + } + if queries[1].contains(" ") { + msg.reply(ctx, "Not a valid regex").await?; + return Ok(()); + } + let db: String = env::var("DB_URL").expect("bhay DB_URL daal na"); + let (client, conn) = tokio_postgres::connect(&db, NoTls) + .await + .expect("cant connect bha"); + tokio::spawn(async move { + if let Err(e) = conn.await { + eprintln!("connection error: {}", e); + } + }); + let check_existense = client + .query( + format!("select name, reg from words where name='{}'", queries[0]).as_str(), + &[], + ) + .await?; + if check_existense.len() != 0 { + let reg: String = check_existense[0].get(1); + msg.reply( + ctx, + format!("This word already exists with the regex '{}'", reg), + ) + .await?; + return Ok(()); + } + client + .execute( + format!( + "insert into words(name, reg, owner) values('{}','(?i){}', '{}')", + queries[0], + queries[1], + msg.author.id.as_u64().to_owned().to_string() + ) + .as_str(), + &[], + ) + .await?; + msg.reply(ctx, "Added").await?; + Ok(()) +} + +#[command] +pub async fn rm(ctx: &Context, msg: &Message, args: Args) -> CommandResult { + let query: String = args.raw().collect::>().join(" "); + let db: String = env::var("DB_URL").expect("bhay DB_URL daal na"); + let (client, conn) = tokio_postgres::connect(&db, NoTls) + .await + .expect("cant connect bha"); + tokio::spawn(async move { + if let Err(e) = conn.await { + eprintln!("connection error: {}", e); + } + }); + let owner = client + .query( + format!("select owner from words where name = '{}'", query).as_str(), + &[], + ) + .await?; + if owner.len() == 1 { + let owner_id: String = owner[0].get(0); + if owner_id != msg.author.id.as_u64().to_owned().to_string() { + msg.reply(ctx, "You don't even own this word").await?; + return Ok(()); + } + } + client + .execute( + format!("delete from words where name='{}'", query,).as_str(), + &[], + ) + .await?; + msg.reply(ctx, "Deleted if it existed").await?; + Ok(()) +} + +#[command] +pub async fn change(ctx: &Context, msg: &Message, args: Args) -> CommandResult { + let query: String = args.raw().collect::>().join(" "); + let queries = query.split("&").collect::>(); + if queries.len() != 2 { + msg.reply(ctx, "Please use the proper syntax\nxxchange &") + .await?; + return Ok(()); + } + if queries[1].contains(" ") { + msg.reply(ctx, "Not a valid regex").await?; + return Ok(()); + } + let db: String = env::var("DB_URL").expect("bhay DB_URL daal na"); + let (client, conn) = tokio_postgres::connect(&db, NoTls) + .await + .expect("cant connect bha"); + tokio::spawn(async move { + if let Err(e) = conn.await { + eprintln!("connection error: {}", e); + } + }); + let owner = client + .query( + format!("select owner from words where name = '{}'", queries[0]).as_str(), + &[], + ) + .await?; + if owner.len() == 1 { + let owner_id: String = owner[0].get(0); + if owner_id != msg.author.id.as_u64().to_owned().to_string() { + msg.reply(ctx, "You don't even own this word").await?; + return Ok(()); + } + } + client + .execute( + format!( + "update words set reg='(?i){}' where name='{}'", + queries[1], queries[0] + ) + .as_str(), + &[], + ) + .await?; + msg.reply(ctx, "Changed the value if it existed").await?; Ok(()) } diff --git a/src/commands/minigames.rs b/src/commands/minigames.rs index ee59340..3c19723 100644 --- a/src/commands/minigames.rs +++ b/src/commands/minigames.rs @@ -6,7 +6,8 @@ use serenity::{ }; use std::time::Duration; -async fn chall(ctx: &Context, msg: &Message) -> CommandResult { +#[command] +pub async fn challenge(ctx: &Context, msg: &Message) -> CommandResult { if msg.mentions.is_empty() { msg.reply(ctx, "mention to daal chutiye").await?; return Ok(()); @@ -35,7 +36,7 @@ async fn chall(ctx: &Context, msg: &Message) -> CommandResult { } else if ["no", "nahi", "n"].contains(&answer.content.to_lowercase().as_str()) { msg.reply(ctx, "Challenge not accepted").await?; challenge.delete(&ctx.http).await?; - return 1; + return Ok(()); } else { answer .reply( @@ -43,17 +44,12 @@ async fn chall(ctx: &Context, msg: &Message) -> CommandResult { "Please only answer in no/nahi/n or yes/ha/y\ndeleting challenge ...", ) .await?; - return 1; + return Ok(()); } } else { msg.reply(ctx, "Challenge not accepted in 60s").await?; - return 1; + return Ok(()); } - return 0; -} - -#[command] -pub async fn challenge(ctx: &Context, msg: &Message) -> CommandResult { let won = random(); let winner = if won { msg.mentions[0].mention() diff --git a/src/handler/count.rs b/src/handler/count.rs index 62ae4da..2082e83 100644 --- a/src/handler/count.rs +++ b/src/handler/count.rs @@ -1,18 +1,9 @@ use regex::Regex; use serenity::model::channel::Message; -use std::collections::HashMap; use std::env; use tokio_postgres::NoTls; pub async fn count(msg: Message) { - let words: HashMap<&str, Regex> = [ - ("nword", Regex::new(r"(?i)(nig+(er|a)|nig{2,})").unwrap()), - ("acha", Regex::new(r"(?i)a(c+?h+?|6+?)a+").unwrap()), - ("sus", Regex::new(r"(?i)sus|(?i)amon??g\s??us").unwrap()), - ] - .iter() - .cloned() - .collect(); let db: String = env::var("DB_URL").expect("bhay DB_URL daal na"); let (client, conn) = tokio_postgres::connect(&db, NoTls) .await @@ -41,8 +32,14 @@ pub async fn count(msg: Message) { .await .expect("cant create table"); - for name in ["nword", "acha", "sus"] { - let count = words[name].captures_iter(&msg.content).count(); + for row in client + .query("SELECT name, reg FROM words", &[]) + .await + .expect("can't get the words to count") + { + let name: &str = row.get(0); + let regex: Regex = Regex::new(row.get(1)).unwrap(); + let count = regex.captures_iter(&msg.content).count(); if count > 0 { let query_result = client .query( diff --git a/src/main.rs b/src/main.rs index 4cf826f..16476e2 100644 --- a/src/main.rs +++ b/src/main.rs @@ -23,7 +23,7 @@ impl TypeMapKey for ShardManagerContainer { struct General; #[group] -#[commands(kitna)] +#[commands(kitna,add,rm,change)] struct Count; #[group]