feat: document storage size

This commit is contained in:
Zack Fu Zi Xiang 2024-03-14 17:32:30 +08:00
parent d7cd101c44
commit 9093363b4f
No known key found for this signature in database
6 changed files with 69 additions and 14 deletions

View File

@ -1,8 +1,8 @@
use database_entity::dto::AFWorkspace;
use super::entities::{
JsonResponse, UserUsageLimit, WorkspaceBlobUsage, WorkspaceMember, WorkspaceUsage,
WorkspaceUsageLimit,
JsonResponse, UserUsageLimit, WorkspaceBlobUsage, WorkspaceDocUsage, WorkspaceMember,
WorkspaceUsageLimit, WorkspaceUsageLimits,
};
pub async fn get_user_workspace_count(auth_header: &str, appflowy_cloud_base_url: &str) -> u32 {
@ -68,24 +68,35 @@ pub async fn get_user_workspace_usages(
auth_header: &str,
appflowy_cloud_base_url: &str,
appflowy_cloud_gateway_base_url: &str,
) -> Vec<WorkspaceUsage> {
) -> Vec<WorkspaceUsageLimits> {
let user_workspaces = get_user_workspaces(auth_header, appflowy_cloud_base_url).await;
let mut workspace_usages: Vec<WorkspaceUsage> = Vec::with_capacity(user_workspaces.len());
let mut workspace_usages: Vec<WorkspaceUsageLimits> = Vec::with_capacity(user_workspaces.len());
for user_workspace in user_workspaces {
let workspace_id = user_workspace.workspace_id.to_string();
let members =
get_user_workspace_members(&workspace_id, auth_header, appflowy_cloud_base_url).await;
let workspace_limits =
get_user_workspace_limits(&workspace_id, auth_header, appflowy_cloud_gateway_base_url).await;
let blob_usage =
let total_blob_size =
get_user_workspace_blob_usage(&workspace_id, auth_header, appflowy_cloud_base_url)
.await
.map(|u| u.consumed_capacity)
.map(|u| human_bytes::human_bytes(u.consumed_capacity as f64))
.unwrap_or_else(|err| {
tracing::error!("Error getting user workspace blob usage: {:?}", err);
0
"0".to_owned()
});
let total_doc_size = {
get_user_workspace_doc_usage(&workspace_id, auth_header, appflowy_cloud_base_url)
.await
.map(|u| human_bytes::human_bytes(u.total_document_size as f64))
.unwrap_or_else(|err| {
tracing::error!("Error getting user workspace doc usage: {:?}", err);
"0".to_owned()
})
};
let (member_limit, total_blob_limit) = match workspace_limits {
Some(limit) => (
limit.member_count.to_string(),
@ -94,12 +105,12 @@ pub async fn get_user_workspace_usages(
None => ("N/A".to_string(), "N/A".to_string()),
};
workspace_usages.push(WorkspaceUsage {
workspace_usages.push(WorkspaceUsageLimits {
name: user_workspace.workspace_name,
member_count: members.len(),
member_limit,
total_doc_size: "WIP".to_string(),
total_blob_size: human_bytes::human_bytes(blob_usage as f64),
total_doc_size,
total_blob_size,
total_blob_limit,
});
}
@ -189,3 +200,23 @@ async fn get_user_workspace_blob_usage(
let res = resp.json::<JsonResponse<WorkspaceBlobUsage>>().await?;
Ok(res.data)
}
async fn get_user_workspace_doc_usage(
workspace_id: &str,
auth_header: &str,
appflowy_cloud_base_url: &str,
) -> Result<WorkspaceDocUsage, reqwest::Error> {
let http_client = reqwest::Client::new();
let url = format!(
"{}/api/workspace/{}/usage",
appflowy_cloud_base_url, workspace_id
);
let resp = http_client
.get(url)
.header("Authorization", format!("Bearer {}", auth_header))
.send()
.await?;
let res = resp.json::<JsonResponse<WorkspaceDocUsage>>().await?;
Ok(res.data)
}

View File

@ -12,7 +12,7 @@ pub struct UserUsageLimit {
}
#[derive(Serialize)]
pub struct WorkspaceUsage {
pub struct WorkspaceUsageLimits {
pub name: String,
pub member_count: usize,
pub member_limit: String,
@ -39,3 +39,8 @@ pub struct WorkspaceUsageLimit {
pub struct WorkspaceBlobUsage {
pub consumed_capacity: u64,
}
#[derive(Deserialize)]
pub struct WorkspaceDocUsage {
pub total_document_size: i64,
}

View File

@ -1,7 +1,7 @@
use askama::Template;
use gotrue_entity::{dto::User, sso::SSOProvider};
use crate::ext::entities::WorkspaceUsage;
use crate::ext::entities::WorkspaceUsageLimits;
#[derive(Template)]
#[template(path = "components/user_usage.html")]
@ -14,7 +14,7 @@ pub struct UserUsage {
#[derive(Template)]
#[template(path = "components/workspace_usage.html")]
pub struct WorkspaceUsageList {
pub workspace_usages: Vec<WorkspaceUsage>,
pub workspace_usages: Vec<WorkspaceUsageLimits>,
}
#[derive(Template)]

View File

@ -2,7 +2,7 @@ use crate::error::WebAppError;
use crate::ext::api::{
get_user_workspace_count, get_user_workspace_limit, get_user_workspace_usages,
};
use crate::ext::entities::WorkspaceUsage;
use crate::ext::entities::WorkspaceUsageLimits;
use crate::session::UserSession;
use askama::Template;
use axum::extract::{Path, State};

View File

@ -258,6 +258,11 @@ pub enum QueryCollabResult {
#[derive(Serialize, Deserialize)]
pub struct BatchQueryCollabResult(pub HashMap<String, QueryCollabResult>);
#[derive(Serialize, Deserialize)]
pub struct WorkspaceUsage {
pub total_document_size: i64,
}
#[derive(Debug, Clone, Validate, Serialize, Deserialize)]
pub struct InsertCollabMemberParams {
pub uid: i64,

View File

@ -101,6 +101,9 @@ pub fn workspace_scope() -> Scope {
.app_data(PayloadConfig::new(10 * 1024 * 1024))
.route(web::post().to(create_collab_list_handler)),
)
.service(
web::resource("/{workspace_id}/usage").route(web::get().to(get_workspace_usage_handler)),
)
.service(
web::resource("/{workspace_id}/{object_id}/snapshot")
.route(web::get().to(get_collab_snapshot_handler))
@ -841,6 +844,17 @@ async fn post_realtime_message_stream_handler(
Err(AppError::Internal(anyhow!("Failed to send message to websocket server")).into())
}
async fn get_workspace_usage_handler(
user_uuid: UserUuid,
workspace_id: web::Path<Uuid>,
state: Data<AppState>,
) -> Result<Json<AppResponse<WorkspaceUsage>>> {
let res = WorkspaceUsage {
total_document_size: 19978, // TODO
};
Ok(Json(AppResponse::Ok().with_data(res)))
}
#[inline]
async fn parser_realtime_msg(
payload: Bytes,