Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
16 changes: 16 additions & 0 deletions .env.example
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
# This declares an environment variable named "DISCORD_TOKEN" with the given
# value.
# Environment variables are separated by newlines and must not have space
# around the equals sign (`=`).
DISCORD_TOKEN=put your token here
# Declares the level of logging to use. Read the documentation for the `log`
# and `env_logger` crates for more information.
RUST_LOG=debug
#prefix used by the bot, useful if you use a different prefix for testing and release
DISCORD_PREFIX=t:
#DB URL for SQL queries
#this assumes the DB is already setup correclty, for more information see README.md
DATABASE_URL=mysql://user:pass@host/database
#if one wishes to log the tracing contents (highly recommended!) they should do so in the following file
#on linux call the executable and dumb STDERR to LOG_FILE
LOG_FILE=botanist.log
6 changes: 3 additions & 3 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
/target
Cargo.lock
.env
*.log
*.pyc
*.json
OLD*
26 changes: 26 additions & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
[package]
name = "botanist"
version = "0.1.0"
authors = ["s0lst1ce <thithib.cohergne@gmail.com>"]
edition = "2018"

# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html

[dependencies]
dotenv = "0.15"
tracing = "0.1.23"
tracing-subscriber = "0.2"
chrono = "0.4"
async-trait = "0.1"

[dependencies.sqlx]
version = "0.5"
features = ["macros", "runtime-tokio-rustls", "mysql"]

[dependencies.serenity]
version = "0.10"
features = ["framework", "standard_framework", "rustls_backend", "cache"]

[dependencies.tokio]
version = "1.0"
features = ["macros", "rt-multi-thread", "signal"]
87 changes: 0 additions & 87 deletions deploy.sh

This file was deleted.

1 change: 0 additions & 1 deletion requirements.txt

This file was deleted.

3 changes: 3 additions & 0 deletions run.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
source .env
cargo b --release
cargo r --release 2>$LOG_FILE
13 changes: 13 additions & 0 deletions src/checks.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
use serenity::framework::standard::{macros::check, Args, CommandOptions, Reason};
use serenity::model::channel::Message;
use serenity::prelude::*;

#[check]
async fn is_manager(
_: &Context,
_msg: &Message,
_: &mut Args,
_: &CommandOptions,
) -> Result<(), Reason> {
unimplemented!()
}
129 changes: 129 additions & 0 deletions src/commands/dev.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,129 @@
use crate::utils::*;
use crate::ShardManagerContainer;
use serenity::model::prelude::*;
use serenity::prelude::*;
use serenity::{
client::bridge::gateway::ShardId,
framework::standard::{
macros::{command, group},
CommandError, CommandResult,
},
};
use std::env;
use tracing::error;
#[group]
#[commands(shutdown, latency, log)]
struct Development;

#[command]
#[owners_only]
async fn shutdown(ctx: &Context, msg: &Message) -> CommandResult {
let data = ctx.data.read().await;

if let Some(manager) = data.get::<ShardManagerContainer>() {
msg.reply(ctx, "Shutting down!").await?;
manager.lock().await.shutdown_all().await;
} else {
//we contact the dev directly
msg.author
.dm(ctx, |m| {
{
{
m.content("There was a problem getting the sard manager.")
}
}
})
.await?;
return Ok(());
}
Ok(())
}

#[command]
#[owners_only]
async fn latency(ctx: &Context, msg: &Message) -> CommandResult {
// The shard manager is an interface for mutating, stopping, restarting, and
// retrieving information about shards.
let data = ctx.data.read().await;

let shard_manager = match data.get::<ShardManagerContainer>() {
Some(v) => v,
None => {
msg.reply(ctx, "There was a problem getting the shard manager")
.await?;

return Ok(());
}
};

let manager = shard_manager.lock().await;
let runners = manager.runners.lock().await;

// Shards are backed by a "shard runner" responsible for processing events
// over the shard, so we'll get the information about the shard runner for
// the shard this command was sent over.
let runner = match runners.get(&ShardId(ctx.shard_id)) {
Some(runner) => runner,
None => {
msg.reply(ctx, "No shard found").await?;

return Ok(());
}
};

msg.reply(ctx, &format!("The shard latency is {:?}", runner.latency))
.await?;

Ok(())
}

#[command]
#[owners_only]
//Allows owners to send messages to all owners of the guilds the bot is in
async fn update(ctx: &Context, msg: &Message) -> CommandResult {
for guild in ctx.cache.guilds().await {
guild
.to_partial_guild(ctx)
.await?
.owner_id
.to_user(ctx)
.await?
.dm(ctx, |m| m.content(&msg.content))
.await?;
}
Ok(())
}

#[command]
#[owners_only]
#[only_in(dm)]
//sends the log file over to discord
async fn log(ctx: &Context, msg: &Message) -> CommandResult {
let path = match env::var("LOG_FILE") {
Ok(path) => path,
Err(err) => {
error!("{:#}", err);
let error = BotError::new(
"LOG_FILE is missing",
Some(BotErrorKind::EnvironmentError),
Some(msg),
);
report_error(ctx, &msg.channel_id, &error).await;
return Err(CommandError::from(err));
}
};
match msg
.channel_id
.send_files(ctx, vec![path.as_str()], |m| m)
.await
{
Ok(_) => (),
//we know the only error that can occur is HttpError::UnsuccessfulRequest(ErrorResponse) (file too large)
Err(_) => {
msg.channel_id
.say(ctx, "The log is too large to be sent")
.await?;
}
}
Ok(())
}
Loading