mirror of
https://github.com/chatmail/core.git
synced 2026-04-28 10:56:29 +03:00
Add Quota to Connectivity View (#2612)
* add imap::get_quota_roots() * schedule quote-checking job on getting connectivity-html * get quota and debug print it * basic quota output * update quota at most once per minute, emit event on changes * use more meaningful names * add some comments, move update_recent_quota() to quota.rs * show root name only if there are several roots * make clippy happy, some refactorings * allow only one update-quota job per time * add now supported QUOTA to standards.md
This commit is contained in:
@@ -3,9 +3,14 @@ use std::{ops::Deref, sync::Arc};
|
||||
|
||||
use async_std::sync::{Mutex, RwLockReadGuard};
|
||||
|
||||
use crate::dc_tools::time;
|
||||
use crate::events::EventType;
|
||||
use crate::quota::{
|
||||
QUOTA_ERROR_THRESHOLD_PERCENTAGE, QUOTA_MAX_AGE_SECONDS, QUOTA_WARN_THRESHOLD_PERCENTAGE,
|
||||
};
|
||||
use crate::{config::Config, scheduler::Scheduler};
|
||||
use crate::{context::Context, log::LogExt};
|
||||
use humansize::{file_size_opts, FileSize};
|
||||
|
||||
#[derive(Debug, Clone, Copy, PartialEq, Eq, EnumProperty, PartialOrd, Ord)]
|
||||
pub enum Connectivity {
|
||||
@@ -403,6 +408,81 @@ impl Context {
|
||||
ret += &*escaper::encode_minimal(&detailed.to_string_smtp(self));
|
||||
ret += "</li></ul>";
|
||||
|
||||
ret += "<h3>Quota</h3><ul>";
|
||||
let quota = self.quota.read().await;
|
||||
if let Some(quota) = &*quota {
|
||||
match "a.recent {
|
||||
Ok(quota) => {
|
||||
let roots_cnt = quota.len();
|
||||
for (root_name, resources) in quota {
|
||||
use async_imap::types::QuotaResourceName::*;
|
||||
for resource in resources {
|
||||
ret += "<li>";
|
||||
|
||||
let usage_percent = resource.get_usage_percentage();
|
||||
if usage_percent >= QUOTA_ERROR_THRESHOLD_PERCENTAGE {
|
||||
ret += "<span class=\"red dot\"></span> ";
|
||||
} else if usage_percent >= QUOTA_WARN_THRESHOLD_PERCENTAGE {
|
||||
ret += "<span class=\"yellow dot\"></span> ";
|
||||
} else {
|
||||
ret += "<span class=\"green dot\"></span> ";
|
||||
}
|
||||
|
||||
// root name is empty eg. for gmail and redundant eg. for riseup.
|
||||
// therefore, use it only if there are really several roots.
|
||||
if roots_cnt > 1 && !root_name.is_empty() {
|
||||
ret +=
|
||||
&format!("<b>{}:</b> ", &*escaper::encode_minimal(root_name));
|
||||
} else {
|
||||
info!(self, "connectivity: root name hidden: \"{}\"", root_name);
|
||||
}
|
||||
|
||||
ret += &match &resource.name {
|
||||
Atom(resource_name) => {
|
||||
format!(
|
||||
"<b>{}:</b> {} of {} used",
|
||||
&*escaper::encode_minimal(resource_name),
|
||||
resource.usage.to_string(),
|
||||
resource.limit.to_string(),
|
||||
)
|
||||
}
|
||||
Message => {
|
||||
format!(
|
||||
"<b>Messages:</b> {} of {} used",
|
||||
resource.usage.to_string(),
|
||||
resource.limit.to_string(),
|
||||
)
|
||||
}
|
||||
Storage => {
|
||||
let usage = (resource.usage * 1024)
|
||||
.file_size(file_size_opts::BINARY)
|
||||
.unwrap_or_default();
|
||||
let limit = (resource.limit * 1024)
|
||||
.file_size(file_size_opts::BINARY)
|
||||
.unwrap_or_default();
|
||||
format!("<b>Storage:</b> {} of {} used", usage, limit)
|
||||
}
|
||||
};
|
||||
ret += &format!(" ({}%)", usage_percent);
|
||||
|
||||
ret += "</li>";
|
||||
}
|
||||
}
|
||||
}
|
||||
Err(e) => {
|
||||
ret += format!("<li>{}</li>", e).as_str();
|
||||
}
|
||||
}
|
||||
|
||||
if quota.modified + QUOTA_MAX_AGE_SECONDS < time() {
|
||||
self.schedule_quota_update().await;
|
||||
}
|
||||
} else {
|
||||
ret += "<li>One moment...</li>";
|
||||
self.schedule_quota_update().await;
|
||||
}
|
||||
ret += "</ul>";
|
||||
|
||||
ret += "</body></html>\n";
|
||||
ret
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user