added rest of the buttons (still needs listeners) & reformatted/improved other code

This commit is contained in:
2025-06-06 15:37:06 +02:00
parent 53a1fdee19
commit c0793562e3
19 changed files with 132 additions and 105 deletions
+2
View File
@@ -1,5 +1,7 @@
### High priority: ### High priority:
- [ ] Reddit bot that scrapes images with tag "Original Art" and posts them in Discord server - [ ] Reddit bot that scrapes images with tag "Original Art" and posts them in Discord server
- [ ] handle dm_on_error cfg
- [ ] Add button event listeners
- [ ] Allow updating the data autonomously and via manual commands. - [ ] Allow updating the data autonomously and via manual commands.
- [ ] Automatically approve posts that don't get caught by reverse image search (ris) - [ ] Automatically approve posts that don't get caught by reverse image search (ris)
- [ ] Make buttons do stuff - [ ] Make buttons do stuff
+3 -3
View File
@@ -6,10 +6,10 @@
"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_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_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_socket": "Unknown internal Python error occurred: Websocket response error",
"dc_msg_dm_python_err": "Unknown internal Python Error: {0}", "dc_msg_dm_python_err": "Unknown internal Python Error: `{0}`",
"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**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_removed": "## Removed by `{0}`\n**Reason:** {1}\nURL: ||<{2}>||\n\nJSON: ||`{3}`||", "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.",
"dc_msg_mandatory_response": "Mandatory response message, please ignore.", "dc_msg_mandatory_response": "Mandatory response message, please ignore.",
@@ -25,7 +25,7 @@
"dc_msg_re_post_add_success": "Added post with URL \"<{0}>\"!", "dc_msg_re_post_add_success": "Added post with URL \"<{0}>\"!",
"dc_msg_re_post_approve_success": "Successfully approved the post!", "dc_msg_re_post_approve_success": "Successfully approved the post!",
"dc_msg_re_post_disapprove_success": "Successfully disapproved the post!", "dc_msg_re_post_disapprove_success": "Successfully disapproved the post!",
"dc_msg_re_post_remove_success": "Successfully removed post!", "dc_msg_re_post_remove_success": "Successfully removed post with URL \"<{0}>\"!",
"dc_msg_re_post_unremove_success": "Successfully un-removed post with URL \"<{0}>\"!", "dc_msg_re_post_unremove_success": "Successfully un-removed post with URL \"<{0}>\"!",
"dc_msg_re_post_update_success": "Updated post with URL \"<{0}>\"!", "dc_msg_re_post_update_success": "Updated post with URL \"<{0}>\"!",
"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_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).",
+6 -6
View File
@@ -1,6 +1,11 @@
{ {
"posts": { "posts": {
"EXAMPLE VALUE": { "EXAMPLE URL": {
"removed": {
"removed": false,
"by": null,
"reason": null
},
"post_data": { "post_data": {
"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,
@@ -21,11 +26,6 @@
"by_human": true, "by_human": true,
"by_ris": true "by_ris": true
} }
},
"EXAMPLE VALUE DELETED": {
"removed": true,
"removed_by": "ME!!!!",
"remove_reason": "i HATED that post >:("
} }
} }
} }
+1 -1
View File
@@ -19,7 +19,7 @@ pub async fn cmd(
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_mutex_data(&ctx.data().cfg).await?;
let d_str = serde_json::to_string(&d)?; let d_str = serde_json::to_string(&d)?;
let r = send_cmd_json("update_cfg", Some(json!([d_str]))).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(
+1 -1
View File
@@ -26,7 +26,7 @@ pub async fn cmd(
let msg = send_msg(ctx, lang!("dc_msg_owner_data_save"), true, true).await.unwrap(); let msg = send_msg(ctx, lang!("dc_msg_owner_data_save"), true, true).await.unwrap();
data::write_dc_data(ctx.data()).await; data::write_dc_data(ctx.data()).await;
data::write_re_data().await; data::write_re_data().await;
send_cmd_json("stop_praw", None).await; send_cmd_json("stop_praw", None, true).await;
edit_reply(ctx, msg, lang!("dc_msg_owner_data_save_complete")).await; edit_reply(ctx, msg, lang!("dc_msg_owner_data_save_complete")).await;
ctx.serenity_context().set_presence(None, OnlineStatus::Invisible); ctx.serenity_context().set_presence(None, OnlineStatus::Invisible);
+3 -3
View File
@@ -103,13 +103,13 @@ fn generate_re_data() {
pub async fn update_re_data(data: &Data) { pub async fn update_re_data(data: &Data) {
send_cmd_json("update_data_file", None).await; send_cmd_json("update_data_file", None, true).await;
read_re_data(data, false).await; read_re_data(data, false).await;
} }
pub async fn write_re_data() { pub async fn write_re_data() {
send_cmd_json("update_data_file", None).await; send_cmd_json("update_data_file", None, true).await;
} }
@@ -127,7 +127,7 @@ pub async fn read_cfg_data(data: &Data, wipe: bool) {
let mut cfg_data = data.cfg.lock().await; let mut cfg_data = data.cfg.lock().await;
*cfg_data = json_data; *cfg_data = json_data;
send_cmd_json("update_cfg", Some(json!([str_data]))).await; send_cmd_json("update_cfg", Some(json!([str_data])), true).await;
} }
+2 -4
View File
@@ -100,14 +100,12 @@ async fn make_cmd_vec(data: &Data) -> Vec<Cmd> {
re_cmds::top::cmd(), re_cmds::top::cmd(),
re_cmds::update::cmd(), re_cmds::update::cmd(),
re_cmds::vote::cmd(), re_cmds::vote::cmd(),
re_cmds::shorturl::cmd() re_cmds::shorturl::cmd(),
re_cmds::admin_bind::cmd(),
]); ]);
} }
cmds.extend([ cmds.extend([
// reddit admin
re_cmds::admin_bind::cmd(),
// cfg
cmds::reload_cfg::cmd() cmds::reload_cfg::cmd()
]); ]);
+9 -3
View File
@@ -94,13 +94,15 @@ struct Data {
static CFG_DATA_RE: &str = "posts"; static CFG_DATA_RE: &str = "posts";
pub static mut LANG: Option<serde_json::Value> = None; pub static mut LANG: Option<serde_json::Value> = None;
pub static mut NOPING: bool = false;
#[tokio::main] #[tokio::main]
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; }
rs_println!("Fetching language file..."); rs_println!("Fetching language file...");
data::load_lang_data(args.clone().lang); data::load_lang_data(args.clone().lang);
@@ -118,6 +120,8 @@ async fn main() {
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 -----"); }
if args.nosched { println!("----- NO SCHEDULES -----"); } if args.nosched { println!("----- NO SCHEDULES -----"); }
// TODO: handle if config for reddit is disabled to not start python
if args.py && !args.rs { if args.py && !args.rs {
println!("----- PYTHON ONLY MODE -----"); println!("----- PYTHON ONLY MODE -----");
rs_println!("ARGS: {}", args_str); rs_println!("ARGS: {}", args_str);
@@ -174,6 +178,8 @@ async fn start(args: Args, owners: Vec<u64>) {
async fn read_reddit_inbox() { async fn read_reddit_inbox() {
unsafe { if !websocket::HAS_CONNECTED { return; } } unsafe {
send_cmd_json("respond_mentions", None).await; if !websocket::HAS_CONNECTED { return; }
send_cmd_json("respond_mentions", None, !NOPING).await;
}
} }
+24 -22
View File
@@ -5,7 +5,6 @@ use crate::{lang, Args, Context};
use poise::serenity_prelude::json::Value; use poise::serenity_prelude::json::Value;
use poise::{serenity_prelude::CreateMessage, CreateReply, ReplyHandle}; use poise::{serenity_prelude::CreateMessage, CreateReply, ReplyHandle};
use poise::serenity_prelude::{ChannelId, Color, CreateActionRow, CreateButton, CreateEmbed, CreateEmbedAuthor, EditMessage, Http, Message, ReactionType, Timestamp, UserId}; use poise::serenity_prelude::{ChannelId, Color, CreateActionRow, CreateButton, CreateEmbed, CreateEmbedAuthor, EditMessage, Http, Message, ReactionType, Timestamp, UserId};
use serde_json::json;
#[derive(Clone)] #[derive(Clone)]
@@ -48,6 +47,9 @@ impl Default for EmbedOptions {
static DEFAULT_DC_COL: u32 = 5793266; static DEFAULT_DC_COL: u32 = 5793266;
static REMOVED_DC_COL: u32 = 16716032; static REMOVED_DC_COL: u32 = 16716032;
pub static JSON_TEXT_START: &str = "-# JSON: ||`";
pub static JSON_TEXT_END: &str = "`||";
fn none_to_empty(string: Option<String>) -> String { fn none_to_empty(string: Option<String>) -> String {
return string.unwrap_or_default(); return string.unwrap_or_default();
@@ -226,25 +228,19 @@ pub fn make_post_embed(post_data: &Value, url: &str, ephemeral: bool) -> EmbedOp
.collect::<Vec<_>>() .collect::<Vec<_>>()
.join("\n"); .join("\n");
let json_min = json!(
{"post_data": json!({ "upvotes": post_data["post_data"]["upvotes"] }),
"added": post_data["added"],
"approved": post_data["approved"],
"votes": json!({"mod_voters": post_data["votes"]["mod_voters"]})}
);
let media_urls = post_data["post_data"]["media_urls"].as_array().unwrap(); let media_urls = post_data["post_data"]["media_urls"].as_array().unwrap();
let action_row = CreateActionRow::Buttons(vec![ let action_row = CreateActionRow::Buttons(vec![
CreateButton::new("upvote_btn") .label("Upvote") .emoji(ReactionType::Unicode("⬆️".to_string())), CreateButton::new("vote_btn") .label("Vote") .emoji(ReactionType::Unicode("⬆️".to_string())),
CreateButton::new("unupvote_btn") .label("Un-upvote"), CreateButton::new("unvote_btn") .label("Un-vote"),
CreateButton::new("approve_btn") .label("Approve") .emoji(ReactionType::Unicode("".to_string())), CreateButton::new("approve_btn") .label("Approve") .emoji(ReactionType::Unicode("".to_string())),
CreateButton::new("unapprove_btn") .label("Disapprove") .emoji(ReactionType::Unicode("".to_string())), CreateButton::new("unapprove_btn").label("Disapprove") .emoji(ReactionType::Unicode("".to_string())),
CreateButton::new("remove_btn") .label("Remove") .emoji(ReactionType::Unicode("🗑️".to_string())) CreateButton::new("remove_btn") .label("Remove") .emoji(ReactionType::Unicode("🗑️".to_string()))
]); ]);
return EmbedOptions { return EmbedOptions {
title: Some(post_data["post_data"]["title"].as_str().unwrap().to_string()), title: Some(post_data["post_data"]["title"].as_str().unwrap().to_string()),
desc: format!("{}\n\nJSON: ||`{}`||", trimmed, serde_json::to_string(&json_min).unwrap()), desc: format!("{}\n\n{}{}{}", trimmed, JSON_TEXT_START, serde_json::to_string(&post_data).unwrap(), JSON_TEXT_END),
col: Some(DEFAULT_DC_COL), col: Some(DEFAULT_DC_COL),
url: Some(url.to_string()), url: Some(url.to_string()),
ts: Some(Timestamp::from_unix_timestamp(post_data["post_data"]["date_unix"].as_i64().unwrap()).unwrap()), ts: Some(Timestamp::from_unix_timestamp(post_data["post_data"]["date_unix"].as_i64().unwrap()).unwrap()),
@@ -259,20 +255,26 @@ pub fn make_post_embed(post_data: &Value, url: &str, ephemeral: bool) -> EmbedOp
pub fn make_removed_embed(post_data: &Value, url: &str, ephemeral: bool) -> EmbedOptions { pub fn make_removed_embed(post_data: &Value, url: &str, ephemeral: bool) -> EmbedOptions {
let action_row = CreateActionRow::Buttons(vec![
CreateButton::new("unremove_btn").label("Un-remove").emoji(ReactionType::Unicode("↩️".to_string()))
]);
let desc = lang!(
"dc_msg_embed_re_removed",
post_data["removed"]["by"].as_str().unwrap(),
if !post_data["removed"]["reason"].is_null() { post_data["removed"]["reason"].as_str().unwrap() }
else { "None" },
url
);
return EmbedOptions { return EmbedOptions {
title: Some("REMOVED!".to_string()), title: Some(format!("[REMOVED] {}", post_data["post_data"]["title"])),
desc: lang!( desc: format!("{}\n\n{}{}{}", desc, JSON_TEXT_START, serde_json::to_string(&post_data).unwrap(), JSON_TEXT_END),
"dc_msg_embed_re_removed",
post_data["removed_by"].as_str().unwrap(),
if !post_data["remove_reason"].is_null() { post_data["remove_reason"].as_str().unwrap() }
else { "None" },
url,
serde_json::to_string(&post_data).unwrap()
),
col: Some(REMOVED_DC_COL), col: Some(REMOVED_DC_COL),
url: Some(url.to_string()), url: Some(url.to_string()),
ts: Some(Timestamp::from_unix_timestamp(post_data["post_data"]["date_unix"].as_i64().unwrap()).unwrap()), ts: Some(Timestamp::from_unix_timestamp(post_data["post_data"]["date_unix"].as_i64().unwrap()).unwrap()),
ephemeral, ephemeral,
actionrows: Some(vec![action_row]),
..Default::default() ..Default::default()
}; };
} }
+33 -28
View File
@@ -18,14 +18,20 @@ class PostData:
date_unix: int, date_unix: int,
media_type: str, media_type: str,
media_urls: list[str], media_urls: list[str],
voters_re: list[str] = [], removed: bool = False,
voters_dc: list[int] = [], removed_by: str | None = None,
mod_voters: list[int] = [], removed_reason: str | None = None,
added_by_human: bool = False, voters_re: list[str] = [],
added_by_bot: bool = False, voters_dc: list[int] = [],
approved_by_human: bool = False, mod_voters: list[int] = [],
approved_by_ris: bool = False added_by_human: bool = False,
added_by_bot: bool = False,
approved_by_human: bool = False,
approved_by_ris: bool = False
): ):
self.removed = removed
self.removed_by = removed_by
self.removed_reason = removed_reason
self.url = url self.url = url
self.title = title self.title = title
self.upvotes = upvotes self.upvotes = upvotes
@@ -42,6 +48,11 @@ class PostData:
def to_json(self): def to_json(self):
return { return {
"removed": {
"removed": self.removed,
"by": self.removed_reason,
"reason": self.removed_reason
},
"post_data": { "post_data": {
"title": self.title, "title": self.title,
"upvotes": self.upvotes, "upvotes": self.upvotes,
@@ -125,31 +136,26 @@ async def read_cfg(bot: botPy.Bot) -> bool:
def add_post_to_data(bot: botPy.Bot, new_data: PostData, bypass_conditions: bool = False) -> bool: def add_post_to_data(bot: botPy.Bot, new_data: PostData, bypass_conditions: bool = False) -> bool:
if new_data.removed:
new_data.removed = False
new_data.removed_by = None
new_data.removed_reason = None
if bypass_conditions: if bypass_conditions:
bot.data[botPy.RE_DATA_POSTS][new_data.url] = new_data.to_json() bot.data[botPy.RE_DATA_POSTS][new_data.url] = new_data.to_json()
if bot.args["dev"]: if bot.args["dev"]: py_print(f"Added post \"{new_data.url}\" (Conditions bypassed)")
py_print(f"Added post \"{new_data.url}\" (Conditions bypassed)")
return True return True
# not sure what this is for if new_data.url not in bot.data[botPy.RE_DATA_POSTS]:
updated = False
if new_data.url not in bot.data[botPy.RE_DATA_POSTS] or updated:
bot.data[botPy.RE_DATA_POSTS][new_data.url] = new_data.to_json() bot.data[botPy.RE_DATA_POSTS][new_data.url] = new_data.to_json()
if bot.args["dev"]: if bot.args["dev"]: py_print(f"Added post \"{new_data.url}\"")
py_print(f"Added post \"{new_data.url}\"")
return True return True
if "removed" not in bot.data[botPy.RE_DATA_POSTS][new_data.url]:
updated = new_data.upvotes != bot.data[botPy.RE_DATA_POSTS][new_data.url]["post_data"]
else: return False
py_print(f"Failed to add post \"{new_data.url}\": Removed flag is True.")
return False
def set_approve_post(bot: botPy.Bot, approved: bool, url: str) -> bool: def set_approve_post(bot: botPy.Bot, approved: bool, url: str) -> bool:
if not hasattr(bot.data[botPy.RE_DATA_POSTS][url], "removed"): if not bot.data[botPy.RE_DATA_POSTS][url]["removed"]["removed"]:
bot.data[botPy.RE_DATA_POSTS][url]["approved"]["by_human"] = approved bot.data[botPy.RE_DATA_POSTS][url]["approved"]["by_human"] = approved
return True return True
@@ -160,12 +166,11 @@ def remove_post(bot: botPy.Bot, url: str, removed_by: str = "UNKNOWN", reason: s
weekly = bot.data[botPy.RE_DATA_POSTS] weekly = bot.data[botPy.RE_DATA_POSTS]
if url in weekly: if url in weekly:
weekly[url] = { rm = weekly[url]["removed"]
"removed": True, rm["removed"] = True
"removed_by": removed_by, rm["by"] = removed_by
"remove_reason": reason, rm["reason"] = reason
"post_data": { "date_unix": weekly[url]["post_data"]["date_unix"] } weekly[url]["removed"] = rm
}
return True return True
else: else:
return False return False
+7 -5
View File
@@ -46,7 +46,7 @@ async def parse_json(response: str, bot: botPy.Bot):
try: try:
json_response = json.loads(json_str) json_response = json.loads(json_str)
if json_response["value"] not in ["respond_mentions"] or bot.args["dev"]: if json_response["value"] not in ["respond_mentions"] or bot.args["dev"]:
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() await ws_global.ping()
@@ -86,13 +86,15 @@ async def json_to_func(v: dict, bot: botPy.Bot) -> dict:
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"]
if not value_supported: if not value_supported:
val = v["value"] val = v["value"]
py_print(f"Value \"{val}\" is not supported") py_print(f"Value \"{val}\" is not supported")
return {"type": "result", "value": False} return result_json(False, print_result)
return result_json(r) return result_json(r, print_result)
def result_json(bool: bool) -> dict: def result_json(bool: bool, print_result: bool) -> dict:
return {"type": "result", "value": bool} return {"type": "result", "value": bool, "print": print_result}
+13 -15
View File
@@ -2,8 +2,9 @@ use serde_json::json;
use crate::data::get_mutex_data; use crate::data::get_mutex_data;
use crate::messages::send_msg; use crate::messages::send_msg;
use crate::{data, websocket, Context, Error, CFG_DATA_RE}; use crate::re_cmds::get::get_post_from_data;
use crate::re_cmds::generic_fns::{get_readable_subreddits, is_bk_mod, to_shorturl}; use crate::{data, websocket::send_cmd_json, Context, Error, CFG_DATA_RE};
use crate::re_cmds::generic_fns::{get_readable_subreddits, is_bk_mod, send_embed_for_post, to_shorturl};
use crate::lang; use crate::lang;
#[poise::command( #[poise::command(
@@ -34,7 +35,7 @@ pub async fn cmd(
if let Some(bk_week) = reddit_data.get(CFG_DATA_RE) { if let Some(bk_week) = reddit_data.get(CFG_DATA_RE) {
let a = approve.unwrap_or(false); let a = approve.unwrap_or(false);
let r = websocket::send_cmd_json("add_post_url", Some(json!([&shorturl, a, true]))).await.unwrap(); let r = send_cmd_json("add_post_url", Some(json!([&shorturl, a, true])), true).await.unwrap();
if !r["value"].as_bool().unwrap() { if !r["value"].as_bool().unwrap() {
send_msg( send_msg(
@@ -49,20 +50,17 @@ pub async fn cmd(
} }
if let Some(post) = bk_week.get(shorturl) { if let Some(post) = bk_week.get(shorturl) {
if post.get("removed").is_some() { if post["removed"]["removed"].as_bool().unwrap()
send_msg(ctx, lang!("dc_msg_re_post_unremove_success", url), true, true).await; { send_msg(ctx, lang!("dc_msg_re_post_unremove_success", &shorturl), true, true).await; }
} else { send_msg(ctx, lang!("dc_msg_re_post_update_success", &shorturl), true, true).await; }
else {
send_msg(ctx, lang!("dc_msg_re_post_update_success", url), true, true).await;
}
}
else {
send_msg(ctx, lang!("dc_msg_re_post_add_success", &shorturl), true, true).await;
} }
else { send_msg(ctx, lang!("dc_msg_re_post_add_success", &shorturl), true, true).await; }
if a { if a { send_msg(ctx, lang!("dc_msg_re_also_approved"), true, true).await; }
send_msg(ctx, lang!("dc_msg_re_also_approved"), true, true).await; }
}
if let Some(post) = get_post_from_data(ctx, &reddit_data, &url).await? {
send_embed_for_post(ctx, post, &url).await?;
} }
return Ok(()); return Ok(());
+1 -1
View File
@@ -40,7 +40,7 @@ async fn approve_cmd(ctx: Context<'_>, url: &str, reddit_data: &Value, approve:
return; return;
} }
let r = websocket::send_cmd_json("set_approve_post", Some(json!([approve, &url]))).await.unwrap(); let r = websocket::send_cmd_json("set_approve_post", Some(json!([approve, &url])), true).await.unwrap();
if r.get("value").is_some() { if r.get("value").is_some() {
if approve { if approve {
send_msg(ctx, lang!("dc_msg_re_post_approve_success"), true, true).await; send_msg(ctx, lang!("dc_msg_re_post_approve_success"), true, true).await;
+1 -1
View File
@@ -36,7 +36,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_mutex_data(&ctx.data().cfg).await?;
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/");
+2 -2
View File
@@ -29,10 +29,10 @@ pub async fn cmd(
} }
async fn get_post_from_data(ctx: Context<'_>, reddit_data: &Value, url: &str) -> Result<Option<Value>, Error> { pub async fn get_post_from_data(ctx: Context<'_>, reddit_data: &Value, url: &str) -> Result<Option<Value>, Error> {
if let Some(bk_week) = reddit_data.get(CFG_DATA_RE) { if let Some(bk_week) = reddit_data.get(CFG_DATA_RE) {
if let Some(post) = bk_week.get(url) { if let Some(post) = bk_week.get(url) {
if post.get("removed").is_some() { if post["removed"]["removed"].as_bool().unwrap() {
send_embed_for_removed(ctx, url, post).await; send_embed_for_removed(ctx, url, post).await;
return Ok(None); return Ok(None);
} }
+12 -3
View File
@@ -1,6 +1,6 @@
use serde_json::json; use serde_json::json;
use crate::{lang, messages::send_msg, re_cmds::generic_fns::{get_readable_subreddits, is_bk_mod}, websocket::send_cmd_json, Context, Error}; use crate::{data::{self, get_mutex_data}, lang, messages::send_msg, re_cmds::{generic_fns::{get_readable_subreddits, is_bk_mod, send_embed_for_removed}, get::get_post_from_data}, websocket::send_cmd_json, Context, Error};
#[poise::command( #[poise::command(
slash_command, slash_command,
@@ -23,12 +23,12 @@ pub async fn cmd(
} }
let auth = &ctx.author().name; let auth = &ctx.author().name;
let r = send_cmd_json("remove_post_url", Some(json!([&url, &auth, &reason]))).await.unwrap(); let r = send_cmd_json("remove_post_url", Some(json!([&url, &auth, &reason])), true).await.unwrap();
if r["value"].as_bool().unwrap() { if r["value"].as_bool().unwrap() {
send_msg( send_msg(
ctx, ctx,
lang!("dc_msg_re_post_remove_success"), lang!("dc_msg_re_post_remove_success", &url),
true, true,
true true
).await; ).await;
@@ -37,5 +37,14 @@ pub async fn cmd(
send_msg(ctx, lang!("dc_msg_re_post_404"), false, false).await; send_msg(ctx, lang!("dc_msg_re_post_404"), false, false).await;
} }
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? {
if post["removed"]["removed"].as_bool().unwrap() {
send_embed_for_removed(ctx, &url, &post).await;
}
}
return Ok(()); return Ok(());
} }
+4 -4
View File
@@ -3,7 +3,7 @@ use std::time::{SystemTime, UNIX_EPOCH};
use poise::{serenity_prelude::{ChannelId, EditMessage, GetMessages, Http, Message, MessageId, UserId}, ReplyHandle}; use poise::{serenity_prelude::{ChannelId, EditMessage, GetMessages, Http, Message, MessageId, UserId}, ReplyHandle};
use serde_json::{json, Map, Value}; use serde_json::{json, Map, Value};
use crate::{data::{self, get_mutex_data, DC_POSTS_CHANNEL_KEY}, lang, messages::{edit_reply, embed_from_options, http_send_embed, make_post_embed, make_removed_embed, send_msg}, websocket::send_cmd_json, Context, Error, CFG_DATA_RE}; use crate::{data::{self, get_mutex_data, DC_POSTS_CHANNEL_KEY}, lang, messages::{edit_reply, embed_from_options, http_send_embed, make_post_embed, make_removed_embed, send_msg, JSON_TEXT_END, JSON_TEXT_START}, websocket::send_cmd_json, Context, Error, CFG_DATA_RE};
#[poise::command( #[poise::command(
slash_command, slash_command,
@@ -35,7 +35,7 @@ pub async fn cmd(
let max_age_u = max_age.unwrap_or(8); let max_age_u = max_age.unwrap_or(8);
let max_age_secs = max_age_u as u64 * (60 * 60 * 24); let max_age_secs = max_age_u as u64 * (60 * 60 * 24);
send_cmd_json("add_new_posts", Some(json!([max_age_secs]))).await; send_cmd_json("add_new_posts", Some(json!([max_age_secs])), true).await;
data::update_re_data(ctx.data()).await; data::update_re_data(ctx.data()).await;
let r_data = get_mutex_data(&ctx.data().reddit_data).await?; let r_data = get_mutex_data(&ctx.data().reddit_data).await?;
@@ -80,7 +80,7 @@ pub async fn cmd(
if max_age_u > 0 { if max_age_u > 0 {
p_text = update_progress(ctx, progress.clone(), p_text.clone(), format!("\nRemoving old posts (threshold: {}d)...", max_age_u)).await; p_text = update_progress(ctx, progress.clone(), p_text.clone(), format!("\nRemoving old posts (threshold: {}d)...", max_age_u)).await;
remove_old(http, c_id, &msgs_json).await; remove_old(http, c_id, &msgs_json).await;
send_cmd_json("remove_old_posts", Some(json!([max_age_secs]))).await; send_cmd_json("remove_old_posts", Some(json!([max_age_secs])), true).await;
} }
// Removing duplicate posts // Removing duplicate posts
@@ -181,7 +181,7 @@ async fn msgs_to_json(msgs: Vec<Message>, reddit_data: &Value, max_age: u64) ->
if msg_last_len < 13 { continue; } if msg_last_len < 13 { continue; }
let msg_json_str = &msg_lines.clone().last().unwrap()[9..msg_last_len - 3]; let msg_json_str = &msg_lines.clone().last().unwrap()[JSON_TEXT_START.len()..msg_last_len - JSON_TEXT_END.len()];
let msg_json = serde_json::from_str(msg_json_str); let msg_json = serde_json::from_str(msg_json_str);
if msg_json.is_err() { continue; } if msg_json.is_err() { continue; }
+1 -1
View File
@@ -47,7 +47,7 @@ pub async fn cmd(
return Ok(()); return Ok(());
} }
let r = send_cmd_json("set_vote_post", Some(json!([url, uid, is_mod, true, unw_vote]))).await.unwrap(); let r = send_cmd_json("set_vote_post", Some(json!([url, uid, is_mod, true, unw_vote])), true).await.unwrap();
let unw_r = r["value"].as_bool().unwrap(); let unw_r = r["value"].as_bool().unwrap();
if unw_r && !unw_vote && is_mod { if unw_r && !unw_vote && is_mod {
+7 -2
View File
@@ -47,7 +47,7 @@ pub async fn send_msg(msg: &str) {
#[allow(static_mut_refs)] #[allow(static_mut_refs)]
pub async fn send_cmd_json(func_name: &str, func_args: Option<Value>) -> Option<Value> { pub async fn send_cmd_json(func_name: &str, func_args: Option<Value>, print_output: bool) -> Option<Value> {
unsafe { unsafe {
let Some(sender) = &GLOBAL_SENDER else { return None }; let Some(sender) = &GLOBAL_SENDER else { return None };
let mut sender = sender.lock().await; let mut sender = sender.lock().await;
@@ -56,7 +56,7 @@ pub async fn send_cmd_json(func_name: &str, func_args: Option<Value>) -> Option<
let unw_args = func_args.unwrap_or(json!([])); let unw_args = func_args.unwrap_or(json!([]));
let json_str = format!( let json_str = format!(
"json:{{\"type\": \"function\", \"value\":\"{}\", \"args\": {}}}", "json:{{\"type\": \"function\", \"value\":\"{}\", \"args\": {}, \"print\": {print_output}}}",
func_name, unw_args func_name, unw_args
); );
@@ -65,6 +65,11 @@ pub async fn send_cmd_json(func_name: &str, func_args: Option<Value>) -> Option<
} }
let r = receive_response().await; let r = receive_response().await;
if let Some(rs) = r.clone() {
if !rs.get("print").unwrap_or(&json![false]).as_bool().unwrap()
{ return r; }
}
if !["respond_mentions"].contains(&func_name) || <Args as clap::Parser>::parse().dev { if !["respond_mentions"].contains(&func_name) || <Args as clap::Parser>::parse().dev {
rs_println!("Received from Python: [RESPONSE] {:?}", r); rs_println!("Received from Python: [RESPONSE] {:?}", r);
} }