mirror of
https://github.com/supleed2/nanobot.git
synced 2024-12-22 14:15:51 +00:00
Add fuzzy whois
commands
This commit is contained in:
parent
89a9d2b085
commit
d8f87d4ebd
|
@ -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"
|
||||||
|
}
|
|
@ -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"
|
||||||
|
}
|
1
migrations/20230925132804_pg_trgm.sql
Normal file
1
migrations/20230925132804_pg_trgm.sql
Normal file
|
@ -0,0 +1 @@
|
||||||
|
CREATE EXTENSION pg_trgm;
|
50
src/cmds.rs
50
src/cmds.rs
|
@ -572,20 +572,36 @@ pub(crate) async fn whois_by_id(ctx: ACtx<'_>, id: serenity::User) -> Result<(),
|
||||||
#[poise::command(slash_command, rename = "nick")]
|
#[poise::command(slash_command, rename = "nick")]
|
||||||
pub(crate) async fn whois_by_nickname(ctx: ACtx<'_>, nickname: String) -> Result<(), Error> {
|
pub(crate) async fn whois_by_nickname(ctx: ACtx<'_>, nickname: String) -> Result<(), Error> {
|
||||||
println!("Cmd: ({}) whois_by_nickname {nickname}", ctx.author().name);
|
println!("Cmd: ({}) whois_by_nickname {nickname}", ctx.author().name);
|
||||||
// TODO: fuzzy finding
|
|
||||||
match db::get_member_by_nickname(&ctx.data().db, &nickname).await? {
|
match db::get_member_by_nickname(&ctx.data().db, &nickname).await? {
|
||||||
Some(m) => {
|
Some(m) => {
|
||||||
ctx.send(|c| {
|
ctx.send(|c| {
|
||||||
c.content(format!("{nickname}: <@{}>", m.discord_id))
|
c.content(format!("{nickname}: <@{}>", m.discord_id))
|
||||||
.ephemeral(true)
|
.ephemeral(true)
|
||||||
})
|
})
|
||||||
.await?
|
.await?;
|
||||||
}
|
}
|
||||||
None => {
|
None => {
|
||||||
ctx.say(format!("No member entry found for nickname {nickname}",))
|
let members = db::get_member_by_nickname_fuzzy(&ctx.data().db, &nickname, 3).await?;
|
||||||
.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(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -593,18 +609,34 @@ pub(crate) async fn whois_by_nickname(ctx: ACtx<'_>, nickname: String) -> Result
|
||||||
#[poise::command(slash_command, rename = "name")]
|
#[poise::command(slash_command, rename = "name")]
|
||||||
pub(crate) async fn whois_by_realname(ctx: ACtx<'_>, realname: String) -> Result<(), Error> {
|
pub(crate) async fn whois_by_realname(ctx: ACtx<'_>, realname: String) -> Result<(), Error> {
|
||||||
println!("Cmd: ({}) whois_by_realname {realname}", ctx.author().name);
|
println!("Cmd: ({}) whois_by_realname {realname}", ctx.author().name);
|
||||||
// TODO: fuzzy finding
|
|
||||||
match db::get_member_by_realname(&ctx.data().db, &realname).await? {
|
match db::get_member_by_realname(&ctx.data().db, &realname).await? {
|
||||||
Some(m) => {
|
Some(m) => {
|
||||||
ctx.send(|c| {
|
ctx.send(|c| {
|
||||||
c.content(format!("{realname}: <@{}>", m.discord_id))
|
c.content(format!("{realname}: <@{}>", m.discord_id))
|
||||||
.ephemeral(true)
|
.ephemeral(true)
|
||||||
})
|
})
|
||||||
.await?
|
.await?;
|
||||||
}
|
}
|
||||||
None => {
|
None => {
|
||||||
ctx.say(format!("No member entry found for realname {realname}",))
|
let members = db::get_member_by_realname_fuzzy(&ctx.data().db, &realname, 3).await?;
|
||||||
.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(())
|
Ok(())
|
||||||
|
|
|
@ -64,6 +64,22 @@ pub(crate) async fn get_member_by_nickname(
|
||||||
.await?)
|
.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
|
/// Get member entry by Real Name
|
||||||
pub(crate) async fn get_member_by_realname(
|
pub(crate) async fn get_member_by_realname(
|
||||||
pool: &sqlx::PgPool,
|
pool: &sqlx::PgPool,
|
||||||
|
@ -78,6 +94,22 @@ pub(crate) async fn get_member_by_realname(
|
||||||
.await?)
|
.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
|
/// Add member entry to members table
|
||||||
pub(crate) async fn insert_member(pool: &sqlx::PgPool, m: Member) -> Result<(), Error> {
|
pub(crate) async fn insert_member(pool: &sqlx::PgPool, m: Member) -> Result<(), Error> {
|
||||||
sqlx::query!(
|
sqlx::query!(
|
||||||
|
|
Loading…
Reference in a new issue