add endpoint for general stats
load build data to graph redesign top info tiles place add button on header folder restructure
This commit is contained in:
@ -1,9 +1,10 @@
|
||||
use crate::api::add::okapi_add_operation_for_package_add_;
|
||||
use crate::api::add::package_add;
|
||||
use crate::api::list::okapi_add_operation_for_build_output_;
|
||||
use crate::api::list::okapi_add_operation_for_list_builds_;
|
||||
use crate::api::list::okapi_add_operation_for_stats_;
|
||||
use crate::api::list::{build_output, okapi_add_operation_for_package_list_};
|
||||
use crate::api::list::{list_builds, okapi_add_operation_for_search_};
|
||||
use crate::api::list::{okapi_add_operation_for_build_output_, stats};
|
||||
use crate::api::list::{package_list, search};
|
||||
use crate::api::remove::okapi_add_operation_for_package_del_;
|
||||
use crate::api::remove::okapi_add_operation_for_version_del_;
|
||||
@ -20,5 +21,6 @@ pub fn build_api() -> Vec<Route> {
|
||||
version_del,
|
||||
build_output,
|
||||
list_builds,
|
||||
stats
|
||||
]
|
||||
}
|
||||
|
@ -2,14 +2,18 @@ use crate::aur::aur::query_aur;
|
||||
use crate::db::migration::JoinType;
|
||||
use crate::db::prelude::{Builds, Packages};
|
||||
use crate::db::{builds, packages, versions};
|
||||
use crate::utils::dir_size::dir_size;
|
||||
use rocket::response::status::NotFound;
|
||||
use rocket::serde::json::Json;
|
||||
use rocket::serde::{Deserialize, Serialize};
|
||||
use rocket::{get, State};
|
||||
use rocket_okapi::okapi::schemars;
|
||||
use rocket_okapi::{openapi, JsonSchema};
|
||||
use sea_orm::PaginatorTrait;
|
||||
use sea_orm::{ColumnTrait, QueryFilter};
|
||||
use sea_orm::{DatabaseConnection, EntityTrait, FromQueryResult, QuerySelect, RelationTrait};
|
||||
use std::path::PathBuf;
|
||||
use std::{fs, io};
|
||||
|
||||
#[derive(Serialize, JsonSchema)]
|
||||
#[serde(crate = "rocket::serde")]
|
||||
@ -149,3 +153,65 @@ pub async fn list_builds(
|
||||
|
||||
Ok(Json(build))
|
||||
}
|
||||
|
||||
#[derive(FromQueryResult, Deserialize, JsonSchema, Serialize)]
|
||||
#[serde(crate = "rocket::serde")]
|
||||
pub struct ListStats {
|
||||
total_builds: u32,
|
||||
failed_builds: u32,
|
||||
avg_queue_wait_time: u32,
|
||||
avg_build_time: u32,
|
||||
repo_storage_size: u32,
|
||||
active_builds: u32,
|
||||
total_packages: u32,
|
||||
}
|
||||
|
||||
#[openapi(tag = "test")]
|
||||
#[get("/stats")]
|
||||
pub async fn stats(db: &State<DatabaseConnection>) -> Result<Json<ListStats>, NotFound<String>> {
|
||||
let db = db as &DatabaseConnection;
|
||||
|
||||
return match get_stats(db).await {
|
||||
Ok(v) => Ok(Json(v)),
|
||||
Err(e) => Err(NotFound(e.to_string())),
|
||||
};
|
||||
}
|
||||
|
||||
async fn get_stats(db: &DatabaseConnection) -> anyhow::Result<ListStats> {
|
||||
// Count total builds
|
||||
let total_builds: u32 = Builds::find().count(db).await?.try_into()?;
|
||||
|
||||
// Count failed builds
|
||||
let failed_builds: u32 = Builds::find()
|
||||
.filter(builds::Column::Status.eq(2))
|
||||
.count(db)
|
||||
.await?
|
||||
.try_into()?;
|
||||
|
||||
// todo implement this values somehow
|
||||
let avg_queue_wait_time: u32 = 42;
|
||||
let avg_build_time: u32 = 42;
|
||||
|
||||
// Calculate repo storage size
|
||||
let repo_storage_size: u32 = dir_size("repo/").unwrap_or(0).try_into()?;
|
||||
|
||||
// Count active builds
|
||||
let active_builds: u32 = Builds::find()
|
||||
.filter(builds::Column::Status.eq(0))
|
||||
.count(db)
|
||||
.await?
|
||||
.try_into()?;
|
||||
|
||||
// Count total packages
|
||||
let total_packages: u32 = Packages::find().count(db).await?.try_into()?;
|
||||
|
||||
Ok(ListStats {
|
||||
total_builds,
|
||||
failed_builds,
|
||||
avg_queue_wait_time,
|
||||
avg_build_time,
|
||||
repo_storage_size,
|
||||
active_builds,
|
||||
total_packages,
|
||||
})
|
||||
}
|
||||
|
@ -4,6 +4,7 @@ mod builder;
|
||||
mod db;
|
||||
mod pkgbuild;
|
||||
mod repo;
|
||||
mod utils;
|
||||
|
||||
use crate::api::backend;
|
||||
#[cfg(feature = "static")]
|
||||
|
17
backend/src/utils/dir_size.rs
Normal file
17
backend/src/utils/dir_size.rs
Normal file
@ -0,0 +1,17 @@
|
||||
use std::path::PathBuf;
|
||||
use std::{fs, io};
|
||||
|
||||
pub fn dir_size(path: impl Into<PathBuf>) -> io::Result<u64> {
|
||||
fn dir_size(mut dir: fs::ReadDir) -> io::Result<u64> {
|
||||
dir.try_fold(0, |acc, file| {
|
||||
let file = file?;
|
||||
let size = match file.metadata()? {
|
||||
data if data.is_dir() => dir_size(fs::read_dir(file.path())?)?,
|
||||
data => data.len(),
|
||||
};
|
||||
Ok(acc + size)
|
||||
})
|
||||
}
|
||||
|
||||
dir_size(fs::read_dir(path.into())?)
|
||||
}
|
1
backend/src/utils/mod.rs
Normal file
1
backend/src/utils/mod.rs
Normal file
@ -0,0 +1 @@
|
||||
pub mod dir_size;
|
Reference in New Issue
Block a user