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)
 | |
|     }
 | |
| }
 |