use crate::files::parse_version;
use crate::Logger;
use anyhow::anyhow;
use anyhow::Error;
use reqwest::{Client, StatusCode};
use serde::{Deserialize, Serialize};
use std::fs::File;
use std::io::copy;
use std::io::Cursor;
use tempfile::{Builder, TempDir};
#[tokio::main]
pub async fn download_to_tmp_folder(
http_client: &Client,
url: String,
log: &Logger,
) -> Result<(TempDir, String), Error> {
let tmp_dir = Builder::new().prefix("selenium-manager").tempdir()?;
log.trace(format!(
"Downloading {} to temporal folder {:?}",
url,
tmp_dir.path()
));
let response = http_client.get(&url).send().await?;
let status_code = response.status();
if status_code != StatusCode::OK {
return Err(anyhow!(format!(
"Unsuccessful response ({}) for URL {}",
status_code, url
)));
}
let target_path;
let mut tmp_file = {
let target_name = response
.url()
.path_segments()
.and_then(|segments| segments.last())
.and_then(|name| if name.is_empty() { None } else { Some(name) })
.unwrap_or("tmp.bin");
log.trace(format!("File to be downloaded: {}", target_name));
let target_name = tmp_dir.path().join(target_name);
target_path = String::from(target_name.to_str().unwrap());
log.trace(format!(
"File downloaded to temporal folder: {}",
target_path
));
File::create(target_name)?
};
let mut content = Cursor::new(response.bytes().await?);
copy(&mut content, &mut tmp_file)?;
Ok((tmp_dir, target_path))
}
pub fn read_version_from_link(
http_client: &Client,
url: &str,
log: &Logger,
) -> Result<String, Error> {
parse_version(read_content_from_link(http_client, url)?, log)
}
#[tokio::main]
pub async fn read_content_from_link(http_client: &Client, url: &str) -> Result<String, Error> {
Ok(http_client.get(url).send().await?.text().await?)
}
#[tokio::main]
pub async fn read_redirect_from_link(
http_client: &Client,
url: String,
log: &Logger,
) -> Result<String, Error> {
parse_version(
http_client.get(&url).send().await?.url().path().to_string(),
log,
)
}
pub fn parse_json_from_url<T>(http_client: &Client, url: &str) -> Result<T, Error>
where
T: Serialize + for<'a> Deserialize<'a>,
{
let content = read_content_from_link(http_client, url)?;
match serde_json::from_str(&content) {
Ok(json) => Ok(json),
Err(err) => Err(anyhow!(format!(
"Error parsing JSON from URL {} {}",
url, err
))),
}
}