WIP late submissions

late-submissions
Elnu 2 years ago
parent b90ef09836
commit 1db0d0da0c

@ -34,7 +34,11 @@ pub async fn challenge(ctx: Context<'_>) -> Result<(), Error> {
broadcast_typing, broadcast_typing,
description_localized("en-US", "Submit to the latest handwriting challenge.") description_localized("en-US", "Submit to the latest handwriting challenge.")
)] )]
pub async fn submit(ctx: Context<'_>, submission: serenity::Attachment) -> Result<(), Error> { pub async fn submit(
ctx: Context<'_>,
challenge: Option<i32>,
submission: serenity::Attachment
) -> Result<(), Error> {
// TODO: The code for this command needs to be refactored, // TODO: The code for this command needs to be refactored,
// there are large duplicated sections that need to be merged somehow. // there are large duplicated sections that need to be merged somehow.
match ctx { match ctx {
@ -71,16 +75,30 @@ pub async fn submit(ctx: Context<'_>, submission: serenity::Attachment) -> Resul
.await?; .await?;
return Ok(()); return Ok(());
} }
let latest_challenge = get_challenge_number();
let challenge_number = get_challenge_number(); let late;
let submission_images_dir = get_submission_images_dir(); let challenge_number = match challenge {
Some(challenge) => {
if challenge > latest_challenge {
ctx.say(format!("That challenge doesn't exist, the latest challenge is #{latest_challenge}.")).await?;
return Ok(());
};
late = challenge < latest_challenge;
challenge
},
None => {
late = false;
get_challenge_number()
},
};
let submission_images_dir = get_submission_images_dir(challenge_number);
let timestamp = std::time::SystemTime::now().duration_since(std::time::UNIX_EPOCH).unwrap().as_millis(); let timestamp = std::time::SystemTime::now().duration_since(std::time::UNIX_EPOCH).unwrap().as_millis();
// Ensure that submission_images_dir exists // Ensure that submission_images_dir exists
let path = Path::new(&submission_images_dir); let path = Path::new(&submission_images_dir);
std::fs::create_dir_all(path)?; std::fs::create_dir_all(path)?;
let mut submission_data = get_current_submission_data(); let mut submission_data = get_submission_data(challenge_number);
let mut existing_submitter = false; let mut existing_submitter = false;
let mut invalid_types = false; let mut invalid_types = false;
let mut requires_rebuild = false; let mut requires_rebuild = false;
@ -92,7 +110,7 @@ pub async fn submit(ctx: Context<'_>, submission: serenity::Attachment) -> Resul
let author = ctx.author(); let author = ctx.author();
let mut submitted_images = Vec::new(); let mut submitted_images = Vec::new();
for submission in submission_data.iter_mut() { for submission in submission_data.iter_mut() {
if is_matching_submission(&submission, author) { if is_matching_submission(&submission, author) && late == (submission.as_object().unwrap().contains_key("late") && submission["late"].as_bool().unwrap()) {
existing_submitter = true; existing_submitter = true;
let mut images: Vec<String> = submission["images"].as_array_mut().unwrap().clone().iter().map(|value| value.as_str().unwrap().to_owned()).collect(); let mut images: Vec<String> = submission["images"].as_array_mut().unwrap().clone().iter().map(|value| value.as_str().unwrap().to_owned()).collect();
for (i, attachment) in attachments.iter().enumerate() { for (i, attachment) in attachments.iter().enumerate() {
@ -173,9 +191,12 @@ pub async fn submit(ctx: Context<'_>, submission: serenity::Attachment) -> Resul
} }
submitter_data.insert(String::from("images"), images.into()); submitter_data.insert(String::from("images"), images.into());
submitter_data.insert(String::from("id"), author.id.as_u64().to_string().into()); submitter_data.insert(String::from("id"), author.id.as_u64().to_string().into());
if late {
submitter_data.insert(String::from("late"), true.into());
}
submission_data.push(submitter_data.into()); submission_data.push(submitter_data.into());
} }
set_submission_data(submission_data); set_submission_data(challenge_number, submission_data);
let mut message = String::new(); let mut message = String::new();
if requires_rebuild { if requires_rebuild {
let thank_you = &format!("Thank you for submitting! You can view your submission at <https://tegakituesday.com/{}>", challenge_number); let thank_you = &format!("Thank you for submitting! You can view your submission at <https://tegakituesday.com/{}>", challenge_number);
@ -206,7 +227,7 @@ pub async fn submit(ctx: Context<'_>, submission: serenity::Attachment) -> Resul
for image in submitted_images.iter() { for image in submitted_images.iter() {
for (other_guild_id, data) in guild_data.iter() { for (other_guild_id, data) in guild_data.iter() {
let here = other_guild_id.eq(&ctx.guild_id().unwrap().as_u64().to_string()); let here = other_guild_id.eq(&ctx.guild_id().unwrap().as_u64().to_string());
if !repost_here && here { if (late && !here) || (!repost_here && here) {
continue; continue;
} }
let data = data.as_object().unwrap(); let data = data.as_object().unwrap();
@ -230,8 +251,7 @@ pub async fn submit(ctx: Context<'_>, submission: serenity::Attachment) -> Resul
channel.send_message(&ctx.discord().http, |m| { channel.send_message(&ctx.discord().http, |m| {
m.embed(|e| { m.embed(|e| {
let username = format!("{}#{}", author.name, author.discriminator); let username = format!("{}#{}", author.name, author.discriminator);
let n = get_challenge_number(); let mut description = format!("New {}submission to [Tegaki Tuesday #{n}](https://tegakituesday.com/{n})!", if late { "late " } else { "" }, n = challenge_number);
let mut description = format!("New submission to [Tegaki Tuesday #{n}](https://tegakituesday.com/{n})!");
if !here { if !here {
description.push_str(&if let Some(invite) = invite { description.push_str(&if let Some(invite) = invite {
format!("\nCrossposted from [{}](https://discord.gg/{invite})", guild.name) format!("\nCrossposted from [{}](https://discord.gg/{invite})", guild.name)
@ -246,7 +266,7 @@ pub async fn submit(ctx: Context<'_>, submission: serenity::Attachment) -> Resul
.name(username) .name(username)
.url(format!("https://discord.com/users/{}", author.id)); .url(format!("https://discord.com/users/{}", author.id));
e.set_author(embed_author); e.set_author(embed_author);
e.image(format!("https://tegakituesday.com/{n}/{image}#{timestamp}")); e.image(format!("https://tegakituesday.com/{challenge_number}/{image}#{timestamp}"));
if let Some(accent_color) = accent_color { if let Some(accent_color) = accent_color {
e.color(accent_color); e.color(accent_color);
} }
@ -358,7 +378,7 @@ pub async fn imagedelete(ctx: Context<'_>, number: i32) -> Result<(), Error> {
} }
let index = number as usize - 1; let index = number as usize - 1;
let image = images[index].as_str().unwrap().to_owned(); let image = images[index].as_str().unwrap().to_owned();
let submission_images_dir = get_submission_images_dir(); let submission_images_dir = get_submission_images_dir(challenge_number);
let image_path = format!("{}/{}", submission_images_dir, image); let image_path = format!("{}/{}", submission_images_dir, image);
match fs::remove_file(image_path) { match fs::remove_file(image_path) {
Ok(_) => (), Ok(_) => (),
@ -374,7 +394,7 @@ pub async fn imagedelete(ctx: Context<'_>, number: i32) -> Result<(), Error> {
images.remove(index); images.remove(index);
submission["images"] = images.into(); submission["images"] = images.into();
} }
set_submission_data(submission_data); set_submission_data(challenge_number, submission_data);
rebuild_site(); rebuild_site();
ctx.say(message).await?; ctx.say(message).await?;
return Ok(()); return Ok(());
@ -387,7 +407,6 @@ pub async fn imagedelete(ctx: Context<'_>, number: i32) -> Result<(), Error> {
Ok(()) Ok(())
} }
// TODO: make also slash command
#[command( #[command(
prefix_command, prefix_command,
slash_command, slash_command,

@ -38,18 +38,14 @@ pub fn get_hugo_path() -> String {
env::var("HUGO").unwrap() env::var("HUGO").unwrap()
} }
pub fn get_submission_images_dir() -> String { pub fn get_submission_images_dir(challenge: i32) -> String {
format!("{}/assets/{}", get_hugo_path(), get_challenge_number()) format!("{}/assets/{challenge}", get_hugo_path())
} }
pub fn get_submission_data_path(challenge: i32) -> String { pub fn get_submission_data_path(challenge: i32) -> String {
format!("{}/data/challenges/{}.json", get_hugo_path(), challenge) format!("{}/data/challenges/{}.json", get_hugo_path(), challenge)
} }
pub fn get_current_submission_data_path() -> String {
get_submission_data_path(get_challenge_number())
}
pub fn get_current_submission_data() -> Vec<Value> { pub fn get_current_submission_data() -> Vec<Value> {
get_submission_data(get_challenge_number()) get_submission_data(get_challenge_number())
} }
@ -74,12 +70,12 @@ pub fn get_submission_data(challenge: i32) -> Vec<Value> {
submission_data.as_array_mut().unwrap().clone() submission_data.as_array_mut().unwrap().clone()
} }
pub fn set_submission_data(submission_data: Vec<Value>) { pub fn set_submission_data(challenge: i32, submission_data: Vec<Value>) {
let submission_data: Value = submission_data.into(); let submission_data: Value = submission_data.into();
let mut submission_data_file = OpenOptions::new() let mut submission_data_file = OpenOptions::new()
.write(true) .write(true)
.truncate(true) .truncate(true)
.open(get_current_submission_data_path()) .open(get_submission_data_path(challenge))
.unwrap(); .unwrap();
submission_data_file submission_data_file
.write_all( .write_all(
@ -359,9 +355,14 @@ pub async fn leaderboard(ctx: &Context<'_>) -> Result<(), Error> {
for challenge in 1..get_challenge_number() + 1 { for challenge in 1..get_challenge_number() + 1 {
let submission_data = get_submission_data(challenge); let submission_data = get_submission_data(challenge);
for submission in submission_data.iter() { for submission in submission_data.iter() {
let submission = submission.as_object().unwrap();
if submission.contains_key("late") && submission["late"].as_bool().unwrap() {
// Don't count late submissions toward leaderboard
continue;
}
let user = submission_counts let user = submission_counts
.entry(String::from( .entry(String::from(
submission.as_object().unwrap()["id"].as_str().unwrap(), submission["id"].as_str().unwrap(),
)) ))
.or_insert(0); .or_insert(0);
*user += 1; *user += 1;
@ -384,6 +385,7 @@ pub async fn leaderboard(ctx: &Context<'_>) -> Result<(), Error> {
leaderboard_html.push_str("</table>"); leaderboard_html.push_str("</table>");
let mut file = std::fs::OpenOptions::new() let mut file = std::fs::OpenOptions::new()
.create(true) .create(true)
.truncate(true) // potential fix for trailing >table> after leaderboard
.write(true) .write(true)
.open(env::var("LEADERBOARD").unwrap()) .open(env::var("LEADERBOARD").unwrap())
.unwrap(); .unwrap();

Loading…
Cancel
Save