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.
@@ -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