ditty 0.9.1 → 0.10.1
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.
- checksums.yaml +4 -4
- data/.env.test +2 -0
- data/.gitignore +1 -0
- data/.rubocop.yml +23 -4
- data/.travis.yml +2 -7
- data/Gemfile.ci +0 -15
- data/ditty.gemspec +19 -15
- data/lib/ditty.rb +2 -2
- data/lib/ditty/cli.rb +5 -0
- data/lib/ditty/components/ditty.rb +4 -7
- data/lib/ditty/controllers/application_controller.rb +6 -5
- data/lib/ditty/controllers/audit_logs_controller.rb +2 -0
- data/lib/ditty/controllers/auth_controller.rb +5 -2
- data/lib/ditty/controllers/component_controller.rb +3 -3
- data/lib/ditty/controllers/user_login_traits_controller.rb +28 -1
- data/lib/ditty/controllers/users_controller.rb +3 -2
- data/lib/ditty/db.rb +4 -3
- data/lib/ditty/emails/base.rb +32 -30
- data/lib/ditty/generators/crud_generator.rb +51 -41
- data/lib/ditty/generators/project_generator.rb +1 -0
- data/lib/ditty/helpers/pundit.rb +4 -4
- data/lib/ditty/helpers/response.rb +6 -11
- data/lib/ditty/helpers/views.rb +21 -3
- data/lib/ditty/listener.rb +1 -1
- data/lib/ditty/models/base.rb +5 -0
- data/lib/ditty/models/identity.rb +7 -7
- data/lib/ditty/models/user.rb +9 -1
- data/lib/ditty/policies/user_policy.rb +1 -1
- data/lib/ditty/services/authentication.rb +19 -9
- data/lib/ditty/services/email.rb +13 -13
- data/lib/ditty/services/logger.rb +26 -20
- data/lib/ditty/services/pagination_wrapper.rb +7 -5
- data/lib/ditty/services/settings.rb +7 -6
- data/lib/ditty/tasks/ditty.rake +2 -1
- data/lib/ditty/templates/application.rb +1 -1
- data/lib/ditty/templates/config.ru +2 -2
- data/lib/ditty/templates/controller.rb.erb +7 -1
- data/{public → lib/ditty/templates/public}/browserconfig.xml +0 -0
- data/{public → lib/ditty/templates/public}/css/styles.css +0 -0
- data/lib/ditty/templates/public/favicon.ico +0 -0
- data/{public → lib/ditty/templates/public}/images/apple-icon.png +0 -0
- data/{public → lib/ditty/templates/public}/images/favicon-16x16.png +0 -0
- data/{public → lib/ditty/templates/public}/images/favicon-32x32.png +0 -0
- data/{public → lib/ditty/templates/public}/images/launcher-icon-1x.png +0 -0
- data/{public → lib/ditty/templates/public}/images/launcher-icon-2x.png +0 -0
- data/{public → lib/ditty/templates/public}/images/launcher-icon-4x.png +0 -0
- data/{public → lib/ditty/templates/public}/images/mstile-150x150.png +0 -0
- data/{public → lib/ditty/templates/public}/images/safari-pinned-tab.svg +0 -0
- data/{public → lib/ditty/templates/public}/js/scripts.js +0 -0
- data/{public/manifest.json → lib/ditty/templates/public/manifest.json.erb} +2 -2
- data/lib/ditty/templates/settings.yml.erb +1 -0
- data/lib/ditty/templates/spec_helper.rb +1 -1
- data/lib/ditty/templates/views/display.haml.tt +1 -1
- data/lib/ditty/templates/views/edit.haml.tt +1 -1
- data/lib/ditty/templates/views/index.haml.tt +1 -1
- data/lib/ditty/templates/views/new.haml.tt +1 -1
- data/lib/ditty/version.rb +1 -1
- data/spec/ditty/api_spec.rb +1 -1
- data/spec/ditty/emails/base_spec.rb +3 -3
- data/spec/ditty/emails/forgot_password_spec.rb +3 -2
- data/spec/ditty/models/user_spec.rb +3 -3
- data/spec/ditty/services/logger_spec.rb +7 -6
- data/spec/ditty/services/settings_spec.rb +2 -2
- data/spec/factories.rb +4 -4
- data/spec/spec_helper.rb +5 -1
- data/views/403.haml +1 -1
- data/views/500.haml +11 -0
- data/views/audit_logs/index.haml +12 -11
- data/views/auth/forgot_password.haml +29 -24
- data/views/auth/ldap.haml +1 -1
- data/views/auth/login.haml +3 -2
- data/views/auth/register.haml +3 -2
- data/views/auth/reset_password.haml +36 -19
- data/views/blank.haml +1 -0
- data/views/embedded.haml +17 -11
- data/views/layout.haml +16 -8
- data/views/partials/actions.haml +15 -14
- data/views/partials/filter_control.haml +1 -1
- data/views/partials/footer.haml +10 -2
- data/views/partials/form_tag.haml +1 -1
- data/views/partials/navitems.haml +25 -27
- data/views/partials/pager.haml +44 -25
- data/views/partials/search.haml +14 -9
- data/views/partials/sidebar.haml +2 -2
- data/views/partials/sort_ui.haml +2 -0
- data/views/partials/timespan_selector.haml +64 -0
- data/views/partials/topbar.haml +0 -15
- data/views/partials/user_associations.haml +32 -0
- data/views/quick_start.haml +23 -0
- data/views/roles/display.haml +3 -3
- data/views/roles/edit.haml +1 -1
- data/views/roles/index.haml +2 -2
- data/views/roles/new.haml +1 -1
- data/views/user_login_traits/display.haml +1 -1
- data/views/user_login_traits/edit.haml +1 -1
- data/views/user_login_traits/index.haml +23 -25
- data/views/user_login_traits/new.haml +1 -1
- data/views/users/display.haml +5 -5
- data/views/users/edit.haml +1 -1
- data/views/users/index.haml +5 -5
- data/views/users/login_traits.haml +2 -2
- data/views/users/new.haml +1 -1
- data/views/users/profile.haml +4 -4
- data/views/users/user.haml +1 -1
- metadata +116 -54
|
@@ -31,6 +31,8 @@ module Ditty
|
|
|
31
31
|
def create_model
|
|
32
32
|
filename = File.join("lib/#{folder}/models", "#{model_name.underscore}.rb")
|
|
33
33
|
template '../templates/model.rb.erb', filename
|
|
34
|
+
rescue StandardError => e
|
|
35
|
+
puts "Could not generate model for #{model_name}: #{e.message}"
|
|
34
36
|
end
|
|
35
37
|
|
|
36
38
|
def create_controller
|
|
@@ -38,16 +40,22 @@ module Ditty
|
|
|
38
40
|
template '../templates/controller.rb.erb', filename
|
|
39
41
|
# TODO: Insert the route into the component file
|
|
40
42
|
# insert_into_file 'config.ru', "use #{class_name}\n", after: 'run ApplicationController\n'
|
|
43
|
+
rescue StandardError => e
|
|
44
|
+
puts "Could not generate controller for #{model_name}: #{e.message}"
|
|
41
45
|
end
|
|
42
46
|
|
|
43
47
|
def create_policy
|
|
44
48
|
filename = File.join("lib/#{folder}/policies", "#{policy_name.underscore}.rb")
|
|
45
49
|
template '../templates/policy.rb.erb', filename
|
|
50
|
+
rescue StandardError => e
|
|
51
|
+
puts "Could not generate policy for #{model_name}: #{e.message}"
|
|
46
52
|
end
|
|
47
53
|
|
|
48
54
|
def create_type
|
|
49
55
|
filename = File.join("lib/#{folder}/types", "#{model_name.underscore}_type.rb")
|
|
50
56
|
template '../templates/type.rb.erb', filename
|
|
57
|
+
rescue StandardError => e
|
|
58
|
+
puts "Could not generate type for #{model_name}: #{e.message}"
|
|
51
59
|
end
|
|
52
60
|
|
|
53
61
|
def create_views
|
|
@@ -58,47 +66,49 @@ module Ditty
|
|
|
58
66
|
|
|
59
67
|
private
|
|
60
68
|
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
69
|
+
def meta_columns
|
|
70
|
+
%i[id guid slug created_at updated_at]
|
|
71
|
+
end
|
|
72
|
+
|
|
73
|
+
def columns
|
|
74
|
+
require "#{folder}/models/#{model_name.underscore}"
|
|
75
|
+
name.constantize.columns
|
|
76
|
+
rescue StandardError
|
|
77
|
+
[]
|
|
78
|
+
end
|
|
79
|
+
|
|
80
|
+
def schema
|
|
81
|
+
require "#{folder}/models/#{model_name.underscore}"
|
|
82
|
+
name.constantize.db_schema
|
|
83
|
+
rescue StandardError
|
|
84
|
+
[]
|
|
85
|
+
end
|
|
86
|
+
|
|
87
|
+
def many_to_ones
|
|
88
|
+
DB.foreign_key_list(model_name.underscore.pluralize)
|
|
89
|
+
end
|
|
90
|
+
|
|
91
|
+
def name_column(table)
|
|
92
|
+
candidates = DB.schema(table.to_sym).to_h.keys - DB.foreign_key_list(table.to_sym).map do |e|
|
|
93
|
+
e[:columns]
|
|
94
|
+
end.flatten
|
|
95
|
+
(candidates - meta_columns).first
|
|
96
|
+
end
|
|
97
|
+
|
|
98
|
+
def graphql_types
|
|
99
|
+
@graphql_types ||= Hash.new('String').merge(
|
|
100
|
+
integer: 'Integer',
|
|
101
|
+
boolean: 'Boolean',
|
|
102
|
+
datetime: 'GraphQL::Types::ISO8601DateTime'
|
|
103
|
+
)
|
|
104
|
+
end
|
|
105
|
+
|
|
106
|
+
def input_types
|
|
107
|
+
@input_types ||= Hash.new('text').merge(
|
|
108
|
+
integer: 'number',
|
|
109
|
+
datetime: 'date'
|
|
110
|
+
)
|
|
111
|
+
end
|
|
102
112
|
end
|
|
103
113
|
end
|
|
104
114
|
end
|
data/lib/ditty/helpers/pundit.rb
CHANGED
|
@@ -16,10 +16,10 @@ module Ditty
|
|
|
16
16
|
policy = policy(record)
|
|
17
17
|
action ||= record.new? ? :create : :update
|
|
18
18
|
method_name = if policy.respond_to?("permitted_attributes_for_#{action}")
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
19
|
+
"permitted_attributes_for_#{action}"
|
|
20
|
+
else
|
|
21
|
+
'permitted_attributes'
|
|
22
|
+
end
|
|
23
23
|
policy.public_send(method_name)
|
|
24
24
|
end
|
|
25
25
|
|
|
@@ -2,8 +2,6 @@
|
|
|
2
2
|
|
|
3
3
|
require 'csv'
|
|
4
4
|
|
|
5
|
-
require 'csv'
|
|
6
|
-
|
|
7
5
|
module Ditty
|
|
8
6
|
module Helpers
|
|
9
7
|
module Response
|
|
@@ -27,6 +25,7 @@ module Ditty
|
|
|
27
25
|
)
|
|
28
26
|
end
|
|
29
27
|
format.csv do
|
|
28
|
+
attachment "#{base_path}.csv"
|
|
30
29
|
CSV.generate do |csv|
|
|
31
30
|
csv << result.first.for_csv.keys
|
|
32
31
|
result.all.each do |r|
|
|
@@ -41,7 +40,7 @@ module Ditty
|
|
|
41
40
|
respond_to do |format|
|
|
42
41
|
format.html do
|
|
43
42
|
flash[:success] = "#{heading} Created"
|
|
44
|
-
redirect with_layout(flash[:redirect_to] || "#{base_path}/#{entity.display_id}")
|
|
43
|
+
redirect with_layout(params[:redirect_to] || flash[:redirect_to] || "#{base_path}/#{entity.display_id}")
|
|
45
44
|
end
|
|
46
45
|
format.json do
|
|
47
46
|
content_type :json
|
|
@@ -62,6 +61,8 @@ module Ditty
|
|
|
62
61
|
respond_to do |format|
|
|
63
62
|
format.html do
|
|
64
63
|
title = heading(:read) + (entity.respond_to?(:name) ? ": #{entity.name}" : '')
|
|
64
|
+
last_modified entity.updated_at if entity.respond_to?(:updated_at)
|
|
65
|
+
etag entity.etag if entity.respond_to?(:etag)
|
|
65
66
|
haml :"#{view_location}/display",
|
|
66
67
|
locals: { entity: entity, title: title, actions: actions },
|
|
67
68
|
layout: layout
|
|
@@ -76,12 +77,6 @@ module Ditty
|
|
|
76
77
|
csv << entity.for_csv.values
|
|
77
78
|
end
|
|
78
79
|
end
|
|
79
|
-
format.csv do
|
|
80
|
-
CSV.generate do |csv|
|
|
81
|
-
csv << entity.for_csv.keys
|
|
82
|
-
csv << entity.for_csv.values
|
|
83
|
-
end
|
|
84
|
-
end
|
|
85
80
|
end
|
|
86
81
|
end
|
|
87
82
|
|
|
@@ -90,7 +85,7 @@ module Ditty
|
|
|
90
85
|
format.html do
|
|
91
86
|
# TODO: Ability to customize the return path and message?
|
|
92
87
|
flash[:success] = "#{heading} Updated"
|
|
93
|
-
redirect with_layout(
|
|
88
|
+
redirect with_layout(params[:redirect_to] || flash[:redirect_to] || "#{base_path}/#{entity.display_id}")
|
|
94
89
|
end
|
|
95
90
|
format.json do
|
|
96
91
|
content_type :json
|
|
@@ -103,7 +98,7 @@ module Ditty
|
|
|
103
98
|
respond_to do |format|
|
|
104
99
|
format.html do
|
|
105
100
|
flash[:success] = "#{heading} Deleted"
|
|
106
|
-
redirect with_layout(flash[:redirect_to] || back || base_path)
|
|
101
|
+
redirect with_layout(params[:redirect_to] || flash[:redirect_to] || back || base_path)
|
|
107
102
|
end
|
|
108
103
|
format.json do
|
|
109
104
|
content_type :json
|
data/lib/ditty/helpers/views.rb
CHANGED
|
@@ -62,13 +62,13 @@ module Ditty
|
|
|
62
62
|
messages = flash(key).collect do |message|
|
|
63
63
|
" <div class='alert alert-#{message[0]} alert-dismissable' role='alert'>#{message[1]}</div>\n"
|
|
64
64
|
end
|
|
65
|
-
"<div id='#{id}'>\n
|
|
65
|
+
"<div id='#{id}'>\n#{messages.join}</div>"
|
|
66
66
|
end
|
|
67
67
|
|
|
68
68
|
def query_string(add = {})
|
|
69
69
|
qs = params.clone.merge(add)
|
|
70
70
|
qs.delete('captures')
|
|
71
|
-
Rack::Utils.build_query
|
|
71
|
+
Rack::Utils.build_query(qs.delete_if { |_k, v| v == '' })
|
|
72
72
|
end
|
|
73
73
|
|
|
74
74
|
def delete_form(entity, label = 'Delete')
|
|
@@ -94,7 +94,7 @@ module Ditty
|
|
|
94
94
|
def form_tag(url, options = {}, &block)
|
|
95
95
|
options[:form_verb] ||= :post
|
|
96
96
|
options[:attributes] ||= {}
|
|
97
|
-
options[:attributes] = {
|
|
97
|
+
options[:attributes] = { class: 'form-horizontal' }.merge options[:attributes]
|
|
98
98
|
options[:url] = options[:form_verb].to_sym == :get ? url : with_layout(url)
|
|
99
99
|
haml :'partials/form_tag', locals: options.merge(block: block)
|
|
100
100
|
end
|
|
@@ -138,6 +138,24 @@ module Ditty
|
|
|
138
138
|
haml_tag :a, name, html_options
|
|
139
139
|
end
|
|
140
140
|
end
|
|
141
|
+
|
|
142
|
+
def sort_ui(field)
|
|
143
|
+
haml :'partials/sort_ui', locals: { field: field }
|
|
144
|
+
end
|
|
145
|
+
|
|
146
|
+
def sort_query(field)
|
|
147
|
+
query_string(
|
|
148
|
+
order: params[:sort] == field.to_s && params[:order] == 'asc' ? 'desc' : 'asc',
|
|
149
|
+
sort: field,
|
|
150
|
+
)
|
|
151
|
+
end
|
|
152
|
+
|
|
153
|
+
def sort_icon(field)
|
|
154
|
+
return 'fa-sort' unless params[:sort] == field.to_s
|
|
155
|
+
return 'fa-sort-up' if params[:order] == 'asc'
|
|
156
|
+
|
|
157
|
+
'fa-sort-down'
|
|
158
|
+
end
|
|
141
159
|
end
|
|
142
160
|
end
|
|
143
161
|
end
|
data/lib/ditty/listener.rb
CHANGED
|
@@ -66,7 +66,7 @@ module Ditty
|
|
|
66
66
|
def action_from(target, method)
|
|
67
67
|
return method unless method.to_s.start_with? 'component_'
|
|
68
68
|
|
|
69
|
-
target.class.to_s.demodulize.underscore
|
|
69
|
+
"#{target.class.to_s.demodulize.underscore}_#{method.to_s.gsub(/^component_/, '')}"
|
|
70
70
|
end
|
|
71
71
|
|
|
72
72
|
def log_action(values)
|
data/lib/ditty/models/base.rb
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
|
+
require 'digest/sha2'
|
|
3
4
|
require 'sequel'
|
|
4
5
|
|
|
5
6
|
module Ditty
|
|
@@ -12,6 +13,10 @@ module Ditty
|
|
|
12
13
|
self[:slug] || self[:guid] || self[:id]
|
|
13
14
|
end
|
|
14
15
|
|
|
16
|
+
def etag
|
|
17
|
+
Digest::SHA2.hexdigest values.to_json
|
|
18
|
+
end
|
|
19
|
+
|
|
15
20
|
alias for_csv for_json
|
|
16
21
|
end
|
|
17
22
|
end
|
|
@@ -55,7 +55,7 @@ module Ditty
|
|
|
55
55
|
# 1 Special Character
|
|
56
56
|
# 1 Number
|
|
57
57
|
# At least 8 characters
|
|
58
|
-
%r[\A(?=.*[A-Z])(?=.*[a-z])(?=.*[!@#&$*)(}{%^=_+|\\:";'
|
|
58
|
+
%r[\A(?=.*[A-Z])(?=.*[a-z])(?=.*[!@#&$*)(}{%^=_+|\\:";'<>,.\-/?\[\]])(?=.*[0-9]).{8,}\Z],
|
|
59
59
|
:password,
|
|
60
60
|
message: 'is not strong enough'
|
|
61
61
|
)
|
|
@@ -72,12 +72,12 @@ module Ditty
|
|
|
72
72
|
|
|
73
73
|
private
|
|
74
74
|
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
75
|
+
def encrypt_password
|
|
76
|
+
self.crypted_password = ::BCrypt::Password.create(password)
|
|
77
|
+
end
|
|
78
78
|
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
79
|
+
def password_required
|
|
80
|
+
crypted_password.blank? || !password.blank?
|
|
81
|
+
end
|
|
82
82
|
end
|
|
83
83
|
end
|
data/lib/ditty/models/user.rb
CHANGED
|
@@ -40,7 +40,9 @@ module Ditty
|
|
|
40
40
|
end
|
|
41
41
|
|
|
42
42
|
def respond_to_missing?(name, _include_private = false)
|
|
43
|
-
name[-1] == '?'
|
|
43
|
+
return true if name[-1] == '?'
|
|
44
|
+
|
|
45
|
+
super
|
|
44
46
|
end
|
|
45
47
|
|
|
46
48
|
def gravatar
|
|
@@ -57,6 +59,12 @@ module Ditty
|
|
|
57
59
|
validates_format(/\A([^@\s]+)@((?:[-a-z0-9]+\.)+[a-z]{2,})\Z/i, :email)
|
|
58
60
|
end
|
|
59
61
|
|
|
62
|
+
def before_save
|
|
63
|
+
super
|
|
64
|
+
self.name = nil if name.blank?
|
|
65
|
+
self.surname = nil if surname.blank?
|
|
66
|
+
end
|
|
67
|
+
|
|
60
68
|
# Add the basic roles and identity
|
|
61
69
|
def after_create
|
|
62
70
|
super
|
|
@@ -3,7 +3,6 @@
|
|
|
3
3
|
require 'ditty/controllers/application_controller'
|
|
4
4
|
require 'ditty/services/settings'
|
|
5
5
|
require 'ditty/services/logger'
|
|
6
|
-
require 'backports/2.4.0/hash/compact'
|
|
7
6
|
|
|
8
7
|
require 'omniauth'
|
|
9
8
|
OmniAuth.config.logger = ::Ditty::Services::Logger
|
|
@@ -23,26 +22,36 @@ module Ditty
|
|
|
23
22
|
end
|
|
24
23
|
|
|
25
24
|
def providers
|
|
26
|
-
config.compact.keys
|
|
25
|
+
config.compact.keys.select { |e| config[e][:available] && config[e][:enabled] != false }
|
|
27
26
|
end
|
|
28
27
|
|
|
29
28
|
def setup
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
require
|
|
29
|
+
config.compact.each_key do |provider|
|
|
30
|
+
::Ditty::Services::Logger.debug "Loading authentication provider #{provider}"
|
|
31
|
+
req = if config.dig(provider, :require)
|
|
32
|
+
[config[provider][:require]]
|
|
33
|
+
else
|
|
34
|
+
["omniauth/#{provider}", "omniauth-#{provider}"]
|
|
35
|
+
end
|
|
36
|
+
req.find do |e|
|
|
37
|
+
require e
|
|
38
|
+
config[provider][:available] = true
|
|
39
|
+
true
|
|
34
40
|
rescue LoadError
|
|
35
|
-
|
|
41
|
+
::Ditty::Services::Logger.warn "Could not load authentication provider #{provider} using #{e}"
|
|
42
|
+
config[provider][:available] = false
|
|
43
|
+
false
|
|
36
44
|
end
|
|
37
45
|
end
|
|
38
46
|
end
|
|
39
47
|
|
|
40
48
|
def config
|
|
41
|
-
default.merge
|
|
49
|
+
@config ||= default.merge(::Ditty::Services::Settings.values(:authentication) || {})
|
|
42
50
|
end
|
|
43
51
|
|
|
44
52
|
def provides?(provider)
|
|
45
|
-
|
|
53
|
+
provider = provider.to_sym
|
|
54
|
+
providers.include?(provider) && config[provider][:available] && config.dig(provider, :enabled) != false
|
|
46
55
|
end
|
|
47
56
|
|
|
48
57
|
def default
|
|
@@ -50,6 +59,7 @@ module Ditty
|
|
|
50
59
|
require 'ditty/controllers/auth_controller'
|
|
51
60
|
{
|
|
52
61
|
identity: {
|
|
62
|
+
available: true,
|
|
53
63
|
arguments: [
|
|
54
64
|
{
|
|
55
65
|
fields: [:username],
|
data/lib/ditty/services/email.rb
CHANGED
|
@@ -34,21 +34,21 @@ module Ditty
|
|
|
34
34
|
|
|
35
35
|
private
|
|
36
36
|
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
37
|
+
def config
|
|
38
|
+
@config ||= default.merge ::Ditty::Services::Settings.values(:email) || {}
|
|
39
|
+
end
|
|
40
40
|
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
41
|
+
def default
|
|
42
|
+
{
|
|
43
|
+
delivery_method: :logger,
|
|
44
|
+
logger: ::Ditty::Services::Logger
|
|
45
|
+
}
|
|
46
|
+
end
|
|
47
47
|
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
48
|
+
def from_symbol(email, options)
|
|
49
|
+
require "ditty/emails/#{email}"
|
|
50
|
+
constantize("Ditty::Emails::#{classify(email)}").new(options)
|
|
51
|
+
end
|
|
52
52
|
end
|
|
53
53
|
end
|
|
54
54
|
end
|