From 575a8a29a4b025d73d0e79895b3b3d7e6f1d656c Mon Sep 17 00:00:00 2001 From: Artur Yurii Korchynskyi <42449190+akorchyn@users.noreply.github.com> Date: Tue, 6 Aug 2024 19:12:29 +0300 Subject: [PATCH] feat: shareable image similar to bot image (#160) @race-of-sloths --- public/badge_share_template.svg | 224 ---------------- public/badge_share_template_dark.svg | 339 +++++++++++++++++++++++++ public/badge_share_template_white.svg | 352 ++++++++++++++++++++++++++ server/src/entrypoints/user.rs | 18 +- server/src/svg.rs | 103 ++------ 5 files changed, 726 insertions(+), 310 deletions(-) delete mode 100644 public/badge_share_template.svg create mode 100644 public/badge_share_template_dark.svg create mode 100644 public/badge_share_template_white.svg diff --git a/public/badge_share_template.svg b/public/badge_share_template.svg deleted file mode 100644 index bf9d2ee..0000000 --- a/public/badge_share_template.svg +++ /dev/null @@ -1,224 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - {total-contributions} - - - Total ROS contributions - - - - - - {rank-svg} - - - {rank} - - - {rank-title} - - - - - - {total-rating} - - - Sloth Points - - - - - - - - - - - - - {place} - - - {place-type} Place - - - - - - - {max-month-streak} - - - Max. month streak - - - - - - - {max-week-streak} - - - Max. week streak - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/public/badge_share_template_dark.svg b/public/badge_share_template_dark.svg new file mode 100644 index 0000000..42e2351 --- /dev/null +++ b/public/badge_share_template_dark.svg @@ -0,0 +1,339 @@ + + + + + + + + + + + + + + + + + + + {rank-svg} + + + {rank} + + + {rank-title} + + + + + + {total-rating} + + + Sloth Points + + + + + + + + + + + + + {place} + + + {place-type} Place + + + + + + + {max-month-streak} + + + Max. month streak + + + + + + + {max-week-streak} + + + Max. week streak + + + + + + + + + + + + + + + + + + + + + + + + + + + + + {total-contributions} + + + Total contributions + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/public/badge_share_template_white.svg b/public/badge_share_template_white.svg new file mode 100644 index 0000000..b2f3551 --- /dev/null +++ b/public/badge_share_template_white.svg @@ -0,0 +1,352 @@ + + + + + + + + + + + + + + + + + + + {rank-svg} + + + {rank} + + + {rank-title} + + + + + + {total-rating} + + + Sloth Points + + + + + + + + + + + + + {place} + + + {place-type} Place + + + + + + + {max-month-streak} + + + Max. month streak + + + + + + + {max-week-streak} + + + Max. week streak + + + + + + + + + + + + + + + + + + + + + + + + + + + + + {total-contributions} + + + Total contributions + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/server/src/entrypoints/user.rs b/server/src/entrypoints/user.rs index 30b9d1c..c3243ba 100644 --- a/server/src/entrypoints/user.rs +++ b/server/src/entrypoints/user.rs @@ -8,7 +8,7 @@ use race_of_sloths_server::{ DB, }, github_pull::GithubClient, - svg::{generate_png_meta_badge, generate_svg_bot_badge, generate_svg_share_badge, Mode}, + svg::{generate_png_meta_badge, generate_svg_badge, Mode}, }; use rocket::{ http::{ContentType, Header, Status}, @@ -168,12 +168,12 @@ pub async fn get_badge<'a>( return Badge::with_status(Status::InternalServerError); } }; - construct_svg_badge_from_result(generate_svg_bot_badge( + construct_svg_badge_from_result(generate_svg_badge( telegram, - user, - metadata, font.inner().clone(), + user, theme.unwrap_or(Mode::Dark), + Some(metadata), )) } "meta" => { @@ -193,9 +193,13 @@ pub async fn get_badge<'a>( Err(_) => Badge::with_status(Status::InternalServerError), } } - "share" => { - construct_svg_badge_from_result(generate_svg_share_badge(user, font.inner().clone())) - } + "share" => construct_svg_badge_from_result(generate_svg_badge( + telegram, + font.inner().clone(), + user, + theme.unwrap_or(Mode::Dark), + None, + )), _ => { rocket::info!("Unknown badge type {badge_type}, returning 404"); Badge::with_status(Status::NotFound) diff --git a/server/src/svg.rs b/server/src/svg.rs index b84b331..11da56a 100644 --- a/server/src/svg.rs +++ b/server/src/svg.rs @@ -13,12 +13,12 @@ pub enum Mode { Light, } -pub fn generate_svg_bot_badge( +pub fn generate_svg_badge( telegram: &Arc, - user_record: UserRecord, - user_metadata: UserCachedMetadata, fontdb: Arc, + user_record: UserRecord, mode: Mode, + user_metadata: Option, ) -> anyhow::Result { let all_time = TimePeriod::AllTime.time_string(0); let total_period = user_record.get_total_period().cloned().unwrap_or_default(); @@ -53,25 +53,32 @@ pub fn generate_svg_bot_badge( }) .unwrap_or_else(|| ("Global".to_string(), "N/A".to_string())); - let svg_icon = match mode { - Mode::Light => std::fs::read_to_string("./public/badge_bot_template_white.svg")?, - Mode::Dark => std::fs::read_to_string("./public/badge_bot_template_dark.svg")?, + let svg_icon = match (&user_metadata, mode) { + (Some(_), Mode::Light) => std::fs::read_to_string("./public/badge_bot_template_white.svg")?, + (Some(_), Mode::Dark) => std::fs::read_to_string("./public/badge_bot_template_dark.svg")?, + (None, Mode::Light) => std::fs::read_to_string("./public/badge_share_template_white.svg")?, + (None, Mode::Dark) => std::fs::read_to_string("./public/badge_share_template_dark.svg")?, }; - let svg_icon = image_processing( - telegram, - svg_icon, - &user_metadata.image_base64, - &user_record.login, - ); - let sloth_id = if user_record.id == i32::MAX { - "Newcomer".to_string() + + let svg_icon = if let Some(user_metadata) = user_metadata { + let sloth_id = if user_record.id == i32::MAX { + "Newcomer".to_string() + } else { + format!("Sloth#{:04}", user_record.id) + }; + image_processing( + telegram, + svg_icon, + &user_metadata.image_base64, + &user_record.login, + ) + .replace("{login}", &user_record.login) + .replace("{sloth-id}", &sloth_id) } else { - format!("Sloth#{:04}", user_record.id) + svg_icon }; let svg_icon = svg_icon - .replace("{login}", &user_record.login) - .replace("{sloth-id}", &sloth_id) .replace( "{total-contributions}", &total_period.prs_opened.to_string(), @@ -90,68 +97,6 @@ pub fn generate_svg_bot_badge( postprocess_svg(svg_icon, fontdb) } -pub fn generate_svg_share_badge( - user_record: UserRecord, - fontdb: Arc, -) -> anyhow::Result { - let all_time = TimePeriod::AllTime.time_string(0); - let total_period = user_record - .period_data - .iter() - .find(|p| p.period_type == all_time) - .cloned() - .unwrap_or_default(); - let week_streak = user_record - .streaks - .iter() - .find(|e| e.streak_type == "Weekly") - .cloned() - .unwrap_or_default() - .best; - let month_streak = user_record - .streaks - .iter() - .find(|e| e.streak_type == "Monthly") - .cloned() - .unwrap_or_default() - .best; - - let (place_type, place) = user_record - .leaderboard_places - .iter() - .min_by(|(_, a), (_, b)| a.cmp(b)) - .map(|(a, place)| { - ( - if a == &all_time { - "Global".to_string() - } else { - "Monthly".to_string() - }, - place.to_string(), - ) - }) - .unwrap_or_else(|| ("Global".to_string(), "N/A".to_string())); - - let svg_icon = std::fs::read_to_string("./public/badge_share_template.svg")?; - - let svg_icon = svg_icon.replace( - "{total-contributions}", - &total_period.prs_opened.to_string(), - ); - let svg_icon = process_rank(svg_icon, &user_record); - - let svg_icon = svg_icon.replace( - "{total-rating}", - &total_period.total_rating.to_formatted_string(&Locale::en), - ); - let svg_icon = svg_icon.replace("{max-week-streak}", &week_streak.to_string()); - let svg_icon = svg_icon.replace("{max-month-streak}", &month_streak.to_string()); - let svg_icon = svg_icon.replace("{place}", &place); - let svg_icon = svg_icon.replace("{place-type}", &place_type); - - postprocess_svg(svg_icon, fontdb) -} - pub fn generate_png_meta_badge( telegram: &Arc, user_record: UserRecord,