added voting system, bug fixes, and a ton more
This commit is contained in:
@@ -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
@@ -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**
|
||||
```
|
||||
|
||||
@@ -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"
|
||||
|
||||
@@ -0,0 +1,29 @@
|
||||
{
|
||||
"bk1": {
|
||||
"discord": [
|
||||
697149665166229614,
|
||||
526842473062989864,
|
||||
1171015493537247273,
|
||||
1156779840956010496,
|
||||
1021944396473716847,
|
||||
1085622021024653362,
|
||||
1223480842525872148,
|
||||
1155349278655520858
|
||||
],
|
||||
"reddit": [
|
||||
|
||||
]
|
||||
},
|
||||
"bk2": {
|
||||
"discord": [
|
||||
1004132854227292272,
|
||||
1031352334745354282,
|
||||
1173039143245332520,
|
||||
1281040971710201857,
|
||||
772049174672703528
|
||||
],
|
||||
"reddit": [
|
||||
|
||||
]
|
||||
}
|
||||
}
|
||||
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
|
||||
@@ -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
|
||||
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
Reference in New Issue
Block a user