checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
---
2
- SHA1:
3
- metadata.gz: 9ffb7fb3c92d6c74cd952b1e2db925518a24b75b
4
- data.tar.gz: b167c999e085a9017a5ba924aa6b2769ced36e70
2
+ SHA256:
3
+ metadata.gz: b863ca933317f600b397b26c3e1ba6075f0882cbf9790687f1556288e2819e65
4
+ data.tar.gz: b6d46fb71f809753fd66f0fa1639bb2f0afe1b04d021874aff4f9112e1304882
5
5
SHA512:
6
- metadata.gz: 8da5f1a457ff6bdf6926318df3b3d8757d27651d7ca11a1e472d4d2587452b6e543e28d42d2bc524d0055f6e13f265b34bf546df6360a78b76a0d81d5822550c
7
- data.tar.gz: 6f2a17440d22d992863a6cd4f3ac0f5a7dd5c61b32a3764f025db1d559902a04231d24dad422c1fa7ff885561b5da443d67e762711638394196dd75f440fe0e9
6
+ metadata.gz: f3358210249ae43ea51905979fcd0f3b10f560a67ca203dbd13b6f32124d3ebb91f9d3b5558f4997f849de1ab549a567f9a608b5f9a5a32ccd5e7b072a10a033
7
+ data.tar.gz: cecd4649f0078410f928c91608a40d5d8ba12484b49af38e74acf3764ae87e5014b5c5a8f7eda5219d2bd47dd9c673ce8c1faa79a15e74e5efe8ba09f93f5b79
data/README.md CHANGED
@@ -1,19 +1,16 @@
1
1
# Pushr
2
2
3
- Please note: We're in the process of updating this gem. The current code is not yet stable. Please contact us if you
4
- want to test or contribute to this project.
5
-
6
3
[![Build Status](https://travis-ci.org/9to5/pushr-core.svg?branch=master)](https://travis-ci.org/9to5/pushr-core)
7
4
[![Code Climate](https://codeclimate.com/github/9to5/pushr-core.png)](https://codeclimate.com/github/9to5/pushr-core)
8
5
[![Coverage Status](https://coveralls.io/repos/9to5/pushr-core/badge.png)](https://coveralls.io/r/9to5/pushr-core)
9
6
10
7
## Features
11
8
12
- * Lightening fast push notification delivery
9
+ * Lightning fast push notification delivery
13
10
* Redis for queueing
14
11
* Redis or YAML for configuration
15
12
* Multi-App
16
- * Multi-Provider ([APNS](https://github.com/9to5/pushr-apns), [GCM](https://github.com/9to5/pushr-gcm))
13
+ * Multi-Provider ([APNS](https://github.com/9to5/pushr-apns), [APNS2](https://github.com/9to5/pushr-apns2), [GCM](https://github.com/9to5/pushr-gcm), [FCM](https://github.com/9to5/pushr-fcm), [WNS](https://github.com/9to5/pushr-wns))
17
14
* Multi-process
18
15
* Integrated feedback processing
19
16
@@ -133,18 +130,21 @@ Where `<options>` can be:
133
130
134
131
## Sending notifications
135
132
133
+ Use the `new` and `save` methods to create a message or use the `create` and `create!` methods. These methods are
134
+ similar to the ActiveRecord model methods.
135
+
136
136
APNS:
137
137
```ruby
138
138
Pushr::MessageApns.create(
139
- app: 'app_name',
140
- device: '<APNS device_token here>',
141
- alert: 'Hello World',
142
- sound: '1.aiff',
143
- badge: 1,
144
- expiry: 1.day.from_now.to_i,
145
- attributes_for_device: {key: 'MSG'},
146
- priority: 10,
147
- content_available: 1)
139
+ app: 'app_name', # required: String, the name of the configuration
140
+ device: '<APNS device_token here>', # required: String, token of the device
141
+ expiry: 1.day.from_now.to_i, # required: Integer, A UNIX epoch date expressed in seconds
142
+ priority: 10, # required: Integer, 10 or 5 (should be 10 if message includes an alert, sound or badge)
143
+ alert: 'Hello World', # optional: String or Hash, read APNS documentation for more information
144
+ sound: '1.aiff', # optional: String, sound to play
145
+ badge: 1, # optional: Integer, display badge on homescreen
146
+ attributes_for_device: {key: 'MSG'}, # optional: Hash, send additional parameters
147
+ content_available: 1) # optional: Integer, 1 if device should be notified if new content is available
148
148
```
149
149
150
150
@@ -168,15 +168,15 @@ Use `content_available: 1` if the iOS device should start your app upon receivin
168
168
GCM:
169
169
```ruby
170
170
Pushr::MessageGcm.create(
171
- app: 'app_name',
172
- registration_ids: ['<GCM registration_id here>', '<GCM registration_id here>'],
173
- notification_key: 'notification_key_name',
174
- delay_while_idle: true,
175
- data: { message: 'Hello World' },
176
- time_to_live: 24 * 60 * 60,
177
- restricted_package_name: 'com.example.gcm',
178
- dry_run: false,
179
- collapse_key: 'MSG')
171
+ app: 'app_name', # required: String, the name of the configuration
172
+ registration_ids: ['<registration_id>', '...'], # required: Array of registration ids
173
+ notification_key: 'notification_key_name', # optional: String, Use with User Notifications
174
+ delay_while_idle: true, # optional: Boolean, message is received if device is active
175
+ data: { message: 'Hello World' }, # optional: Hash, contains information for the app
176
+ time_to_live: 24 * 60 * 60, # optional: Integer, in seconds how long the message will be stored
177
+ restricted_package_name: 'com.example.gcm', # optional: String, message will only be received with this package name
178
+ dry_run: false, # optional: Boolean, do not actually deliver the message to the app
179
+ collapse_key: 'MSG') # optional: String, messages with the same key can be collapsed into one
180
180
```
181
181
182
182
## Feedback processing
data/bin/pushr CHANGED
@@ -68,14 +68,13 @@ Pushr::Core.configure do |config|
68
68
config.redis = x
69
69
end
70
70
71
- if ENV['AIRBRAKE_API_KEY']
71
+ if ENV['AIRBRAKE_API_KEY'] || ENV['AIRBRAKE_PROJECT_KEY']
72
72
require 'airbrake'
73
73
settings.error_notification = true
74
74
Airbrake.configure do |airbrake|
75
- airbrake.api_key = ENV['AIRBRAKE_API_KEY']
76
- airbrake.host = ENV['AIRBRAKE_HOST']
77
- airbrake.port = ENV['AIRBRAKE_PORT'] ? ENV['AIRBRAKE_PORT'].to_i : 80
75
+ airbrake.host = ENV['AIRBRAKE_HOST']
76
+ airbrake.project_id = ENV['AIRBRAKE_PROJECT_ID'] || 1
77
+ airbrake.project_key = ENV['AIRBRAKE_API_KEY'] || ENV['AIRBRAKE_PROJECT_KEY']
78
- airbrake.secure = airbrake.port == 443
79
78
end
80
79
end
81
80
data/lib/pushr/configuration.rb CHANGED
@@ -33,6 +33,18 @@ module Pushr
33
33
m
34
34
end
35
35
36
+ def self.create!(attributes = {})
37
+ m = new(attributes)
38
+ unless m.save
39
+ raise Pushr::Error::RecordInvalid
40
+ end
41
+ m
42
+ end
43
+
44
+ def queue_depth
45
+ Pushr::Core.redis { |conn| conn.llen("pushr:#{key}") }
46
+ end
47
+
36
48
def delete
37
49
Pushr::Core.redis { |conn| conn.hdel('pushr:configurations', key) }
38
50
end
@@ -57,13 +69,13 @@ module Pushr
57
69
def self.read_from_yaml_file
58
70
filename = Pushr::Core.configuration_file
59
71
configs = File.open(filename) { |fd| YAML.load(fd) }
60
- configs.map { |hsh| instantiate(hsh) }
72
+ configs.map { |hsh| instantiate(hsh) }.compact
61
73
end
62
74
63
75
def self.read_from_redis
64
76
configurations = Pushr::Core.redis { |conn| conn.hgetall('pushr:configurations') }
65
77
configurations.each { |key, config| configurations[key] = instantiate_json(config, key) }
66
- configurations.values
78
+ configurations.values.compact
67
79
end
68
80
69
81
def self.instantiate_json(config, id)
@@ -71,7 +83,12 @@ module Pushr
71
83
end
72
84
73
85
def self.instantiate(hsh)
74
- klass = hsh['type'].split('::').reduce(Object) { |a, e| a.const_get e }
86
+ klass = hsh['type'].split('::').reduce(Object) do |a, e|
87
+ if Object.const_defined?(hsh['type'])
88
+ a.const_get e
89
+ end
90
+ end
91
+ return nil if klass == nil
75
92
klass.new(hsh)
76
93
end
77
94
end
data/lib/pushr/core.rb CHANGED
@@ -2,6 +2,7 @@ require 'yaml'
2
2
require 'active_model'
3
3
require 'multi_json'
4
4
require 'pushr/version'
5
+ require 'pushr/error'
5
6
require 'pushr/configuration'
6
7
require 'pushr/message'
7
8
require 'pushr/feedback'
data/lib/pushr/daemon/logger.rb CHANGED
@@ -45,7 +45,7 @@ module Pushr
45
45
46
46
def error_notification(e)
47
47
if do_error_notification?(e) && defined?(Airbrake)
48
- Airbrake.notify_or_ignore(e)
48
+ Airbrake.notify(e)
49
49
end
50
50
end
51
51
data/lib/pushr/daemon/message_handler.rb CHANGED
@@ -1,7 +1,7 @@
1
1
module Pushr
2
2
module Daemon
3
3
class MessageHandler
4
- attr_reader :name
4
+ attr_reader :name, :connection
5
5
6
6
def initialize(queue_name, connection, name, i)
7
7
@queue_name = queue_name
@@ -30,8 +30,8 @@ module Pushr
30
30
return if message.nil?
31
31
32
32
Pushr::Core.instrument('message', app: message.app, type: message.type) do
33
- @connection.write(message)
34
- Pushr::Daemon.logger.info("[#{@connection.name}] Message delivered to #{message.to_json}")
33
+ connection.write(message)
34
+ Pushr::Daemon.logger.info("[#{connection.name}] Message delivered to #{message.to_json}")
35
35
end
36
36
rescue => e
37
37
Pushr::Daemon.logger.error(e)
data/lib/pushr/daemon/settings.rb CHANGED
@@ -12,8 +12,8 @@ module Pushr
12
12
@pid_file = nil
13
13
end
14
14
15
- def pid_file=(arg)
16
- @pid_file = File.join(Dir.pwd, arg) if arg && !Pathname.new(arg).absolute?
15
+ def pid_file=(file)
16
+ @pid_file = Pathname.new(file).absolute? ? file : File.join(Dir.pwd, file)
17
17
end
18
18
end
19
19
end
data/lib/pushr/error.rb ADDED
@@ -0,0 +1,10 @@
1
+ module Pushr
2
+
3
+ # Module containing Pushr::Error classes, all of which extend StandardError.
4
+ module Error
5
+
6
+ # Raised if the entered authentication details (API key or username and password) are incorrect. (Error code: 2)
7
+ class RecordInvalid < StandardError
8
+ end
9
+ end
10
+ end
data/lib/pushr/feedback.rb CHANGED
@@ -29,6 +29,14 @@ module Pushr
29
29
m
30
30
end
31
31
32
+ def self.create!(attributes = {})
33
+ m = new(attributes)
34
+ unless m.save
35
+ raise Pushr::Error::RecordInvalid
36
+ end
37
+ m
38
+ end
39
+
32
40
def to_json
33
41
MultiJson.dump(to_hash)
34
42
end
data/lib/pushr/message.rb CHANGED
@@ -26,6 +26,14 @@ module Pushr
26
26
m
27
27
end
28
28
29
+ def self.create!(attributes = {})
30
+ m = new(attributes)
31
+ unless m.save
32
+ raise Pushr::Error::RecordInvalid
33
+ end
34
+ m
35
+ end
36
+
29
37
def to_json
30
38
MultiJson.dump(to_hash)
31
39
end
data/lib/pushr/redis_connection.rb CHANGED
@@ -17,7 +17,7 @@ module Pushr
17
17
end
18
18
19
19
def self.build_client(url, namespace, driver)
20
- client = Redis.connect(url: url, driver: driver)
20
+ client = Redis.new(url: url, driver: driver)
21
21
if namespace
22
22
Redis::Namespace.new(namespace, redis: client)
23
23
else
data/lib/pushr/version.rb CHANGED
@@ -1,3 +1,3 @@
1
1
module Pushr
2
- VERSION = '1.0.0'
2
+ VERSION = '1.0.5'
3
3
end
data/spec/lib/pushr/configuration_spec.rb CHANGED
@@ -12,6 +12,12 @@ describe Pushr::Configuration do
12
12
it 'returns all configurations' do
13
13
expect(Pushr::Configuration.all).to eql([])
14
14
end
15
+
16
+ it 'should not load missing configuration constant' do
17
+ Pushr::ConfigurationDummy2.new(app: 'app_name', connections: 2, enabled: true).save
18
+ Pushr.send(:remove_const, :ConfigurationDummy2)
19
+ expect(Pushr::Configuration.all).to eql([])
20
+ end
15
21
end
16
22
17
23
describe 'create' do
@@ -49,6 +55,28 @@ describe Pushr::Configuration do
49
55
end
50
56
end
51
57
58
+ describe 'create!' do
59
+ subject { Pushr::ConfigurationDummy.create!(app: app_name, connections: 2, enabled: true) }
60
+
61
+ context 'with app name' do
62
+ let(:app_name) { 'app_name' }
63
+ it 'should create a message' do
64
+ expect(subject.valid?).to eql true
65
+ end
66
+
67
+ it 'should create a ConfigurationDummy class' do
68
+ expect(subject.class).to eql Pushr::ConfigurationDummy
69
+ end
70
+ end
71
+
72
+ context 'without app name' do
73
+ let(:app_name) { nil }
74
+ it 'should raise error' do
75
+ expect { subject }.to raise_error Pushr::Error::RecordInvalid
76
+ end
77
+ end
78
+ end
79
+
52
80
describe 'find' do
53
81
let!(:config) { Pushr::ConfigurationDummy.new(app: 'app_name', connections: 2, enabled: true) }
54
82
it 'should find a configuration' do
data/spec/lib/pushr/daemon/settings_spec.rb ADDED
@@ -0,0 +1,22 @@
1
+ require 'spec_helper'
2
+ require 'pushr/daemon'
3
+
4
+ describe Pushr::Daemon::Settings do
5
+ describe 'log level' do
6
+ subject { Pushr::Daemon::Settings.new }
7
+
8
+ it 'returns absolute path' do
9
+ subject.pid_file = __FILE__
10
+ expect(subject.pid_file).to eql __FILE__
11
+ end
12
+
13
+ it 'returns relative path' do
14
+ subject.pid_file = 'filename.pid'
15
+ expect(subject.pid_file).to eql File.join(Dir.pwd, 'filename.pid')
16
+ end
17
+
18
+ it 'returns nil if no pid_file' do
19
+ expect(subject.pid_file).to eql nil
20
+ end
21
+ end
22
+ end
data/spec/lib/pushr/feedback_spec.rb CHANGED
@@ -35,4 +35,26 @@ describe Pushr::Feedback do
35
35
expect(subject.class).to eql Pushr::FeedbackDummy
36
36
end
37
37
end
38
+
39
+ describe 'create!' do
40
+ subject { Pushr::FeedbackDummy.create!(app: app_name, device: 'a' * 64, follow_up: 'delete', failed_at: Time.now) }
41
+
42
+ context 'with app name' do
43
+ let(:app_name) { 'app_name' }
44
+ it 'should create a message' do
45
+ expect(subject.valid?).to eql true
46
+ end
47
+
48
+ it 'should create a FeedbackDummy class' do
49
+ expect(subject.class).to eql Pushr::FeedbackDummy
50
+ end
51
+ end
52
+
53
+ context 'without app name' do
54
+ let(:app_name) { nil }
55
+ it 'should raise error' do
56
+ expect { subject }.to raise_error Pushr::Error::RecordInvalid
57
+ end
58
+ end
59
+ end
38
60
end
data/spec/lib/pushr/message_spec.rb CHANGED
@@ -41,4 +41,26 @@ describe Pushr::Message do
41
41
expect(subject.class).to eql Pushr::MessageDummy
42
42
end
43
43
end
44
+
45
+ describe 'create!' do
46
+ subject { Pushr::MessageDummy.create!(app: app_name) }
47
+
48
+ context 'with app name' do
49
+ let(:app_name) { 'app_name' }
50
+ it 'should create a message' do
51
+ expect(subject.valid?).to eql true
52
+ end
53
+
54
+ it 'should create a MessageDummy class' do
55
+ expect(subject.class).to eql Pushr::MessageDummy
56
+ end
57
+ end
58
+
59
+ context 'without app name' do
60
+ let(:app_name) { nil }
61
+ it 'should raise error' do
62
+ expect { subject }.to raise_error Pushr::Error::RecordInvalid
63
+ end
64
+ end
65
+ end
44
66
end
data/spec/spec_helper.rb CHANGED
@@ -6,10 +6,10 @@
6
6
require 'simplecov'
7
7
require 'coveralls'
8
8
9
- SimpleCov.formatter = SimpleCov::Formatter::MultiFormatter[
9
+ SimpleCov.formatter = SimpleCov::Formatter::MultiFormatter.new([
10
10
SimpleCov::Formatter::HTMLFormatter,
11
11
Coveralls::SimpleCov::Formatter
12
- ]
12
+ ])
13
13
SimpleCov.start
14
14
15
15
require 'pushr/core'
data/spec/support/pushr_configuration_dummy2.rb ADDED
@@ -0,0 +1,13 @@
1
+ module Pushr
2
+ class ConfigurationDummy2 < Pushr::Configuration
3
+ attr_accessor :test_attr
4
+
5
+ def name
6
+ :dummy
7
+ end
8
+
9
+ def to_hash(_ = nil)
10
+ { id: [@app, name].join(':'), type: self.class.to_s, app: app, enabled: enabled, connections: connections, test_attr: test_attr }
11
+ end
12
+ end
13
+ end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
--- !ruby/object:Gem::Specification
2
2
name: pushr-core
3
3
version: !ruby/object:Gem::Version
4
- version: 1.0.0
4
+ version: 1.0.5
5
5
platform: ruby
6
6
authors:
7
7
- Tom Pesman
8
8
autorequire:
9
9
bindir: bin
10
10
cert_chain: []
11
- date: 2014-06-27 00:00:00.000000000 Z
11
+ date: 2019-11-08 00:00:00.000000000 Z
12
12
dependencies:
13
13
- !ruby/object:Gem::Dependency
14
14
name: redis
@@ -16,28 +16,28 @@ dependencies:
16
16
requirements:
17
17
- - "~>"
18
18
- !ruby/object:Gem::Version
19
- version: '3.0'
19
+ version: '4.0'
20
20
type: :runtime
21
21
prerelease: false
22
22
version_requirements: !ruby/object:Gem::Requirement
23
23
requirements:
24
24
- - "~>"
25
25
- !ruby/object:Gem::Version
26
- version: '3.0'
26
+ version: '4.0'
27
27
- !ruby/object:Gem::Dependency
28
28
name: redis-namespace
29
29
requirement: !ruby/object:Gem::Requirement
30
30
requirements:
31
- - - '='
31
+ - - "~>"
32
32
- !ruby/object:Gem::Version
33
- version: 1.4.1
33
+ version: '1.4'
34
34
type: :runtime
35
35
prerelease: false
36
36
version_requirements: !ruby/object:Gem::Requirement
37
37
requirements:
38
- - - '='
38
+ - - "~>"
39
39
- !ruby/object:Gem::Version
40
- version: 1.4.1
40
+ version: '1.4'
41
41
- !ruby/object:Gem::Dependency
42
42
name: multi_json
43
43
requirement: !ruby/object:Gem::Requirement
@@ -84,16 +84,16 @@ dependencies:
84
84
name: rspec
85
85
requirement: !ruby/object:Gem::Requirement
86
86
requirements:
87
- - - '='
87
+ - - "~>"
88
88
- !ruby/object:Gem::Version
89
- version: 3.0.0.beta2
89
+ version: '3.0'
90
90
type: :development
91
91
prerelease: false
92
92
version_requirements: !ruby/object:Gem::Requirement
93
93
requirements:
94
- - - '='
94
+ - - "~>"
95
95
- !ruby/object:Gem::Version
96
- version: 3.0.0.beta2
96
+ version: '3.0'
97
97
- !ruby/object:Gem::Dependency
98
98
name: guard
99
99
requirement: !ruby/object:Gem::Requirement
@@ -201,6 +201,9 @@ executables:
201
201
extensions: []
202
202
extra_rdoc_files: []
203
203
files:
204
+ - MIT-LICENSE
205
+ - README.md
206
+ - bin/pushr
204
207
- lib/generators/templates/feedback_processor.rb
205
208
- lib/generators/templates/pushr.yml
206
209
- lib/pushr/configuration.rb
@@ -213,18 +216,18 @@ files:
213
216
- lib/pushr/daemon/message_handler.rb
214
217
- lib/pushr/daemon/pid_file.rb
215
218
- lib/pushr/daemon/settings.rb
219
+ - lib/pushr/error.rb
216
220
- lib/pushr/feedback.rb
217
221
- lib/pushr/message.rb
218
222
- lib/pushr/redis_connection.rb
219
223
- lib/pushr/version.rb
220
- - README.md
221
- - MIT-LICENSE
222
224
- spec/lib/pushr/configuration_spec.rb
223
225
- spec/lib/pushr/daemon/app_spec.rb
224
226
- spec/lib/pushr/daemon/delivery_error_spec.rb
225
227
- spec/lib/pushr/daemon/feedback_handler_spec.rb
226
228
- spec/lib/pushr/daemon/logger_spec.rb
227
229
- spec/lib/pushr/daemon/message_handler_spec.rb
230
+ - spec/lib/pushr/daemon/settings_spec.rb
228
231
- spec/lib/pushr/daemon_spec.rb
229
232
- spec/lib/pushr/feedback_spec.rb
230
233
- spec/lib/pushr/message_spec.rb
@@ -232,13 +235,13 @@ files:
232
235
- spec/spec_helper.rb
233
236
- spec/support/logger.rb
234
237
- spec/support/pushr_configuration_dummy.rb
238
+ - spec/support/pushr_configuration_dummy2.rb
235
239
- spec/support/pushr_connection_dummy.rb
236
240
- spec/support/pushr_dummy.rb
237
241
- spec/support/pushr_feedback_dummy.rb
238
242
- spec/support/pushr_feedback_processor_dummy.rb
239
243
- spec/support/pushr_invalid_configuration_dummy.rb
240
244
- spec/support/pushr_message_dummy.rb
241
- - bin/pushr
242
245
homepage: https://github.com/9to5/pushr-core
243
246
licenses:
244
247
- MIT
@@ -251,15 +254,14 @@ required_ruby_version: !ruby/object:Gem::Requirement
251
254
requirements:
252
255
- - ">="
253
256
- !ruby/object:Gem::Version
254
- version: 1.9.3
257
+ version: 2.2.0
255
258
required_rubygems_version: !ruby/object:Gem::Requirement
256
259
requirements:
257
260
- - ">="
258
261
- !ruby/object:Gem::Version
259
262
version: '0'
260
263
requirements: []
261
- rubyforge_project:
264
+ rubygems_version: 3.0.6
262
- rubygems_version: 2.1.11
263
265
signing_key:
264
266
specification_version: 4
265
267
summary: Core of the pushr daemon.
@@ -270,6 +272,7 @@ test_files:
270
272
- spec/lib/pushr/daemon/feedback_handler_spec.rb
271
273
- spec/lib/pushr/daemon/logger_spec.rb
272
274
- spec/lib/pushr/daemon/message_handler_spec.rb
275
+ - spec/lib/pushr/daemon/settings_spec.rb
273
276
- spec/lib/pushr/daemon_spec.rb
274
277
- spec/lib/pushr/feedback_spec.rb
275
278
- spec/lib/pushr/message_spec.rb
@@ -277,6 +280,7 @@ test_files:
277
280
- spec/spec_helper.rb
278
281
- spec/support/logger.rb
279
282
- spec/support/pushr_configuration_dummy.rb
283
+ - spec/support/pushr_configuration_dummy2.rb
280
284
- spec/support/pushr_connection_dummy.rb
281
285
- spec/support/pushr_dummy.rb
282
286
- spec/support/pushr_feedback_dummy.rb