email_spy 1.0.3 → 1.6.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/lib/email_spy.rb +5 -0
- data/lib/email_spy/delivery_method.rb +31 -7
- data/lib/email_spy/message.html.erb +82 -71
- data/lib/email_spy/message.rb +43 -11
- data/lib/email_spy/railtie.rb +2 -1
- data/lib/email_spy/version.rb +1 -1
- metadata +2 -2
data/lib/email_spy.rb
CHANGED
@@ -1,8 +1,13 @@
|
|
1
1
|
require "fileutils"
|
2
2
|
require "digest/sha1"
|
3
3
|
require "cgi"
|
4
|
+
require "uri"
|
4
5
|
require "launchy"
|
5
6
|
|
7
|
+
module EmailSpy
|
8
|
+
EMAIL_DIRECTORY_NAME = "email_spy"
|
9
|
+
end
|
10
|
+
|
6
11
|
require_relative "email_spy/message"
|
7
12
|
require_relative "email_spy/delivery_method"
|
8
13
|
require_relative "email_spy/railtie" if defined? Rails
|
@@ -3,20 +3,44 @@ module EmailSpy
|
|
3
3
|
attr_accessor :settings
|
4
4
|
|
5
5
|
def initialize(options = {})
|
6
|
-
@settings = { location:
|
6
|
+
@settings = { location: email_directory }
|
7
7
|
@settings.merge! options
|
8
8
|
end
|
9
9
|
|
10
10
|
def deliver!(email)
|
11
|
-
|
12
|
-
|
13
|
-
|
11
|
+
launch messages(email, location(email, settings))
|
12
|
+
end
|
13
|
+
|
14
|
+
private
|
14
15
|
|
15
|
-
|
16
|
-
|
17
|
-
|
16
|
+
def location(email, settings)
|
17
|
+
File.join settings[:location], "#{Time.now.to_i}_#{digest email}"
|
18
|
+
end
|
19
|
+
|
20
|
+
def digest(email)
|
21
|
+
Digest::SHA1.hexdigest(email.encoded)[0..6]
|
22
|
+
end
|
18
23
|
|
24
|
+
def messages(email, path)
|
25
|
+
if email.html_part || email.text_part
|
26
|
+
[email.html_part, email.text_part].compact.map do |part|
|
27
|
+
Message.new path, email, part
|
28
|
+
end
|
29
|
+
else
|
30
|
+
[Message.new(path, email)]
|
31
|
+
end.each &:render
|
32
|
+
end
|
33
|
+
|
34
|
+
def launch(messages)
|
19
35
|
Launchy.open URI.parse "file://#{messages.first.filepath}"
|
20
36
|
end
|
37
|
+
|
38
|
+
def email_directory
|
39
|
+
if defined?(Rails)
|
40
|
+
Rails.root.join "tmp", EMAIL_DIRECTORY_NAME
|
41
|
+
else
|
42
|
+
File.join '.', EMAIL_DIRECTORY_NAME
|
43
|
+
end
|
44
|
+
end
|
21
45
|
end
|
22
46
|
end
|
@@ -1,88 +1,99 @@
|
|
1
1
|
<meta http-equiv="Content-Type" content="text/html; charset=<%= encoding %>">
|
2
|
-
<style type="text/css">
|
3
|
-
#message_headers {
|
4
|
-
position: relative;
|
5
|
-
top: 0px;
|
6
|
-
left: 0;
|
7
|
-
width: 100%;
|
8
|
-
height: 85px;
|
9
|
-
padding: 10px 0 0 0;
|
10
|
-
margin: 0;
|
11
|
-
margin-bottom:20px;
|
12
|
-
background: #fff;
|
13
|
-
font-size: 12px;
|
14
|
-
font-family: "Lucida Grande";
|
15
|
-
border-bottom: 1px solid #dedede;
|
16
|
-
overflow: hidden;
|
17
|
-
}
|
18
|
-
|
19
|
-
#message_headers dl {
|
20
|
-
margin: 0;
|
21
|
-
padding: 0;
|
22
|
-
}
|
23
|
-
|
24
|
-
#message_headers dt {
|
25
|
-
width: 60px;
|
26
|
-
padding: 1px;
|
27
|
-
float: left;
|
28
|
-
text-align: right;
|
29
|
-
font-weight: bold;
|
30
|
-
color: #7f7f7f;
|
31
|
-
}
|
32
2
|
|
33
|
-
|
34
|
-
|
35
|
-
|
3
|
+
<style type="text/css">
|
4
|
+
body {
|
5
|
+
background: pearl;
|
36
6
|
}
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
7
|
+
.header .clearfix{*zoom:1}.header .clearfix:before,.header .clearfix:after{display:table;content:""}.header .clearfix:after{clear:both}.header .hide-text{font:0/0 a;color:transparent;text-shadow:none;background-color:transparent;border:0}.header .input-block-level{display:block;width:100%;min-height:28px;-webkit-box-sizing:border-box;-moz-box-sizing:border-box;-ms-box-sizing:border-box;box-sizing:border-box}.header article,.header aside,.header details,.header figcaption,.header figure,.header footer,.header header,.header hgroup,.header nav,.header section{display:block}.header audio,.header canvas,.header video{display:inline-block;*display:inline;*zoom:1}.header audio:not([controls]){display:none}.header html{font-size:100%;-webkit-text-size-adjust:100%;-ms-text-size-adjust:100%}.header a:focus{outline:thin dotted #333;outline:5px auto -webkit-focus-ring-color;outline-offset:-2px}.header a:hover,.header a:active{outline:0}.header sub,.header sup{position:relative;font-size:75%;line-height:0;vertical-align:baseline}.header sup{top:-0.5em}.header sub{bottom:-0.25em}.header img{max-width:100%;vertical-align:middle;border:0;-ms-interpolation-mode:bicubic}.header #map_canvas img{max-width:none}.header button,.header input,.header select,.header textarea{margin:0;font-size:100%;vertical-align:middle}.header button,.header input{*overflow:visible;line-height:normal}.header button::-moz-focus-inner,.header input::-moz-focus-inner{padding:0;border:0}.header button,.header input[type="button"],.header input[type="reset"],.header input[type="submit"]{cursor:pointer;-webkit-appearance:button}.header input[type="search"]{-webkit-box-sizing:content-box;-moz-box-sizing:content-box;box-sizing:content-box;-webkit-appearance:textfield}.header input[type="search"]::-webkit-search-decoration,.header input[type="search"]::-webkit-search-cancel-button{-webkit-appearance:none}.header textarea{overflow:auto;vertical-align:top}.header body{margin:0;font-family:"Helvetica Neue",Helvetica,Arial,sans-serif;font-size:13px;line-height:18px;color:#333;background-color:#fff}.header a{color:#08c;text-decoration:none}.header a:hover{color:#005580;text-decoration:underline}.header .row{margin-left:-20px;*zoom:1}.header .row:before,.header .row:after{display:table;content:""}.header .row:after{clear:both}.header [class*="span"]{float:left;margin-left:20px}.header .container,.header .navbar-fixed-top .container,.header .navbar-fixed-bottom .container{width:940px}.header .span12{width:940px}.header .span11{width:860px}.header .span10{width:780px}.header .span9{width:700px}.header .span8{width:620px}.header .span7{width:540px}.header .span6{width:460px}.header .span5{width:380px}.header .span4{width:300px}.header .span3{width:220px}.header .span2{width:140px}.header .span1{width:60px}.header .offset12{margin-left:980px}.header .offset11{margin-left:900px}.header .offset10{margin-left:820px}.header .offset9{margin-left:740px}.header .offset8{margin-left:660px}.header .offset7{margin-left:580px}.header .offset6{margin-left:500px}.header .offset5{margin-left:420px}.header .offset4{margin-left:340px}.header .offset3{margin-left:260px}.header .offset2{margin-left:180px}.header .offset1{margin-left:100px}.header .row-fluid{width:100%;*zoom:1}.header .row-fluid:before,.header .row-fluid:after{display:table;content:""}.header .row-fluid:after{clear:both}.header .row-fluid [class*="span"]{display:block;width:100%;min-height:28px;-webkit-box-sizing:border-box;-moz-box-sizing:border-box;-ms-box-sizing:border-box;box-sizing:border-box;float:left;margin-left:2.127659574%;*margin-left:2.0744680846382977%}.header .row-fluid [class*="span"]:first-child{margin-left:0}.header .row-fluid .span12{width:99.99999998999999%;*width:99.94680850063828%}.header .row-fluid .span11{width:91.489361693%;*width:91.4361702036383%}.header .row-fluid .span10{width:82.97872339599999%;*width:82.92553190663828%}.header .row-fluid .span9{width:74.468085099%;*width:74.4148936096383%}.header .row-fluid .span8{width:65.95744680199999%;*width:65.90425531263828%}.header .row-fluid .span7{width:57.446808505%;*width:57.3936170156383%}.header .row-fluid .span6{width:48.93617020799999%;*width:48.88297871863829%}.header .row-fluid .span5{width:40.425531911%;*width:40.3723404216383%}.header .row-fluid .span4{width:31.914893614%;*width:31.8617021246383%}.header .row-fluid .span3{width:23.404255317%;*width:23.3510638276383%}.header .row-fluid .span2{width:14.89361702%;*width:14.8404255306383%}.header .row-fluid .span1{width:6.382978723%;*width:6.329787233638298%}.header p{margin:0 0 9px}.header p small{font-size:11px;color:#999}.header .lead{margin-bottom:18px;font-size:20px;font-weight:200;line-height:27px}.header h1,.header h2,.header h3,.header h4,.header h5,.header h6{margin:0;font-family:inherit;font-weight:bold;color:inherit;text-rendering:optimizelegibility}.header h1 small,.header h2 small,.header h3 small,.header h4 small,.header h5 small,.header h6 small{font-weight:normal;color:#999}.header h1{font-size:30px;line-height:36px}.header h1 small{font-size:18px}.header h2{font-size:24px;line-height:36px}.header h2 small{font-size:18px}.header h3{font-size:18px;line-height:27px}.header h3 small{font-size:14px}.header h4,.header h5,.header h6{line-height:18px}.header h4{font-size:14px}.header h4 small{font-size:12px}.header h5{font-size:12px}.header h6{font-size:11px;color:#999;text-transform:uppercase}.header .page-header{padding-bottom:17px;margin:18px 0;border-bottom:1px solid #eee}.header .page-header h1{line-height:1}.header ul,.header ol{padding:0;margin:0 0 9px 25px}.header ul ul,.header ul ol,.header ol ol,.header ol ul{margin-bottom:0}.header ul{list-style:disc}.header ol{list-style:decimal}.header li{line-height:18px}.header ul.unstyled,.header ol.unstyled{margin-left:0;list-style:none}.header dl{margin-bottom:18px}.header dt,.header dd{line-height:18px}.header dt{font-weight:bold;line-height:17px}.header dd{margin-left:9px}.header .dl-horizontal dt{float:left;width:120px;clear:left;text-align:right;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.header .dl-horizontal dd{margin-left:130px}.header hr{margin:18px 0;border:0;border-top:1px solid #eee;border-bottom:1px solid #fff}.header strong{font-weight:bold}.header em{font-style:italic}.header .muted{color:#999}.header abbr[title]{cursor:help;border-bottom:1px dotted #999}.header abbr.initialism{font-size:90%;text-transform:uppercase}.header blockquote{padding:0 0 0 15px;margin:0 0 18px;border-left:5px solid #eee}.header blockquote p{margin-bottom:0;font-size:16px;font-weight:300;line-height:22.5px}.header blockquote small{display:block;line-height:18px;color:#999}.header blockquote small:before{content:'\2014 \00A0'}.header blockquote.pull-right{float:right;padding-right:15px;padding-left:0;border-right:5px solid #eee;border-left:0}.header blockquote.pull-right p,.header blockquote.pull-right small{text-align:right}.header q:before,.header q:after,.header blockquote:before,.header blockquote:after{content:""}.header address{display:block;margin-bottom:18px;font-style:normal;line-height:18px}.header small{font-size:100%}.header cite{font-style:normal}.header .label,.header .badge{font-size:10.998px;font-weight:bold;line-height:14px;color:#fff;vertical-align:baseline;white-space:nowrap;text-shadow:0 -1px 0 rgba(0,0,0,0.25);background-color:#999}.header .label{padding:1px 4px 2px;-webkit-border-radius:3px;-moz-border-radius:3px;border-radius:3px}.header .badge{padding:1px 9px 2px;-webkit-border-radius:9px;-moz-border-radius:9px;border-radius:9px}.header a.label:hover,.header a.badge:hover{color:#fff;text-decoration:none;cursor:pointer}.header .label-important,.header .badge-important{background-color:#b94a48}.header .label-important[href],.header .badge-important[href]{background-color:#953b39}.header .label-warning,.header .badge-warning{background-color:#f89406}.header .label-warning[href],.header .badge-warning[href]{background-color:#c67605}.header .label-success,.header .badge-success{background-color:#468847}.header .label-success[href],.header .badge-success[href]{background-color:#356635}.header .label-info,.header .badge-info{background-color:#3a87ad}.header .label-info[href],.header .badge-info[href]{background-color:#2d6987}.header .label-inverse,.header .badge-inverse{background-color:#333}.header .label-inverse[href],.header .badge-inverse[href]{background-color:#1a1a1a}.header .btn{display:inline-block;*display:inline;*zoom:1;padding:4px 10px 4px;margin-bottom:0;font-size:13px;line-height:18px;*line-height:20px;color:#333;text-align:center;text-shadow:0 1px 1px rgba(255,255,255,0.75);vertical-align:middle;cursor:pointer;background-color:#f5f5f5;background-image:-moz-linear-gradient(top,white,#e6e6e6);background-image:-ms-linear-gradient(top,white,#e6e6e6);background-image:-webkit-gradient(linear,0 0,0 100%,from(white),to(#e6e6e6));background-image:-webkit-linear-gradient(top,white,#e6e6e6);background-image:-o-linear-gradient(top,white,#e6e6e6);background-image:linear-gradient(top,#fff,#e6e6e6);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffffff',endColorstr='#e6e6e6',GradientType=0);border-color:#e6e6e6 #e6e6e6 #bfbfbf;border-color:rgba(0,0,0,0.1) rgba(0,0,0,0.1) rgba(0,0,0,0.25);*background-color:#e6e6e6;filter:progid:DXImageTransform.Microsoft.gradient(enabled = false);border:1px solid #ccc;*border:0;border-bottom-color:#b3b3b3;-webkit-border-radius:4px;-moz-border-radius:4px;border-radius:4px;*margin-left:.3em;-webkit-box-shadow:inset 0 1px 0 rgba(255,255,255,0.2),0 1px 2px rgba(0,0,0,0.05);-moz-box-shadow:inset 0 1px 0 rgba(255,255,255,0.2),0 1px 2px rgba(0,0,0,0.05);box-shadow:inset 0 1px 0 rgba(255,255,255,0.2),0 1px 2px rgba(0,0,0,0.05)}.header .btn:hover,.header .btn:active,.header .btn.active,.header .btn.disabled,.header .btn[disabled]{background-color:#e6e6e6;*background-color:#d9d9d9}.header .btn:active,.header .btn.active{background-color:#ccc \9}.header .btn:first-child{*margin-left:0}.header .btn:hover{color:#333;text-decoration:none;background-color:#e6e6e6;*background-color:#d9d9d9;background-position:0 -15px;-webkit-transition:background-position .1s linear;-moz-transition:background-position .1s linear;-ms-transition:background-position .1s linear;-o-transition:background-position .1s linear;transition:background-position .1s linear}.header .btn:focus{outline:thin dotted #333;outline:5px auto -webkit-focus-ring-color;outline-offset:-2px}.header .btn.active,.header .btn:active{background-color:#e6e6e6;background-color:#d9d9d9 \9;background-image:none;outline:0;-webkit-box-shadow:inset 0 2px 4px rgba(0,0,0,0.15),0 1px 2px rgba(0,0,0,0.05);-moz-box-shadow:inset 0 2px 4px rgba(0,0,0,0.15),0 1px 2px rgba(0,0,0,0.05);box-shadow:inset 0 2px 4px rgba(0,0,0,0.15),0 1px 2px rgba(0,0,0,0.05)}.header .btn.disabled,.header .btn[disabled]{cursor:default;background-color:#e6e6e6;background-image:none;opacity:.65;filter:alpha(opacity=65);-webkit-box-shadow:none;-moz-box-shadow:none;box-shadow:none}.header .btn-large{padding:9px 14px;font-size:15px;line-height:normal;-webkit-border-radius:5px;-moz-border-radius:5px;border-radius:5px}.header .btn-large [class^="icon-"]{margin-top:1px}.header .btn-small{padding:5px 9px;font-size:11px;line-height:16px}.header .btn-small [class^="icon-"]{margin-top:-1px}.header .btn-mini{padding:2px 6px;font-size:11px;line-height:14px}.header .btn-primary,.header .btn-primary:hover,.header .btn-warning,.header .btn-warning:hover,.header .btn-danger,.header .btn-danger:hover,.header .btn-success,.header .btn-success:hover,.header .btn-info,.header .btn-info:hover,.header .btn-inverse,.header .btn-inverse:hover{color:#fff;text-shadow:0 -1px 0 rgba(0,0,0,0.25)}.header .btn-primary.active,.header .btn-warning.active,.header .btn-danger.active,.header .btn-success.active,.header .btn-info.active,.header .btn-inverse.active{color:rgba(255,255,255,0.75)}.header .btn{border-color:#ccc;border-color:rgba(0,0,0,0.1) rgba(0,0,0,0.1) rgba(0,0,0,0.25)}.header .btn-primary{background-color:#0074cc;background-image:-moz-linear-gradient(top,#08c,#05c);background-image:-ms-linear-gradient(top,#08c,#05c);background-image:-webkit-gradient(linear,0 0,0 100%,from(#08c),to(#05c));background-image:-webkit-linear-gradient(top,#08c,#05c);background-image:-o-linear-gradient(top,#08c,#05c);background-image:linear-gradient(top,#08c,#05c);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#0088cc',endColorstr='#0055cc',GradientType=0);border-color:#05c #05c #003580;border-color:rgba(0,0,0,0.1) rgba(0,0,0,0.1) rgba(0,0,0,0.25);*background-color:#05c;filter:progid:DXImageTransform.Microsoft.gradient(enabled = false)}.header .btn-primary:hover,.header .btn-primary:active,.header .btn-primary.active,.header .btn-primary.disabled,.header .btn-primary[disabled]{background-color:#05c;*background-color:#004ab3}.header .btn-primary:active,.header .btn-primary.active{background-color:#004099 \9}.header .btn-warning{background-color:#faa732;background-image:-moz-linear-gradient(top,#fbb450,#f89406);background-image:-ms-linear-gradient(top,#fbb450,#f89406);background-image:-webkit-gradient(linear,0 0,0 100%,from(#fbb450),to(#f89406));background-image:-webkit-linear-gradient(top,#fbb450,#f89406);background-image:-o-linear-gradient(top,#fbb450,#f89406);background-image:linear-gradient(top,#fbb450,#f89406);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#fbb450',endColorstr='#f89406',GradientType=0);border-color:#f89406 #f89406 #ad6704;border-color:rgba(0,0,0,0.1) rgba(0,0,0,0.1) rgba(0,0,0,0.25);*background-color:#f89406;filter:progid:DXImageTransform.Microsoft.gradient(enabled = false)}.header .btn-warning:hover,.header .btn-warning:active,.header .btn-warning.active,.header .btn-warning.disabled,.header .btn-warning[disabled]{background-color:#f89406;*background-color:#df8505}.header .btn-warning:active,.header .btn-warning.active{background-color:#c67605 \9}.header .btn-danger{background-color:#da4f49;background-image:-moz-linear-gradient(top,#ee5f5b,#bd362f);background-image:-ms-linear-gradient(top,#ee5f5b,#bd362f);background-image:-webkit-gradient(linear,0 0,0 100%,from(#ee5f5b),to(#bd362f));background-image:-webkit-linear-gradient(top,#ee5f5b,#bd362f);background-image:-o-linear-gradient(top,#ee5f5b,#bd362f);background-image:linear-gradient(top,#ee5f5b,#bd362f);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ee5f5b',endColorstr='#bd362f',GradientType=0);border-color:#bd362f #bd362f #802420;border-color:rgba(0,0,0,0.1) rgba(0,0,0,0.1) rgba(0,0,0,0.25);*background-color:#bd362f;filter:progid:DXImageTransform.Microsoft.gradient(enabled = false)}.header .btn-danger:hover,.header .btn-danger:active,.header .btn-danger.active,.header .btn-danger.disabled,.header .btn-danger[disabled]{background-color:#bd362f;*background-color:#a9302a}.header .btn-danger:active,.header .btn-danger.active{background-color:#942a25 \9}.header .btn-success{background-color:#5bb75b;background-image:-moz-linear-gradient(top,#62c462,#51a351);background-image:-ms-linear-gradient(top,#62c462,#51a351);background-image:-webkit-gradient(linear,0 0,0 100%,from(#62c462),to(#51a351));background-image:-webkit-linear-gradient(top,#62c462,#51a351);background-image:-o-linear-gradient(top,#62c462,#51a351);background-image:linear-gradient(top,#62c462,#51a351);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#62c462',endColorstr='#51a351',GradientType=0);border-color:#51a351 #51a351 #387038;border-color:rgba(0,0,0,0.1) rgba(0,0,0,0.1) rgba(0,0,0,0.25);*background-color:#51a351;filter:progid:DXImageTransform.Microsoft.gradient(enabled = false)}.header .btn-success:hover,.header .btn-success:active,.header .btn-success.active,.header .btn-success.disabled,.header .btn-success[disabled]{background-color:#51a351;*background-color:#499249}.header .btn-success:active,.header .btn-success.active{background-color:#408140 \9}.header .btn-info{background-color:#49afcd;background-image:-moz-linear-gradient(top,#5bc0de,#2f96b4);background-image:-ms-linear-gradient(top,#5bc0de,#2f96b4);background-image:-webkit-gradient(linear,0 0,0 100%,from(#5bc0de),to(#2f96b4));background-image:-webkit-linear-gradient(top,#5bc0de,#2f96b4);background-image:-o-linear-gradient(top,#5bc0de,#2f96b4);background-image:linear-gradient(top,#5bc0de,#2f96b4);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#5bc0de',endColorstr='#2f96b4',GradientType=0);border-color:#2f96b4 #2f96b4 #1f6377;border-color:rgba(0,0,0,0.1) rgba(0,0,0,0.1) rgba(0,0,0,0.25);*background-color:#2f96b4;filter:progid:DXImageTransform.Microsoft.gradient(enabled = false)}.header .btn-info:hover,.header .btn-info:active,.header .btn-info.active,.header .btn-info.disabled,.header .btn-info[disabled]{background-color:#2f96b4;*background-color:#2a85a0}.header .btn-info:active,.header .btn-info.active{background-color:#24748c \9}.header .btn-inverse{background-color:#414141;background-image:-moz-linear-gradient(top,#555,#222);background-image:-ms-linear-gradient(top,#555,#222);background-image:-webkit-gradient(linear,0 0,0 100%,from(#555),to(#222));background-image:-webkit-linear-gradient(top,#555,#222);background-image:-o-linear-gradient(top,#555,#222);background-image:linear-gradient(top,#555,#222);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#555555',endColorstr='#222222',GradientType=0);border-color:#222 #222 #000;border-color:rgba(0,0,0,0.1) rgba(0,0,0,0.1) rgba(0,0,0,0.25);*background-color:#222;filter:progid:DXImageTransform.Microsoft.gradient(enabled = false)}.header .btn-inverse:hover,.header .btn-inverse:active,.header .btn-inverse.active,.header .btn-inverse.disabled,.header .btn-inverse[disabled]{background-color:#222;*background-color:#151515}.header .btn-inverse:active,.header .btn-inverse.active{background-color:#080808 \9}.header button.btn,.header input[type="submit"].btn{*padding-top:2px;*padding-bottom:2px}.header button.btn::-moz-focus-inner,.header input[type="submit"].btn::-moz-focus-inner{padding:0;border:0}.header button.btn.btn-large,.header input[type="submit"].btn.btn-large{*padding-top:7px;*padding-bottom:7px}.header button.btn.btn-small,.header input[type="submit"].btn.btn-small{*padding-top:3px;*padding-bottom:3px}.header button.btn.btn-mini,.header input[type="submit"].btn.btn-mini{*padding-top:1px;*padding-bottom:1px}.header .well{min-height:20px;padding:19px;margin-bottom:20px;background-color:#f5f5f5;border:1px solid #eee;border:1px solid rgba(0,0,0,0.05);-webkit-border-radius:4px;-moz-border-radius:4px;border-radius:4px;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,0.05);-moz-box-shadow:inset 0 1px 1px rgba(0,0,0,0.05);box-shadow:inset 0 1px 1px rgba(0,0,0,0.05)}.header .well blockquote{border-color:#ddd;border-color:rgba(0,0,0,0.15)}.header .well-large{padding:24px;-webkit-border-radius:6px;-moz-border-radius:6px;border-radius:6px}.header .well-small{padding:9px;-webkit-border-radius:3px;-moz-border-radius:3px;border-radius:3px}
|
8
|
+
.header .label { text-align: right; }
|
9
|
+
.header .controls { text-align: center; }
|
10
|
+
.message {
|
11
|
+
width: 760px;
|
12
|
+
margin: 10px auto;
|
13
|
+
padding: 0px 5px;
|
14
|
+
border: 1px solid grey;
|
15
|
+
box-shadow: 3px 3px 3px silver;
|
42
16
|
}
|
17
|
+
</style>
|
18
|
+
<div class="header">
|
19
|
+
<div class="well">
|
20
|
+
<div class="row">
|
21
|
+
<div class="from field span6">
|
22
|
+
<strong class="label label-info span1">From:</strong>
|
23
|
+
|
24
|
+
<%= from %>
|
25
|
+
</div>
|
43
26
|
|
44
|
-
|
45
|
-
|
46
|
-
|
27
|
+
<div class="to field span6">
|
28
|
+
<strong class="label label-info span1">To:</strong>
|
29
|
+
|
30
|
+
<%= email.to.join ", " unless email.to.empty? %>
|
31
|
+
</div>
|
47
32
|
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
33
|
+
<% if email.cc || email.bcc %>
|
34
|
+
<% if email.cc %>
|
35
|
+
<div class="cc field span6">
|
36
|
+
<strong class="label label-info span1">CC:</strong>
|
37
|
+
|
38
|
+
<%= email.cc.join ", " %>
|
39
|
+
</div>
|
40
|
+
<% end %>
|
52
41
|
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
42
|
+
<% if email.bcc %>
|
43
|
+
<div class="cc field span6">
|
44
|
+
<strong class="label label-info span1">BCC:</strong>
|
45
|
+
|
46
|
+
<%= email.bcc.join ", " %>
|
47
|
+
</div>
|
48
|
+
<% end %>
|
49
|
+
<% end %>
|
57
50
|
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
51
|
+
<% unless reply_to.empty? %>
|
52
|
+
<div class="reply-to field span6">
|
53
|
+
<strong class="label label-info span1">Reply-To:</strong>
|
54
|
+
|
55
|
+
<%= reply_to %>
|
56
|
+
</div>
|
57
|
+
<% end %>
|
62
58
|
|
63
|
-
|
64
|
-
|
59
|
+
<div class="subject field span6">
|
60
|
+
<strong class="label label-info span1">Subject:</strong>
|
61
|
+
|
62
|
+
<%= email.subject %>
|
63
|
+
</div>
|
65
64
|
|
66
|
-
|
67
|
-
|
65
|
+
<div class="date field span6">
|
66
|
+
<strong class="label label-info span1">Date:</strong>
|
67
|
+
|
68
|
+
<%= Time.now.strftime "%b %e, %Y %I:%M:%S %p %Z" %>
|
69
|
+
</div>
|
68
70
|
|
69
|
-
|
70
|
-
|
71
|
-
|
71
|
+
<% if attachments.any? %>
|
72
|
+
<div class="attachments field span12">
|
73
|
+
<strong class="label label-info span2">Attachments:</strong>
|
74
|
+
|
75
|
+
<%= attachments.map { |a| "<a href='#{a.last}'>#{a.first}</a>" }.join ', ' %>
|
76
|
+
</div>
|
77
|
+
<% end %>
|
78
|
+
</div>
|
79
|
+
</div>
|
72
80
|
|
73
81
|
<% if email.multipart? %>
|
74
|
-
<
|
75
|
-
<%
|
76
|
-
<a href="
|
77
|
-
<%
|
78
|
-
<a href="
|
82
|
+
<div class="controls">
|
83
|
+
<% case when type == "rich" && email.text_part %>
|
84
|
+
<a href="plain.html" class="btn btn-large">Text</a>
|
85
|
+
<% when type == "plain" && email.html_part %>
|
86
|
+
<a href="rich.html" class="btn btn-large">HTML</a>
|
79
87
|
<% end %>
|
80
|
-
</
|
88
|
+
</div>
|
81
89
|
<% end %>
|
90
|
+
</div>
|
82
91
|
</div>
|
83
92
|
|
84
|
-
|
85
|
-
|
86
|
-
|
87
|
-
|
88
|
-
|
93
|
+
<div class="message">
|
94
|
+
<% unless type == "plain" %>
|
95
|
+
<%= body %>
|
96
|
+
<% else %>
|
97
|
+
<pre><%= CGI.escapeHTML body %></pre>
|
98
|
+
<% end %>
|
99
|
+
</div>
|
data/lib/email_spy/message.rb
CHANGED
@@ -1,19 +1,15 @@
|
|
1
1
|
module EmailSpy
|
2
2
|
class Message
|
3
3
|
attr_reader :email
|
4
|
+
attr_reader :attachments
|
4
5
|
|
5
6
|
def initialize(location, email, part = nil)
|
6
|
-
@location = location
|
7
|
-
@email = email
|
8
|
-
@part = part
|
7
|
+
@location, @email, @part, @attachments = location, email, part, []
|
9
8
|
end
|
10
9
|
|
11
10
|
def render
|
12
|
-
|
13
|
-
|
14
|
-
File.open filepath, 'w' do |file|
|
15
|
-
file.write ERB.new(template).result binding
|
16
|
-
end
|
11
|
+
create_attachments unless email.attachments.empty?
|
12
|
+
create_templates filepath, binding
|
17
13
|
end
|
18
14
|
|
19
15
|
def template
|
@@ -33,15 +29,51 @@ module EmailSpy
|
|
33
29
|
end
|
34
30
|
|
35
31
|
def from
|
36
|
-
@from ||= @email.from
|
32
|
+
@from ||= Array(@email.from).join ", "
|
33
|
+
end
|
34
|
+
|
35
|
+
def reply_to
|
36
|
+
@reply_to ||= Array(@email.reply_to).join ", "
|
37
37
|
end
|
38
38
|
|
39
39
|
def type
|
40
|
-
content_type =~ /html/
|
40
|
+
if content_type =~ /html/ then "rich" else "plain" end
|
41
41
|
end
|
42
42
|
|
43
43
|
def encoding
|
44
|
-
body.respond_to?
|
44
|
+
if body.respond_to? :encoding then body.encoding else "utf-8" end
|
45
|
+
end
|
46
|
+
|
47
|
+
private
|
48
|
+
|
49
|
+
def create_templates(file_path, binding)
|
50
|
+
FileUtils.mkdir_p @location
|
51
|
+
|
52
|
+
File.open file_path, 'w' do |file|
|
53
|
+
file.write ERB.new(template).result binding
|
54
|
+
end
|
55
|
+
end
|
56
|
+
|
57
|
+
def create_attachments
|
58
|
+
FileUtils.mkdir_p attachments_directory
|
59
|
+
|
60
|
+
email.attachments.each &method(:save_attachment)
|
61
|
+
end
|
62
|
+
|
63
|
+
def attachments_directory
|
64
|
+
File.join @location, 'attachments'
|
65
|
+
end
|
66
|
+
|
67
|
+
def attachment_path(attachment)
|
68
|
+
File.join attachments_directory, attachment.filename
|
69
|
+
end
|
70
|
+
|
71
|
+
def save_attachment(attachment)
|
72
|
+
File.open attachment_path(attachment), 'wb' do |file|
|
73
|
+
file.write attachment.body.raw_source
|
74
|
+
end unless File.exists? attachment_path attachment
|
75
|
+
|
76
|
+
@attachments << [attachment.filename, "attachments/#{URI.escape attachment.filename }"]
|
45
77
|
end
|
46
78
|
end
|
47
79
|
end
|
data/lib/email_spy/railtie.rb
CHANGED
@@ -1,7 +1,8 @@
|
|
1
1
|
module EmailSpy
|
2
2
|
class Railtie < Rails::Railtie
|
3
3
|
initializer "emailspy.add_delivery_method" do
|
4
|
-
|
4
|
+
path_to_emails = Rails.root.join "tmp", EMAIL_DIRECTORY_NAME
|
5
|
+
ActionMailer::Base.add_delivery_method :email_spy, EmailSpy::DeliveryMethod, location: path_to_emails
|
5
6
|
end
|
6
7
|
end
|
7
8
|
end
|
data/lib/email_spy/version.rb
CHANGED
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: email_spy
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.0
|
4
|
+
version: 1.6.0
|
5
5
|
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -9,7 +9,7 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date: 2012-06-
|
12
|
+
date: 2012-06-21 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: launchy
|