notifiable-core 0.1.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.
Files changed (27) hide show
  1. checksums.yaml +7 -0
  2. data/README.md +39 -0
  3. data/Rakefile +8 -0
  4. data/db/migrate/20131210115648_create_notifiable_apps.rb +12 -0
  5. data/db/migrate/20131210115649_create_notifiable_device_tokens.rb +18 -0
  6. data/db/migrate/20131210115650_create_notifiable_notifications.rb +27 -0
  7. data/db/migrate/20131210115652_create_notifiable_statuses.rb +12 -0
  8. data/db/migrate/20131210115653_add_name_to_notifiable_device_tokens.rb +7 -0
  9. data/db/migrate/20161208221332_add_badge_count_to_notifiable_notifications.rb +7 -0
  10. data/db/migrate/20170108221332_remove_is_valid_from_notifiable_device_tokens.rb +7 -0
  11. data/db/migrate/20170108221432_add_app_id_token_index_to_notifiable_device_tokens.rb +7 -0
  12. data/db/migrate/20180302212641_add_last_error_message_to_notifications.rb +7 -0
  13. data/db/migrate/201803142135000_add_title_to_notifications.rb +7 -0
  14. data/db/migrate/201805292135000_add_language_and_country_to_device_tokens.rb +8 -0
  15. data/db/migrate/201806182135000_add_thread_id_to_notifications.rb +7 -0
  16. data/db/migrate/201806242135000_add_category_to_notifications.rb +7 -0
  17. data/db/migrate/201808242135000_add_error_message_to_notification_statuses.rb +7 -0
  18. data/lib/notifiable/app.rb +58 -0
  19. data/lib/notifiable/device_token.rb +28 -0
  20. data/lib/notifiable/engine.rb +24 -0
  21. data/lib/notifiable/notification.rb +52 -0
  22. data/lib/notifiable/notification_status.rb +24 -0
  23. data/lib/notifiable/notifier_base.rb +57 -0
  24. data/lib/notifiable/version.rb +3 -0
  25. data/lib/notifiable.rb +35 -0
  26. data/lib/tasks/db.rake +34 -0
  27. metadata +237 -0
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA256:
3
+ metadata.gz: 8ac554de551cf36da88b12784f86156c1de6734c46a6e053f7eb9035559bba4e
4
+ data.tar.gz: 5330a372f587925e7e743facde1bb13fa07dc1b268399f1b2a9e55d8a78c2f4f
5
+ SHA512:
6
+ metadata.gz: d35a7d6f7b4769243cbebb8c04d01fcc707070c4e85101318f6b4e4351abc6def65cf7f1ff000d9cc7c93dc7c4f4b015d5a909c198452a2ae1a7605f5a1fc264
7
+ data.tar.gz: fbfffe1ac698f8dd26b8a2e2ea435b0dad141252e3e30d5d27173a001a506d78db39c8e9190454ead5e506fc3ee244cc10f2356f2137b3a6a85e5cdce4209437
data/README.md ADDED
@@ -0,0 +1,39 @@
1
+ # Notifiable
2
+
3
+ Welcome to your new gem! In this directory, you'll find the files you need to be able to package up your Ruby library into a gem. Put your Ruby code in the file `lib/notifiable`. To experiment with that code, run `bin/console` for an interactive prompt.
4
+
5
+ TODO: Delete this and the text above, and describe your gem
6
+
7
+ ## Installation
8
+
9
+ Add this line to your application's Gemfile:
10
+
11
+ ```ruby
12
+ gem 'notifiable'
13
+ ```
14
+
15
+ And then execute:
16
+
17
+ $ bundle
18
+
19
+ Or install it yourself as:
20
+
21
+ $ gem install notifiable
22
+
23
+ ## Usage
24
+
25
+ TODO: Write usage instructions here
26
+
27
+ ## Development
28
+
29
+ After checking out the repo, run `bin/setup` to install dependencies. Then, run `rake spec` to run the tests. You can also run `bin/console` for an interactive prompt that will allow you to experiment.
30
+
31
+ To install this gem onto your local machine, run `bundle exec rake install`. To release a new version, update the version number in `version.rb`, and then run `bundle exec rake release`, which will create a git tag for the version, push git commits and tags, and push the `.gem` file to [rubygems.org](https://rubygems.org).
32
+
33
+ ## Contributing
34
+
35
+ Bug reports and pull requests are welcome on GitHub at https://github.com/[USERNAME]/notifiable.
36
+
37
+ ## License
38
+
39
+ The gem is available as open source under the terms of the [MIT License](https://opensource.org/licenses/MIT).
data/Rakefile ADDED
@@ -0,0 +1,8 @@
1
+ require 'bundler/gem_tasks'
2
+ require 'rspec/core/rake_task'
3
+
4
+ load 'tasks/db.rake'
5
+
6
+ RSpec::Core::RakeTask.new(:spec)
7
+
8
+ task default: :spec
@@ -0,0 +1,12 @@
1
+ # frozen_string_literal: true
2
+
3
+ class CreateNotifiableApps < ActiveRecord::Migration[4.2]
4
+ def change
5
+ create_table :notifiable_apps do |t|
6
+ t.string :name
7
+ t.text :configuration
8
+
9
+ t.timestamps
10
+ end
11
+ end
12
+ end
@@ -0,0 +1,18 @@
1
+ # frozen_string_literal: true
2
+
3
+ class CreateNotifiableDeviceTokens < ActiveRecord::Migration[4.2]
4
+ def change
5
+ create_table :notifiable_device_tokens do |t|
6
+ t.string :token
7
+ t.string :provider
8
+ t.string :locale
9
+ t.boolean :is_valid, default: true
10
+ t.string :user_alias
11
+ t.references :app
12
+
13
+ t.timestamps
14
+ end
15
+
16
+ add_index :notifiable_device_tokens, :user_alias
17
+ end
18
+ end
@@ -0,0 +1,27 @@
1
+ # frozen_string_literal: true
2
+
3
+ class CreateNotifiableNotifications < ActiveRecord::Migration[4.2]
4
+ def change
5
+ create_table :notifiable_notifications do |t|
6
+ t.references :app
7
+
8
+ # stats
9
+ t.integer :sent_count, default: 0
10
+ t.integer :gateway_accepted_count, default: 0
11
+ t.integer :opened_count, default: 0
12
+
13
+ # notification properties
14
+ t.text :message
15
+ t.text :parameters
16
+ t.string :sound
17
+
18
+ # apns
19
+ t.string :identifier
20
+ t.datetime :expiry
21
+ t.boolean :content_available
22
+ t.boolean :mutable_content
23
+
24
+ t.timestamps
25
+ end
26
+ end
27
+ end
@@ -0,0 +1,12 @@
1
+ # frozen_string_literal: true
2
+
3
+ class CreateNotifiableStatuses < ActiveRecord::Migration[4.2]
4
+ def change
5
+ create_table :notifiable_statuses do |t|
6
+ t.references :notification
7
+ t.references :device_token
8
+ t.integer :status
9
+ t.datetime :created_at
10
+ end
11
+ end
12
+ end
@@ -0,0 +1,7 @@
1
+ # frozen_string_literal: true
2
+
3
+ class AddNameToNotifiableDeviceTokens < ActiveRecord::Migration[4.2]
4
+ def change
5
+ add_column :notifiable_device_tokens, :name, :string
6
+ end
7
+ end
@@ -0,0 +1,7 @@
1
+ # frozen_string_literal: true
2
+
3
+ class AddBadgeCountToNotifiableNotifications < ActiveRecord::Migration[4.2]
4
+ def change
5
+ add_column :notifiable_notifications, :badge_count, :integer
6
+ end
7
+ end
@@ -0,0 +1,7 @@
1
+ # frozen_string_literal: true
2
+
3
+ class RemoveIsValidFromNotifiableDeviceTokens < ActiveRecord::Migration[4.2]
4
+ def change
5
+ remove_column :notifiable_device_tokens, :is_valid, :boolean, default: true
6
+ end
7
+ end
@@ -0,0 +1,7 @@
1
+ # frozen_string_literal: true
2
+
3
+ class AddAppIdTokenIndexToNotifiableDeviceTokens < ActiveRecord::Migration[4.2]
4
+ def change
5
+ add_index :notifiable_device_tokens, %i[app_id token], unique: true
6
+ end
7
+ end
@@ -0,0 +1,7 @@
1
+ # frozen_string_literal: true
2
+
3
+ class AddLastErrorMessageToNotifications < ActiveRecord::Migration[4.2]
4
+ def change
5
+ add_column :notifiable_notifications, :last_error_message, :text
6
+ end
7
+ end
@@ -0,0 +1,7 @@
1
+ # frozen_string_literal: true
2
+
3
+ class AddTitleToNotifications < ActiveRecord::Migration[4.2]
4
+ def change
5
+ add_column :notifiable_notifications, :title, :string
6
+ end
7
+ end
@@ -0,0 +1,8 @@
1
+ # frozen_string_literal: true
2
+
3
+ class AddLanguageAndCountryToDeviceTokens < ActiveRecord::Migration[4.2]
4
+ def change
5
+ add_column :notifiable_device_tokens, :language, :string
6
+ add_column :notifiable_device_tokens, :country, :string
7
+ end
8
+ end
@@ -0,0 +1,7 @@
1
+ # frozen_string_literal: true
2
+
3
+ class AddThreadIdToNotifications < ActiveRecord::Migration[4.2]
4
+ def change
5
+ add_column :notifiable_notifications, :thread_id, :string
6
+ end
7
+ end
@@ -0,0 +1,7 @@
1
+ # frozen_string_literal: true
2
+
3
+ class AddCategoryToNotifications < ActiveRecord::Migration[4.2]
4
+ def change
5
+ add_column :notifiable_notifications, :category, :string
6
+ end
7
+ end
@@ -0,0 +1,7 @@
1
+ # frozen_string_literal: true
2
+
3
+ class AddErrorMessageToNotificationStatuses < ActiveRecord::Migration[4.2]
4
+ def change
5
+ add_column :notifiable_statuses, :error_message, :string
6
+ end
7
+ end
@@ -0,0 +1,58 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Notifiable
4
+ class App < ActiveRecord::Base
5
+ self.table_name_prefix = 'notifiable_'
6
+
7
+ has_many :device_tokens, class_name: 'Notifiable::DeviceToken', dependent: :destroy
8
+ has_many :notifications, class_name: 'Notifiable::Notification', dependent: :destroy
9
+
10
+ serialize :configuration
11
+
12
+ validates :name, presence: true, allow_blank: false
13
+
14
+ def configure(provider, notifier)
15
+ return unless configuration && configuration[provider]
16
+
17
+ configuration[provider].each_pair { |key, value| notifier.instance_variable_set("@#{key}", value) if notifier.class.notifier_attributes.include?(key) }
18
+ end
19
+
20
+ def configuration
21
+ unless read_attribute(:configuration)
22
+ write_attribute(:configuration, default_configuration)
23
+ end
24
+ read_attribute(:configuration)
25
+ end
26
+
27
+ def default_configuration
28
+ configuration = {}
29
+ Notifiable.notifier_classes.each_pair do |provider, clazz|
30
+ configuration[provider] = {}
31
+ next unless clazz.notifier_attributes
32
+ clazz.notifier_attributes.each do |notifier_attribute|
33
+ configuration[provider][notifier_attribute] = nil
34
+ end
35
+ end
36
+ configuration
37
+ end
38
+
39
+ def self.define_configuration_accessors(notifiers)
40
+ notifiers.each_pair do |provider, clazz|
41
+ next unless clazz.notifier_attributes
42
+
43
+ clazz.notifier_attributes.each do |attribute|
44
+ define_method("#{provider}_#{attribute}=") { |v| configuration[provider][attribute] = v }
45
+ define_method("#{provider}_#{attribute}") { configuration[provider][attribute] }
46
+ end
47
+ end
48
+ end
49
+
50
+ def save_notification_statuses
51
+ configuration[:save_notification_statuses] == true || configuration[:save_notification_statuses].eql?('1')
52
+ end
53
+
54
+ def save_notification_statuses=(save_notification_statuses)
55
+ configuration[:save_notification_statuses] = save_notification_statuses
56
+ end
57
+ end
58
+ end
@@ -0,0 +1,28 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Notifiable
4
+ class DeviceToken < ActiveRecord::Base
5
+ self.table_name_prefix = 'notifiable_'
6
+
7
+ belongs_to :app, class_name: 'Notifiable::App'
8
+ has_many :notification_statuses, class_name: 'Notifiable::NotificationStatus'
9
+
10
+ validates :token, presence: true, uniqueness: { scope: :app }
11
+ validates :provider, presence: true
12
+ validates :app, presence: true
13
+ validates :language, length: { in: 2..3 }, allow_blank: true # ISO 639-1 or ISO 6369-2 language code
14
+ validates :country, length: { is: 2 }, allow_blank: true # ISO 3166-1 alpha-2 country code
15
+
16
+ before_save :downcase_language, :downcase_country
17
+
18
+ private
19
+
20
+ def downcase_language
21
+ language&.downcase!
22
+ end
23
+
24
+ def downcase_country
25
+ country&.downcase!
26
+ end
27
+ end
28
+ end
@@ -0,0 +1,24 @@
1
+ require 'rails'
2
+
3
+ module Notifiable
4
+
5
+ class Engine < ::Rails::Engine
6
+ isolate_namespace Notifiable
7
+
8
+ # load decorators
9
+ config.to_prepare do
10
+ Dir.glob(Rails.root + "app/decorators/**/*_decorator*.rb").each do |c|
11
+ require_dependency(c)
12
+ end
13
+ end
14
+
15
+ initializer :append_migrations do |app|
16
+ unless app.root.to_s.match root.to_s
17
+ config.paths["db/migrate"].expanded.each do |expanded_path|
18
+ app.config.paths["db/migrate"] << expanded_path
19
+ end
20
+ end
21
+ end
22
+ end
23
+
24
+ end
@@ -0,0 +1,52 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Notifiable
4
+ class Notification < ActiveRecord::Base
5
+ self.table_name_prefix = 'notifiable_'
6
+
7
+ belongs_to :app, class_name: 'Notifiable::App'
8
+ validates :app, presence: true
9
+
10
+ serialize :parameters
11
+
12
+ has_many :notification_statuses, class_name: 'Notifiable::NotificationStatus', dependent: :destroy
13
+
14
+ def batch
15
+ yield(self)
16
+ update(last_error_message: nil)
17
+ rescue Exception => e
18
+ update(last_error_message: e.message)
19
+ ensure
20
+ close
21
+ end
22
+
23
+ def add_device_token(d)
24
+ provider = d.provider.to_sym
25
+
26
+ unless notifiers[provider]
27
+ clazz = Notifiable.notifier_class(self, d)
28
+ raise "Notifier #{provider} not configured" unless clazz
29
+ notifier = clazz.new(self)
30
+ app.configure(provider, notifier)
31
+ @notifiers[provider] = notifier
32
+ end
33
+
34
+ notifiers[provider].send_notification(d)
35
+ end
36
+
37
+ def send_params
38
+ @send_params ||= (parameters || {}).merge(n_id: id)
39
+ end
40
+
41
+ private
42
+
43
+ def notifiers
44
+ @notifiers ||= {}
45
+ end
46
+
47
+ def close
48
+ notifiers.each_value(&:close)
49
+ @notifiers = nil
50
+ end
51
+ end
52
+ end
@@ -0,0 +1,24 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Notifiable
4
+ class NotificationStatus < ActiveRecord::Base
5
+ self.table_name_prefix = 'notifiable_'
6
+
7
+ belongs_to :notification, class_name: 'Notifiable::Notification'
8
+ validates :notification, presence: true
9
+
10
+ belongs_to :device_token, class_name: 'Notifiable::DeviceToken'
11
+ validates :device_token, presence: true
12
+
13
+ self.table_name = 'notifiable_statuses'
14
+
15
+ def opened!
16
+ update_attribute(:status, -1)
17
+ notification.increment!(:opened_count)
18
+ end
19
+
20
+ def opened?
21
+ status == -1
22
+ end
23
+ end
24
+ end
@@ -0,0 +1,57 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Notifiable
4
+ class NotifierBase
5
+ attr_reader :env, :notification
6
+
7
+ def self.notifier_attribute(*vars)
8
+ @notifier_attributes ||= []
9
+ @notifier_attributes.concat vars
10
+ attr_writer(*vars)
11
+ end
12
+
13
+ class << self
14
+ attr_reader :notifier_attributes
15
+ end
16
+
17
+ def initialize(notification)
18
+ @notification = notification
19
+ end
20
+
21
+ def send_notification(device_token)
22
+ enqueue(device_token, notification)
23
+ end
24
+
25
+ def close
26
+ flush
27
+ save_receipts if Notifiable.save_receipts
28
+ @notification.save
29
+ end
30
+
31
+ protected
32
+
33
+ def flush; end
34
+
35
+ def processed(device_token, status, error_message = nil)
36
+ if @notification.app.save_notification_statuses
37
+ receipts << { notification_id: notification.id, device_token_id: device_token.id, status: status, created_at: DateTime.now, error_message: error_message }
38
+ save_receipts if receipts.count >= Notifiable.notification_status_batch_size
39
+ end
40
+
41
+ @notification.sent_count += 1
42
+ @notification.gateway_accepted_count += 1 if status == 0
43
+ @notification.save if @notification.sent_count % Notifiable.notification_status_batch_size == 0
44
+ end
45
+
46
+ private
47
+
48
+ def receipts
49
+ @receipts ||= []
50
+ end
51
+
52
+ def save_receipts
53
+ Notifiable::NotificationStatus.import receipts, validate: false
54
+ @receipts = []
55
+ end
56
+ end
57
+ end
@@ -0,0 +1,3 @@
1
+ module Notifiable
2
+ VERSION = '0.1.0'.freeze
3
+ end
data/lib/notifiable.rb ADDED
@@ -0,0 +1,35 @@
1
+ require 'active_record'
2
+ require 'activerecord-import/base'
3
+
4
+ require 'notifiable/version'
5
+ require 'notifiable/engine' if defined?(Rails)
6
+ require 'notifiable/app'
7
+ require 'notifiable/notification'
8
+ require 'notifiable/notification_status'
9
+ require 'notifiable/device_token'
10
+ require 'notifiable/notifier_base'
11
+
12
+ module Notifiable
13
+ mattr_accessor :delivery_method
14
+ @@delivery_method = :send
15
+
16
+ mattr_accessor :save_receipts
17
+ @@save_receipts = true
18
+
19
+ mattr_accessor :notification_status_batch_size
20
+ @@notification_status_batch_size = 10_000
21
+
22
+ mattr_accessor :notifier_classes
23
+ @@notifier_classes = {}
24
+
25
+ mattr_accessor :find_notifier_class_proc
26
+ @@find_notifier_class_proc = nil
27
+
28
+ def self.configure
29
+ yield self
30
+ end
31
+
32
+ def self.notifier_class(notification, device)
33
+ Notifiable.find_notifier_class_proc ? Notifiable.find_notifier_class_proc.call(notification, device) : Notifiable.notifier_classes[device.provider.to_sym]
34
+ end
35
+ end
data/lib/tasks/db.rake ADDED
@@ -0,0 +1,34 @@
1
+ namespace :db do
2
+ task :env do
3
+ require 'active_record'
4
+ include ActiveRecord::Tasks
5
+ DatabaseTasks.database_configuration = YAML.load_file('config/database.yml')
6
+ DatabaseTasks.db_dir = 'db'
7
+ ActiveRecord::Base.configurations = DatabaseTasks.database_configuration
8
+ @env_name = ENV['NOTIFIABLE_ENV'] || 'test'
9
+ @migration_paths = [File.join(File.dirname(__FILE__), '..', '..', 'db', 'migrate')]
10
+ end
11
+
12
+ # used to override migration paths
13
+ # bit of a hack
14
+ task :before_migrate do
15
+
16
+ end
17
+
18
+ desc 'Create the database'
19
+ task create: :env do
20
+ DatabaseTasks.create_current(@env_name)
21
+ end
22
+
23
+ desc 'Drop the database'
24
+ task drop: :env do
25
+ DatabaseTasks.drop_current(@env_name)
26
+ end
27
+
28
+ desc 'Migrate the database'
29
+ task migrate: [:env, :before_migrate] do
30
+ ActiveRecord::Base.establish_connection(YAML.load_file('config/database.yml')[@env_name])
31
+ ActiveRecord::Migration.verbose = true
32
+ ActiveRecord::MigrationContext.new(@migration_paths).migrate
33
+ end
34
+ end
metadata ADDED
@@ -0,0 +1,237 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: notifiable-core
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.0
5
+ platform: ruby
6
+ authors:
7
+ - Matt Brooke-Smith
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2018-08-26 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: activerecord
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - ">="
18
+ - !ruby/object:Gem::Version
19
+ version: '0'
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - ">="
25
+ - !ruby/object:Gem::Version
26
+ version: '0'
27
+ - !ruby/object:Gem::Dependency
28
+ name: activerecord-import
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - ">="
32
+ - !ruby/object:Gem::Version
33
+ version: '0'
34
+ type: :runtime
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - ">="
39
+ - !ruby/object:Gem::Version
40
+ version: '0'
41
+ - !ruby/object:Gem::Dependency
42
+ name: bundler
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - "~>"
46
+ - !ruby/object:Gem::Version
47
+ version: '1.16'
48
+ type: :development
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - "~>"
53
+ - !ruby/object:Gem::Version
54
+ version: '1.16'
55
+ - !ruby/object:Gem::Dependency
56
+ name: database_cleaner
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - ">="
60
+ - !ruby/object:Gem::Version
61
+ version: '0'
62
+ type: :development
63
+ prerelease: false
64
+ version_requirements: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - ">="
67
+ - !ruby/object:Gem::Version
68
+ version: '0'
69
+ - !ruby/object:Gem::Dependency
70
+ name: factory_bot
71
+ requirement: !ruby/object:Gem::Requirement
72
+ requirements:
73
+ - - ">="
74
+ - !ruby/object:Gem::Version
75
+ version: '0'
76
+ type: :development
77
+ prerelease: false
78
+ version_requirements: !ruby/object:Gem::Requirement
79
+ requirements:
80
+ - - ">="
81
+ - !ruby/object:Gem::Version
82
+ version: '0'
83
+ - !ruby/object:Gem::Dependency
84
+ name: pg
85
+ requirement: !ruby/object:Gem::Requirement
86
+ requirements:
87
+ - - ">="
88
+ - !ruby/object:Gem::Version
89
+ version: '0'
90
+ type: :development
91
+ prerelease: false
92
+ version_requirements: !ruby/object:Gem::Requirement
93
+ requirements:
94
+ - - ">="
95
+ - !ruby/object:Gem::Version
96
+ version: '0'
97
+ - !ruby/object:Gem::Dependency
98
+ name: rake
99
+ requirement: !ruby/object:Gem::Requirement
100
+ requirements:
101
+ - - "~>"
102
+ - !ruby/object:Gem::Version
103
+ version: '10.0'
104
+ type: :development
105
+ prerelease: false
106
+ version_requirements: !ruby/object:Gem::Requirement
107
+ requirements:
108
+ - - "~>"
109
+ - !ruby/object:Gem::Version
110
+ version: '10.0'
111
+ - !ruby/object:Gem::Dependency
112
+ name: rspec
113
+ requirement: !ruby/object:Gem::Requirement
114
+ requirements:
115
+ - - "~>"
116
+ - !ruby/object:Gem::Version
117
+ version: '3.0'
118
+ type: :development
119
+ prerelease: false
120
+ version_requirements: !ruby/object:Gem::Requirement
121
+ requirements:
122
+ - - "~>"
123
+ - !ruby/object:Gem::Version
124
+ version: '3.0'
125
+ - !ruby/object:Gem::Dependency
126
+ name: rubocop
127
+ requirement: !ruby/object:Gem::Requirement
128
+ requirements:
129
+ - - ">="
130
+ - !ruby/object:Gem::Version
131
+ version: '0'
132
+ type: :development
133
+ prerelease: false
134
+ version_requirements: !ruby/object:Gem::Requirement
135
+ requirements:
136
+ - - ">="
137
+ - !ruby/object:Gem::Version
138
+ version: '0'
139
+ - !ruby/object:Gem::Dependency
140
+ name: rubocop-rspec
141
+ requirement: !ruby/object:Gem::Requirement
142
+ requirements:
143
+ - - ">="
144
+ - !ruby/object:Gem::Version
145
+ version: '0'
146
+ type: :development
147
+ prerelease: false
148
+ version_requirements: !ruby/object:Gem::Requirement
149
+ requirements:
150
+ - - ">="
151
+ - !ruby/object:Gem::Version
152
+ version: '0'
153
+ - !ruby/object:Gem::Dependency
154
+ name: simplecov
155
+ requirement: !ruby/object:Gem::Requirement
156
+ requirements:
157
+ - - ">="
158
+ - !ruby/object:Gem::Version
159
+ version: '0'
160
+ type: :development
161
+ prerelease: false
162
+ version_requirements: !ruby/object:Gem::Requirement
163
+ requirements:
164
+ - - ">="
165
+ - !ruby/object:Gem::Version
166
+ version: '0'
167
+ - !ruby/object:Gem::Dependency
168
+ name: simplecov-rcov
169
+ requirement: !ruby/object:Gem::Requirement
170
+ requirements:
171
+ - - ">="
172
+ - !ruby/object:Gem::Version
173
+ version: '0'
174
+ type: :development
175
+ prerelease: false
176
+ version_requirements: !ruby/object:Gem::Requirement
177
+ requirements:
178
+ - - ">="
179
+ - !ruby/object:Gem::Version
180
+ version: '0'
181
+ description:
182
+ email:
183
+ - matt@futureworkshops.com
184
+ executables: []
185
+ extensions: []
186
+ extra_rdoc_files: []
187
+ files:
188
+ - README.md
189
+ - Rakefile
190
+ - db/migrate/20131210115648_create_notifiable_apps.rb
191
+ - db/migrate/20131210115649_create_notifiable_device_tokens.rb
192
+ - db/migrate/20131210115650_create_notifiable_notifications.rb
193
+ - db/migrate/20131210115652_create_notifiable_statuses.rb
194
+ - db/migrate/20131210115653_add_name_to_notifiable_device_tokens.rb
195
+ - db/migrate/20161208221332_add_badge_count_to_notifiable_notifications.rb
196
+ - db/migrate/20170108221332_remove_is_valid_from_notifiable_device_tokens.rb
197
+ - db/migrate/20170108221432_add_app_id_token_index_to_notifiable_device_tokens.rb
198
+ - db/migrate/20180302212641_add_last_error_message_to_notifications.rb
199
+ - db/migrate/201803142135000_add_title_to_notifications.rb
200
+ - db/migrate/201805292135000_add_language_and_country_to_device_tokens.rb
201
+ - db/migrate/201806182135000_add_thread_id_to_notifications.rb
202
+ - db/migrate/201806242135000_add_category_to_notifications.rb
203
+ - db/migrate/201808242135000_add_error_message_to_notification_statuses.rb
204
+ - lib/notifiable.rb
205
+ - lib/notifiable/app.rb
206
+ - lib/notifiable/device_token.rb
207
+ - lib/notifiable/engine.rb
208
+ - lib/notifiable/notification.rb
209
+ - lib/notifiable/notification_status.rb
210
+ - lib/notifiable/notifier_base.rb
211
+ - lib/notifiable/version.rb
212
+ - lib/tasks/db.rake
213
+ homepage: https://github.com/FutureWorkshops/notifiable
214
+ licenses:
215
+ - MIT
216
+ metadata: {}
217
+ post_install_message:
218
+ rdoc_options: []
219
+ require_paths:
220
+ - lib
221
+ required_ruby_version: !ruby/object:Gem::Requirement
222
+ requirements:
223
+ - - ">="
224
+ - !ruby/object:Gem::Version
225
+ version: 2.3.1
226
+ required_rubygems_version: !ruby/object:Gem::Requirement
227
+ requirements:
228
+ - - ">="
229
+ - !ruby/object:Gem::Version
230
+ version: '0'
231
+ requirements: []
232
+ rubyforge_project:
233
+ rubygems_version: 2.7.3
234
+ signing_key:
235
+ specification_version: 4
236
+ summary: Notifiable core classes.
237
+ test_files: []