From dd198747b79a48bd7ef86bc641a353a7ccd8877b Mon Sep 17 00:00:00 2001 From: andryyy Date: Fri, 19 Mar 2021 16:33:50 +0100 Subject: [PATCH] [Web] Use api/v1/get/mailbox/reduced for faster loading of mailbox table --- data/web/inc/functions.mailbox.inc.php | 97 +++++++++++++++----------- data/web/inc/init_db.inc.php | 5 +- data/web/js/site/mailbox.js | 8 ++- data/web/json_api.php | 3 +- 4 files changed, 65 insertions(+), 48 deletions(-) diff --git a/data/web/inc/functions.mailbox.inc.php b/data/web/inc/functions.mailbox.inc.php index dca40a75..ae9aeadf 100644 --- a/data/web/inc/functions.mailbox.inc.php +++ b/data/web/inc/functions.mailbox.inc.php @@ -997,7 +997,7 @@ function mailbox($_action, $_type, $_data = null, $_extra = null) { COUNT(*) as count, COALESCE(ROUND(SUM(`quota`)/1048576), 0) as `quota` FROM `mailbox` - WHERE `kind` NOT REGEXP 'location|thing|group' + WHERE (`kind` = '' OR `kind` = NULL) AND `domain` = :domain"); $stmt->execute(array(':domain' => $domain)); $MailboxData = $stmt->fetch(PDO::FETCH_ASSOC); @@ -2215,7 +2215,7 @@ function mailbox($_action, $_type, $_data = null, $_extra = null) { MAX(COALESCE(ROUND(`quota`/1048576), 0)) AS `biggest_mailbox`, COALESCE(ROUND(SUM(`quota`)/1048576), 0) AS `quota_all` FROM `mailbox` - WHERE `kind` NOT REGEXP 'location|thing|group' + WHERE (`kind` = '' OR `kind` = NULL) AND domain = :domain"); $stmt->execute(array(':domain' => $domain)); $MailboxData = $stmt->fetch(PDO::FETCH_ASSOC); @@ -2887,7 +2887,7 @@ function mailbox($_action, $_type, $_data = null, $_extra = null) { return false; } elseif (isset($_data) && hasDomainAccess($_SESSION['mailcow_cc_username'], $_SESSION['mailcow_cc_role'], $_data)) { - $stmt = $pdo->prepare("SELECT `username` FROM `mailbox` WHERE `kind` NOT REGEXP 'location|thing|group' AND `domain` = :domain"); + $stmt = $pdo->prepare("SELECT `username` FROM `mailbox` WHERE (`kind` = '' OR `kind` = NULL) AND `domain` = :domain"); $stmt->execute(array( ':domain' => $_data, )); @@ -2897,7 +2897,7 @@ function mailbox($_action, $_type, $_data = null, $_extra = null) { } } else { - $stmt = $pdo->prepare("SELECT `username` FROM `mailbox` WHERE `kind` NOT REGEXP 'location|thing|group' AND (`domain` IN (SELECT `domain` FROM `domain_admins` WHERE `active` = '1' AND `username` = :username) OR 'admin' = :role)"); + $stmt = $pdo->prepare("SELECT `username` FROM `mailbox` WHERE (`kind` = '' OR `kind` = NULL) AND (`domain` IN (SELECT `domain` FROM `domain_admins` WHERE `active` = '1' AND `username` = :username) OR 'admin' = :role)"); $stmt->execute(array( ':username' => $_SESSION['mailcow_cc_username'], ':role' => $_SESSION['mailcow_cc_role'], @@ -3432,10 +3432,10 @@ function mailbox($_action, $_type, $_data = null, $_extra = null) { if (empty($row)) { return false; } - $stmt = $pdo->prepare("SELECT COUNT(*) AS `count`, + $stmt = $pdo->prepare("SELECT COUNT(`username`) AS `count`, COALESCE(SUM(`quota`), 0) AS `in_use` FROM `mailbox` - WHERE `kind` NOT REGEXP 'location|thing|group' + WHERE (`kind` = '' OR `kind` = NULL) AND `domain` = :domain"); $stmt->execute(array(':domain' => $row['domain'])); $MailboxDataDomain = $stmt->fetch(PDO::FETCH_ASSOC); @@ -3491,7 +3491,7 @@ function mailbox($_action, $_type, $_data = null, $_extra = null) { $domaindata['relay_all_recipients_int'] = $row['relay_all_recipients']; $domaindata['relay_unknown_only'] = $row['relay_unknown_only']; $domaindata['relay_unknown_only_int'] = $row['relay_unknown_only']; - $stmt = $pdo->prepare("SELECT COUNT(*) AS `alias_count` FROM `alias` + $stmt = $pdo->prepare("SELECT COUNT(`address`) AS `alias_count` FROM `alias` WHERE (`domain`= :domain OR `domain` IN (SELECT `alias_domain` FROM `alias_domain` WHERE `target_domain` = :domain2)) AND `address` NOT IN ( SELECT `username` FROM `mailbox` @@ -3519,7 +3519,6 @@ function mailbox($_action, $_type, $_data = null, $_extra = null) { return false; } $mailboxdata = array(); - $rl = ratelimit('get', 'mailbox', $_data); $last_imap_login = $redis->Get('last-login/imap/' . $_data); $last_smtp_login = $redis->Get('last-login/smtp/' . $_data); $last_pop3_login = $redis->Get('last-login/pop3/' . $_data); @@ -3547,7 +3546,10 @@ function mailbox($_action, $_type, $_data = null, $_extra = null) { `attributes`, `quota2`.`messages` FROM `mailbox`, `quota2`, `domain` - WHERE `mailbox`.`kind` NOT REGEXP 'location|thing|group' AND `mailbox`.`username` = `quota2`.`username` AND `domain`.`domain` = `mailbox`.`domain` AND `mailbox`.`username` = :mailbox"); + WHERE (`mailbox`.`kind` = '' OR `mailbox`.`kind` = NULL) + AND `mailbox`.`username` = `quota2`.`username` + AND `domain`.`domain` = `mailbox`.`domain` + AND `mailbox`.`username` = :mailbox"); } else { $stmt = $pdo->prepare("SELECT @@ -3564,55 +3566,34 @@ function mailbox($_action, $_type, $_data = null, $_extra = null) { `attributes`, `quota2replica`.`messages` FROM `mailbox`, `quota2replica`, `domain` - WHERE `mailbox`.`kind` NOT REGEXP 'location|thing|group' AND `mailbox`.`username` = `quota2replica`.`username` AND `domain`.`domain` = `mailbox`.`domain` AND `mailbox`.`username` = :mailbox"); + WHERE (`mailbox`.`kind` = '' OR `mailbox`.`kind` = NULL) + AND `mailbox`.`username` = `quota2replica`.`username` + AND `domain`.`domain` = `mailbox`.`domain` + AND `mailbox`.`username` = :mailbox"); } $stmt->execute(array( ':mailbox' => $_data, )); $row = $stmt->fetch(PDO::FETCH_ASSOC); - $stmt = $pdo->prepare("SELECT `maxquota`, `quota` FROM `domain` WHERE `domain` = :domain"); - $stmt->execute(array(':domain' => $row['domain'])); - $DomainQuota = $stmt->fetch(PDO::FETCH_ASSOC); - $stmt = $pdo->prepare("SELECT IFNULL(COUNT(`active`), 0) AS `pushover_active` FROM `pushover` WHERE `username` = :username AND `active` = 1"); - $stmt->execute(array(':username' => $_data)); - $PushoverActive = $stmt->fetch(PDO::FETCH_ASSOC); - $stmt = $pdo->prepare("SELECT COALESCE(SUM(`quota`), 0) as `in_use` FROM `mailbox` WHERE `kind` NOT REGEXP 'location|thing|group' AND `domain` = :domain AND `username` != :username"); - $stmt->execute(array(':domain' => $row['domain'], ':username' => $_data)); - $MailboxUsage = $stmt->fetch(PDO::FETCH_ASSOC); - $stmt = $pdo->prepare("SELECT IFNULL(COUNT(`address`), 0) AS `sa_count` FROM `spamalias` WHERE `goto` = :address AND `validity` >= :unixnow"); - $stmt->execute(array(':address' => $_data, ':unixnow' => time())); - $SpamaliasUsage = $stmt->fetch(PDO::FETCH_ASSOC); - $mailboxdata['max_new_quota'] = ($DomainQuota['quota'] * 1048576) - $MailboxUsage['in_use']; - if ($mailboxdata['max_new_quota'] > ($DomainQuota['maxquota'] * 1048576)) { - $mailboxdata['max_new_quota'] = ($DomainQuota['maxquota'] * 1048576); - } + $mailboxdata['username'] = $row['username']; - if (!empty($rl)) { - $mailboxdata['rl'] = $rl; - $mailboxdata['rl_scope'] = 'mailbox'; - } - else { - $mailboxdata['rl'] = ratelimit('get', 'domain', $row['domain']); - $mailboxdata['rl_scope'] = 'domain'; - } - $mailboxdata['is_relayed'] = $row['backupmx']; - $mailboxdata['name'] = $row['name']; - $mailboxdata['last_imap_login'] = $last_imap_login; - $mailboxdata['last_smtp_login'] = $last_smtp_login; - $mailboxdata['last_pop3_login'] = $last_pop3_login; $mailboxdata['active'] = $row['active']; $mailboxdata['active_int'] = $row['active']; $mailboxdata['domain'] = $row['domain']; $mailboxdata['domain_xmpp'] = $row['domain_xmpp']; + $mailboxdata['name'] = $row['name']; $mailboxdata['domain_xmpp_prefix'] = $row['domain_xmpp_prefix']; $mailboxdata['local_part'] = $row['local_part']; $mailboxdata['quota'] = $row['quota']; + $mailboxdata['messages'] = $row['messages']; $mailboxdata['attributes'] = json_decode($row['attributes'], true); $mailboxdata['quota_used'] = intval($row['bytes']); $mailboxdata['percent_in_use'] = ($row['quota'] == 0) ? '- ' : round((intval($row['bytes']) / intval($row['quota'])) * 100); - $mailboxdata['messages'] = $row['messages']; - $mailboxdata['spam_aliases'] = $SpamaliasUsage['sa_count']; - $mailboxdata['pushover_active'] = ($PushoverActive['pushover_active'] == 1) ? 1 : 0; + + $mailboxdata['last_imap_login'] = $last_imap_login; + $mailboxdata['last_smtp_login'] = $last_smtp_login; + $mailboxdata['last_pop3_login'] = $last_pop3_login; + if ($mailboxdata['percent_in_use'] === '- ') { $mailboxdata['percent_class'] = "info"; } @@ -3625,6 +3606,38 @@ function mailbox($_action, $_type, $_data = null, $_extra = null) { else { $mailboxdata['percent_class'] = "success"; } + + if (!isset($_extra) || $_extra != 'reduced') { + $rl = ratelimit('get', 'mailbox', $_data); + $stmt = $pdo->prepare("SELECT `maxquota`, `quota` FROM `domain` WHERE `domain` = :domain"); + $stmt->execute(array(':domain' => $row['domain'])); + $DomainQuota = $stmt->fetch(PDO::FETCH_ASSOC); + $stmt = $pdo->prepare("SELECT IFNULL(COUNT(`active`), 0) AS `pushover_active` FROM `pushover` WHERE `username` = :username AND `active` = 1"); + $stmt->execute(array(':username' => $_data)); + $PushoverActive = $stmt->fetch(PDO::FETCH_ASSOC); + $stmt = $pdo->prepare("SELECT COALESCE(SUM(`quota`), 0) as `in_use` FROM `mailbox` WHERE (`kind` = '' OR `kind` = NULL) AND `domain` = :domain AND `username` != :username"); + $stmt->execute(array(':domain' => $row['domain'], ':username' => $_data)); + $MailboxUsage = $stmt->fetch(PDO::FETCH_ASSOC); + $stmt = $pdo->prepare("SELECT IFNULL(COUNT(`address`), 0) AS `sa_count` FROM `spamalias` WHERE `goto` = :address AND `validity` >= :unixnow"); + $stmt->execute(array(':address' => $_data, ':unixnow' => time())); + $SpamaliasUsage = $stmt->fetch(PDO::FETCH_ASSOC); + $mailboxdata['max_new_quota'] = ($DomainQuota['quota'] * 1048576) - $MailboxUsage['in_use']; + $mailboxdata['spam_aliases'] = $SpamaliasUsage['sa_count']; + $mailboxdata['pushover_active'] = ($PushoverActive['pushover_active'] == 1) ? 1 : 0; + if ($mailboxdata['max_new_quota'] > ($DomainQuota['maxquota'] * 1048576)) { + $mailboxdata['max_new_quota'] = ($DomainQuota['maxquota'] * 1048576); + } + if (!empty($rl)) { + $mailboxdata['rl'] = $rl; + $mailboxdata['rl_scope'] = 'mailbox'; + } + else { + $mailboxdata['rl'] = ratelimit('get', 'domain', $row['domain']); + $mailboxdata['rl_scope'] = 'domain'; + } + $mailboxdata['is_relayed'] = $row['backupmx']; + } + return $mailboxdata; break; case 'resource_details': diff --git a/data/web/inc/init_db.inc.php b/data/web/inc/init_db.inc.php index 6a6e958c..85e907c2 100644 --- a/data/web/inc/init_db.inc.php +++ b/data/web/inc/init_db.inc.php @@ -3,7 +3,7 @@ function init_db_schema() { try { global $pdo; - $db_version = "08022021_1000"; + $db_version = "09032021_1000"; $stmt = $pdo->query("SHOW TABLES LIKE 'versions'"); $num_results = count($stmt->fetchAll(PDO::FETCH_ASSOC)); @@ -321,7 +321,8 @@ function init_db_schema() { "" => array("username") ), "key" => array( - "domain" => array("domain") + "domain" => array("domain"), + "kind" => array("kind") ) ), "attr" => "ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 ROW_FORMAT=DYNAMIC" diff --git a/data/web/js/site/mailbox.js b/data/web/js/site/mailbox.js index 6f1cb8d5..7686bc42 100644 --- a/data/web/js/site/mailbox.js +++ b/data/web/js/site/mailbox.js @@ -354,7 +354,7 @@ jQuery(function($){ return Number(res[0]); }, }, - {"name":"spam_aliases","filterable": false,"title":lang.spam_aliases,"breakpoints":"all"}, + /* {"name":"spam_aliases","filterable": false,"title":lang.spam_aliases,"breakpoints":"all"}, */ {"name":"tls_enforce_in","filterable": false,"title":lang.tls_enforce_in,"breakpoints":"all"}, {"name":"tls_enforce_out","filterable": false,"title":lang.tls_enforce_out,"breakpoints":"all"}, {"name":"smtp_access","filterable": false,"title":"SMTP","breakpoints":"all"}, @@ -378,14 +378,14 @@ jQuery(function($){ }, }, {"name":"messages","filterable": false,"title":lang.msg_num,"breakpoints":"xs sm md"}, - {"name":"rl","title":"RL","breakpoints":"all","style":{"width":"125px"}}, + /* {"name":"rl","title":"RL","breakpoints":"all","style":{"width":"125px"}}, */ {"name":"active","filterable": false,"style":{"maxWidth":"80px","width":"80px"},"title":lang.active,"formatter": function(value){return 1==value?'✓':(0==value?'✕':2==value&&'—');}}, {"name":"action","filterable": false,"sortable": false,"style":{"min-width":"290px","text-align":"right"},"type":"html","title":lang.action,"breakpoints":"xs sm md"} ], "empty": lang.empty, "rows": $.ajax({ dataType: 'json', - url: '/api/v1/get/mailbox/all', + url: '/api/v1/get/mailbox/reduced', jsonp: false, error: function () { console.log('Cannot draw mailbox table'); @@ -395,6 +395,7 @@ jQuery(function($){ item.quota = item.quota_used + "/" + item.quota; item.max_quota_for_mbox = humanFileSize(item.max_quota_for_mbox); item.last_mail_login = item.last_imap_login + '/' + item.last_pop3_login + '/' + item.last_smtp_login; + /* if (!item.rl) { item.rl = '∞'; } else { @@ -405,6 +406,7 @@ jQuery(function($){ item.rl = '↪ ' + item.rl + ' (via ' + item.domain + ')'; } } + */ item.chkbox = ''; item.tls_enforce_in = ''; item.tls_enforce_out = ''; diff --git a/data/web/json_api.php b/data/web/json_api.php index e199511a..55b69ffa 100644 --- a/data/web/json_api.php +++ b/data/web/json_api.php @@ -841,6 +841,7 @@ if (isset($_GET['query'])) { case "mailbox": switch ($object) { case "all": + case "reduced": if (empty($extra)) { $domains = mailbox('get', 'domains'); } @@ -852,7 +853,7 @@ if (isset($_GET['query'])) { $mailboxes = mailbox('get', 'mailboxes', $domain); if (!empty($mailboxes)) { foreach ($mailboxes as $mailbox) { - if ($details = mailbox('get', 'mailbox_details', $mailbox)) { + if ($details = mailbox('get', 'mailbox_details', $mailbox, $object)) { $data[] = $details; } else {