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