ses_machine 0.0.1.dev
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/.gitignore +1 -0
- data/Gemfile +4 -0
- data/Gemfile.lock +41 -0
- data/MIT-LICENSE +20 -0
- data/README.rdoc +13 -0
- data/Rakefile +23 -0
- data/app/controllers/application_controller.rb +3 -0
- data/app/controllers/ses_machine_controller.rb +64 -0
- data/app/helpers/ses_machine_helper.rb +8 -0
- data/app/views/layouts/ses_machine/application.html.erb +20 -0
- data/app/views/ses_machine/activity.html.erb +37 -0
- data/app/views/ses_machine/index.html.erb +17 -0
- data/app/views/ses_machine/show_message.html.erb +76 -0
- data/generators/ses_machine/USAGE +3 -0
- data/generators/ses_machine/ses_machine_generator.rb +19 -0
- data/generators/ses_machine/templates/README +7 -0
- data/generators/ses_machine/templates/ses_machine.css +14 -0
- data/generators/ses_machine/templates/ses_machine.rb +19 -0
- data/generators/ses_machine/templates/ses_machine.yml +15 -0
- data/generators/ses_machine/templates/ses_machine_hooks.rb +33 -0
- data/init.rb +3 -0
- data/install.rb +3 -0
- data/lib/ses_machine/bounce.rb +16 -0
- data/lib/ses_machine/config.rb +107 -0
- data/lib/ses_machine/db.rb +92 -0
- data/lib/ses_machine/errors.rb +24 -0
- data/lib/ses_machine/mailer.rb +68 -0
- data/lib/ses_machine/routing.rb +8 -0
- data/lib/ses_machine/version.rb +13 -0
- data/lib/ses_machine.rb +88 -0
- data/lib/tasks/db.rake +28 -0
- data/lib/tasks/ses_machine.rake +91 -0
- data/public/stylesheets/all.css +0 -0
- data/ses_machine.gemspec +29 -0
- data/test/config_test.rb +34 -0
- data/test/db_test.rb +50 -0
- data/test/fixtures/config/ses_machine.yml +11 -0
- data/test/routing_test.rb +17 -0
- data/test/ses_machine_controller_test.rb +49 -0
- data/test/ses_machine_generator_test.rb +38 -0
- data/test/ses_machine_test.rb +10 -0
- data/test/test_helper.rb +7 -0
- data/uninstall.rb +3 -0
- metadata +193 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: 6b1b83c2af26a6179d2161b61e2d6cbef89e3d93
|
4
|
+
data.tar.gz: 3cbee7e7443a3bf2231efad0215a560d40c4cb91
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: c632d7ea1e812b517003713666a4b55ba4fb2960115cd067858653033151262d798c9bac4eae153a462d5d02715d1008adfee019237fc0549f8d70065db64d0d
|
7
|
+
data.tar.gz: cb106e7c84abc41418ccb2b04ab416e338952062f0bceb27b036a179b7c84ce5cd8160f84b42c421af4dba571d3c16a41514d22eb8d61b659545ae617669ec99
|
data/.gitignore
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
pkg
|
data/Gemfile
ADDED
data/Gemfile.lock
ADDED
@@ -0,0 +1,41 @@
|
|
1
|
+
PATH
|
2
|
+
remote: .
|
3
|
+
specs:
|
4
|
+
ses_machine (0.0.1.dev)
|
5
|
+
aws-ses (>= 0.4.2)
|
6
|
+
mail (>= 2.2.15)
|
7
|
+
mongo (>= 1.3.0)
|
8
|
+
rubydkim (>= 0.3.1)
|
9
|
+
will_paginate (>= 2.3.15)
|
10
|
+
|
11
|
+
GEM
|
12
|
+
remote: https://rubygems.org/
|
13
|
+
specs:
|
14
|
+
aws-ses (0.4.4)
|
15
|
+
builder
|
16
|
+
mail (> 2.2.5)
|
17
|
+
mime-types
|
18
|
+
xml-simple
|
19
|
+
bson (1.6.4)
|
20
|
+
builder (3.2.2)
|
21
|
+
dnsruby (1.53)
|
22
|
+
mail (2.5.4)
|
23
|
+
mime-types (~> 1.16)
|
24
|
+
treetop (~> 1.4.8)
|
25
|
+
mime-types (1.24)
|
26
|
+
mongo (1.6.4)
|
27
|
+
bson (~> 1.6.4)
|
28
|
+
polyglot (0.3.3)
|
29
|
+
rubydkim (0.3.1)
|
30
|
+
dnsruby
|
31
|
+
treetop (1.4.15)
|
32
|
+
polyglot
|
33
|
+
polyglot (>= 0.3.1)
|
34
|
+
will_paginate (3.0.3)
|
35
|
+
xml-simple (1.1.2)
|
36
|
+
|
37
|
+
PLATFORMS
|
38
|
+
ruby
|
39
|
+
|
40
|
+
DEPENDENCIES
|
41
|
+
ses_machine!
|
data/MIT-LICENSE
ADDED
@@ -0,0 +1,20 @@
|
|
1
|
+
Copyright (c) 2011 Heiaheia.com
|
2
|
+
|
3
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
4
|
+
a copy of this software and associated documentation files (the
|
5
|
+
"Software"), to deal in the Software without restriction, including
|
6
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
7
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
8
|
+
permit persons to whom the Software is furnished to do so, subject to
|
9
|
+
the following conditions:
|
10
|
+
|
11
|
+
The above copyright notice and this permission notice shall be
|
12
|
+
included in all copies or substantial portions of the Software.
|
13
|
+
|
14
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
15
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
16
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
17
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
18
|
+
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
19
|
+
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
20
|
+
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/README.rdoc
ADDED
data/Rakefile
ADDED
@@ -0,0 +1,23 @@
|
|
1
|
+
require 'rake/testtask'
|
2
|
+
require 'rdoc/task'
|
3
|
+
require 'bundler'
|
4
|
+
Bundler::GemHelper.install_tasks
|
5
|
+
|
6
|
+
desc 'Default: run unit tests.'
|
7
|
+
task :default => :test
|
8
|
+
|
9
|
+
desc 'Test the ses_machine plugin.'
|
10
|
+
Rake::TestTask.new(:test) do |t|
|
11
|
+
t.libs << 'lib'
|
12
|
+
t.libs << 'test'
|
13
|
+
t.pattern = 'test/**/*_test.rb'
|
14
|
+
t.verbose = true
|
15
|
+
end
|
16
|
+
|
17
|
+
desc 'Generate documentation for the ses_machine plugin.'
|
18
|
+
RDoc::Task.new do |rdoc|
|
19
|
+
rdoc.main = 'README.rdoc'
|
20
|
+
rdoc.title = 'SES Machine'
|
21
|
+
rdoc.rdoc_dir = 'rdoc'
|
22
|
+
rdoc.rdoc_files.include('README.rdoc', 'lib/**/*.rb')
|
23
|
+
end
|
@@ -0,0 +1,64 @@
|
|
1
|
+
# -*- encoding : utf-8 -*-
|
2
|
+
|
3
|
+
class SesMachineController < Admin::ApplicationController
|
4
|
+
unloadable
|
5
|
+
|
6
|
+
unless ENV['RAILS_ENV'].eql?('test')
|
7
|
+
include SesMachineAuthHooks
|
8
|
+
before_filter :ses_machine_authorize!
|
9
|
+
end
|
10
|
+
|
11
|
+
helper :ses_machine
|
12
|
+
before_filter :assign_database
|
13
|
+
layout 'ses_machine/application'
|
14
|
+
|
15
|
+
def index
|
16
|
+
@date = (params[:date] || Date.current).to_date.beginning_of_month
|
17
|
+
monthly_stats = @db['monthly_stats'].find().sort([['_id.year', Mongo::DESCENDING], ['_id.month', Mongo::DESCENDING]]).to_a
|
18
|
+
@monthly_stats = monthly_stats.map do |e|
|
19
|
+
date = Date.new(e['_id']['year'], e['_id']['month'])
|
20
|
+
[date.strftime("%B %Y"), date.to_s]
|
21
|
+
end
|
22
|
+
@stats = @db['monthly_stats'].find_one('_id.year' => @date.year, '_id.month' => @date.month)
|
23
|
+
@count_mails_sent = @stats.blank? ? 0 : @stats['value']['total'].to_i
|
24
|
+
@count_mails_bounced = @stats.blank? ? 0 : (@count_mails_sent - @stats['value'][SesMachine::Bounce::TYPES[:email_sent].to_s]).to_i
|
25
|
+
end
|
26
|
+
|
27
|
+
def activity
|
28
|
+
page = params[:page].to_i
|
29
|
+
page = 1 if page < 1
|
30
|
+
per_page = 25
|
31
|
+
@bounce_type = ''
|
32
|
+
@q = ''
|
33
|
+
conditions = {}
|
34
|
+
unless params[:type].blank?
|
35
|
+
@bounce_type = params[:type].to_i
|
36
|
+
conditions.merge!('bounce_type' => @bounce_type)
|
37
|
+
end
|
38
|
+
unless params[:q].blank?
|
39
|
+
@q = SesMachine::DB.get_keywords(params[:q].to_s.split)
|
40
|
+
conditions.merge!('_keywords' => {'$all' => @q}) unless @q.blank?
|
41
|
+
end
|
42
|
+
@messages = @mails.find(conditions).sort('date', -1).skip((page-1) * per_page).limit(per_page).to_a
|
43
|
+
messages_count = @mails.find(conditions).count
|
44
|
+
@bounce_types = SesMachine::Bounce::TYPES.map{|k, v| [k.to_s.humanize, v]}
|
45
|
+
@bounce_types.unshift(['All emails', ''])
|
46
|
+
@pager = WillPaginate::Collection.new(page, per_page, messages_count)
|
47
|
+
end
|
48
|
+
|
49
|
+
def show_message
|
50
|
+
begin
|
51
|
+
@mail = @mails.find_one('_id' => BSON::ObjectId(params[:id]))
|
52
|
+
@mail['body'] = Mail.read_from_string(@mail['raw_source']).body
|
53
|
+
rescue
|
54
|
+
flash[:error] = 'Mail not found'
|
55
|
+
redirect_to ses_machine_path
|
56
|
+
end
|
57
|
+
end
|
58
|
+
|
59
|
+
private
|
60
|
+
def assign_database
|
61
|
+
@db = SesMachine.database
|
62
|
+
@mails = @db['mails']
|
63
|
+
end
|
64
|
+
end
|
@@ -0,0 +1,20 @@
|
|
1
|
+
<!doctype html>
|
2
|
+
<html>
|
3
|
+
<head>
|
4
|
+
<title>Ses Machine</title>
|
5
|
+
<%= stylesheet_link_tag('ses_machine') unless ENV['RAILS_ENV'].eql?('test') %>
|
6
|
+
</head>
|
7
|
+
<body>
|
8
|
+
<div id="ses-machine-wrapper">
|
9
|
+
<h1>Ses Machine</h1>
|
10
|
+
<ul>
|
11
|
+
<li><%= link_to_unless_current 'Overview', url_for(:controller => 'ses_machine', :action => 'index') %></li>
|
12
|
+
<li><%= link_to_unless_current 'Activity', url_for(:controller => 'ses_machine', :action => 'activity') %></li>
|
13
|
+
</ul>
|
14
|
+
<%- flash.each do |k, v| -%>
|
15
|
+
<div class="flash-<%= k %>"><%= v %></div>
|
16
|
+
<%- end -%>
|
17
|
+
<%= yield -%>
|
18
|
+
</div>
|
19
|
+
</body>
|
20
|
+
</html>
|
@@ -0,0 +1,37 @@
|
|
1
|
+
<h2>Activity</h2>
|
2
|
+
|
3
|
+
<%= form_tag request.path, :method => :get do %>
|
4
|
+
<%= select_tag :type, options_for_select(@bounce_types, @bounce_type), :onchange => "this.form.submit();" %>
|
5
|
+
<%= text_field_tag "q", params[:q], :placeholder => 'Search by email or subject…' %>
|
6
|
+
<%= submit_tag 'Search', :disable_with => 'Searching...' -%>
|
7
|
+
<% end %>
|
8
|
+
|
9
|
+
|
10
|
+
<%- if !@messages.blank? -%>
|
11
|
+
<%- date = nil -%>
|
12
|
+
<%- @messages.each do |message| -%>
|
13
|
+
<%- if date.blank? || date.to_date != message['date'].to_date -%>
|
14
|
+
<div class="activity-date">
|
15
|
+
<%- if message['date'].today? -%>
|
16
|
+
Today
|
17
|
+
<%- else -%>
|
18
|
+
<%= message['date'].strftime('%B %d, %Y') %>
|
19
|
+
<%- end -%>
|
20
|
+
</div>
|
21
|
+
<hr class="black"/>
|
22
|
+
<%- date = message['date'] -%>
|
23
|
+
<%- end -%>
|
24
|
+
<div class="activity-item <%= bounce_type(message['bounce_type']).dasherize %>">
|
25
|
+
<span class="address"><%= link_to message['address'], url_for(:controller => 'ses_machine', :action => 'show_message', :id => message['_id']) %></span>
|
26
|
+
<br/>
|
27
|
+
<div class="status">
|
28
|
+
<%= bounce_type(message['bounce_type']).humanize %> — <%= message['date'].strftime('%d.%m.%Y %l:%M %p') %>
|
29
|
+
</div>
|
30
|
+
<div class="subject"><%= message['subject'] %></div>
|
31
|
+
<div class="clear"></div>
|
32
|
+
</div>
|
33
|
+
<%- end -%>
|
34
|
+
<%= will_paginate @pager %>
|
35
|
+
<%- else -%>
|
36
|
+
No messages
|
37
|
+
<%- end -%>
|
@@ -0,0 +1,17 @@
|
|
1
|
+
<h2>Mails Sent</h2>
|
2
|
+
<div>
|
3
|
+
<% form_tag url_for(:controller => 'ses_machine', :action => 'index'), :method => :get do %>
|
4
|
+
<%= select_tag 'date', options_for_select(@monthly_stats, @date.to_s), :onchange => "this.form.submit();" %>
|
5
|
+
<%- end -%>
|
6
|
+
</div>
|
7
|
+
|
8
|
+
<div>
|
9
|
+
TRUE CHART
|
10
|
+
</div>
|
11
|
+
|
12
|
+
<h2>Mail Stats</h2>
|
13
|
+
<div>
|
14
|
+
<p><%= @count_mails_sent %> mails sent</p>
|
15
|
+
<p><%= @count_mails_bounced %> mails bounced</p>
|
16
|
+
</div>
|
17
|
+
|
@@ -0,0 +1,76 @@
|
|
1
|
+
<%- if !request.env["HTTP_REFERER"].blank? && request.env["HTTP_REFERER"] != request.env["REQUEST_URI"] -%>
|
2
|
+
<div style="float:right;"><%= link_to "← Back", :back %></div>
|
3
|
+
<%- end -%>
|
4
|
+
<h2>Message Status</h2>
|
5
|
+
<div class="clear"></div>
|
6
|
+
<div><span style="color:#aaa;">Email</span> <span style="font-weight: bold;"><%= @mail['address'].join(', ') %></span></div>
|
7
|
+
<div><span style="color:#aaa;">Subject</span> <%= @mail['subject'] %></div>
|
8
|
+
<hr class="gray"/>
|
9
|
+
|
10
|
+
<%- unless @mail['bounce'].blank? -%>
|
11
|
+
<div>
|
12
|
+
<%= @mail['bounce']['date'].strftime('%d.%m.%Y %l:%M %p') %> <%= bounce_type(@mail['bounce_type']).humanize %>
|
13
|
+
<%- unless @mail['bounce']['details'].blank? -%>
|
14
|
+
<div style="color:#aaa;font-size:small;"><%= @mail['bounce']['details'] %></div>
|
15
|
+
<%- end -%>
|
16
|
+
</div>
|
17
|
+
<%- end -%>
|
18
|
+
<div><%= @mail['date'].strftime('%d.%m.%Y %l:%M %p') %> <span><%= bounce_type(0).humanize %></span></div>
|
19
|
+
|
20
|
+
<ul>
|
21
|
+
<%- unless @mail['response'].blank? -%>
|
22
|
+
<li><a href="#" onclick="showAmazonResponse();">XML Amazon Response</a></li>
|
23
|
+
<%- end -%>
|
24
|
+
<li><a href="#" onclick="showPlainText();">Plain Text</a></li>
|
25
|
+
<li><a href="#" onclick="showRawSource();">Raw Source</a></li>
|
26
|
+
<%- unless @mail['bounce'].blank? -%>
|
27
|
+
<li><a href="#" onclick="showBounceRawSource();">Bounce Raw Source</a></li>
|
28
|
+
<%- end -%>
|
29
|
+
</ul>
|
30
|
+
|
31
|
+
<%- unless @mail['response'].blank? -%>
|
32
|
+
<div id="amazon-response" style="display:none;font-size:small;border:1px solid #aaa;">
|
33
|
+
<pre><%= h @mail['response'] %></pre>
|
34
|
+
</div>
|
35
|
+
<%- end -%>
|
36
|
+
<div id="plain-text" style="font-size:small;border:1px solid #aaa;"><%= simple_format @mail['body'].to_s %></div>
|
37
|
+
<div id="raw-source" style="display:none;font-size:small;border:1px solid #aaa;">
|
38
|
+
<%#= simple_format @mail['raw_source'] %>
|
39
|
+
<pre><%= h @mail['raw_source'] %></pre>
|
40
|
+
</div>
|
41
|
+
<%- unless @mail['bounce'].blank? -%>
|
42
|
+
<div id="bounce-raw-source" style="display:none;font-size:small;border:1px solid #aaa;">
|
43
|
+
<pre><%= h @mail['bounce']['raw_source'] %></pre>
|
44
|
+
</div>
|
45
|
+
<%- end -%>
|
46
|
+
|
47
|
+
<script type="text/javascript">
|
48
|
+
function showPlainText() {
|
49
|
+
document.getElementById('amazon-response').style.display = 'none';
|
50
|
+
document.getElementById('plain-text').style.display = null;
|
51
|
+
document.getElementById('raw-source').style.display = 'none';
|
52
|
+
document.getElementById('bounce-raw-source').style.display = 'none';
|
53
|
+
return false;
|
54
|
+
}
|
55
|
+
function showRawSource() {
|
56
|
+
document.getElementById('amazon-response').style.display = 'none';
|
57
|
+
document.getElementById('plain-text').style.display = 'none';
|
58
|
+
document.getElementById('raw-source').style.display = null;
|
59
|
+
document.getElementById('bounce-raw-source').style.display = 'none';
|
60
|
+
return false;
|
61
|
+
}
|
62
|
+
function showBounceRawSource() {
|
63
|
+
document.getElementById('amazon-response').style.display = 'none';
|
64
|
+
document.getElementById('plain-text').style.display = 'none';
|
65
|
+
document.getElementById('raw-source').style.display = 'none';
|
66
|
+
document.getElementById('bounce-raw-source').style.display = null;
|
67
|
+
return false;
|
68
|
+
}
|
69
|
+
function showAmazonResponse() {
|
70
|
+
document.getElementById('amazon-response').style.display = null;
|
71
|
+
document.getElementById('plain-text').style.display = 'none';
|
72
|
+
document.getElementById('raw-source').style.display = 'none';
|
73
|
+
document.getElementById('bounce-raw-source').style.display = 'none';
|
74
|
+
return false;
|
75
|
+
}
|
76
|
+
</script>
|
@@ -0,0 +1,19 @@
|
|
1
|
+
# -*- encoding : utf-8 -*-
|
2
|
+
|
3
|
+
class SesMachineGenerator < Rails::Generator::Base
|
4
|
+
def manifest
|
5
|
+
record do |m|
|
6
|
+
m.directory 'config'
|
7
|
+
m.template 'ses_machine.yml', 'config/ses_machine.yml'
|
8
|
+
|
9
|
+
m.directory 'config/initializers'
|
10
|
+
m.template 'ses_machine.rb', 'config/initializers/ses_machine.rb'
|
11
|
+
m.template 'ses_machine_hooks.rb', 'config/initializers/ses_machine_hooks.rb'
|
12
|
+
|
13
|
+
m.directory 'public/stylesheets'
|
14
|
+
m.template 'ses_machine.css', 'public/stylesheets/ses_machine.css'
|
15
|
+
|
16
|
+
m.readme 'README' unless ENV['RAILS_ENV'].eql?('test')
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
@@ -0,0 +1,14 @@
|
|
1
|
+
hr.black{border:none;border-bottom:1px solid black}
|
2
|
+
hr.gray{border:none;border-bottom:1px solid #aaa}
|
3
|
+
|
4
|
+
#ses-machine-wrapper{width:900px;margin:0 auto}
|
5
|
+
|
6
|
+
.activity-date{padding:10px 0 5px 0;font-weight:bold}
|
7
|
+
.activity-item{padding:5px 0;border:none;border-bottom:1px solid #aaa}
|
8
|
+
.activity-item.email-sent .address a{color:green}
|
9
|
+
.activity-item.unknown .address a{color:#666}
|
10
|
+
.activity-item.hard-bounce .address a{color:red}
|
11
|
+
.activity-item .status{float:right;color:gray;font-size:small}
|
12
|
+
.activity-item .subject{color:gray;font-size:small}
|
13
|
+
.clear{height:1px;line-height:1px;clear:both}
|
14
|
+
.flash-error{padding:8px 15px;border:1px solid #991010;background-color:#ffc0cb}
|
@@ -0,0 +1,19 @@
|
|
1
|
+
# -*- encoding : utf-8 -*-
|
2
|
+
|
3
|
+
SesMachine.configure do |config|
|
4
|
+
# Email configuration for rake tasks
|
5
|
+
config.email_server = 'imap.googlemail.com'
|
6
|
+
config.email_port = 993
|
7
|
+
config.email_use_ssl = true
|
8
|
+
config.email_account = 'username@gmail.com' # The email address to which bounce notifications are to be forwarded.
|
9
|
+
config.email_password = '12345'
|
10
|
+
config.email_imap_folders = ['INBOX', '[Gmail]/Spam']
|
11
|
+
|
12
|
+
# DKIM
|
13
|
+
config.use_dkim = false
|
14
|
+
# config.dkim_domain = 'example.com'
|
15
|
+
# config.dkim_selector = 'ses'
|
16
|
+
# config.dkim_private_key = '/path/to/private/key'
|
17
|
+
end
|
18
|
+
|
19
|
+
|
@@ -0,0 +1,33 @@
|
|
1
|
+
# -*- encoding : utf-8 -*-
|
2
|
+
|
3
|
+
module SesMachineAuthHooks
|
4
|
+
protected
|
5
|
+
|
6
|
+
def ses_machine_authorize!
|
7
|
+
true
|
8
|
+
end
|
9
|
+
end
|
10
|
+
|
11
|
+
# module SesMachineHooks
|
12
|
+
# def soft_bounce_hook(email)
|
13
|
+
# # Add your code
|
14
|
+
# end
|
15
|
+
#
|
16
|
+
# def hard_bounce_hook(email)
|
17
|
+
# # Add your code
|
18
|
+
# end
|
19
|
+
#
|
20
|
+
# def unknown_hook(email)
|
21
|
+
# # Add your code
|
22
|
+
# end
|
23
|
+
#
|
24
|
+
# def spam_complaint_hook(email)
|
25
|
+
# # Add your code
|
26
|
+
# end
|
27
|
+
#
|
28
|
+
# def auto_responder_hook(email)
|
29
|
+
# # Add your code
|
30
|
+
# end
|
31
|
+
# end
|
32
|
+
|
33
|
+
# SesMachine::Hooks.send :extend, SesMachineHooks
|
data/init.rb
ADDED
data/install.rb
ADDED
@@ -0,0 +1,107 @@
|
|
1
|
+
# -*- encoding : utf-8 -*-
|
2
|
+
|
3
|
+
|
4
|
+
module SesMachine #:nodoc:
|
5
|
+
class Config #:nodoc:
|
6
|
+
include Singleton
|
7
|
+
|
8
|
+
attr_accessor :ses,
|
9
|
+
:dkim_domain, :dkim_selector, :dkim_private_key,
|
10
|
+
:email_server, :email_port, :email_use_ssl, :email_account, :email_password, :email_imap_folders
|
11
|
+
attr_reader :database, :use_dkim
|
12
|
+
alias_method :use_dkim?, :use_dkim
|
13
|
+
|
14
|
+
# Defaults the configuration options
|
15
|
+
def initialize
|
16
|
+
reset
|
17
|
+
end
|
18
|
+
|
19
|
+
# Reset the configuration options to the defaults.
|
20
|
+
#
|
21
|
+
# Example:
|
22
|
+
#
|
23
|
+
# <tt>Config.reset</tt>
|
24
|
+
def reset
|
25
|
+
@use_dkim = false
|
26
|
+
@dkim_domain = nil
|
27
|
+
@dkim_selector = nil
|
28
|
+
@dkim_private_key = nil
|
29
|
+
end
|
30
|
+
|
31
|
+
def load(filename=nil)
|
32
|
+
filename = File.join(ENV['RAILS_ROOT'], 'config', 'ses_machine.yml') if filename.blank?
|
33
|
+
if File.exist?(filename)
|
34
|
+
settings = YAML.load_file(filename)[ENV['RAILS_ENV']]
|
35
|
+
from_hash(settings)
|
36
|
+
else
|
37
|
+
$stderr.puts "WARNING: File '#{filename}' doesn't exist"
|
38
|
+
end
|
39
|
+
end
|
40
|
+
|
41
|
+
# TODO: fix readme
|
42
|
+
# Sets whether the times returned from the database are in UTC or local time.
|
43
|
+
# If you omit this setting, then times will be returned in
|
44
|
+
# the local time zone.
|
45
|
+
#
|
46
|
+
# Example:
|
47
|
+
#
|
48
|
+
# <tt>Config.use_dkim = true</tt>
|
49
|
+
#
|
50
|
+
# Returns:
|
51
|
+
#
|
52
|
+
# A boolean
|
53
|
+
def use_dkim=(value=false)
|
54
|
+
@use_dkim = value
|
55
|
+
end
|
56
|
+
|
57
|
+
# Configure SesMachine from a hash that was usually parsed out of yml.
|
58
|
+
#
|
59
|
+
# Example:
|
60
|
+
#
|
61
|
+
# <tt>SesMachine::Config.instance.from_hash({})</tt>
|
62
|
+
def from_hash(settings)
|
63
|
+
_database(settings)
|
64
|
+
settings.except('database').each_pair do |name, value|
|
65
|
+
send("#{name}=", value) if respond_to?(name)
|
66
|
+
end
|
67
|
+
end
|
68
|
+
|
69
|
+
# Sets the Mongo::DB database to be used. If the object trying to be
|
70
|
+
# set is not a valid +Mongo::DB+, then an error will be raised.
|
71
|
+
#
|
72
|
+
# Example:
|
73
|
+
#
|
74
|
+
# <tt>Config.database = Mongo::Connection.db('test')</tt>
|
75
|
+
#
|
76
|
+
# Returns:
|
77
|
+
#
|
78
|
+
# The +Mongo::DB+ instance.
|
79
|
+
def database=(db)
|
80
|
+
check_database!(db)
|
81
|
+
@database = db
|
82
|
+
end
|
83
|
+
|
84
|
+
protected
|
85
|
+
|
86
|
+
# Check if the database is valid and the correct version.
|
87
|
+
#
|
88
|
+
# Example:
|
89
|
+
#
|
90
|
+
# <tt>config.check_database!</tt>
|
91
|
+
def check_database!(database)
|
92
|
+
raise Errors::InvalidDatabase.new(database) unless database.kind_of?(Mongo::DB)
|
93
|
+
end
|
94
|
+
|
95
|
+
# Get a database from settings.
|
96
|
+
#
|
97
|
+
# Example:
|
98
|
+
#
|
99
|
+
# <tt>config._database({})</tt>
|
100
|
+
def _database(settings)
|
101
|
+
name = settings['database']['name']
|
102
|
+
host = settings['database']['host'] || 'localhost'
|
103
|
+
port = settings['database']['port'] || 27017
|
104
|
+
self.database = Mongo::Connection.new(host, port).db(name)
|
105
|
+
end
|
106
|
+
end
|
107
|
+
end
|