Skip to content

Commit

Permalink
Merge pull request #12 from byarr/feat/private_leaderboard
Browse files Browse the repository at this point in the history
feat: Add private-leaderboard command
  • Loading branch information
scarvalhojr authored Dec 14, 2022
2 parents 8c988ef + 6144c51 commit 1823498
Show file tree
Hide file tree
Showing 5 changed files with 127 additions and 1 deletion.
15 changes: 15 additions & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

3 changes: 2 additions & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,8 @@ html2text = "0.4"
http = "0.2"
log = "0.4"
regex = "1.7"
reqwest = { version = "0.11", features = ["blocking"] }
reqwest = { version = "0.11", features = ["blocking", "json"] }
serde = { version = "1.0", features=["derive"] }
term_size = "0.3"
thiserror = "1.0"

Expand Down
103 changes: 103 additions & 0 deletions src/aoc.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,9 @@ use reqwest::header::{
USER_AGENT,
};
use reqwest::redirect::Policy;
use serde::Deserialize;
use std::cmp::Reverse;
use std::collections::HashMap;
use std::env;
use std::fs::{read_to_string, OpenOptions};
use std::io::Write;
Expand Down Expand Up @@ -317,3 +320,103 @@ pub fn read(
println!("\n{}", from_read(desc.as_bytes(), col_width));
Ok(())
}

fn get_private_leaderboard_results(
args: &Args,
session: &str,
leaderboard: &str,
year: PuzzleYear,
) -> AocResult<PrivateLeaderboard> {
debug!("🦌 Fetching private leaderboard {}", leaderboard);

let url = format!(
"https://adventofcode.com/{}/leaderboard/private/view/{}.json",
year, leaderboard
);

let leaderboard: PrivateLeaderboard =
build_client(session, "application/json")?
.get(&url)
.send()
.and_then(|response| response.error_for_status())
.and_then(|response| response.json())
.map_err(AocError::from)?;
Ok(leaderboard)
}

pub fn show_private_leaderboard_results(
args: &Args,
session: &str,
leaderboard: &str,
) -> AocResult<()> {
let (year, day) = puzzle_year_day(args.year, args.day)?;
let leaderboard =
get_private_leaderboard_results(args, session, leaderboard, year)?;

let mut members: Vec<_> = leaderboard.members.values().collect();
members.sort_by_key(|m| Reverse(m.local_score));
members.iter().enumerate().for_each(|(idx, m)| {
let display_name = m
.name
.clone()
.unwrap_or(format!("anonymous user #{}", m.id));

let stars: String = (1..=25)
.map(|d| {
if d > day {
' '
} else {
let stars = m.stars_per_day(d);
match stars {
2 => '★',
1 => '☆',
_ => '.',
}
}
})
.collect();

let order = idx + 1;
println!("{}\t{}\t{}\t{}", order, m.local_score, stars, display_name);
});

Ok(())
}

#[derive(Deserialize)]
struct PrivateLeaderboard {
owner_id: usize,
event: String,
members: HashMap<String, Member>,
}

#[derive(Deserialize)]
struct Member {
name: Option<String>,
id: u64,
global_score: u64,
local_score: u64,
stars: u8,
completion_day_level: HashMap<u32, DayLevel>,
}

impl Member {
fn stars_per_day(&self, day: u32) -> u8 {
self.completion_day_level
.get(&day)
.map(|d| d.stars.len() as u8)
.unwrap_or(0)
}
}

#[derive(Deserialize)]
struct DayLevel {
#[serde(flatten)]
stars: HashMap<String, Star>,
}

#[derive(Deserialize)]
struct Star {
get_star_ts: u64,
star_index: u64,
}
4 changes: 4 additions & 0 deletions src/args.rs
Original file line number Diff line number Diff line change
Expand Up @@ -95,6 +95,10 @@ pub enum Command {
/// Puzzle answer
answer: String,
},

/// Get private leaderboard results
#[command(visible_alias = "pr")]
PrivateLeaderboard { leaderboard: String },
}

fn convert_number<T: FromStr>(s: &str) -> Result<T, String>
Expand Down
3 changes: 3 additions & 0 deletions src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -77,6 +77,9 @@ fn run(args: &Args) -> AocResult<()> {
Some(Command::Submit { part, answer }) => {
submit(args, &session, width, part, answer)
}
Some(Command::PrivateLeaderboard { leaderboard }) => {
show_private_leaderboard_results(args, &session, leaderboard)
}
_ => read(args, &session, width),
}
}

0 comments on commit 1823498

Please sign in to comment.