notify_user 0.0.1 → 0.0.5

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.
Files changed (79) hide show
  1. checksums.yaml +7 -0
  2. data/app/assets/javascripts/notify_user/notification.js +7 -0
  3. data/app/assets/stylesheets/notify_user/notify_user.css +50 -0
  4. data/app/controllers/notify_user/base_notifications_controller.rb +144 -0
  5. data/app/controllers/notify_user/notifications_controller.rb +7 -32
  6. data/app/helpers/notify_user/application_helper.rb +9 -0
  7. data/app/mailers/notify_user/notification_mailer.rb +2 -0
  8. data/app/models/notify_user/apns.rb +37 -0
  9. data/app/models/notify_user/base_notification.rb +136 -32
  10. data/app/models/notify_user/unsubscribe.rb +55 -0
  11. data/app/models/notify_user/user_hash.rb +36 -0
  12. data/app/serializers/notify_user/notification_serializer.rb +2 -2
  13. data/app/views/notify_user/action_mailer/aggregate_notification.html.erb +2 -1
  14. data/app/views/notify_user/action_mailer/notification.html.erb +1 -1
  15. data/app/views/notify_user/base_notifications/index.html.erb +20 -0
  16. data/app/views/notify_user/base_notifications/unsubscribe.html.erb +19 -0
  17. data/config/routes.rb +8 -0
  18. data/lib/generators/notify_user/install/install_generator.rb +20 -3
  19. data/lib/generators/notify_user/install/templates/{migration.rb → create_notify_user_notifications.rb} +1 -1
  20. data/lib/generators/notify_user/install/templates/create_notify_user_unsubscribes.rb +10 -0
  21. data/lib/generators/notify_user/install/templates/create_notify_user_user_hashes.rb +12 -0
  22. data/lib/generators/notify_user/install/templates/initializer.rb +2 -0
  23. data/lib/generators/notify_user/install/templates/notifications_controller.rb +9 -0
  24. data/lib/generators/notify_user/json_update/USAGE +5 -0
  25. data/lib/generators/notify_user/json_update/json_update_generator.rb +36 -0
  26. data/lib/generators/notify_user/json_update/templates/add_json_column_to_notifications.rb +9 -0
  27. data/lib/generators/notify_user/json_update/templates/move_params_to_json.rb +8 -0
  28. data/lib/generators/notify_user/notification/notification_generator.rb +2 -0
  29. data/lib/generators/notify_user/notification/templates/email_layout_template.html.erb.erb +6 -0
  30. data/lib/generators/notify_user/notification/templates/notification.rb.erb +2 -1
  31. data/lib/notify_user.rb +4 -1
  32. data/lib/notify_user/channels/action_mailer/action_mailer_channel.rb +2 -1
  33. data/lib/notify_user/channels/apns/apns_channel.rb +17 -0
  34. data/lib/notify_user/engine.rb +2 -0
  35. data/lib/notify_user/railtie.rb +10 -0
  36. data/lib/notify_user/version.rb +1 -1
  37. data/lib/tasks/notify_user.rake +15 -0
  38. data/spec/controllers/notify_user/notifications_controller_spec.rb +89 -1
  39. data/spec/dummy/rails-4.0.2/Gemfile +2 -2
  40. data/spec/dummy/rails-4.0.2/app/controllers/notify_user/notifications_controller.rb +9 -0
  41. data/spec/dummy/rails-4.0.2/app/notifications/new_post_notification.rb +2 -1
  42. data/spec/dummy/rails-4.0.2/app/views/notify_user/layouts/action_mailer.html.erb +6 -0
  43. data/spec/dummy/rails-4.0.2/config/database.yml +42 -13
  44. data/spec/dummy/rails-4.0.2/config/database2.yml +57 -0
  45. data/spec/dummy/rails-4.0.2/config/initializers/notify_user.rb +2 -0
  46. data/spec/dummy/rails-4.0.2/config/initializers/secret_token.rb +1 -1
  47. data/spec/dummy/rails-4.0.2/db/migrate/{20140105070446_create_users.rb → 20140428015529_create_users.rb} +0 -0
  48. data/spec/dummy/rails-4.0.2/db/migrate/{20140105070448_create_notify_user_notifications.rb → 20140428015531189189694000_create_notify_user_notifications.rb} +1 -1
  49. data/spec/dummy/rails-4.0.2/db/migrate/20140428015531190190743000_create_notify_user_unsubscribes.rb +10 -0
  50. data/spec/dummy/rails-4.0.2/db/migrate/20140428015531191191953000_create_notify_user_user_hashes.rb +12 -0
  51. data/spec/dummy/rails-4.0.2/db/schema.rb +23 -2
  52. data/spec/dummy/rails-4.0.2/log/test.log +787 -1414
  53. data/spec/dummy/rails-4.0.2/tmp/cache/assets/test/sprockets/13195a56ea8581e42f709ea01ea4604f +0 -0
  54. data/{app/assets/stylesheets/notify_user/application.css → spec/dummy/rails-4.0.2/tmp/cache/assets/test/sprockets/13fe41fee1fe35b49d145bcc06610705} +0 -0
  55. data/spec/dummy/rails-4.0.2/tmp/cache/assets/test/sprockets/148f39f7dc2ea6cb194598111dbd4598 +0 -0
  56. data/spec/dummy/rails-4.0.2/tmp/cache/assets/test/sprockets/1d6bc1877ba2bbb89f393e10e8303d39 +0 -0
  57. data/spec/dummy/rails-4.0.2/tmp/cache/assets/test/sprockets/2f5173deea6c795b8fdde723bb4b63af +0 -0
  58. data/spec/dummy/rails-4.0.2/tmp/cache/assets/test/sprockets/311d2b645a860b78f79ff156f12092ce +0 -0
  59. data/spec/dummy/rails-4.0.2/tmp/cache/assets/test/sprockets/357970feca3ac29060c1e3861e2c0953 +0 -0
  60. data/spec/dummy/rails-4.0.2/tmp/cache/assets/test/sprockets/39651f0f2ac78423732234ebf092c632 +0 -0
  61. data/spec/dummy/rails-4.0.2/tmp/cache/assets/test/sprockets/5c85b1b5ac27b699c5f800c4e7ec82fb +0 -0
  62. data/spec/dummy/rails-4.0.2/tmp/cache/assets/test/sprockets/68752c7ddc300bee3e9823db8befc306 +0 -0
  63. data/spec/dummy/rails-4.0.2/tmp/cache/assets/test/sprockets/6961013077b8573ed19d1e33abb8ebc5 +0 -0
  64. data/spec/dummy/rails-4.0.2/tmp/cache/assets/test/sprockets/7a316b3629b980c6d3a28924cb5fbbd8 +0 -0
  65. data/spec/dummy/rails-4.0.2/tmp/cache/assets/test/sprockets/8698d6fed0ef2f173a377160752b959f +0 -0
  66. data/spec/dummy/rails-4.0.2/tmp/cache/assets/test/sprockets/8bab520aad78da438df1c428288cf229 +0 -0
  67. data/spec/dummy/rails-4.0.2/tmp/cache/assets/test/sprockets/cffd775d018f68ce5dba1ee0d951a994 +0 -0
  68. data/spec/dummy/rails-4.0.2/tmp/cache/assets/test/sprockets/d771ace226fc8215a3572e0aa35bb0d6 +0 -0
  69. data/spec/dummy/rails-4.0.2/tmp/cache/assets/test/sprockets/f7cbd26ba1d28d48de824f0e94586655 +0 -0
  70. data/spec/dummy/rails-4.0.2/tmp/cache/assets/test/sprockets/fa138a16887e031c0ae1b4caccfb4c05 +0 -0
  71. data/spec/mailers/notify_user/notification_mailer_spec.rb +1 -0
  72. data/spec/models/notify_user/notification_spec.rb +122 -1
  73. data/spec/models/notify_user/unsubscribe_spec.rb +40 -0
  74. data/spec/models/notify_user/user_hash_spec.rb +35 -0
  75. data/spec/spec_helper.rb +5 -0
  76. data/spec/support/database.yml +21 -0
  77. data/spec/support/rails_template.rb +9 -0
  78. metadata +196 -65
  79. data/spec/dummy/rails-4.0.2/db/test.sqlite3 +0 -0
@@ -0,0 +1,55 @@
1
+ module NotifyUser
2
+ class Unsubscribe < ActiveRecord::Base
3
+ self.table_name = "notify_user_unsubscribes"
4
+
5
+ # The user to send the notification to
6
+ belongs_to :target, polymorphic: true
7
+
8
+ validates_presence_of :target_id, :target_type, :target, :type
9
+
10
+ validate :is_unsubscribable
11
+
12
+ validates :type, :uniqueness => {:scope => [:target_type, :target_id]}
13
+
14
+ self.inheritance_column = :_type_disabled
15
+
16
+ if Rails.version.to_i < 4
17
+ attr_accessible :target, :type
18
+ end
19
+
20
+ def self.for_target(target)
21
+ where(target_id: target.id)
22
+ .where(target_type: target.class.base_class)
23
+ end
24
+
25
+ def self.toggle_status(target, type)
26
+ if NotifyUser::Unsubscribe.has_unsubscribed_from(target, type).empty?
27
+ NotifyUser::Unsubscribe.create(target: target, type: type)
28
+ else
29
+ NotifyUser::Unsubscribe.unsubscribe(target,type)
30
+ end
31
+ end
32
+
33
+ def self.unsubscribe(target, type)
34
+ #deletes unsubscribe object in essence subscribing a user
35
+ where(target_id: target.id)
36
+ .where(target_type: target.class.base_class)
37
+ .where(type: type).destroy_all
38
+ end
39
+
40
+ def self.has_unsubscribed_from(target, type)
41
+ where(target_id: target.id)
42
+ .where(target_type: target.class.base_class)
43
+ .where(type: type)
44
+ end
45
+
46
+ private
47
+
48
+ #only throw error if both are false
49
+ def is_unsubscribable
50
+ errors.add(:type, ("not found")) if (NotifyUser.unsubscribable_notifications.include? self.type) == false &&
51
+ NotifyUser::BaseNotification.channels.has_key?(self.type.to_sym) == false
52
+ end
53
+
54
+ end
55
+ end
@@ -0,0 +1,36 @@
1
+ module NotifyUser
2
+ class UserHash < ActiveRecord::Base
3
+ self.table_name = "notify_user_user_hashes"
4
+
5
+ # The user to send the notification to
6
+ belongs_to :target, polymorphic: true
7
+
8
+ validates_presence_of :target_id, :target_type, :target, :type
9
+
10
+ before_create :generate_token
11
+
12
+ self.inheritance_column = :_type_disabled
13
+
14
+ if Rails.version.to_i < 4
15
+ attr_accessible :target, :type, :active
16
+ end
17
+
18
+ def self.confirm_hash(token, type)
19
+ return NotifyUser::UserHash.exists?(token: token, type: type, active: true)
20
+ end
21
+
22
+ def deactivate
23
+ self.active = false
24
+ save
25
+ end
26
+
27
+ private
28
+ def generate_token
29
+ self.token = loop do
30
+ random_token = SecureRandom.urlsafe_base64(nil, false) + SecureRandom.urlsafe_base64(nil, false)
31
+ break random_token unless NotifyUser::UserHash.exists?(token: random_token)
32
+ end
33
+ end
34
+
35
+ end
36
+ end
@@ -1,12 +1,12 @@
1
1
  class NotifyUser::NotificationSerializer < ActiveModel::Serializer
2
2
  root :notifications
3
3
 
4
- attributes :id, :message, :read
4
+ attributes :id, :type, :message, :read, :params, :created_at
5
5
 
6
6
  def message
7
7
  options[:template_renderer].render_to_string(:template => object.class.views[:mobile_sdk][:template_path].call(object),
8
8
  :locals => {params: object.params},
9
- :layout => false)
9
+ :layout => false, :formats => [:html])
10
10
  end
11
11
 
12
12
  def read
@@ -1,5 +1,6 @@
1
+
1
2
  <% @notifications.each do |notification| %>
2
3
  <div>
3
4
  <%= render template: "notify_user/#{notification.class.name.underscore}/action_mailer/notification", locals: { notification: notification, params: notification.params } %>
4
5
  </div>
5
- <% end %>
6
+ <% end %>
@@ -1 +1 @@
1
- <%= render template: "notify_user/#{@notification.class.name.underscore}/action_mailer/notification", locals: { notification: @notification, params: @notification.params } %>
1
+ <%= render template: "notify_user/#{@notification.class.name.underscore}/action_mailer/notification", locals: { notification: @notification, params: @notification.params } %>
@@ -0,0 +1,20 @@
1
+ <%= javascript_include_tag 'notify_user/notification' %>
2
+ <%= stylesheet_link_tag 'notify_user/notify_user' %>
3
+
4
+ <div id="notifications_list">
5
+ <div class="mark_as_read">
6
+ <%= link_to 'Mark all as read', notify_user_notifications_mark_all_path %>
7
+ </div>
8
+
9
+ <div class="inner">
10
+ <% @notifications.each do |notification| %>
11
+ <div class="item <%= !notification.read? ? 'unread' : 'read' %>">
12
+ <div class="content"><%= link_to notification.message, notify_user_path(notification), :class => 'message', :id => notification.id %></div>
13
+ <div class="time_ago">
14
+ <%= time_ago_in_words(notification.created_at) %> ago
15
+ </div>
16
+ </div>
17
+ <% end %>
18
+ </div>
19
+
20
+ </div>
@@ -0,0 +1,19 @@
1
+
2
+
3
+ <div id="notifications_list">
4
+ <div class="title">Unsubscribe from notifications</div>
5
+ <%= flash[:message] %>
6
+ <div class="inner">
7
+ <% @unsubscribale_types.each do |type| %>
8
+ <div class="item">
9
+ <%= type %>
10
+ <% if NotifyUser::Unsubscribe.has_unsubscribed_from(@user, type).empty? %>
11
+ <%= link_to "Unsubscribe", notify_user_notifications_unsubscribe_path(:type => type) %>
12
+ <% else %>
13
+ <%= link_to "Subscribe", notify_user_notifications_subscribe_path(:type => type) %>
14
+ <% end %>
15
+ </div>
16
+ <% end %>
17
+ </div>
18
+
19
+ </div>
data/config/routes.rb CHANGED
@@ -2,5 +2,13 @@ Rails.application.routes.draw do
2
2
  namespace :notify_user do
3
3
  resources :notifications, only: [:index]
4
4
  put 'notifications/mark_read' => 'notifications#mark_read'
5
+ get 'notifications/notifications_count' => 'notifications#notifications_count'
6
+ get 'notifications/:id/read' => 'notifications#read'
7
+ get 'notifications/mark_all' => 'notifications#mark_all'
8
+ get 'notifications/unsubscribe' => 'notifications#unsubscribe'
9
+ get 'notifications/subscribe' => 'notifications#subscribe'
10
+ get 'notifications/unauth_unsubscribe' => 'notifications#unauth_unsubscribe'
11
+ get 'notifications/subscriptions' => 'notifications#subscriptions'
12
+ put 'notifications/subscriptions' => 'notifications#subscriptions'
5
13
  end
6
14
  end
@@ -5,8 +5,11 @@ class NotifyUser::InstallGenerator < Rails::Generators::Base
5
5
 
6
6
  source_root File.expand_path('../templates', __FILE__)
7
7
 
8
- def copy_migration
9
- migration_template "migration.rb", "db/migrate/create_notify_user_notifications"
8
+ def copy_migrations
9
+ copy_migration "create_notify_user_notifications"
10
+ copy_migration "create_notify_user_unsubscribes"
11
+ copy_migration "create_notify_user_user_hashes"
12
+
10
13
  puts "Installation successful. You can now run:"
11
14
  puts " rake db:migrate"
12
15
  end
@@ -15,14 +18,28 @@ class NotifyUser::InstallGenerator < Rails::Generators::Base
15
18
  template "initializer.rb", "config/initializers/notify_user.rb"
16
19
  end
17
20
 
21
+ def copy_notifications_controller
22
+ template "notifications_controller.rb", "app/controllers/notify_user/notifications_controller.rb"
23
+ end
24
+
18
25
  # This is defined in ActiveRecord::Generators::Base, but that inherits from NamedBase, so it expects a name argument
19
26
  # which we don't want here. So we redefine it here. Yuck.
20
27
  def self.next_migration_number(dirname)
21
28
  if ActiveRecord::Base.timestamped_migrations
22
- Time.now.utc.strftime("%Y%m%d%H%M%S")
29
+ Time.now.utc.strftime("%Y%m%d%H%M%S%L%N")
23
30
  else
24
31
  "%.3d" % (current_migration_number(dirname) + 1)
25
32
  end
26
33
  end
27
34
 
35
+ protected
36
+
37
+ def copy_migration(filename)
38
+ if self.class.migration_exists?("db/migrate", "#{filename}")
39
+ say_status("skipped", "Migration #{filename}.rb already exists")
40
+ else
41
+ migration_template "#{filename}.rb", "db/migrate/#{filename}.rb"
42
+ end
43
+ end
44
+
28
45
  end
@@ -4,7 +4,7 @@ class CreateNotifyUserNotifications < ActiveRecord::Migration
4
4
  t.string :type
5
5
  t.integer :target_id
6
6
  t.string :target_type
7
- t.text :params
7
+ t.json :params
8
8
  t.string :state
9
9
 
10
10
  t.timestamps
@@ -0,0 +1,10 @@
1
+ class CreateNotifyUserUnsubscribes < ActiveRecord::Migration
2
+ def change
3
+ create_table :notify_user_unsubscribes do |t|
4
+ t.string :type
5
+ t.integer :target_id
6
+ t.string :target_type
7
+ t.timestamps
8
+ end
9
+ end
10
+ end
@@ -0,0 +1,12 @@
1
+ class CreateNotifyUserUserHashes < ActiveRecord::Migration
2
+ def change
3
+ create_table :notify_user_user_hashes do |t|
4
+ t.string :type
5
+ t.integer :target_id
6
+ t.string :target_type
7
+ t.string :token
8
+ t.boolean :active, default: true
9
+ t.timestamps
10
+ end
11
+ end
12
+ end
@@ -9,4 +9,6 @@ NotifyUser.setup do |config|
9
9
  # NotifyUser will call this within NotificationsController to return the current logged in user.
10
10
  config.current_user_method = :current_user
11
11
 
12
+ # Override the default notification type
13
+ config.unsubscribable_notifications = ['NewPostNotification']
12
14
  end
@@ -0,0 +1,9 @@
1
+ class NotifyUser::NotificationsController < NotifyUser::BaseNotificationsController
2
+ def redirect_logic(notification)
3
+ render :text => "set redirect logic in notify_user/notifications_controller.rb"
4
+ # notification redirect logic goes here
5
+ # class_name = notification.params[:type].capitalize.constantize
6
+ # object = class_name.find(@notification.params[:id])
7
+ # redirect_to property_url(object)
8
+ end
9
+ end
@@ -0,0 +1,5 @@
1
+ Description:
2
+ Updates notify_user params to the PostgresSQL datatype json
3
+
4
+ Example:
5
+ rails generate notify_user:json_update
@@ -0,0 +1,36 @@
1
+ require 'rails/generators/active_record'
2
+
3
+ class NotifyUser::JsonUpdateGenerator < Rails::Generators::Base
4
+ include Rails::Generators::Migration
5
+
6
+ source_root File.expand_path('../templates', __FILE__)
7
+
8
+ def copy_migrations
9
+ copy_migration "add_json_column_to_notifications"
10
+ copy_migration "move_params_to_json"
11
+
12
+ puts "Installation successful. You can now run:"
13
+ puts " rake db:migrate"
14
+ end
15
+
16
+ # This is defined in ActiveRecord::Generators::Base, but that inherits from NamedBase, so it expects a name argument
17
+ # which we don't want here. So we redefine it here. Yuck.
18
+ def self.next_migration_number(dirname)
19
+ if ActiveRecord::Base.timestamped_migrations
20
+ Time.now.utc.strftime("%Y%m%d%H%M%S%L%N")
21
+ else
22
+ "%.3d" % (current_migration_number(dirname) + 1)
23
+ end
24
+ end
25
+
26
+ protected
27
+
28
+ def copy_migration(filename)
29
+ if self.class.migration_exists?("db/migrate", "#{filename}")
30
+ say_status("skipped", "Migration #{filename}.rb already exists")
31
+ else
32
+ migration_template "#{filename}.rb", "db/migrate/#{filename}.rb"
33
+ end
34
+ end
35
+
36
+ end
@@ -0,0 +1,9 @@
1
+ class AddJsonColumnToNotifications < ActiveRecord::Migration
2
+ def up
3
+ add_column :notify_user_notifications, :json, :json, default: {}
4
+ end
5
+
6
+ def down
7
+ remove_column :notify_user_notifications, :json
8
+ end
9
+ end
@@ -0,0 +1,8 @@
1
+ class MoveParamsToJson < ActiveRecord::Migration
2
+ def change
3
+ system('rake notify_user:move_params_to_json')
4
+
5
+ remove_column :notify_user_notifications, :params
6
+ rename_column :notify_user_notifications, :json, :params
7
+ end
8
+ end
@@ -5,6 +5,8 @@ module NotifyUser
5
5
 
6
6
  def generate_notification
7
7
  template "notification.rb.erb", "app/notifications/#{name.underscore}.rb"
8
+ puts "If you wish this notification to be unsubscribable add it to the unsubscribable_notifications array in the initializer"
9
+
8
10
  end
9
11
 
10
12
  def generate_view_scaffolds
@@ -18,6 +18,12 @@
18
18
  </div>
19
19
  <div style="width: 100%; min-height: 80px; margin: 0; padding: 0;">
20
20
  <div style="width: 600px; margin: 0 auto; padding: 0;">
21
+ <%% if is_unsubscribeable? @notification %>
22
+ <p style="text-align: center;">
23
+ <%%= unsubscribe_link(@notification, "Unsubscribe") %>
24
+ </p>
25
+ <%%
26
+ end %>
21
27
  <p style="text-align: center;">
22
28
  This is the default generated layout. A privacy declaration could go here.
23
29
  </p>
@@ -4,7 +4,8 @@ class <%= name.camelize %> < NotifyUser::BaseNotification
4
4
  subject: "<%= Rails.application.class.parent_name.titleize %>: You have a new <%= name.humanize %> notification.",
5
5
  aggregate: {
6
6
  subject: "<%= Rails.application.class.parent_name.titleize %>: You have new <%= name.humanize %> notifications."
7
- }
7
+ }
8
8
 
9
+ @@description = "please override this type description"
9
10
  @@aggregate_per = 10.minutes
10
11
  end
data/lib/notify_user.rb CHANGED
@@ -1,5 +1,5 @@
1
1
  require "kaminari"
2
-
2
+ require "notify_user/railtie"
3
3
  require "notify_user/engine"
4
4
 
5
5
  module NotifyUser
@@ -13,6 +13,9 @@ module NotifyUser
13
13
  mattr_accessor :current_user_method
14
14
  @@current_user_method = nil
15
15
 
16
+ mattr_accessor :unsubscribable_notifications
17
+ @@unsubscribable_notifications = nil
18
+
16
19
  # Used to set up NotifyUser from the initializer.
17
20
  def self.setup
18
21
  yield self
@@ -7,7 +7,8 @@ class ActionMailerChannel
7
7
  subject: "New Notification",
8
8
  aggregate: {
9
9
  subject: "New Notifications"
10
- }
10
+ },
11
+ description: "Email notifications"
11
12
  }
12
13
  end
13
14
 
@@ -0,0 +1,17 @@
1
+ class ApnsChannel
2
+
3
+ class << self
4
+
5
+ def default_options
6
+ {
7
+ description: "Apple push notifications service"
8
+ }
9
+ end
10
+
11
+ def deliver(notification, options={})
12
+ NotifyUser::Apns.push_notification(notification)
13
+ end
14
+
15
+ end
16
+
17
+ end
@@ -1,5 +1,7 @@
1
1
  module NotifyUser
2
2
  class Engine < ::Rails::Engine
3
+ require 'active_model_serializers'
4
+ require 'urbanairship'
3
5
 
4
6
  config.generators do |g|
5
7
  g.test_framework :rspec, :fixture => false
@@ -0,0 +1,10 @@
1
+ class Railtie < ::Rails::Railtie
2
+ initializer "notify_user.setup_assets" do |app|
3
+ app.config.assets.precompile += %w( notify_user/notify_user.css )
4
+ end
5
+
6
+ rake_tasks do
7
+ gem_dir = File.expand_path('..',File.dirname(__FILE__))
8
+ load "#{gem_dir}/tasks/notify_user.rake"
9
+ end
10
+ end