added voting system, bug fixes, and a ton more

This commit is contained in:
2025-02-17 22:48:03 +01:00
parent 896a455d6c
commit 7fc23896cb
11 changed files with 262 additions and 86 deletions
+8 -6
View File
@@ -5,11 +5,13 @@
<!-- - [x] ~~Scrape the data~~ -->
<!-- - [x] ~~Put it in a JSON~~ -->
<!-- - [x] ~~Multithread so it can run both Discord and Reddit bot!!!~~ -->¨
- [ ] Security that only allows bk mods to run these commands
<!-- - [x] Security that only allows bk mods to run these commands. -->
<!-- - [x] Some kind of voting system. -->
- [ ] Allow updating the data autonomously and via manual commands.
- [ ] 30-minute schedule
- [ ] 30-minute schedule when bot adds posts
- [ ] Manually add posts
- [ ] via `u/[bot] add`
- [ ] 5 minute schedule when user adds post
<!-- - [x] ~~via `/bk_week_add [url]`~~ -->
<!-- - [x] ~~Manually remove posts via `/bk_week_remove [url]`~~ -->
<!-- - [x] ~~Manually approve posts via `/bk_week_approve [url]`~~ -->
@@ -18,7 +20,7 @@
- [ ] Automatically remove posts older than 7 days from JSON
- [x] ~~Function~~
- [ ] Automate
- [ ] Automatically approve posts that dont get caught by reverse image search (ris)
- [ ] Automatically approve posts that don't get caught by reverse image search (ris)
<!-- - [x] Log all posts in a Discord thread -->
<!-- - [x] ~~`/bk_week_bind` to bind a channel for bk_week logs~~ -->
<!-- - [x] Add post if it exists in data but not in channel -->
@@ -29,9 +31,9 @@
### Medium priority:
<!-- - [x] ~~JSON -> Rules list~~ -->
- [ ] View single rule (/rule {rulename})
- [ ] View single rule (/rule {rule_name})
- [ ] Postfix calculator
- [ ] Postfic generator
- [ ] Postfix generator
- [ ] JSON -> BPS class init
- [ ] BPS args -> JSON
- [ ] Random tip (from ByteDice.net/data/loadingScreenTips.json)
@@ -44,7 +46,7 @@
- [ ] Weekly coding competition
* Same as particle of the week but with coding
- [ ] Content update sender
* Automatically sends sneek peeks (like commit history or manual) of projects when theyre updated
* Automatically sends sneak peeks (like commit history or manual) of projects when they're updated
- [ ] Language TLDR command
* Shows a TLDR with pros/cons on a programming language
- [ ] PowerPlate info viewer
+9 -7
View File
@@ -1,16 +1,18 @@
# Discord Commands
## `/bk_week_add [url] [approve]`
## `/bk_week_add [url] <approve>`
Adds a URL to the list of posts. This is done automatically by the bot for certain posts.
- **`[approve]`**: `true` or `false`, determines whether to pre-approve the post.
- **`<approve>`**: (OPTIONAL) `true` or `false`, determines whether to pre-approve the post.
## `/bk_week_remove [url]`
Removes an existing URL from the list of posts.
## `/bk_week_approve [url]`
## `/bk_week_approve [url] <disapprove>`
Flags the post as **human_approved**, confirming that the artwork is original.
## `/bk_week_disapprove [url]`
Reverses the effect of `/bk_week_approve`.
- **`<disapprove>`**: (OPTIONAL) `true` or `false`, set to `true` if you want to undo an approval.
## `/bk_week_update`
Updates all data in the binded Discord channel. It's reccommended to run this rarely.
## `/bk_week_bind`
Updates all data in the bound Discord channel. It's recommended to run this rarely.
## `/bk_week_vote [url] <remove_vote>`
Adds a vote to a post. The intended use for votes is for a "moderator picks" and a "community picks" section of the weekly art.
You can vote on as many posts as you want, but only once per post.
## `/bk_admin_bind`
Binds the current channel as the channel where the bk_week data is sent and updated in. No binding means the only way to view the data is using `/bk_week_get`.
### **Examples**
```
+3
View File
@@ -4,6 +4,9 @@ To execute a command on the Reddit bot, include `u/ByteDiceAssistant [args]` in
## `bk_week_add`
Adds the post to the list of posts.
- **Only moderators of a subreddit or the OP (Original Poster) can use this command.**
## `bk_week_vote`
Adds a vote to the post. (see `/bk_week_vote` in the Discord help).
- **Anyone can use this command.**
### **Examples**
```
"u/ByteDiceAssistant bk_week_add"
+29
View File
@@ -0,0 +1,29 @@
{
"bk1": {
"discord": [
697149665166229614,
526842473062989864,
1171015493537247273,
1156779840956010496,
1021944396473716847,
1085622021024653362,
1223480842525872148,
1155349278655520858
],
"reddit": [
]
},
"bk2": {
"discord": [
1004132854227292272,
1031352334745354282,
1173039143245332520,
1281040971710201857,
772049174672703528
],
"reddit": [
]
}
}
+7 -3
View File
@@ -1,5 +1,4 @@
{
"file_created_correctly": true,
"bk_weekly_art_posts": {
"EXAMPLE VALUE": {
"post_data": {
@@ -9,7 +8,11 @@
"media_type": null,
"media_urls": []
},
"nominated_by_human": true,
"votes": {
"voters_re": ["bytedice"],
"voters_dc": [0],
"mod_voters": [0]
},
"added": {
"by_human": false,
"by_bot": true
@@ -21,7 +24,8 @@
},
"EXAMPLE VALUE DELETED": {
"removed": true,
"removed_by": "ME!!!!"
"removed_by": "ME!!!!",
"remove_reason": "i HATED that post >:("
}
}
}
+109 -36
View File
@@ -17,6 +17,20 @@ enum HelpOptions {
}
fn is_bk_mod(mod_list: Value, uid: u64) -> bool {
let obj = mod_list.as_object().unwrap();
let bk1_arr = obj["bk1"]["discord"].as_array().unwrap();
let bk2_arr = obj["bk2"]["discord"].as_array().unwrap();
return bk1_arr.contains(&json!(uid)) || bk2_arr.contains(&json!(uid));
}
async fn not_bk_mod_msg(ctx: Context<'_>) {
send_msg(ctx, "Permission denied: You are not a moderator of r/boykisser or r/boykisser2".to_string(), true, true).await;
}
#[poise::command(
slash_command,
prefix_command
@@ -48,11 +62,11 @@ pub async fn bk_week_help(
#[poise::command(slash_command, prefix_command, guild_only)]
#[poise::command(slash_command, prefix_command)]
/// Retrieves the data of a single post just for you. The data has to be within the database to work.
pub async fn bk_week_get(
ctx: Context<'_>,
#[description = "The post URL"] url: String
#[description = "The post URL."] url: String
) -> Result<(), Error>
{
data::update_re_data(ctx.data()).await;
@@ -68,10 +82,10 @@ pub async fn bk_week_get(
async fn get_reddit_data(ctx: Context<'_>) -> Result<Value, Error> {
let data_lock = ctx.data().reddit_data.lock().await;
match data_lock.as_ref() {
return match data_lock.as_ref() {
Some(data) => Ok(data.clone()),
None => Err("Reddit data is corrupted".into()),
}
};
}
@@ -146,14 +160,19 @@ async fn send_data_corrupted_message(ctx: Context<'_>, url: &str) {
#[poise::command(slash_command, prefix_command, guild_only)]
#[poise::command(slash_command, prefix_command)]
/// Fetches a post from Reddit and adds it to the database.
pub async fn bk_week_add(
ctx: Context<'_>,
#[description = "The post URL"] url: String,
#[description = "The post URL."] url: String,
#[description = "Wether to approve it after adding it"] approve: Option<bool>
) -> Result<(), Error>
{
if !is_bk_mod(ctx.data().bk_mods_json.clone(), ctx.author().id.get()) {
not_bk_mod_msg(ctx).await;
return Ok(());
}
data::update_re_data(ctx.data()).await;
let reddit_data = get_reddit_data(ctx).await.unwrap();
@@ -206,15 +225,21 @@ async fn send_updated_msg(ctx: Context<'_>, url: &str) {
#[poise::command(slash_command, prefix_command, guild_only)]
#[poise::command(slash_command, prefix_command)]
/// Removes a post from the database. It will show who last removed it.
pub async fn bk_week_remove(
ctx: Context<'_>,
#[description = "The post URL"] url: String
#[description = "The post URL."] url: String,
#[description = "The reason of the removal."] reason: Option<String>
) -> Result<(), Error>
{
if !is_bk_mod(ctx.data().bk_mods_json.clone(), ctx.author().id.get()) {
not_bk_mod_msg(ctx).await;
return Ok(());
}
let auth = &ctx.author().name;
let r = send_cmd_json("remove_post_url", json!([&url, &auth])).await.unwrap();
let r = send_cmd_json("remove_post_url", json!([&url, &auth, &reason])).await.unwrap();
if r["value"].as_bool().unwrap() {
send_msg(
@@ -234,17 +259,23 @@ pub async fn bk_week_remove(
#[poise::command(slash_command, prefix_command, guild_only)]
#[poise::command(slash_command, prefix_command)]
/// Approves a post in the database. Approving posts tells the bot that it's original.
pub async fn bk_week_approve(
ctx: Context<'_>,
#[description = "The post URL"] url: String
#[description = "The post URL."] url: String,
#[description = "Wether to approve or disapprove the post"] disapprove: Option<bool>
) -> Result<(), Error>
{
if !is_bk_mod(ctx.data().bk_mods_json.clone(), ctx.author().id.get()) {
not_bk_mod_msg(ctx).await;
return Ok(());
}
data::update_re_data(ctx.data()).await;
let reddit_data = get_reddit_data(ctx).await.unwrap();
approve_cmd(ctx, &url, &reddit_data, true).await;
approve_cmd(ctx, &url, &reddit_data, !disapprove.unwrap_or_else(|| false)).await;
return Ok(());
}
@@ -277,27 +308,9 @@ async fn approve_cmd(ctx: Context<'_>, url: &str, reddit_data: &Value, approve:
#[poise::command(slash_command, prefix_command, guild_only)]
/// Opposite effects of `/bk_week_approve`.
pub async fn bk_week_disapprove(
ctx: Context<'_>,
#[description = "The post URL"] url: String
) -> Result<(), Error>
{
data::update_re_data(ctx.data()).await;
let reddit_data = get_reddit_data(ctx).await.unwrap();
approve_cmd(ctx, &url, &reddit_data, false).await;
return Ok(());
}
#[poise::command(slash_command, prefix_command, default_member_permissions = "ADMINISTRATOR", guild_only)]
/// Sets the channel where the bot will dump all log info. It's recommended to only run this once.
pub async fn bk_week_bind(
pub async fn bk_admin_bind(
ctx: Context<'_>
) -> Result<(), Error>
{
@@ -333,23 +346,23 @@ pub async fn bk_week_update(
let progress = send_msg(ctx, p_text.clone(), true, true).await;
send_cmd_json("add_new_posts", json!([])).await;
data::update_re_data(ctx.data()).await;
let r_data = get_reddit_data(ctx).await.unwrap();
let c_id = get_c_id(ctx).await.unwrap_or_else(|| 0);
p_text = update_progress(ctx, progress.clone().unwrap(), p_text.clone(), format!("\nReading messages in <#{}>...", c_id)).await;
if c_id == 0 {
send_msg(ctx, "Could not find bk_week_channel in data!\nHint: Run `/bk_week_bind` in a (preferably read-only) channel.".to_string(), true, true).await;
send_msg(ctx, "Could not find bk_week_channel in data!\nHint: Run (or tell an admin to run) `/bk_admin_bind` in a (preferably read-only) channel.".to_string(), true, true).await;
return Ok(());
}
p_text = update_progress(ctx, progress.clone().unwrap(), p_text.clone(), format!("\nReading messages in <#{}>...", c_id)).await;
let msgs = read_msgs(ctx, c_id).await;
p_text = update_progress(ctx, progress.clone().unwrap(), p_text.clone(), "\nParsing messages to JSON...".to_string()).await;
let msgs_json = msgs_to_json(msgs, &r_data).await;
p_text = update_progress(ctx, progress.clone().unwrap(), p_text.clone(), "\nAdding new posts...".to_string()).await;
let weekly_art = r_data["bk_weekly_art_posts"].as_object().unwrap();
for url in weekly_art.keys() {
@@ -399,6 +412,7 @@ pub async fn bk_week_update(
}
update_progress(ctx, progress.clone().unwrap(), p_text.clone(), "\n## Done!".to_string()).await;
return Ok(());
}
@@ -458,6 +472,8 @@ async fn read_msgs(ctx: Context<'_>, c_id: u64) -> Vec<Message> {
}
// TODO: all posts get updated for some reason (i think, debug print pls)
// TODO: also doesn't edit messages if they got removed
async fn msgs_to_json<'a>(msgs: Vec<Message>, reddit_data: &'a Value) -> Value {
let mut msgs_json: Value = json!({"no_change": {}, "updated": {}, "removed": {}, "duplicates": {}});
@@ -506,9 +522,10 @@ async fn msgs_to_json<'a>(msgs: Vec<Message>, reddit_data: &'a Value) -> Value {
}
}
if u_json["added"] != re_url["added"]
|| u_json["approved"] != re_url["approved"]
if u_json["added"] != re_url["added"]
|| u_json["approved"] != re_url["approved"]
|| u_json["post_data"]["upvotes"] != re_url["post_data"]["upvotes"]
|| u_json["votes"] != re_url["votes"]
{
u_json.as_object_mut().unwrap().insert("msg_id".to_string(), Value::String(msg.id.clone().to_string()));
@@ -525,4 +542,60 @@ async fn msgs_to_json<'a>(msgs: Vec<Message>, reddit_data: &'a Value) -> Value {
}
return msgs_json;
}
#[poise::command(slash_command, prefix_command)]
pub async fn bk_week_vote(
ctx: Context<'_>,
#[description = "The post URL."] url: String,
#[description = "Wether to undo your vote or not"] un_vote: Option<bool>
) -> Result<(), Error>
{
data::update_re_data(ctx.data()).await;
let uid = ctx.author().id.get();
let re_data = get_reddit_data(ctx).await.unwrap();
let post_data = re_data["bk_weekly_art_posts"].clone();
let unw_vote = un_vote.unwrap_or_else(|| false);
if post_data.get(&url).is_none() {
send_post_not_found_message(ctx, &url).await;
return Ok(());
}
let url_data = &post_data[&url];
let is_mod = is_bk_mod(ctx.data().bk_mods_json.clone(), ctx.author().id.get());
let voters_dc = url_data["votes"]["voters_dc"].as_array().unwrap();
let mod_voters = url_data["votes"]["mod_voters"].as_array().unwrap();
let voters = if is_mod { mod_voters } else { voters_dc };
if voters.contains(&json!(uid)) && !unw_vote {
send_msg(ctx, "Couldn't cast a vote: You have already voted on this post!".to_string(), true, true).await;
return Ok(());
}
else if !voters.contains(&json!(uid)) && unw_vote {
send_msg(ctx, "Couldn't remove your vote: You haven't voted on this post yet!".to_string(), true, true).await;
return Ok(());
}
let r = send_cmd_json("set_vote_post", json!([url, uid, is_mod, true, unw_vote])).await.unwrap();
let unw_r = r["value"].as_bool().unwrap();
if unw_r && !unw_vote && is_mod {
send_msg(ctx, "Successfully voted (as moderator vote)!".to_string(), true, true).await;
}
else if unw_r && !unw_vote && !is_mod {
send_msg(ctx, "Successfully voted!".to_string(), true, true).await;
}
else if unw_r && unw_vote {
send_msg(ctx, "Successfully removed vote!".to_string(), true, true).await;
}
else {
send_msg(ctx, "Failed to vote/un-vote: Unknown internal error".to_string(), true, true).await;
}
return Ok(());
}
+9 -5
View File
@@ -23,7 +23,6 @@ use serde_json;
// TODO: bot command permissions
// TODO: bk_mod verification system
#[derive(Parser, Serialize, Clone)]
@@ -49,6 +48,7 @@ struct Data {
byte_dice_id: u64,
reddit_data: Mutex<Option<Value>>,
discord_data: Mutex<Option<Value>>,
bk_mods_json: Value,
args: Args
// TODO: schedules
}
@@ -66,6 +66,7 @@ async fn main() {
if args.test { println!("----- USING TEST BOT -----"); }
if args.dev { println!("----- DEV MODE ENABLED -----"); }
if args.dev && args.wipe { println!("----- \"DON'T WORRY ABOUT IT\" MODE ENABLED -----"); }
if args.py && !args.rs {
println!("----- PYTHON ONLY MODE -----");
@@ -115,13 +116,16 @@ async fn start(args: Args) {
async fn gen_data(args: Args) -> Data {
let ball_classic_str = std::fs::read_to_string("./data/8-ball_classic.txt").unwrap();
let ball_quirk_str = std::fs::read_to_string("./data/8-ball_quirky.txt").unwrap();
let ball_quirk_str = std::fs::read_to_string("./data/8-ball_quirky.txt").unwrap();
let bk_mods_str = std::fs::read_to_string("./data/bk_mods.json").unwrap();
let ball_classic: Vec<String> = ball_classic_str.lines().map(String::from).collect();
let ball_quirk: Vec<String> = ball_quirk_str .lines().map(String::from).collect();
let bk_mods: Value = serde_json::from_str(&bk_mods_str).unwrap();
let data = Data {
ball_prompts: [ball_classic, ball_quirk],
bk_mods_json: bk_mods,
byte_dice_id: 697149665166229614,
reddit_data: None.into(),
discord_data: None.into(),
@@ -168,9 +172,9 @@ async fn gen_bot(data: Data, args: Args) -> Client {
bk_week_cmds::bk_week_add(),
bk_week_cmds::bk_week_remove(),
bk_week_cmds::bk_week_approve(),
bk_week_cmds::bk_week_disapprove(),
bk_week_cmds::bk_week_bind(),
bk_week_cmds::bk_week_update()
bk_week_cmds::bk_admin_bind(),
bk_week_cmds::bk_week_update(),
bk_week_cmds::bk_week_vote()
],
event_handler: events::event_handler,
..Default::default()
+24 -3
View File
@@ -137,15 +137,25 @@ pub async fn edit_msg(
pub fn embed_post(post_data: &Value, url: &str, empheral: bool) -> EmbedOptions {
let media_type = &post_data["post_data"]["media_type"];
let re_votes = &post_data["votes"]["voters_re"].as_array().unwrap().len();
let dc_votes = &post_data["votes"]["voters_dc"].as_array().unwrap().len();
let desc_str = format!(
r#"Sorted by what I think will be most important
Spoilers and vote length anonymizer for fair review!
## Post Data:
**Media type:** `{}`
**Upvotes:** ||`{:>6}`||
**Post upvotes:** ||`{:>6}`||
**URL:** ||<{}>||
**Media URLS:**
{}
## Voting data:
**Moderator votes:** ||`{:>6}`||
**Community votes:** ||`{:>6}`||
* ||**From Reddit:** `{:>6}`||
* ||**From Discord:** `{:>6}`||
## Listing Data:
**Added by:** `{{ human: {}, bot: {} }}`
**Approved by:** `{{ human: {}, bot: [not implemented] }}`"#,
@@ -153,6 +163,12 @@ pub fn embed_post(post_data: &Value, url: &str, empheral: bool) -> EmbedOptions
post_data["post_data"]["upvotes"].as_i64().unwrap(),
url,
post_data["post_data"]["media_urls"].as_array().unwrap().iter().map(|s| format!("* ||<{}>||", s.as_str().unwrap())).collect::<Vec<_>>().join("\n"),
post_data["votes"]["mod_voters"].as_array().unwrap().len(),
re_votes + dc_votes,
re_votes,
dc_votes,
if post_data["added"] ["by_human"].as_bool().unwrap() { "" } else { "" },
if post_data["added"] ["by_bot"].as_bool().unwrap() { "" } else { "" },
if post_data["approved"]["by_human"].as_bool().unwrap() { "" } else { "" }
@@ -169,7 +185,7 @@ pub fn embed_post(post_data: &Value, url: &str, empheral: bool) -> EmbedOptions
return EmbedOptions {
title: Some(post_data["post_data"]["title"].as_str().unwrap().to_string()),
desc: format!("{}\nJSON: ||`{}`||", trimmed, serde_json::to_string(&json_min).unwrap()),
desc: format!("{}\n\nJSON: ||`{}`||", trimmed, serde_json::to_string(&json_min).unwrap()),
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()),
@@ -185,7 +201,12 @@ pub fn embed_post(post_data: &Value, url: &str, empheral: bool) -> EmbedOptions
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()),
desc: format!(
"## Removed by `{}`\n**Reason:** {}\n\nJSON: ||`{}`||",
post_data["removed_by"].as_str().unwrap(),
post_data["remove_reason"].as_str().unwrap(),
serde_json::to_string(&post_data).unwrap()
),
col: Some(REMOVED_DC_COL),
url: Some(url.to_string()),
empheral,
+63 -25
View File
@@ -12,17 +12,19 @@ BK_WEEKLY: Final[str] = "bk_weekly_art_posts"
class PostData:
def __init__(
self,
url: str,
title: str,
upvotes: int,
date_unix: int,
media_type: str,
media_urls: list[str],
nominated_by_human: bool = False,
added_by_human: bool = False,
added_by_bot: bool = False,
url: str,
title: str,
upvotes: int,
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
approved_by_ris: bool = False
):
self.url = url
self.title = title
@@ -30,7 +32,9 @@ class PostData:
self.date_unix = date_unix
self.media_type = media_type
self.media_urls = media_urls
self.nominated_by_human = nominated_by_human
self.voters_re = voters_re
self.voters_dc = voters_dc
self.mod_voters = mod_voters
self.added_by_human = added_by_human
self.added_by_bot = added_by_bot
self.approved_by_human = approved_by_human
@@ -45,7 +49,11 @@ class PostData:
"media_type": self.media_type,
"media_urls": self.media_urls
},
"nominated_by_human": self.nominated_by_human,
"votes": {
"voters_re": self.voters_re,
"voters_dc": self.voters_dc,
"mod_voters": self.mod_voters
},
"added": {
"by_human": self.added_by_human,
"by_bot": self.added_by_bot
@@ -83,9 +91,6 @@ def read_data(bot: botPy.Bot) -> bool:
data_str = bot.data_f.read()
json_data = json.loads(data_str)
bot.data = json_data
if not bot.data["file_created_correctly"]:
raise Exception("reddit_data.json file wasn't created properly. Delete the file and retry.")
return True
@@ -104,22 +109,20 @@ 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
# not sure what this is for
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}\"")
return True
elif "removed" in bot.data[BK_WEEKLY][new_data.url]:
py_print(f"Failed to add post \"{new_data.url}\": Removed flag is True.")
return 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"]
else:
py_print(f"Failed to add post \"{new_data.url}\": Already exists.")
py_print(f"Failed to add post \"{new_data.url}\": Removed flag is True.")
return False
@@ -131,9 +134,44 @@ def set_approve_post(bot: botPy.Bot, approved: bool, url: str) -> bool:
return False
def remove_post(bot: botPy.Bot, url: str, removed_by: str = "UNKNOWN") -> bool:
def remove_post(bot: botPy.Bot, url: str, removed_by: str = "UNKNOWN", reason: str = "None") -> bool:
if url in bot.data[BK_WEEKLY]:
bot.data[BK_WEEKLY][url] = { "removed": True, "removed_by": removed_by }
bot.data[BK_WEEKLY][url] = { "removed": True, "removed_by": removed_by, "remove_reason": reason }
return True
else:
return False
return False
def set_vote_post(
bot: botPy.Bot,
url: str,
user: str | int,
mod_vote: bool = False,
from_dc: bool = False,
remove_vote: bool = False,
) -> bool:
if url not in bot.data[BK_WEEKLY]:
return False
votes = bot.data[BK_WEEKLY][url]["votes"]
re_voters: set[str] = set(votes["voters_re"])
dc_voters: set[int] = set(votes["voters_dc"])
mod_voters: set[int] = set(votes["mod_voters"])
target_voters = mod_voters if mod_vote else (dc_voters if from_dc else re_voters)
if remove_vote:
if user not in target_voters:
return False
target_voters.remove(user)
else:
if user in target_voters:
return False
target_voters.add(user)
bot.data[BK_WEEKLY][url]["votes"]["voters_re"] = list(re_voters)
bot.data[BK_WEEKLY][url]["votes"]["voters_dc"] = list(dc_voters)
bot.data[BK_WEEKLY][url]["votes"]["mod_voters"] = list(mod_voters)
return True
-1
View File
@@ -50,7 +50,6 @@ async def add_new_posts(bot: botPy.Bot) -> bool:
f" {without_media} had no media, " +
f"and {not_added} weren't added because they are removed or already existed")
data.write_data(bot)
return True
+1
View File
@@ -68,6 +68,7 @@ async def json_to_func(v: dict, bot: botPy.Bot) -> dict:
case "add_post_url": result = result_json(await posts.add_post_url(bot, *v["args"]))
case "remove_post_url": result = result_json(data.remove_post(bot, *v["args"]))
case "set_approve_post": result = result_json(data.set_approve_post(bot, *v["args"]))
case "set_vote_post": result = result_json(data.set_vote_post(bot, *v["args"]))
case "stop_praw": result = result_json(await bot.stop())
case _: value_supported = False