feat: download cli command

This commit is contained in:
Matej Janezic 2022-11-28 21:59:26 +01:00
parent 000000208a
commit 0000003007
Signed by: janezicmatej
GPG Key ID: 4298E230ED37B2C0
9 changed files with 1091 additions and 6 deletions

View File

@ -1,3 +1,5 @@
[alias] [alias]
prepare = "run --bin prepare --" prepare = "run --bin prepare --"
download = "run --bin download --"
solve = "run --bin" solve = "run --bin"

2
.env.example Normal file
View File

@ -0,0 +1,2 @@
TOKEN=secret
YEAR=2022

999
Cargo.lock generated

File diff suppressed because it is too large Load Diff

View File

@ -8,4 +8,8 @@ default-run = "aoc"
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
[dependencies] [dependencies]
# framework
dotenv = "0.15.0"
pico-args = "0.5.0" pico-args = "0.5.0"
reqwest = { version = "0.11.13", features = ["blocking"] }
# for solving

View File

@ -16,6 +16,21 @@ cargo prepare <day>
# 🎄 Type `cargo solve 01` to run your solution. # 🎄 Type `cargo solve 01` to run your solution.
``` ```
### Download input
prepare `.env` file
```
cp .env.example .env
```
set `YEAR` to whichever year you are solving for and `TOKEN` to AoC session Cookie.
```sh
# example: `cargo download 1`
cargo download <day>
# output:
# Downloaded input file "src/inputs/01.txt"
```
### Solve ### Solve
```sh ```sh
# example: `cargo solve 01` # example: `cargo solve 01`

62
src/bin/download.rs Normal file
View File

@ -0,0 +1,62 @@
use dotenv::dotenv;
use reqwest::blocking::Client;
use reqwest::header;
use std::{env, fs::OpenOptions, io::Write, process};
fn main() {
let day: u8 = match aoc::parse_args() {
Ok(day) => day,
Err(_) => {
eprintln!("Need to specify a day (as integer). example: `cargo download 7`");
process::exit(1);
}
};
dotenv().ok();
let day_padded = format!("{:02}", day);
let token = env::var("TOKEN").expect("$TOKEN is not set");
let year = env::var("YEAR")
.expect("$YEAR is not set")
.parse::<u32>()
.expect("$YEAR must be a number");
let mut headers = header::HeaderMap::new();
let mut session_header = header::HeaderValue::from_str(format!("session={}", token).as_str())
.expect("Error building cookie header");
session_header.set_sensitive(true);
headers.insert(header::COOKIE, session_header);
let client = Client::builder().default_headers(headers).build().unwrap();
let res = client
.get(format!(
"https://adventofcode.com/{}/day/{}/input",
year, day
))
.send()
.unwrap()
.text()
.unwrap();
let input_path = format!("src/inputs/{}.txt", day_padded);
let mut file = match OpenOptions::new()
.write(true)
.create(true)
.open(&input_path)
{
Ok(file) => file,
Err(e) => {
eprintln!("Failed to create module file: {}", e);
process::exit(1);
}
};
match file.write_all(res.as_bytes()) {
Ok(_) => {
println!("Downloaded input file \"{}\"", &input_path);
}
Err(e) => {
eprintln!("Failed to write module contents: {}", e);
process::exit(1);
}
}
}

View File

@ -35,11 +35,6 @@ mod tests {
} }
"###; "###;
fn parse_args() -> Result<u8, pico_args::Error> {
let mut args = pico_args::Arguments::from_env();
args.free_from_str()
}
fn safe_create_file(path: &str) -> Result<File, std::io::Error> { fn safe_create_file(path: &str) -> Result<File, std::io::Error> {
OpenOptions::new().write(true).create_new(true).open(path) OpenOptions::new().write(true).create_new(true).open(path)
} }
@ -49,7 +44,7 @@ fn create_file(path: &str) -> Result<File, std::io::Error> {
} }
fn main() { fn main() {
let day = match parse_args() { let day = match aoc::parse_args() {
Ok(day) => day, Ok(day) => day,
Err(_) => { Err(_) => {
eprintln!("Need to specify a day (as integer). example: `cargo prepare 7`"); eprintln!("Need to specify a day (as integer). example: `cargo prepare 7`");

View File

@ -0,0 +1 @@

View File

@ -54,6 +54,11 @@ fn parse_time(val: &str, postfix: &str) -> f64 {
val.split(postfix).next().unwrap().parse().unwrap() val.split(postfix).next().unwrap().parse().unwrap()
} }
pub fn parse_args() -> Result<u8, pico_args::Error> {
let mut args = pico_args::Arguments::from_env();
args.free_from_str()
}
pub fn parse_exec_time(output: &str) -> f64 { pub fn parse_exec_time(output: &str) -> f64 {
output.lines().fold(0_f64, |acc, l| { output.lines().fold(0_f64, |acc, l| {
if !l.contains("elapsed:") { if !l.contains("elapsed:") {