i kinda forgot to commit. Anyways, i made the config into toml, edited readme, and... refactored code...
This commit is contained in:
+6
-6
@@ -3,12 +3,12 @@ target/
|
|||||||
Cargo.lock
|
Cargo.lock
|
||||||
**/*.rs.bk
|
**/*.rs.bk
|
||||||
*.pdb
|
*.pdb
|
||||||
__pycache__/
|
**/__pycache__/
|
||||||
.vscode/
|
.vscode/
|
||||||
|
|
||||||
# program-created data
|
# program-created data
|
||||||
data/reddit_data.json
|
**/reddit_data.json
|
||||||
data/discord_data.json
|
**/discord_data.json
|
||||||
data/re_data.json
|
**/re_data.json
|
||||||
data/dc_data.json
|
**/dc_data.json
|
||||||
data/cfg.json
|
**/cfg.toml
|
||||||
@@ -17,3 +17,4 @@ serde = "1.0.217"
|
|||||||
serde_json = "1.0.138"
|
serde_json = "1.0.138"
|
||||||
tokio = { version = "1.43.0", features = ["rt-multi-thread"] }
|
tokio = { version = "1.43.0", features = ["rt-multi-thread"] }
|
||||||
tokio-tungstenite = "0.26.1"
|
tokio-tungstenite = "0.26.1"
|
||||||
|
toml = "0.8.23"
|
||||||
|
|||||||
@@ -1,3 +1,4 @@
|
|||||||
|
<!-- If for some reason you're reading this without MD formatting - please disable word-wrap for your own good. -->
|
||||||
# ByteDiceAssistant
|
# ByteDiceAssistant
|
||||||
An automation tool primarily made for myself (Byte Dice) but publicly available for anyone to use. It's both a Discord and Reddit bot in one program.
|
An automation tool primarily made for myself (Byte Dice) but publicly available for anyone to use. It's both a Discord and Reddit bot in one program.
|
||||||
|
|
||||||
@@ -10,36 +11,45 @@ An automation tool primarily made for myself (Byte Dice) but publicly available
|
|||||||
**ByteDiceAssistant © 2025 by Byte Dice is licensed under CC BY-NC-SA 4.0.**\
|
**ByteDiceAssistant © 2025 by Byte Dice is licensed under CC BY-NC-SA 4.0.**\
|
||||||
**You can learn more about copyright by reading the full [license](/LICENSE.txt).**
|
**You can learn more about copyright by reading the full [license](/LICENSE.txt).**
|
||||||
|
|
||||||
|
## Commands
|
||||||
|
|
||||||
|
| Name | Category | Description |
|
||||||
|
| -----------------------| -------- | -------------------------------------------------------------------- |
|
||||||
|
| `help` | help | Sends a help menu. |
|
||||||
|
| `8_ball` | fun | Sends a random answer to a prompt. |
|
||||||
|
| `add_server` | admin | Adds your server to the bots database for storage (no data is sold). |
|
||||||
|
| `embed` | owner | Creates an embed (requires `ASSISTANT_OWNERS` for security reasons). |
|
||||||
|
| `ping` | fun | Makes the bot reply with "pong" or a custom message. |
|
||||||
|
| `send` | owner | Sends a message (requires `ASSISTANT_OWNERS` for security reasons). |
|
||||||
|
| `stop` | owner | Stops the bot (requires `ASSISTANT_OWNERS` for security reasons). |
|
||||||
|
| ---------------------- | -------- | -------------------------------------------------------------------- |
|
||||||
|
| `admin_re_bindchannel` | admin | Sets the channel the command was run in as the one where `re_updatediscord` dumps information. This command is required for any of the other "re" commands to work. |
|
||||||
|
| `re_addpost` | re | Adds a post to the database. |
|
||||||
|
| `re_approvepost` | re | Flags a post in the database as approved. |
|
||||||
|
| `re_getpost` | re | Sends information about a post in the database. |
|
||||||
|
| `re_removepost` | re | "Removes" a post from the database (It actually only flags it as removed). |
|
||||||
|
| `re_shorturl` | re | Converts a long URL `https://www.reddit.com/r/SUBREDDIT/comments/POST_ID/POST_TITLE/` to a short one `https://redd.it/POST_ID`. |
|
||||||
|
| `re_topposts` | re | Sends the top posts in a category (such as upvotes). The posts have to be within the database. |
|
||||||
|
| `re_updatediscord` | re | Dumps the entire database (with a few restrictions) in the `admin_re_bindchannel` channel. |
|
||||||
|
| `re_vote` | re | Adds a vote (separate from Reddit upvotes) to a post. Use votes however you'd like. |
|
||||||
|
|
||||||
## How to run
|
## How to run
|
||||||
### Dependencies:
|
### Dependencies:
|
||||||
|
|
||||||
This program uses Rust (v1.82.0) and Python (v3.11.4), you can likely use other versions if they are compatible. This program also uses these Python modules:
|
This program uses Rust (v1.82.0) and Python (v3.11.4), you can likely use other versions if they are compatible.\
|
||||||
* asyncio
|
It is required to install all used Python modules. You can find those in [req.txt](/req.txt). Installation instructions are in the *How to Run* section.
|
||||||
* asyncpraw
|
|
||||||
* asyncprawcore
|
|
||||||
* emoji
|
|
||||||
* io
|
|
||||||
* json
|
|
||||||
* os
|
|
||||||
* sys
|
|
||||||
* threading
|
|
||||||
* time
|
|
||||||
* typing
|
|
||||||
* websockets
|
|
||||||
|
|
||||||
You can install Python modules by running `$ pip install {module}` or `$ python -m pip install {module}` in a terminal.
|
|
||||||
|
|
||||||
### Environment variables:
|
### Environment variables:
|
||||||
| **Name** | **Description** |
|
| **Name** | **Description** |
|
||||||
| ---------------------- | --- |
|
| ---------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
||||||
| `ASSISTANT_TOKEN` | The Discord bot token. (Create a Discord bot [here](https://discord.com/developers/docs/intro)!) |
|
| `ASSISTANT_TOKEN` | The Discord bot token. (Create a Discord bot [here](https://discord.com/developers/docs/intro)!) |
|
||||||
| `ASSISTANT_TOKEN_TEST` | (Optional) A testing Discord bot token. This is only needed when the program is run with `-t` or `--test`. |
|
| `ASSISTANT_TOKEN_TEST` | (Optional) A testing Discord bot token. This is only needed when the program is run with `-t` or `--test`. |
|
||||||
| `ASSISTANT_R_ID` | The id for the Reddit bot/account. (Create a Reddit bot [here](https://www.reddit.com/prefs/apps)!) |
|
| `ASSISTANT_R_ID` | The id for the Reddit bot/account. (Create a Reddit bot [here](https://www.reddit.com/prefs/apps)!) |
|
||||||
| `ASSISTANT_R_TOKEN` | The token for the Reddit bot/account. |
|
| `ASSISTANT_R_TOKEN` | The token for the Reddit bot/account. |
|
||||||
| `ASSISTANT_R_NAME` | The username of the Reddit bot/account. |
|
| `ASSISTANT_R_NAME` | The username of the Reddit bot/account. |
|
||||||
| `ASSISTANT_R_PASS` | The password for the Reddit bot/account. |
|
| `ASSISTANT_R_PASS` | The password for the Reddit bot/account. |
|
||||||
| `ASSISTANT_OWNERS` | (OPTIONAL) A list of Discord user IDs that "own" the bot. Separate each ID with a single comma and **no** spaces. This will allow the specified user IDs to run root commands such as `/stop`, it will also DM these users when *certain* errors occur. |
|
| `ASSISTANT_OWNERS` | (OPTIONAL) A list of Discord user IDs that "own" the bot. Separate each ID with a single comma and **no** spaces. This will allow the specified user IDs to run root commands such as `/stop`, it will also DM these users when *certain* errors occur. |
|
||||||
| `ASSISTANT_BK_MODS` | (OPTIONAL) Same format as `ASSISTANT_OWNERS` but for people who are allowed to use the `/re_*` commands. |
|
| `ASSISTANT_BK_MODS` | (OPTIONAL) Same format as `ASSISTANT_OWNERS` but for people who are allowed to use the `/re_*` commands. |
|
||||||
|
|
||||||
### Required permissions:
|
### Required permissions:
|
||||||
**These are automatically set if you use the [official invite link](https://discord.com/oauth2/authorize?client_id=1212127255795335208&permissions=84992&integration_type=0&scope=bot) or an invite link with the permissions integer set to `84992`.** (The permission integer is this part of the URL `&permissions=84992`)
|
**These are automatically set if you use the [official invite link](https://discord.com/oauth2/authorize?client_id=1212127255795335208&permissions=84992&integration_type=0&scope=bot) or an invite link with the permissions integer set to `84992`.** (The permission integer is this part of the URL `&permissions=84992`)
|
||||||
@@ -54,6 +64,7 @@ You can install Python modules by running `$ pip install {module}` or `$ python
|
|||||||
* Set the environment variables (listed above).
|
* Set the environment variables (listed above).
|
||||||
* Restart the terminal.
|
* Restart the terminal.
|
||||||
* Navigate to the project root directory.
|
* Navigate to the project root directory.
|
||||||
|
* Install all Python modules. (`pip install -r req.txt`)
|
||||||
* Run with `cargo run`.
|
* Run with `cargo run`.
|
||||||
* Alternatively, run `cargo run -- {args here}` to add args.
|
* Alternatively, run `cargo run -- {args here}` to add args.
|
||||||
* For help, run `cargo run -- -h` or `cargo run -- --help`.
|
* For help, run `cargo run -- -h` or `cargo run -- --help`.
|
||||||
@@ -64,16 +75,20 @@ You can install Python modules by running `$ pip install {module}` or `$ python
|
|||||||
* Open a terminal.
|
* Open a terminal.
|
||||||
* Set the environment variables (listed above).
|
* Set the environment variables (listed above).
|
||||||
* On Windows:
|
* On Windows:
|
||||||
|
|
||||||
* Run `setx VARIABLE_NAME "value in quotes"` in a terminal.
|
* Run `setx VARIABLE_NAME "value in quotes"` in a terminal.
|
||||||
|
|
||||||
* On Unix (Linux / Mac):
|
* On Linux:
|
||||||
* Run `sudo nano /etc/environment` or `sudo vim /etc/environment` in the terminal (and enter your password if prompted to).
|
* Run `sudo nano /etc/environment` or `sudo vim /etc/environment` in the terminal (and enter your password if prompted to).
|
||||||
* Press `i` (only if you used VIM).
|
* Press `i` (only if you used VIM).
|
||||||
* Write `VARIABLE_NAME="value"` + a new line for every variable.
|
* Write `VARIABLE_NAME="value"` + a new line for every variable.
|
||||||
* if nano: `ctrl + O` (and press enter) then `ctrl + X`.
|
* if nano: `ctrl + O` (and press enter) then `ctrl + X`.
|
||||||
* if VIM: press `esc` then write `:wq` (and press enter).
|
* if VIM: press `esc` then write `:wq` (and press enter).
|
||||||
|
|
||||||
|
* On macOS:
|
||||||
|
* Probably the same as Linux, but I don't use this OS so I have no clue.
|
||||||
|
|
||||||
* Restart the terminal if you added/changed any environment variables.
|
* Restart the terminal if you added/changed any environment variables.
|
||||||
* Run `cd path/to/extracted/folder` to navigate to the downloaded files (replace `path/to/extracted/folder` with your actual path).
|
* Run `cd path/to/extracted/folder` to navigate to the downloaded files (replace `path/to/extracted/folder` with your actual path).
|
||||||
|
* Install all python modules with `pip install -r req.txt`.
|
||||||
* Run `cargo run` to start the program. You can view a list of options by running `cargo run -- --help` or `cargo run -- -h`.
|
* Run `cargo run` to start the program. You can view a list of options by running `cargo run -- --help` or `cargo run -- -h`.
|
||||||
* If you only want to run the Python code, you can either run `cargo run -- --py` or `python ./src/python/main.py`. The second option is recommended for better error output.
|
* If you only want to run the Python code, you can either run `cargo run -- --py` or `python ./src/python/main.py`. The second option is recommended for better error output.
|
||||||
@@ -1,8 +0,0 @@
|
|||||||
{
|
|
||||||
"comment": "IMPORTANT!!! Anything labeled with 'RESTART_{cfg-name-here}' requires a restart to apply",
|
|
||||||
"reddit": {
|
|
||||||
"RESTART_enabled": true,
|
|
||||||
"subreddits": "bytedicetesting",
|
|
||||||
"fetch_limit": 100
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -0,0 +1,19 @@
|
|||||||
|
[reddit]
|
||||||
|
# Which subreddits the bot will scan when executing "re"-category commands.
|
||||||
|
# Is automatically disabled when `disabled_categories` includes "re".
|
||||||
|
# Separate multiple subreddits with a "+", e.g "memes+askreddit".
|
||||||
|
subreddits = "bytedicetesting"
|
||||||
|
|
||||||
|
# How many posts the bot scans when running `/re_updatediscord`.
|
||||||
|
fetch_limit = 100
|
||||||
|
|
||||||
|
[commands]
|
||||||
|
# TODO: readme
|
||||||
|
# Disabled selected command categories. All commands and their categories can be viewed in the README.
|
||||||
|
# "admin" and "owner" categories are always enabled.
|
||||||
|
# [REQUIRES RESTART]
|
||||||
|
disabled_categories = [
|
||||||
|
# "fun",
|
||||||
|
# "help"
|
||||||
|
# "re"
|
||||||
|
]
|
||||||
@@ -1,6 +1,6 @@
|
|||||||
use serde_json::json;
|
use serde_json::json;
|
||||||
|
|
||||||
use crate::{data::{get_mutex_data, read_cfg_data}, lang, messages::send_msg, websocket::send_cmd_json, Context, Error};
|
use crate::{data::{get_toml_mutex, read_cfg_data}, lang, messages::send_msg, websocket::send_cmd_json, Context, Error};
|
||||||
|
|
||||||
|
|
||||||
#[poise::command(
|
#[poise::command(
|
||||||
@@ -17,14 +17,14 @@ pub async fn cmd(
|
|||||||
) -> Result<(), Error>
|
) -> Result<(), Error>
|
||||||
{
|
{
|
||||||
read_cfg_data(&ctx.data(), false).await;
|
read_cfg_data(&ctx.data(), false).await;
|
||||||
let d = get_mutex_data(&ctx.data().cfg).await?;
|
let d = get_toml_mutex(&ctx.data().cfg).await.unwrap();
|
||||||
let d_str = serde_json::to_string(&d)?;
|
let d_str = toml::to_string(&d)?;
|
||||||
let r = send_cmd_json("update_cfg", Some(json!([d_str])), true).await;
|
let r = send_cmd_json("update_cfg", Some(json!([d_str])), true).await;
|
||||||
|
|
||||||
if r.is_some() && r.unwrap()["value"].as_bool().unwrap() {
|
if r.is_some() && r.unwrap()["value"].as_bool().unwrap() {
|
||||||
send_msg(
|
send_msg(
|
||||||
ctx,
|
ctx,
|
||||||
lang!("dc_msg_reload_cfg_success", serde_json::to_string_pretty(&d).unwrap()),
|
lang!("dc_msg_reload_cfg_success", toml::to_string_pretty(&d).unwrap()),
|
||||||
true,
|
true,
|
||||||
true
|
true
|
||||||
).await;
|
).await;
|
||||||
|
|||||||
+23
-11
@@ -8,12 +8,15 @@ use crate::{errln, rs_println, Data, Error, CFG_DATA_RE, LANG};
|
|||||||
use crate::websocket::send_cmd_json;
|
use crate::websocket::send_cmd_json;
|
||||||
|
|
||||||
|
|
||||||
static DATA_PATH_DC: &str = "./data/dc_data.json";
|
static DATA_PATH_DC: &str = "./data/db/dc_data.json";
|
||||||
static PRESET_PATH_DC: &str = "./data/dc_data_preset.json";
|
static PRESET_PATH_DC: &str = "./data/defaults/dc_data_preset.json";
|
||||||
static DATA_PATH_RE: &str = "./data/re_data.json";
|
|
||||||
static PRESET_PATH_RE: &str = "./data/re_data_preset.json";
|
static DATA_PATH_RE: &str = "./data/db/re_data.json";
|
||||||
static DATA_PATH_CFG: &str = "./data/cfg.json";
|
static PRESET_PATH_RE: &str = "./data/defaults/re_data_preset.json";
|
||||||
static PRESET_PATH_CFG: &str = "./data/cfg_default.json";
|
|
||||||
|
static DATA_PATH_CFG: &str = "./cfg/cfg.toml";
|
||||||
|
static PRESET_PATH_CFG: &str = "./data/defaults/cfg_default.toml";
|
||||||
|
|
||||||
static DATA_PATH_LANG: &str = "./data/lang/";
|
static DATA_PATH_LANG: &str = "./data/lang/";
|
||||||
|
|
||||||
pub static DC_POSTS_CHANNEL_KEY: &str = "re_posts_channel";
|
pub static DC_POSTS_CHANNEL_KEY: &str = "re_posts_channel";
|
||||||
@@ -117,15 +120,15 @@ pub async fn read_cfg_data(data: &Data, wipe: bool) {
|
|||||||
if !Path::new(DATA_PATH_CFG).exists() || wipe {
|
if !Path::new(DATA_PATH_CFG).exists() || wipe {
|
||||||
rs_println!(
|
rs_println!(
|
||||||
"{} creating new from preset...",
|
"{} creating new from preset...",
|
||||||
if !wipe { "cfg.json not found," } else { "[WIPE] (cfg.json)" }
|
if !wipe { "cfg.toml not found," } else { "[WIPE] (cfg.toml)" }
|
||||||
);
|
);
|
||||||
generate_cfg_data();
|
generate_cfg_data();
|
||||||
}
|
}
|
||||||
|
|
||||||
let str_data = fs::read_to_string(DATA_PATH_CFG).unwrap();
|
let str_data = fs::read_to_string(DATA_PATH_CFG).unwrap();
|
||||||
let json_data = serde_json::from_str(&str_data).unwrap();
|
let json_data: toml::Value = str_data.parse().unwrap();
|
||||||
let mut cfg_data = data.cfg.lock().await;
|
let mut cfg_data = data.cfg.lock().await;
|
||||||
*cfg_data = json_data;
|
*cfg_data = Some(json_data);
|
||||||
|
|
||||||
send_cmd_json("update_cfg", Some(json!([str_data])), true).await;
|
send_cmd_json("update_cfg", Some(json!([str_data])), true).await;
|
||||||
}
|
}
|
||||||
@@ -133,9 +136,9 @@ pub async fn read_cfg_data(data: &Data, wipe: bool) {
|
|||||||
|
|
||||||
fn generate_cfg_data() {
|
fn generate_cfg_data() {
|
||||||
let preset_str = fs::read_to_string(PRESET_PATH_CFG).unwrap();
|
let preset_str = fs::read_to_string(PRESET_PATH_CFG).unwrap();
|
||||||
let preset_json: Value = serde_json::from_str(&preset_str).unwrap();
|
let preset_json: toml::Value = preset_str.parse().unwrap();
|
||||||
|
|
||||||
let json_str = serde_json::to_string_pretty(&preset_json).unwrap();
|
let json_str = toml::to_string_pretty(&preset_json).unwrap();
|
||||||
|
|
||||||
let mut file = fs::File::create(DATA_PATH_CFG).unwrap();
|
let mut file = fs::File::create(DATA_PATH_CFG).unwrap();
|
||||||
file.write_all(json_str.as_bytes()).unwrap();
|
file.write_all(json_str.as_bytes()).unwrap();
|
||||||
@@ -200,6 +203,15 @@ pub async fn get_mutex_data(data: &Mutex<Option<Value>>) -> Result<Value, Error>
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
pub async fn get_toml_mutex(data: &Mutex<Option<toml::Value>>) -> Result<toml::Value, Error> {
|
||||||
|
let data_lock = data.lock().await;
|
||||||
|
return match data_lock.as_ref() {
|
||||||
|
Some(data) => Ok(data.clone()),
|
||||||
|
None => Err("Cannot get mutex data: The data is corrupted!".into()),
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
pub fn load_lang_data(lang: String) {
|
pub fn load_lang_data(lang: String) {
|
||||||
let full_path = format!("{}{}.json", DATA_PATH_LANG, lang);
|
let full_path = format!("{}{}.json", DATA_PATH_LANG, lang);
|
||||||
|
|
||||||
|
|||||||
+1
-3
@@ -19,10 +19,8 @@ pub fn event_handler<'a>(
|
|||||||
data_about_bot.user.id
|
data_about_bot.user.id
|
||||||
);
|
);
|
||||||
|
|
||||||
let file_text = std::fs::read_to_string("./data/status.txt").unwrap();
|
let file_text = std::fs::read_to_string("./cfg/status.txt").unwrap();
|
||||||
let custom_activity = ActivityData::custom(file_text);
|
let custom_activity = ActivityData::custom(file_text);
|
||||||
// TODO: make custom rich presence
|
|
||||||
//let playing_activity
|
|
||||||
|
|
||||||
ctx.online();
|
ctx.online();
|
||||||
ctx.set_activity(Some(custom_activity));
|
ctx.set_activity(Some(custom_activity));
|
||||||
|
|||||||
+30
-29
@@ -4,12 +4,12 @@ use poise::serenity_prelude::UserId;
|
|||||||
use poise::serenity_prelude as serenity;
|
use poise::serenity_prelude as serenity;
|
||||||
use poise::serenity_prelude::Client;
|
use poise::serenity_prelude::Client;
|
||||||
|
|
||||||
use crate::{cmds, data::{self, get_mutex_data}, events, re_cmds, rs_println, Args, Cmd, Data};
|
use crate::{cmds, data::{self, get_toml_mutex}, events, re_cmds, rs_println, Args, Cmd, Data};
|
||||||
|
|
||||||
|
|
||||||
pub async fn gen_data(args: Args, owners: Vec<u64>) -> Data {
|
pub async fn gen_data(args: Args, owners: Vec<u64>) -> Data {
|
||||||
let ball_classic_str = std::fs::read_to_string("./data/8-ball_classic.txt").unwrap();
|
let ball_classic_str = std::fs::read_to_string("./cfg/8-ball_classic.txt").unwrap();
|
||||||
let ball_quirk_str = std::fs::read_to_string("./data/8-ball_quirky.txt").unwrap();
|
let ball_quirk_str = std::fs::read_to_string("./cfg/8-ball_quirky.txt").unwrap();
|
||||||
|
|
||||||
let ball_classic: Vec<String> = ball_classic_str.lines().map(String::from).collect();
|
let ball_classic: Vec<String> = ball_classic_str.lines().map(String::from).collect();
|
||||||
let ball_quirk: Vec<String> = ball_quirk_str .lines().map(String::from).collect();
|
let ball_quirk: Vec<String> = ball_quirk_str .lines().map(String::from).collect();
|
||||||
@@ -76,38 +76,39 @@ pub async fn gen_bot(data: Data, args: Args) -> Client {
|
|||||||
|
|
||||||
|
|
||||||
async fn make_cmd_vec(data: &Data) -> Vec<Cmd> {
|
async fn make_cmd_vec(data: &Data) -> Vec<Cmd> {
|
||||||
let mut cmds = vec![];
|
let mut cmds = vec![
|
||||||
let cfg = get_mutex_data(&data.cfg).await.unwrap();
|
// GENERIC
|
||||||
|
|
||||||
// GENERIC
|
|
||||||
cmds.extend([
|
|
||||||
cmds::help::cmd(),
|
cmds::help::cmd(),
|
||||||
cmds::ping::cmd(),
|
cmds::ping::cmd(),
|
||||||
|
cmds::eight_ball::cmd(),
|
||||||
|
// REDDIT
|
||||||
|
re_cmds::add::cmd(),
|
||||||
|
re_cmds::approve::cmd(),
|
||||||
|
re_cmds::get::cmd(),
|
||||||
|
re_cmds::remove::cmd(),
|
||||||
|
re_cmds::top::cmd(),
|
||||||
|
re_cmds::update::cmd(),
|
||||||
|
re_cmds::vote::cmd(),
|
||||||
|
re_cmds::shorturl::cmd(),
|
||||||
|
// [ADMIN / OWNER]
|
||||||
cmds::embed::cmd(),
|
cmds::embed::cmd(),
|
||||||
cmds::send::cmd(),
|
cmds::send::cmd(),
|
||||||
cmds::stop::cmd(),
|
cmds::stop::cmd(),
|
||||||
cmds::eight_ball::cmd(),
|
cmds::add_server::cmd(),
|
||||||
cmds::add_server::cmd()
|
cmds::reload_cfg::cmd(),
|
||||||
]);
|
// REDDIT [ADMIN / OWNER]
|
||||||
|
re_cmds::admin_bind::cmd()
|
||||||
|
];
|
||||||
|
let cfg = get_toml_mutex(&data.cfg).await.unwrap();
|
||||||
|
|
||||||
// REDDIT
|
let disabled = cfg["commands"]["disabled_categories"]
|
||||||
if cfg["reddit"]["RESTART_enabled"].as_bool().unwrap() {
|
.as_array()
|
||||||
cmds.extend([
|
.unwrap()
|
||||||
re_cmds::add::cmd(),
|
.iter()
|
||||||
re_cmds::approve::cmd(),
|
.filter_map(|v| v.as_str())
|
||||||
re_cmds::get::cmd(),
|
.collect::<Vec<_>>();
|
||||||
re_cmds::remove::cmd(),
|
|
||||||
re_cmds::top::cmd(),
|
|
||||||
re_cmds::update::cmd(),
|
|
||||||
re_cmds::vote::cmd(),
|
|
||||||
re_cmds::shorturl::cmd(),
|
|
||||||
re_cmds::admin_bind::cmd(),
|
|
||||||
]);
|
|
||||||
}
|
|
||||||
|
|
||||||
cmds.extend([
|
cmds.retain(|cmd| !disabled.contains(&cmd.category.as_ref().unwrap().as_str()));
|
||||||
cmds::reload_cfg::cmd()
|
|
||||||
]);
|
|
||||||
|
|
||||||
return cmds
|
return cmds;
|
||||||
}
|
}
|
||||||
+1
-1
@@ -86,7 +86,7 @@ struct Data {
|
|||||||
ball_prompts: [Vec<String>; 2],
|
ball_prompts: [Vec<String>; 2],
|
||||||
reddit_data: Mutex<Option<Value>>,
|
reddit_data: Mutex<Option<Value>>,
|
||||||
discord_data: Mutex<Option<Value>>,
|
discord_data: Mutex<Option<Value>>,
|
||||||
cfg: Mutex<Option<Value>>,
|
cfg: Mutex<Option<toml::Value>>,
|
||||||
bk_mods: Vec<u64>,
|
bk_mods: Vec<u64>,
|
||||||
args: Args,
|
args: Args,
|
||||||
}
|
}
|
||||||
|
|||||||
+2
-2
@@ -3,7 +3,7 @@ import asyncpraw as praw
|
|||||||
import os
|
import os
|
||||||
from typing import Final
|
from typing import Final
|
||||||
from macros import *
|
from macros import *
|
||||||
import json
|
import toml
|
||||||
|
|
||||||
|
|
||||||
RE_DATA_POSTS: Final[str] = "posts"
|
RE_DATA_POSTS: Final[str] = "posts"
|
||||||
@@ -56,7 +56,7 @@ class Bot:
|
|||||||
return False
|
return False
|
||||||
|
|
||||||
async def update_cfg_str(self, new_cfg: str) -> bool:
|
async def update_cfg_str(self, new_cfg: str) -> bool:
|
||||||
json_cfg = json.loads(new_cfg)
|
json_cfg = toml.loads(new_cfg)
|
||||||
self.sr = await self.r.subreddit(json_cfg[CFG_DATA_RE]["subreddits"])
|
self.sr = await self.r.subreddit(json_cfg[CFG_DATA_RE]["subreddits"])
|
||||||
self.fetch_limit = json_cfg[CFG_DATA_RE]["fetch_limit"]
|
self.fetch_limit = json_cfg[CFG_DATA_RE]["fetch_limit"]
|
||||||
return True
|
return True
|
||||||
|
|||||||
+12
-8
@@ -1,4 +1,5 @@
|
|||||||
import os
|
import os
|
||||||
|
import toml
|
||||||
import json
|
import json
|
||||||
import time
|
import time
|
||||||
|
|
||||||
@@ -6,7 +7,10 @@ import bot as botPy
|
|||||||
from macros import *
|
from macros import *
|
||||||
|
|
||||||
|
|
||||||
DATA_PATH = os.path.abspath(os.path.join(os.path.join(os.getcwd(), "data")))
|
DATA_PATH = os.path.join(os.path.join(os.getcwd(), "data"))
|
||||||
|
DB_PATH = os.path.join(DATA_PATH, "db")
|
||||||
|
DEFAULT_PATH = os.path.join(DATA_PATH, "default")
|
||||||
|
CFG_PATH = os.path.join(os.path.join(os.getcwd(), "cfg"))
|
||||||
|
|
||||||
|
|
||||||
class PostData:
|
class PostData:
|
||||||
@@ -77,7 +81,7 @@ class PostData:
|
|||||||
|
|
||||||
|
|
||||||
def read_data(bot: botPy.Bot) -> bool:
|
def read_data(bot: botPy.Bot) -> bool:
|
||||||
r_path = os.path.join(DATA_PATH, "re_data.json")
|
r_path = os.path.join(DB_PATH, "re_data.json")
|
||||||
|
|
||||||
if os.path.isfile(r_path):
|
if os.path.isfile(r_path):
|
||||||
bot.data_f = open(r_path, "r+")
|
bot.data_f = open(r_path, "r+")
|
||||||
@@ -113,23 +117,23 @@ def write_data(bot: botPy.Bot) -> bool:
|
|||||||
|
|
||||||
|
|
||||||
async def read_cfg(bot: botPy.Bot) -> bool:
|
async def read_cfg(bot: botPy.Bot) -> bool:
|
||||||
r_path = os.path.join(DATA_PATH, "cfg.json")
|
r_path = os.path.join(CFG_PATH, "cfg.toml")
|
||||||
|
|
||||||
if os.path.isfile(r_path):
|
if os.path.isfile(r_path):
|
||||||
bot.data_f = open(r_path, "r+")
|
bot.data_f = open(r_path, "r+")
|
||||||
|
|
||||||
else:
|
else:
|
||||||
py_print("cfg.json not found, creating new from preset...")
|
py_print("cfg.toml not found, creating new from preset...")
|
||||||
with open(os.path.join(DATA_PATH, "cfg_default.json", "r")) as f:
|
with open(os.path.join(DEFAULT_PATH, "cfg_default.toml", "r")) as f:
|
||||||
data_preset_json = json.load(f)
|
data_preset_json = toml.load(f)
|
||||||
|
|
||||||
with open(r_path, "w") as f:
|
with open(r_path, "w") as f:
|
||||||
json.dump(data_preset_json, f, indent = 2)
|
toml.dump(data_preset_json, f, indent = 2)
|
||||||
|
|
||||||
bot.data_f = open(r_path, "r+")
|
bot.data_f = open(r_path, "r+")
|
||||||
|
|
||||||
data_str = bot.data_f.read()
|
data_str = bot.data_f.read()
|
||||||
json_data = json.loads(data_str)
|
json_data = toml.loads(data_str)
|
||||||
await bot.update_cfg(json_data)
|
await bot.update_cfg(json_data)
|
||||||
|
|
||||||
return True
|
return True
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
use regex::Regex;
|
use regex::Regex;
|
||||||
use serde_json::Value;
|
use serde_json::Value;
|
||||||
|
|
||||||
use crate::{data::get_mutex_data, messages::{make_post_embed, make_removed_embed, send_embed}, Context, Error};
|
use crate::{data::get_toml_mutex, messages::{make_post_embed, make_removed_embed, send_embed}, Context, Error};
|
||||||
|
|
||||||
pub fn is_bk_mod(mod_list: Vec<u64>, uid: u64) -> bool {
|
pub fn is_bk_mod(mod_list: Vec<u64>, uid: u64) -> bool {
|
||||||
return mod_list.contains(&uid);
|
return mod_list.contains(&uid);
|
||||||
@@ -35,7 +35,7 @@ pub async fn send_embed_for_removed(ctx: Context<'_>, url: &str, post: &Value) {
|
|||||||
|
|
||||||
|
|
||||||
pub async fn get_readable_subreddits(ctx: Context<'_>) -> Result<String, Error> {
|
pub async fn get_readable_subreddits(ctx: Context<'_>) -> Result<String, Error> {
|
||||||
let d = get_mutex_data(&ctx.data().cfg).await?;
|
let d = get_toml_mutex(&ctx.data().cfg).await.unwrap();
|
||||||
let sr = d["reddit"]["subreddits"].as_str().ok_or("Item of key \"subreddit\" is not a string type.\nTrace: `get_readable_subreddits -> let sr = ...`")?;
|
let sr = d["reddit"]["subreddits"].as_str().ok_or("Item of key \"subreddit\" is not a string type.\nTrace: `get_readable_subreddits -> let sr = ...`")?;
|
||||||
let split: Vec<&str> = sr.split("+").collect();
|
let split: Vec<&str> = sr.split("+").collect();
|
||||||
let join = split.join(", r/");
|
let join = split.join(", r/");
|
||||||
|
|||||||
@@ -5,6 +5,7 @@ use crate::{lang, messages::send_msg, re_cmds::generic_fns::to_shorturl, Context
|
|||||||
slash_command,
|
slash_command,
|
||||||
prefix_command,
|
prefix_command,
|
||||||
rename = "re_shorturl",
|
rename = "re_shorturl",
|
||||||
|
category = "re",
|
||||||
required_bot_permissions = "SEND_MESSAGES | VIEW_CHANNEL"
|
required_bot_permissions = "SEND_MESSAGES | VIEW_CHANNEL"
|
||||||
)]
|
)]
|
||||||
/// Convert a long reddit URL to a short one. The bot ONLY uses shortURLs when asking for one.
|
/// Convert a long reddit URL to a short one. The bot ONLY uses shortURLs when asking for one.
|
||||||
|
|||||||
Reference in New Issue
Block a user