Skip to content

Commit

Permalink
download all files
Browse files Browse the repository at this point in the history
  • Loading branch information
dev-ardi committed Nov 24, 2023
1 parent 4f956f3 commit 2aaa5db
Show file tree
Hide file tree
Showing 6 changed files with 116 additions and 31 deletions.
6 changes: 3 additions & 3 deletions aoc-runner-derive/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -10,9 +10,9 @@ repository = "https://github.com/gobanos/aoc-runner-derive"
proc-macro = true

[dependencies]
syn = { version = "1.0.5", features = ["extra-traits"] }
quote = "1.0.2"
proc-macro2 = "1.0.5"
syn = { version = "1.0.109", features = ["extra-traits"] }
quote = "1.0.33"
proc-macro2 = "1.0.69"
#aoc-runner-internal = { path = "../aoc-runner-internal" }
aoc-runner-internal = "0.1.0"

Expand Down
6 changes: 3 additions & 3 deletions aoc-runner-internal/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,6 @@ license = "MIT/Apache-2.0"
repository = "https://github.com/gobanos/aoc-runner-internal"

[dependencies]
serde = "1.0.101"
serde_derive = "1.0.101"
serde_json = "1.0.41"
serde = "1.0.193"
serde_derive = "1.0.193"
serde_json = "1.0.108"
11 changes: 6 additions & 5 deletions cargo-aoc/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -12,10 +12,11 @@ edition = "2021"
[dependencies]
#aoc-runner-internal = { path = "../aoc-runner-internal" }
aoc-runner-internal = "0.1.0"
toml = "0.5.9"
chrono = "0.4.24"
chrono-tz = "0.8.1"
reqwest = { version = "0.11.15", features = ["blocking"] }
webbrowser = "0.8.2"
toml = "0.5.11"
chrono = "0.4.31"
chrono-tz = "0.8.4"
reqwest = { version = "0.11.22", features = ["blocking"] }
webbrowser = "0.8.12"
directories = "4.0.1"
clap = { version = "4.4.8", features = ["derive"] }
tokio = { version = "1.34.0", features = ["full"] }
113 changes: 96 additions & 17 deletions cargo-aoc/src/app.rs
Original file line number Diff line number Diff line change
@@ -1,12 +1,18 @@
use crate::{
credentials::CredentialsManager, date, project::ProjectManager, Bench, Credentials, Input,
};
use aoc_runner_internal::{Day, Part};
use crate::{Bench, Credentials, credentials::CredentialsManager, date, project::ProjectManager, Input};
use date::AOCDate;
use reqwest::{blocking::Client, header::{COOKIE, USER_AGENT}, StatusCode};
use std::error;
use reqwest::{
header::{HeaderMap, COOKIE, USER_AGENT},
StatusCode,
};
use std::fs::{self, File};
use std::io::Write;
use std::path::Path;
use std::process;
use std::{error, sync::Arc};
use tokio::task::JoinSet;

use crate::Cli;

Expand All @@ -31,29 +37,37 @@ pub fn execute_credentials(args: &Credentials) {
}

/// Executes the "input" subcommand of the app
pub fn execute_input(sub_args: &Input) {
pub fn execute_input(args: &Input) {
// Gets the token or exit if it's not referenced.
let token = CredentialsManager::new().get_session_token().expect(
"Error: you need to setup your AOC token using \"cargo aoc credentials -s {token}\"",
);

let formated_token = format!("session={}", token);
let mut headers = HeaderMap::new();
headers.insert(USER_AGENT, CARGO_AOC_USER_AGENT.parse().unwrap());
headers.insert(COOKIE, formated_token.parse().unwrap());

if args.all {
let year = args
.year
.expect("Need to specify a year to run cargo-aoc input --all");
download_all_inputs(year, headers);
return;
}

// Creates the AOCDate struct from the arguments (defaults to today...)
let date: AOCDate = AOCDate::new(sub_args);
let date: AOCDate = AOCDate::new(args);
println!(
"Requesting input for year {}, day {} ...",
date.year, date.day
);

// Creates an HTTP Client
let client = Client::new();
let client = reqwest::blocking::Client::new();
// Cookie formatting ...
let formated_token = format!("session={}", token);
// Sends the query to the right URL, with the user token
let res = client
.get(&date.request_url())
.header(USER_AGENT, CARGO_AOC_USER_AGENT)
.header(COOKIE, formated_token)
.send();
let res = client.get(&date.request_url()).headers(headers).send();

// Depending on the StatusCode of the request, we'll write errors or try to write
// the result of the HTTP Request to a file
Expand All @@ -80,6 +94,74 @@ pub fn execute_input(sub_args: &Input) {
}
}

// The client should have the appropriate headers set
async fn download_input_async(
date: AOCDate,
client: &reqwest::Client,
) -> Result<(), Box<dyn error::Error>> {
let filename = date.filename();
let filename = Path::new(&filename);

if filename.exists() {
return Ok(());
}

let response = client.get(&date.request_url()).send().await?;

match response.status() {
StatusCode::OK => {
let dir = date.directory();
// Creates the file-tree to store inputs
// TODO: Maybe use crate's infos to get its root in the filesystem ?
fs::create_dir_all(&dir)?;

// Gets the body from the response and outputs everything to a file
let body = response
.text()
.await
.map_err(|e| format!("Can't convert response to text: {e:?}"))?;
let mut file = File::create(&filename)?;
file.write_all(body.as_bytes())?;
Ok(())
}
StatusCode::NOT_FOUND => Err(format!("Day {} not yet ready", date.day))?,
sc => Err(format!(
"Could not find corresponding input. Is the token correct?\n\
Status: {}\n\n\
Message: {}",
sc,
response.text().await.unwrap_or_else(|_| String::new())
))?,
}
}

fn download_all_inputs(year: i32, headers: HeaderMap) {
let rt = tokio::runtime::Runtime::new().unwrap();
rt.block_on(async {
let client = reqwest::Client::builder()
.default_headers(headers)
.build()
.unwrap();
let client = Arc::new(client);

let mut tasks = Vec::new();
for day in 1..26u32 {
let client = client.clone();
tasks.push(tokio::spawn(async move {
let date = AOCDate { day, year };
match download_input_async(date, &*client).await {
Ok(_) => println!("Successfully downloaded day {day}"),
Err(e) => eprintln!("{e}"),
};
}));
}
for task in tasks {
let _ = task.await;
}
});
return;
}

fn download_input(day: Day, year: u32) -> Result<(), Box<dyn error::Error>> {
let date = AOCDate {
day: u32::from(day.0),
Expand All @@ -95,7 +177,7 @@ fn download_input(day: Day, year: u32) -> Result<(), Box<dyn error::Error>> {

let token = CredentialsManager::new().get_session_token()?;
// Creates an HTTP Client
let client = Client::new();
let client = reqwest::blocking::Client::new();
// Cookie formatting ...
let formated_token = format!("session={}", token);

Expand Down Expand Up @@ -194,10 +276,7 @@ pub fn execute_default(args: &Cli) -> Result<(), Box<dyn error::Error>> {
))
.replace("{CRATE_SLUG}", &pm.slug)
.replace("{YEAR}", &day_parts.year.to_string())
.replace(
"{INPUT}",
&template_input(day, year, args.input.as_deref()),
)
.replace("{INPUT}", &template_input(day, year, args.input.as_deref()))
.replace("{BODY}", &body);

fs::create_dir_all("target/aoc/aoc-autobuild/src")
Expand Down
5 changes: 5 additions & 0 deletions cargo-aoc/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -85,6 +85,11 @@ pub struct Input {
/// Specifies the year. Defaults to the current year.
#[clap(short, long)]
year: Option<i32>,


/// Downloads all possible inputs for a given year
#[clap(short, long)]
all: bool,
}

fn main() {
Expand Down
6 changes: 3 additions & 3 deletions examples/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,6 @@ path = "aoc-2018/main.rs"
[dependencies]
aoc-runner = { path = "../aoc-runner" }
aoc-runner-derive = { path = "../aoc-runner-derive" }
fnv = "1.0.6"
chrono = "0.4.6"
petgraph = "0.4.13"
fnv = "1.0.7"
chrono = "0.4.31"
petgraph = "0.4.13"

0 comments on commit 2aaa5db

Please sign in to comment.