SQLite not working, send help

This commit is contained in:
Ladislav Hano 2024-02-14 13:22:29 +01:00
parent 6abc80a8a7
commit b3c3c8cfb0
11 changed files with 989 additions and 368 deletions

984
Cargo.lock generated

File diff suppressed because it is too large Load diff

View file

@ -8,13 +8,19 @@ edition = "2021"
[dependencies]
rand = "0.8.5"
anyhow = "1.0.71"
# cron = "0.12.0"
# tokio-cron-scheduler = "0.9.4"
tokio_schedule = "0.3.1"
dotenv = "0.15.0"
# mongodb = "2.6.0"
# poise = "0.5.5"
serenity = { version = "0.11.6", default-features = false, features = ["client", "gateway", "rustls_backend", "model", "http"] }
serenity = { version = "0.12.0", default-features = false, features = ["client", "gateway", "rustls_backend", "model", "http", "cache"] }
serenity_utils = "0.7.0"
tokio = { version = "1.29.1", features = ["macros", "rt-multi-thread"] }
rand = "0.8.4"
regex = "1.9.0"
url = "2.4.0"
# sqlite = "0.32.0"
# async-sqlite = { version = "0.2.1", default-features = false }
async-rusqlite = "0.4.0"
chrono = "0.4.31"
[features]
DEBUG = []
RELEASE = []

12
makefile Normal file
View file

@ -0,0 +1,12 @@
dev:
cargo build --features DEBUG
release:
cargo build --release --features RELEASE
run:
cargo build --features DEBUG
./target/debug/moover_rust
run_release:
./target/release/moover_rust

View file

@ -1,74 +1,78 @@
use std::sync::Arc;
use std::time::Duration;
use anyhow::{self, Context};
use poise::serenity_prelude::AttachmentType;
use serenity::builder::CreateEmbed;
use anyhow::Context;
use serenity::builder::{CreateAttachment, CreateEmbed, CreateMessage};
use serenity::http::Http;
use serenity::model::channel::Message;
use tokio::time::sleep;
use url::Url;
use regex::Regex;
use serenity::model::id::ChannelId;
// Checks if the message should be mooved
// If the message should be mooved, try to move it and return Ok if mooved succesfully
// else returns Err()
pub enum MooveResult {
Mooved,
NotMooveRequest
}
pub async fn moove(http: Arc<Http>, msg: Message) -> anyhow::Result<MooveResult> {
pub async fn moove_check(msg: &Message) -> Option<u64> {
let word_count = msg.content.trim().split_whitespace().count();
let re = Regex::new(r"<#[0-9]*>$").unwrap();
if word_count != 1 || re.captures(&msg.content).is_none() {
return Ok(MooveResult::NotMooveRequest);
return None
}
let msg_to_moove = msg.clone().referenced_message.context("no message present")?;
let mentioned_channel = http.get_channel(
msg.content[2..msg.content.len() - 1].parse::<u64>()
.unwrap()).await?.id();
let channel_id = match msg.content[2..msg.content.len() - 1].parse::<u64>() {
Ok(val) => val,
Err(_) => return None
};
return Some(channel_id);
}
pub async fn moove(http: Arc<Http>, msg: Message, m_channel_id: u64) -> anyhow::Result<()> {
// this should be in moove_check, but I need to find a good way to return in with channel_id
let msg_to_moove = msg.clone().referenced_message.context("Referenced message not found")?;
//steals all attachments, but sets all of them as Image urls, so rip actual docs etc
let attachments = msg_to_moove
.attachments.clone()
.into_iter()
.map(|att| AttachmentType::Image(Url::parse(att.url.as_str()).unwrap()));
let mut attachments: Vec<CreateAttachment> = Vec::new();
for attachment in msg_to_moove.attachments.clone() {
let data = attachment.download().await?;
attachments.push(CreateAttachment::bytes(data, attachment.filename));
}
//steals all the embeds
let embeds: Vec<CreateEmbed> = msg_to_moove
.embeds.clone()
.into_iter()
.map(|em| CreateEmbed::from(em))
.map(| embed | CreateEmbed::from(embed))
.collect();
let mut new_content = format!("Sent by {}\n mooved {}\n", msg_to_moove.author, msg.author);
let mut new_msg = CreateMessage::new();
// Either copy all the attachments and embeds and create a new message that contains them all
if attachments.len() > 0 || embeds.len() > 0 {
new_content += format!("Message:\n{}", msg_to_moove.content).as_str();
mentioned_channel.send_message(http.clone(), |m| {
m.content(new_content)
.add_embeds(embeds)
.add_files(attachments)
}).await?;
new_msg = new_msg.content(new_content)
.add_embeds(embeds)
.add_files(attachments);
}
else if !msg_to_moove.content.is_empty() {
mentioned_channel.send_message(http.clone(), |m| {
m.add_embed(|e| {
e.field("MOO", new_content, false)
.field("Message:\n", msg_to_moove.content.clone(), false)
})
}).await?;
// or create a new embed with the content of the mooved message as one of the fields
else {
let embed = CreateEmbed::new()
.field("MOO", new_content, false)
.field("Message:\n", msg_to_moove.content.clone(), false);
new_msg = new_msg.add_embed(embed);
}
ChannelId::new(m_channel_id).send_message(http.clone(), new_msg).await?;
sleep(Duration::from_secs(2)).await;
msg_to_moove.delete(http.clone()).await?;
msg.delete(http).await?;
Ok(MooveResult::Mooved)
Ok(())
}

View file

@ -1,17 +1,27 @@
use rand::random;
use std::sync::atomic::AtomicUsize;
use chrono::Utc;
use serenity::async_trait;
use serenity::model::channel::Message;
use serenity::model::gateway::Ready;
use serenity::prelude::*;
use serenity::client::Context;
// use tokio_cron_scheduler::{JobScheduler, JobToRun, Job};
use tokio_schedule::{every, EveryDay, Job};
use util::security::dotenv_var;
use other::msg::hello;
use std::sync::Arc;
mod message_handler;
use message_handler::handle;
mod commands;
mod util;
use util::debug::send_error;
mod other;
use other::notice;
struct Handler;
@ -23,39 +33,46 @@ impl EventHandler for Handler {
async fn ready(&self, ctx: Context, ready: Ready) {
println!("{} is connected!", ready.user.name);
let debug = match dotenv_var("DEBUG") {
Some(v) => v,
None => "OFF".to_string(),
};
if debug != "ON" {
let messages = [
"AAAAAAAAAAAAAAAAAAAA",
"Henlooo",
"Good day y'all!",
"May have crashed...",
"MOOOooo",
"Heyyyyy!",
"I'm baaaaack!",
"Whom'st have summoned the ancient one?",
];
let rand_num = random::<usize>() % messages.len();
let channel = ctx.http.get_channel(780439236867653635).await.unwrap().id();
match channel.say(&ctx.http, messages[rand_num]).await {
Err(e) => println!("Something went wrong: {e}"),
Ok(_) => return,
};
}
// if ready.user.name != "MOOver Debug" {
hello(ctx.http).await;
// }
// use util::debug::hello;
// hello(ctx.http.clone()).await;
notice::notice_wrapper(ctx).await;
// let scheduler = every(1).day().at(13, 30, 0)
// .perform(|| async {
// notice::notice_wrapper(ctx.clone()).await
// }).await;
// let mut scheduler = JobScheduler::new().await;
// scheduler.
// scheduler.add(match Job::new_async("5 * * * * * *", |uuid, mut l| Box::pin( async {
// notice::notice(ctx.clone()).await;
// })) {
// Ok(_) => {}
// Err(e) => {
// send_error(ctx.http.clone(), e.to_string());
// panic!()
// }
// });
// scheduler.add(Job::new(daily("22"), move || {
// notice::notice(ctx.clone())
// }));
}
}
#[tokio::main]
async fn main() -> anyhow::Result<()> {
use anyhow::Context;
let token = dotenv_var("TOKEN").context("No TOKEN in env")?;
let token_str = "TOKEN";
#[cfg(feature="DEBUG")]
let token_str = "DEBUGTOKEN";
let token = dotenv_var(token_str).context("No TOKEN in env")?;
let intents = GatewayIntents::GUILD_MESSAGES | GatewayIntents::MESSAGE_CONTENT;
let mut client = Client::builder(&token, intents)

View file

@ -1,11 +1,75 @@
use serenity::client::Context;
use rand::random;
use serenity::{client::Context, http::Http};
use serenity::model::channel::Message;
use std::sync::Arc;
use crate::commands::moove::moove;
use crate::util::debug::send_error;
use crate::commands::moove::{moove, moove_check};
pub async fn handle(ctx: Context, msg: Message) {
match moove(ctx.http, msg).await {
if msg.author.bot {
return
}
let lower_case_content = msg.content.to_lowercase();
let bot_id = ctx.cache.current_user().id;
if msg.mentions_user_id(bot_id) || lower_case_content.contains("moover") {
if !response(ctx.http.clone(), msg.clone()).await {
// NOTE maybe should exit here instead since there is something very wrong if I can't reply
return
}
}
else if lower_case_content.contains("henlo") {
if !henlo(ctx.http.clone(), msg.clone()).await {
// NOTE same as above
return
}
}
let channel_id = match moove_check(&msg).await {
Some(val) => val,
None => return
};
match moove(ctx.http, msg, channel_id).await {
Ok(_) => return,
Err(e) => println!("ERROR: {e}")
};
}
async fn response(http: Arc<Http>, msg: Message) -> bool {
// NOTE probably not clever to do it this way
const RESPONSES: [&str; 4] = [
"To som jaaa",
"Henloooo",
"Čo môj?",
"Hm?"
];
let num = random::<usize>() % RESPONSES.len();
match msg.reply(http.clone(), RESPONSES[num]).await {
Ok(_) => { return true }
Err(e) => {
send_error(http, e.to_string()).await;
return false
}
};
}
async fn henlo(http: Arc<Http>, msg: Message) -> bool {
const EMOJIS: [&str; 7] = ["🥰", "🐄", "🐮", "❤️", "👋", "🤠", "😊"];
let num = random::<usize>() % EMOJIS.len();
let response = format!("Henlooo {} {}", msg.author.name, EMOJIS[num]);
match msg.reply(http.clone(), response).await {
Ok(_) => { return true }
Err(e) => {
send_error(http, e.to_string()).await;
return false
}
};
}

View file

@ -1 +1 @@
pub mod msg;
pub mod notice;

View file

@ -1,23 +0,0 @@
use serenity::http::Http;
use std::sync::Arc;
pub async fn hello(http: Arc<Http>) {
let messages = [
"AAAAAAAAAAAAAAAAAAAA",
"Henlooo",
"Good day y'all!",
"May have crashed...",
"MOOOooo",
"Heyyyyy!",
"I'm baaaaack!",
"Whom'st have summoned the ancient one?",
];
let channel = http.get_channel(780439236867653635).await.unwrap();
let num = rand::random::<usize>() % messages.len();
if let Err(why) = channel.id().say(http, messages[num]).await {
print!("Error sending message: {:?}", why);
};
}

67
src/other/notice.rs Normal file
View file

@ -0,0 +1,67 @@
use serenity::prelude::*;
use chrono::{Local, Datelike};
// use async_sqlite::{rusqlite::{Rows, Statement}, ClientBuilder, JournalMode};
use crate::util::debug::send_error;
use anyhow::Result;
use async_rusqlite::Connection;
pub async fn notice_wrapper(ctx: Context) {
match notice(ctx.clone()).await {
Ok(_) => return,
Err(e) => {
send_error(ctx.http.clone(), e.to_string()).await;
return
}
}
}
struct BirtdayRow {
day: u8,
month: u8,
nick: String
}
async fn notice(ctx: Context) -> anyhow::Result<()> {
let local = Local::now();
let day = local.day();
let month = local.month();
let conn = Connection::open("my.db").await?;
let stmt = conn.call(move |conn| {
conn.prepare("SELECT * FROM birthdays WHERE day=6 AND month=3;")
}).await?;
// let result = Vec::new();
// let stmt = client.conn(|conn| {
// // conn.prepare(format!("SELECT * FROM {db} WHERE day={day} AND month={month};").as_str());
// conn.prepare("SELECT * FROM birthdays WHERE day=6 AND month=3;")
// }).await?;
let rows = stmt.query([])?;
let result: Vec<BirtdayRow> = Vec::new();
while let Some(row) = rows.next()? {
let bd = BirtdayRow {
day: row.get(1)?,
month: row.get(2)?,
nick: row.get(3)?
};
result.push(bd);
}
println!("VALUE: {:?}", result[0].day);
// for db in ["birthdays", "events"] {
// // let mut stmt = client.conn(|conn| {
// // conn.
// // }).await;
// }
Ok(())
}

33
src/util/debug.rs Normal file
View file

@ -0,0 +1,33 @@
use serenity::{all::ChannelId, builder::CreateMessage, http::Http};
use std::{process::exit, sync::Arc};
pub async fn send_error(http: Arc<Http>, msg: String) {
println!("ERROR: {msg}");
#[cfg(feature="RELEASE")]
match ChannelId::new(1199495008416440491)
.send_message(http, CreateMessage::new().content(msg)).await {
Ok(_) => { return; }
Err(_) => { exit(-1) }
};
}
pub async fn hello(http: Arc<Http>) {
let messages = [
"AAAAAAAAAAAAAAAAAAAA",
"Henlooo",
"Good day y'all!",
"May have crashed...",
"MOOOooo",
"Heyyyyy!",
"I'm baaaaack!",
"Whom'st have summoned the ancient one?",
];
let num = rand::random::<usize>() % messages.len();
let channel = ChannelId::new(780439236867653635);
if let Err(why) = channel.say(http, messages[num]).await {
print!("Error sending message: {:?}", why);
};
}

View file

@ -1 +1,2 @@
pub mod security;
pub mod security;
pub mod debug;