Skip to content
Merged
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
3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,4 +1,7 @@
/target
/data/Secrets.toml
/data/rustbot.sqlite
.env
.idea/
.sqlx/
*.DS_Store
18 changes: 18 additions & 0 deletions .pre-commit-config.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
repos:
- repo: local
hooks:
- id: rustfmt
name: rustfmt
entry: bash -c 'cargo fmt --all -- --check || (echo "Code is not formatted. Run, cargo fmt --all" && exit 1)'
language: system
pass_filenames: false
always_run: true
stages: [pre-commit]

- id: clippy
name: clippy
entry: bash -c 'cargo clippy --all-targets --all-features -- -D warnings || exit 1'
language: system
pass_filenames: false
always_run: true
stages: [pre-commit]
2 changes: 1 addition & 1 deletion Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

20 changes: 17 additions & 3 deletions Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,17 +1,31 @@
[package]
name = "RustBot"
version = "0.4.5"
version = "0.4.6"
authors = ["Tim Hillier tim.r.hillier@gmail.com"]
edition = "2024"

[dependencies]
serenity = { version = "0.12.4", default-features = false, features = ["client", "gateway", "rustls_backend", "model", "cache", "standard_framework", "framework", "utils", "voice"] }
serenity = { version = "0.12.4", default-features = false, features = [
"client",
"gateway",
"rustls_backend",
"model",
"cache",
"standard_framework",
"framework",
"utils",
"voice",
] }
tokio = { version = "1.32.0", features = ["macros", "rt-multi-thread"] }
serde = { version = "1.0.188", features = ["derive"] }
serde_json = "1.0.145"
toml = "0.9.8"
rand = "0.9.2"
sqlx = { version = "0.8.6", features = ["runtime-tokio-rustls", "tls-rustls", "sqlite"] }
sqlx = { version = "0.8.6", features = [
"runtime-tokio-rustls",
"tls-rustls",
"sqlite",
] }
poise = "0.6.1"
thousands = "0.2.0"
quickchart-rs = { version = "0.1.1" }
Expand Down
37 changes: 35 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -36,8 +36,8 @@ All commands use the `!` prefix.

### Fun Commands

- **`!smash`** - Returns a random "Smash" or "Pass" response. Used as a reply to messages.
- **`!judge`** - Judges a post by adding a random +2 or -2 reaction. Must be used as a reply to another message. Prevents duplicate judgments on the same post. *Note: Marked for rework.*
- **`!smash`** - Returns a random "Smash" or "Pass" response. Used as a reply to messages.
- **`!judge`** - Judges a post by adding a random +2 or -2 reaction. Must be used as a reply to another message. Prevents duplicate judgments on the same post. _Note: Marked for rework._

### Utility Commands

Expand All @@ -52,3 +52,36 @@ All commands use the `!` prefix.
- **Leaderboards**: Track top performers in the community
- **Migration Support**: Database migrations managed through sqlx-cli

## Development

### Pre-commit Hooks

This project uses pre-commit hooks to ensure code quality before commits. To set up:

1. Install pre-commit (requires Python):

```bash
pip install pre-commit
```

2. Install the git hooks:

```bash
pre-commit install
```

3. The hooks will now run automatically on every commit, checking:
- **rustfmt**: Code formatting with `cargo fmt`
- **clippy**: Linting with `cargo clippy`

To manually run the hooks:

```bash
pre-commit run --all-files
```

To skip hooks for a single commit (not recommended):

```bash
git commit --no-verify
```
4 changes: 2 additions & 2 deletions src/bot_types.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
pub struct Data{}
pub struct Data {}
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>;
97 changes: 23 additions & 74 deletions src/bot_utils.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@ use rand::Rng;
use serde::Deserialize;
use sqlx::{Pool, Sqlite};
use std::fs;
use toml;

#[derive(Debug, Deserialize)]
struct SecretsToml {
Expand All @@ -16,13 +15,12 @@ struct SecretsToml {
}

pub fn get_toml() -> String {
let toml_str = fs::read_to_string("data/Secrets.toml").expect("Failed to read TOML");
return toml_str;
fs::read_to_string("data/Secrets.toml").expect("Failed to read TOML")
}
pub fn get_secret() -> String {
let toml_str = get_toml();
let secrets_toml: SecretsToml = toml::from_str(&toml_str).expect("Failed to decode toml");
return secrets_toml.discord_token;
secrets_toml.discord_token
}

pub fn get_env() -> String {
Expand All @@ -32,7 +30,7 @@ pub fn get_env() -> String {
if environment.is_empty() {
return String::from("testing");
}
return environment;
environment
}

pub fn is_bot(id: String) -> bool {
Expand All @@ -46,28 +44,20 @@ pub fn is_bot(id: String) -> bool {

pub fn get_random_bool(prob: f64) -> bool {
let mut rng = rand::rng();
return rng.random_bool(prob);
}

#[allow(dead_code)]
pub fn get_random_number() -> i32 {
let mut rng = rand::thread_rng();
return rng.gen_range(0..999);
rng.random_bool(prob)
}

// A connection to the database.
pub async fn connect_to_database() -> Pool<Sqlite> {
let database = sqlx::sqlite::SqlitePoolOptions::new()
sqlx::sqlite::SqlitePoolOptions::new()
.max_connections(5)
.connect_with(
sqlx::sqlite::SqliteConnectOptions::new()
.filename("data/rustbot.sqlite")
.create_if_missing(true),
)
.await
.expect("Couldn't Connect to database.");

return database;
.expect("Couldn't Connect to database.")
}

pub async fn score_update(user_id: &str, points: i16) {
Expand Down Expand Up @@ -200,50 +190,6 @@ pub async fn take_plus_two(user_id: &str, amount_taken: i16) {
.expect("Couldn't take plus two");
}

/**
Directly give the user_id plus 2's
**/
pub async fn give_minus_two(user_id: &str, amount_given: i16) {
let database = connect_to_database().await;
sqlx::query!(
"UPDATE user SET minus_two_received = minus_two_received + ? WHERE user_id = ?",
amount_given,
user_id
)
.execute(&database)
.await
.expect("Couldn't give minus two");
}

/**
Get the current amount of minus 2's the user has.
**/
pub async fn get_minus_two_received(user_id: &str) {
let database = connect_to_database().await;
let plus_2_amount = sqlx::query!(
"SELECT minus_two_received FROM user WHERE user_id = ?",
user_id
)
.fetch_all(&database)
.await
.unwrap();
}

/**
Directly take the user_id plus 2's
**/
pub async fn take_minus_two(user_id: &str, amount_taken: i16) {
let database = connect_to_database().await;
sqlx::query!(
"UPDATE user SET minus_two_received = minus_two_received - ? WHERE user_id = ?",
amount_taken,
user_id
)
.execute(&database)
.await
.expect("Couldn't take minus two");
}

/**
Get the users score formated for userInfo.
**/
Expand All @@ -254,10 +200,10 @@ pub async fn get_user_info_score(user: &str) -> UserInfo {
.await
.unwrap();

return UserInfo {
UserInfo {
user_name: user.user_name,
score: user.score.unwrap(),
};
}
}

/**
Expand All @@ -270,7 +216,7 @@ pub async fn get_score(user: &str) -> i64 {
.await
.unwrap();

return result.score.unwrap();
result.score.unwrap()
}

/**
Expand All @@ -295,7 +241,7 @@ pub(crate) async fn get_top_scores(limit: i8) -> crate::commands::score::UserInf
user_vector.0.push(temp_user)
}

return user_vector;
user_vector
}

/**
Expand Down Expand Up @@ -362,7 +308,7 @@ pub async fn get_shop_items() -> crate::commands::shop::ItemInfoVec {
};
item_vector.0.push(temp_item)
}
return item_vector;
item_vector
}

/**
Expand All @@ -371,10 +317,12 @@ Returns the current number of active Bombs.
pub async fn get_count(item: &str) -> i64 {
let database = connect_to_database().await;
let number_of_mines = sqlx::query!(
"SELECT current_amount FROM shop_items WHERE short_name = ?", item
).fetch_one(&database)
.await
.unwrap();
"SELECT current_amount FROM shop_items WHERE short_name = ?",
item
)
.fetch_one(&database)
.await
.unwrap();

number_of_mines.current_amount
}
Expand All @@ -385,10 +333,12 @@ Resets the current number of active Bombs back to 1.
pub async fn reset_count(item: &str) {
let database = connect_to_database().await;
sqlx::query!(
"UPDATE shop_items SET current_amount = 1 WHERE short_name = ?", item
).execute(&database)
.await
.unwrap();
"UPDATE shop_items SET current_amount = 1 WHERE short_name = ?",
item
)
.execute(&database)
.await
.unwrap();
}

pub async fn get_current_bot_id() -> String {
Expand All @@ -398,5 +348,4 @@ pub async fn get_current_bot_id() -> String {
return secrets_toml.live_bot_user_id;
}
secrets_toml.testing_bot_user_id

}
8 changes: 4 additions & 4 deletions src/commands/help.rs
Original file line number Diff line number Diff line change
@@ -1,13 +1,13 @@
use poise::builtins::HelpConfiguration;
use crate::bot_types::{_Context as Context, Error};
use poise::builtins::HelpConfiguration;

/// Display Help & Command menu.
#[poise::command(prefix_command)]
pub async fn help (
pub async fn help(
ctx: Context<'_>,
#[description = "Command to get help for."]
#[rest]
mut command: Option<String>
mut command: Option<String>,
) -> Result<(), Error> {
if ctx.invoked_command_name() != "help" {
command = match command {
Expand All @@ -30,4 +30,4 @@ pub async fn help (
};
poise::builtins::help(ctx, command.as_deref(), config).await?;
Ok(())
}
}
Loading
Loading