rapns 3.3.0 → 3.3.1

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.
@@ -1,3 +1,10 @@
1
+ ## 3.3.1 (June 2, 2013)
2
+ * Fix compatibility with postgres_ext (#104).
3
+ * Add ability to switch the logger (@maxsz).
4
+ * Do not validate presence of alert, badge or sound - not actually required by the APNs (#129) (@wilg).
5
+ * Catch IOError from an APNs connection. (@maxsz).
6
+ * Allow nested hashes in APNs notification attributes (@perezda).
7
+
1
8
  ## 3.3.0 (April 21, 2013)
2
9
  * GCM: collapse_key is no longer required to set expiry (time_to_live).
3
10
  * Add reflection for GCM canonical IDs.
data/README.md CHANGED
@@ -89,14 +89,18 @@ As a daemon:
89
89
 
90
90
  Inside an existing process (see [Embedding API](https://github.com/ileitch/rapns/wiki/Embedding-API)):
91
91
 
92
- Rapns.embed
92
+ ```ruby
93
+ Rapns.embed
94
+ ```
93
95
 
94
96
  *Please note that only ever a single instance of Rapns should be running.*
95
97
 
96
98
  In a scheduler (see [Push API](https://github.com/ileitch/rapns/wiki/Push-API)):
97
99
 
98
- Rapns.push
99
- Rapns.apns_feedback
100
+ ```ruby
101
+ Rapns.push
102
+ Rapns.apns_feedback
103
+ ```
100
104
 
101
105
  See [Configuration](https://github.com/ileitch/rapns/wiki/Configuration) for a list of options, or run `rapns --help`.
102
106
 
@@ -115,6 +119,7 @@ After updating you should run `rails g rapns` to check for any new migrations.
115
119
  * [Reflection API](https://github.com/ileitch/rapns/wiki/Reflection-API)
116
120
  * [Push API](https://github.com/ileitch/rapns/wiki/Push-API)
117
121
  * [Embedding API](https://github.com/ileitch/rapns/wiki/Embedding-API)
122
+ * [Implementing your own storage backend](https://github.com/ileitch/rapns/wiki/Implementing-your-own-storage-backend)
118
123
 
119
124
  ### APNs
120
125
  * [Generating Certificates](https://github.com/ileitch/rapns/wiki/Generating-Certificates)
@@ -158,3 +163,6 @@ Thank you to the following wonderful people for contributing:
158
163
  * [@jeffarena](https://github.com/jeffarena)
159
164
  * [@DianthuDia](https://github.com/DianthuDia)
160
165
  * [@dup2](https://github.com/dup2)
166
+ * [@maxsz](https://github.com/maxsz)
167
+ * [@wilg](https://github.com/wilg)
168
+ * [@perezda](https://github.com/perezda)
@@ -23,6 +23,9 @@
23
23
  # Path to write PID file. Relative to Rails root unless absolute.
24
24
  # config.pid_file = '/path/to/rapns.pid'
25
25
 
26
+ # Define a custom logger.
27
+ # config.logger = MyLogger.new
28
+
26
29
  end
27
30
 
28
31
  Rapns.reflect do |on|
@@ -17,7 +17,6 @@ require 'rapns/upgraded'
17
17
 
18
18
  require 'rapns/apns/binary_notification_validator'
19
19
  require 'rapns/apns/device_token_format_validator'
20
- require 'rapns/apns/required_fields_validator'
21
20
  require 'rapns/apns/notification'
22
21
  require 'rapns/apns/feedback'
23
22
  require 'rapns/apns/app'
@@ -8,7 +8,6 @@ module Rapns
8
8
 
9
9
  validates_with Rapns::Apns::DeviceTokenFormatValidator
10
10
  validates_with Rapns::Apns::BinaryNotificationValidator
11
- validates_with Rapns::Apns::RequiredFieldsValidator
12
11
 
13
12
  alias_method :attributes_for_device=, :data=
14
13
  alias_method :attributes_for_device, :data
@@ -69,7 +68,7 @@ module Rapns
69
68
 
70
69
  if attributes_for_device
71
70
  non_aps_attributes = attributes_for_device.reject { |k, v| k == CONTENT_AVAILABLE_KEY }
72
- non_aps_attributes.each { |k, v| json[k.to_s] = v.to_s }
71
+ non_aps_attributes.each { |k, v| json[k.to_s] = v }
73
72
  end
74
73
  end
75
74
 
@@ -9,7 +9,7 @@ module Rapns
9
9
 
10
10
  CONFIG_ATTRS = [:foreground, :push_poll, :feedback_poll, :embedded,
11
11
  :airbrake_notify, :check_for_errors, :pid_file, :batch_size,
12
- :push, :store]
12
+ :push, :store, :logger]
13
13
 
14
14
  class ConfigurationWithoutDefaults < Struct.new(*CONFIG_ATTRS)
15
15
  end
@@ -39,6 +39,10 @@ module Rapns
39
39
  end
40
40
  end
41
41
 
42
+ def logger=(logger)
43
+ super(logger)
44
+ end
45
+
42
46
  def foreground=(bool)
43
47
  if Rapns.jruby?
44
48
  # The JVM does not support fork().
@@ -53,8 +57,6 @@ module Rapns
53
57
  end
54
58
  deprecated(:on_apns_feedback, 3.2, "Please use the Rapns.reflect API instead.")
55
59
 
56
- private
57
-
58
60
  def set_defaults
59
61
  if Rapns.jruby?
60
62
  # The JVM does not support fork().
@@ -71,6 +73,7 @@ module Rapns
71
73
  self.pid_file = nil
72
74
  self.apns_feedback_callback = nil
73
75
  self.store = :active_record
76
+ self.logger = nil
74
77
 
75
78
  # Internal options.
76
79
  self.embedded = false
@@ -49,7 +49,7 @@ module Rapns
49
49
 
50
50
  begin
51
51
  write_data(data)
52
- rescue Errno::EPIPE, Errno::ETIMEDOUT, OpenSSL::SSL::SSLError => e
52
+ rescue Errno::EPIPE, Errno::ETIMEDOUT, OpenSSL::SSL::SSLError, IOError => e
53
53
  retry_count += 1;
54
54
 
55
55
  if retry_count == 1
@@ -6,12 +6,7 @@ module Rapns
6
6
  begin
7
7
  log = File.open(File.join(Rails.root, 'log', 'rapns.log'), 'a')
8
8
  log.sync = true
9
- if defined?(ActiveSupport::BufferedLogger)
10
- @logger = ActiveSupport::BufferedLogger.new(log, Rails.logger.level)
11
- @logger.auto_flushing = Rails.logger.respond_to?(:auto_flushing) ? Rails.logger.auto_flushing : true
12
- else
13
- @logger = ActiveSupport::Logger.new(log, Rails.logger.level)
14
- end
9
+ setup_logger(log)
15
10
  rescue Errno::ENOENT, Errno::EPERM => e
16
11
  @logger = nil
17
12
  error(e)
@@ -34,6 +29,17 @@ module Rapns
34
29
 
35
30
  private
36
31
 
32
+ def setup_logger(log)
33
+ if Rapns.config.logger
34
+ @logger = Rapns.config.logger
35
+ elsif defined?(ActiveSupport::BufferedLogger)
36
+ @logger = ActiveSupport::BufferedLogger.new(log, Rails.logger.level)
37
+ @logger.auto_flushing = Rails.logger.respond_to?(:auto_flushing) ? Rails.logger.auto_flushing : true
38
+ else
39
+ @logger = ActiveSupport::Logger.new(log, Rails.logger.level)
40
+ end
41
+ end
42
+
37
43
  def log(where, msg, prefix = nil, io = STDOUT)
38
44
  if msg.is_a?(Exception)
39
45
  formatted_backtrace = msg.backtrace.join("\n")
@@ -22,7 +22,7 @@ module Rapns
22
22
  }
23
23
 
24
24
  scope :for_apps, lambda { |apps|
25
- where(:app_id => apps.map(&:id))
25
+ where('app_id IN (?)', apps.map(&:id))
26
26
  }
27
27
 
28
28
  def initialize(*args)
@@ -1,3 +1,3 @@
1
1
  module Rapns
2
- VERSION = '3.3.0'
2
+ VERSION = '3.3.1'
3
3
  end
@@ -31,16 +31,6 @@ describe Rapns::Apns::Notification do
31
31
  it "should default the expiry to 1 day" do
32
32
  notification.expiry.should == 1.day.to_i
33
33
  end
34
-
35
- # The notification must contain one of alert, sound or badge.
36
- # @see https://developer.apple.com/library/ios/#documentation/NetworkingInternet/Conceptual/RemoteNotificationsPG/ApplePushService/ApplePushService.html
37
- it "should not be valid if there is none of alert,sound,badge present" do
38
- notification.alert = nil
39
- notification.sound = nil
40
- notification.badge = nil
41
- notification.valid?.should be_false
42
- notification.errors[:base].should include("APN Notification must contain one of alert, badge, or sound")
43
- end
44
34
  end
45
35
 
46
36
  describe Rapns::Apns::Notification, "when assigning the device token" do
@@ -97,6 +87,13 @@ describe Rapns::Apns::Notification, "as_json" do
97
87
  notification.as_json["omg"].should == "lol"
98
88
  notification.as_json["wtf"].should == "dunno"
99
89
  end
90
+
91
+ it "should allow attributes to include a hash" do
92
+ notification = Rapns::Apns::Notification.new
93
+ notification.attributes_for_device = {:omg => {:ilike => :hashes}}
94
+ notification.as_json["omg"]["ilike"].should == "hashes"
95
+ end
96
+
100
97
  end
101
98
 
102
99
  describe Rapns::Apns::Notification, 'MDM' do
@@ -185,6 +185,14 @@ describe Rapns::Daemon::Apns::Connection do
185
185
  end
186
186
  end
187
187
 
188
+ describe "when write raises an IOError" do
189
+ it_should_behave_like "when the write fails"
190
+
191
+ def error_type
192
+ IOError
193
+ end
194
+ end
195
+
188
196
  describe "when reconnecting" do
189
197
  it 'closes the socket' do
190
198
  connection.should_receive(:close)
@@ -7,7 +7,8 @@ describe Rapns::Daemon, "when starting" do
7
7
  let(:certificate) { stub }
8
8
  let(:password) { stub }
9
9
  let(:config) { stub(:pid_file => nil, :airbrake_notify => false,
10
- :foreground => true, :embedded => false, :push => false, :store => :active_record) }
10
+ :foreground => true, :embedded => false, :push => false,
11
+ :store => :active_record, :logger => nil) }
11
12
  let(:logger) { stub(:logger, :info => nil, :error => nil, :warn => nil) }
12
13
 
13
14
  before do
@@ -102,6 +103,7 @@ end
102
103
 
103
104
  describe Rapns::Daemon, "when being shutdown" do
104
105
  let(:config) { stub(:pid_file => '/rails_root/rapns.pid') }
106
+ let(:logger) { stub(:info => nil, :error => nil, :warn => nil) }
105
107
 
106
108
  before do
107
109
  Rapns.stub(:config => config)
@@ -55,6 +55,14 @@ describe Rapns::Logger do
55
55
  Rapns::Logger.new(:foreground => true)
56
56
  end
57
57
 
58
+ it 'uses the user-defined logger' do
59
+ my_logger = stub
60
+ Rapns.config.logger = my_logger
61
+ logger = Rapns::Logger.new({})
62
+ my_logger.should_receive(:info)
63
+ logger.info('test')
64
+ end
65
+
58
66
  it "should print out the msg if running in the foreground" do
59
67
  logger = Rapns::Logger.new(:foreground => true)
60
68
  STDOUT.should_receive(:puts).with(/hi mom/)
@@ -75,6 +75,7 @@ RSpec.configure do |config|
75
75
  config.after(:each) do
76
76
  Rapns.logger = nil
77
77
  Rapns::Daemon.store = nil
78
+ Rapns.config.set_defaults if Rapns.config.kind_of?(Rapns::Configuration)
78
79
  end
79
80
  end
80
81
 
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: rapns
3
3
  version: !ruby/object:Gem::Version
4
- version: 3.3.0
4
+ version: 3.3.1
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -9,7 +9,7 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2013-04-21 00:00:00.000000000 Z
12
+ date: 2013-06-02 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: multi_json
@@ -68,7 +68,6 @@ files:
68
68
  - lib/rapns/apns/device_token_format_validator.rb
69
69
  - lib/rapns/apns/feedback.rb
70
70
  - lib/rapns/apns/notification.rb
71
- - lib/rapns/apns/required_fields_validator.rb
72
71
  - lib/rapns/apns_feedback.rb
73
72
  - lib/rapns/app.rb
74
73
  - lib/rapns/configuration.rb
@@ -175,7 +174,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
175
174
  version: '0'
176
175
  segments:
177
176
  - 0
178
- hash: -3085387548794744992
177
+ hash: -138032401300594712
179
178
  required_rubygems_version: !ruby/object:Gem::Requirement
180
179
  none: false
181
180
  requirements:
@@ -184,7 +183,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
184
183
  version: '0'
185
184
  segments:
186
185
  - 0
187
- hash: -3085387548794744992
186
+ hash: -138032401300594712
188
187
  requirements: []
189
188
  rubyforge_project:
190
189
  rubygems_version: 1.8.25
@@ -1,14 +0,0 @@
1
- module Rapns
2
- module Apns
3
- class RequiredFieldsValidator < ActiveModel::Validator
4
-
5
- # Notifications must contain one of alert, badge or sound as per:
6
- # https://developer.apple.com/library/ios/#documentation/NetworkingInternet/Conceptual/RemoteNotificationsPG/ApplePushService/ApplePushService.html
7
- def validate(record)
8
- if record.alert.nil? && record.badge.nil? && record.sound.nil?
9
- record.errors[:base] << "APN Notification must contain one of alert, badge, or sound"
10
- end
11
- end
12
- end
13
- end
14
- end