// SPDX-FileCopyrightText: 2020 Florian Warzecha // // SPDX-License-Identifier: MPL-2.0 use std::fs::File; use std::io::Write; use std::path::Path; use anyhow::{anyhow, Result}; use reqwest::{blocking::Client, header::COOKIE, StatusCode}; use crate::Aoc; /// Get the input for the exercise of the specified day. /// /// If the file exists, read it and return the content. /// /// If it does not exist, check if download of the file should be attempted, /// download it, read it and return the content. pub fn get_input(aoc: &Aoc, day: u8) -> Result { let dirname = format!("input/{}/", aoc.year); let file = format!("{}day{}.txt", dirname, day); let file = Path::new(&file); if !file.is_file() { if !aoc.allow_download { return Err(anyhow!( "Missing input file '{}' and automatic download is disabled.", file.display() )); } let credentials = std::fs::read_to_string(".aoc_session.txt") .map_err(|e| anyhow!("Failed to read token from '.aoc_session.txt': {}", e))?; let credentials = credentials.trim(); let formated_token = format!("session={}", credentials); let url = format!("https://adventofcode.com/{}/day/{}/input", aoc.year, day); println!("Starting download of '{}'...", file.display()); let client = Client::new(); let res = client .get(&url) .header(COOKIE, formated_token) .send() .map_err(|e| anyhow!("Failed to get response: {}", e))?; match res.status() { StatusCode::OK => { std::fs::create_dir_all(dirname) .map_err(|e| anyhow!("Failed to create directory: {}", e))?; let body = res .text() .map_err(|e| anyhow!("Could not read content: {}", e))?; let mut file = File::create(&file).map_err(|e| anyhow!("Could not create file: {}", e))?; file.write_all(body.as_bytes()) .map_err(|e| anyhow!("Could not write: {}", e))?; } sc => { println!("Failed to download file. Status: {}", sc); } } } Ok(std::fs::read_to_string(file) .map_err(|e| anyhow!("Failed to read input file '{}': {}", file.display(), e))?) }