feat: Mise en place answer ++ retravaille tracing
This commit is contained in:
parent
24b9d67198
commit
070153be8a
24
cog.toml
Normal file
24
cog.toml
Normal file
@ -0,0 +1,24 @@
|
|||||||
|
from_latest_tag = false
|
||||||
|
ignore_merge_commits = false
|
||||||
|
disable_changelog = false
|
||||||
|
disable_bump_commit = false
|
||||||
|
generate_mono_repository_global_tag = true
|
||||||
|
branch_whitelist = []
|
||||||
|
skip_ci = "[skip ci]"
|
||||||
|
skip_untracked = false
|
||||||
|
pre_bump_hooks = []
|
||||||
|
post_bump_hooks = []
|
||||||
|
pre_package_bump_hooks = []
|
||||||
|
post_package_bump_hooks = []
|
||||||
|
|
||||||
|
[git_hooks]
|
||||||
|
|
||||||
|
[commit_types]
|
||||||
|
|
||||||
|
[changelog]
|
||||||
|
path = "CHANGELOG.md"
|
||||||
|
authors = []
|
||||||
|
|
||||||
|
[bump_profiles]
|
||||||
|
|
||||||
|
[packages]
|
@ -19,7 +19,7 @@ path = "/projects/base-image"
|
|||||||
[[tracing]]
|
[[tracing]]
|
||||||
kind = "Console"
|
kind = "Console"
|
||||||
name = "console"
|
name = "console"
|
||||||
level = 1
|
level = 2
|
||||||
|
|
||||||
[tracing.additional]
|
[tracing.additional]
|
||||||
|
|
||||||
@ -29,4 +29,4 @@ name = "otel"
|
|||||||
level = 2
|
level = 2
|
||||||
|
|
||||||
[tracing.additional]
|
[tracing.additional]
|
||||||
endpoint = "http://localhost:4317"
|
endpoint = "http://localhost:4317"
|
||||||
|
51
src/botv2/cmd/meme/answer.rs
Normal file
51
src/botv2/cmd/meme/answer.rs
Normal file
@ -0,0 +1,51 @@
|
|||||||
|
use crate::{
|
||||||
|
botv2::init::{Context, Error},
|
||||||
|
domain::meme::answer::{answer_meme, AnswerResult},
|
||||||
|
};
|
||||||
|
use poise::CreateReply;
|
||||||
|
use tracing::instrument;
|
||||||
|
|
||||||
|
#[instrument(skip(ctx), level = "info", fields(channel = ctx.channel_id().get(), guild = ?ctx.guild_id().unwrap().get()))]
|
||||||
|
#[poise::command(slash_command, prefix_command, category = "meme")]
|
||||||
|
pub async fn answer(
|
||||||
|
ctx: Context<'_>,
|
||||||
|
#[description = "keyword thaat you want to search"] keyword: String,
|
||||||
|
) -> Result<(), Error> {
|
||||||
|
let guild_id = match ctx.guild_id() {
|
||||||
|
Some(guild) => guild.get(),
|
||||||
|
None => return Ok(()),
|
||||||
|
};
|
||||||
|
let user_id = ctx.author().id.get();
|
||||||
|
let config_img = ctx.data().config_img.clone();
|
||||||
|
let base_path = ctx.data().config.image.path.clone();
|
||||||
|
let bot_entity = ctx.data().entity_name.clone();
|
||||||
|
let answer = answer_meme(
|
||||||
|
user_id, guild_id, keyword, base_path, config_img, bot_entity,
|
||||||
|
)
|
||||||
|
.await;
|
||||||
|
if let Ok(answer) = answer {
|
||||||
|
match answer {
|
||||||
|
AnswerResult::Embed(embeds, attachments) => {
|
||||||
|
let mut reply = CreateReply::default();
|
||||||
|
reply.embeds = embeds;
|
||||||
|
reply.attachments = attachments;
|
||||||
|
if let Err(why) = ctx.send(reply).await {
|
||||||
|
tracing::error!("Error sending message: {:?}", why);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
AnswerResult::Animated(attachments) => {
|
||||||
|
let mut reply = CreateReply::default();
|
||||||
|
reply.attachments = attachments;
|
||||||
|
if let Err(why) = ctx.send(reply).await {
|
||||||
|
tracing::error!("Error sending message: {:?}", why);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
let builder = CreateReply::default().content("No meme keyword found");
|
||||||
|
if let Err(why) = ctx.send(builder).await {
|
||||||
|
tracing::error!("Error sending message: {:?}", why);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Ok(())
|
||||||
|
}
|
@ -1,19 +1,17 @@
|
|||||||
use crate::{botv2::init::{Context,Error}, domain::meme::change_auto_meme::change_auto_meme};
|
use crate::{
|
||||||
|
botv2::init::{Context, Error},
|
||||||
|
domain::meme::change_auto_meme::change_auto_meme,
|
||||||
|
};
|
||||||
use poise::CreateReply;
|
use poise::CreateReply;
|
||||||
use tracing::instrument;
|
use tracing::instrument;
|
||||||
|
|
||||||
/// Enable/Disable auto answer available meme keywords
|
/// Enable/Disable auto answer available meme keywords
|
||||||
#[instrument(skip(ctx),level="info")]
|
#[instrument(skip(ctx), level = "info", fields(channel = ctx.channel_id().get(), guild = ?ctx.guild_id().unwrap().get()))]
|
||||||
#[poise::command(
|
#[poise::command(slash_command, prefix_command, category = "meme")]
|
||||||
slash_command,
|
|
||||||
prefix_command,
|
|
||||||
category = "meme"
|
|
||||||
)]
|
|
||||||
pub async fn enable(
|
pub async fn enable(
|
||||||
ctx: Context<'_>,
|
ctx: Context<'_>,
|
||||||
#[description = "Enable or diable "] enable: Option<bool>
|
#[description = "Enable or diable "] enable: Option<bool>,
|
||||||
) -> Result<(), Error> {
|
) -> Result<(), Error> {
|
||||||
tracing::info!(channel = ctx.channel_id().get(), guild = ?ctx.guild_id().unwrap().get(),"Enable command called");
|
|
||||||
let guild = match ctx.guild_id() {
|
let guild = match ctx.guild_id() {
|
||||||
Some(guild) => guild,
|
Some(guild) => guild,
|
||||||
None => return Ok(()),
|
None => return Ok(()),
|
||||||
@ -27,4 +25,4 @@ pub async fn enable(
|
|||||||
tracing::error!("Error sending message: {:?}", why);
|
tracing::error!("Error sending message: {:?}", why);
|
||||||
}
|
}
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
@ -1,17 +1,16 @@
|
|||||||
use crate::botv2::init::{Context,Error};
|
use crate::botv2::init::{Context, Error};
|
||||||
use poise::{serenity_prelude::{CreateEmbed, CreateEmbedFooter, CreateMessage}, CreateReply};
|
use poise::{
|
||||||
|
serenity_prelude::{CreateEmbed, CreateEmbedFooter, CreateMessage},
|
||||||
|
CreateReply,
|
||||||
|
};
|
||||||
use tracing::instrument;
|
use tracing::instrument;
|
||||||
|
|
||||||
/// List available meme keywords
|
/// List available meme keywords
|
||||||
#[instrument(skip(ctx),level="info")]
|
#[instrument(skip(ctx), level = "info", fields(channel = ctx.channel_id().get(), guild = ?ctx.guild_id().unwrap().get()))]
|
||||||
#[poise::command(
|
#[poise::command(slash_command, prefix_command, category = "meme")]
|
||||||
slash_command,
|
|
||||||
prefix_command,
|
|
||||||
category = "meme"
|
|
||||||
)]
|
|
||||||
pub async fn list(ctx: Context<'_>) -> Result<(), Error> {
|
pub async fn list(ctx: Context<'_>) -> Result<(), Error> {
|
||||||
tracing::info!(channel = ctx.channel_id().get(), guild = ?ctx.guild_id().unwrap().get(),"List command called");
|
|
||||||
let config_img = ctx.data().config_img.clone();
|
let config_img = ctx.data().config_img.clone();
|
||||||
|
let bot_name = ctx.data().entity_name.clone();
|
||||||
let list_value: Vec<(String, String, bool)> = config_img
|
let list_value: Vec<(String, String, bool)> = config_img
|
||||||
.keyword
|
.keyword
|
||||||
.iter()
|
.iter()
|
||||||
@ -25,7 +24,7 @@ pub async fn list(ctx: Context<'_>) -> Result<(), Error> {
|
|||||||
return Ok(());
|
return Ok(());
|
||||||
}
|
}
|
||||||
let embed_vec = list_value.chunks(25).map(|chunks| {
|
let embed_vec = list_value.chunks(25).map(|chunks| {
|
||||||
let footer = CreateEmbedFooter::new("WeeboBot");
|
let footer = CreateEmbedFooter::new(bot_name.clone());
|
||||||
CreateEmbed::new()
|
CreateEmbed::new()
|
||||||
.title("Meme List")
|
.title("Meme List")
|
||||||
.fields(chunks.to_vec())
|
.fields(chunks.to_vec())
|
||||||
@ -40,4 +39,4 @@ pub async fn list(ctx: Context<'_>) -> Result<(), Error> {
|
|||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
// https://github.com/serenity-rs/poise/blob/current/examples/fluent_localization/main.rs
|
// https://github.com/serenity-rs/poise/blob/current/examples/fluent_localization/main.rs
|
||||||
|
@ -1,2 +1,3 @@
|
|||||||
pub mod list;
|
pub mod list;
|
||||||
pub mod enable;
|
pub mod enable;
|
||||||
|
pub mod answer;
|
@ -1,9 +1,9 @@
|
|||||||
use tokio::fs::File;
|
|
||||||
use poise::serenity_prelude as serenity;
|
|
||||||
use serenity::all::{CreateAttachment,CreateMessage};
|
|
||||||
use rand::Rng;
|
|
||||||
use crate::{db::user_image::User, img::config_file::KeyWordItem};
|
|
||||||
use super::init::{Data, Error};
|
use super::init::{Data, Error};
|
||||||
|
use crate::{db::user_image::User, img::config_file::KeyWordItem};
|
||||||
|
use poise::serenity_prelude as serenity;
|
||||||
|
use rand::Rng;
|
||||||
|
use serenity::all::{CreateAttachment, CreateMessage};
|
||||||
|
use tokio::fs::File;
|
||||||
|
|
||||||
pub async fn event_handler(
|
pub async fn event_handler(
|
||||||
ctx: &serenity::Context,
|
ctx: &serenity::Context,
|
||||||
@ -16,7 +16,10 @@ pub async fn event_handler(
|
|||||||
println!("{} is connected !", data_about_bot.user.name);
|
println!("{} is connected !", data_about_bot.user.name);
|
||||||
}
|
}
|
||||||
serenity::FullEvent::Message { new_message } => {
|
serenity::FullEvent::Message { new_message } => {
|
||||||
if new_message.author.bot || new_message.content.starts_with(&data.config.prefix.clone()) || new_message.content.len() == 0 {
|
if new_message.author.bot
|
||||||
|
|| new_message.content.starts_with(&data.config.prefix.clone())
|
||||||
|
|| new_message.content.len() == 0
|
||||||
|
{
|
||||||
return Ok(());
|
return Ok(());
|
||||||
}
|
}
|
||||||
let config_img = data.config_img.clone();
|
let config_img = data.config_img.clone();
|
||||||
@ -25,25 +28,28 @@ pub async fn event_handler(
|
|||||||
Some(guild) => guild,
|
Some(guild) => guild,
|
||||||
None => return Ok(()),
|
None => return Ok(()),
|
||||||
};
|
};
|
||||||
let user_in_db = match User::find_by_server_id_user_id(&guild.get(), &new_message.author.id.get()).await {
|
let user_in_db =
|
||||||
Ok(Some(user_in_db)) => user_in_db.clone(),
|
match User::find_by_server_id_user_id(&guild.get(), &new_message.author.id.get())
|
||||||
Ok(None) => {
|
.await
|
||||||
let user_in_db = User::new(guild.get(), new_message.author.id.get(), false).unwrap();
|
{
|
||||||
match user_in_db.create().await {
|
Ok(Some(user_in_db)) => user_in_db.clone(),
|
||||||
Ok(_) => user_in_db,
|
Ok(None) => {
|
||||||
Err(e) => {
|
let user_in_db =
|
||||||
println!("Error saving user image: {:?}", e);
|
User::new(guild.get(), new_message.author.id.get(), false).unwrap();
|
||||||
return Ok(());
|
match user_in_db.create().await {
|
||||||
|
Ok(_) => user_in_db,
|
||||||
|
Err(e) => {
|
||||||
|
println!("Error saving user image: {:?}", e);
|
||||||
|
return Ok(());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
Err(e) => {
|
||||||
Err(e) => {
|
println!("Error finding user image: {:?}", e);
|
||||||
println!("Error finding user image: {:?}", e);
|
return Ok(());
|
||||||
return Ok(());
|
}
|
||||||
}
|
};
|
||||||
};
|
|
||||||
if !user_in_db.enable {
|
if !user_in_db.enable {
|
||||||
println!("User image is not enable");
|
|
||||||
return Ok(());
|
return Ok(());
|
||||||
}
|
}
|
||||||
if config_img.keyword.len() == 0 || new_message.content.len() > 50 {
|
if config_img.keyword.len() == 0 || new_message.content.len() > 50 {
|
||||||
@ -100,11 +106,15 @@ pub async fn event_handler(
|
|||||||
};
|
};
|
||||||
let builder = CreateMessage::new().add_file(attachment);
|
let builder = CreateMessage::new().add_file(attachment);
|
||||||
|
|
||||||
if let Err(why) = new_message.channel_id.send_message(&ctx.http, builder).await {
|
if let Err(why) = new_message
|
||||||
|
.channel_id
|
||||||
|
.send_message(&ctx.http, builder)
|
||||||
|
.await
|
||||||
|
{
|
||||||
println!("Error sending message: {:?}", why);
|
println!("Error sending message: {:?}", why);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
_ => {}
|
_ => {}
|
||||||
}
|
}
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
@ -1,24 +1,24 @@
|
|||||||
use poise::serenity_prelude as serenity;
|
use crate::botv2::cmd::meme::{answer::answer, enable::enable, list::list};
|
||||||
use tracing::instrument;
|
use crate::botv2::cmd::{help::help, ping::ping};
|
||||||
use std::fs;
|
|
||||||
use serenity::GatewayIntents;
|
|
||||||
use crate::botv2::cmd::meme::enable::enable;
|
|
||||||
use crate::botv2::cmd::{ping::ping,help::help, meme::list::list};
|
|
||||||
use crate::{botv2::handler::event_handler, img::config_file::ConfigFile};
|
|
||||||
use crate::config::Config;
|
use crate::config::Config;
|
||||||
|
use crate::{botv2::handler::event_handler, img::config_file::ConfigFile};
|
||||||
|
use poise::serenity_prelude as serenity;
|
||||||
|
use serenity::GatewayIntents;
|
||||||
|
use std::fs;
|
||||||
use tokio::sync::oneshot;
|
use tokio::sync::oneshot;
|
||||||
use tokio::task::spawn_blocking;
|
use tokio::task::spawn_blocking;
|
||||||
pub struct Data{
|
use tracing::instrument;
|
||||||
|
pub struct Data {
|
||||||
pub config_img: ConfigFile,
|
pub config_img: ConfigFile,
|
||||||
pub config: Config,
|
pub config: Config,
|
||||||
|
pub entity_name: String,
|
||||||
}
|
}
|
||||||
|
|
||||||
// Types used by all command functions
|
// Types used by all command functions
|
||||||
pub type Error = Box<dyn std::error::Error + Send + Sync>;
|
pub type Error = Box<dyn std::error::Error + Send + Sync>;
|
||||||
pub type Context<'a> = poise::Context<'a, Data, Error>;
|
pub type Context<'a> = poise::Context<'a, Data, Error>;
|
||||||
|
|
||||||
|
#[instrument(skip(ctx), level = "info")]
|
||||||
#[instrument(skip(ctx),level="info")]
|
|
||||||
#[poise::command(slash_command, prefix_command)]
|
#[poise::command(slash_command, prefix_command)]
|
||||||
async fn age(
|
async fn age(
|
||||||
ctx: Context<'_>,
|
ctx: Context<'_>,
|
||||||
@ -30,88 +30,96 @@ async fn age(
|
|||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn start_bot(config: Config, rx: oneshot::Receiver<()>){
|
pub fn start_bot(config: Config, rx: oneshot::Receiver<()>) {
|
||||||
if config.token != "" {
|
if config.token != "" {
|
||||||
spawn_blocking(move||{
|
spawn_blocking(move || {
|
||||||
let rt = tokio::runtime::Handle::current();
|
let rt = tokio::runtime::Handle::current();
|
||||||
rt.block_on(async move{
|
rt.block_on(async move {
|
||||||
let local = tokio::task::LocalSet::new();
|
let local = tokio::task::LocalSet::new();
|
||||||
let _ = local.run_until(async move{
|
let _ = local
|
||||||
let config_img = match fs::read_to_string(format!(
|
.run_until(async move {
|
||||||
"{}/config.yaml",
|
let config_img = match fs::read_to_string(format!(
|
||||||
config.image.path
|
"{}/config.yaml",
|
||||||
)) {
|
config.image.path
|
||||||
Ok(content) => content,
|
)) {
|
||||||
Err(err) => {
|
Ok(content) => content,
|
||||||
println!("Error while opening config.yaml : {:?}", err);
|
Err(err) => {
|
||||||
return;
|
println!("Error while opening config.yaml : {:?}", err);
|
||||||
}
|
return;
|
||||||
};
|
}
|
||||||
let config_parsed = match ConfigFile::parse_config(config_img) {
|
};
|
||||||
Ok(config) => config,
|
let config_parsed = match ConfigFile::parse_config(config_img) {
|
||||||
Err(err) => {
|
Ok(config) => config,
|
||||||
println!("Error while parsing config.yaml : {:?}", err);
|
Err(err) => {
|
||||||
return;
|
println!("Error while parsing config.yaml : {:?}", err);
|
||||||
}
|
return;
|
||||||
};
|
}
|
||||||
let intents = GatewayIntents::GUILD_MESSAGES
|
};
|
||||||
| GatewayIntents::DIRECT_MESSAGES
|
let intents = GatewayIntents::GUILD_MESSAGES
|
||||||
| GatewayIntents::MESSAGE_CONTENT
|
| GatewayIntents::DIRECT_MESSAGES
|
||||||
| GatewayIntents::GUILD_VOICE_STATES
|
| GatewayIntents::MESSAGE_CONTENT
|
||||||
| GatewayIntents::GUILDS
|
| GatewayIntents::GUILD_VOICE_STATES
|
||||||
| GatewayIntents::GUILD_MEMBERS
|
| GatewayIntents::GUILDS
|
||||||
| GatewayIntents::GUILD_PRESENCES
|
| GatewayIntents::GUILD_MEMBERS
|
||||||
| GatewayIntents::GUILD_MESSAGE_REACTIONS;
|
| GatewayIntents::GUILD_PRESENCES
|
||||||
let token = config.token.clone();
|
| GatewayIntents::GUILD_MESSAGE_REACTIONS;
|
||||||
let prefix = config.prefix.clone();
|
let token = config.token.clone();
|
||||||
let framework = poise::Framework::builder()
|
let prefix = config.prefix.clone();
|
||||||
.options(poise::FrameworkOptions {
|
let framework = poise::Framework::builder()
|
||||||
commands: vec![age(), ping(), help(), list(), enable()],
|
.options(poise::FrameworkOptions {
|
||||||
prefix_options: poise::PrefixFrameworkOptions {
|
commands: vec![age(), ping(), help(), list(), enable(), answer()],
|
||||||
prefix: Some(prefix.into()),
|
prefix_options: poise::PrefixFrameworkOptions {
|
||||||
|
prefix: Some(prefix.into()),
|
||||||
|
..Default::default()
|
||||||
|
},
|
||||||
|
event_handler: |ctx, event, framework, data| {
|
||||||
|
Box::pin(event_handler(ctx, event, framework, data))
|
||||||
|
},
|
||||||
..Default::default()
|
..Default::default()
|
||||||
},
|
})
|
||||||
event_handler: |ctx, event, framework, data| {
|
.setup(|ctx, _ready, framework| {
|
||||||
Box::pin(event_handler(ctx, event, framework, data))
|
Box::pin(async move {
|
||||||
},
|
poise::builtins::register_globally(
|
||||||
..Default::default()
|
ctx,
|
||||||
})
|
&framework.options().commands,
|
||||||
.setup(|ctx, _ready, framework| {
|
)
|
||||||
Box::pin(async move {
|
.await?;
|
||||||
poise::builtins::register_globally(ctx, &framework.options().commands).await?;
|
Ok(Data {
|
||||||
Ok(Data {
|
config_img: config_parsed,
|
||||||
config_img: config_parsed,
|
config: config.clone(),
|
||||||
config: config.clone(),
|
entity_name: config.bot_name.clone(),
|
||||||
|
})
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
})
|
.build();
|
||||||
.build();
|
let mut client = serenity::ClientBuilder::new(token, intents)
|
||||||
let mut client = serenity::ClientBuilder::new(token, intents)
|
.framework(framework)
|
||||||
.framework(framework)
|
.await
|
||||||
.await.expect("Error creating client");
|
.expect("Error creating client");
|
||||||
let shard_manager = client.shard_manager.clone();
|
let shard_manager = client.shard_manager.clone();
|
||||||
let client_start = client.start_autosharded();
|
let client_start = client.start_autosharded();
|
||||||
tokio::spawn(async move {
|
tokio::spawn(async move {
|
||||||
match rx.await {
|
match rx.await {
|
||||||
Ok(_) => {
|
Ok(_) => {
|
||||||
println!("Received shutdown signal");
|
println!("Received shutdown signal");
|
||||||
shard_manager.shutdown_all().await;
|
shard_manager.shutdown_all().await;
|
||||||
println!("Shutting down bot");
|
println!("Shutting down bot");
|
||||||
}
|
}
|
||||||
Err(_) => {
|
Err(_) => {
|
||||||
println!("Channel dropped signal");
|
println!("Channel dropped signal");
|
||||||
shard_manager.shutdown_all().await;
|
shard_manager.shutdown_all().await;
|
||||||
println!("Shutting down bot");
|
println!("Shutting down bot");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
});
|
||||||
|
println!("Bot is running...");
|
||||||
|
if let Err(why) = client_start.await {
|
||||||
|
println!("Client error: {why:?}");
|
||||||
}
|
}
|
||||||
});
|
println!("Bot is stopped...");
|
||||||
println!("Bot is running...");
|
})
|
||||||
if let Err(why) = client_start.await {
|
.await;
|
||||||
println!("Client error: {why:?}");
|
|
||||||
}
|
|
||||||
println!("Bot is stopped...");
|
|
||||||
}).await;
|
|
||||||
})
|
})
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
121
src/domain/meme/answer.rs
Normal file
121
src/domain/meme/answer.rs
Normal file
@ -0,0 +1,121 @@
|
|||||||
|
use crate::img::config_file::{ConfigFile, KeyWordItem};
|
||||||
|
use poise::serenity_prelude::{model::colour, CreateAttachment, CreateEmbed, CreateEmbedFooter};
|
||||||
|
use rand::Rng;
|
||||||
|
use tokio::fs::File;
|
||||||
|
use tracing::error;
|
||||||
|
use tracing::instrument;
|
||||||
|
|
||||||
|
pub enum AnswerError {
|
||||||
|
ConfigGlobal,
|
||||||
|
ConfigImgGlobal,
|
||||||
|
KeyWordItem,
|
||||||
|
UnknownError(String),
|
||||||
|
}
|
||||||
|
|
||||||
|
pub enum AnswerResult {
|
||||||
|
Embed(Vec<CreateEmbed>, Vec<CreateAttachment>),
|
||||||
|
Animated(Vec<CreateAttachment>),
|
||||||
|
}
|
||||||
|
|
||||||
|
#[instrument(level = "info", skip(config_img, base_path))]
|
||||||
|
pub async fn answer_meme(
|
||||||
|
user_id: u64,
|
||||||
|
guild_id: u64,
|
||||||
|
keyword: String,
|
||||||
|
base_path: String,
|
||||||
|
config_img: ConfigFile,
|
||||||
|
bot_entity: String,
|
||||||
|
) -> Result<AnswerResult, AnswerError> {
|
||||||
|
let footer = CreateEmbedFooter::new(bot_entity);
|
||||||
|
|
||||||
|
let folder_container = match config_img
|
||||||
|
.keyword
|
||||||
|
.iter()
|
||||||
|
.find(|keyword_under_search| keyword_under_search.does_value_match(keyword.clone()))
|
||||||
|
{
|
||||||
|
Some(keyword_matching) => {
|
||||||
|
let keyword_path = match keyword_matching.path.len() {
|
||||||
|
0 => keyword_matching.path[0].clone(),
|
||||||
|
_ => {
|
||||||
|
let id: usize = {
|
||||||
|
let mut rng = rand::thread_rng();
|
||||||
|
rng.gen_range(0..keyword_matching.path.len())
|
||||||
|
};
|
||||||
|
keyword_matching.path[id].clone()
|
||||||
|
}
|
||||||
|
};
|
||||||
|
keyword_path.clone()
|
||||||
|
}
|
||||||
|
None => {
|
||||||
|
return Ok(AnswerResult::Embed(
|
||||||
|
vec![CreateEmbed::new()
|
||||||
|
.title("No match found")
|
||||||
|
.footer(footer)
|
||||||
|
.color(colour::Color::RED)],
|
||||||
|
vec![],
|
||||||
|
));
|
||||||
|
}
|
||||||
|
};
|
||||||
|
let path = format!("{}/{}", base_path, folder_container);
|
||||||
|
let file_folder = KeyWordItem::output_folder_content(path.clone());
|
||||||
|
let id_rand: usize = {
|
||||||
|
let mut rng = rand::thread_rng();
|
||||||
|
rng.gen_range(0..file_folder.len())
|
||||||
|
};
|
||||||
|
let filename = match file_folder.get(id_rand) {
|
||||||
|
Some(file) => file.file_name().to_str().unwrap(),
|
||||||
|
None => {
|
||||||
|
error!(folder = path, "Couldn't find a file to send");
|
||||||
|
return Ok(AnswerResult::Embed(
|
||||||
|
vec![CreateEmbed::new()
|
||||||
|
.title("Couldn't find a file to send, please contact your administrator")
|
||||||
|
.footer(footer)
|
||||||
|
.color(colour::Color::RED)],
|
||||||
|
vec![],
|
||||||
|
));
|
||||||
|
}
|
||||||
|
};
|
||||||
|
let file_path = format!("{}/{}", path, filename);
|
||||||
|
let file = match File::open(file_path.clone()).await {
|
||||||
|
Ok(file) => file,
|
||||||
|
Err(e) => {
|
||||||
|
error!(
|
||||||
|
folder = file_path,
|
||||||
|
error = e.to_string(),
|
||||||
|
"Couldn't open file"
|
||||||
|
);
|
||||||
|
return Ok(AnswerResult::Embed(
|
||||||
|
vec![CreateEmbed::new()
|
||||||
|
.title("Couldn't find file, please contact your administrator")
|
||||||
|
.footer(footer)
|
||||||
|
.color(colour::Color::RED)],
|
||||||
|
vec![],
|
||||||
|
));
|
||||||
|
}
|
||||||
|
};
|
||||||
|
let attachment = match CreateAttachment::file(&file, filename).await {
|
||||||
|
Ok(attachment) => attachment,
|
||||||
|
Err(e) => {
|
||||||
|
error!(
|
||||||
|
folder = file_path,
|
||||||
|
error = e.to_string(),
|
||||||
|
"Couldn't create attachment"
|
||||||
|
);
|
||||||
|
return Ok(AnswerResult::Embed(
|
||||||
|
vec![CreateEmbed::new()
|
||||||
|
.title("Couldn't create attachment, please contact your administrator")
|
||||||
|
.footer(footer)
|
||||||
|
.color(colour::Color::RED)],
|
||||||
|
vec![],
|
||||||
|
));
|
||||||
|
}
|
||||||
|
};
|
||||||
|
if filename.ends_with(".mp3") || filename.ends_with(".mp4") {
|
||||||
|
return Ok(AnswerResult::Animated(vec![attachment]));
|
||||||
|
}
|
||||||
|
let embed = CreateEmbed::new()
|
||||||
|
.title(keyword)
|
||||||
|
.footer(footer)
|
||||||
|
.image(format!("attachment://{}", filename));
|
||||||
|
Ok(AnswerResult::Embed(vec![embed], vec![attachment]))
|
||||||
|
}
|
@ -1 +1,2 @@
|
|||||||
pub mod change_auto_meme;
|
pub mod change_auto_meme;
|
||||||
|
pub mod answer;
|
@ -1,5 +1,6 @@
|
|||||||
use std::{vec,fs::File,sync::Arc};
|
use std::{fs::File, sync::Arc, vec};
|
||||||
|
|
||||||
|
use super::tracing_kind::{Tracing, TracingKind};
|
||||||
use opentelemetry::KeyValue;
|
use opentelemetry::KeyValue;
|
||||||
use opentelemetry_otlp::WithExportConfig;
|
use opentelemetry_otlp::WithExportConfig;
|
||||||
use opentelemetry_sdk::{runtime, trace, Resource};
|
use opentelemetry_sdk::{runtime, trace, Resource};
|
||||||
@ -8,12 +9,11 @@ use tracing::level_filters::LevelFilter;
|
|||||||
use tracing::subscriber;
|
use tracing::subscriber;
|
||||||
use tracing_bunyan_formatter::{BunyanFormattingLayer, JsonStorageLayer};
|
use tracing_bunyan_formatter::{BunyanFormattingLayer, JsonStorageLayer};
|
||||||
use tracing_opentelemetry::OpenTelemetryLayer;
|
use tracing_opentelemetry::OpenTelemetryLayer;
|
||||||
use tracing_subscriber::{filter, fmt, Layer, Registry};
|
|
||||||
use super::tracing_kind::{Tracing, TracingKind};
|
|
||||||
use tracing_subscriber::fmt::time::UtcTime;
|
use tracing_subscriber::fmt::time::UtcTime;
|
||||||
use tracing_subscriber::prelude::__tracing_subscriber_SubscriberExt;
|
use tracing_subscriber::prelude::__tracing_subscriber_SubscriberExt;
|
||||||
|
use tracing_subscriber::{fmt, EnvFilter, Layer, Registry};
|
||||||
|
|
||||||
pub fn init_tracing(tracing_config: Vec<Tracing>,name: String){
|
pub fn init_tracing(tracing_config: Vec<Tracing>, name: String) {
|
||||||
let mut layers = vec![];
|
let mut layers = vec![];
|
||||||
for config in tracing_config {
|
for config in tracing_config {
|
||||||
match config.kind {
|
match config.kind {
|
||||||
@ -24,7 +24,8 @@ pub fn init_tracing(tracing_config: Vec<Tracing>,name: String){
|
|||||||
.append(true)
|
.append(true)
|
||||||
.open("trace.log")
|
.open("trace.log")
|
||||||
.expect("Failed to create trace.log");
|
.expect("Failed to create trace.log");
|
||||||
let formating_layer = BunyanFormattingLayer::new(name.clone(), Arc::new(file)).boxed();
|
let formating_layer =
|
||||||
|
BunyanFormattingLayer::new(name.clone(), Arc::new(file)).boxed();
|
||||||
layers.push(JsonStorageLayer.boxed());
|
layers.push(JsonStorageLayer.boxed());
|
||||||
layers.push(formating_layer);
|
layers.push(formating_layer);
|
||||||
}
|
}
|
||||||
@ -32,42 +33,55 @@ pub fn init_tracing(tracing_config: Vec<Tracing>,name: String){
|
|||||||
let time_format = format_description::parse("[hour]:[minute]:[second]")
|
let time_format = format_description::parse("[hour]:[minute]:[second]")
|
||||||
.expect("format string should be valid!");
|
.expect("format string should be valid!");
|
||||||
let timer = UtcTime::new(time_format);
|
let timer = UtcTime::new(time_format);
|
||||||
|
let env_filter = EnvFilter::builder()
|
||||||
|
.with_default_directive(LevelFilter::from(config.level).into())
|
||||||
|
.from_env()
|
||||||
|
.unwrap()
|
||||||
|
.add_directive("serenity=error".parse().unwrap());
|
||||||
let terminal_out = fmt::layer()
|
let terminal_out = fmt::layer()
|
||||||
.with_thread_names(true)
|
.with_thread_names(true)
|
||||||
.with_timer(timer)
|
.with_timer(timer)
|
||||||
.with_target(false)
|
.with_target(false)
|
||||||
.with_filter(LevelFilter::from(config.level)).boxed();
|
.with_filter(env_filter)
|
||||||
|
.boxed();
|
||||||
layers.push(terminal_out);
|
layers.push(terminal_out);
|
||||||
}
|
}
|
||||||
TracingKind::Otel => {
|
TracingKind::Otel => {
|
||||||
let endpoint = match config.additional.get("endpoint"){
|
let endpoint = match config.additional.get("endpoint") {
|
||||||
Some(endpoint) => endpoint.to_string(),
|
Some(endpoint) => endpoint.to_string(),
|
||||||
None => "http://localhost:4317".to_string()
|
None => "http://localhost:4317".to_string(),
|
||||||
};
|
};
|
||||||
let pod_name = std::env::var("POD_NAME").unwrap_or_else(|_| "not_a_pod".to_string());
|
let pod_name =
|
||||||
|
std::env::var("POD_NAME").unwrap_or_else(|_| "not_a_pod".to_string());
|
||||||
let telemetry = opentelemetry_otlp::new_pipeline()
|
let telemetry = opentelemetry_otlp::new_pipeline()
|
||||||
.tracing()
|
.tracing()
|
||||||
.with_exporter(opentelemetry_otlp::new_exporter().tonic().with_endpoint(endpoint))
|
.with_exporter(
|
||||||
|
opentelemetry_otlp::new_exporter()
|
||||||
|
.tonic()
|
||||||
|
.with_endpoint(endpoint),
|
||||||
|
)
|
||||||
.with_trace_config(trace::config().with_resource(Resource::new(vec![
|
.with_trace_config(trace::config().with_resource(Resource::new(vec![
|
||||||
KeyValue::new("service.name", name.clone()),
|
KeyValue::new("service.name", name.clone()),
|
||||||
KeyValue::new("service.pod", pod_name.clone()),
|
KeyValue::new("service.pod", pod_name.clone()),
|
||||||
])))
|
])))
|
||||||
.install_batch(runtime::Tokio)
|
.install_batch(runtime::Tokio)
|
||||||
.expect("Failed to install opentelemetry");
|
.expect("Failed to install opentelemetry");
|
||||||
let tele_layer = OpenTelemetryLayer::new(telemetry).with_filter(filter::LevelFilter::from(config.level));
|
let env_filter = EnvFilter::builder()
|
||||||
|
.with_default_directive(LevelFilter::from(config.level).into())
|
||||||
|
.from_env()
|
||||||
|
.unwrap()
|
||||||
|
.add_directive("serenity=error".parse().unwrap());
|
||||||
|
let tele_layer = OpenTelemetryLayer::new(telemetry).with_filter(env_filter);
|
||||||
layers.push(tele_layer.boxed());
|
layers.push(tele_layer.boxed());
|
||||||
println!("Otel Tracing not implemented yet");
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
subscriber::set_global_default(Registry::default().with(layers))
|
subscriber::set_global_default(Registry::default().with(layers))
|
||||||
.expect("setting default subscriber failed");
|
.expect("setting default subscriber failed");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn stop_tracing(tracing_config: Vec<Tracing>, _name: String) {
|
||||||
pub fn stop_tracing(tracing_config: Vec<Tracing>,_name: String){
|
if tracing_config.iter().any(|x| x.kind == TracingKind::Otel) {
|
||||||
if tracing_config.iter().any(|x| x.kind == TracingKind::Otel){
|
|
||||||
opentelemetry::global::shutdown_tracer_provider();
|
opentelemetry::global::shutdown_tracer_provider();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user