rapns 2.0.1 → 2.0.3
Sign up to get free protection for your applications and to get access to all the features.
- data/CHANGELOG.md +8 -0
- data/README.md +6 -4
- data/bin/rapns +1 -1
- data/lib/rapns/app.rb +2 -0
- data/lib/rapns/daemon/database_reconnectable.rb +4 -1
- data/lib/rapns/daemon.rb +2 -1
- data/lib/rapns/feedback.rb +2 -0
- data/lib/rapns/notification.rb +25 -6
- data/lib/rapns/version.rb +1 -1
- data/spec/rapns/daemon/database_reconnectable_spec.rb +2 -0
- data/spec/rapns/daemon_spec.rb +11 -11
- data/spec/rapns/notification_spec.rb +34 -0
- data/spec/spec_helper.rb +23 -3
- metadata +5 -5
data/CHANGELOG.md
CHANGED
@@ -1,3 +1,11 @@
|
|
1
|
+
## 2.0.3 (July 26, 2012) ##
|
2
|
+
* JRuby support.
|
3
|
+
* Explicitly list all attributes instead of calling column_names (#53).
|
4
|
+
|
5
|
+
## 2.0.2 (July 25, 2012) ##
|
6
|
+
* Support MultiJson < 1.3.0.
|
7
|
+
* Make all model attributes accessible.
|
8
|
+
|
1
9
|
## 2.0.1 (July 7, 2012) ##
|
2
10
|
* Fix delivery when using Ruby 1.8.
|
3
11
|
* MultiJson support.
|
data/README.md
CHANGED
@@ -24,7 +24,7 @@
|
|
24
24
|
Add rapns to your Gemfile:
|
25
25
|
|
26
26
|
gem 'rapns'
|
27
|
-
|
27
|
+
|
28
28
|
Generate the migration, rapns.yml and migrate:
|
29
29
|
|
30
30
|
rails g rapns
|
@@ -62,7 +62,7 @@ Generate the migration, rapns.yml and migrate:
|
|
62
62
|
|
63
63
|
cd /path/to/rails/app
|
64
64
|
bundle exec rapns <Rails environment> [options]
|
65
|
-
|
65
|
+
|
66
66
|
### Options
|
67
67
|
|
68
68
|
* `-f` `--foreground` Prevent rapns from forking into a daemon.
|
@@ -125,7 +125,7 @@ Although rapns makes such errors highly unlikely due to validation, the APNs rep
|
|
125
125
|
`error` is set to Apple's code for the error.
|
126
126
|
`error_description` is set to a (somewhat brief) description of the error.
|
127
127
|
|
128
|
-
rapns will not attempt to deliver the notification again.
|
128
|
+
rapns will not attempt to deliver the notification again.
|
129
129
|
|
130
130
|
### Via the Feedback Service.
|
131
131
|
|
@@ -141,6 +141,7 @@ After updating you should run `rails g rapns` to check for any new migrations.
|
|
141
141
|
|
142
142
|
## Wiki
|
143
143
|
|
144
|
+
* [Deploying to Heroku](https://github.com/ileitch/rapns/wiki/Heroku)
|
144
145
|
* [Why open multiple connections to the APNs?](https://github.com/ileitch/rapns/wiki/Why-open-multiple-connections-to-the-APNs%3F)
|
145
146
|
|
146
147
|
## Contributing to rapns
|
@@ -162,4 +163,5 @@ Thank you to the following wonderful people for contributing to rapns:
|
|
162
163
|
* [@taybenlor](https://github.com/taybenlor)
|
163
164
|
* [@tompesman](https://github.com/tompesman)
|
164
165
|
* [@EpicDraws](https://github.com/EpicDraws)
|
165
|
-
* [@dei79](https://github.com/dei79)
|
166
|
+
* [@dei79](https://github.com/dei79)
|
167
|
+
* [@adorr](https://github.com/adorr)
|
data/bin/rapns
CHANGED
data/lib/rapns/app.rb
CHANGED
@@ -2,6 +2,8 @@ module Rapns
|
|
2
2
|
class App < ActiveRecord::Base
|
3
3
|
self.table_name = 'rapns_apps'
|
4
4
|
|
5
|
+
attr_accessible :key, :environment, :certificate, :password, :connections
|
6
|
+
|
5
7
|
validates :key, :presence => true, :uniqueness => true
|
6
8
|
validates :environment, :presence => true, :inclusion => { :in => %w(development production) }
|
7
9
|
validates :certificate, :presence => true
|
@@ -1,11 +1,14 @@
|
|
1
1
|
class PGError < StandardError; end if !defined?(PGError)
|
2
2
|
class Mysql; class Error < StandardError; end; end if !defined?(Mysql)
|
3
3
|
module Mysql2; class Error < StandardError; end; end if !defined?(Mysql2)
|
4
|
+
module ActiveRecord; end
|
5
|
+
class ActiveRecord::JDBCError < StandardError; end if !defined?(ActiveRecord::JDBCError)
|
4
6
|
|
5
7
|
module Rapns
|
6
8
|
module Daemon
|
7
9
|
module DatabaseReconnectable
|
8
|
-
ADAPTER_ERRORS = [ActiveRecord::StatementInvalid, PGError, Mysql::Error,
|
10
|
+
ADAPTER_ERRORS = [ActiveRecord::StatementInvalid, PGError, Mysql::Error,
|
11
|
+
Mysql2::Error, ActiveRecord::JDBCError]
|
9
12
|
|
10
13
|
def with_database_reconnect_and_retry
|
11
14
|
begin
|
data/lib/rapns/daemon.rb
CHANGED
@@ -1,6 +1,7 @@
|
|
1
1
|
require 'thread'
|
2
2
|
require 'socket'
|
3
3
|
require 'pathname'
|
4
|
+
require 'openssl'
|
4
5
|
|
5
6
|
require 'rapns/daemon/interruptible_sleep'
|
6
7
|
require 'rapns/daemon/delivery_error'
|
@@ -23,7 +24,7 @@ module Rapns
|
|
23
24
|
attr_accessor :logger, :config
|
24
25
|
end
|
25
26
|
|
26
|
-
def self.start(
|
27
|
+
def self.start(config)
|
27
28
|
self.config = config
|
28
29
|
self.logger = Logger.new(:foreground => config.foreground, :airbrake_notify => config.airbrake_notify)
|
29
30
|
setup_signal_hooks
|
data/lib/rapns/feedback.rb
CHANGED
data/lib/rapns/notification.rb
CHANGED
@@ -2,6 +2,9 @@ module Rapns
|
|
2
2
|
class Notification < ActiveRecord::Base
|
3
3
|
self.table_name = 'rapns_notifications'
|
4
4
|
|
5
|
+
attr_accessible :badge, :device_token, :sound, :alert, :attributes_for_device, :expiry,:delivered,
|
6
|
+
:delivered_at, :failed, :failed_at, :error_code, :error_description, :deliver_after, :alert_is_json, :app
|
7
|
+
|
5
8
|
validates :app, :presence => true
|
6
9
|
validates :device_token, :presence => true
|
7
10
|
validates :badge, :numericality => true, :allow_nil => true
|
@@ -18,7 +21,7 @@ module Rapns
|
|
18
21
|
|
19
22
|
def alert=(alert)
|
20
23
|
if alert.is_a?(Hash)
|
21
|
-
write_attribute(:alert,
|
24
|
+
write_attribute(:alert, multi_json_dump(alert))
|
22
25
|
self.alert_is_json = true if has_attribute?(:alert_is_json)
|
23
26
|
else
|
24
27
|
write_attribute(:alert, alert)
|
@@ -31,22 +34,22 @@ module Rapns
|
|
31
34
|
|
32
35
|
if has_attribute?(:alert_is_json)
|
33
36
|
if alert_is_json?
|
34
|
-
|
37
|
+
multi_json_load(string_or_json)
|
35
38
|
else
|
36
39
|
string_or_json
|
37
40
|
end
|
38
41
|
else
|
39
|
-
|
42
|
+
multi_json_load(string_or_json) rescue string_or_json
|
40
43
|
end
|
41
44
|
end
|
42
45
|
|
43
46
|
def attributes_for_device=(attrs)
|
44
47
|
raise ArgumentError, "attributes_for_device must be a Hash" if !attrs.is_a?(Hash)
|
45
|
-
write_attribute(:attributes_for_device,
|
48
|
+
write_attribute(:attributes_for_device, multi_json_dump(attrs))
|
46
49
|
end
|
47
50
|
|
48
51
|
def attributes_for_device
|
49
|
-
|
52
|
+
multi_json_load(read_attribute(:attributes_for_device)) if read_attribute(:attributes_for_device)
|
50
53
|
end
|
51
54
|
|
52
55
|
MDM_OVERIDE_KEY = '__rapns_mdm__'
|
@@ -71,7 +74,7 @@ module Rapns
|
|
71
74
|
end
|
72
75
|
|
73
76
|
def payload
|
74
|
-
|
77
|
+
multi_json_dump(as_json)
|
75
78
|
end
|
76
79
|
|
77
80
|
def payload_size
|
@@ -84,5 +87,21 @@ module Rapns
|
|
84
87
|
id_for_pack = options[:for_validation] ? 0 : id
|
85
88
|
[1, id_for_pack, expiry, 0, 32, device_token, payload_size, payload].pack("cNNccH*na*")
|
86
89
|
end
|
90
|
+
|
91
|
+
|
92
|
+
private
|
93
|
+
|
94
|
+
def multi_json_load(string, options = {})
|
95
|
+
# Calling load on multi_json less than v1.3.0 attempts to load a file from disk. Check the version explicitly.
|
96
|
+
if Gem.loaded_specs['multi_json'].version >= Gem::Version.create('1.3.0')
|
97
|
+
MultiJson.load(string, options)
|
98
|
+
else
|
99
|
+
MultiJson.decode(string, options)
|
100
|
+
end
|
101
|
+
end
|
102
|
+
|
103
|
+
def multi_json_dump(string, options = {})
|
104
|
+
MultiJson.respond_to?(:dump) ? MultiJson.dump(string, options) : MultiJson.encode(string, options)
|
105
|
+
end
|
87
106
|
end
|
88
107
|
end
|
data/lib/rapns/version.rb
CHANGED
data/spec/rapns/daemon_spec.rb
CHANGED
@@ -21,45 +21,45 @@ describe Rapns::Daemon, "when starting" do
|
|
21
21
|
config.stub(:foreground => false)
|
22
22
|
ActiveRecord::Base.stub(:establish_connection)
|
23
23
|
Rapns::Daemon.should_receive(:daemonize)
|
24
|
-
Rapns::Daemon.start(
|
24
|
+
Rapns::Daemon.start(config)
|
25
25
|
end
|
26
26
|
|
27
27
|
it "does not fork into a daemon if the foreground option is true" do
|
28
28
|
config.stub(:foreground => true)
|
29
29
|
Rapns::Daemon.should_not_receive(:daemonize)
|
30
|
-
Rapns::Daemon.start(
|
30
|
+
Rapns::Daemon.start(config)
|
31
31
|
end
|
32
32
|
|
33
33
|
it "writes the process ID to the PID file" do
|
34
34
|
Rapns::Daemon.should_receive(:write_pid_file)
|
35
|
-
Rapns::Daemon.start(
|
35
|
+
Rapns::Daemon.start(config)
|
36
36
|
end
|
37
37
|
|
38
38
|
it "logs an error if the PID file could not be written" do
|
39
39
|
config.stub(:pid_file => '/rails_root/rapns.pid')
|
40
40
|
File.stub(:open).and_raise(Errno::ENOENT)
|
41
41
|
logger.should_receive(:error).with("Failed to write PID to '/rails_root/rapns.pid': #<Errno::ENOENT: No such file or directory>")
|
42
|
-
Rapns::Daemon.start(
|
42
|
+
Rapns::Daemon.start(config)
|
43
43
|
end
|
44
44
|
|
45
45
|
it "starts the feeder" do
|
46
46
|
Rapns::Daemon::Feeder.should_receive(:start).with(2)
|
47
|
-
Rapns::Daemon.start(
|
47
|
+
Rapns::Daemon.start(config)
|
48
48
|
end
|
49
49
|
|
50
50
|
it "syncs apps" do
|
51
51
|
Rapns::Daemon::AppRunner.should_receive(:sync)
|
52
|
-
Rapns::Daemon.start(
|
52
|
+
Rapns::Daemon.start(config)
|
53
53
|
end
|
54
54
|
|
55
55
|
it "sets up the logger" do
|
56
56
|
config.stub(:airbrake_notify => true)
|
57
57
|
Rapns::Daemon::Logger.should_receive(:new).with(:foreground => true, :airbrake_notify => true)
|
58
|
-
Rapns::Daemon.start(
|
58
|
+
Rapns::Daemon.start(config)
|
59
59
|
end
|
60
60
|
|
61
61
|
it "makes the logger accessible" do
|
62
|
-
Rapns::Daemon.start(
|
62
|
+
Rapns::Daemon.start(config)
|
63
63
|
Rapns::Daemon.logger.should == logger
|
64
64
|
end
|
65
65
|
|
@@ -67,20 +67,20 @@ describe Rapns::Daemon, "when starting" do
|
|
67
67
|
Rapns::App.stub(:count => 0)
|
68
68
|
Rapns::Daemon.should_receive(:puts).any_number_of_times
|
69
69
|
Rapns::Daemon.should_receive(:exit).with(1)
|
70
|
-
Rapns::Daemon.start(
|
70
|
+
Rapns::Daemon.start(config)
|
71
71
|
end
|
72
72
|
|
73
73
|
it 'prints a warning exists if rapns has not been upgraded' do
|
74
74
|
Rapns::App.stub(:count).and_raise(ActiveRecord::StatementInvalid)
|
75
75
|
Rapns::Daemon.should_receive(:puts).any_number_of_times
|
76
76
|
Rapns::Daemon.should_receive(:exit).with(1)
|
77
|
-
Rapns::Daemon.start(
|
77
|
+
Rapns::Daemon.start(config)
|
78
78
|
end
|
79
79
|
|
80
80
|
it 'warns if rapns.yml still exists' do
|
81
81
|
File.should_receive(:exists?).with('/rails_root/config/rapns/rapns.yml').and_return(true)
|
82
82
|
logger.should_receive(:warn).with("Since 2.0.0 rapns uses command-line options instead of a configuration file. Please remove config/rapns/rapns.yml.")
|
83
|
-
Rapns::Daemon.start(
|
83
|
+
Rapns::Daemon.start(config)
|
84
84
|
end
|
85
85
|
end
|
86
86
|
|
@@ -161,4 +161,38 @@ describe Rapns::Notification, "bug #35" do
|
|
161
161
|
notification.payload_size.should < 256
|
162
162
|
notification.should be_valid
|
163
163
|
end
|
164
|
+
end
|
165
|
+
|
166
|
+
describe Rapns::Notification, "multi_json usage" do
|
167
|
+
describe Rapns::Notification, "alert" do
|
168
|
+
it "should call MultiJson.load when multi_json version is 1.3.0" do
|
169
|
+
notification = Rapns::Notification.new(:alert => { :a => 1 }, :alert_is_json => true)
|
170
|
+
Gem.stub(:loaded_specs).and_return( { 'multi_json' => Gem::Specification.new('multi_json', '1.3.0') } )
|
171
|
+
MultiJson.should_receive(:load).with(any_args())
|
172
|
+
notification.alert
|
173
|
+
end
|
174
|
+
|
175
|
+
it "should call MultiJson.decode when multi_json version is 1.2.9" do
|
176
|
+
notification = Rapns::Notification.new(:alert => { :a => 1 }, :alert_is_json => true)
|
177
|
+
Gem.stub(:loaded_specs).and_return( { 'multi_json' => Gem::Specification.new('multi_json', '1.2.9') } )
|
178
|
+
MultiJson.should_receive(:decode).with(any_args())
|
179
|
+
notification.alert
|
180
|
+
end
|
181
|
+
end
|
182
|
+
|
183
|
+
describe Rapns::Notification, "attributes_for_device=" do
|
184
|
+
it "should call MultiJson.dump when multi_json responds to :dump" do
|
185
|
+
notification = Rapns::Notification.new
|
186
|
+
MultiJson.stub(:respond_to?).with(:dump).and_return(true)
|
187
|
+
MultiJson.should_receive(:dump).with(any_args())
|
188
|
+
notification.attributes_for_device = { :pirates => 1 }
|
189
|
+
end
|
190
|
+
|
191
|
+
it "should call MultiJson.encode when multi_json does not respond to :dump" do
|
192
|
+
notification = Rapns::Notification.new
|
193
|
+
MultiJson.stub(:respond_to?).with(:dump).and_return(false)
|
194
|
+
MultiJson.should_receive(:encode).with(any_args())
|
195
|
+
notification.attributes_for_device = { :ninjas => 1 }
|
196
|
+
end
|
197
|
+
end
|
164
198
|
end
|
data/spec/spec_helper.rb
CHANGED
@@ -10,8 +10,28 @@ rescue LoadError
|
|
10
10
|
end
|
11
11
|
|
12
12
|
require 'active_record'
|
13
|
-
adapters = ['mysql', 'mysql2', 'postgresql']
|
14
|
-
|
13
|
+
adapters = ['mysql', 'mysql2', 'postgresql', 'jdbcpostgresql']
|
14
|
+
|
15
|
+
jruby = defined?(RUBY_ENGINE) && RUBY_ENGINE == 'jruby'
|
16
|
+
|
17
|
+
$adapter = if ENV['ADAPTER']
|
18
|
+
ENV['ADAPTER']
|
19
|
+
elsif jruby
|
20
|
+
'jdbcpostgresql'
|
21
|
+
else
|
22
|
+
'postgresql'
|
23
|
+
end
|
24
|
+
|
25
|
+
if jruby
|
26
|
+
if ENV['TRAVIS']
|
27
|
+
username = 'postgres'
|
28
|
+
else
|
29
|
+
require 'etc'
|
30
|
+
username = Etc.getlogin
|
31
|
+
end
|
32
|
+
else
|
33
|
+
username = nil
|
34
|
+
end
|
15
35
|
|
16
36
|
if !adapters.include?($adapter)
|
17
37
|
puts "No such adapter '#{$adapter}'. Valid adapters are #{adapters.join(', ')}."
|
@@ -20,7 +40,7 @@ end
|
|
20
40
|
|
21
41
|
puts "Using #{$adapter} adapter."
|
22
42
|
|
23
|
-
ActiveRecord::Base.establish_connection('adapter' => $adapter, 'database' => 'rapns_test')
|
43
|
+
ActiveRecord::Base.establish_connection('username' => username, 'adapter' => $adapter, 'database' => 'rapns_test')
|
24
44
|
require 'generators/templates/create_rapns_notifications'
|
25
45
|
require 'generators/templates/create_rapns_feedback'
|
26
46
|
require 'generators/templates/add_alert_is_json_to_rapns_notifications'
|
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: 2.0.
|
4
|
+
version: 2.0.3
|
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: 2012-07-
|
12
|
+
date: 2012-07-26 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: multi_json
|
@@ -27,8 +27,7 @@ dependencies:
|
|
27
27
|
- - ~>
|
28
28
|
- !ruby/object:Gem::Version
|
29
29
|
version: '1.0'
|
30
|
-
description: Easy to use
|
31
|
-
3
|
30
|
+
description: Easy to use, full featured APNs daemon for Rails 3
|
32
31
|
email:
|
33
32
|
- port001@gmail.com
|
34
33
|
executables:
|
@@ -109,7 +108,7 @@ rubyforge_project:
|
|
109
108
|
rubygems_version: 1.8.23
|
110
109
|
signing_key:
|
111
110
|
specification_version: 3
|
112
|
-
summary: Easy to use
|
111
|
+
summary: Easy to use, full featured APNs daemon for Rails 3
|
113
112
|
test_files:
|
114
113
|
- spec/rapns/daemon/app_runner_spec.rb
|
115
114
|
- spec/rapns/daemon/connection_spec.rb
|
@@ -126,3 +125,4 @@ test_files:
|
|
126
125
|
- spec/rapns/feedback_spec.rb
|
127
126
|
- spec/rapns/notification_spec.rb
|
128
127
|
- spec/spec_helper.rb
|
128
|
+
has_rdoc:
|