use std::
{
fs,
env,
time::Duration,
path::Path,
};
use ureq::{ Error, Agent };
use serde_json::Value;
use semver::Version;
use crate::consts;
#[cfg(feature = "client")]
use std::sync::mpsc::Sender;
#[cfg(feature = "client")]
use crate::network::client::ClientEvent;
#[cfg(feature = "server")]
use std::path::PathBuf;
fn get_dir(dir: &str) -> String
{
dir.replace("{HOME}", dirs::home_dir().expect("Could not determine home directory").to_str().expect("Invalid home directory"))
}
pub fn get_version<'a>() -> &'a str {
env!("CARGO_PKG_VERSION")
}
pub fn get_identifier() -> String {
format!("WHY2/{}", get_version())
}
pub fn fetch_data(url: &str) -> Result<String, Error> {
let agent: Agent = Agent::config_builder()
.timeout_global(Some(Duration::from_millis(consts::FETCH_TIMEOUT)))
.build()
.into();
agent.get(url)
.header("User-Agent", &get_identifier())
.call()?
.body_mut()
.read_to_string()
}
pub fn check_version(#[cfg(feature = "client")] tx: &Sender<ClientEvent>) {
let metadata_raw = match fetch_data(consts::METADATA_URL)
{
Ok(m) => m,
Err(_) =>
{
#[cfg(feature = "client")]
{
tx.send(ClientEvent::VersionFailed).unwrap();
}
#[cfg(feature = "server")]
{
log::warn!("Fetching versions failed, this release could be unsafe!");
}
return;
}
};
let metadata: Value = serde_json::from_str(&metadata_raw).expect("Parsing versions failed"); let newest_version = metadata.get("crate") .and_then(|c| c.get("newest_version"))
.and_then(|v| v.as_str())
.unwrap();
let current_version = get_version();
if current_version != newest_version
{
let versions = metadata.get("versions").and_then(|v| v.as_array()).unwrap();
let mut newer_versions = 0usize;
let current_version = Version::parse(current_version).expect("Invalid version");
for version in versions
{
if Version::parse(version.get("num").and_then(|n| n.as_str()).unwrap()).unwrap() > current_version
{
newer_versions += 1;
}
}
#[cfg(feature = "client")]
{
tx.send(ClientEvent::UnsafeVersion(newer_versions, current_version, newest_version.to_owned())).unwrap();
}
#[cfg(feature = "server")]
{
log::warn!("This release could be unsafe! You are {newer_versions} versions behind! ({current_version}/{newest_version})");
}
}
}
pub fn get_why2_dir() -> String {
get_dir(consts::CONFIG_DIR)
}
pub fn check_directory() {
let config = get_why2_dir();
if !Path::new(&config).is_dir()
{
fs::create_dir_all(config).expect("Failed to create WHY2 config directory");
}
}
#[cfg(feature = "server")]
pub fn get_upload_dir(username: &str) -> PathBuf {
env::temp_dir().join(consts::UPLOADS_DIR).join(username)
}