ses-proxy 0.1.1 → 0.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/app/views/_search_form.haml +4 -3
- data/app/views/layout.haml +2 -0
- data/app/views/mails.haml +2 -1
- data/app/web_panel.rb +98 -19
- data/lib/ses_proxy/models/bounced_email.rb +15 -0
- data/lib/ses_proxy/models/recipients_number.rb +12 -0
- data/lib/ses_proxy/smtp_server.rb +25 -3
- data/ses_proxy.rb +2 -0
- metadata +3 -1
data/app/views/_search_form.haml
CHANGED
@@ -1,9 +1,10 @@
|
|
1
1
|
%form.form-horizontal(data-ajax-url="#{@chart_url}" data-chart="chartdiv")
|
2
2
|
%fieldset(style="text-align: left")
|
3
3
|
%legend Search:
|
4
|
-
|
5
|
-
%
|
6
|
-
|
4
|
+
-if @menu_item.eql? "mails" or @menu_item.eql? "bounced_mails"
|
5
|
+
%div(style="display: inline-block;vertical-align: middle;")
|
6
|
+
%label Text
|
7
|
+
%input.span4(type="text" name="q" value="#{@q}" placeholder="Type something…")
|
7
8
|
%div.input-append.date(data-date="#{@s||Time.now.strftime('%d/%m/%Y')}" data-date-format="dd-mm-yyyy")
|
8
9
|
%label From
|
9
10
|
%input.span2(size="16" type="text" name="s" value="#{@s}" placeholder="dd-mm-yyyy")
|
data/app/views/layout.haml
CHANGED
@@ -15,6 +15,8 @@
|
|
15
15
|
%ul.nav.nav-pills
|
16
16
|
%li{:class => ('active' if @menu_item.eql? "mails")}
|
17
17
|
%a(href="/") Sent Emails
|
18
|
+
%li{:class => ('active' if @menu_item.eql? "bounced_mails")}
|
19
|
+
%a(href="/bounced_mails") Bounced Emails
|
18
20
|
%li{:class => ('active' if @menu_item.eql? "bounces")}
|
19
21
|
%a(href="/bounces") Bounced Addresses
|
20
22
|
= yield
|
data/app/views/mails.haml
CHANGED
data/app/web_panel.rb
CHANGED
@@ -39,6 +39,7 @@ get '/' do
|
|
39
39
|
protected!
|
40
40
|
@menu_item = "mails"
|
41
41
|
@chart_url = "/mails.json"
|
42
|
+
@page_title = "Sent Emails"
|
42
43
|
@per = params[:per] || 20
|
43
44
|
mails = mails_query
|
44
45
|
@mails = mails.page(params[:page]).per(@per)
|
@@ -49,7 +50,55 @@ get '/mails.json' do
|
|
49
50
|
protected!
|
50
51
|
mails = mails_query
|
51
52
|
d_array = (string_to_date(@s)..string_to_date(@e)).to_a
|
52
|
-
|
53
|
+
recipients_number = SesProxy::RecipientsNumber.where(:created_at=>{'$gte' => string_to_date(@s),'$lte' => string_to_date(@e)+1.day})
|
54
|
+
data = {}
|
55
|
+
grouped_collection = {}
|
56
|
+
filtered_rate_collection = {}
|
57
|
+
key_format = get_key_format d_array
|
58
|
+
data[:x] = make_formatted_array d_array, key_format
|
59
|
+
data[:y] ||= []
|
60
|
+
data[:x].each do |d|
|
61
|
+
grouped_collection[d] = mails.collect{|b| b if b.created_at.strftime(key_format).eql? d}.compact.size
|
62
|
+
filtered_rate_collection[d] = recipients_number.collect{|b| b.filtered if b.created_at.strftime(key_format).eql? d}.compact.sum.to_f
|
63
|
+
end
|
64
|
+
data[:y] << {:name=>"Mails",:data=>grouped_collection.values}
|
65
|
+
data[:y] << {:name=>"Sents",:data=>filtered_rate_collection.values}
|
66
|
+
|
67
|
+
content_type :json
|
68
|
+
data.to_json
|
69
|
+
end
|
70
|
+
|
71
|
+
get '/bounced_mails' do
|
72
|
+
protected!
|
73
|
+
@menu_item = "bounced_mails"
|
74
|
+
@chart_url = "/bounced_mails.json"
|
75
|
+
@page_title = "Bounced Emails"
|
76
|
+
@per = params[:per] || 20
|
77
|
+
mails = bounced_mails_query
|
78
|
+
@mails = mails.page(params[:page]).per(@per)
|
79
|
+
haml :mails
|
80
|
+
end
|
81
|
+
|
82
|
+
get '/bounced_mails.json' do
|
83
|
+
protected!
|
84
|
+
mails = bounced_mails_query
|
85
|
+
d_array = (string_to_date(@s)..string_to_date(@e)).to_a
|
86
|
+
recipients_number = SesProxy::RecipientsNumber.where(:created_at=>{'$gte' => string_to_date(@s),'$lte' => string_to_date(@e)+1.day})
|
87
|
+
data = {}
|
88
|
+
grouped_collection = {}
|
89
|
+
bounced_rate_collection = {}
|
90
|
+
key_format = get_key_format d_array
|
91
|
+
data[:x] = make_formatted_array d_array, key_format
|
92
|
+
data[:y] ||= []
|
93
|
+
data[:x].each do |d|
|
94
|
+
grouped_collection[d] = mails.collect{|b| b if b.created_at.strftime(key_format).eql? d}.compact.size
|
95
|
+
original_size = recipients_number.collect{|b| b.original if b.created_at.strftime(key_format).eql? d}.compact.sum.to_f
|
96
|
+
filtered_size = recipients_number.collect{|b| b.filtered if b.created_at.strftime(key_format).eql? d}.compact.sum.to_f
|
97
|
+
bounced_rate_collection[d] = original_size - filtered_size
|
98
|
+
end
|
99
|
+
data[:y] << {:name=>"Mails",:data=>grouped_collection.values}
|
100
|
+
data[:y] << {:name=>"Bounced Sents",:data=>bounced_rate_collection.values}
|
101
|
+
|
53
102
|
content_type :json
|
54
103
|
data.to_json
|
55
104
|
end
|
@@ -67,17 +116,39 @@ end
|
|
67
116
|
get '/bounces.json' do
|
68
117
|
protected!
|
69
118
|
bounces = bounces_query
|
119
|
+
recipients_number = SesProxy::RecipientsNumber.where(:created_at=>{'$gte' => string_to_date(@s),'$lte' => string_to_date(@e)+1.day})
|
70
120
|
d_array = (string_to_date(@s)..string_to_date(@e)).to_a
|
71
|
-
data =
|
121
|
+
data = {}
|
122
|
+
original_rate_collection = {}
|
123
|
+
filtered_rate_collection = {}
|
124
|
+
key_format = get_key_format d_array
|
125
|
+
data[:x] = make_formatted_array d_array, key_format
|
126
|
+
data[:y] ||= []
|
127
|
+
data[:x].each do |d|
|
128
|
+
bounces_size = bounces.collect{|b| b if b.created_at.strftime(key_format).eql? d}.compact.size.to_f
|
129
|
+
original_size = recipients_number.collect{|b| b.original if b.created_at.strftime(key_format).eql? d}.compact.sum.to_f
|
130
|
+
filtered_size = recipients_number.collect{|b| b.filtered if b.created_at.strftime(key_format).eql? d}.compact.sum.to_f
|
131
|
+
if original_size > 0
|
132
|
+
original_rate_collection[d] = (((bounces_size.to_f + original_size - filtered_size) / original_size) * 100).round(2)
|
133
|
+
else
|
134
|
+
original_rate_collection[d] = 0
|
135
|
+
end
|
136
|
+
if filtered_size > 0
|
137
|
+
filtered_rate_collection[d] = ((bounces_size.to_f / filtered_size) * 100).round(2)
|
138
|
+
else
|
139
|
+
filtered_rate_collection[d] = 0
|
140
|
+
end
|
141
|
+
end
|
142
|
+
data[:y] << {:name=>"Original Rate (%)",:data=>original_rate_collection.values}
|
143
|
+
data[:y] << {:name=>"Filtered Rate (%)",:data=>filtered_rate_collection.values}
|
144
|
+
|
72
145
|
content_type :json
|
73
146
|
data.to_json
|
74
147
|
end
|
75
148
|
|
76
149
|
private
|
77
150
|
|
78
|
-
def
|
79
|
-
data = {}
|
80
|
-
grouped_collection = {}
|
151
|
+
def get_key_format(d_array)
|
81
152
|
if d_array.size <= 30
|
82
153
|
#days
|
83
154
|
key_format = "%d/%m/%Y"
|
@@ -88,13 +159,11 @@ def get_data_json(name, collection, method, d_array)
|
|
88
159
|
#months
|
89
160
|
key_format = "%B/%Y"
|
90
161
|
end
|
91
|
-
|
92
|
-
|
93
|
-
|
94
|
-
|
95
|
-
|
96
|
-
data[:y] << {:name=>name,:data=>grouped_collection.values}
|
97
|
-
data
|
162
|
+
key_format
|
163
|
+
end
|
164
|
+
|
165
|
+
def make_formatted_array(d_array, key_format)
|
166
|
+
return d_array.map{|d| d.to_date.strftime(key_format)}.uniq
|
98
167
|
end
|
99
168
|
|
100
169
|
def mails_query
|
@@ -103,36 +172,46 @@ def mails_query
|
|
103
172
|
@e = params[:e]||Date.today.strftime("%d-%m-%Y")
|
104
173
|
if @q.nil? or @q.eql?""
|
105
174
|
if valid_date(@s) and valid_date(@e)
|
106
|
-
mails = SesProxy::Email.where(:created_at=>{'$gte' => string_to_date(@s),'$
|
175
|
+
mails = SesProxy::Email.where(:created_at=>{'$gte' => string_to_date(@s),'$lte' => string_to_date(@e)+1.day})
|
107
176
|
else
|
108
177
|
mails = SesProxy::Email.all
|
109
178
|
end
|
110
179
|
else
|
111
180
|
if valid_date(@s) and valid_date(@e)
|
112
|
-
mails = SesProxy::Email.where(:created_at=>{'$gte' => string_to_date(@s),'$
|
181
|
+
mails = SesProxy::Email.where(:created_at=>{'$gte' => string_to_date(@s),'$lte' => string_to_date(@e)+1.day}).any_of({:recipients => /.*#{@q}.*/i },{:sender => /.*#{@q}.*/i },{:system => /.*#{@q}.*/i },{:subject => /.*#{@q}.*/i })
|
113
182
|
else
|
114
183
|
mails = SesProxy::Email.any_of({:recipients => /.*#{@q}.*/i },{:sender => /.*#{@q}.*/i },{:system => /.*#{@q}.*/i },{:subject => /.*#{@q}.*/i }).page(params[:page]).per(20)
|
115
184
|
end
|
116
185
|
end
|
117
186
|
end
|
118
187
|
|
119
|
-
def
|
188
|
+
def bounced_mails_query
|
120
189
|
@q = params[:q]
|
121
190
|
@s = params[:s]||(Date.today-1.month).strftime("%d-%m-%Y")
|
122
191
|
@e = params[:e]||Date.today.strftime("%d-%m-%Y")
|
123
192
|
if @q.nil? or @q.eql?""
|
124
193
|
if valid_date(@s) and valid_date(@e)
|
125
|
-
|
194
|
+
mails = SesProxy::BouncedEmail.where(:created_at=>{'$gte' => string_to_date(@s),'$lte' => string_to_date(@e)+1.day})
|
126
195
|
else
|
127
|
-
|
196
|
+
mails = SesProxy::BouncedEmail.all
|
128
197
|
end
|
129
198
|
else
|
130
199
|
if valid_date(@s) and valid_date(@e)
|
131
|
-
|
200
|
+
mails = SesProxy::BouncedEmail.where(:created_at=>{'$gte' => string_to_date(@s),'$lte' => string_to_date(@e)+1.day}).any_of({:recipients => /.*#{@q}.*/i },{:sender => /.*#{@q}.*/i },{:system => /.*#{@q}.*/i },{:subject => /.*#{@q}.*/i })
|
132
201
|
else
|
133
|
-
|
202
|
+
mails = SesProxy::BouncedEmail.any_of({:recipients => /.*#{@q}.*/i },{:sender => /.*#{@q}.*/i },{:system => /.*#{@q}.*/i },{:subject => /.*#{@q}.*/i }).page(params[:page]).per(20)
|
134
203
|
end
|
135
204
|
end
|
205
|
+
end
|
206
|
+
|
207
|
+
def bounces_query
|
208
|
+
@s = params[:s]||(Date.today-1.month).strftime("%d-%m-%Y")
|
209
|
+
@e = params[:e]||Date.today.strftime("%d-%m-%Y")
|
210
|
+
if valid_date(@s) and valid_date(@e)
|
211
|
+
bounces = SesProxy::Bounce.where(:created_at=>{'$gte' => string_to_date(@s),'$lte' => string_to_date(@e)+1.day})
|
212
|
+
else
|
213
|
+
bounces = SesProxy::Bounce.all
|
214
|
+
end
|
136
215
|
bounces
|
137
216
|
end
|
138
217
|
|
@@ -0,0 +1,15 @@
|
|
1
|
+
require 'mongoid'
|
2
|
+
|
3
|
+
module SesProxy
|
4
|
+
class BouncedEmail
|
5
|
+
include Mongoid::Document
|
6
|
+
|
7
|
+
field :sender, type: String
|
8
|
+
field :recipients, type: String
|
9
|
+
field :subject, type: String
|
10
|
+
field :body, type: String
|
11
|
+
field :system, type: String
|
12
|
+
field :created_at, type: DateTime
|
13
|
+
field :updated_at, type: DateTime
|
14
|
+
end
|
15
|
+
end
|
@@ -69,6 +69,15 @@ module SesProxy
|
|
69
69
|
actual_recipients = recipients - bounced
|
70
70
|
actual_cc_addrs = mail.cc_addrs - bounced
|
71
71
|
actual_bcc_addrs = mail.bcc_addrs - bounced
|
72
|
+
original_number = recipients.size+mail.cc_addrs.size+mail.bcc_addrs.size
|
73
|
+
filtered_number = actual_recipients.size+actual_cc_addrs.size+actual_bcc_addrs.size
|
74
|
+
record = RecipientsNumber.new({
|
75
|
+
:original=>original_number,
|
76
|
+
:filtered=>filtered_number,
|
77
|
+
:created_at => Time.now,
|
78
|
+
:updated_at => Time.now
|
79
|
+
})
|
80
|
+
record.save!
|
72
81
|
if actual_recipients.any?
|
73
82
|
mail.to = actual_recipients.uniq.join(",")
|
74
83
|
mail.cc = actual_cc_addrs.uniq.join(",")
|
@@ -85,15 +94,28 @@ module SesProxy
|
|
85
94
|
record.save!
|
86
95
|
begin
|
87
96
|
ses.send_raw_email(mail.to_s)
|
88
|
-
true
|
89
97
|
rescue Exception => e
|
90
98
|
print "Error! "
|
91
99
|
puts e.message
|
92
|
-
false
|
100
|
+
return false
|
93
101
|
end
|
94
102
|
else
|
95
103
|
puts "No valid recipients!"
|
96
|
-
|
104
|
+
end
|
105
|
+
if not original_number.eql? filtered_number
|
106
|
+
mail.to = (recipients&bounced).uniq.join(",")
|
107
|
+
mail.cc = (mail.cc_addrs&bounced).uniq.join(",")
|
108
|
+
mail.bcc = (mail.bcc_addrs&bounced).uniq.join(",")
|
109
|
+
record = BouncedEmail.new({
|
110
|
+
:sender => sender,
|
111
|
+
:recipients => (recipients&bounced).uniq.join(","),
|
112
|
+
:subject => mail.subject,
|
113
|
+
:body => mail.body.decoded,
|
114
|
+
:system => mail['X-Sender-System']||"Unknown",
|
115
|
+
:created_at => Time.now,
|
116
|
+
:updated_at => Time.now
|
117
|
+
})
|
118
|
+
record.save!
|
97
119
|
end
|
98
120
|
end
|
99
121
|
|
data/ses_proxy.rb
CHANGED
@@ -7,4 +7,6 @@ module SesProxy
|
|
7
7
|
autoload :Bounce, 'ses_proxy/models/bounce'
|
8
8
|
autoload :Complaint, 'ses_proxy/models/complaint'
|
9
9
|
autoload :Email, 'ses_proxy/models/email'
|
10
|
+
autoload :BouncedEmail, 'ses_proxy/models/bounced_email'
|
11
|
+
autoload :RecipientsNumber, 'ses_proxy/models/recipients_number'
|
10
12
|
end
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: ses-proxy
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.2.0
|
5
5
|
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -212,6 +212,8 @@ extra_rdoc_files: []
|
|
212
212
|
files:
|
213
213
|
- ses_proxy.rb
|
214
214
|
- lib/ses_proxy/sns_endpoint.rb
|
215
|
+
- lib/ses_proxy/models/recipients_number.rb
|
216
|
+
- lib/ses_proxy/models/bounced_email.rb
|
215
217
|
- lib/ses_proxy/models/email.rb
|
216
218
|
- lib/ses_proxy/models/complaint.rb
|
217
219
|
- lib/ses_proxy/models/bounce.rb
|