diff --git a/.gitignore b/.gitignore
index 448c8eb..022b0e9 100644
--- a/.gitignore
+++ b/.gitignore
@@ -3,10 +3,12 @@ target/
Cargo.lock
**/*.rs.bk
*.pdb
-__pycache__/
+**/__pycache__/
.vscode/
# program-created data
-data/reddit_data.json
-data/discord_data.json
-data/cfg.json
\ No newline at end of file
+**/reddit_data.json
+**/discord_data.json
+**/re_data.json
+**/dc_data.json
+**/cfg.toml
\ No newline at end of file
diff --git a/BDA_icon_64x64.png b/BDA_icon_64x64.png
new file mode 100644
index 0000000..76de73e
Binary files /dev/null and b/BDA_icon_64x64.png differ
diff --git a/Cargo.toml b/Cargo.toml
index 53528d7..cd577ac 100644
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -6,7 +6,10 @@ edition = "2021"
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
[dependencies]
+base64 = "0.22.1"
clap = { version = "4.5.28", features = ["derive"] }
+flate2 = "1.1.2"
+formatx = "0.2.3"
futures = "0.3.31"
poise = "0.6.1"
pyo3 = "0.23.4"
@@ -16,3 +19,4 @@ serde = "1.0.217"
serde_json = "1.0.138"
tokio = { version = "1.43.0", features = ["rt-multi-thread"] }
tokio-tungstenite = "0.26.1"
+toml = "0.8.23"
diff --git a/README.md b/README.md
index 2dd7c12..2a6fdec 100644
--- a/README.md
+++ b/README.md
@@ -1,72 +1,90 @@
+
# ByteDiceAssistant
-An automation tool for Byte Dice. 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.
> [!CAUTION]
> This tool is not intended for public use outside of the official *Byte Dice Assistant* bots. Expect issues if you host this yourself.\
-> This tool is only designed to run on Windows (10 and 11) and XUbuntu and may not work on any other OS.
+> This tool is only designed to run on Windows (10 and 11) and XUbuntu (24.04 and above) and may not work on any other OS.
> [!NOTE]
-> This is an older version of the software. The newest version can be found in the [embed_buttons branch](https://github.com/ByteDice/ByteDiceAssistant/tree/embed_buttons).\
-> Keep in mind that said branch is unstable and constantly updated with untested stuff. Download code from there at your own risk or wait until this notice is removed or replaced.
+> This bot never modifies any Reddit content. All it does and will ever do is read/scrape.
+> The data will never be sold and will only be shared with permission from subreddit moderators.
-# Open-source - Copyright
+## Open-source - Copyright
**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).**
+## 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
### 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:
-* asyncio
-* 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.
+This program uses Rust (v1.82.0) and Python (v3.11.4), you can likely use other versions if they are compatible.\
+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 start the program* section.
### Environment variables:
-| **Name** | **Description** |
-| --- | --- |
-| `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_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_NAME` | The username of 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_BK_MODS` | (OPTIONAL) Same format as `ASSISTANT_OWNERS` but for people who are allowed to use the `/bk_week` commands. |
+| **Name** | **Description** |
+| ---------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
+| `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_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_NAME` | The username of 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_BK_MODS` | (OPTIONAL) Same format as `ASSISTANT_OWNERS` but for people who are allowed to use the `/re_*` commands. |
### 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`.**
+**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`)
* Send Messages
* Read Message History
* View Channels
* Embed Links
-### How to run:
+### Configuration:
+You can find config files in the [cfg/](cfg/) folder. You can also find the default configs in the [data/defaults/cfg_default.toml](data/defaults/cfg_default.toml) file.\
+**NOTE:** Some config files are automatically generated, and you will need to run the app once for them to generate.
+
+### How to start the program:
+#### Short answer for experienced people:
+* Download the code.
+* Set the environment variables (listed above).
+* Restart the terminal.
+* Navigate to the project root directory.
+* Install all Python modules. (`pip install -r req.txt`)
+* Run with `cargo run`.
+ * Alternatively, run `cargo run -- {args here}` to add args.
+ * For help, run `cargo run -- -h` or `cargo run -- --help`.
+ * To only run the Python part, use `cargo run -- --py`, or for a better error output, `python ./src/python/main.py`
+
+#### Long answer for beginners:
* Download the code (and extract it if needed).
* Open a terminal.
-* Set the environment variables.
- * On Windows:
-
- * Run `$ setx VARIABLE_NAME "value"` in a terminal.
-
- * On Unix (Linux / Mac):
- * 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).
- * write `VARIABLE_NAME="value"` + a new line for every variable.
- * if nano: `ctrl + O` (and press enter) then `ctrl + X`.
- * if VIM: press `esc` then write `:wq` (and press enter).
+* Set the environment variables (listed above).
+* Run `setx VARIABLE_NAME "value in quotes"` in a terminal. (WINDOWS ONLY)
* Restart the terminal if you added/changed the environment variables.
* Run `$ cd path/to/extracted/folder`.
* Run `$ cargo run`. 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 performance.
diff --git a/TODO.md b/TODO.md
index 65d324e..b20de1d 100644
--- a/TODO.md
+++ b/TODO.md
@@ -1,55 +1,15 @@
### High priority:
-
- [ ] Reddit bot that scrapes images with tag "Original Art" and posts them in Discord server
-
-
-
-
-
-
-
-
- - [ ] Allow disabling bk_week
- - [ ] Language files?
+ - [ ] handle dm_on_error cfg
- [ ] Allow updating the data autonomously and via manual commands.
-
-
-
-
-
-
-
-
-
-
- - [ ] Automatically approve posts that don't get caught by reverse image search (ris)
-
-
-
-
-
-
-
+ - [ ] 10-minute schedule for updating Discord channel (IMPOSSIBLE / REALLY FUCKING HARD)
### Medium priority:
-
-- [ ] View single rule (/rule {rule_name})
- [ ] Postfix calculator
- [ ] Postfix generator
-- [ ] JSON -> BPS class init
-- [ ] BPS args -> JSON
- [ ] Random tip (from ByteDice.net/data/loadingScreenTips.json)
- [ ] A command that just sends my socials
-
### Low priority:
-- [ ] Particle of the week
- * Starts a 1 week contest where people make particles based on a theme using BDE_ParticleSys
-- [ ] Weekly coding competition
- * Same as particle of the week but with coding
- [ ] Content update sender
* Automatically sends sneak peeks (like commit history or manual) of projects when they're updated
-- [ ] Language TLDR command
- * Shows a TLDR with pros/cons on a programming language
-- [ ] PowerPlate info viewer
- * Shows basic info on a PowerPlate
diff --git a/bk_week_help_re.md b/bk_week_help_re.md
index ae4c77e..3f7a834 100644
--- a/bk_week_help_re.md
+++ b/bk_week_help_re.md
@@ -1,12 +1,10 @@
# Reddit Commands
-To execute a command on the Reddit bot, include `u/ByteDiceAssistant [cmd]` in a comment.
-- **`[cmd]`**: The command you want to run and its arguments.
-## `bk_week_add`
-Adds the post to the list of posts.
+To execute a command on the Reddit bot, include `u/{BOTNAME} [cmd]` in a comment. (Replace {BOTNAME} with the actual bot name, and [cmd] with any command listed below).
+
+## `add_post`
+Adds a post to the bots database.
- **Only moderators of a subreddit or the OP (Original Poster) can use this command.**
### **Examples**
-```
-"u/ByteDiceAssistant bk_week_add"
-"Cool art, let me add that. u/ByteDiceAssistant bk_week_add"
-"Cool art. Just gonna u/ByteDiceAssistant bk_week_add so it can become featured."
-```
\ No newline at end of file
+* `u/{BOTNAME} add_post`
+* `Cool art, let me add that. u/{BOTNAME} weekly_art` (weekly art is an alias for add_post that is enabled by default)
+* `Cool art. Just gonna u/{BOTNAME} add_post so it can become featured.`
\ No newline at end of file
diff --git a/data/8-ball_classic.txt b/cfg/8-ball_classic.txt
similarity index 100%
rename from data/8-ball_classic.txt
rename to cfg/8-ball_classic.txt
diff --git a/data/8-ball_quirky.txt b/cfg/8-ball_quirky.txt
similarity index 70%
rename from data/8-ball_quirky.txt
rename to cfg/8-ball_quirky.txt
index a530560..0918a09 100644
--- a/data/8-ball_quirky.txt
+++ b/cfg/8-ball_quirky.txt
@@ -4,11 +4,11 @@ Error 404: Answer not found.
Consult your nearest wizard.
Why should I know? Go ask your cat or something.
The stars say yes, but the moon disagrees.
-You don’t want to know... trust me.
-Sure, but don’t quote me on that.
+You don't want to know... trust me.
+Sure, but don't quote me on that.
In an alternate universe, yes.
Why are you asking a stupid bot?
Only if you bring snacks.
-Flip a coin, I’m on break.
+Flip a coin, I'm on break.
The spirits are buffering... please wait.
You already know the answer.
\ No newline at end of file
diff --git a/data/cfg_default.json b/data/cfg_default.json
deleted file mode 100644
index 5f92ab3..0000000
--- a/data/cfg_default.json
+++ /dev/null
@@ -1,6 +0,0 @@
-{
- "bk_week": {
- "subreddits": "bytedicetesting",
- "fetch_limit": 100
- }
-}
\ No newline at end of file
diff --git a/data/db/.gitkeep b/data/db/.gitkeep
new file mode 100644
index 0000000..69abd31
--- /dev/null
+++ b/data/db/.gitkeep
@@ -0,0 +1,2 @@
+This file is only here so git saves this folder.
+The file is not important and may be removed unless you are contributing to the project.
\ No newline at end of file
diff --git a/data/defaults/cfg_default.toml b/data/defaults/cfg_default.toml
new file mode 100644
index 0000000..a0bcc72
--- /dev/null
+++ b/data/defaults/cfg_default.toml
@@ -0,0 +1,37 @@
+[general]
+# The language of the bot. Available languages can be found in the data/lang folder.
+# NOTE: Do not include the file extension of the language. For example, "en.json" is just "en".
+lang = "en"
+
+# The discord bots status text
+status = "🎲 https://bytedice.net"
+
+[reddit]
+# Which subreddits the bot will scan when executing "re"-category commands.
+# Is automatically disabled when `disabled_categories` includes "re".
+subreddits = ["bytedicetesting"]
+
+# How many posts the bot scans when running `/re_updatediscord`.
+fetch_limit = 100
+
+# A list of flairs the post must be tagged under to be scraped.
+# Leave empty to search for everything
+search_flairs = ["Original Art"]
+
+# Command aliases for the Reddit bot, since those aren't autocomplete-able.
+[reddit.aliases]
+add_post = ["weekly_art", "weekly"]
+
+
+[commands]
+# 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"
+]
+
+# The chance (between 0..1) for the `/8_ball` command to output a "quirky" answer.
+eight_ball_quirky_chance = 0.2
\ No newline at end of file
diff --git a/data/defaults/dc_data_preset.json b/data/defaults/dc_data_preset.json
new file mode 100644
index 0000000..502a5b4
--- /dev/null
+++ b/data/defaults/dc_data_preset.json
@@ -0,0 +1,8 @@
+{
+ "servers": {
+ "SERVER ID": {
+ "re_posts_channel": 0,
+ "re_disabled": false
+ }
+ }
+}
\ No newline at end of file
diff --git a/data/reddit_data_preset.json b/data/defaults/re_data_preset.json
similarity index 72%
rename from data/reddit_data_preset.json
rename to data/defaults/re_data_preset.json
index 587fc1c..bc8ffcf 100644
--- a/data/reddit_data_preset.json
+++ b/data/defaults/re_data_preset.json
@@ -1,7 +1,13 @@
{
- "bk_weekly_art_posts": {
- "EXAMPLE VALUE": {
+ "posts": {
+ "EXAMPLE URL": {
+ "removed": {
+ "removed": false,
+ "by": null,
+ "reason": null
+ },
"post_data": {
+ "subreddit": "bytedicetesting",
"title": "I JUST BOUGHT THE CONTINENT OF NORTH AMERICA FOR A DOLLAR!",
"upvotes": 69420,
"date_unix": 1738614657,
@@ -21,11 +27,6 @@
"by_human": true,
"by_ris": true
}
- },
- "EXAMPLE VALUE DELETED": {
- "removed": true,
- "removed_by": "ME!!!!",
- "remove_reason": "i HATED that post >:("
}
}
}
\ No newline at end of file
diff --git a/data/discord_data_preset.json b/data/discord_data_preset.json
deleted file mode 100644
index 47bc7fb..0000000
--- a/data/discord_data_preset.json
+++ /dev/null
@@ -1,13 +0,0 @@
-{
- "servers": {
- "SERVER ID": {
- "bk_week_channel": "CHANNEL ID INT",
- "bk_mod_role": "bk mod",
- "bk_mods": [
- "USER ID 1",
- "USER ID 2"
- ],
- "bk_week_disabled": false
- }
- }
-}
\ No newline at end of file
diff --git a/data/lang/en.json b/data/lang/en.json
new file mode 100644
index 0000000..edc8d3f
--- /dev/null
+++ b/data/lang/en.json
@@ -0,0 +1,66 @@
+{
+ "dc_btn_approve": "Approve",
+ "dc_btn_remove": "Remove",
+ "dc_btn_unapprove": "Disapprove",
+ "dc_btn_unremove": "Restore",
+ "dc_btn_unvote": "Un-vote",
+ "dc_btn_vote": "Vote",
+ "dc_msg_8-ball_answer": "## You shook a magic 8-ball...\n**Q:** {0}\n**A:** {1}",
+ "dc_msg_add_to_data": "Added your server to my data! Thanks for letting me steal it! (/s)",
+ "dc_msg_bound_channel": "Successfully bound channel ID `{0}` as the \"where all collected Reddit data gets dumped\" channel!",
+ "dc_msg_cmd_404": "No command \"{0}\" found!\nHint: Try `/help` without any arguments or `/help `",
+ "dc_msg_corrupted_data": "Oopsies `(。>\\\\<)`. It looks like my data i-is \\**sob*\\*... c-corrupted!\n[From Byte Dice]: I have no idea what I was thinking while writing this at 2am. I'm not removing it.",
+ "dc_msg_data_server_404": "This server is not in the data!\n Hint: Run the command `/add_server` inside of a Discord server (requires administrator permission).",
+ "dc_msg_dm_python_err_socket": "Unknown internal Python error occurred: Websocket response error",
+ "dc_msg_dm_python_err": "Unknown internal Python Error:\n```\n{0}\n```",
+ "dc_msg_embed_default_embed_desc": "Default english embed description.",
+ "dc_msg_embed_re_post": "Spoilers and vote length anonymizer for fair review!\n## Post Data:\n**Subreddit:** {0}\n**Post upvotes:** ||`{1:>6}`||\n**Moderator votes:** ||`{2:>6}`||\n**Media type:** `{3}`\n## Listing Data:\n**Added by:** human: {4} | bot: {5}\n**Approved:** {6}",
+ "dc_msg_embed_re_removed": "## Removed by `{0}`\n**Reason:** {1}",
+ "dc_msg_err_trace": "Unknown error!\nError trace: {0}",
+ "dc_msg_failed_shorturl_conversion": "Couldn't convert to shortURL: Invalid Reddit URL format.",
+ "dc_msg_mandatory_response": "Mandatory response message, please ignore.",
+ "dc_msg_owner_data_save_complete": "Saving data... Done!\nShutting down...",
+ "dc_msg_owner_data_save": "Saving data...",
+ "dc_msg_owner_shutdown_failed_confirmation": "Failed to shut down: Invalid confirmation.",
+ "dc_msg_re_already_voted": "Couldn't cast a vote: You have already voted on this post!",
+ "dc_msg_re_also_approved": "Also approved it!",
+ "dc_msg_re_data_corrupted": "Post URL \"<{0}>\" not found: Post data is corrupted!\n Full details: Could not find key \"posts\" in data file \"re_data.json\"",
+ "dc_msg_re_help_removed": "Reddit help file not found, someone likely deleted it.\n Hint: You can find the official help text at https://github.com/ByteDice/ByteDiceAssistant in `re_help.md`.\n**CAUTION:** The official help file may contain incorrect information if you're not using the official bot by Byte Dice.",
+ "dc_msg_re_permdeny_not_re_mod": "Permission denied: You are not a moderator of the subreddit(s) {0}",
+ "dc_msg_re_post_404": "Post URL \"<{0}>\" not found: Post doesn't exist in the data!\n Hint: Run the command `/re_addpost [URL]` in a Discord channel or `u/ByteDiceAssistant add_post` in a Reddit post.",
+ "dc_msg_re_post_add_success": "Added post with URL \"<{0}>\"!",
+ "dc_msg_re_post_approve_remove": "Couldn't approve the post because it has been removed!",
+ "dc_msg_re_post_approve_success": "Successfully approved the post!",
+ "dc_msg_re_post_disapprove_success": "Successfully disapproved the post!",
+ "dc_msg_re_post_remove_success": "Successfully removed post with URL \"<{0}>\"!",
+ "dc_msg_re_post_unremove_success": "Successfully restored post with URL \"<{0}>\"!",
+ "dc_msg_re_post_update_success": "Updated post with URL \"<{0}>\"!",
+ "dc_msg_re_post_vote_removed_post": "Couldn't [vote / un-vote] the post because it has been removed!",
+ "dc_msg_re_posts_channel_404": "Could not find `re_posts_channel` in data!\nHint: Run `/admin_re_bindchannel` in a (preferably read-only) channel (requires administrator permission).",
+ "dc_msg_re_vote_err": "Failed to [vote / un-vote]: Unknown internal error.",
+ "dc_msg_re_vote_mod_success": "Successfully voted (as moderator vote)!",
+ "dc_msg_re_vote_remove_havent": "Couldn't remove your vote: You haven't voted on this post yet!",
+ "dc_msg_re_vote_remove_success": "Successfully removed vote!",
+ "dc_msg_re_vote_success": "Successfully voted!",
+ "dc_msg_reload_cfg_python_fail": "Failed to reload configs: Failed-type response from Python.",
+ "dc_msg_reload_cfg_success": "Successfully reloaded the configs!\nNew configs:\n```\n{0}\n```",
+ "dc_msg_removed_square_brackets": "[REMOVED] {0}",
+ "dc_msg_shorturl": "ShortURL: <{0}>",
+ "dc_msg_update_add": "{0}Adding new posts...",
+ "dc_msg_update_done": "{0}Done!",
+ "dc_msg_update_editing": "{0}Editing updated posts...",
+ "dc_msg_update_fetch": "{0}Fetching new posts & updating data file...",
+ "dc_msg_update_parse": "{0}Parsing messages to JSON...",
+ "dc_msg_update_read": "{0}Reading messages in <#{1}>...",
+ "dc_msg_update_removing_dupe": "{0}Removing duplicate posts...",
+ "dc_msg_update_removing_old": "{0}Removing old posts (threshold: {1}d)...",
+ "dc_msg_update_removing": "{0}Removing removed posts...",
+ "dc_msg_whoami": "**Bot \"owner\":** {0}\n**BK moderator:** {1}",
+ "log_lang_load_success": "Successfully loaded the english language file!",
+ "none": "None",
+ "py_re_response_suffix": "^(I am not an AI, I am just a bot. This action was performed automatically by the way. You can report bugs and view my source code [here](https://github.com/ByteDice/ByteDiceAssistant)!)",
+ "py_re_response_weekly_add": "Successfully added your post to the weekly art submissions! Thank you for participating!",
+ "py_re_response_weekly_exists": "Couldn't add this post to the submissions! Luckily, it's already there! Thank you for participating!",
+ "py_re_response_weekly_mod_add": "[MOD ACTION] Successfully added this post to the weekly art submissions!",
+ "py_re_response_weekly_mod_unremove": "[MOD ACTION] Successfully un-removed this post from the weekly art submissions!"
+}
\ No newline at end of file
diff --git a/data/lang/gpt_fr.json b/data/lang/gpt_fr.json
new file mode 100644
index 0000000..e04b2de
--- /dev/null
+++ b/data/lang/gpt_fr.json
@@ -0,0 +1,66 @@
+{
+ "dc_btn_approve": "Approuver",
+ "dc_btn_remove": "Supprimer",
+ "dc_btn_unapprove": "Désapprouver",
+ "dc_btn_unremove": "Restaurer",
+ "dc_btn_unvote": "Annuler le vote",
+ "dc_btn_vote": "Voter",
+ "dc_msg_8-ball_answer": "## Vous avez secoué une boule magique 8...\n**Q :** {0}\n**R :** {1}",
+ "dc_msg_add_to_data": "Serveur ajouté à mes données ! Merci de me laisser les voler ! (/s)",
+ "dc_msg_bound_channel": "Canal avec l’identifiant `{0}` lié avec succès comme canal \"où toutes les données Reddit collectées sont envoyées\" !",
+ "dc_msg_cmd_404": "Commande \"{0}\" introuvable !\nAstuce : Essayez `/help` sans arguments ou `/help `",
+ "dc_msg_corrupted_data": "Oups `(。>\\\\<)`. On dirait que mes données sont \\**snif*\\*... c-corrompues !\n[De Byte Dice] : Je n’ai aucune idée de ce que je faisais à 2h du matin. Je ne le supprime pas.",
+ "dc_msg_data_server_404": "Ce serveur n’est pas dans les données !\n Astuce : Exécutez la commande `/add_server` dans un serveur Discord (nécessite les droits administrateur).",
+ "dc_msg_dm_python_err_socket": "Erreur Python interne inconnue : erreur de réponse WebSocket",
+ "dc_msg_dm_python_err": "Erreur Python interne inconnue :\n```\n{0}\n```",
+ "dc_msg_embed_default_embed_desc": "Description par défaut de l'encart en anglais.",
+ "dc_msg_embed_re_post": "Spoilers et anonymiseur de durée des votes pour une évaluation équitable !\n## Données du post :\n**Subreddit :** {0}\n**Votes positifs du post :** ||`{1:>6}`||\n**Votes des modérateurs :** ||`{2:>6}`||\n**Type de média :** `{3}`\n## Données d'inscription :\n**Ajouté par :** humain : {4} | bot : {5}\n**Approuvé:** {6}",
+ "dc_msg_embed_re_removed": "## Supprimé par `{0}`\n**Raison :** {1}",
+ "dc_msg_err_trace": "Erreur inconnue !\nTrace de l’erreur : {0}",
+ "dc_msg_failed_shorturl_conversion": "Échec de la conversion en shortURL : format d’URL Reddit invalide.",
+ "dc_msg_mandatory_response": "Message de réponse obligatoire, merci d’ignorer.",
+ "dc_msg_owner_data_save_complete": "Sauvegarde des données... Terminé !\nFermeture...",
+ "dc_msg_owner_data_save": "Sauvegarde des données...",
+ "dc_msg_owner_shutdown_failed_confirmation": "Échec de l’arrêt : confirmation invalide.",
+ "dc_msg_re_already_voted": "Impossible de voter : vous avez déjà voté pour ce post !",
+ "dc_msg_re_also_approved": "Également approuvé !",
+ "dc_msg_re_data_corrupted": "URL du post \"<{0}>\" introuvable : données du post corrompues !\n Détails : clé \"posts\" introuvable dans le fichier \"re_data.json\"",
+ "dc_msg_re_help_removed": "Fichier d’aide Reddit introuvable, il a probablement été supprimé.\n Astuce : Vous pouvez trouver le fichier d’aide officiel à https://github.com/ByteDice/ByteDiceAssistant dans `re_help.md`.\n**ATTENTION :** Le fichier d’aide peut contenir des informations incorrectes si vous n’utilisez pas le bot officiel de Byte Dice.",
+ "dc_msg_re_permdeny_not_re_mod": "Permission refusée : vous n’êtes pas modérateur des subreddit(s) {0}",
+ "dc_msg_re_post_404": "URL du post \"<{0}>\" introuvable : le post n’existe pas dans les données !\n Astuce : Exécutez la commande `/re_addpost [URL]` dans un canal Discord ou `u/ByteDiceAssistant add_post` sur un post Reddit.",
+ "dc_msg_re_post_add_success": "Post ajouté avec succès à l’URL \"<{0}>\" !",
+ "dc_msg_re_post_approve_remove": "Impossible d’approuver le post car il a été supprimé !",
+ "dc_msg_re_post_approve_success": "Post approuvé avec succès !",
+ "dc_msg_re_post_disapprove_success": "Post désapprouvé avec succès !",
+ "dc_msg_re_post_remove_success": "Post supprimé avec succès à l’URL \"<{0}>\" !",
+ "dc_msg_re_post_unremove_success": "Post restauré avec succès à l’URL \"<{0}>\" !",
+ "dc_msg_re_post_update_success": "Post mis à jour avec succès à l’URL \"<{0}>\" !",
+ "dc_msg_re_post_vote_removed_post": "Impossible de [voter / annuler le vote] : le post a été supprimé !",
+ "dc_msg_re_posts_channel_404": "Impossible de trouver `re_posts_channel` dans les données !\nAstuce : Exécutez `/admin_re_bindchannel` dans un canal (de préférence en lecture seule) (nécessite les droits administrateur).",
+ "dc_msg_re_vote_err": "Échec du [vote / annulation du vote] : erreur interne inconnue.",
+ "dc_msg_re_vote_mod_success": "Vote enregistré avec succès (vote modérateur) !",
+ "dc_msg_re_vote_remove_havent": "Impossible de retirer le vote : vous n’avez pas encore voté pour ce post !",
+ "dc_msg_re_vote_remove_success": "Vote retiré avec succès !",
+ "dc_msg_re_vote_success": "Vote enregistré avec succès !",
+ "dc_msg_reload_cfg_python_fail": "Échec du rechargement des configurations : réponse invalide de Python.",
+ "dc_msg_reload_cfg_success": "Configurations rechargées avec succès !\nNouvelles configurations :\n```\n{0}\n```",
+ "dc_msg_removed_square_brackets": "[SUPPRIMÉ] {0}",
+ "dc_msg_shorturl": "ShortURL : <{0}>",
+ "dc_msg_update_add": "{0}Ajout de nouveaux posts...",
+ "dc_msg_update_done": "{0}Terminé !",
+ "dc_msg_update_editing": "{0}Modification des posts mis à jour...",
+ "dc_msg_update_fetch": "{0}Récupération des nouveaux posts et mise à jour du fichier de données...",
+ "dc_msg_update_parse": "{0}Analyse des messages vers JSON...",
+ "dc_msg_update_read": "{0}Lecture des messages dans <#{1}>...",
+ "dc_msg_update_removing_dupe": "{0}Suppression des posts en double...",
+ "dc_msg_update_removing_old": "{0}Suppression des anciens posts (seuil : {1}j)...",
+ "dc_msg_update_removing": "{0}Suppression des posts supprimés...",
+ "dc_msg_whoami": "**Propriétaire du bot :** {0}\n**Modérateur BK :** {1}",
+ "log_lang_load_success": "Fichier de langue français chargé avec succès !",
+ "none": "Aucun",
+ "py_re_response_suffix": "^(Je ne suis pas une IA, juste un bot. Cette action a été effectuée automatiquement. Vous pouvez signaler des bugs et consulter mon code source [ici](https://github.com/ByteDice/ByteDiceAssistant) !)",
+ "py_re_response_weekly_add": "Post ajouté avec succès aux soumissions hebdomadaires d'art ! Merci pour votre participation !",
+ "py_re_response_weekly_exists": "Impossible d’ajouter ce post, il est déjà présent ! Merci pour votre participation !",
+ "py_re_response_weekly_mod_add": "[ACTION MOD] Post ajouté avec succès aux soumissions hebdomadaires d’art !",
+ "py_re_response_weekly_mod_unremove": "[ACTION MOD] Post restauré avec succès dans les soumissions hebdomadaires d’art !"
+}
\ No newline at end of file
diff --git a/data/status.txt b/data/status.txt
deleted file mode 100644
index 4251794..0000000
--- a/data/status.txt
+++ /dev/null
@@ -1 +0,0 @@
-🎲 https://bytedice.net
\ No newline at end of file
diff --git a/req.txt b/req.txt
new file mode 100644
index 0000000..e0b97af
--- /dev/null
+++ b/req.txt
@@ -0,0 +1,5 @@
+asyncpraw
+asyncprawcore
+emoji
+toml
+websockets
\ No newline at end of file
diff --git a/src/bk_week_cmds.rs b/src/bk_week_cmds.rs
deleted file mode 100644
index 06c21d5..0000000
--- a/src/bk_week_cmds.rs
+++ /dev/null
@@ -1,752 +0,0 @@
-use crate::websocket::send_cmd_json;
-use crate::{cmds, rs_println, websocket, Context, Error, BK_WEEK};
-use crate::messages::*;
-use crate::data::{self, dc_bind_bk, get_mutex_data};
-
-use std::collections::HashMap;
-use std::time::{SystemTime, UNIX_EPOCH};
-
-use poise::serenity_prelude::{ChannelId, EditMessage, GetMessages, Http, Message, MessageId, UserId};
-use poise::ReplyHandle;
-use serde_json::{json, Map, Value};
-
-
-#[derive(poise::ChoiceParameter, PartialEq)]
-enum TopCategory {
- Upvotes,
- ModVotes,
- Oldest,
- Newest
-}
-
-
-fn is_bk_mod(mod_list: Vec, uid: u64) -> bool {
- return mod_list.contains(&uid);
-}
-
-
-async fn not_bk_mod_msg(ctx: Context<'_>) {
- send_msg(ctx, "Permission denied: You are not a moderator of r/boykisser or r/boykisser2".to_string(), true, true).await;
-}
-
-
-
-
-#[poise::command(
- slash_command,
- prefix_command,
- category = "bk_week",
- required_bot_permissions = "SEND_MESSAGES | VIEW_CHANNEL | EMBED_LINKS"
-)]
-/// Fetches the data of a single post, just for you. The data has to be within the database to work.
-pub async fn bk_week_get(
- ctx: Context<'_>,
- #[description = "The post URL."] url: String
-) -> Result<(), Error>
-{
- data::update_re_data(ctx.data()).await;
-
- let reddit_data = get_mutex_data(&ctx.data().reddit_data).await?;
-
- if let Some(post) = get_post_from_data(ctx, &reddit_data, &url).await? {
- send_embed_for_post(ctx, post, &url).await?;
- }
-
- return Ok(());
-}
-
-
-async fn get_post_from_data(ctx: Context<'_>, reddit_data: &Value, url: &str) -> Result