rapns 2.0.1 → 2.0.3

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.
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
@@ -43,4 +43,4 @@ if config.pid_file && !Pathname.new(config.pid_file).absolute?
43
43
  config.pid_file = File.join(Rails.root, config.pid_file)
44
44
  end
45
45
 
46
- Rapns::Daemon.start(environment, config)
46
+ Rapns::Daemon.start(config)
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, Mysql2::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(environment, config)
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
@@ -2,6 +2,8 @@ module Rapns
2
2
  class Feedback < ActiveRecord::Base
3
3
  self.table_name = 'rapns_feedback'
4
4
 
5
+ attr_accessible :device_token, :failed_at, :app
6
+
5
7
  validates :device_token, :presence => true
6
8
  validates :failed_at, :presence => true
7
9
 
@@ -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, MultiJson.dump(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
- MultiJson.load(string_or_json)
37
+ multi_json_load(string_or_json)
35
38
  else
36
39
  string_or_json
37
40
  end
38
41
  else
39
- MultiJson.load(string_or_json) rescue string_or_json
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, MultiJson.dump(attrs))
48
+ write_attribute(:attributes_for_device, multi_json_dump(attrs))
46
49
  end
47
50
 
48
51
  def attributes_for_device
49
- MultiJson.load(read_attribute(:attributes_for_device)) if read_attribute(:attributes_for_device)
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
- MultiJson.dump(as_json)
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
@@ -1,3 +1,3 @@
1
1
  module Rapns
2
- VERSION = '2.0.1'
2
+ VERSION = '2.0.3'
3
3
  end
@@ -29,6 +29,8 @@ describe Rapns::Daemon::DatabaseReconnectable do
29
29
  Mysql::Error
30
30
  when 'mysql2'
31
31
  Mysql2::Error
32
+ when 'jdbcpostgresql'
33
+ ActiveRecord::JDBCError
32
34
  else
33
35
  raise "Please update #{__FILE__} for adapter #{$adapter}"
34
36
  end
@@ -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("development", config)
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("development", config)
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("development", config)
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("development", config)
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("development", config)
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("development", config)
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("development", config)
58
+ Rapns::Daemon.start(config)
59
59
  end
60
60
 
61
61
  it "makes the logger accessible" do
62
- Rapns::Daemon.start("development", config)
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("development", config)
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("development", config)
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("development", config)
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
- $adapter = ENV['ADAPTER'] || 'postgresql'
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.1
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-08 00:00:00.000000000 Z
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 library for Apple's Push Notification Service with Rails
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 library for Apple's Push Notification Service with Rails 3
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: