maily 0.6.3 → 0.7.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.gitignore +1 -0
- data/.travis.yml +5 -11
- data/Appraisals +4 -0
- data/CHANGELOG.md +90 -0
- data/MIT-LICENSE +1 -1
- data/README.md +21 -2
- data/app/assets/images/maily/icons/globe.svg +13 -0
- data/app/assets/images/maily/icons/paperclip.svg +8 -0
- data/app/assets/images/maily/logo.png +0 -0
- data/app/assets/stylesheets/maily/_variables.scss +6 -0
- data/app/assets/stylesheets/maily/application.scss +88 -96
- data/app/assets/stylesheets/maily/normalize.css +23 -129
- data/app/controllers/maily/emails_controller.rb +10 -5
- data/app/helpers/maily/application_helper.rb +15 -1
- data/app/helpers/maily/emails_helper.rb +10 -1
- data/app/views/layouts/maily/application.html.erb +5 -5
- data/app/views/maily/emails/edit.html.erb +16 -18
- data/app/views/maily/emails/index.html.erb +2 -4
- data/app/views/maily/emails/show.html.erb +61 -64
- data/app/views/maily/shared/_flash_messages.html.erb +7 -0
- data/app/views/maily/shared/_header.html.erb +4 -1
- data/app/views/maily/shared/_sidebar.html.erb +2 -2
- data/gemfiles/rails_4.2.gemfile +2 -2
- data/gemfiles/rails_5.0.gemfile +1 -1
- data/gemfiles/rails_5.1.gemfile +1 -1
- data/gemfiles/rails_5.2.gemfile +7 -0
- data/lib/maily.rb +1 -3
- data/lib/maily/email.rb +18 -13
- data/lib/maily/mailer.rb +32 -14
- data/lib/maily/version.rb +1 -1
- data/maily.gemspec +1 -2
- data/screenshot.png +0 -0
- data/spec/controllers_spec.rb +40 -1
- data/spec/dummy/app/mailers/notifier.rb +8 -0
- data/spec/dummy/lib/maily_hooks.rb +3 -0
- data/spec/email_spec.rb +5 -0
- data/spec/mailer_spec.rb +6 -1
- data/spec/maily_spec.rb +1 -1
- data/spec/spec_helper.rb +1 -0
- metadata +10 -26
- data/app/assets/images/maily/icons/maily.eot +0 -0
- data/app/assets/images/maily/icons/maily.svg +0 -90
- data/app/assets/images/maily/icons/maily.ttf +0 -0
- data/app/assets/images/maily/icons/maily.woff +0 -0
- data/app/assets/stylesheets/maily/icons.css +0 -199
- data/spec/dummy/app/mailers/.keep +0 -0
- data/spec/dummy/lib/assets/.keep +0 -0
@@ -1,73 +1,70 @@
|
|
1
|
-
|
2
|
-
<% if @maily_email.description %>
|
3
|
-
<div>
|
4
|
-
<b>Description </b><%= @maily_email.description %>
|
5
|
-
</div><br>
|
6
|
-
<% end %>
|
7
|
-
|
8
|
-
<ul class="maily_action_bar">
|
9
|
-
<li>
|
10
|
-
<em class="icon-maily-pencil"></em>
|
11
|
-
<%= link_to 'Edit', edit_maily_email_path(mailer: params[:mailer], email: params[:email], part: params[:part]) %>
|
12
|
-
</li>
|
13
|
-
|
14
|
-
<li class="maily_languages">
|
15
|
-
<% if Maily.available_locales.present? %>
|
16
|
-
<ul>
|
17
|
-
<li>
|
18
|
-
<em class="icon-maily-earth"></em>
|
19
|
-
Languages</li>
|
20
|
-
<% Maily.available_locales.each do |locale| %>
|
21
|
-
<li><%= link_to locale.upcase, url_for(params.to_unsafe_h.merge(locale: locale)) %></li>
|
22
|
-
<% end %>
|
23
|
-
</ul>
|
24
|
-
<% end %>
|
25
|
-
</li>
|
26
|
-
|
27
|
-
<li class="maily_splitter">|</li>
|
28
|
-
<li>
|
29
|
-
<%= form_tag(deliver_maily_email_path(mailer: params[:mailer], email: params[:email], locale: params[:locale]), method: :post, class: 'maily_send') do %>
|
30
|
-
<ul>
|
31
|
-
<li>Send to</li>
|
32
|
-
<li><%= email_field_tag :to, nil, class: 'maily_textfield', placeholder: "Enter email", required: true %></li>
|
33
|
-
<li><%= submit_tag 'Send', class: 'maily_button' %></li>
|
34
|
-
</ul>
|
35
|
-
<% end %>
|
36
|
-
</li>
|
37
|
-
</ul>
|
1
|
+
<%= email_description(@maily_email) %>
|
38
2
|
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
<% if @email.to %><li><b>To</b> <%= @email.to.join(', ') %></li><% end %>
|
44
|
-
<% if @email.cc %><li><b>Cc</b> <%= @email.cc.join(', ') %></li><% end %>
|
45
|
-
<% if @email.bcc %><li><b>Bcc</b> <%= @email.bcc.join(', ') %></li><% end %>
|
46
|
-
<% if @email.reply_to %><li><b>Reply to</b> <%= @email.reply_to.join(', ') %></li><% end %>
|
47
|
-
</ul>
|
3
|
+
<ul class="action_bar">
|
4
|
+
<li>
|
5
|
+
<%= link_to 'Edit', edit_maily_email_path(mailer: params[:mailer], email: params[:email], part: params[:part]) %>
|
6
|
+
</li>
|
48
7
|
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
<li
|
8
|
+
<li class="languages">
|
9
|
+
<% if Maily.available_locales.present? %>
|
10
|
+
<ul>
|
11
|
+
<li>
|
12
|
+
<%= icon 'globe' %> Languages
|
13
|
+
</li>
|
14
|
+
<% Maily.available_locales.each do |locale| %>
|
15
|
+
<li><%= link_to locale.upcase, url_for(params.to_unsafe_h.merge(locale: locale)) %></li>
|
16
|
+
<% end %>
|
53
17
|
</ul>
|
54
18
|
<% end %>
|
19
|
+
</li>
|
55
20
|
|
56
|
-
|
57
|
-
<iframe class="maily_preview" onload='javascript:resizeIframe(this);' src="<%= raw_maily_email_path(mailer: params[:mailer], email: params[:email], locale: params[:locale], part: params[:part]) %>" frameborder="1" width="100%"></iframe>
|
58
|
-
<% end %>
|
21
|
+
<li class="splitter">|</li>
|
59
22
|
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
<li>
|
64
|
-
|
65
|
-
|
66
|
-
<li><em class="icon-maily-attachment"></em><%= link_to attachment.filename, attachment_maily_email_path(mailer: params[:mailer], email: params[:email], attachment: attachment.filename) %></li>
|
67
|
-
<% end %>
|
68
|
-
</ul>
|
69
|
-
</li>
|
23
|
+
<li>
|
24
|
+
<%= form_tag(deliver_maily_email_path(mailer: params[:mailer], email: params[:email], locale: params[:locale]), method: :post, class: 'mail_deliver') do %>
|
25
|
+
<ul>
|
26
|
+
<li>Send to</li>
|
27
|
+
<li><%= email_field_tag :to, nil, placeholder: "Enter email", required: true %></li>
|
28
|
+
<li><%= submit_tag 'Send', class: 'button' %></li>
|
70
29
|
</ul>
|
71
30
|
<% end %>
|
72
|
-
</
|
31
|
+
</li>
|
32
|
+
</ul>
|
33
|
+
|
34
|
+
<div class="mail_preview">
|
35
|
+
<ul class="mail_details">
|
36
|
+
<% if @email.subject %><li><b>Subject</b> <%= @email.subject %></li><% end %>
|
37
|
+
<% if @email.from %><li><b>From</b> <%= @email.from.join(', ') %></li><% end %>
|
38
|
+
<% if @email.to %><li><b>To</b> <%= @email.to.join(', ') %></li><% end %>
|
39
|
+
<% if @email.cc %><li><b>Cc</b> <%= @email.cc.join(', ') %></li><% end %>
|
40
|
+
<% if @email.bcc %><li><b>Bcc</b> <%= @email.bcc.join(', ') %></li><% end %>
|
41
|
+
<% if @email.reply_to %><li><b>Reply to</b> <%= @email.reply_to.join(', ') %></li><% end %>
|
42
|
+
</ul>
|
43
|
+
|
44
|
+
<% if @email.html_part && @email.text_part %>
|
45
|
+
<ul class="format_mail">
|
46
|
+
<li><%= link_to 'HTML', url_for(params.to_unsafe_h.merge(part: 'html')), class: part_class('html') %></li>
|
47
|
+
<li><%= link_to 'TEXT', url_for(params.to_unsafe_h.merge(part: 'text')), class: part_class('text') %></li>
|
48
|
+
</ul>
|
49
|
+
<% end %>
|
50
|
+
|
51
|
+
<% if @email.html_part || @email.text_part || @email.body.present? %>
|
52
|
+
<iframe class="mail_iframe" onload='resizeIframe(this)' src="<%= raw_maily_email_path(mailer: params[:mailer], email: params[:email], locale: params[:locale], part: params[:part]) %>" frameborder="1" width="100%"></iframe>
|
53
|
+
<% end %>
|
54
|
+
|
55
|
+
<% if @email.attachments.present? %>
|
56
|
+
<ul class="mail_attachments">
|
57
|
+
<li>Attachments:</li>
|
58
|
+
<li>
|
59
|
+
<ul>
|
60
|
+
<% @email.attachments.each do |attachment| %>
|
61
|
+
<li>
|
62
|
+
<%= icon 'paperclip' %>
|
63
|
+
<%= link_to attachment.filename, attachment_maily_email_path(mailer: params[:mailer], email: params[:email], attachment: attachment.filename) %>
|
64
|
+
</li>
|
65
|
+
<% end %>
|
66
|
+
</ul>
|
67
|
+
</li>
|
68
|
+
</ul>
|
69
|
+
<% end %>
|
73
70
|
</div>
|
@@ -1,3 +1,6 @@
|
|
1
1
|
<header class="header">
|
2
|
-
<a href="<%= root_path %>" class="logo_link"
|
2
|
+
<a href="<%= root_path %>" class="logo_link">
|
3
|
+
<%= image_tag 'maily/logo.png', align: 'center', width: 45 %>
|
4
|
+
<span>Maily</span>
|
5
|
+
</a>
|
3
6
|
</header>
|
@@ -1,9 +1,9 @@
|
|
1
1
|
<aside class="sidebar">
|
2
2
|
<% @mailers.sort_by(&:name).each do |mailer| %>
|
3
3
|
<section class="nav_list">
|
4
|
-
<h3 class="
|
4
|
+
<h3 class="nav_title"><%= "#{mailer.name.humanize} (#{mailer.total_emails})" %></h3>
|
5
5
|
<ul>
|
6
|
-
<% mailer.emails.sort_by(&:name).each do |email| %>
|
6
|
+
<% mailer.emails.values.sort_by(&:name).each do |email| %>
|
7
7
|
<li><%= link_to email.name.humanize, maily_email_path(mailer: mailer.name, email: email.name), class: sidebar_class(mailer, email) %></li>
|
8
8
|
<% end %>
|
9
9
|
</ul>
|
data/gemfiles/rails_4.2.gemfile
CHANGED
data/gemfiles/rails_5.0.gemfile
CHANGED
data/gemfiles/rails_5.1.gemfile
CHANGED
data/lib/maily.rb
CHANGED
@@ -23,9 +23,7 @@ module Maily
|
|
23
23
|
# Load emails from file system
|
24
24
|
Dir[Rails.root + 'app/mailers/*.rb'].each do |mailer|
|
25
25
|
klass_name = File.basename(mailer, '.rb')
|
26
|
-
|
27
|
-
methods = klass.send(:public_instance_methods, false)
|
28
|
-
Maily::Mailer.new(klass_name, methods)
|
26
|
+
Maily::Mailer.new(klass_name)
|
29
27
|
end
|
30
28
|
|
31
29
|
# Load hooks
|
data/lib/maily/email.rb
CHANGED
@@ -1,15 +1,20 @@
|
|
1
1
|
module Maily
|
2
2
|
class Email
|
3
|
-
attr_accessor :name, :mailer, :arguments, :template_path, :description
|
3
|
+
attr_accessor :name, :mailer, :arguments, :template_path, :template_name, :description
|
4
4
|
|
5
5
|
def initialize(name, mailer)
|
6
|
-
self.name = name
|
6
|
+
self.name = name
|
7
7
|
self.mailer = mailer
|
8
8
|
self.arguments = nil
|
9
|
-
self.template_path = mailer
|
9
|
+
self.template_path = mailer.name
|
10
|
+
self.template_name = name
|
10
11
|
self.description = nil
|
11
12
|
end
|
12
13
|
|
14
|
+
def mailer_klass
|
15
|
+
mailer.klass
|
16
|
+
end
|
17
|
+
|
13
18
|
def parameters
|
14
19
|
mailer_klass.instance_method(name).parameters
|
15
20
|
end
|
@@ -45,21 +50,21 @@ module Maily
|
|
45
50
|
|
46
51
|
if args.last.is_a?(Hash)
|
47
52
|
self.description = args.last.delete(:description)
|
48
|
-
|
53
|
+
|
54
|
+
if tpl_path = args.last.delete(:template_path)
|
55
|
+
self.template_path = tpl_path
|
56
|
+
end
|
57
|
+
|
58
|
+
if tpl_name = args.last.delete(:template_name)
|
59
|
+
self.template_name = tpl_name
|
60
|
+
end
|
61
|
+
|
49
62
|
args.pop
|
50
63
|
end
|
51
64
|
|
52
65
|
self.arguments = args
|
53
66
|
end
|
54
67
|
|
55
|
-
def mailer_klass_name
|
56
|
-
mailer.camelize
|
57
|
-
end
|
58
|
-
|
59
|
-
def mailer_klass
|
60
|
-
mailer_klass_name.constantize
|
61
|
-
end
|
62
|
-
|
63
68
|
def call
|
64
69
|
*args = arguments && arguments.map { |arg| arg.respond_to?(:call) ? arg.call : arg }
|
65
70
|
|
@@ -71,7 +76,7 @@ module Maily
|
|
71
76
|
end
|
72
77
|
|
73
78
|
def base_path(part)
|
74
|
-
"#{Rails.root}/app/views/#{template_path}/#{
|
79
|
+
"#{Rails.root}/app/views/#{template_path}/#{template_name}.#{part}.erb"
|
75
80
|
end
|
76
81
|
|
77
82
|
def path(part = nil)
|
data/lib/maily/mailer.rb
CHANGED
@@ -1,13 +1,17 @@
|
|
1
1
|
module Maily
|
2
2
|
class Mailer
|
3
3
|
cattr_accessor :collection
|
4
|
-
attr_accessor :name, :emails
|
4
|
+
attr_accessor :name, :emails, :klass
|
5
5
|
|
6
|
-
def initialize(name
|
7
|
-
self.
|
8
|
-
self.
|
9
|
-
self.emails
|
10
|
-
|
6
|
+
def initialize(name)
|
7
|
+
self.name = name
|
8
|
+
self.klass = name.camelize.constantize
|
9
|
+
self.emails = {}
|
10
|
+
|
11
|
+
parse_emails
|
12
|
+
|
13
|
+
self.class.collection ||= {}
|
14
|
+
self.class.collection[name] = self
|
11
15
|
end
|
12
16
|
|
13
17
|
def self.all
|
@@ -16,22 +20,36 @@ module Maily
|
|
16
20
|
end
|
17
21
|
|
18
22
|
def self.find(mailer_name)
|
19
|
-
all
|
23
|
+
all[mailer_name]
|
20
24
|
end
|
21
25
|
|
22
|
-
def
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
+
def find_email(email_name)
|
27
|
+
emails[email_name.to_s]
|
28
|
+
end
|
29
|
+
|
30
|
+
def total_emails
|
31
|
+
emails.size
|
26
32
|
end
|
27
33
|
|
28
34
|
def register_hook(email_name, *args)
|
29
35
|
email = find_email(email_name)
|
30
|
-
email.register_hook(args)
|
36
|
+
email && email.register_hook(args)
|
31
37
|
end
|
32
38
|
|
33
|
-
def
|
34
|
-
|
39
|
+
def hide_email(*email_names)
|
40
|
+
email_names.each do |email_name|
|
41
|
+
emails.delete(email_name.to_s)
|
42
|
+
end
|
43
|
+
end
|
44
|
+
|
45
|
+
private
|
46
|
+
|
47
|
+
def parse_emails
|
48
|
+
_emails = klass.send(:public_instance_methods, false)
|
49
|
+
|
50
|
+
_emails.map(&:to_s).each do |email|
|
51
|
+
self.emails[email] = Maily::Email.new(email, self)
|
52
|
+
end
|
35
53
|
end
|
36
54
|
end
|
37
55
|
end
|
data/lib/maily/version.rb
CHANGED
data/maily.gemspec
CHANGED
@@ -19,6 +19,5 @@ Gem::Specification.new do |s|
|
|
19
19
|
|
20
20
|
s.add_development_dependency "rspec-rails"
|
21
21
|
s.add_development_dependency "appraisal"
|
22
|
-
s.add_development_dependency
|
23
|
-
s.add_development_dependency "byebug" if RUBY_VERSION.to_i >= 2
|
22
|
+
s.add_development_dependency "byebug"
|
24
23
|
end
|
data/screenshot.png
CHANGED
Binary file
|
data/spec/controllers_spec.rb
CHANGED
@@ -1,6 +1,15 @@
|
|
1
1
|
require 'spec_helper'
|
2
2
|
|
3
3
|
describe Maily::EmailsController, type: :controller do
|
4
|
+
# Rails 4 <-> 5 compatibility
|
5
|
+
def compatible_get(action, **params)
|
6
|
+
if ::Rails::VERSION::STRING > '5'
|
7
|
+
get action, params: params
|
8
|
+
else
|
9
|
+
get action, params
|
10
|
+
end
|
11
|
+
end
|
12
|
+
|
4
13
|
routes { Maily::Engine.routes }
|
5
14
|
|
6
15
|
before(:each) do
|
@@ -11,22 +20,52 @@ describe Maily::EmailsController, type: :controller do
|
|
11
20
|
expect { get :index }.not_to raise_error
|
12
21
|
end
|
13
22
|
|
14
|
-
it '
|
23
|
+
it 'raises 404 if disabled' do
|
15
24
|
Maily.enabled = false
|
25
|
+
|
16
26
|
get :index
|
27
|
+
|
17
28
|
expect(response.status).to eq(404)
|
18
29
|
end
|
19
30
|
|
20
31
|
it 'responds with 401 if http authorization fails' do
|
21
32
|
Maily.http_authorization = { username: 'admin', password: 'admin' }
|
33
|
+
|
22
34
|
get :index
|
35
|
+
|
23
36
|
expect(response.status).to eq(401)
|
24
37
|
end
|
25
38
|
|
26
39
|
it 'responds ok with valid http authorization' do
|
27
40
|
Maily.http_authorization = { username: 'admin', password: 'admin' }
|
28
41
|
request.env['HTTP_AUTHORIZATION'] = ActionController::HttpAuthentication::Basic.encode_credentials('admin', 'admin')
|
42
|
+
|
29
43
|
get :index
|
44
|
+
|
30
45
|
expect(response.status).to eq(200)
|
31
46
|
end
|
47
|
+
|
48
|
+
describe 'non-existent emails' do
|
49
|
+
it 'email not in the system -> 302' do
|
50
|
+
compatible_get :show, mailer: 'notifier', email: 'non_existent_email'
|
51
|
+
|
52
|
+
expect(response.status).to eq(302)
|
53
|
+
expect(flash.alert).to eq("Email not found!")
|
54
|
+
end
|
55
|
+
|
56
|
+
it 'hidden emails -> 302' do
|
57
|
+
compatible_get :show, mailer: 'notifier', email: 'hidden'
|
58
|
+
|
59
|
+
expect(response.status).to eq(302)
|
60
|
+
expect(flash.alert).to eq("Email not found!")
|
61
|
+
end
|
62
|
+
end
|
63
|
+
|
64
|
+
describe 'GET #raw' do
|
65
|
+
it 'renders the template' do
|
66
|
+
compatible_get :raw, mailer: 'notifier', email: 'invitation'
|
67
|
+
|
68
|
+
expect(response.body).to match("<h1>Invitation</h1>")
|
69
|
+
end
|
70
|
+
end
|
32
71
|
end
|
@@ -3,4 +3,7 @@ email = -> { 'foo@foo.com' }
|
|
3
3
|
Maily.hooks_for('Notifier') do |mailer|
|
4
4
|
mailer.register_hook(:invitation, email)
|
5
5
|
mailer.register_hook(:recommendation, template_path: 'notifications', description: 'description')
|
6
|
+
mailer.register_hook(:custom_template_name, template_name: 'invitation')
|
7
|
+
|
8
|
+
mailer.hide_email(:hidden)
|
6
9
|
end
|