inbox 0.0.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/README.md +126 -0
- data/app/assets/images/inbox/results_bg.png +0 -0
- data/app/assets/images/inbox/tree_bg.png +0 -0
- data/app/assets/javascripts/inbox/application.js +1 -2
- data/app/assets/javascripts/inbox/emails.js +2 -0
- data/app/assets/stylesheets/inbox/emails.css +59 -0
- data/app/assets/stylesheets/inbox/panel.css.erb +229 -0
- data/app/assets/stylesheets/inbox/reset.css +53 -0
- data/app/controllers/inbox/application_controller.rb +1 -1
- data/app/controllers/inbox/emails_controller.rb +52 -0
- data/app/helpers/inbox/emails_helper.rb +4 -0
- data/app/mailers/inbox/email_mailer.rb +11 -0
- data/app/models/inbox/email.rb +51 -0
- data/app/views/inbox/emails/index.html.erb +0 -0
- data/app/views/inbox/emails/new.html.erb +9 -0
- data/app/views/inbox/emails/show.html.erb +48 -0
- data/app/views/layouts/inbox/application.html.erb +10 -9
- data/app/views/layouts/inbox/inbox.html.erb +25 -0
- data/config/routes.rb +4 -0
- data/lib/inbox/engine.rb +4 -0
- data/lib/inbox/version.rb +1 -1
- data/lib/inbox.rb +30 -0
- data/test/dummy/config/environments/development.rb +3 -1
- data/test/dummy/config/initializers/backtrace_silencers.rb +1 -1
- data/test/dummy/db/development.sqlite3 +0 -0
- data/test/dummy/db/production.sqlite3 +0 -0
- data/test/dummy/db/test.sqlite3 +0 -0
- data/test/dummy/log/development.log +3641 -0
- data/test/dummy/log/test.log +0 -0
- data/test/dummy/tmp/cache/assets/C4D/8B0/sprockets%2F5e1b589842222e2ea0043890c2c84539 +0 -0
- data/test/dummy/tmp/cache/assets/C6F/5C0/sprockets%2F259fb59d511a70d46436201b6770a04a +0 -0
- data/test/dummy/tmp/cache/assets/CF2/F90/sprockets%2F5378bb2470df984ccf2643991a6e476d +0 -0
- data/test/dummy/tmp/cache/assets/D0B/330/sprockets%2F582a2b19d6be92a0393afa63894d721a +0 -0
- data/test/dummy/tmp/cache/assets/D1B/CE0/sprockets%2F09c9c18794df089e62443d3debb117e5 +0 -0
- data/test/dummy/tmp/cache/assets/D1D/BA0/sprockets%2F29888f599d35bb11e4a8183d6dc5e23a +0 -0
- data/test/dummy/tmp/cache/assets/D1F/600/sprockets%2Fdd3578c9bd0719efe092c59655a25c55 +0 -0
- data/test/dummy/tmp/cache/assets/D21/920/sprockets%2F85fd59fe11746a33f5f917a923d84be3 +0 -0
- data/test/dummy/tmp/cache/assets/D4D/FB0/sprockets%2Fd5743837e8babdab4825364c4ee86f73 +0 -0
- data/test/dummy/tmp/cache/assets/D4F/520/sprockets%2F88ecb483df9e177ee775202ba0691ec7 +0 -0
- data/test/dummy/tmp/cache/assets/D6E/300/sprockets%2Fcc54b61039f74d6b8a2a7d04ad9d77f0 +0 -0
- data/test/dummy/tmp/cache/assets/D74/390/sprockets%2F5eda33e637dd54ff6a27bb76c482a473 +0 -0
- data/test/dummy/tmp/cache/assets/D76/170/sprockets%2Ffa5e461b362e11c80d5fd9e877fb63e2 +0 -0
- data/test/dummy/tmp/cache/assets/D7F/2D0/sprockets%2F141c2c9cb5235c8d21a00fbc8d7a2ab1 +0 -0
- data/test/dummy/tmp/cache/assets/D84/AA0/sprockets%2F5e841fe9d79e3ebf4333be8842b77bc5 +0 -0
- data/test/dummy/tmp/cache/assets/DA0/520/sprockets%2Fb8e93a54478c1f1a0e750ef2cbf74f3c +0 -0
- data/test/dummy/tmp/cache/assets/DC1/520/sprockets%2Feb8cea402f0bf04560adcd0cb8807b88 +0 -0
- data/test/dummy/tmp/mails/1345541756.4616725 +11 -0
- data/test/functional/inbox/email_test.rb +9 -0
- data/test/functional/inbox/emails_controller_test.rb +16 -0
- data/test/unit/helpers/inbox/emails_helper_test.rb +6 -0
- metadata +146 -56
- data/README.rdoc +0 -3
data/README.md
ADDED
@@ -0,0 +1,126 @@
|
|
1
|
+
Inbox
|
2
|
+
=====
|
3
|
+
|
4
|
+
|
5
|
+
Description
|
6
|
+
-----------
|
7
|
+
|
8
|
+
* Preview send emails in development and test mode.
|
9
|
+
|
10
|
+
* Test them using your standard Capybara matchers or
|
11
|
+
any other testing framework that you prefer.
|
12
|
+
|
13
|
+
|
14
|
+
Installation
|
15
|
+
------------
|
16
|
+
|
17
|
+
In your `Gemfile` add:
|
18
|
+
|
19
|
+
```ruby
|
20
|
+
gem 'inbox'
|
21
|
+
```
|
22
|
+
|
23
|
+
And run:
|
24
|
+
|
25
|
+
```
|
26
|
+
bundle install
|
27
|
+
```
|
28
|
+
|
29
|
+
|
30
|
+
Setup
|
31
|
+
-----
|
32
|
+
|
33
|
+
Mount engine in `config/routes.rb`
|
34
|
+
|
35
|
+
```ruby
|
36
|
+
Rails.application.routes.draw do
|
37
|
+
mount Inbox::Engine => "/inbox"
|
38
|
+
end
|
39
|
+
```
|
40
|
+
|
41
|
+
Feel free to mount it under different route
|
42
|
+
if this one is already taken in your application
|
43
|
+
|
44
|
+
```ruby
|
45
|
+
mount Inbox::Engine => "/mailer"
|
46
|
+
```
|
47
|
+
|
48
|
+
|
49
|
+
Usage
|
50
|
+
-----
|
51
|
+
|
52
|
+
### Manual
|
53
|
+
|
54
|
+
Navigate to `/inbox/<email>/emails` ex.: `/inbox/robert.pankowecki@gmail.com/emails`
|
55
|
+
to see a list of emails that would have been delivered to the user.
|
56
|
+
|
57
|
+
Click subject of the email to see its content
|
58
|
+
|
59
|
+
### Testing framework
|
60
|
+
|
61
|
+
In [capybara](https://github.com/jnicklas/capybara/) or [bbq](https://github.com/drugpl/bbq)
|
62
|
+
|
63
|
+
```ruby
|
64
|
+
visit("/inbox/robert.pankowecki@gmail.com/emails")
|
65
|
+
click_link("Subject of the email")
|
66
|
+
has_content?("This should be in email")
|
67
|
+
click_link("Some link in the email ex. account activation link")
|
68
|
+
```
|
69
|
+
|
70
|
+
The nice thing is that this is just HTML page displaying email content so you can use
|
71
|
+
your favorite testing framework (`BBQ`, `Capybara`, `Test::Unit`, `Spinach`, `Cucumber`, `RSpec`, whatever)
|
72
|
+
for checking the content of page. And you can reuse your matchers.
|
73
|
+
|
74
|
+
|
75
|
+
### Sending
|
76
|
+
|
77
|
+
Navigate to `/inbox/<email>/emails/new` ex.: `/inbox/robert.pankowecki@gmail.com/emails/new`
|
78
|
+
to see an ugly form for sending emails that you can use to play around and see if everything
|
79
|
+
works fine.
|
80
|
+
|
81
|
+
### Clear send emails
|
82
|
+
|
83
|
+
```ruby
|
84
|
+
ActionMailer::Base.deliveries.clear # in :test mode
|
85
|
+
Inbox::FileDelivery.new(ActionMailer::Base.inbox_settings).clear # in :inbox mode
|
86
|
+
```
|
87
|
+
|
88
|
+
Async (distributed / queue)
|
89
|
+
---------------------------
|
90
|
+
|
91
|
+
In case you want to have acceptance tests of emails that are
|
92
|
+
sent using external process (`resque`, `sidekiq`, ...) just set
|
93
|
+
|
94
|
+
```ruby
|
95
|
+
config.action_mailer.delivery_method = :inbox
|
96
|
+
```
|
97
|
+
|
98
|
+
in `config/environments/test.rb` and create `tmp/mails` directory.
|
99
|
+
|
100
|
+
|
101
|
+
If you send emails from your Rails models, controllers, services or use-cases you can stick with:
|
102
|
+
|
103
|
+
```ruby
|
104
|
+
config.action_mailer.delivery_method = :test
|
105
|
+
```
|
106
|
+
|
107
|
+
|
108
|
+
Look & Feel
|
109
|
+
-----------
|
110
|
+
|
111
|
+

|
112
|
+
|
113
|
+
|
114
|
+
Inspirations
|
115
|
+
------------
|
116
|
+
|
117
|
+
* [https://github.com/37signals/mail_view](https://github.com/37signals/mail_view)
|
118
|
+
* [https://github.com/ryanb/letter_opener](https://github.com/ryanb/letter_opener)
|
119
|
+
* [https://github.com/suhrawardi/capybara_email/](https://github.com/suhrawardi/capybara_email/)
|
120
|
+
* [https://github.com/pawelpacana/mail_inbox/](https://github.com/pawelpacana/mail_inbox/)
|
121
|
+
* [http://api.rubyonrails.org/](http://api.rubyonrails.org/)
|
122
|
+
|
123
|
+
License
|
124
|
+
-------
|
125
|
+
|
126
|
+
MIT-LICENSE
|
Binary file
|
Binary file
|
@@ -0,0 +1,59 @@
|
|
1
|
+
/*
|
2
|
+
Place all the styles related to the matching controller here.
|
3
|
+
They will automatically be included in application.css.
|
4
|
+
*/
|
5
|
+
|
6
|
+
#message_headers {
|
7
|
+
width: 75%;
|
8
|
+
padding: 20px 0 20px 0;
|
9
|
+
margin: 0;
|
10
|
+
background: #fff;
|
11
|
+
font-size: 12px;
|
12
|
+
font-family: "Lucida Grande";
|
13
|
+
border-bottom: 1px solid #dedede;
|
14
|
+
overflow: hidden;
|
15
|
+
float: left;
|
16
|
+
}
|
17
|
+
|
18
|
+
#message_headers dl {
|
19
|
+
margin: 0;
|
20
|
+
padding: 0;
|
21
|
+
}
|
22
|
+
|
23
|
+
#message_headers dt {
|
24
|
+
width: 60px;
|
25
|
+
padding: 1px;
|
26
|
+
float: left;
|
27
|
+
text-align: right;
|
28
|
+
font-weight: bold;
|
29
|
+
color: #7f7f7f;
|
30
|
+
}
|
31
|
+
|
32
|
+
#message_headers dd {
|
33
|
+
margin-left: 70px;
|
34
|
+
padding: 1px;
|
35
|
+
}
|
36
|
+
|
37
|
+
#message_headers p.alternate {
|
38
|
+
position: absolute;
|
39
|
+
top: 0;
|
40
|
+
right: 15px;
|
41
|
+
}
|
42
|
+
|
43
|
+
#message_headers p.alternate a {
|
44
|
+
color: #09c;
|
45
|
+
}
|
46
|
+
|
47
|
+
pre#message_body {
|
48
|
+
padding: 10px;
|
49
|
+
white-space: pre-wrap;
|
50
|
+
}
|
51
|
+
|
52
|
+
.clear {
|
53
|
+
clear: both;
|
54
|
+
display: block;
|
55
|
+
overflow: hidden;
|
56
|
+
visibility: hidden;
|
57
|
+
width: 0;
|
58
|
+
height: 0;
|
59
|
+
}
|
@@ -0,0 +1,229 @@
|
|
1
|
+
/* Panel (begin) */
|
2
|
+
.panel
|
3
|
+
{
|
4
|
+
float: left;
|
5
|
+
width: 25%;
|
6
|
+
height: 1000px;
|
7
|
+
top: 0;
|
8
|
+
left: 0;
|
9
|
+
background: #FFF;
|
10
|
+
font-family: "Helvetica Neue", "Arial", sans-serif;
|
11
|
+
}
|
12
|
+
|
13
|
+
/* Header with search box (begin) */
|
14
|
+
.panel .header
|
15
|
+
{
|
16
|
+
width: 100%;
|
17
|
+
height: 29px;
|
18
|
+
border-bottom: 1px solid #666;
|
19
|
+
position: relative;
|
20
|
+
left: 0; top: 0;
|
21
|
+
background: #e8e8e8;
|
22
|
+
}
|
23
|
+
|
24
|
+
.panel .header div
|
25
|
+
{
|
26
|
+
margin: 0 7px;
|
27
|
+
}
|
28
|
+
.panel .header table
|
29
|
+
{
|
30
|
+
height: 29px;
|
31
|
+
width: 100%;
|
32
|
+
}
|
33
|
+
|
34
|
+
.panel .header table td
|
35
|
+
{
|
36
|
+
vertical-align: middle;
|
37
|
+
text-align: middle;
|
38
|
+
}
|
39
|
+
|
40
|
+
.panel .header label
|
41
|
+
{
|
42
|
+
position: absolute;
|
43
|
+
font-size: 12px;
|
44
|
+
line-height: 29px;
|
45
|
+
margin-left: 3px;
|
46
|
+
color: #777;
|
47
|
+
cursor: text;
|
48
|
+
}
|
49
|
+
|
50
|
+
.panel .header table input
|
51
|
+
{
|
52
|
+
width: 100%;
|
53
|
+
box-sizing: border-box;
|
54
|
+
-moz-box-sizing: border-box;
|
55
|
+
-webkit-box-sizing: border-box;
|
56
|
+
display: inline-block;
|
57
|
+
-webkit-appearance: searchfield;
|
58
|
+
height: 22px;
|
59
|
+
//height: auto;
|
60
|
+
}
|
61
|
+
|
62
|
+
/* Header with search box (end) */
|
63
|
+
|
64
|
+
|
65
|
+
/* Results (begin) */
|
66
|
+
.panel .result
|
67
|
+
{
|
68
|
+
|
69
|
+
height: 1000px;
|
70
|
+
bottom: 0;
|
71
|
+
left: 0;
|
72
|
+
width: 100%;
|
73
|
+
|
74
|
+
overflow-y: scroll;
|
75
|
+
overflow-x: hidden;
|
76
|
+
-overflow-y: hidden;
|
77
|
+
background: #EEE url(<%= image_path("inbox/results_bg.png") %>);
|
78
|
+
z-index: 2;
|
79
|
+
//zoom:1;
|
80
|
+
}
|
81
|
+
|
82
|
+
.panel .result ul
|
83
|
+
{
|
84
|
+
font-size: 0.8em;
|
85
|
+
width: 100%;
|
86
|
+
background: #EEE url(<%= image_path("inbox/results_bg.png") %>);
|
87
|
+
//zoom:1;
|
88
|
+
}
|
89
|
+
|
90
|
+
.panel .result ul li
|
91
|
+
{
|
92
|
+
height: 46px;
|
93
|
+
overflow: hidden;
|
94
|
+
padding: 4px 10px 0 10px;
|
95
|
+
cursor: pointer;
|
96
|
+
}
|
97
|
+
|
98
|
+
.panel .result ul li h1
|
99
|
+
{
|
100
|
+
font-size: 13px;
|
101
|
+
font-weight: normal;
|
102
|
+
color: #333;
|
103
|
+
margin-bottom: 2px;
|
104
|
+
white-space: nowrap;
|
105
|
+
}
|
106
|
+
|
107
|
+
.panel .result ul li p
|
108
|
+
{
|
109
|
+
font-size: 11px;
|
110
|
+
color: #333;
|
111
|
+
margin-bottom: 2px;
|
112
|
+
white-space: nowrap;
|
113
|
+
}
|
114
|
+
|
115
|
+
.panel .result ul li h1 i,
|
116
|
+
.panel .result ul li p.snippet
|
117
|
+
{
|
118
|
+
color: #777;
|
119
|
+
}
|
120
|
+
|
121
|
+
.panel .result ul li b
|
122
|
+
{
|
123
|
+
color: #000;
|
124
|
+
}
|
125
|
+
|
126
|
+
.panel .result ul li.current
|
127
|
+
{
|
128
|
+
background: #C52F24;
|
129
|
+
}
|
130
|
+
|
131
|
+
.panel .result ul li.current h1,
|
132
|
+
.panel .result ul li.current p
|
133
|
+
{
|
134
|
+
color: #D9D9D9;
|
135
|
+
}
|
136
|
+
|
137
|
+
.panel .result ul li.current h1 i,
|
138
|
+
.panel .result ul li.current p.snippet
|
139
|
+
{
|
140
|
+
color: #ACACAC;
|
141
|
+
}
|
142
|
+
|
143
|
+
.panel .result ul li.current b
|
144
|
+
{
|
145
|
+
color: #FFF;
|
146
|
+
}
|
147
|
+
|
148
|
+
|
149
|
+
.panel .result ul li:hover,
|
150
|
+
.panel .result ul li.selected
|
151
|
+
{
|
152
|
+
background: #d0d0d0;
|
153
|
+
}
|
154
|
+
|
155
|
+
.panel .result ul li.current:hover
|
156
|
+
{
|
157
|
+
background: #C52F24;
|
158
|
+
}
|
159
|
+
|
160
|
+
.panel .result ul li .badge
|
161
|
+
{
|
162
|
+
margin-right: 0.4em;
|
163
|
+
margin-left: -0.2em;
|
164
|
+
padding: 0 0.2em;
|
165
|
+
color: #000;
|
166
|
+
border-radius: 3px;
|
167
|
+
}
|
168
|
+
|
169
|
+
.panel .result ul li .badge_1
|
170
|
+
{
|
171
|
+
background: #ACDBF4;
|
172
|
+
}
|
173
|
+
|
174
|
+
.panel .result ul li.current .badge_1
|
175
|
+
{
|
176
|
+
background: #97BFD7;
|
177
|
+
}
|
178
|
+
|
179
|
+
.panel .result ul li .badge_2
|
180
|
+
{
|
181
|
+
background: #ACF3C3;
|
182
|
+
}
|
183
|
+
|
184
|
+
.panel .result ul li.current .badge_2
|
185
|
+
{
|
186
|
+
background: #98D7AC;
|
187
|
+
}
|
188
|
+
|
189
|
+
.panel .result ul li .badge_3
|
190
|
+
{
|
191
|
+
background: #E0F3AC;
|
192
|
+
}
|
193
|
+
|
194
|
+
.panel .result ul li.current .badge_3
|
195
|
+
{
|
196
|
+
background: #C4D798;
|
197
|
+
}
|
198
|
+
|
199
|
+
.panel .result ul li .badge_4
|
200
|
+
{
|
201
|
+
background: #D7CA98;
|
202
|
+
}
|
203
|
+
|
204
|
+
.panel .result ul li.current .badge_4
|
205
|
+
{
|
206
|
+
background: #A6B0AC;
|
207
|
+
}
|
208
|
+
|
209
|
+
.panel .result ul li .badge_5
|
210
|
+
{
|
211
|
+
background: #F3C8AC;
|
212
|
+
}
|
213
|
+
|
214
|
+
.panel .result ul li.current .badge_5
|
215
|
+
{
|
216
|
+
background: #D7B198;
|
217
|
+
}
|
218
|
+
|
219
|
+
.panel .result ul li .badge_6
|
220
|
+
{
|
221
|
+
background: #F3ACC3;
|
222
|
+
}
|
223
|
+
|
224
|
+
.panel .result ul li.current .badge_6
|
225
|
+
{
|
226
|
+
background: #D798AB;
|
227
|
+
}
|
228
|
+
|
229
|
+
/* Panel (end) */
|
@@ -0,0 +1,53 @@
|
|
1
|
+
/* http://meyerweb.com/eric/tools/css/reset/ */
|
2
|
+
/* v1.0 | 20080212 */
|
3
|
+
|
4
|
+
html, body, div, span, applet, object, iframe,
|
5
|
+
h1, h2, h3, h4, h5, h6, p, blockquote, pre,
|
6
|
+
a, abbr, acronym, address, big, cite, code,
|
7
|
+
del, dfn, em, font, img, ins, kbd, q, s, samp,
|
8
|
+
small, strike, strong, sub, sup, tt, var,
|
9
|
+
b, u, i, center,
|
10
|
+
dl, dt, dd, ol, ul, li,
|
11
|
+
fieldset, form, label, legend,
|
12
|
+
table, caption, tbody, tfoot, thead, tr, th, td {
|
13
|
+
margin: 0;
|
14
|
+
padding: 0;
|
15
|
+
border: 0;
|
16
|
+
outline: 0;
|
17
|
+
font-size: 100%;
|
18
|
+
vertical-align: baseline;
|
19
|
+
background: transparent;
|
20
|
+
}
|
21
|
+
body {
|
22
|
+
line-height: 1;
|
23
|
+
}
|
24
|
+
ol, ul {
|
25
|
+
list-style: none;
|
26
|
+
}
|
27
|
+
blockquote, q {
|
28
|
+
quotes: none;
|
29
|
+
}
|
30
|
+
blockquote:before, blockquote:after,
|
31
|
+
q:before, q:after {
|
32
|
+
content: '';
|
33
|
+
content: none;
|
34
|
+
}
|
35
|
+
|
36
|
+
/* remember to define focus styles! */
|
37
|
+
:focus {
|
38
|
+
outline: 0;
|
39
|
+
}
|
40
|
+
|
41
|
+
/* remember to highlight inserts somehow! */
|
42
|
+
ins {
|
43
|
+
text-decoration: none;
|
44
|
+
}
|
45
|
+
del {
|
46
|
+
text-decoration: line-through;
|
47
|
+
}
|
48
|
+
|
49
|
+
/* tables still need 'cellspacing="0"' in the markup */
|
50
|
+
table {
|
51
|
+
border-collapse: collapse;
|
52
|
+
border-spacing: 0;
|
53
|
+
}
|
@@ -0,0 +1,52 @@
|
|
1
|
+
require 'mail'
|
2
|
+
require 'pathname'
|
3
|
+
|
4
|
+
module Inbox
|
5
|
+
class EmailsController < ApplicationController
|
6
|
+
|
7
|
+
layout 'inbox/inbox'
|
8
|
+
before_filter do
|
9
|
+
@mail = params[:mail]
|
10
|
+
mailer = case ActionMailer::Base.delivery_method
|
11
|
+
when :test
|
12
|
+
Mail::TestMailer
|
13
|
+
when :inbox
|
14
|
+
Inbox::FileDelivery.new ActionMailer::Base.inbox_settings
|
15
|
+
else
|
16
|
+
raise "ArgumentError"
|
17
|
+
end
|
18
|
+
|
19
|
+
@emails = mailer.deliveries.select{|e| Array.wrap(e.to).any?{|m| m.include?(@mail) } }.reverse
|
20
|
+
end
|
21
|
+
|
22
|
+
def index
|
23
|
+
|
24
|
+
end
|
25
|
+
|
26
|
+
def show
|
27
|
+
@email = @emails.find{|e| e.message_id == params[:id] }
|
28
|
+
@body_part = @email
|
29
|
+
|
30
|
+
if @email.multipart?
|
31
|
+
format = "." + (params[:format] || :html).to_s
|
32
|
+
content_type = Rack::Mime.mime_type(format)
|
33
|
+
@body_part = @email.parts.find { |part| part.content_type.match(content_type) } || @email.parts.first
|
34
|
+
end
|
35
|
+
end
|
36
|
+
|
37
|
+
def new
|
38
|
+
@email = Email.new()
|
39
|
+
end
|
40
|
+
|
41
|
+
def create
|
42
|
+
@email = Email.new(params[:email])
|
43
|
+
if @email.valid?
|
44
|
+
@email.deliver
|
45
|
+
redirect_to :action => :index
|
46
|
+
else
|
47
|
+
render :new
|
48
|
+
end
|
49
|
+
end
|
50
|
+
|
51
|
+
end
|
52
|
+
end
|
@@ -0,0 +1,51 @@
|
|
1
|
+
module Inbox
|
2
|
+
class Email
|
3
|
+
extend ::ActiveModel::Naming
|
4
|
+
extend ::ActiveModel::Callbacks
|
5
|
+
extend ::ActiveModel::Translation
|
6
|
+
|
7
|
+
include ::ActiveModel::Conversion
|
8
|
+
include ::ActiveModel::Validations
|
9
|
+
include ::ActiveModel::Validations::Callbacks
|
10
|
+
include ::ActiveModel::MassAssignmentSecurity
|
11
|
+
# include ::ActiveModel::Warnings
|
12
|
+
|
13
|
+
PopularHeaders = [:from, :to, :cc, :bcc, :subject, :body, :reply_to]
|
14
|
+
|
15
|
+
attr_accessible *PopularHeaders
|
16
|
+
|
17
|
+
def initialize(attributes = {})
|
18
|
+
self.attributes = attributes
|
19
|
+
end
|
20
|
+
|
21
|
+
def attributes=(values)
|
22
|
+
values.stringify_keys!
|
23
|
+
@attributes = attributes.merge sanitize_for_mass_assignment(values)
|
24
|
+
end
|
25
|
+
|
26
|
+
def attributes
|
27
|
+
@attributes ||= ActiveSupport::HashWithIndifferentAccess.new
|
28
|
+
@attributes.clone
|
29
|
+
end
|
30
|
+
|
31
|
+
PopularHeaders.each do |header|
|
32
|
+
define_method(header) do
|
33
|
+
attributes[header]
|
34
|
+
end
|
35
|
+
|
36
|
+
define_method(:"#{header}=") do |value|
|
37
|
+
attributes[header]= value
|
38
|
+
end
|
39
|
+
end
|
40
|
+
|
41
|
+
def persisted?
|
42
|
+
false
|
43
|
+
end
|
44
|
+
|
45
|
+
def deliver
|
46
|
+
body = attributes.delete('body')
|
47
|
+
EmailMailer.normal(attributes, body).deliver
|
48
|
+
end
|
49
|
+
|
50
|
+
end
|
51
|
+
end
|
File without changes
|
@@ -0,0 +1,48 @@
|
|
1
|
+
<head>
|
2
|
+
<meta http-equiv="Content-Type" content="text/html; charset=<%= @body_part.charset %>" />
|
3
|
+
</head>
|
4
|
+
<div id="message_headers">
|
5
|
+
<dl>
|
6
|
+
<dt>From:</dt>
|
7
|
+
<dd><%= Array.wrap(@email.from).join(", ") %> </dd>
|
8
|
+
|
9
|
+
<dt>Subject:</dt>
|
10
|
+
<dd><strong><%= @email.subject %></strong> </dd>
|
11
|
+
|
12
|
+
<dt>Date:</dt>
|
13
|
+
<dd><%= Time.now.strftime("%b %e, %Y %I:%M:%S %p %Z") %> </dd>
|
14
|
+
|
15
|
+
<dt>To:</dt>
|
16
|
+
<dd><%= Array.wrap(@email.to).join(", ") %> </dd>
|
17
|
+
|
18
|
+
<% if @email.cc.present? %>
|
19
|
+
<dt>Cc:</dt>
|
20
|
+
<dd><%= Array.wrap(@email.cc).join(", ") %> </dd>
|
21
|
+
<% end %>
|
22
|
+
|
23
|
+
<% if @email.bcc.present? %>
|
24
|
+
<dt>Bcc:</dt>
|
25
|
+
<dd><%= Array.wrap(@email.bcc).join(", ") %> </dd>
|
26
|
+
<% end %>
|
27
|
+
</dl>
|
28
|
+
|
29
|
+
<% if @email.multipart? %>
|
30
|
+
<p class="alternate">
|
31
|
+
<% if @body_part.content_type && @body_part.content_type.match(/text\/html/) %>
|
32
|
+
<a href="<%= :x %>.txt">View plain text version</a>
|
33
|
+
<% else %>
|
34
|
+
<a href="<%= :y %>.html">View HTML version</a>
|
35
|
+
<% end %>
|
36
|
+
</p>
|
37
|
+
<% end %>
|
38
|
+
</div>
|
39
|
+
|
40
|
+
<div id="message_body">
|
41
|
+
<% if @body_part.content_type && @body_part.content_type.match(/text\/html/) %>
|
42
|
+
<%= raw @body_part.body %>
|
43
|
+
<% else %>
|
44
|
+
<pre id="message_body">
|
45
|
+
<%= auto_link @body_part.body %>
|
46
|
+
</pre>
|
47
|
+
<% end %>
|
48
|
+
</div>
|
@@ -1,14 +1,15 @@
|
|
1
1
|
<!DOCTYPE html>
|
2
2
|
<html>
|
3
|
-
<head>
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
</head>
|
9
|
-
<body>
|
3
|
+
<head>
|
4
|
+
<title>Inbox</title>
|
5
|
+
<%= stylesheet_link_tag "inbox/application" %>
|
6
|
+
<%= javascript_include_tag "inbox/application" %>
|
7
|
+
<%= csrf_meta_tags %>
|
8
|
+
</head>
|
9
|
+
<body>
|
10
10
|
|
11
|
-
<%= yield %>
|
11
|
+
<%= tmp = yield :application %>
|
12
|
+
<%= yield if tmp.blank? %>
|
12
13
|
|
13
|
-
</body>
|
14
|
+
</body>
|
14
15
|
</html>
|