diff --git a/TODO.md b/TODO.md index 52f5c8f..6609c7c 100644 --- a/TODO.md +++ b/TODO.md @@ -17,13 +17,12 @@ - [x] ~~Function~~ - [ ] Automate - [ ] Automatically approve posts that dont get caught by reverse image search (ris) - - [ ] Log all posts in a Discord thread + - - [ ] Add post if it exists in data but not in channel - - [ ] Edit post if it exists in channel and is different in data - - [ ] Remove post if its `"removed": true` in data - - [ ] Add posts to data from channel - - [ ] `/bk_week_update` to forcefully trigger this ^ + + + + ### Medium priority: diff --git a/src/bk_week_cmds.rs b/src/bk_week_cmds.rs index 49110e2..7f88cf7 100644 --- a/src/bk_week_cmds.rs +++ b/src/bk_week_cmds.rs @@ -1,11 +1,11 @@ use crate::websocket::send_cmd_json; -use crate::{messages, rs_println, websocket, Context, Error, BK_WEEK}; -use crate::messages::{edit_msg, send_embed, send_msg}; +use crate::{rs_println, websocket, Context, Error, BK_WEEK}; +use crate::messages::{edit_msg, embed_from_options, embed_post, embed_post_removed, send_embed, send_msg}; use crate::data::{self, dc_bind_bk}; use std::fs; -use poise::serenity_prelude::{ChannelId, GetMessages, Message}; +use poise::serenity_prelude::{ChannelId, EditMessage, GetMessages, Message, MessageId}; use poise::ReplyHandle; use serde_json::{json, Value}; @@ -97,7 +97,7 @@ async fn get_post_from_data(ctx: Context<'_>, reddit_data: &Value, url: &str) -> async fn send_embed_for_post(ctx: Context<'_>, post: Value, url: &str) -> Result<(), Error> { - send_embed(ctx, messages::embed_post(&post, url, true), true).await; + send_embed(ctx, embed_post(&post, url, true), true).await; Ok(()) } @@ -352,10 +352,12 @@ pub async fn bk_week_update( { continue; } if msgs_json["duplicates"].as_object().unwrap().contains_key(url) { continue; } - if weekly_art[url].get("removed").is_some() { continue; } + if weekly_art[url].get("removed").is_some() { + send_embed(ctx, embed_post_removed(&weekly_art[url], url, false), false).await; + continue; + } - send_embed(ctx, messages::embed_post(&weekly_art[url], url, false), false).await; - break; + send_embed(ctx, embed_post(&weekly_art[url], url, false), false).await; } if only_add.unwrap_or_else(|| false) { @@ -364,13 +366,30 @@ pub async fn bk_week_update( } p_text = update_progress(ctx, progress.clone().unwrap(), p_text.clone(), "✅\nEditing updated posts...".to_string()).await; - // TODO: edit outdated posts + for (url, msg_id) in msgs_json["updated"].as_object().unwrap() { + let mut msg = ctx.http().get_message(ctx.channel_id(), MessageId::new(msg_id.as_u64().unwrap())).await.unwrap(); + let r = EditMessage::new() + .embeds(vec![embed_from_options(embed_post(&weekly_art[url], url, false))]); + + let _ = msg.edit(ctx, r).await; + } p_text = update_progress(ctx, progress.clone().unwrap(), p_text.clone(), "✅\nRemoving removed posts...".to_string()).await; - // TODO: remove removed posts + for (url, msg_id) in msgs_json["removed"].as_object().unwrap() { + let mut msg = ctx.http().get_message(ctx.channel_id(), MessageId::new(msg_id.as_u64().unwrap())).await.unwrap(); + let r = EditMessage::new() + .embeds(vec![embed_from_options(embed_post_removed(&weekly_art[url], url, false))]); + + let _ = msg.edit(ctx, r).await; + } p_text = update_progress(ctx, progress.clone().unwrap(), p_text.clone(), "✅\nRemoving duplicate posts...".to_string()).await; - // TODO: remove duplicates + for (_url, msgs) in msgs_json["duplicates"].as_object().unwrap() { + for msg_id in msgs.as_array().unwrap() { + let msg = ctx.http().get_message(ctx.channel_id(), MessageId::new(msg_id.as_u64().unwrap())).await.unwrap(); + let _ = msg.delete(ctx.http()).await; + } + } update_progress(ctx, progress.clone().unwrap(), p_text.clone(), "✅\n## Done!".to_string()).await; return Ok(()); @@ -465,10 +484,17 @@ async fn msgs_to_json<'a>(msgs: Vec, reddit_data: &'a Value) -> Value { let mut u_json: Value = msg_json.unwrap(); let re_url = &reddit_data["bk_weekly_art_posts"][&url]; - if u_json.get("removed").is_some() { + if re_url.get("removed").is_some() { + if msgs_json.get("removed").is_some() { + if let Some(obj) = msgs_json["no_change"].as_object_mut() { + obj.insert(url.clone(), json!(msg.id.get())); + obj.insert(url.clone(), u_json.clone()); + continue; + } + } + if let Some(obj) = msgs_json["removed"].as_object_mut() { - if !obj.contains_key(&url) { obj.insert(url.clone(), json!([])); } - obj[&url].as_array_mut().unwrap().push(json!(msg.id.get())); + obj.insert(url.clone(), json!(msg.id.get())); continue; } } @@ -480,15 +506,13 @@ async fn msgs_to_json<'a>(msgs: Vec, reddit_data: &'a Value) -> Value { u_json.as_object_mut().unwrap().insert("msg_id".to_string(), Value::String(msg.id.clone().to_string())); if let Some(obj) = msgs_json["updated"].as_object_mut() { - if !obj.contains_key(&url) { obj.insert(url.clone(), json!([])); } - obj[&url].as_array_mut().unwrap().push(json!(msg.id.get())); + obj.insert(url.clone(), json!(msg.id.get())); continue; } } if let Some(obj) = msgs_json["no_change"].as_object_mut() { - if !obj.contains_key(&url) { obj.insert(url.clone(), json!([])); } - obj[&url].as_array_mut().unwrap().push(json!(msg.id.get())); + obj.insert(url.clone(), json!(msg.id.get())); obj.insert(url, u_json); } } diff --git a/src/cmds.rs b/src/cmds.rs index 517e57c..303b520 100644 --- a/src/cmds.rs +++ b/src/cmds.rs @@ -85,7 +85,7 @@ pub async fn embed( ctx, EmbedOptions { desc: description.replace("\\n", "\n"), - title: Some(title.unwrap().replace("\\n", "\n")), + title: if title.is_some() { Some(title.unwrap().replace("\\n", "\n")) } else { None }, col: color, url, ts: timestamp, diff --git a/src/messages.rs b/src/messages.rs index bf12381..6b1d321 100644 --- a/src/messages.rs +++ b/src/messages.rs @@ -6,11 +6,13 @@ use poise::serenity_prelude::{Color, CreateEmbed, CreateEmbedAuthor, Timestamp}; use serde_json::json; +#[derive(Clone)] pub struct Author { pub name: String, pub url: String, pub icon_url: String } +#[derive(Clone)] pub struct EmbedOptions { pub desc: String, pub title: Option, @@ -40,6 +42,7 @@ impl Default for EmbedOptions { static DEFAULT_DC_COL: u32 = 5793266; +static REMOVED_DC_COL: u32 = 16716032; fn none_to_empty(string: Option) -> String { @@ -77,20 +80,7 @@ pub async fn send_embed( reply: bool ) -> Option> { - let mut author: Option = None; - if let Some(o_author) = options.author { - author = Some(CreateEmbedAuthor::new(o_author.name).url(o_author.url).icon_url(o_author.icon_url)) - } - - let mut embed = CreateEmbed::new() - .title (none_to_empty(options.title)) - .description(options.desc) - .colour (Color::new(options.col.unwrap_or_else(|| DEFAULT_DC_COL))) - .url (none_to_empty(options.url)); - - if let Some(a) = author { embed = embed.author(a); } - if options.thumbnail.is_some() { embed = embed.thumbnail(options.thumbnail.unwrap()); } - if options.ts.is_some() { embed = embed.timestamp(options.ts.unwrap()); } + let embed = embed_from_options(options.clone()); if reply { let r = CreateReply { @@ -111,6 +101,26 @@ pub async fn send_embed( } +pub fn embed_from_options(options: EmbedOptions) -> CreateEmbed { + let mut author: Option = None; + if let Some(o_author) = options.author { + author = Some(CreateEmbedAuthor::new(o_author.name).url(o_author.url).icon_url(o_author.icon_url)) + } + + let mut embed = CreateEmbed::new() + .title (none_to_empty(options.title)) + .description(options.desc) + .colour (Color::new(options.col.unwrap_or_else(|| DEFAULT_DC_COL))) + .url (none_to_empty(options.url)); + + if let Some(a) = author { embed = embed.author(a); } + if options.thumbnail.is_some() { embed = embed.thumbnail(options.thumbnail.unwrap()); } + if options.ts.is_some() { embed = embed.timestamp(options.ts.unwrap()); } + + return embed; +} + + pub async fn edit_msg( ctx: Context<'_>, msg: ReplyHandle<'_>, @@ -168,4 +178,16 @@ pub fn embed_post(post_data: &Value, url: &str, empheral: bool) -> EmbedOptions .or_else(|| None), ..Default::default() }; +} + + +pub fn embed_post_removed(post_data: &Value, url: &str, empheral: bool) -> EmbedOptions { + return EmbedOptions { + title: Some("REMOVED!".to_string()), + desc: format!("## Removed by `{}`\nJSON: ||`{}`||", post_data["removed_by"].as_str().unwrap(), serde_json::to_string(&post_data).unwrap()), + col: Some(REMOVED_DC_COL), + url: Some(url.to_string()), + empheral, + ..Default::default() + }; } \ No newline at end of file diff --git a/src/python/data.py b/src/python/data.py index 7d655b7..39a2fef 100644 --- a/src/python/data.py +++ b/src/python/data.py @@ -104,7 +104,11 @@ def add_post_to_data(bot: botPy.Bot, new_data: PostData, bypass_conditions: bool py_print(f"Added post \"{new_data.url}\" (Conditions bypassed)") return True - if new_data.url not in bot.data[BK_WEEKLY] or new_data.upvotes != bot.data[BK_WEEKLY][new_data.url]["post_data"]: + updated = False + if "removed" not in bot.data[BK_WEEKLY][new_data.url]: + updated = new_data.upvotes != bot.data[BK_WEEKLY][new_data.url]["post_data"] + + if new_data.url not in bot.data[BK_WEEKLY] or updated: bot.data[BK_WEEKLY][new_data.url] = new_data.to_json() if bot.args["dev"]: py_print(f"Added post \"{new_data.url}\"")