diff --git a/Cargo.toml b/Cargo.toml index ae916a5..2d1528f 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -5,4 +5,4 @@ edition = "2024" [dependencies] alhp_api = {path = "crates/alhp_api"} - +alpm = "4.0.2" diff --git a/crates/alhp_api/Cargo.toml b/crates/alhp_api/Cargo.toml index 0bc7b2f..f6ad11a 100644 --- a/crates/alhp_api/Cargo.toml +++ b/crates/alhp_api/Cargo.toml @@ -8,3 +8,4 @@ authors = ["mpuchstein"] serde = { version = "1.0.219", features = ["derive"] } serde_json = "1.0.140" reqwest = { version = "0.12.15" , features = ["blocking"] } +log = "0.4.27" diff --git a/crates/alhp_api/src/lib.rs b/crates/alhp_api/src/lib.rs index 5aac3f6..d7c530a 100644 --- a/crates/alhp_api/src/lib.rs +++ b/crates/alhp_api/src/lib.rs @@ -1,10 +1,17 @@ -use std::fmt; -use serde::{Serialize, Deserialize}; +use log::{error, info}; +use reqwest::StatusCode; use reqwest::blocking::Client; +use serde::{Deserialize, Serialize}; +use std::error::Error; +use std::fmt; + +const API_BASE_URL: &str = "https://api.alhp.dev"; +const API_PACKAGES_EXT: &str = "/packages?"; +const API_GENERAL_EXT: &str = "/stats?"; #[derive(Debug, Clone, Copy, Serialize, Deserialize, Eq, PartialEq)] #[serde(rename_all = "lowercase")] -pub enum PackageStatus{ +pub enum PackageStatus { Latest, Failed, Built, @@ -18,7 +25,21 @@ pub enum PackageStatus{ impl fmt::Display for PackageStatus { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - write!(f, "{}", serde_json::to_string(self).unwrap().trim_matches('"')) + write!( + f, + "{}", + match self { + PackageStatus::Latest => "latest", + PackageStatus::Failed => "failed", + PackageStatus::Built => "build", + PackageStatus::Skipped => "skipped", + PackageStatus::Delayed => "delayed", + PackageStatus::Building => "building", + PackageStatus::Signing => "signing", + PackageStatus::Unknown => "unknown", + PackageStatus::Queued => "queued", + } + ) } } @@ -28,11 +49,13 @@ pub struct Package { repo: String, split_packages: Vec, status: PackageStatus, + skip_reason: Option, lto: String, debug_symbols: String, arch_version: String, repo_version: String, - build_date: String, + build_date: Option, + peak_mem: Option, } #[derive(Debug, Clone, Serialize, Deserialize)] @@ -40,7 +63,7 @@ pub struct PackageResponse { pub total: usize, pub offset: usize, pub limit: usize, - pub packages: Vec + pub packages: Vec, } #[derive(Debug, Serialize, Default)] pub struct PackageRequest { @@ -71,13 +94,51 @@ impl PackageRequest { params.push(format!("limit={}", self.limit)); params.join("&") } - pub fn response(&self) -> Result { + pub fn response(&self) -> Result> { + let query_url = format!( + "{}{}{}", + API_BASE_URL, + API_PACKAGES_EXT, + self.query_string() + ); + println!("{}", query_url); let client = Client::new(); - let query_string = self.query_string(); - let url = format!("https://api.alhp.dev/packages?{}", query_string); - println!("{}", url); - let response = client.get(url).send()?.text()?; - let response: PackageResponse = serde_json::from_str(&response).unwrap(); - Ok(response) + info!("Fetching URL: {}", query_url); + let response = client.get(query_url).send()?; + match response.status() { + StatusCode::OK => { + let response = response.text()?; + println!("{}", response); + match serde_json::from_str(&response) { + Ok(json) => Ok(json), + Err(e) => { + error!("Failed to deserialize JSON: {}", e); + error!("Response body: {}", response); + Err(Box::new(e)) + } + } + } + StatusCode::NOT_FOUND => { + info!("No packages found"); + Ok(PackageResponse{ + total: 0, + offset: 0, + limit: 0, + packages: vec![], + }) + } + StatusCode::INTERNAL_SERVER_ERROR => { + panic!("Internal Server Error"); + } + _ => { + let query_url = format!( + "{}{}{}", + API_BASE_URL, + API_PACKAGES_EXT, + self.query_string() + ); + panic!("Unexpected server response: {:?} for query url: {}", response, query_url); + } + } } } diff --git a/src/main.rs b/src/main.rs index 2c9a949..3231c4b 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,31 +1,29 @@ use alhp_api; -use std::process::Command; +use alpm::{Alpm}; use alhp_api::{PackageRequest, PackageStatus}; -fn pacman_query_installed_packages() -> Vec { - match Command::new("pacman").arg("-Qqn").output() { - Ok(packages) => String::from_utf8_lossy(&packages.stdout) - .lines() - .map(|s| s.to_string()) - .collect(), - _ => { - panic!("pacman query failed"); - } +fn query_installed_packages() { + let alpm = match Alpm::new("/", "/var/lib/pacman"){ + Ok(alpm) => alpm, + Err(_) => panic!("Error establishing ALPM handle."), + }; + let local_db= alpm.localdb(); + let server = local_db.servers(); + for s in server { + println!("{}", s); } } fn main() { - let installed_packages = pacman_query_installed_packages(); - println!("installed packages: {:?}", installed_packages); - let status = vec!(); let pkg = PackageRequest{ - status, - pkgbase: Some("go".to_string()), + status: vec![PackageStatus::Building, PackageStatus::Queued], + pkgbase: None, exact: true, repo: Some("extra-x86-64-v3".to_string()), offset: 0, limit: 0, }; let pkg = pkg.response().unwrap(); - println!("pkg: {:?}", pkg); + println!("{:#?}", pkg); + query_installed_packages(); }