use crate::prelude::*;
use chrono::{DateTime, TimeDelta, Utc};
use reqwest::Client;
use reqwest::Error as ReqwestError;
const RELEASES_API: &str = "https://api.github.com/repos/RogueOneEcho/caesura/releases/latest";
const RELEASES_URL: &str = "https://github.com/RogueOneEcho/caesura/releases";
#[derive(Deserialize)]
pub(crate) struct GitHubRelease {
tag_name: String,
published_at: DateTime<Utc>,
}
impl GitHubRelease {
pub(crate) async fn check_for_update() {
let current = app_version_or_describe();
let Ok(latest) = Self::get_latest().await else {
return;
};
if latest.tag_name == current {
trace!(
"Version matches the latest GitHub release: {}",
latest.tag_name
);
} else {
let age = format_duration(Utc::now() - latest.published_at);
warn!("{} is available", "Update".bold());
info!(
"Latest version is {}. Released {} ago",
latest.tag_name, age
);
info!("{RELEASES_URL}");
}
}
async fn get_latest() -> Result<GitHubRelease, ReqwestError> {
Client::new()
.get(RELEASES_API)
.header("User-Agent", app_user_agent(true))
.send()
.await?
.json()
.await
}
}
fn format_duration(delta: TimeDelta) -> String {
let mins = delta.num_minutes() % 60;
let hours = delta.num_hours() % 24;
let days = delta.num_days() % 7;
let weeks = delta.num_weeks();
if weeks > 0 {
format!("{weeks} weeks, {days} days")
} else if days > 0 {
format!("{days} days, {hours} hours")
} else if hours > 0 {
format!("{hours} hours, {mins} minutes")
} else {
format!("{mins} minutes")
}
}