ses-proxy 0.1.1 → 0.2.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -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
- %div(style="display: inline-block;vertical-align: middle;")
5
- %label Text
6
- %input.span4(type="text" name="q" value="#{@q}" placeholder="Type something…")
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")
@@ -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
@@ -1,4 +1,5 @@
1
- %h1.page-title(style="text-align: center; margin-bottom:20px;") Sent Emails
1
+ %h1.page-title(style="text-align: center; margin-bottom:20px;")
2
+ = @page_title
2
3
  = haml :_search_form
3
4
  = haml :_chart
4
5
  %table.table.table-striped(style="table-layout:fixed")
@@ -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
- data = get_data_json "Mails", mails, "created_at", d_array
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 = get_data_json "Bounced", bounces, "created_at", d_array
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 get_data_json(name, collection, method, d_array)
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
- data[:x] = d_array.map{|d| d.to_date.strftime(key_format)}.uniq
92
- data[:y] ||= []
93
- data[:x].each do |d|
94
- grouped_collection[d] = collection.collect{|b| b if b.send(method).strftime(key_format).eql? d}.compact.size
95
- end
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),'$lt' => string_to_date(@e)})
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),'$lt' => string_to_date(@e)}).any_of({:recipients => /.*#{@q}.*/i },{:sender => /.*#{@q}.*/i },{:system => /.*#{@q}.*/i },{:subject => /.*#{@q}.*/i })
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 bounces_query
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
- bounces = SesProxy::Bounce.where(:created_at=>{'$gte' => string_to_date(@s),'$lte' => string_to_date(@e)})
194
+ mails = SesProxy::BouncedEmail.where(:created_at=>{'$gte' => string_to_date(@s),'$lte' => string_to_date(@e)+1.day})
126
195
  else
127
- bounces = SesProxy::Bounce.all
196
+ mails = SesProxy::BouncedEmail.all
128
197
  end
129
198
  else
130
199
  if valid_date(@s) and valid_date(@e)
131
- bounces = SesProxy::Bounce.where(:created_at=>{'$gte' => string_to_date(@s),'$lte' => string_to_date(@e)}).any_of({:email => /.*#{@q}.*/i },{ :type => /.*#{@q}.*/i },{ :desc => /.*#{@q}.*/i })
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
- bounces = SesProxy::Bounce.any_of({:email => /.*#{@q}.*/i },{ :type => /.*#{@q}.*/i },{ :desc => /.*#{@q}.*/i })
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
@@ -0,0 +1,12 @@
1
+ require 'mongoid'
2
+
3
+ module SesProxy
4
+ class RecipientsNumber
5
+ include Mongoid::Document
6
+
7
+ field :original, type: Integer
8
+ field :filtered, type: Integer
9
+ field :created_at, type: DateTime
10
+ field :updated_at, type: DateTime
11
+ end
12
+ 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
- true
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
 
@@ -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.1.1
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