Skip to content

Instantly share code, notes, and snippets.

@chapuzzo
Created December 1, 2022 19:27
Show Gist options
  • Save chapuzzo/eede7e89f4fef52954a1e136457a5695 to your computer and use it in GitHub Desktop.
Save chapuzzo/eede7e89f4fef52954a1e136457a5695 to your computer and use it in GitHub Desktop.
Little tool to download samples/inputs for AoC
use clap::Parser;
use reqwest::Client;
use select::predicate::{Name, Predicate};
use std::env;
use std::fs::{create_dir_all, File};
use std::io::Write;
use std::path::Path;
use std::time::Duration;
#[derive(PartialEq)]
enum Kind {
Snippets,
Input,
}
#[derive(Parser, Debug)]
#[command(author, version, about, long_about)]
struct Args {
#[arg()]
day: u8,
#[arg(default_value = "2022")]
year: u16,
#[arg(long, short = 'i')]
input: bool,
}
#[tokio::main]
async fn main() {
dotenv::dotenv().ok();
let args = Args::parse();
let kind = if args.input {
Kind::Input
} else {
Kind::Snippets
};
download(args.year, args.day, kind)
.await
.expect("download failed");
}
async fn download(year: u16, day: u8, kind: Kind) -> Result<(), anyhow::Error> {
let client = Client::builder()
.timeout(Duration::from_secs(3))
.build()
.expect("cannot build http client");
let suffix = if kind == Kind::Input { "/input" } else { "" };
let url = format!("https://adventofcode.com/{year}/day/{day}{suffix}");
let cookie = env::var("COOKIE")
.expect("must set a valid session cookie in .env");
let ua = env::var("UA")
.expect("must set a valid user agent to perform requests");
let response = client
.get(url)
.header(reqwest::header::USER_AGENT, ua)
.header(reqwest::header::COOKIE, cookie)
.send()
.await?
.text()
.await?;
let cwd = env::current_dir().expect("cannot get cwd");
let destination = cwd.join(Path::new(format!("{}/{:0>2}", year, day).as_str()));
create_dir_all(destination.clone()).expect("could not create folder for download");
match kind {
Kind::Snippets => {
let doc = select::document::Document::from(response.as_str());
let fragments = doc.find(Name("pre").descendant(Name("code")));
for (id, fragment) in fragments.enumerate() {
let mut file = File::create(destination.join(format!("snippet_{:0>2}.txt", id)))
.expect("could not create file for storing");
write!(file, "{}", fragment.text()).expect("could not write file");
}
}
Kind::Input => {
let mut file = File::create(destination.join("input.txt"))
.expect("could not create file for storing");
write!(file, "{}", response)?;
}
};
Ok(())
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment