Add fuzzy whois commands

This commit is contained in:
Aadi Desai 2023-09-25 21:32:48 +01:00
parent 89a9d2b085
commit d8f87d4ebd
Signed by: supleed2
SSH key fingerprint: SHA256:CkbNRs0yVzXEiUp2zd0PSxsfRUMFF9bLlKXtE1xEbKM
5 changed files with 168 additions and 9 deletions

View file

@ -0,0 +1,47 @@
{
"db_name": "PostgreSQL",
"query": "select * from members where similarity(realname,$1) > 0.3 order by similarity(realname,$1) desc limit $2",
"describe": {
"columns": [
{
"ordinal": 0,
"name": "discord_id",
"type_info": "Int8"
},
{
"ordinal": 1,
"name": "shortcode",
"type_info": "Varchar"
},
{
"ordinal": 2,
"name": "nickname",
"type_info": "Text"
},
{
"ordinal": 3,
"name": "realname",
"type_info": "Text"
},
{
"ordinal": 4,
"name": "fresher",
"type_info": "Bool"
}
],
"parameters": {
"Left": [
"Text",
"Int8"
]
},
"nullable": [
false,
false,
false,
false,
false
]
},
"hash": "1f1b8289dc5079b3b4516f69436d403400bd6d70a26e2a73e2f60999c45b09d9"
}

View file

@ -0,0 +1,47 @@
{
"db_name": "PostgreSQL",
"query": "select * from members where similarity(nickname,$1) > 0.3 order by similarity(nickname,$1) desc limit $2",
"describe": {
"columns": [
{
"ordinal": 0,
"name": "discord_id",
"type_info": "Int8"
},
{
"ordinal": 1,
"name": "shortcode",
"type_info": "Varchar"
},
{
"ordinal": 2,
"name": "nickname",
"type_info": "Text"
},
{
"ordinal": 3,
"name": "realname",
"type_info": "Text"
},
{
"ordinal": 4,
"name": "fresher",
"type_info": "Bool"
}
],
"parameters": {
"Left": [
"Text",
"Int8"
]
},
"nullable": [
false,
false,
false,
false,
false
]
},
"hash": "b8d6ddf5d4f4f009ac27e78005c1fe898de981a7c148d692dc812bfe21dc4558"
}

View file

@ -0,0 +1 @@
CREATE EXTENSION pg_trgm;

View file

@ -572,20 +572,36 @@ pub(crate) async fn whois_by_id(ctx: ACtx<'_>, id: serenity::User) -> Result<(),
#[poise::command(slash_command, rename = "nick")]
pub(crate) async fn whois_by_nickname(ctx: ACtx<'_>, nickname: String) -> Result<(), Error> {
println!("Cmd: ({}) whois_by_nickname {nickname}", ctx.author().name);
// TODO: fuzzy finding
match db::get_member_by_nickname(&ctx.data().db, &nickname).await? {
Some(m) => {
ctx.send(|c| {
c.content(format!("{nickname}: <@{}>", m.discord_id))
.ephemeral(true)
})
.await?
.await?;
}
None => {
ctx.say(format!("No member entry found for nickname {nickname}",))
.await?
let members = db::get_member_by_nickname_fuzzy(&ctx.data().db, &nickname, 3).await?;
if members.is_empty() {
ctx.send(|c| {
c.content(format!("No member entry found for nickname {nickname}"))
.ephemeral(true)
})
.await?;
} else {
ctx.send(|c| {
c.ephemeral(true).content(format!(
"Possible matches for {nickname}: {}",
members
.iter()
.map(|m| format!(" <@{}>", m.discord_id))
.collect::<String>()
))
})
.await?;
}
}
}
};
Ok(())
}
@ -593,18 +609,34 @@ pub(crate) async fn whois_by_nickname(ctx: ACtx<'_>, nickname: String) -> Result
#[poise::command(slash_command, rename = "name")]
pub(crate) async fn whois_by_realname(ctx: ACtx<'_>, realname: String) -> Result<(), Error> {
println!("Cmd: ({}) whois_by_realname {realname}", ctx.author().name);
// TODO: fuzzy finding
match db::get_member_by_realname(&ctx.data().db, &realname).await? {
Some(m) => {
ctx.send(|c| {
c.content(format!("{realname}: <@{}>", m.discord_id))
.ephemeral(true)
})
.await?
.await?;
}
None => {
ctx.say(format!("No member entry found for realname {realname}",))
.await?
let members = db::get_member_by_realname_fuzzy(&ctx.data().db, &realname, 3).await?;
if members.is_empty() {
ctx.send(|c| {
c.content(format!("No member entry found for realname {realname}"))
.ephemeral(true)
})
.await?;
} else {
ctx.send(|c| {
c.ephemeral(true).content(format!(
"Possible matches for {realname}: {}",
members
.iter()
.map(|m| format!(" <@{}>", m.discord_id))
.collect::<String>()
))
})
.await?;
}
}
};
Ok(())

View file

@ -64,6 +64,22 @@ pub(crate) async fn get_member_by_nickname(
.await?)
}
/// Get member entry by Nickname (Fuzzy)
pub(crate) async fn get_member_by_nickname_fuzzy(
pool: &sqlx::PgPool,
nickname: &str,
limit: i64,
) -> Result<Vec<Member>, Error> {
Ok(sqlx::query_as!(
Member,
"select * from members where similarity(nickname,$1) > 0.3 order by similarity(nickname,$1) desc limit $2",
nickname,
limit,
)
.fetch_all(pool)
.await?)
}
/// Get member entry by Real Name
pub(crate) async fn get_member_by_realname(
pool: &sqlx::PgPool,
@ -78,6 +94,22 @@ pub(crate) async fn get_member_by_realname(
.await?)
}
/// Get member entry by Real Name (Fuzzy)
pub(crate) async fn get_member_by_realname_fuzzy(
pool: &sqlx::PgPool,
realname: &str,
limit: i64,
) -> Result<Vec<Member>, Error> {
Ok(sqlx::query_as!(
Member,
"select * from members where similarity(realname,$1) > 0.3 order by similarity(realname,$1) desc limit $2",
realname,
limit,
)
.fetch_all(pool)
.await?)
}
/// Add member entry to members table
pub(crate) async fn insert_member(pool: &sqlx::PgPool, m: Member) -> Result<(), Error> {
sqlx::query!(