Skip to content

Commit

Permalink
👔 Update Logic
Browse files Browse the repository at this point in the history
  • Loading branch information
pAkalpa committed Mar 9, 2024
1 parent fe82b2e commit 9c6bea8
Show file tree
Hide file tree
Showing 3 changed files with 129 additions and 25 deletions.
66 changes: 50 additions & 16 deletions src/logics.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
use reqwest::Error;
use reqwest::header::{ACCEPT, AUTHORIZATION, USER_AGENT};
use rocket::serde::json::Json;
use crate::models::{Configs, GetLatestReleaseResponse, UpdateContent};
use crate::models::{Arch, Configs, GetLatestReleaseResponse, LatestJSONContent, OSType, TargetPlatform, UpdateContent};
use version_compare::{Version};

fn is_older_version(request_version: &str, release_version: &str) -> bool {
Expand All @@ -26,25 +26,59 @@ fn extract_url(response: &GetLatestReleaseResponse, category: &str) -> Vec<Strin
}).map(|asset| asset.browser_download_url.clone()).collect()
}

async fn extract_data_from_latest_json(response: &GetLatestReleaseResponse, platform: TargetPlatform) -> Option<Json<UpdateContent>> {
let latest_json_url: Vec<String> = response.assets.iter().filter(|asset| {
asset.name.eq_ignore_ascii_case("latest.json")
}).map(|asset| asset.browser_download_url.clone()).collect();

if &latest_json_url.len() > &0 {
let config = envy::from_env::<Configs>().unwrap();
let client = reqwest::Client::new();
let response = client.get(&latest_json_url[0]).header(USER_AGENT, config.github_repo_owner).send().await.ok();
let res = response?.json::<LatestJSONContent>().await;
match res {
Ok(re) => {
if let Some(platform_info) = re.platforms.get(&platform.to_string()) {
Some(Json(UpdateContent {
version: re.version,
pub_date: re.pub_date,
url: platform_info.url.clone(),
signature: platform_info.signature.clone(),
notes: re.notes,
}))
} else {
None
}
},
Err(_e) => None
}
} else { None }
}

async fn get_signature(url: String) -> Result<String, Error> {
let response = reqwest::get(url).await?.text().await?;
Ok(response)
}

pub async fn windows_logic(version: &str) -> Option<Json<UpdateContent>> {
let response = get_latest_release_data().await.unwrap();
if is_older_version(version, response.tag_name.as_str()) {
let zip_url = extract_url(&response, ".msi.zip")[0].to_owned();
let sig_url = extract_url(&response, ".msi.zip.sig")[0].to_owned();
let signature = get_signature(sig_url).await.unwrap();
Some(Json(UpdateContent {
version: response.tag_name,
pub_date: response.published_at,
url: zip_url,
signature,
notes: response.body
}))
} else {
None
pub async fn get_release_data(version: &str, arch: &str, target: &str) -> Option<Json<UpdateContent>> {
let response = get_latest_release_data().await;
match response {
Ok(res) => {
if !is_older_version(version, &res.tag_name) {
return None;
}

let target_os = target.parse::<OSType>().ok()?;
let architecture = arch.parse::<Arch>().ok()?;

match (target_os, architecture) {
(OSType::Windows, Arch::X86_64) => extract_data_from_latest_json(&res, TargetPlatform::WindowsX86_64).await,
(OSType::Linux, Arch::X86_64) => extract_data_from_latest_json(&res, TargetPlatform::LinuxX86_64).await,
(OSType::Darwin, Arch::X86_64) => extract_data_from_latest_json(&res, TargetPlatform::DarwinX86_64).await,
(OSType::Darwin, Arch::Aarch64) => extract_data_from_latest_json(&res, TargetPlatform::DarwinAarch64).await,
_ => None,
}
},
Err(_) => { None }
}
}
12 changes: 3 additions & 9 deletions src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ use crate::models::{Configs, UpdateContent};
use rocket::http::Header;
use rocket::{Request, Response};
use rocket::fairing::{Fairing, Info, Kind};
use crate::logics::windows_logic;
use crate::logics::{get_release_data};

pub struct CORS;

Expand Down Expand Up @@ -46,18 +46,12 @@ fn index() -> Redirect {
#[get("/<target>?<version>&<arch>")]
async fn get_update_data(target: &str, version: &str, arch: &str) -> Result<Json<UpdateContent>, Status> {
return match target {
"windows" => {
match windows_logic(version).await {
"windows" | "linux" | "darwin" => {
match get_release_data(version, arch, target).await {
Some(data) => Ok(data),
None => Err(Status::NoContent)
}
},
"linux" => {
Err(Status::NoContent)
},
"darwin" => {
Err(Status::NoContent)
},
_ => Err(Status::NoContent) }
}

Expand Down
76 changes: 76 additions & 0 deletions src/models.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
use serde::{Deserialize, Serialize};
use std::{fmt::{Formatter, Display}, collections::HashMap, str::FromStr};

#[derive(Serialize)]
pub struct UpdateContent {
Expand Down Expand Up @@ -34,6 +35,81 @@ pub struct GetLatestReleaseResponse {
pub body: String
}

#[derive(Serialize, Deserialize, Debug)]
pub struct PlatformInfo {
pub signature: String,
pub url: String,
}

#[derive(Serialize, Deserialize, Debug)]
pub struct LatestJSONContent {
pub version: String,
pub notes: String,
pub pub_date: String,
pub platforms: HashMap<String, PlatformInfo>,
}

#[derive(Debug, PartialEq)]
pub enum TargetPlatform {
DarwinX86_64,
DarwinAarch64,
LinuxX86_64,
WindowsX86_64
}

#[derive(Debug, PartialEq)]
pub enum Arch {
X86_64,
Aarch64,
I686,
Armv7
}

#[derive(Debug, PartialEq)]
pub enum OSType {
Windows,
Linux,
Darwin
}

impl FromStr for OSType {
type Err = ();

fn from_str(s: &str) -> Result<Self, Self::Err> {
match s {
"windows" => Ok(OSType::Windows),
"linux" => Ok(OSType::Linux),
"darwin" => Ok(OSType::Darwin),
_ => Err(())
}
}
}

impl FromStr for Arch {
type Err = ();

fn from_str(s: &str) -> Result<Self, Self::Err> {
match s {
"x86_64" => Ok(Arch::X86_64),
"aarch64" => Ok(Arch::Aarch64),
"i686" => Ok(Arch::I686),
"armv7" => Ok(Arch::Armv7),
_ => Err(())
}
}
}

impl Display for TargetPlatform {
fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
match *self {
TargetPlatform::DarwinX86_64 => write!(f, "darwin-x86_64"),
TargetPlatform::DarwinAarch64 => write!(f, "darwin-aarch64"),
TargetPlatform::LinuxX86_64 => write!(f, "linux-x86_64"),
TargetPlatform::WindowsX86_64 => write!(f, "windows-x86_64")
}
}
}

fn default_github_api_url() -> String {
String::from("https://api.github.com")
}
Expand Down

0 comments on commit 9c6bea8

Please sign in to comment.