notifun 1.6

Sign up to get free protection for your applications and to get access to all the features.
Files changed (42) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +1 -0
  3. data/.ruby-gemset +1 -0
  4. data/.ruby-version +1 -0
  5. data/Gemfile +5 -0
  6. data/Gemfile.lock +45 -0
  7. data/README.md +16 -0
  8. data/app/assets/stylesheets/notifun.sass +62 -0
  9. data/app/controllers/notifun/message_templates_controller.rb +31 -0
  10. data/app/controllers/notifun/messages_controller.rb +15 -0
  11. data/app/controllers/notifun/preferences_controller.rb +26 -0
  12. data/app/mailers/notifun/message_mailer.rb +49 -0
  13. data/app/models/notifun/message.rb +7 -0
  14. data/app/models/notifun/message_template.rb +98 -0
  15. data/app/models/notifun/preference.rb +13 -0
  16. data/app/views/notifun/message_templates/edit.html.haml +53 -0
  17. data/app/views/notifun/message_templates/index.html.haml +29 -0
  18. data/app/views/notifun/messages/index.haml +47 -0
  19. data/app/views/notifun/messages/show.haml +47 -0
  20. data/app/views/notifun/preferences/index.haml +45 -0
  21. data/config/routes.rb +16 -0
  22. data/lib/generators/notifun/install_generator.rb +50 -0
  23. data/lib/generators/notifun/templates/migration.rb +48 -0
  24. data/lib/generators/notifun/templates/notifun.rb +39 -0
  25. data/lib/generators/notifun/templates/notifun_add_push_title.rb +8 -0
  26. data/lib/generators/notifun/templates/notifun_templates.json +29 -0
  27. data/lib/notifun.rb +27 -0
  28. data/lib/notifun/configuration.rb +19 -0
  29. data/lib/notifun/engine.rb +5 -0
  30. data/lib/notifun/notification.rb +166 -0
  31. data/lib/notifun/notifiers/cloud_five_notifier.rb +32 -0
  32. data/lib/notifun/notifiers/email_notifier.rb +11 -0
  33. data/lib/notifun/notifiers/empty_notifier.rb +2 -0
  34. data/lib/notifun/notifiers/notifier.rb +17 -0
  35. data/lib/notifun/notifiers/parent_notifier.rb +12 -0
  36. data/lib/notifun/notifiers/twilio_notifier.rb +28 -0
  37. data/lib/notifun/railtie.rb +48 -0
  38. data/lib/notifun/version.rb +3 -0
  39. data/notifun.gemspec +26 -0
  40. data/spec/notifun_spec.rb +108 -0
  41. data/spec/spec_helper.rb +88 -0
  42. metadata +156 -0
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA256:
3
+ metadata.gz: 9c88df68caf7a8299ad9ff4926c6708c889fcaa52462a55210c14fa193a91e3d
4
+ data.tar.gz: 0c4befb2ee25fdc56a5bbb7af87edccd995227663969221aef82a5fe06ca88c1
5
+ SHA512:
6
+ metadata.gz: fb39dca98588e16e36db112920e3ecd7d2babfa68c8339c728b247f6bced42bb7c4efb5aa9eb548223b02cdc06c1765648c0efc1c54b3e310a61498a7d282662
7
+ data.tar.gz: c8ebebaf962f0c7ee2ec01544cfe887ff3ff6d388c5378f48c946927967a991342200e2b499050aab7b6944f61c99cce2f9d8d3f28393177954b9cb8afff5f37
@@ -0,0 +1 @@
1
+ .DS_Store
@@ -0,0 +1 @@
1
+ notifun
@@ -0,0 +1 @@
1
+ 2.4.4
data/Gemfile ADDED
@@ -0,0 +1,5 @@
1
+ # frozen_string_literal: true
2
+ source "https://rubygems.org"
3
+
4
+ # Specify your gem's dependencies in notifun.gemspec
5
+ gemspec
@@ -0,0 +1,45 @@
1
+ PATH
2
+ remote: .
3
+ specs:
4
+ notifun (1.6)
5
+
6
+ GEM
7
+ remote: https://rubygems.org/
8
+ specs:
9
+ awesome_print (1.7.0)
10
+ coderay (1.1.1)
11
+ diff-lcs (1.3)
12
+ method_source (0.8.2)
13
+ pry (0.10.4)
14
+ coderay (~> 1.1.0)
15
+ method_source (~> 0.8.1)
16
+ slop (~> 3.4)
17
+ rake (12.0.0)
18
+ rspec (3.5.0)
19
+ rspec-core (~> 3.5.0)
20
+ rspec-expectations (~> 3.5.0)
21
+ rspec-mocks (~> 3.5.0)
22
+ rspec-core (3.5.4)
23
+ rspec-support (~> 3.5.0)
24
+ rspec-expectations (3.5.0)
25
+ diff-lcs (>= 1.2.0, < 2.0)
26
+ rspec-support (~> 3.5.0)
27
+ rspec-mocks (3.5.0)
28
+ diff-lcs (>= 1.2.0, < 2.0)
29
+ rspec-support (~> 3.5.0)
30
+ rspec-support (3.5.0)
31
+ slop (3.6.0)
32
+
33
+ PLATFORMS
34
+ ruby
35
+
36
+ DEPENDENCIES
37
+ awesome_print
38
+ bundler
39
+ notifun!
40
+ pry
41
+ rake
42
+ rspec (~> 3.0)
43
+
44
+ BUNDLED WITH
45
+ 1.16.6
@@ -0,0 +1,16 @@
1
+ # Notifun
2
+
3
+ To install run: `rails g notifun:install`
4
+
5
+ This will generate three things:
6
+ The config initializer at `config/initializers/notifun.rb`.
7
+ The migration to create the notifun tables.
8
+ The json file for loading message templates at `config/notifun_templates.json`.
9
+
10
+
11
+ Once installed, edit `config/notifun_templates.json` to add your message templates.
12
+ You can edit them at `/notifun/message_templates`.
13
+ You can see the generated messages at `/notifun/messages`.
14
+ Users can edit their preferences at `/notifun/preferences`.
15
+
16
+ `rails g notifun:install` can also be used to install missing fields after updates.
@@ -0,0 +1,62 @@
1
+ .notifun-code, .notifun-code-block
2
+ font-family: courier, monospace
3
+
4
+ .notifun-code-block
5
+ padding: 20px
6
+ background-color: #eee
7
+ margin-bottom: 10px
8
+
9
+ .notifun-preview
10
+ border: 1px solid #ccc
11
+ padding: 10px
12
+
13
+ table.notifun-table
14
+ width: 100%
15
+ &.space-below
16
+ margin-bottom: 50px
17
+
18
+ tr
19
+ border-bottom: 1px solid black
20
+
21
+ td, th
22
+ text-align: center
23
+
24
+ td
25
+ color: black
26
+ padding: 5px 25px 5px 10px
27
+ text-align: left
28
+ &.notifun-category
29
+ font-weight: bold
30
+ &.notifun-indent
31
+ padding-left: 20px
32
+
33
+ th
34
+ background-color: #666666
35
+ border: 1px solid black
36
+ color: white
37
+ padding: 5px 10px
38
+ text-align: left
39
+ text-transform: uppercase
40
+ a:link, a:visited
41
+ color: white
42
+ text-decoration: underline
43
+ a:hover
44
+ text-decoration: none
45
+
46
+ tbody
47
+ tr:nth-child(even)
48
+ background: #dddddd
49
+
50
+ .notifun-center
51
+ text-align: center !important
52
+
53
+ form.notifun-form
54
+ width: 100%
55
+ max-width: 100%
56
+
57
+ .notifun-detail
58
+ padding-bottom: 10px
59
+ .notifun-detail-title
60
+ font-size: 18px
61
+ .notifun-detail-value
62
+ padding-left: 20px
@@ -0,0 +1,31 @@
1
+ class Notifun::MessageTemplatesController < Notifun.configuration.admin_parent_controller.constantize
2
+ def index
3
+ @message_templates = Notifun::MessageTemplate.all
4
+ end
5
+
6
+ def edit
7
+ @message_template = Notifun::MessageTemplate.find_by_key(params[:key])
8
+ end
9
+
10
+ def update
11
+ @message_template = Notifun::MessageTemplate.find_by_key(params[:key])
12
+ if @message_template.update(message_template_attributes)
13
+ redirect_to edit_notifun_message_template_path(@message_template), notice: "Message Template updated."
14
+ else
15
+ render :edit
16
+ end
17
+ end
18
+
19
+ def preview
20
+ @message_template = Notifun::MessageTemplate.find_by_key(params[:key])
21
+ @notifun_models = @message_template.models
22
+
23
+ render html: @message_template.preview_email_html.html_safe, layout: "mailer"
24
+ end
25
+
26
+ private
27
+
28
+ def message_template_attributes
29
+ params.require(:notifun_message_template).permit(:push_title, :push_body, :email_subject, :email_html, :email_text)
30
+ end
31
+ end
@@ -0,0 +1,15 @@
1
+ class Notifun::MessagesController < Notifun.configuration.admin_parent_controller.constantize
2
+ def index
3
+ limit = 100
4
+
5
+ @page = (params[:page].presence || 1).to_i
6
+ offset = limit * (@page - 1)
7
+ @messages = Notifun::Message.order(created_at: :desc)
8
+ @pages = (@messages.count / limit.to_f).ceil
9
+ @messages = @messages.limit(limit).offset(offset)
10
+ end
11
+
12
+ def show
13
+ @message = Notifun::Message.find(params[:id])
14
+ end
15
+ end
@@ -0,0 +1,26 @@
1
+ class Notifun::PreferencesController < Notifun.configuration.user_parent_controller.constantize
2
+ def index
3
+ begin
4
+ @models = self.send(Notifun.configuration.controller_method)
5
+ rescue
6
+ render text: "Notifun.configuration.controller_method is not set or not defined." and return
7
+ end
8
+ @models = [@models].flatten.compact
9
+ if @models.empty?
10
+ render text: "#{Notifun.configuration.controller_method} returned no models."
11
+ end
12
+
13
+ @notification_methods = Notifun.configuration.notification_methods.sort
14
+ end
15
+
16
+ def save
17
+ params[:preferences].each do |index, preference_params|
18
+ permitted_params = preference_params.slice(:preferable_type, :preferable_id, :category, :message_template_key, :email, :push, :text).permit!
19
+ preference = Notifun::Preference.where(permitted_params.slice(:preferable_type, :preferable_id, preference_params[:preference_type])).first_or_initialize
20
+ preference.attributes = permitted_params
21
+ preference.save!
22
+ end
23
+
24
+ redirect_to notifun_preferences_path, notice: "Notification preferences saved."
25
+ end
26
+ end
@@ -0,0 +1,49 @@
1
+ class Notifun::MessageMailer < Notifun.configuration.parent_mailer.constantize
2
+ if Notifun.configuration.premailer_html_to_text && defined?(Premailer)
3
+ include Premailer::HtmlToPlainText
4
+ end
5
+
6
+ def send_message(email, subject, html, text, message_template, options={})
7
+ @notifun_models = message_template.models
8
+
9
+ if options[:attachments].present?
10
+ options[:attachments].each do |key, value|
11
+ attachments[key] = value
12
+ end
13
+ end
14
+
15
+ if options[:instance_variables].present?
16
+ options[:instance_variables].each do |key, value|
17
+ instance_variable_set("@#{key}", value)
18
+ end
19
+ end
20
+
21
+ settings = {
22
+ to: email,
23
+ subject: subject
24
+ }
25
+
26
+ if options[:from].present?
27
+ settings[:from] = options[:from]
28
+ end
29
+ if options[:reply_to].present?
30
+ settings[:reply_to] = options[:reply_to]
31
+ end
32
+
33
+ if Rails.version[0].to_i > 4
34
+ hack_layout = _layout(["text"])
35
+ else
36
+ hack_layout = _layout
37
+ end
38
+
39
+ if Notifun.configuration.premailer_html_to_text && defined?(Premailer)
40
+ text = text.dup
41
+ text = convert_to_text(text)
42
+ end
43
+
44
+ mail(settings) do |format|
45
+ format.text { render plain: text, layout: hack_layout }
46
+ format.html { render html: html.html_safe, layout: hack_layout }
47
+ end
48
+ end
49
+ end
@@ -0,0 +1,7 @@
1
+ class Notifun::Message < ActiveRecord::Base
2
+ self.table_name = 'notifun_messages'
3
+
4
+ def message_template
5
+ Notifun::MessageTemplate.where(key: message_template_key).first
6
+ end
7
+ end
@@ -0,0 +1,98 @@
1
+ class Notifun::MessageTemplate < ActiveRecord::Base
2
+ self.table_name = 'notifun_message_templates'
3
+
4
+ validates :key, uniqueness: true
5
+
6
+ def to_param
7
+ key
8
+ end
9
+
10
+ [:push_title, :push_body, :email_html, :email_text, :email_subject, :text_body].each do |method|
11
+ define_method("merged_#{method}") do |merge_hash|
12
+ merge(self.send(method), merge_hash)
13
+ end
14
+
15
+ define_method("preview_#{method}") do
16
+ merge(self.send(method), merge_fields_preview)
17
+ end
18
+ end
19
+
20
+ def messages
21
+ Notifun::Message.where(message_template_key: key)
22
+ end
23
+
24
+ def default_notification_methods
25
+ notification_methods = self[:default_notification_methods] & Notifun.configuration.notification_methods
26
+ if notification_methods.empty?
27
+ notification_methods = self[:backup_notification_methods] & Notifun.configuration.notification_methods
28
+ end
29
+
30
+ notification_methods
31
+ end
32
+
33
+ def backup_notification_methods
34
+ (self[:backup_notification_methods] & Notifun.configuration.notification_methods) - default_notification_methods
35
+ end
36
+
37
+ def notification_methods
38
+ default_notification_methods + backup_notification_methods
39
+ end
40
+
41
+ def possible_notification_methods
42
+ array = []
43
+ array << "push" if push_body.present?
44
+ array << "email" if email_subject.present?
45
+ array << "text" if text_body.present?
46
+
47
+ if array.empty?
48
+ notification_methods
49
+ else
50
+ array
51
+ end
52
+ end
53
+
54
+ def push?
55
+ notification_methods.include?("push")
56
+ end
57
+
58
+ def email?
59
+ notification_methods.include?("email")
60
+ end
61
+
62
+ def sent_via
63
+ text = default_notification_methods.join(' and ')
64
+ if backup_notification_methods.any?
65
+ text += " or "
66
+ text += backup_notification_methods.join(', ')
67
+ end
68
+
69
+ text
70
+ end
71
+
72
+ def merge_fields_preview
73
+ merge_fields.reduce({}){|hash, (k,v)| hash[k] = v["preview"].presence || v["description"] || v; hash}
74
+ end
75
+
76
+ def merge_fields_description
77
+ merge_fields.reduce({}){|hash, (k,v)| hash[k] = v["description"] || v; hash}
78
+ end
79
+
80
+ def merge_fields_display
81
+ text = []
82
+ merge_fields_description.each do |key, description|
83
+ text << "{#{key}} => #{description}"
84
+ end
85
+ text.join('<br>').html_safe
86
+ end
87
+
88
+ private
89
+
90
+ def merge(text, merge_hash)
91
+ text ||= ""
92
+ merge_hash.each do |key, value|
93
+ text.gsub!(/\{#{key}\}/, value)
94
+ end
95
+
96
+ text
97
+ end
98
+ end
@@ -0,0 +1,13 @@
1
+ class Notifun::Preference < ActiveRecord::Base
2
+ self.table_name = 'notifun_preferences'
3
+
4
+ belongs_to :preferable, polymorphic: true
5
+
6
+ def notification_methods
7
+ array = []
8
+ array << Notifun::NotificationMethods::EMAIL if email
9
+ array << Notifun::NotificationMethods::PUSH if push
10
+ array << Notifun::NotificationMethods::TEXT if text
11
+ array & Notifun.configuration.notification_methods
12
+ end
13
+ end
@@ -0,0 +1,53 @@
1
+ - if Notifun.configuration.wysiwyg == "tinymce"
2
+ = tinymce_assets
3
+ %h1 Edit #{@message_template.key.humanize} Message Template
4
+
5
+ = simple_form_for @message_template, html: { class: "two-columns" } do |f|
6
+ .form-inputs
7
+ = f.error_notification
8
+
9
+ %p= @message_template.description
10
+ %p Models: #{@message_template.models.join(', ')}
11
+ %p Sent Via: #{@message_template.sent_via}
12
+ %p Text surrounded by curly brackets "{example}" is replaced with info from the database when sent. The following are the keys you have available for replacement.
13
+ .notifun-code-block= @message_template.merge_fields_display
14
+ - if @message_template.push?
15
+ = f.input :push_title, input_html: { class: 'notifun-code' }
16
+ .input
17
+ %label Push Title Preview
18
+ .notifun-preview= @message_template.preview_push_title
19
+ %br
20
+ %br
21
+ = f.input :push_body, input_html: { class: 'notifun-code' }
22
+ .input
23
+ %label Push Body Preview
24
+ .notifun-preview= @message_template.preview_push_body
25
+ %br
26
+ %br
27
+ - if @message_template.email?
28
+ = f.input :email_subject, input_html: { class: 'notifun-code' }
29
+ .input
30
+ %label Email Subject Preview
31
+ .notifun-preview= @message_template.preview_email_subject
32
+ %br
33
+ %br
34
+ - if Notifun.configuration.wysiwyg == "tinymce"
35
+ = f.input :email_html, input_html: { rows: 5, class: 'notifun-code tinymce', style: "height: 300px" }
36
+ = tinymce
37
+ - elsif Notifun.configuration.wysiwyg == "froala"
38
+ = f.input :email_html, input_html: { rows: 5, class: 'notifun-code froala-editor', data: { froalaoptions: { heightMin: 300 }} }
39
+ - else
40
+ = f.input :email_html, input_html: { rows: 5, class: 'notifun-code' }
41
+ .input
42
+ %label Email HTML Preview
43
+ .notifun-preview
44
+ %iframe{height: "300px", width: "100%", src: preview_notifun_message_template_path(@message_template)}
45
+ %br
46
+ %br
47
+ = f.input :email_text, input_html: { rows: 5, class: 'notifun-code' }
48
+ .input
49
+ %label Email Text Preview
50
+ .notifun-preview= @message_template.preview_email_text
51
+
52
+ .form-actions
53
+ = f.button :submit