53 lines
1.7 KiB
Rust
53 lines
1.7 KiB
Rust
use reqwest::{blocking::Client, cookie::Jar};
|
|
use std::{env, error::Error, fs, path::PathBuf, sync::Arc};
|
|
|
|
const BASE_URL: &str = "https://adventofcode.com";
|
|
|
|
#[macro_export]
|
|
macro_rules! input {
|
|
() => {{
|
|
let stem = std::path::Path::new(file!())
|
|
.file_stem()
|
|
.unwrap()
|
|
.to_string_lossy();
|
|
let (year, day) = stem.split_once('-').unwrap();
|
|
$crate::get_day(year, day).unwrap()
|
|
}};
|
|
}
|
|
|
|
pub fn get_day(year: &str, day: &str) -> Result<String, Box<dyn Error>> {
|
|
let path = PathBuf::from(format!("input/{year}/day{day}.txt"));
|
|
fs::create_dir_all(path.parent().unwrap())?;
|
|
|
|
if let Ok(input) = fs::read_to_string(&path) {
|
|
Ok(input)
|
|
} else {
|
|
// get session token
|
|
let file = fs::read_to_string(".env").unwrap_or(String::new());
|
|
let session = file
|
|
.lines()
|
|
.filter_map(|line| line.split_once('='))
|
|
.map(|(key, value)| (key.to_string(), value.to_string()))
|
|
.chain(env::vars())
|
|
.find_map(|(k, v)| (k == "SESSION").then_some(v))
|
|
.ok_or(
|
|
"SESSION environment variable not set, retrieve it from https://adventofcode.com",
|
|
)?;
|
|
|
|
// create session cookie
|
|
let cookie = format!("session={session}");
|
|
|
|
// setup client
|
|
let jar = Arc::new(Jar::default());
|
|
jar.add_cookie_str(&cookie, &BASE_URL.parse()?);
|
|
let client = Client::builder().cookie_provider(jar).build()?;
|
|
|
|
// download until day fails
|
|
let url = format!("{BASE_URL}/{year}/day/{day}/input");
|
|
let text = client.get(url).send()?.text()?;
|
|
fs::create_dir_all(path.parent().unwrap())?;
|
|
fs::write(path, &text)?;
|
|
|
|
Ok(text)
|
|
}
|
|
}
|