added more config options & made python type-safe(r).
This commit is contained in:
@@ -1,4 +1,8 @@
|
|||||||
[general]
|
[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
|
# The discord bots status text
|
||||||
status = "🎲 https://bytedice.net"
|
status = "🎲 https://bytedice.net"
|
||||||
|
|
||||||
@@ -15,6 +19,12 @@ fetch_limit = 100
|
|||||||
# Leave empty to search for everything
|
# Leave empty to search for everything
|
||||||
search_flairs = ["Original Art"]
|
search_flairs = ["Original Art"]
|
||||||
|
|
||||||
|
# Command aliases for the Reddit bot, since those aren't autocomplete-able.
|
||||||
|
# TODO: this
|
||||||
|
[reddit.aliases]
|
||||||
|
add_post = []
|
||||||
|
|
||||||
|
|
||||||
[commands]
|
[commands]
|
||||||
# Disabled selected command categories. All commands and their categories can be viewed in the README.
|
# Disabled selected command categories. All commands and their categories can be viewed in the README.
|
||||||
# "admin" and "owner" categories are always enabled.
|
# "admin" and "owner" categories are always enabled.
|
||||||
@@ -23,4 +33,7 @@ disabled_categories = [
|
|||||||
# "fun",
|
# "fun",
|
||||||
# "help"
|
# "help"
|
||||||
# "re"
|
# "re"
|
||||||
]
|
]
|
||||||
|
|
||||||
|
# The chance (between 0..1) for the `/8_ball` command to output a "quirky" answer.
|
||||||
|
eight_ball_quirky_chance = 0.2
|
||||||
@@ -7,6 +7,7 @@
|
|||||||
"reason": null
|
"reason": null
|
||||||
},
|
},
|
||||||
"post_data": {
|
"post_data": {
|
||||||
|
"subreddit": "bytedicetesting",
|
||||||
"title": "I JUST BOUGHT THE CONTINENT OF NORTH AMERICA FOR A DOLLAR!",
|
"title": "I JUST BOUGHT THE CONTINENT OF NORTH AMERICA FOR A DOLLAR!",
|
||||||
"upvotes": 69420,
|
"upvotes": 69420,
|
||||||
"date_unix": 1738614657,
|
"date_unix": 1738614657,
|
||||||
|
|||||||
+2
-2
@@ -5,7 +5,7 @@
|
|||||||
"dc_btn_unremove": "Restore",
|
"dc_btn_unremove": "Restore",
|
||||||
"dc_btn_unvote": "Un-vote",
|
"dc_btn_unvote": "Un-vote",
|
||||||
"dc_btn_vote": "Vote",
|
"dc_btn_vote": "Vote",
|
||||||
"dc_msg_8-ball_answer": "## You shook a magic 8-ball\nQ: {0}\nA: {1}",
|
"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_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_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 <category>`",
|
"dc_msg_cmd_404": "No command \"{0}\" found!\nHint: Try `/help` without any arguments or `/help <category>`",
|
||||||
@@ -14,7 +14,7 @@
|
|||||||
"dc_msg_dm_python_err_socket": "Unknown internal Python error occurred: Websocket response error",
|
"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_dm_python_err": "Unknown internal Python Error:\n```\n{0}\n```",
|
||||||
"dc_msg_embed_default_embed_desc": "Default english embed description.",
|
"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**Post upvotes:** ||`{0:>6}`||\n**Moderator votes:** ||`{1:>6}`||\n**Media type:** `{2}`\n**URL:** ||<{3}>||\n\n## Listing Data:\n**Added by:** `{{ human: {4}, bot: {5} }}`\n**Approved by:** `{{ human: {6}, bot: [not implemented] }}`",
|
"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**URL:** ||<{4}>||\n\n## Listing Data:\n**Added by:** human: {5} | bot: {6}\n**Approved by:** human: {7} | bot: [not implemented]",
|
||||||
"dc_msg_embed_re_removed": "## Removed by `{0}`\n**Reason:** {1}\n**URL**: ||<{2}>||",
|
"dc_msg_embed_re_removed": "## Removed by `{0}`\n**Reason:** {1}\n**URL**: ||<{2}>||",
|
||||||
"dc_msg_err_trace": "Unknown error!\nError trace: {0}",
|
"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_failed_shorturl_conversion": "Couldn't convert to shortURL: Invalid Reddit URL format.",
|
||||||
|
|||||||
@@ -5,7 +5,7 @@
|
|||||||
"dc_btn_unremove": "Restaurer",
|
"dc_btn_unremove": "Restaurer",
|
||||||
"dc_btn_unvote": "Annuler le vote",
|
"dc_btn_unvote": "Annuler le vote",
|
||||||
"dc_btn_vote": "Voter",
|
"dc_btn_vote": "Voter",
|
||||||
"dc_msg_8-ball_answer": "## Vous avez secoué une boule magique 8\nQ : {0}\nR : {1}",
|
"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_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_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 <catégorie>`",
|
"dc_msg_cmd_404": "Commande \"{0}\" introuvable !\nAstuce : Essayez `/help` sans arguments ou `/help <catégorie>`",
|
||||||
@@ -14,7 +14,7 @@
|
|||||||
"dc_msg_dm_python_err_socket": "Erreur Python interne inconnue : erreur de réponse WebSocket",
|
"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_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_default_embed_desc": "Description par défaut de l'encart en anglais.",
|
||||||
"dc_msg_embed_re_post": "Spoilers et anonymisation des votes pour une évaluation équitable !\n## Données du post :\n**Votes positifs du post :** ||`{0:>6}`||\n**Votes des modérateurs :** ||`{1:>6}`||\n**Type de média :** `{2}`\n**URL :** ||<{3}>||\n\n## Données de la liste :\n**Ajouté par :** `{{ humain : {4}, bot : {5} }}`\n**Approuvé par :** `{{ humain : {6}, bot : [non implémenté] }}`",
|
"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**URL :** ||<{4}>||\n\n## Données d'inscription :\n**Ajouté par :** humain : {5} | bot : {6}\n**Approuvé par :** humain : {7} | bot : [non implémenté]",
|
||||||
"dc_msg_embed_re_removed": "## Supprimé par `{0}`\n**Raison :** {1}\n**URL** : ||<{2}>||",
|
"dc_msg_embed_re_removed": "## Supprimé par `{0}`\n**Raison :** {1}\n**URL** : ||<{2}>||",
|
||||||
"dc_msg_err_trace": "Erreur inconnue !\nTrace de l’erreur : {0}",
|
"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_failed_shorturl_conversion": "Échec de la conversion en shortURL : format d’URL Reddit invalide.",
|
||||||
@@ -55,7 +55,7 @@
|
|||||||
"dc_msg_update_removing_dupe": "{0}Suppression des posts en double...",
|
"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_old": "{0}Suppression des anciens posts (seuil : {1}j)...",
|
||||||
"dc_msg_update_removing": "{0}Suppression des posts supprimés...",
|
"dc_msg_update_removing": "{0}Suppression des posts supprimés...",
|
||||||
"log_lang_load_success": "Fichier de langue anglais chargé avec succès !",
|
"log_lang_load_success": "Fichier de langue français chargé avec succès !",
|
||||||
"none": "Aucun",
|
"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_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_add": "Post ajouté avec succès aux soumissions hebdomadaires d'art ! Merci pour votre participation !",
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
use rand::{seq::IteratorRandom, Rng};
|
use rand::{seq::IteratorRandom, Rng};
|
||||||
|
|
||||||
use crate::{lang, messages::send_msg, Context, Error};
|
use crate::{data::get_toml_mutex, lang, messages::send_msg, Context, Error};
|
||||||
|
|
||||||
|
|
||||||
#[poise::command(
|
#[poise::command(
|
||||||
@@ -16,14 +16,15 @@ pub async fn cmd(
|
|||||||
#[description = "Question to ask."] question: String
|
#[description = "Question to ask."] question: String
|
||||||
) -> Result<(), Error>
|
) -> Result<(), Error>
|
||||||
{
|
{
|
||||||
let is_quirky = rand::rng().random_bool(0.2);
|
let quirky_chance = get_toml_mutex(&ctx.data().cfg).await.unwrap()["commands"]["eight_ball_quirky_chance"].as_float().unwrap();
|
||||||
|
let is_quirky = rand::rng().random_bool(quirky_chance.clamp(0.0, 1.0));
|
||||||
let list = &ctx.data().ball_prompts[if is_quirky { 1 } else { 0 }];
|
let list = &ctx.data().ball_prompts[if is_quirky { 1 } else { 0 }];
|
||||||
let rand_item = list.iter().choose(&mut rand::rng());
|
let rand_item = list.iter().choose(&mut rand::rng());
|
||||||
|
|
||||||
send_msg(
|
send_msg(
|
||||||
ctx,
|
ctx,
|
||||||
lang!("dc_msg_8-ball_answer", question, rand_item.unwrap()),
|
lang!("dc_msg_8-ball_answer", question, rand_item.unwrap()),
|
||||||
true,
|
false,
|
||||||
true
|
true
|
||||||
).await;
|
).await;
|
||||||
|
|
||||||
|
|||||||
@@ -1,6 +1,4 @@
|
|||||||
use serde_json::json;
|
use crate::{data::{self, get_toml_mutex, read_cfg_data}, lang, messages::send_msg, 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(
|
||||||
@@ -16,13 +14,15 @@ pub async fn cmd(
|
|||||||
ctx: Context<'_>
|
ctx: Context<'_>
|
||||||
) -> Result<(), Error>
|
) -> Result<(), Error>
|
||||||
{
|
{
|
||||||
read_cfg_data(&ctx.data(), false).await;
|
let r = read_cfg_data(&ctx.data(), false).await;
|
||||||
let d = get_toml_mutex(&ctx.data().cfg).await.unwrap();
|
let d = get_toml_mutex(&ctx.data().cfg).await.unwrap();
|
||||||
let d_str = toml::to_string(&d)?;
|
|
||||||
let r = send_cmd_json("update_cfg", Some(json!([d_str])), true).await;
|
|
||||||
|
|
||||||
if r.is_none() { return Ok(()); }
|
if r.is_none() { return Ok(()); }
|
||||||
|
|
||||||
|
let data_binding = get_toml_mutex(&ctx.data().cfg).await.unwrap();
|
||||||
|
let lang_cfg = data_binding["general"]["lang"].as_str().unwrap();
|
||||||
|
data::load_lang_data(lang_cfg.to_string());
|
||||||
|
|
||||||
if r.unwrap()["value"].as_bool().unwrap() {
|
if r.unwrap()["value"].as_bool().unwrap() {
|
||||||
send_msg(
|
send_msg(
|
||||||
ctx,
|
ctx,
|
||||||
|
|||||||
+4
-4
@@ -95,7 +95,6 @@ fn generate_re_data() {
|
|||||||
|
|
||||||
if let Some(bk_week) = preset_json[CFG_DATA_RE].as_object_mut() {
|
if let Some(bk_week) = preset_json[CFG_DATA_RE].as_object_mut() {
|
||||||
bk_week.remove("EXAMPLE VALUE");
|
bk_week.remove("EXAMPLE VALUE");
|
||||||
bk_week.remove("EXAMPLE VALUE DELETED");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
let json_str = serde_json::to_string_pretty(&preset_json).unwrap();
|
let json_str = serde_json::to_string_pretty(&preset_json).unwrap();
|
||||||
@@ -116,7 +115,7 @@ pub async fn write_re_data() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
pub async fn read_cfg_data(data: &Data, wipe: bool) {
|
pub async fn read_cfg_data(data: &Data, wipe: bool) -> Option<Value> {
|
||||||
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...",
|
||||||
@@ -128,9 +127,10 @@ pub async fn read_cfg_data(data: &Data, wipe: bool) {
|
|||||||
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: toml::Value = str_data.parse().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 = Some(json_data);
|
*cfg_data = Some(json_data.clone());
|
||||||
|
|
||||||
send_cmd_json("update_cfg", Some(json!([str_data])), true).await;
|
let r = send_cmd_json("update_cfg", Some(json!([toml::to_string(&json_data).unwrap()])), true).await;
|
||||||
|
return r;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
+11
-11
@@ -68,12 +68,10 @@ struct Args {
|
|||||||
wipe: bool,
|
wipe: bool,
|
||||||
#[arg(short = 't', long, help = "Makes the program use the ASSISTANT_TOKEN_TEST env var instead of ASSISTANT_TOKEN. This env var should hold the token of a non-production bot.")]
|
#[arg(short = 't', long, help = "Makes the program use the ASSISTANT_TOKEN_TEST env var instead of ASSISTANT_TOKEN. This env var should hold the token of a non-production bot.")]
|
||||||
test: bool,
|
test: bool,
|
||||||
#[arg(long, help = "Removes the annoying ping prints.")]
|
#[arg(long, help = "Adds annoying ping prints.")]
|
||||||
noping: bool,
|
ping: bool,
|
||||||
#[arg(long, help = "Makes the program not use the schedules.")]
|
#[arg(long, help = "Makes the program not use the schedules.")]
|
||||||
nosched: bool,
|
nosched: bool
|
||||||
#[arg(long, default_value = "en", help = "Which language file to use (Do not include file extensions)")]
|
|
||||||
lang: String
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -104,12 +102,7 @@ pub static mut NOPING: bool = false;
|
|||||||
async fn main() {
|
async fn main() {
|
||||||
let args = <Args as clap::Parser>::parse();
|
let args = <Args as clap::Parser>::parse();
|
||||||
let args_str = serde_json::to_string(&args).expect("Error serializing args to JSON");
|
let args_str = serde_json::to_string(&args).expect("Error serializing args to JSON");
|
||||||
unsafe { NOPING = args.noping; }
|
unsafe { NOPING = !args.ping; }
|
||||||
|
|
||||||
|
|
||||||
rs_println!("Fetching language file...");
|
|
||||||
data::load_lang_data(args.clone().lang);
|
|
||||||
rs_println!("[IMPORTANT] The below message is a test message, it should be written in the language you've selected\nTest message: {}", lang!("log_lang_load_success"));
|
|
||||||
|
|
||||||
let own_env = std::env::var("ASSISTANT_OWNERS").unwrap_or("0".to_string());
|
let own_env = std::env::var("ASSISTANT_OWNERS").unwrap_or("0".to_string());
|
||||||
let own_vec_str: Vec<String> = own_env.split(",").map(String::from).collect();
|
let own_vec_str: Vec<String> = own_env.split(",").map(String::from).collect();
|
||||||
@@ -118,8 +111,15 @@ async fn main() {
|
|||||||
.map(|s| s.parse::<u64>().expect("Failed to parse ASSISTANT_OWNERS. Invalid syntax."))
|
.map(|s| s.parse::<u64>().expect("Failed to parse ASSISTANT_OWNERS. Invalid syntax."))
|
||||||
.collect();
|
.collect();
|
||||||
|
|
||||||
|
rs_println!("Generating and/or fetching data and config...");
|
||||||
let data = gen_data(args.clone(), own_vec_u64.clone()).await;
|
let data = gen_data(args.clone(), own_vec_u64.clone()).await;
|
||||||
|
|
||||||
|
rs_println!("Fetching language file...");
|
||||||
|
let data_binding = get_toml_mutex(&data.cfg).await.unwrap();
|
||||||
|
let lang_cfg = data_binding["general"]["lang"].as_str().unwrap();
|
||||||
|
data::load_lang_data(lang_cfg.to_string());
|
||||||
|
rs_println!("[IMPORTANT] The below message is a test message, it should be written in the language you've selected\nTest message: {}", lang!("log_lang_load_success"));
|
||||||
|
|
||||||
if args.test { println!("----- USING TEST BOT -----"); }
|
if args.test { println!("----- USING TEST BOT -----"); }
|
||||||
if args.dev { println!("----- DEV MODE ENABLED -----"); }
|
if args.dev { println!("----- DEV MODE ENABLED -----"); }
|
||||||
if args.dev && args.wipe { println!("----- \"DON'T WORRY ABOUT IT\" MODE ENABLED -----"); }
|
if args.dev && args.wipe { println!("----- \"DON'T WORRY ABOUT IT\" MODE ENABLED -----"); }
|
||||||
|
|||||||
@@ -219,6 +219,7 @@ pub fn make_post_embed(post_data: &Value, url: &str, ephemeral: bool) -> EmbedOp
|
|||||||
|
|
||||||
let desc_str = lang!(
|
let desc_str = lang!(
|
||||||
"dc_msg_embed_re_post",
|
"dc_msg_embed_re_post",
|
||||||
|
post_data["post_data"]["subreddit"].as_str().unwrap(),
|
||||||
post_data["post_data"]["upvotes"].as_i64().unwrap(),
|
post_data["post_data"]["upvotes"].as_i64().unwrap(),
|
||||||
post_data["votes"]["mod_voters"].as_array().unwrap().len(),
|
post_data["votes"]["mod_voters"].as_array().unwrap().len(),
|
||||||
if !media_type.is_null() { media_type.as_str().unwrap() } else { "None" },
|
if !media_type.is_null() { media_type.as_str().unwrap() } else { "None" },
|
||||||
|
|||||||
+13
-12
@@ -1,7 +1,7 @@
|
|||||||
from io import TextIOWrapper
|
from io import TextIOWrapper
|
||||||
import asyncpraw as praw
|
import asyncpraw as praw # type: ignore
|
||||||
import os
|
import os
|
||||||
from typing import Final
|
from typing import Final, Any
|
||||||
from macros import *
|
from macros import *
|
||||||
import toml
|
import toml
|
||||||
|
|
||||||
@@ -11,11 +11,11 @@ CFG_DATA_RE: Final[str] = "reddit"
|
|||||||
|
|
||||||
|
|
||||||
class Bot:
|
class Bot:
|
||||||
args: dict = {"NO_RUST": True, "dev": True, "py": True, "port": 2920}
|
args: dict[str, Any] = {"NO_RUST": True, "dev": True, "py": True, "port": 2920}
|
||||||
r_id: str = os.environ.get("ASSISTANT_R_ID")
|
r_id: str | None = os.environ.get("ASSISTANT_R_ID")
|
||||||
secret: str = os.environ.get("ASSISTANT_R_TOKEN")
|
secret: str | None = os.environ.get("ASSISTANT_R_TOKEN")
|
||||||
username: str = os.environ.get("ASSISTANT_R_NAME")
|
username: str | None = os.environ.get("ASSISTANT_R_NAME")
|
||||||
password: str = os.environ.get("ASSISTANT_R_PASS")
|
password: str | None = os.environ.get("ASSISTANT_R_PASS")
|
||||||
|
|
||||||
fetch_limit = 0
|
fetch_limit = 0
|
||||||
|
|
||||||
@@ -39,14 +39,14 @@ class Bot:
|
|||||||
)
|
)
|
||||||
self.sr_list: list[str] = ["bytedicetesting"]
|
self.sr_list: list[str] = ["bytedicetesting"]
|
||||||
self.sr = None
|
self.sr = None
|
||||||
self.data_f: TextIOWrapper = None
|
self.data_f: TextIOWrapper | None = None
|
||||||
self.data: dict = {}
|
self.data: dict[str, Any] = {}
|
||||||
self.flairs: list[str] = []
|
self.flairs: list[str] = []
|
||||||
|
|
||||||
async def initialize(self):
|
async def initialize(self):
|
||||||
self.sr = await self.r.subreddit("+".join(self.sr_list))
|
self.sr = await self.r.subreddit("+".join(self.sr_list))
|
||||||
|
|
||||||
async def set_args(self, args: dict):
|
async def set_args(self, args: dict[str, Any]):
|
||||||
self.args = args
|
self.args = args
|
||||||
|
|
||||||
async def stop(self) -> bool:
|
async def stop(self) -> bool:
|
||||||
@@ -59,12 +59,13 @@ class Bot:
|
|||||||
|
|
||||||
async def update_cfg_str(self, new_cfg: str) -> bool:
|
async def update_cfg_str(self, new_cfg: str) -> bool:
|
||||||
json_cfg = toml.loads(new_cfg)
|
json_cfg = toml.loads(new_cfg)
|
||||||
self.update_cfg(json_cfg)
|
await self.update_cfg(json_cfg)
|
||||||
return True
|
return True
|
||||||
|
|
||||||
async def update_cfg(self, new_cfg: dict) -> bool:
|
async def update_cfg(self, new_cfg: dict[str, Any]) -> bool:
|
||||||
self.sr_list = new_cfg[CFG_DATA_RE]["subreddits"].split("+")
|
self.sr_list = new_cfg[CFG_DATA_RE]["subreddits"].split("+")
|
||||||
self.sr = await self.r.subreddit("+".join(self.sr_list))
|
self.sr = await self.r.subreddit("+".join(self.sr_list))
|
||||||
self.fetch_limit = new_cfg[CFG_DATA_RE]["fetch_limit"]
|
self.fetch_limit = new_cfg[CFG_DATA_RE]["fetch_limit"]
|
||||||
self.flairs = new_cfg[CFG_DATA_RE]["search_flairs"]
|
self.flairs = new_cfg[CFG_DATA_RE]["search_flairs"]
|
||||||
|
init_lang(new_cfg["general"]["lang"])
|
||||||
return True
|
return True
|
||||||
@@ -1,5 +1,6 @@
|
|||||||
import json
|
|
||||||
import os
|
import os
|
||||||
|
import json
|
||||||
|
|
||||||
from printColors import PrintColors
|
from printColors import PrintColors
|
||||||
|
|
||||||
|
|
||||||
@@ -8,14 +9,15 @@ G_LANG: dict[str, str] = {}
|
|||||||
DATA_PATH_LANG: str = "./data/lang/"
|
DATA_PATH_LANG: str = "./data/lang/"
|
||||||
|
|
||||||
|
|
||||||
def py_print(*args):
|
def py_print(*args: str):
|
||||||
print(
|
print(
|
||||||
PrintColors.FG.blue + "Py",
|
PrintColors.FG.blue + "Py",
|
||||||
"-",
|
"-",
|
||||||
" ".join(args) + PrintColors.Special.reset
|
" ".join(args) + PrintColors.Special.reset
|
||||||
)
|
)
|
||||||
|
|
||||||
def py_error(*args):
|
|
||||||
|
def py_error(*args: str):
|
||||||
print(
|
print(
|
||||||
PrintColors.BG.red + "ERROR" + PrintColors.Special.reset,
|
PrintColors.BG.red + "ERROR" + PrintColors.Special.reset,
|
||||||
PrintColors.FG.blue + "Py",
|
PrintColors.FG.blue + "Py",
|
||||||
@@ -29,13 +31,13 @@ def lang(k: str) -> str:
|
|||||||
if G_LANG == {}:
|
if G_LANG == {}:
|
||||||
py_error("Language must be initialized before use!")
|
py_error("Language must be initialized before use!")
|
||||||
t = G_LANG.get(k)
|
t = G_LANG.get(k)
|
||||||
if k is None: py_error(f"Key not found in language \"{G_LANG_NAME}\": {k}")
|
if t is None: py_error(f"Key not found in language \"{G_LANG_NAME}\": {k}")
|
||||||
return str(t)
|
return str(t)
|
||||||
|
|
||||||
|
|
||||||
def init_lang(lang_name: str):
|
def init_lang(lang_name: str):
|
||||||
global G_LANG, G_LANG_NAME
|
global G_LANG, G_LANG_NAME
|
||||||
G_LANG_NAME = lang_name
|
G_LANG_NAME = lang_name # type: ignore
|
||||||
|
|
||||||
full_path = f"{DATA_PATH_LANG}{lang_name}.json"
|
full_path = f"{DATA_PATH_LANG}{lang_name}.json"
|
||||||
|
|
||||||
@@ -50,4 +52,4 @@ def init_lang(lang_name: str):
|
|||||||
except json.JSONDecodeError as e:
|
except json.JSONDecodeError as e:
|
||||||
py_error(f"Failed to parse JSON for language \"{lang_name}\":\n{e}")
|
py_error(f"Failed to parse JSON for language \"{lang_name}\":\n{e}")
|
||||||
|
|
||||||
G_LANG = json_data
|
G_LANG = json_data # type: ignore
|
||||||
+9
-7
@@ -4,12 +4,12 @@ import time
|
|||||||
|
|
||||||
from macros import *
|
from macros import *
|
||||||
import bot as botPy
|
import bot as botPy
|
||||||
import data
|
import py_data
|
||||||
import py_websocket
|
import py_websocket
|
||||||
|
|
||||||
|
|
||||||
async def main():
|
async def main():
|
||||||
sys.stdout.reconfigure(encoding="utf-8")
|
sys.stdout.reconfigure(encoding="utf-8") # type: ignore
|
||||||
|
|
||||||
py_print("Creating Reddit bot...")
|
py_print("Creating Reddit bot...")
|
||||||
bot = botPy.Bot()
|
bot = botPy.Bot()
|
||||||
@@ -20,8 +20,10 @@ async def main():
|
|||||||
# args is supposed to be undefined.
|
# args is supposed to be undefined.
|
||||||
# It gets defined in Rust.
|
# It gets defined in Rust.
|
||||||
try:
|
try:
|
||||||
await bot.set_args(args)
|
await bot.set_args(args) # type: ignore
|
||||||
init_lang(lang_name)
|
py_print("Fetching language file...")
|
||||||
|
init_lang(lang_name) # type: ignore
|
||||||
|
py_print(f"[IMPORTANT] The below message is a test message, it should be written in the language you've selected\nTest message: {lang('log_lang_load_success')}")
|
||||||
except NameError:
|
except NameError:
|
||||||
py_print("No command args or language name found from Rust. Don't worry though, we have backup in place.")
|
py_print("No command args or language name found from Rust. Don't worry though, we have backup in place.")
|
||||||
init_lang("en")
|
init_lang("en")
|
||||||
@@ -30,17 +32,17 @@ async def main():
|
|||||||
py_print("ARGS:", str(bot.args))
|
py_print("ARGS:", str(bot.args))
|
||||||
|
|
||||||
py_print("Reading config file...")
|
py_print("Reading config file...")
|
||||||
await data.read_cfg(bot)
|
await py_data.read_cfg(bot)
|
||||||
|
|
||||||
py_print("Reading Reddit data...")
|
py_print("Reading Reddit data...")
|
||||||
rd = data.read_data(bot)
|
rd = py_data.read_data(bot)
|
||||||
data_retries = 0
|
data_retries = 0
|
||||||
|
|
||||||
while not rd :
|
while not rd :
|
||||||
data_retries += 1
|
data_retries += 1
|
||||||
time.sleep(1)
|
time.sleep(1)
|
||||||
py_print(f"Failed to read data: File doesn't exist yet. Retrying (#{data_retries}/5)...")
|
py_print(f"Failed to read data: File doesn't exist yet. Retrying (#{data_retries}/5)...")
|
||||||
rd = data.read_data(bot)
|
rd = py_data.read_data(bot)
|
||||||
|
|
||||||
if data_retries == 5 and not rd:
|
if data_retries == 5 and not rd:
|
||||||
raise Exception("Couldn't read re_data.json: File doesn't exist")
|
raise Exception("Couldn't read re_data.json: File doesn't exist")
|
||||||
|
|||||||
+19
-16
@@ -1,10 +1,10 @@
|
|||||||
import emoji
|
import emoji
|
||||||
from asyncpraw import models
|
from asyncpraw import models # type: ignore
|
||||||
import asyncprawcore as prawcore
|
import asyncprawcore as prawcore # type: ignore
|
||||||
import asyncpraw.exceptions as exc
|
import asyncpraw.exceptions as exc # type: ignore
|
||||||
import time
|
import time
|
||||||
|
|
||||||
import data
|
import py_data
|
||||||
import bot as botPy
|
import bot as botPy
|
||||||
from macros import *
|
from macros import *
|
||||||
|
|
||||||
@@ -46,7 +46,7 @@ async def add_new_posts(bot: botPy.Bot, max_age: int) -> bool:
|
|||||||
without_media += 1
|
without_media += 1
|
||||||
continue
|
continue
|
||||||
|
|
||||||
post_added = data.add_post_to_data(
|
post_added = py_data.add_post_to_data(
|
||||||
bot,
|
bot,
|
||||||
details
|
details
|
||||||
)
|
)
|
||||||
@@ -60,7 +60,7 @@ async def add_new_posts(bot: botPy.Bot, max_age: int) -> bool:
|
|||||||
f"{not_added} are removed or already existed, " +
|
f"{not_added} are removed or already existed, " +
|
||||||
f"and {old_posts} were older than the max age threshold.")
|
f"and {old_posts} were older than the max age threshold.")
|
||||||
|
|
||||||
data.write_data(bot)
|
py_data.write_data(bot)
|
||||||
|
|
||||||
return True
|
return True
|
||||||
|
|
||||||
@@ -72,6 +72,8 @@ async def fetch_posts_with_flair(bot: botPy.Bot, flair_names: list[str]) -> list
|
|||||||
f"flair:{flair_names[0]}" if len(flair_names) == 1\
|
f"flair:{flair_names[0]}" if len(flair_names) == 1\
|
||||||
else " OR ".join(f"flair:{flair}" for flair in flair_names)
|
else " OR ".join(f"flair:{flair}" for flair in flair_names)
|
||||||
|
|
||||||
|
if bot.sr is None: return []
|
||||||
|
|
||||||
# ~36 OG-art posts per week, round limit to 50, 75 or 100
|
# ~36 OG-art posts per week, round limit to 50, 75 or 100
|
||||||
async for post in bot.sr.search(f"{flair_names_str}", sort="new", limit=bot.fetch_limit):
|
async for post in bot.sr.search(f"{flair_names_str}", sort="new", limit=bot.fetch_limit):
|
||||||
posts.append(post)
|
posts.append(post)
|
||||||
@@ -79,8 +81,8 @@ async def fetch_posts_with_flair(bot: botPy.Bot, flair_names: list[str]) -> list
|
|||||||
return posts
|
return posts
|
||||||
|
|
||||||
|
|
||||||
def has_media(post: models.Submission) -> tuple[bool, str, int, list[str]]:
|
def has_media(post: models.Submission) -> tuple[bool, str | None, int, list[str]]:
|
||||||
media_type: str = None
|
media_type: str | None = None
|
||||||
media_count = 0
|
media_count = 0
|
||||||
media_urls: list[str] = []
|
media_urls: list[str] = []
|
||||||
|
|
||||||
@@ -109,7 +111,7 @@ def has_media(post: models.Submission) -> tuple[bool, str, int, list[str]]:
|
|||||||
return (media_type != None, media_type, media_count, media_urls)
|
return (media_type != None, media_type, media_count, media_urls)
|
||||||
|
|
||||||
|
|
||||||
async def from_url(bot: botPy.Bot, url: str) -> tuple[bool, models.Submission]:
|
async def from_url(bot: botPy.Bot, url: str) -> tuple[bool, models.Submission | None]:
|
||||||
try:
|
try:
|
||||||
post: models.Submission = await bot.r.submission(url=url)
|
post: models.Submission = await bot.r.submission(url=url)
|
||||||
return True, post
|
return True, post
|
||||||
@@ -120,11 +122,12 @@ async def from_url(bot: botPy.Bot, url: str) -> tuple[bool, models.Submission]:
|
|||||||
return False, None
|
return False, None
|
||||||
|
|
||||||
|
|
||||||
def get_post_details(post: models.Submission, added_by_h: bool = False) -> data.PostData:
|
def get_post_details(post: models.Submission, added_by_h: bool = False) -> py_data.PostData:
|
||||||
media = has_media(post)
|
media = has_media(post)
|
||||||
|
|
||||||
return data.PostData(
|
return py_data.PostData(
|
||||||
post.shortlink,
|
post.shortlink,
|
||||||
|
post.subreddit,
|
||||||
post.title,
|
post.title,
|
||||||
post.score,
|
post.score,
|
||||||
int(post.created_utc),
|
int(post.created_utc),
|
||||||
@@ -135,12 +138,12 @@ def get_post_details(post: models.Submission, added_by_h: bool = False) -> data.
|
|||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
async def add_post_url(bot, url: str, approve: bool = False, added_by_h: bool = False) -> bool:
|
async def add_post_url(bot: botPy.Bot, url: str, approve: bool = False, added_by_h: bool = False) -> bool:
|
||||||
result, post = await from_url(bot, url)
|
result, post = await from_url(bot, url)
|
||||||
|
|
||||||
if not result:
|
if not result: return False
|
||||||
return False
|
if post is None: return False
|
||||||
|
|
||||||
post_data = get_post_details(post, added_by_h)
|
post_data = get_post_details(post, added_by_h)
|
||||||
post_data.approved_by_human = approve
|
post_data.approved_by_human = approve
|
||||||
return data.add_post_to_data(bot, post_data, True)
|
return py_data.add_post_to_data(bot, post_data, True)
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
import asyncpraw.models as models
|
import asyncpraw.models as models # type: ignore
|
||||||
|
|
||||||
from macros import *
|
from macros import *
|
||||||
import bot as botPy
|
import bot as botPy
|
||||||
@@ -2,6 +2,7 @@ import os
|
|||||||
import toml
|
import toml
|
||||||
import json
|
import json
|
||||||
import time
|
import time
|
||||||
|
from typing import Any
|
||||||
|
|
||||||
import bot as botPy
|
import bot as botPy
|
||||||
from macros import *
|
from macros import *
|
||||||
@@ -17,10 +18,11 @@ class PostData:
|
|||||||
def __init__(
|
def __init__(
|
||||||
self,
|
self,
|
||||||
url: str,
|
url: str,
|
||||||
|
subreddit: str,
|
||||||
title: str,
|
title: str,
|
||||||
upvotes: int,
|
upvotes: int,
|
||||||
date_unix: int,
|
date_unix: int,
|
||||||
media_type: str,
|
media_type: str | None,
|
||||||
media_urls: list[str],
|
media_urls: list[str],
|
||||||
removed: bool = False,
|
removed: bool = False,
|
||||||
removed_by: str | None = None,
|
removed_by: str | None = None,
|
||||||
@@ -33,6 +35,7 @@ class PostData:
|
|||||||
approved_by_human: bool = False,
|
approved_by_human: bool = False,
|
||||||
approved_by_ris: bool = False
|
approved_by_ris: bool = False
|
||||||
):
|
):
|
||||||
|
self.subreddit = subreddit
|
||||||
self.removed = removed
|
self.removed = removed
|
||||||
self.removed_by = removed_by
|
self.removed_by = removed_by
|
||||||
self.removed_reason = removed_reason
|
self.removed_reason = removed_reason
|
||||||
@@ -50,7 +53,7 @@ class PostData:
|
|||||||
self.approved_by_human = approved_by_human
|
self.approved_by_human = approved_by_human
|
||||||
self.approved_by_ris = approved_by_ris
|
self.approved_by_ris = approved_by_ris
|
||||||
|
|
||||||
def to_json(self):
|
def to_json(self) -> dict[str, Any]:
|
||||||
return {
|
return {
|
||||||
"removed": {
|
"removed": {
|
||||||
"removed": self.removed,
|
"removed": self.removed,
|
||||||
@@ -58,6 +61,7 @@ class PostData:
|
|||||||
"reason": self.removed_reason
|
"reason": self.removed_reason
|
||||||
},
|
},
|
||||||
"post_data": {
|
"post_data": {
|
||||||
|
"subreddit": self.subreddit,
|
||||||
"title": self.title,
|
"title": self.title,
|
||||||
"upvotes": self.upvotes,
|
"upvotes": self.upvotes,
|
||||||
"date_unix": self.date_unix,
|
"date_unix": self.date_unix,
|
||||||
@@ -92,10 +96,9 @@ def read_data(bot: botPy.Bot) -> bool:
|
|||||||
|
|
||||||
py_print("re_data.json not found, creating new from preset...")
|
py_print("re_data.json not found, creating new from preset...")
|
||||||
with open(os.path.join(DEFAULT_PATH, "re_data_preset.json"), "r") as f:
|
with open(os.path.join(DEFAULT_PATH, "re_data_preset.json"), "r") as f:
|
||||||
data_preset_json = json.load(f)
|
data_preset_json: dict[str, Any] = json.load(f)
|
||||||
|
|
||||||
data_preset_json[botPy.RE_DATA_POSTS].pop("EXAMPLE VALUE", None)
|
data_preset_json[botPy.RE_DATA_POSTS].pop("EXAMPLE VALUE", None)
|
||||||
data_preset_json[botPy.RE_DATA_POSTS].pop("EXAMPLE VALUE DELETED", None)
|
|
||||||
|
|
||||||
with open(r_path, "w") as f:
|
with open(r_path, "w") as f:
|
||||||
json.dump(data_preset_json, f, indent = 2)
|
json.dump(data_preset_json, f, indent = 2)
|
||||||
@@ -110,6 +113,8 @@ def read_data(bot: botPy.Bot) -> bool:
|
|||||||
|
|
||||||
|
|
||||||
def write_data(bot: botPy.Bot) -> bool:
|
def write_data(bot: botPy.Bot) -> bool:
|
||||||
|
if bot.data_f is None: return False
|
||||||
|
|
||||||
bot.data_f.seek(0)
|
bot.data_f.seek(0)
|
||||||
json.dump(bot.data, bot.data_f, indent=2)
|
json.dump(bot.data, bot.data_f, indent=2)
|
||||||
bot.data_f.truncate()
|
bot.data_f.truncate()
|
||||||
@@ -128,7 +133,7 @@ async def read_cfg(bot: botPy.Bot) -> bool:
|
|||||||
data_preset_json = toml.load(f)
|
data_preset_json = toml.load(f)
|
||||||
|
|
||||||
with open(r_path, "w") as f:
|
with open(r_path, "w") as f:
|
||||||
toml.dump(data_preset_json, f, indent = 2)
|
toml.dump(data_preset_json, f, indent = 2) # type: ignore
|
||||||
|
|
||||||
bot.data_f = open(r_path, "r+")
|
bot.data_f = open(r_path, "r+")
|
||||||
|
|
||||||
@@ -224,12 +229,12 @@ def set_vote_post(
|
|||||||
if remove_vote:
|
if remove_vote:
|
||||||
if user not in target_voters:
|
if user not in target_voters:
|
||||||
return False
|
return False
|
||||||
target_voters.remove(user)
|
target_voters.remove(user) # type: ignore
|
||||||
|
|
||||||
else:
|
else:
|
||||||
if user in target_voters:
|
if user in target_voters:
|
||||||
return False
|
return False
|
||||||
target_voters.add(user)
|
target_voters.add(user) # type: ignore
|
||||||
|
|
||||||
bot.data[botPy.RE_DATA_POSTS][url]["votes"]["voters_re"] = list(re_voters)
|
bot.data[botPy.RE_DATA_POSTS][url]["votes"]["voters_re"] = list(re_voters)
|
||||||
bot.data[botPy.RE_DATA_POSTS][url]["votes"]["voters_dc"] = list(dc_voters)
|
bot.data[botPy.RE_DATA_POSTS][url]["votes"]["voters_dc"] = list(dc_voters)
|
||||||
+22
-21
@@ -1,13 +1,13 @@
|
|||||||
import websockets
|
import websockets
|
||||||
import asyncio
|
import asyncio
|
||||||
import json
|
import json
|
||||||
|
from typing import Any
|
||||||
|
|
||||||
from macros import *
|
from macros import *
|
||||||
import bot as botPy
|
import bot as botPy
|
||||||
import data
|
import py_data
|
||||||
import posts
|
import posts
|
||||||
import cmds
|
import py_cmds
|
||||||
import macros
|
|
||||||
|
|
||||||
ws_global = None
|
ws_global = None
|
||||||
is_connected = False
|
is_connected = False
|
||||||
@@ -36,9 +36,10 @@ async def websocket_client(bot: botPy.Bot):
|
|||||||
|
|
||||||
while True:
|
while True:
|
||||||
response = await ws.recv()
|
response = await ws.recv()
|
||||||
if not response.startswith("json:"):
|
str_response = str(response)
|
||||||
|
if not str_response.startswith("json:"): # type: ignore
|
||||||
py_print(f"Received from Rust: {response}")
|
py_print(f"Received from Rust: {response}")
|
||||||
await parse_json(response, bot)
|
await parse_json(str_response, bot)
|
||||||
|
|
||||||
|
|
||||||
async def parse_json(response: str, bot: botPy.Bot):
|
async def parse_json(response: str, bot: botPy.Bot):
|
||||||
@@ -50,7 +51,7 @@ async def parse_json(response: str, bot: botPy.Bot):
|
|||||||
if json_response["print"]: py_print(f"Received from Rust: {response}")
|
if json_response["print"]: py_print(f"Received from Rust: {response}")
|
||||||
|
|
||||||
result = await json_to_func(json_response, bot)
|
result = await json_to_func(json_response, bot)
|
||||||
await ws_global.ping()
|
if ws_global is not None: await ws_global.ping()
|
||||||
await send_message(f"json:{json.dumps(result)}")
|
await send_message(f"json:{json.dumps(result)}")
|
||||||
except json.JSONDecodeError as e:
|
except json.JSONDecodeError as e:
|
||||||
if bot.args["dev"]: py_print(f"failed to parse json: {json_str}\n reason: {e}")
|
if bot.args["dev"]: py_print(f"failed to parse json: {json_str}\n reason: {e}")
|
||||||
@@ -62,29 +63,29 @@ def run_thread(bot: botPy.Bot):
|
|||||||
loop.run_until_complete(websocket_client(bot))
|
loop.run_until_complete(websocket_client(bot))
|
||||||
|
|
||||||
|
|
||||||
async def json_to_func(v: dict, bot: botPy.Bot) -> dict:
|
async def json_to_func(v: dict[str, Any], bot: botPy.Bot) -> dict[str, Any]:
|
||||||
if "type" not in v or "value" not in v or not isinstance(v, dict):
|
if "type" not in v or "value" not in v:
|
||||||
if bot.args["dev"]: py_print("JSON is not a dictionary or does not include \"type\" and \"value\" keys.")
|
if bot.args["dev"]: py_print("JSON is not a dictionary or does not include \"type\" and \"value\" keys.")
|
||||||
return
|
return result_json(False, True)
|
||||||
if v["type"] != "function":
|
if v["type"] != "function":
|
||||||
v_type = v["type"]
|
v_type = v["type"]
|
||||||
if bot.args["dev"]: py_print(f"Type \"{v_type}\" is not supported.")
|
if bot.args["dev"]: py_print(f"Type \"{v_type}\" is not supported.")
|
||||||
return
|
return result_json(False, True)
|
||||||
|
|
||||||
value_supported = True
|
value_supported = True
|
||||||
r = False
|
r = False
|
||||||
|
|
||||||
match v["value"]:
|
match v["value"]:
|
||||||
case "update_data_file": r = data .write_data (bot)
|
case "update_data_file": r = py_data.write_data (bot)
|
||||||
case "respond_mentions": r = await cmds .respond_to_mention(bot)
|
case "respond_mentions": r = await py_cmds.respond_to_mention(bot)
|
||||||
case "add_new_posts": r = await posts .add_new_posts (bot, *v["args"])
|
case "add_new_posts": r = await posts .add_new_posts (bot, *v["args"])
|
||||||
case "add_post_url": r = await posts .add_post_url (bot, *v["args"])
|
case "add_post_url": r = await posts .add_post_url (bot, *v["args"])
|
||||||
case "remove_post_url": r = data .remove_post (bot, *v["args"])
|
case "remove_post_url": r = py_data.remove_post (bot, *v["args"])
|
||||||
case "set_approve_post": r = data .set_approve_post (bot, *v["args"])
|
case "set_approve_post": r = py_data.set_approve_post (bot, *v["args"])
|
||||||
case "set_vote_post": r = data .set_vote_post (bot, *v["args"])
|
case "set_vote_post": r = py_data.set_vote_post (bot, *v["args"])
|
||||||
case "remove_old_posts": r = data .remove_old_posts (bot, *v["args"])
|
case "remove_old_posts": r = py_data.remove_old_posts (bot, *v["args"])
|
||||||
case "update_cfg": r = await bot .update_cfg_str (*v["args"])
|
case "update_cfg": r = await bot .update_cfg_str (*v["args"])
|
||||||
case "stop_praw": r = await bot .stop ()
|
case "stop_praw": r = await bot .stop ()
|
||||||
case _: value_supported = False
|
case _: value_supported = False
|
||||||
|
|
||||||
print_result = v["print"]
|
print_result = v["print"]
|
||||||
@@ -97,5 +98,5 @@ async def json_to_func(v: dict, bot: botPy.Bot) -> dict:
|
|||||||
return result_json(r, print_result)
|
return result_json(r, print_result)
|
||||||
|
|
||||||
|
|
||||||
def result_json(bool: bool, print_result: bool) -> dict:
|
def result_json(bool: bool, print_result: bool) -> dict[str, Any]:
|
||||||
return {"type": "result", "value": bool, "print": print_result}
|
return {"type": "result", "value": bool, "print": print_result}
|
||||||
+2
-2
@@ -152,12 +152,12 @@ async fn handle_message(msg: tungstenite::protocol::Message, args: Args, owners:
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
tungstenite::Message::Binary(bytes) => {
|
tungstenite::Message::Binary(bytes) => {
|
||||||
if args.dev && !args.noping {
|
if args.dev && args.ping {
|
||||||
rs_println!("[Binary] from Python: {:?}", bytes);
|
rs_println!("[Binary] from Python: {:?}", bytes);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
_ => {
|
_ => {
|
||||||
if args.dev && !args.noping {
|
if args.dev && args.ping {
|
||||||
rs_println!("Received from Python: [UNKNOWN / OTHER]");
|
rs_println!("Received from Python: [UNKNOWN / OTHER]");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user