add email_in_limit to store email address that send count less than
limit value
add email_out_limit to store email address that send count beyond limit
value
the email queues email_in_limit/email_out_limit will be reset everyday
at 00:00, every time send mail to an email address, the value for the
email address in email_in_limit will +1, until the value up to the
limited value, the email address will be moved to email_out_limit, and
the email send to the address will be throw away.
Signed-off-by: Luan Shengde <shdluan(a)163.com>
---
.../send-internet-mail/email_limit_queue.rb | 62 +++++++++++++++++++
1 file changed, 62 insertions(+)
create mode 100755 container/send-internet-mail/email_limit_queue.rb
diff --git a/container/send-internet-mail/email_limit_queue.rb b/container/send-internet-mail/email_limit_queue.rb
new file mode 100755
index 0000000..c7e3954
--- /dev/null
+++ b/container/send-internet-mail/email_limit_queue.rb
@@ -0,0 +1,62 @@
+#!/usr/bin/env ruby
+# SPDX-License-Identifier: MulanPSL-2.0+
+# Copyright (c) 2020 Huawei Technologies Co., Ltd. All rights reserved.
+# frozen_string_literal: true
+
+require 'json'
+require 'redis'
+
+# check if the emails count has beyond the limit.
+# email_in_limit is used to store email address email count
+# less than the limit value.
+# email_out_limit is used to store email address email count
+# beyond the limit.
+# case the email is the first one for the day, the email will
+# be add to email_in_limit with value 1.
+# case the email in email_in_limit but email count less than the
+# limit value, its value will +1.
+# case the email's email count up to the limit value, the email
+# will be moved to email_out_limit.
+# when the email is in email_out_limit, if send mail to the email
+# address, the email will be kicked out from the email address bar.
+class EmailRateLimit
+ def initialize(mail_info)
+ @mail_info = mail_info
+ @redis = Redis.new('host' => REDIS_HOST, 'port' => REDIS_PORT)
+ end
+
+ def check_email_counts
+ email_to = @mail_info['to'].clone
+ email_cc = @mail_info['cc'].clone
+ @mail_info['to'] = check_emails(email_to)
+ @mail_info['cc'] = check_emails(email_cc)
+
+ return @mail_info
+ end
+
+ def check_emails(mail_list)
+ return if mail_list.nil? || mail_list.empty?
+
+ mail_list.clone.each do |email|
+ if @redis.hexists 'email_out_limit', email
+ mail_list -= [email]
+ next
+ elsif @redis.hexists 'email_in_limit', email
+ email_account = @redis.hget 'email_in_limit', email
+ @redis.hset 'email_in_limit', email, email_account.to_i + 1
+ else
+ @redis.hset 'email_in_limit', email, 1
+ end
+
+ change_queue(email)
+ end
+ return mail_list
+ end
+
+ def change_queue(email)
+ return unless (@redis.hget 'email_in_limit', email).to_i >= 10
+
+ @redis.hdel 'email_in_limit', email
+ @redis.hset 'email_out_limit', email, 10
+ end
+end
--
2.23.0