check referenced message as well
Signed-off-by: Amneesh Singh <natto@weirdnatto.in>
This commit is contained in:
4
.gitignore
vendored
4
.gitignore
vendored
@@ -1,2 +1,6 @@
|
|||||||
target/
|
target/
|
||||||
result
|
result
|
||||||
|
\#*\#
|
||||||
|
.\#*
|
||||||
|
.*~*~
|
||||||
|
*~
|
||||||
|
10
Cargo.lock
generated
10
Cargo.lock
generated
@@ -532,6 +532,15 @@ version = "0.2.97"
|
|||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "12b8adadd720df158f4d70dfe7ccc6adb0472d7c55ca83445f6a5ab3e36f8fb6"
|
checksum = "12b8adadd720df158f4d70dfe7ccc6adb0472d7c55ca83445f6a5ab3e36f8fb6"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "linkify"
|
||||||
|
version = "0.8.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "ccbcd666d915aa3ae3c3774999a9e20b2776a018309b8159d07df062b91f45e8"
|
||||||
|
dependencies = [
|
||||||
|
"memchr",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "lock_api"
|
name = "lock_api"
|
||||||
version = "0.4.4"
|
version = "0.4.4"
|
||||||
@@ -1120,6 +1129,7 @@ dependencies = [
|
|||||||
name = "singh3"
|
name = "singh3"
|
||||||
version = "0.1.0"
|
version = "0.1.0"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
|
"linkify",
|
||||||
"rand 0.8.4",
|
"rand 0.8.4",
|
||||||
"regex",
|
"regex",
|
||||||
"serenity",
|
"serenity",
|
||||||
|
@@ -9,6 +9,7 @@ tracing = "*"
|
|||||||
regex = "1"
|
regex = "1"
|
||||||
tokio-postgres = "*"
|
tokio-postgres = "*"
|
||||||
rand = "*"
|
rand = "*"
|
||||||
|
linkify = "*"
|
||||||
|
|
||||||
[dependencies.serenity]
|
[dependencies.serenity]
|
||||||
version = "0.10.10"
|
version = "0.10.10"
|
||||||
|
@@ -59,6 +59,7 @@ EOF
|
|||||||
config {
|
config {
|
||||||
image = "natto17/singh3:latest"
|
image = "natto17/singh3:latest"
|
||||||
force_pull = true
|
force_pull = true
|
||||||
|
volumes = [ "/tmp:/tmp" ]
|
||||||
}
|
}
|
||||||
|
|
||||||
template {
|
template {
|
||||||
|
@@ -1,4 +1,4 @@
|
|||||||
use crate::lib::components::make_terminal_components;
|
use crate::lib::{components::make_terminal_components, messages::ExtractInfo};
|
||||||
use core::time::Duration;
|
use core::time::Duration;
|
||||||
use serenity::{
|
use serenity::{
|
||||||
builder::CreateEmbed,
|
builder::CreateEmbed,
|
||||||
@@ -11,6 +11,9 @@ use serenity::{
|
|||||||
};
|
};
|
||||||
use tokio_postgres::Row;
|
use tokio_postgres::Row;
|
||||||
|
|
||||||
|
const GUILD_ID: u64 = 874699899067838535;
|
||||||
|
const ROLE_ID: u64 = 957155053184102400;
|
||||||
|
|
||||||
#[command]
|
#[command]
|
||||||
#[aliases("t")]
|
#[aliases("t")]
|
||||||
pub async fn tag(ctx: &Context, msg: &Message, args: Args) -> CommandResult {
|
pub async fn tag(ctx: &Context, msg: &Message, args: Args) -> CommandResult {
|
||||||
@@ -63,10 +66,10 @@ pub async fn tag(ctx: &Context, msg: &Message, args: Args) -> CommandResult {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[command]
|
#[command]
|
||||||
pub async fn tadd(ctx: &Context, msg: &Message, args: Args) -> CommandResult {
|
pub async fn tadd(ctx: &Context, msg: &Message, mut args: Args) -> CommandResult {
|
||||||
let query: String = args.raw().collect::<Vec<&str>>().join(" ");
|
let tag_value = msg.extract_text(2, true);
|
||||||
let queries = query.splitn(2, " ").collect::<Vec<&str>>();
|
|
||||||
if queries.len() != 2 && msg.attachments.len() == 0 {
|
if tag_value.is_none() {
|
||||||
msg.reply(
|
msg.reply(
|
||||||
ctx,
|
ctx,
|
||||||
"Please use the proper syntax: `,tadd <name> <value>` or attach something",
|
"Please use the proper syntax: `,tadd <name> <value>` or attach something",
|
||||||
@@ -74,13 +77,15 @@ pub async fn tadd(ctx: &Context, msg: &Message, args: Args) -> CommandResult {
|
|||||||
.await?;
|
.await?;
|
||||||
return Ok(());
|
return Ok(());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
let tag_name = args.single::<String>().unwrap();
|
||||||
let data_read = ctx.data.read().await;
|
let data_read = ctx.data.read().await;
|
||||||
let db = data_read
|
let db = data_read
|
||||||
.get::<crate::Database>()
|
.get::<crate::Database>()
|
||||||
.expect("Expected Database in TypeMap.")
|
.expect("Expected Database in TypeMap.")
|
||||||
.clone();
|
.clone();
|
||||||
let check_existense = db
|
let check_existense = db
|
||||||
.query("SELECT name FROM tags WHERE name=$1", &[&queries[0]])
|
.query("SELECT name FROM tags WHERE name=$1", &[&tag_name])
|
||||||
.await?;
|
.await?;
|
||||||
if check_existense.len() != 0 {
|
if check_existense.len() != 0 {
|
||||||
msg.reply(ctx, format!("This tag already exists")).await?;
|
msg.reply(ctx, format!("This tag already exists")).await?;
|
||||||
@@ -88,23 +93,7 @@ pub async fn tadd(ctx: &Context, msg: &Message, args: Args) -> CommandResult {
|
|||||||
}
|
}
|
||||||
db.execute(
|
db.execute(
|
||||||
"INSERT INTO tags(name, value, owner) VALUES($1, $2, $3)",
|
"INSERT INTO tags(name, value, owner) VALUES($1, $2, $3)",
|
||||||
&[
|
&[&tag_name, &tag_value, &msg.author.id.to_string()],
|
||||||
&queries[0],
|
|
||||||
&format!(
|
|
||||||
"{}{}",
|
|
||||||
if queries.len() == 2 {
|
|
||||||
format!("{}{}", queries[1], '\n')
|
|
||||||
} else {
|
|
||||||
"".to_string()
|
|
||||||
},
|
|
||||||
msg.attachments
|
|
||||||
.iter()
|
|
||||||
.map(|x| x.url.clone())
|
|
||||||
.collect::<Vec<String>>()
|
|
||||||
.join("\n")
|
|
||||||
),
|
|
||||||
&msg.author.id.to_string(),
|
|
||||||
],
|
|
||||||
)
|
)
|
||||||
.await?;
|
.await?;
|
||||||
msg.reply(ctx, "Added").await?;
|
msg.reply(ctx, "Added").await?;
|
||||||
@@ -163,7 +152,9 @@ pub async fn tremove(ctx: &Context, msg: &Message, args: Args) -> CommandResult
|
|||||||
.await?;
|
.await?;
|
||||||
if owner.len() == 1 {
|
if owner.len() == 1 {
|
||||||
let owner_id: String = owner[0].get(0);
|
let owner_id: String = owner[0].get(0);
|
||||||
if owner_id != msg.author.id.to_string() {
|
if owner_id != msg.author.id.to_string()
|
||||||
|
&& !msg.author.has_role(&ctx.http, GUILD_ID, ROLE_ID).await?
|
||||||
|
{
|
||||||
msg.reply(ctx, "You don't even own this tag").await?;
|
msg.reply(ctx, "You don't even own this tag").await?;
|
||||||
return Ok(());
|
return Ok(());
|
||||||
}
|
}
|
||||||
@@ -176,50 +167,39 @@ pub async fn tremove(ctx: &Context, msg: &Message, args: Args) -> CommandResult
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[command]
|
#[command]
|
||||||
pub async fn tedit(ctx: &Context, msg: &Message, args: Args) -> CommandResult {
|
pub async fn tedit(ctx: &Context, msg: &Message, mut args: Args) -> CommandResult {
|
||||||
let query: String = args.raw().collect::<Vec<&str>>().join(" ");
|
let tag_value = msg.extract_text(2, true);
|
||||||
let queries = query.splitn(2, " ").collect::<Vec<&str>>();
|
|
||||||
if queries.len() != 2 && msg.attachments.len() == 0 {
|
if tag_value.is_none() {
|
||||||
msg.reply(
|
msg.reply(
|
||||||
ctx,
|
ctx,
|
||||||
"Please use the proper syntax or attach something\n`,tedit <name> <value>`",
|
"Please use the proper syntax: `,tadd <name> <value>` or attach something",
|
||||||
)
|
)
|
||||||
.await?;
|
.await?;
|
||||||
return Ok(());
|
return Ok(());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
let tag_name = args.single::<String>().unwrap();
|
||||||
let data_read = ctx.data.read().await;
|
let data_read = ctx.data.read().await;
|
||||||
let db = data_read
|
let db = data_read
|
||||||
.get::<crate::Database>()
|
.get::<crate::Database>()
|
||||||
.expect("Expected Database in TypeMap.")
|
.expect("Expected Database in TypeMap.")
|
||||||
.clone();
|
.clone();
|
||||||
let owner = db
|
let owner = db
|
||||||
.query("SELECT owner FROM tags WHERE name=$1", &[&queries[0]])
|
.query("SELECT owner FROM tags WHERE name=$1", &[&tag_name])
|
||||||
.await?;
|
.await?;
|
||||||
if owner.len() == 1 {
|
if owner.len() == 1 {
|
||||||
let owner_id: String = owner[0].get(0);
|
let owner_id: String = owner[0].get(0);
|
||||||
if owner_id != msg.author.id.to_string() {
|
if owner_id != msg.author.id.to_string()
|
||||||
|
&& !msg.author.has_role(&ctx.http, GUILD_ID, ROLE_ID).await?
|
||||||
|
{
|
||||||
msg.reply(ctx, "You don't even own this tag").await?;
|
msg.reply(ctx, "You don't even own this tag").await?;
|
||||||
return Ok(());
|
return Ok(());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
db.execute(
|
db.execute(
|
||||||
"UPDATE tags SET value=$1 WHERE name=$2",
|
"UPDATE tags SET value=$1 WHERE name=$2",
|
||||||
&[
|
&[&tag_value, &tag_name],
|
||||||
&format!(
|
|
||||||
"{}{}",
|
|
||||||
if queries.len() == 2 {
|
|
||||||
format!("{}{}", queries[1], '\n')
|
|
||||||
} else {
|
|
||||||
"".to_string()
|
|
||||||
},
|
|
||||||
msg.attachments
|
|
||||||
.iter()
|
|
||||||
.map(|x| x.url.clone())
|
|
||||||
.collect::<Vec<String>>()
|
|
||||||
.join("\n")
|
|
||||||
),
|
|
||||||
&queries[0],
|
|
||||||
],
|
|
||||||
)
|
)
|
||||||
.await?;
|
.await?;
|
||||||
msg.reply(ctx, "Changed the value if it existed").await?;
|
msg.reply(ctx, "Changed the value if it existed").await?;
|
||||||
|
87
src/lib/messages.rs
Normal file
87
src/lib/messages.rs
Normal file
@@ -0,0 +1,87 @@
|
|||||||
|
use linkify::LinkFinder;
|
||||||
|
use serenity::model::channel::Message;
|
||||||
|
|
||||||
|
#[derive(Default)]
|
||||||
|
pub struct URLExtractInfo {
|
||||||
|
urls: Vec<String>,
|
||||||
|
n_attachments: u8,
|
||||||
|
n_links: u16,
|
||||||
|
rn_attachments: Option<u8>,
|
||||||
|
rn_links: Option<u16>,
|
||||||
|
}
|
||||||
|
|
||||||
|
pub trait ExtractInfo {
|
||||||
|
fn extract_urls(&self) -> URLExtractInfo;
|
||||||
|
fn extract_text(&self, skip: usize, with_ref: bool) -> Option<String>;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Priority: Text > Attachments > Reference
|
||||||
|
impl ExtractInfo for Message {
|
||||||
|
fn extract_urls(&self) -> URLExtractInfo {
|
||||||
|
let mut ret = URLExtractInfo::default();
|
||||||
|
let finder = LinkFinder::new();
|
||||||
|
let find_links = |x| finder.links(x).map(|x| x.as_str().to_string()).collect();
|
||||||
|
|
||||||
|
ret.urls = find_links(&self.content);
|
||||||
|
|
||||||
|
ret.n_links = ret.urls.len() as u16;
|
||||||
|
|
||||||
|
ret.urls.extend(
|
||||||
|
self.attachments
|
||||||
|
.iter()
|
||||||
|
.map(|x| x.url.clone())
|
||||||
|
.collect::<Vec<String>>(),
|
||||||
|
);
|
||||||
|
|
||||||
|
ret.n_attachments = self.attachments.len() as u8;
|
||||||
|
|
||||||
|
if let Some(msg) = &self.referenced_message {
|
||||||
|
let msg_links: Vec<String> = find_links(&msg.content);
|
||||||
|
|
||||||
|
ret.rn_attachments = Some(msg.attachments.len() as u8);
|
||||||
|
ret.rn_links = Some(msg_links.len() as u16);
|
||||||
|
ret.urls.extend(msg_links);
|
||||||
|
ret.urls.extend(
|
||||||
|
msg.attachments
|
||||||
|
.iter()
|
||||||
|
.map(|x| x.url.clone())
|
||||||
|
.collect::<Vec<String>>(),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
ret
|
||||||
|
}
|
||||||
|
|
||||||
|
fn extract_text(&self, skip: usize, with_ref: bool) -> Option<String> {
|
||||||
|
let mut ret: String = String::from("");
|
||||||
|
|
||||||
|
let raw: Vec<&str> = self.content.splitn(skip + 1, " ").collect();
|
||||||
|
if raw.len() == skip + 1 {
|
||||||
|
ret += raw[skip];
|
||||||
|
ret += "\n";
|
||||||
|
} else if raw.len() < skip {
|
||||||
|
return None;
|
||||||
|
}
|
||||||
|
|
||||||
|
ret += &self
|
||||||
|
.attachments
|
||||||
|
.iter()
|
||||||
|
.map(|x| x.url.clone())
|
||||||
|
.collect::<Vec<String>>()
|
||||||
|
.join("\n");
|
||||||
|
|
||||||
|
if let Some(msg) = &self.referenced_message {
|
||||||
|
let ref_text = msg.extract_text(0, false);
|
||||||
|
if with_ref && !ref_text.is_none() {
|
||||||
|
ret += "\n";
|
||||||
|
ret += &ref_text.unwrap();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if ret.is_empty() {
|
||||||
|
return None;
|
||||||
|
} else {
|
||||||
|
return Some(ret);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@@ -1 +1,2 @@
|
|||||||
pub mod components;
|
pub mod components;
|
||||||
|
pub mod messages;
|
||||||
|
Reference in New Issue
Block a user