From c0793562e3c6dc6b65620170df520d07950164fe Mon Sep 17 00:00:00 2001 From: ByteDice Date: Fri, 6 Jun 2025 15:37:06 +0200 Subject: [PATCH] added rest of the buttons (still needs listeners) & reformatted/improved other code --- TODO.md | 2 ++ data/lang/en.json | 6 ++-- data/re_data_preset.json | 12 ++++---- src/cmds/reload_cfg.rs | 2 +- src/cmds/stop.rs | 2 +- src/data.rs | 6 ++-- src/gen.rs | 6 ++-- src/main.rs | 12 ++++++-- src/messages.rs | 46 ++++++++++++++-------------- src/python/data.py | 61 +++++++++++++++++++++----------------- src/python/py_websocket.py | 12 ++++---- src/re_cmds/add.rs | 28 ++++++++--------- src/re_cmds/approve.rs | 2 +- src/re_cmds/generic_fns.rs | 2 +- src/re_cmds/get.rs | 4 +-- src/re_cmds/remove.rs | 15 ++++++++-- src/re_cmds/update.rs | 8 ++--- src/re_cmds/vote.rs | 2 +- src/websocket.rs | 9 ++++-- 19 files changed, 132 insertions(+), 105 deletions(-) diff --git a/TODO.md b/TODO.md index bc19d03..eda773d 100644 --- a/TODO.md +++ b/TODO.md @@ -1,5 +1,7 @@ ### High priority: - [ ] 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. - [ ] Automatically approve posts that don't get caught by reverse image search (ris) - [ ] Make buttons do stuff diff --git a/data/lang/en.json b/data/lang/en.json index e62c139..df224ae 100644 --- a/data/lang/en.json +++ b/data/lang/en.json @@ -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_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: {0}", + "dc_msg_dm_python_err": "Unknown internal Python Error: `{0}`", "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_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_failed_shorturl_conversion": "Couldn't convert to shortURL: Invalid Reddit URL format.", "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_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!", + "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_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).", diff --git a/data/re_data_preset.json b/data/re_data_preset.json index f5ec648..100d4b4 100644 --- a/data/re_data_preset.json +++ b/data/re_data_preset.json @@ -1,6 +1,11 @@ { "posts": { - "EXAMPLE VALUE": { + "EXAMPLE URL": { + "removed": { + "removed": false, + "by": null, + "reason": null + }, "post_data": { "title": "I JUST BOUGHT THE CONTINENT OF NORTH AMERICA FOR A DOLLAR!", "upvotes": 69420, @@ -21,11 +26,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/src/cmds/reload_cfg.rs b/src/cmds/reload_cfg.rs index 737fbb1..e4e5fa3 100644 --- a/src/cmds/reload_cfg.rs +++ b/src/cmds/reload_cfg.rs @@ -19,7 +19,7 @@ pub async fn cmd( read_cfg_data(&ctx.data(), false).await; let d = get_mutex_data(&ctx.data().cfg).await?; 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() { send_msg( diff --git a/src/cmds/stop.rs b/src/cmds/stop.rs index ad38001..3622602 100644 --- a/src/cmds/stop.rs +++ b/src/cmds/stop.rs @@ -26,7 +26,7 @@ pub async fn cmd( let msg = send_msg(ctx, lang!("dc_msg_owner_data_save"), true, true).await.unwrap(); data::write_dc_data(ctx.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; ctx.serenity_context().set_presence(None, OnlineStatus::Invisible); diff --git a/src/data.rs b/src/data.rs index 133243e..c23f19a 100644 --- a/src/data.rs +++ b/src/data.rs @@ -103,13 +103,13 @@ fn generate_re_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; } 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; *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; } diff --git a/src/gen.rs b/src/gen.rs index 07c6c76..df85ea8 100644 --- a/src/gen.rs +++ b/src/gen.rs @@ -100,14 +100,12 @@ async fn make_cmd_vec(data: &Data) -> Vec { re_cmds::top::cmd(), re_cmds::update::cmd(), re_cmds::vote::cmd(), - re_cmds::shorturl::cmd() + re_cmds::shorturl::cmd(), + re_cmds::admin_bind::cmd(), ]); } cmds.extend([ - // reddit admin - re_cmds::admin_bind::cmd(), - // cfg cmds::reload_cfg::cmd() ]); diff --git a/src/main.rs b/src/main.rs index 30b6bcb..a95d3b5 100644 --- a/src/main.rs +++ b/src/main.rs @@ -94,13 +94,15 @@ struct Data { static CFG_DATA_RE: &str = "posts"; -pub static mut LANG: Option = None; +pub static mut LANG: Option = None; +pub static mut NOPING: bool = false; #[tokio::main] async fn main() { let args = ::parse(); let args_str = serde_json::to_string(&args).expect("Error serializing args to JSON"); + unsafe { NOPING = args.noping; } rs_println!("Fetching language file..."); 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.nosched { println!("----- NO SCHEDULES -----"); } + // TODO: handle if config for reddit is disabled to not start python + if args.py && !args.rs { println!("----- PYTHON ONLY MODE -----"); rs_println!("ARGS: {}", args_str); @@ -174,6 +178,8 @@ async fn start(args: Args, owners: Vec) { async fn read_reddit_inbox() { - unsafe { if !websocket::HAS_CONNECTED { return; } } - send_cmd_json("respond_mentions", None).await; + unsafe { + if !websocket::HAS_CONNECTED { return; } + send_cmd_json("respond_mentions", None, !NOPING).await; + } } \ No newline at end of file diff --git a/src/messages.rs b/src/messages.rs index 278cc86..d8b3318 100644 --- a/src/messages.rs +++ b/src/messages.rs @@ -5,7 +5,6 @@ use crate::{lang, Args, Context}; use poise::serenity_prelude::json::Value; use poise::{serenity_prelude::CreateMessage, CreateReply, ReplyHandle}; use poise::serenity_prelude::{ChannelId, Color, CreateActionRow, CreateButton, CreateEmbed, CreateEmbedAuthor, EditMessage, Http, Message, ReactionType, Timestamp, UserId}; -use serde_json::json; #[derive(Clone)] @@ -48,6 +47,9 @@ impl Default for EmbedOptions { static DEFAULT_DC_COL: u32 = 5793266; 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 { return string.unwrap_or_default(); @@ -226,25 +228,19 @@ pub fn make_post_embed(post_data: &Value, url: &str, ephemeral: bool) -> EmbedOp .collect::>() .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 action_row = CreateActionRow::Buttons(vec![ - CreateButton::new("upvote_btn") .label("Upvote") .emoji(ReactionType::Unicode("⬆️".to_string())), - CreateButton::new("unupvote_btn") .label("Un-upvote"), - CreateButton::new("approve_btn") .label("Approve") .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("vote_btn") .label("Vote") .emoji(ReactionType::Unicode("⬆️".to_string())), + CreateButton::new("unvote_btn") .label("Un-vote"), + CreateButton::new("approve_btn") .label("Approve") .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())) ]); return EmbedOptions { 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), url: Some(url.to_string()), 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 { + 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 { - title: Some("REMOVED!".to_string()), - desc: lang!( - "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() - ), + title: Some(format!("[REMOVED] {}", post_data["post_data"]["title"])), + desc: format!("{}\n\n{}{}{}", desc, JSON_TEXT_START, serde_json::to_string(&post_data).unwrap(), JSON_TEXT_END), col: Some(REMOVED_DC_COL), url: Some(url.to_string()), ts: Some(Timestamp::from_unix_timestamp(post_data["post_data"]["date_unix"].as_i64().unwrap()).unwrap()), ephemeral, + actionrows: Some(vec![action_row]), ..Default::default() }; } \ No newline at end of file diff --git a/src/python/data.py b/src/python/data.py index 794b3c3..5d4a4fd 100644 --- a/src/python/data.py +++ b/src/python/data.py @@ -18,14 +18,20 @@ class PostData: date_unix: int, media_type: str, media_urls: list[str], - voters_re: list[str] = [], - voters_dc: list[int] = [], - mod_voters: list[int] = [], - added_by_human: bool = False, - added_by_bot: bool = False, - approved_by_human: bool = False, - approved_by_ris: bool = False + removed: bool = False, + removed_by: str | None = None, + removed_reason: str | None = None, + voters_re: list[str] = [], + voters_dc: list[int] = [], + mod_voters: list[int] = [], + 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.title = title self.upvotes = upvotes @@ -42,6 +48,11 @@ class PostData: def to_json(self): return { + "removed": { + "removed": self.removed, + "by": self.removed_reason, + "reason": self.removed_reason + }, "post_data": { "title": self.title, "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: + if new_data.removed: + new_data.removed = False + new_data.removed_by = None + new_data.removed_reason = None + if bypass_conditions: bot.data[botPy.RE_DATA_POSTS][new_data.url] = new_data.to_json() - if bot.args["dev"]: - py_print(f"Added post \"{new_data.url}\" (Conditions bypassed)") + if bot.args["dev"]: py_print(f"Added post \"{new_data.url}\" (Conditions bypassed)") return True - # not sure what this is for - updated = False - - if new_data.url not in bot.data[botPy.RE_DATA_POSTS] or updated: + if new_data.url not in bot.data[botPy.RE_DATA_POSTS]: bot.data[botPy.RE_DATA_POSTS][new_data.url] = new_data.to_json() - if bot.args["dev"]: - py_print(f"Added post \"{new_data.url}\"") + if bot.args["dev"]: py_print(f"Added post \"{new_data.url}\"") 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: - py_print(f"Failed to add post \"{new_data.url}\": Removed flag is True.") - return False + return False 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 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] if url in weekly: - weekly[url] = { - "removed": True, - "removed_by": removed_by, - "remove_reason": reason, - "post_data": { "date_unix": weekly[url]["post_data"]["date_unix"] } - } + rm = weekly[url]["removed"] + rm["removed"] = True + rm["by"] = removed_by + rm["reason"] = reason + weekly[url]["removed"] = rm return True else: return False diff --git a/src/python/py_websocket.py b/src/python/py_websocket.py index 2111ccf..08279dd 100644 --- a/src/python/py_websocket.py +++ b/src/python/py_websocket.py @@ -46,7 +46,7 @@ async def parse_json(response: str, bot: botPy.Bot): try: json_response = json.loads(json_str) 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) 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 _: value_supported = False + print_result = v["print"] + if not value_supported: val = v["value"] 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: - return {"type": "result", "value": bool} \ No newline at end of file +def result_json(bool: bool, print_result: bool) -> dict: + return {"type": "result", "value": bool, "print": print_result} \ No newline at end of file diff --git a/src/re_cmds/add.rs b/src/re_cmds/add.rs index 06e8813..570ac95 100644 --- a/src/re_cmds/add.rs +++ b/src/re_cmds/add.rs @@ -2,8 +2,9 @@ use serde_json::json; use crate::data::get_mutex_data; use crate::messages::send_msg; -use crate::{data, websocket, Context, Error, CFG_DATA_RE}; -use crate::re_cmds::generic_fns::{get_readable_subreddits, is_bk_mod, to_shorturl}; +use crate::re_cmds::get::get_post_from_data; +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; #[poise::command( @@ -34,7 +35,7 @@ pub async fn cmd( if let Some(bk_week) = reddit_data.get(CFG_DATA_RE) { 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() { send_msg( @@ -49,20 +50,17 @@ pub async fn cmd( } if let Some(post) = bk_week.get(shorturl) { - if post.get("removed").is_some() { - send_msg(ctx, lang!("dc_msg_re_post_unremove_success", url), 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; + if post["removed"]["removed"].as_bool().unwrap() + { 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_add_success", &shorturl), true, true).await; } - if a { - send_msg(ctx, lang!("dc_msg_re_also_approved"), true, true).await; - } + if a { 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(()); diff --git a/src/re_cmds/approve.rs b/src/re_cmds/approve.rs index 115be82..6901ca0 100644 --- a/src/re_cmds/approve.rs +++ b/src/re_cmds/approve.rs @@ -40,7 +40,7 @@ async fn approve_cmd(ctx: Context<'_>, url: &str, reddit_data: &Value, approve: 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 approve { send_msg(ctx, lang!("dc_msg_re_post_approve_success"), true, true).await; diff --git a/src/re_cmds/generic_fns.rs b/src/re_cmds/generic_fns.rs index 4c3cbab..1b0eed0 100644 --- a/src/re_cmds/generic_fns.rs +++ b/src/re_cmds/generic_fns.rs @@ -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 { 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 join = split.join(", r/"); diff --git a/src/re_cmds/get.rs b/src/re_cmds/get.rs index 5292461..ad5a869 100644 --- a/src/re_cmds/get.rs +++ b/src/re_cmds/get.rs @@ -29,10 +29,10 @@ pub async fn cmd( } -async fn get_post_from_data(ctx: Context<'_>, reddit_data: &Value, url: &str) -> Result, Error> { +pub async fn get_post_from_data(ctx: Context<'_>, reddit_data: &Value, url: &str) -> Result, Error> { if let Some(bk_week) = reddit_data.get(CFG_DATA_RE) { 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; return Ok(None); } diff --git a/src/re_cmds/remove.rs b/src/re_cmds/remove.rs index d08a785..0755f8e 100644 --- a/src/re_cmds/remove.rs +++ b/src/re_cmds/remove.rs @@ -1,6 +1,6 @@ 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( slash_command, @@ -23,12 +23,12 @@ pub async fn cmd( } 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() { send_msg( ctx, - lang!("dc_msg_re_post_remove_success"), + lang!("dc_msg_re_post_remove_success", &url), true, true ).await; @@ -37,5 +37,14 @@ pub async fn cmd( 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(()); } \ No newline at end of file diff --git a/src/re_cmds/update.rs b/src/re_cmds/update.rs index 1db5a61..a2586db 100644 --- a/src/re_cmds/update.rs +++ b/src/re_cmds/update.rs @@ -3,7 +3,7 @@ use std::time::{SystemTime, UNIX_EPOCH}; use poise::{serenity_prelude::{ChannelId, EditMessage, GetMessages, Http, Message, MessageId, UserId}, ReplyHandle}; 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( slash_command, @@ -35,7 +35,7 @@ pub async fn cmd( let max_age_u = max_age.unwrap_or(8); 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; let r_data = get_mutex_data(&ctx.data().reddit_data).await?; @@ -80,7 +80,7 @@ pub async fn cmd( 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; 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 @@ -181,7 +181,7 @@ async fn msgs_to_json(msgs: Vec, reddit_data: &Value, max_age: u64) -> 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); if msg_json.is_err() { continue; } diff --git a/src/re_cmds/vote.rs b/src/re_cmds/vote.rs index f6549e4..0e2e168 100644 --- a/src/re_cmds/vote.rs +++ b/src/re_cmds/vote.rs @@ -47,7 +47,7 @@ pub async fn cmd( 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(); if unw_r && !unw_vote && is_mod { diff --git a/src/websocket.rs b/src/websocket.rs index 834acba..764d5c9 100644 --- a/src/websocket.rs +++ b/src/websocket.rs @@ -47,7 +47,7 @@ pub async fn send_msg(msg: &str) { #[allow(static_mut_refs)] -pub async fn send_cmd_json(func_name: &str, func_args: Option) -> Option { +pub async fn send_cmd_json(func_name: &str, func_args: Option, print_output: bool) -> Option { unsafe { let Some(sender) = &GLOBAL_SENDER else { return None }; let mut sender = sender.lock().await; @@ -56,7 +56,7 @@ pub async fn send_cmd_json(func_name: &str, func_args: Option) -> Option< let unw_args = func_args.unwrap_or(json!([])); let json_str = format!( - "json:{{\"type\": \"function\", \"value\":\"{}\", \"args\": {}}}", + "json:{{\"type\": \"function\", \"value\":\"{}\", \"args\": {}, \"print\": {print_output}}}", func_name, unw_args ); @@ -65,6 +65,11 @@ pub async fn send_cmd_json(func_name: &str, func_args: Option) -> Option< } 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) || ::parse().dev { rs_println!("Received from Python: [RESPONSE] {:?}", r); }