pushr-core 1.0.0 → 1.0.5

Sign up to get free protection for your applications and to get access to all the features.
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 `` 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
78
- airbrake.secure = airbrake.port == 443
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']
79
78
  end
80
79
  end
81
80
 
@@ -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
@@ -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'
@@ -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
 
@@ -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)
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -1,3 +1,3 @@
1
1
  module Pushr
2
- VERSION = '1.0.0'
2
+ VERSION = '1.0.5'
3
3
  end
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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'
@@ -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:
262
- rubygems_version: 2.1.11
264
+ rubygems_version: 3.0.6
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