apn_on_rails 0.4.0 → 0.4.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.
- data/.gitignore +2 -1
- data/Gemfile +2 -1
- data/Gemfile.lock +12 -10
- data/README +19 -9
- data/README.textile +17 -6
- data/VERSION +1 -1
- data/apn_on_rails.gemspec +39 -5
- data/autotest/discover.rb +1 -0
- data/generators/templates/apn_migrations/002_create_apn_notifications.rb +0 -1
- data/generators/templates/apn_migrations/004_create_apn_apps.rb +2 -2
- data/generators/templates/apn_migrations/010_alter_apn_notifications.rb +21 -0
- data/generators/templates/apn_migrations/011_make_device_token_index_nonunique.rb +11 -0
- data/lib/apn_on_rails/app/models/apn/app.rb +46 -17
- data/lib/apn_on_rails/app/models/apn/device.rb +2 -3
- data/spec/apn_on_rails/app/models/apn/app_spec.rb +63 -11
- data/spec/apn_on_rails/app/models/apn/device_spec.rb +6 -6
- data/spec/factories/app_factory.rb +3 -3
- metadata +54 -39
data/.gitignore
CHANGED
data/Gemfile
CHANGED
@@ -8,8 +8,9 @@ gem 'configatron'
|
|
8
8
|
# Add dependencies to develop your gem here.
|
9
9
|
# Include everything needed to run rake, tests, features, etc.
|
10
10
|
group :development do
|
11
|
+
gem 'autotest'
|
11
12
|
gem 'sqlite3-ruby'
|
12
|
-
gem "rspec", ">= 2.0.0
|
13
|
+
gem "rspec", ">= 2.0.0"
|
13
14
|
gem "bundler", ">= 1.0.0.rc.5"
|
14
15
|
gem "jeweler", "~> 1.5.0.pre2"
|
15
16
|
gem "rcov", ">= 0"
|
data/Gemfile.lock
CHANGED
@@ -7,6 +7,7 @@ GEM
|
|
7
7
|
activerecord (2.3.9)
|
8
8
|
activesupport (= 2.3.9)
|
9
9
|
activesupport (2.3.9)
|
10
|
+
autotest (4.3.2)
|
10
11
|
configatron (2.6.4)
|
11
12
|
yamler (>= 0.1.0)
|
12
13
|
diff-lcs (1.1.2)
|
@@ -18,16 +19,16 @@ GEM
|
|
18
19
|
rack (1.1.0)
|
19
20
|
rake (0.8.7)
|
20
21
|
rcov (0.9.9)
|
21
|
-
rspec (2.0.
|
22
|
-
rspec-core (
|
23
|
-
rspec-expectations (
|
24
|
-
rspec-mocks (
|
25
|
-
rspec-core (2.0.
|
26
|
-
rspec-expectations (2.0.
|
22
|
+
rspec (2.0.1)
|
23
|
+
rspec-core (~> 2.0.1)
|
24
|
+
rspec-expectations (~> 2.0.1)
|
25
|
+
rspec-mocks (~> 2.0.1)
|
26
|
+
rspec-core (2.0.1)
|
27
|
+
rspec-expectations (2.0.1)
|
27
28
|
diff-lcs (>= 1.1.2)
|
28
|
-
rspec-mocks (2.0.
|
29
|
-
rspec-core (
|
30
|
-
rspec-expectations (
|
29
|
+
rspec-mocks (2.0.1)
|
30
|
+
rspec-core (~> 2.0.1)
|
31
|
+
rspec-expectations (~> 2.0.1)
|
31
32
|
sqlite3-ruby (1.3.1)
|
32
33
|
yamler (0.1.0)
|
33
34
|
|
@@ -37,9 +38,10 @@ PLATFORMS
|
|
37
38
|
DEPENDENCIES
|
38
39
|
actionpack (~> 2.3.8)
|
39
40
|
activerecord (~> 2.3.8)
|
41
|
+
autotest
|
40
42
|
bundler (>= 1.0.0.rc.5)
|
41
43
|
configatron
|
42
44
|
jeweler (~> 1.5.0.pre2)
|
43
45
|
rcov
|
44
|
-
rspec (>= 2.0.0
|
46
|
+
rspec (>= 2.0.0)
|
45
47
|
sqlite3-ruby
|
data/README
CHANGED
@@ -4,7 +4,7 @@ APN on Rails is a Ruby on Rails gem that allows you to easily add Apple Push Not
|
|
4
4
|
support to your Rails application.
|
5
5
|
|
6
6
|
It supports:
|
7
|
-
* Multiple iPhone apps managed from the same Rails application
|
7
|
+
* Multiple iPhone apps managed from the same Rails application as well as a legacy default "app" with certs stored in config
|
8
8
|
* Individual notifications and group notifications
|
9
9
|
* Alerts, badges, sounds, and custom properties in notifications
|
10
10
|
* Pull notifications
|
@@ -14,13 +14,16 @@ It supports:
|
|
14
14
|
Multiple iPhone Apps: In previous versions of this gem a single Rails application was set up to
|
15
15
|
manage push notifications for a single iPhone app. In many cases it is useful to have a single Rails
|
16
16
|
app manage push notifications for multiple iPhone apps. With the addition of an APN::App model, this
|
17
|
-
is now possible. The certificates are now stored on instances of APN::
|
18
|
-
with a particular app.
|
17
|
+
is now possible. The certificates are now stored on instances of APN::App and devices are intended to be associated
|
18
|
+
with a particular app. For compatibility with existing implementations it is still possible to create devices that
|
19
|
+
are not associated with an APN::App and to send individual notifications to them using the certs stored in the
|
20
|
+
config directory.
|
19
21
|
|
20
22
|
Individual and Group Notifications: Previous versions of this gem treated each notification individually
|
21
23
|
and did not provide a built-in way to send a broadcast notification to a group of devices. Group notifications
|
22
24
|
are now built into the gem. A group notification is associated with a group of devices and shares its
|
23
|
-
contents across the entire group of devices.
|
25
|
+
contents across the entire group of devices. (Group notifications are only available for groups of devices associated
|
26
|
+
with an APN::App)
|
24
27
|
|
25
28
|
Notification Content Areas: Notifications may contain alerts, badges, sounds, and custom properties.
|
26
29
|
|
@@ -28,7 +31,14 @@ Pull Notifications: This version of the gem supports an alternative notification
|
|
28
31
|
on pulls from client devices and does not interact with the Apple Push Notification servers. This feature
|
29
32
|
may be used entirely independently of the push notification features. Pull notifications may be
|
30
33
|
created for an app. A client app can query for the most recent pull notification available since a
|
31
|
-
given date to retrieve any notifications waiting for it.
|
34
|
+
given date to retrieve any notifications waiting for it.
|
35
|
+
|
36
|
+
==Version 0.4.1 Notes
|
37
|
+
|
38
|
+
* Backwards compatibility. 0.4.0 required a manual upgrade to associate existing and new devices with an APN::App model. This version allows continued use of devices that are associated with a default "app" that stores its certificates in the config directory. This ought to allow upgrade to this version without code changes.
|
39
|
+
* Batched finds. Finds on the APN::Device model that can return large numbers of records have been batched to limit memory impact.
|
40
|
+
* Custom properties migration. At a pre-0.4.0 version the custom_properties attribute was added to the migration template that created the notifications table. This introduced a potential problem for gem users who had previously run this migration. The custom_properties alteration to the apn_notifications table has been moved to its own migration and should work regardless of whether your apn_notifications table already has a custom_properties attribute.
|
41
|
+
* last_registered_at changed to work intuitively. The last_registered_at attribute of devices was being updated only on creation potentially causing a bug in which a device that opts out of APNs and then opts back in before apn_on_rails received feedback about it might miss a period of APNs that it should receive.
|
32
42
|
|
33
43
|
==Acknowledgements:
|
34
44
|
|
@@ -105,9 +115,9 @@ Now, to create the tables you need for APN on Rails, run the following task:
|
|
105
115
|
|
106
116
|
APN on Rails uses the Configatron gem, http://github.com/markbates/configatron/tree/master,
|
107
117
|
to configure itself. (With the change to multi-app support, the certifications are stored in the
|
108
|
-
database rather than in the config directory
|
109
|
-
|
110
|
-
see fit:
|
118
|
+
database rather than in the config directory, however, it is still possible to use the default "app" and the certificates
|
119
|
+
stored in the config directory. For this setup, the following configurations apply.)
|
120
|
+
APN on Rails has the following default configurations that you change as you see fit:
|
111
121
|
|
112
122
|
# development (delivery):
|
113
123
|
configatron.apn.passphrase # => ''
|
@@ -142,7 +152,7 @@ That way you ensure you have the latest version of the database tables needed.
|
|
142
152
|
==Example (assuming you have created an app and stored your keys on it):
|
143
153
|
|
144
154
|
$ ./script/console
|
145
|
-
>> app = APN::App.
|
155
|
+
>> app = APN::App.create(:name => "My App", :apn_dev_cert => "PASTE YOUR DEV CERT HERE", :apn_prod_cert => "PASTE YOUR PROD CERT HERE")
|
146
156
|
>> device = APN::Device.create(:token => "XXXXXXXX XXXXXXXX XXXXXXXX XXXXXXXX XXXXXXXX XXXXXXXX XXXXXXXX XXXXXXXX",:app_id => app.id)
|
147
157
|
>> notification = APN::Notification.new
|
148
158
|
>> notification.device = device
|
data/README.textile
CHANGED
@@ -4,7 +4,7 @@ APN on Rails is a Ruby on Rails gem that allows you to easily add Apple Push Not
|
|
4
4
|
support to your Rails application.
|
5
5
|
|
6
6
|
It supports:
|
7
|
-
* Multiple iPhone apps managed from the same Rails application
|
7
|
+
* Multiple iPhone apps managed from the same Rails application as well as a legacy default "app" with certs stored in config
|
8
8
|
* Individual notifications and group notifications
|
9
9
|
* Alerts, badges, sounds, and custom properties in notifications
|
10
10
|
* Pull notifications
|
@@ -14,13 +14,16 @@ h2. Feature Descriptions
|
|
14
14
|
Multiple iPhone Apps: In previous versions of this gem a single Rails application was set up to
|
15
15
|
manage push notifications for a single iPhone app. In many cases it is useful to have a single Rails
|
16
16
|
app manage push notifications for multiple iPhone apps. With the addition of an APN::App model, this
|
17
|
-
is now possible. The certificates are now stored on instances of APN::
|
18
|
-
with a particular app.
|
17
|
+
is now possible. The certificates are now stored on instances of APN::App and all devices are intended to be associated
|
18
|
+
with a particular app. For compatibility with existing implementations it is still possible to create devices that
|
19
|
+
are not associated with an APN::App and to send individual notifications to them using the certs stored in the
|
20
|
+
config directory.
|
19
21
|
|
20
22
|
Individual and Group Notifications: Previous versions of this gem treated each notification individually
|
21
23
|
and did not provide a built-in way to send a broadcast notification to a group of devices. Group notifications
|
22
24
|
are now built into the gem. A group notification is associated with a group of devices and shares its
|
23
|
-
contents across the entire group of devices.
|
25
|
+
contents across the entire group of devices. (Group notifications are only available for groups of devices associated
|
26
|
+
with an APN::App)
|
24
27
|
|
25
28
|
Notification Content Areas: Notifications may contain alerts, badges, sounds, and custom properties.
|
26
29
|
|
@@ -30,6 +33,13 @@ may be used entirely independently of the push notification features. Pull noti
|
|
30
33
|
created for an app. A client app can query for the most recent pull notification available since a
|
31
34
|
given date to retrieve any notifications waiting for it.
|
32
35
|
|
36
|
+
h2. Version 0.4.1 Notes
|
37
|
+
|
38
|
+
* Backwards compatibility. 0.4.0 required a manual upgrade to associate existing and new devices with an APN::App model. This version allows continued use of devices that are associated with a default "app" that stores its certificates in the config directory. This ought to allow upgrade to this version without code changes.
|
39
|
+
* Batched finds. Finds on the APN::Device model that can return large numbers of records have been batched to limit memory impact.
|
40
|
+
* Custom properties migration. At a pre-0.4.0 version the custom_properties attribute was added to the migration template that created the notifications table. This introduced a potential problem for gem users who had previously run this migration. The custom_properties alteration to the apn_notifications table has been moved to its own migration and should work regardless of whether your apn_notifications table already has a custom_properties attribute.
|
41
|
+
* last_registered_at changed to work intuitively. The last_registered_at attribute of devices was being updated only on creation potentially causing a bug in which a device that opts out of APNs and then opts back in before apn_on_rails received feedback about it might miss a period of APNs that it should receive.
|
42
|
+
|
33
43
|
h2. Acknowledgements:
|
34
44
|
|
35
45
|
From Mark Bates:
|
@@ -121,7 +131,8 @@ Now, to create the tables you need for APN on Rails, run the following task:
|
|
121
131
|
|
122
132
|
APN on Rails uses the Configatron gem, http://github.com/markbates/configatron/tree/master,
|
123
133
|
to configure itself. (With the change to multi-app support, the certifications are stored in the
|
124
|
-
database rather than in the config directory
|
134
|
+
database rather than in the config directory, however, it is still possible to use the default "app" and the certificates
|
135
|
+
stored in the config directory. For this setup, the following configurations apply.)
|
125
136
|
APN on Rails has the following default configurations that you change as you
|
126
137
|
see fit:
|
127
138
|
|
@@ -166,7 +177,7 @@ h2. Example (assuming you have created an app and stored your keys on it):
|
|
166
177
|
|
167
178
|
<pre><code>
|
168
179
|
$ ./script/console
|
169
|
-
>> app = APN::App.
|
180
|
+
>> app = APN::App.create(:name => "My App", :apn_dev_cert => "PASTE YOUR DEV CERT HERE", :apn_prod_cert => "PASTE YOUR PROD CERT HERE")
|
170
181
|
>> device = APN::Device.create(:token => "XXXXXXXX XXXXXXXX XXXXXXXX XXXXXXXX XXXXXXXX XXXXXXXX XXXXXXXX XXXXXXXX",:app_id => app.id)
|
171
182
|
>> notification = APN::Notification.new
|
172
183
|
>> notification.device = device
|
data/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
0.4.
|
1
|
+
0.4.1
|
data/apn_on_rails.gemspec
CHANGED
@@ -5,11 +5,11 @@
|
|
5
5
|
|
6
6
|
Gem::Specification.new do |s|
|
7
7
|
s.name = %q{apn_on_rails}
|
8
|
-
s.version = "0.
|
8
|
+
s.version = "0.4.1"
|
9
9
|
|
10
10
|
s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
|
11
11
|
s.authors = ["markbates", "Rebecca Nesson"]
|
12
|
-
s.date = %q{2010-
|
12
|
+
s.date = %q{2010-11-09}
|
13
13
|
s.description = %q{APN on Rails is a Ruby on Rails gem that allows you to
|
14
14
|
easily add Apple Push Notification (iPhone) support to your Rails application.
|
15
15
|
}
|
@@ -22,6 +22,7 @@ easily add Apple Push Notification (iPhone) support to your Rails application.
|
|
22
22
|
s.files = [
|
23
23
|
".gitignore",
|
24
24
|
".rspec",
|
25
|
+
".specification",
|
25
26
|
"Gemfile",
|
26
27
|
"Gemfile.lock",
|
27
28
|
"LICENSE",
|
@@ -30,28 +31,50 @@ easily add Apple Push Notification (iPhone) support to your Rails application.
|
|
30
31
|
"Rakefile",
|
31
32
|
"VERSION",
|
32
33
|
"apn_on_rails.gemspec",
|
34
|
+
"autotest/discover.rb",
|
33
35
|
"generators/apn_migrations_generator.rb",
|
34
36
|
"generators/templates/apn_migrations/001_create_apn_devices.rb",
|
35
37
|
"generators/templates/apn_migrations/002_create_apn_notifications.rb",
|
36
38
|
"generators/templates/apn_migrations/003_alter_apn_devices.rb",
|
39
|
+
"generators/templates/apn_migrations/004_create_apn_apps.rb",
|
40
|
+
"generators/templates/apn_migrations/005_create_groups.rb",
|
41
|
+
"generators/templates/apn_migrations/006_alter_apn_groups.rb",
|
42
|
+
"generators/templates/apn_migrations/007_create_device_groups.rb",
|
43
|
+
"generators/templates/apn_migrations/008_create_apn_group_notifications.rb",
|
44
|
+
"generators/templates/apn_migrations/009_create_pull_notifications.rb",
|
45
|
+
"generators/templates/apn_migrations/010_alter_apn_notifications.rb",
|
46
|
+
"generators/templates/apn_migrations/011_make_device_token_index_nonunique.rb",
|
37
47
|
"lib/apn_on_rails.rb",
|
38
48
|
"lib/apn_on_rails/apn_on_rails.rb",
|
49
|
+
"lib/apn_on_rails/app/models/apn/app.rb",
|
39
50
|
"lib/apn_on_rails/app/models/apn/base.rb",
|
40
51
|
"lib/apn_on_rails/app/models/apn/device.rb",
|
52
|
+
"lib/apn_on_rails/app/models/apn/device_grouping.rb",
|
53
|
+
"lib/apn_on_rails/app/models/apn/group.rb",
|
54
|
+
"lib/apn_on_rails/app/models/apn/group_notification.rb",
|
41
55
|
"lib/apn_on_rails/app/models/apn/notification.rb",
|
56
|
+
"lib/apn_on_rails/app/models/apn/pull_notification.rb",
|
42
57
|
"lib/apn_on_rails/libs/connection.rb",
|
43
58
|
"lib/apn_on_rails/libs/feedback.rb",
|
44
59
|
"lib/apn_on_rails/tasks/apn.rake",
|
45
60
|
"lib/apn_on_rails/tasks/db.rake",
|
46
61
|
"lib/apn_on_rails_tasks.rb",
|
47
62
|
"spec/active_record/setup_ar.rb",
|
63
|
+
"spec/apn_on_rails/app/models/apn/app_spec.rb",
|
48
64
|
"spec/apn_on_rails/app/models/apn/device_spec.rb",
|
65
|
+
"spec/apn_on_rails/app/models/apn/group_notification_spec.rb",
|
49
66
|
"spec/apn_on_rails/app/models/apn/notification_spec.rb",
|
67
|
+
"spec/apn_on_rails/app/models/apn/pull_notification_spec.rb",
|
50
68
|
"spec/apn_on_rails/libs/connection_spec.rb",
|
51
69
|
"spec/apn_on_rails/libs/feedback_spec.rb",
|
52
70
|
"spec/extensions/string.rb",
|
71
|
+
"spec/factories/app_factory.rb",
|
53
72
|
"spec/factories/device_factory.rb",
|
73
|
+
"spec/factories/device_grouping_factory.rb",
|
74
|
+
"spec/factories/group_factory.rb",
|
75
|
+
"spec/factories/group_notification_factory.rb",
|
54
76
|
"spec/factories/notification_factory.rb",
|
77
|
+
"spec/factories/pull_notification_factory.rb",
|
55
78
|
"spec/fixtures/hexa.bin",
|
56
79
|
"spec/fixtures/message_for_sending.bin",
|
57
80
|
"spec/rails_root/config/apple_push_notification_development.pem",
|
@@ -63,13 +86,21 @@ easily add Apple Push Notification (iPhone) support to your Rails application.
|
|
63
86
|
s.summary = %q{Apple Push Notifications on Rails}
|
64
87
|
s.test_files = [
|
65
88
|
"spec/active_record/setup_ar.rb",
|
89
|
+
"spec/apn_on_rails/app/models/apn/app_spec.rb",
|
66
90
|
"spec/apn_on_rails/app/models/apn/device_spec.rb",
|
91
|
+
"spec/apn_on_rails/app/models/apn/group_notification_spec.rb",
|
67
92
|
"spec/apn_on_rails/app/models/apn/notification_spec.rb",
|
93
|
+
"spec/apn_on_rails/app/models/apn/pull_notification_spec.rb",
|
68
94
|
"spec/apn_on_rails/libs/connection_spec.rb",
|
69
95
|
"spec/apn_on_rails/libs/feedback_spec.rb",
|
70
96
|
"spec/extensions/string.rb",
|
97
|
+
"spec/factories/app_factory.rb",
|
71
98
|
"spec/factories/device_factory.rb",
|
99
|
+
"spec/factories/device_grouping_factory.rb",
|
100
|
+
"spec/factories/group_factory.rb",
|
101
|
+
"spec/factories/group_notification_factory.rb",
|
72
102
|
"spec/factories/notification_factory.rb",
|
103
|
+
"spec/factories/pull_notification_factory.rb",
|
73
104
|
"spec/spec_helper.rb"
|
74
105
|
]
|
75
106
|
|
@@ -79,8 +110,9 @@ easily add Apple Push Notification (iPhone) support to your Rails application.
|
|
79
110
|
|
80
111
|
if Gem::Version.new(Gem::VERSION) >= Gem::Version.new('1.2.0') then
|
81
112
|
s.add_runtime_dependency(%q<configatron>, [">= 0"])
|
113
|
+
s.add_development_dependency(%q<autotest>, [">= 0"])
|
82
114
|
s.add_development_dependency(%q<sqlite3-ruby>, [">= 0"])
|
83
|
-
s.add_development_dependency(%q<rspec>, [">= 2.0.0
|
115
|
+
s.add_development_dependency(%q<rspec>, [">= 2.0.0"])
|
84
116
|
s.add_development_dependency(%q<bundler>, [">= 1.0.0.rc.5"])
|
85
117
|
s.add_development_dependency(%q<jeweler>, ["~> 1.5.0.pre2"])
|
86
118
|
s.add_development_dependency(%q<rcov>, [">= 0"])
|
@@ -88,8 +120,9 @@ easily add Apple Push Notification (iPhone) support to your Rails application.
|
|
88
120
|
s.add_development_dependency(%q<activerecord>, ["~> 2.3.8"])
|
89
121
|
else
|
90
122
|
s.add_dependency(%q<configatron>, [">= 0"])
|
123
|
+
s.add_dependency(%q<autotest>, [">= 0"])
|
91
124
|
s.add_dependency(%q<sqlite3-ruby>, [">= 0"])
|
92
|
-
s.add_dependency(%q<rspec>, [">= 2.0.0
|
125
|
+
s.add_dependency(%q<rspec>, [">= 2.0.0"])
|
93
126
|
s.add_dependency(%q<bundler>, [">= 1.0.0.rc.5"])
|
94
127
|
s.add_dependency(%q<jeweler>, ["~> 1.5.0.pre2"])
|
95
128
|
s.add_dependency(%q<rcov>, [">= 0"])
|
@@ -98,8 +131,9 @@ easily add Apple Push Notification (iPhone) support to your Rails application.
|
|
98
131
|
end
|
99
132
|
else
|
100
133
|
s.add_dependency(%q<configatron>, [">= 0"])
|
134
|
+
s.add_dependency(%q<autotest>, [">= 0"])
|
101
135
|
s.add_dependency(%q<sqlite3-ruby>, [">= 0"])
|
102
|
-
s.add_dependency(%q<rspec>, [">= 2.0.0
|
136
|
+
s.add_dependency(%q<rspec>, [">= 2.0.0"])
|
103
137
|
s.add_dependency(%q<bundler>, [">= 1.0.0.rc.5"])
|
104
138
|
s.add_dependency(%q<jeweler>, ["~> 1.5.0.pre2"])
|
105
139
|
s.add_dependency(%q<rcov>, [">= 0"])
|
@@ -0,0 +1 @@
|
|
1
|
+
Autotest.add_discovery { "rspec2" }
|
@@ -0,0 +1,21 @@
|
|
1
|
+
class AlterApnNotifications < ActiveRecord::Migration # :nodoc:
|
2
|
+
|
3
|
+
module APN # :nodoc:
|
4
|
+
class Notification < ActiveRecord::Base # :nodoc:
|
5
|
+
set_table_name 'apn_notifications'
|
6
|
+
end
|
7
|
+
end
|
8
|
+
|
9
|
+
def self.up
|
10
|
+
unless APN::Notification.column_names.include?("custom_properties")
|
11
|
+
add_column :apn_notifications, :custom_properties, :text
|
12
|
+
end
|
13
|
+
end
|
14
|
+
|
15
|
+
def self.down
|
16
|
+
if APN::Notification.column_names.include?("custom_properties")
|
17
|
+
remove_column :apn_notifications, :custom_properties
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
end
|
@@ -0,0 +1,11 @@
|
|
1
|
+
class MakeDeviceTokenIndexNonunique < ActiveRecord::Migration
|
2
|
+
def self.up
|
3
|
+
remove_index :apn_devices, :column => :token
|
4
|
+
add_index :apn_devices, :token
|
5
|
+
end
|
6
|
+
|
7
|
+
def self.down
|
8
|
+
remove_index :apn_devices, :column => :token
|
9
|
+
add_index :apn_devices, :token, :unique => true
|
10
|
+
end
|
11
|
+
end
|
@@ -23,15 +23,7 @@ class APN::App < APN::Base
|
|
23
23
|
raise APN::Errors::MissingCertificateError.new
|
24
24
|
return
|
25
25
|
end
|
26
|
-
|
27
|
-
APN::Connection.open_for_delivery({:cert => self.cert}) do |conn, sock|
|
28
|
-
unsent_notifications.each do |noty|
|
29
|
-
conn.write(noty.message_for_sending)
|
30
|
-
noty.sent_at = Time.now
|
31
|
-
noty.save
|
32
|
-
end
|
33
|
-
end
|
34
|
-
end
|
26
|
+
APN::App.send_notifications_for_cert(self.cert, self.id)
|
35
27
|
end
|
36
28
|
|
37
29
|
def self.send_notifications
|
@@ -39,6 +31,32 @@ class APN::App < APN::Base
|
|
39
31
|
apps.each do |app|
|
40
32
|
app.send_notifications
|
41
33
|
end
|
34
|
+
global_cert = File.read(configatron.apn.cert)
|
35
|
+
if global_cert
|
36
|
+
send_notifications_for_cert(global_cert, nil)
|
37
|
+
end
|
38
|
+
end
|
39
|
+
|
40
|
+
def self.send_notifications_for_cert(the_cert, app_id)
|
41
|
+
# unless self.unsent_notifications.nil? || self.unsent_notifications.empty?
|
42
|
+
if (app_id == nil)
|
43
|
+
conditions = "app_id is null"
|
44
|
+
else
|
45
|
+
conditions = ["app_id = ?", app_id]
|
46
|
+
end
|
47
|
+
begin
|
48
|
+
APN::Connection.open_for_delivery({:cert => the_cert}) do |conn, sock|
|
49
|
+
APN::Device.find_each(:conditions => conditions) do |dev|
|
50
|
+
dev.unsent_notifications.each do |noty|
|
51
|
+
conn.write(noty.message_for_sending)
|
52
|
+
noty.sent_at = Time.now
|
53
|
+
noty.save
|
54
|
+
end
|
55
|
+
end
|
56
|
+
end
|
57
|
+
rescue
|
58
|
+
end
|
59
|
+
# end
|
42
60
|
end
|
43
61
|
|
44
62
|
def send_group_notifications
|
@@ -49,8 +67,7 @@ class APN::App < APN::Base
|
|
49
67
|
unless self.unsent_group_notifications.nil? || self.unsent_group_notifications.empty?
|
50
68
|
APN::Connection.open_for_delivery({:cert => self.cert}) do |conn, sock|
|
51
69
|
unsent_group_notifications.each do |gnoty|
|
52
|
-
|
53
|
-
gnoty.devices.each do |device|
|
70
|
+
gnoty.devices.find_each do |device|
|
54
71
|
conn.write(gnoty.message_for_sending(device))
|
55
72
|
end
|
56
73
|
gnoty.sent_at = Time.now
|
@@ -67,7 +84,7 @@ class APN::App < APN::Base
|
|
67
84
|
end
|
68
85
|
unless gnoty.nil?
|
69
86
|
APN::Connection.open_for_delivery({:cert => self.cert}) do |conn, sock|
|
70
|
-
gnoty.devices.
|
87
|
+
gnoty.devices.find_each do |device|
|
71
88
|
conn.write(gnoty.message_for_sending(device))
|
72
89
|
end
|
73
90
|
gnoty.sent_at = Time.now
|
@@ -98,11 +115,7 @@ class APN::App < APN::Base
|
|
98
115
|
raise APN::Errors::MissingCertificateError.new
|
99
116
|
return
|
100
117
|
end
|
101
|
-
APN::
|
102
|
-
if device.last_registered_at < device.feedback_at
|
103
|
-
device.destroy
|
104
|
-
end
|
105
|
-
end
|
118
|
+
APN::App.process_devices_for_cert(self.cert)
|
106
119
|
end # process_devices
|
107
120
|
|
108
121
|
def self.process_devices
|
@@ -110,6 +123,22 @@ class APN::App < APN::Base
|
|
110
123
|
apps.each do |app|
|
111
124
|
app.process_devices
|
112
125
|
end
|
126
|
+
global_cert = File.read(configatron.apn.cert)
|
127
|
+
if global_cert
|
128
|
+
APN::App.process_devices_for_cert(global_cert)
|
129
|
+
end
|
130
|
+
end
|
131
|
+
|
132
|
+
def self.process_devices_for_cert(the_cert)
|
133
|
+
puts "in APN::App.process_devices_for_cert"
|
134
|
+
APN::Feedback.devices(the_cert).each do |device|
|
135
|
+
if device.last_registered_at < device.feedback_at
|
136
|
+
puts "device #{device.id} -> #{device.last_registered_at} < #{device.feedback_at}"
|
137
|
+
device.destroy
|
138
|
+
else
|
139
|
+
puts "device #{device.id} -> #{device.last_registered_at} not < #{device.feedback_at}"
|
140
|
+
end
|
141
|
+
end
|
113
142
|
end
|
114
143
|
|
115
144
|
end
|
@@ -17,7 +17,7 @@ class APN::Device < APN::Base
|
|
17
17
|
validates_uniqueness_of :token, :scope => :app_id
|
18
18
|
validates_format_of :token, :with => /^[a-z0-9]{8}\s[a-z0-9]{8}\s[a-z0-9]{8}\s[a-z0-9]{8}\s[a-z0-9]{8}\s[a-z0-9]{8}\s[a-z0-9]{8}\s[a-z0-9]{8}$/
|
19
19
|
|
20
|
-
|
20
|
+
before_create :set_last_registered_at
|
21
21
|
|
22
22
|
# The <tt>feedback_at</tt> accessor is set when the
|
23
23
|
# device is marked as potentially disconnected from your
|
@@ -42,9 +42,8 @@ class APN::Device < APN::Base
|
|
42
42
|
[self.token.delete(' ')].pack('H*')
|
43
43
|
end
|
44
44
|
|
45
|
-
private
|
46
45
|
def set_last_registered_at
|
47
|
-
self.last_registered_at = Time.now if self.last_registered_at.nil?
|
46
|
+
self.last_registered_at = Time.now #if self.last_registered_at.nil?
|
48
47
|
end
|
49
48
|
|
50
49
|
end
|
@@ -10,27 +10,59 @@ describe APN::App do
|
|
10
10
|
device = DeviceFactory.create({:app_id => app.id})
|
11
11
|
notifications = [NotificationFactory.create({:device_id => device.id}),
|
12
12
|
NotificationFactory.create({:device_id => device.id})]
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
13
|
+
|
14
|
+
notifications.each_with_index do |notify, i|
|
15
|
+
notify.stub(:message_for_sending).and_return("message-#{i}")
|
16
|
+
notify.should_receive(:sent_at=).with(instance_of(Time))
|
17
|
+
notify.should_receive(:save)
|
18
|
+
end
|
19
|
+
|
20
|
+
APN::App.should_receive(:all).once.and_return([app])
|
21
21
|
app.should_receive(:cert).twice.and_return(app.apn_dev_cert)
|
22
22
|
|
23
|
+
APN::Device.should_receive(:find_each).twice.and_yield(device)
|
24
|
+
|
25
|
+
device.should_receive(:unsent_notifications).and_return(notifications,[])
|
26
|
+
|
27
|
+
|
23
28
|
ssl_mock = mock('ssl_mock')
|
24
29
|
ssl_mock.should_receive(:write).with('message-0')
|
25
30
|
ssl_mock.should_receive(:write).with('message-1')
|
26
|
-
APN::Connection.should_receive(:open_for_delivery).and_yield(ssl_mock, nil)
|
27
|
-
|
31
|
+
APN::Connection.should_receive(:open_for_delivery).twice.and_yield(ssl_mock, nil)
|
28
32
|
APN::App.send_notifications
|
29
33
|
|
30
34
|
end
|
31
35
|
|
32
36
|
end
|
33
37
|
|
38
|
+
describe 'send_notifications_not_associated_with_an_app' do
|
39
|
+
|
40
|
+
it 'should send unsent notifications that are associated with devices that are not with any app' do
|
41
|
+
RAILS_ENV = 'staging'
|
42
|
+
device = DeviceFactory.create
|
43
|
+
device.app_id = nil
|
44
|
+
device.save
|
45
|
+
APN::App.all.each { |a| a.destroy }
|
46
|
+
notifications = [NotificationFactory.create({:device_id => device.id}),
|
47
|
+
NotificationFactory.create({:device_id => device.id})]
|
48
|
+
|
49
|
+
notifications.each_with_index do |notify, i|
|
50
|
+
notify.stub(:message_for_sending).and_return("message-#{i}")
|
51
|
+
notify.should_receive(:sent_at=).with(instance_of(Time))
|
52
|
+
notify.should_receive(:save)
|
53
|
+
end
|
54
|
+
|
55
|
+
APN::Device.should_receive(:find_each).and_yield(device)
|
56
|
+
device.should_receive(:unsent_notifications).and_return(notifications)
|
57
|
+
|
58
|
+
ssl_mock = mock('ssl_mock')
|
59
|
+
ssl_mock.should_receive(:write).with('message-0')
|
60
|
+
ssl_mock.should_receive(:write).with('message-1')
|
61
|
+
APN::Connection.should_receive(:open_for_delivery).and_yield(ssl_mock, nil)
|
62
|
+
APN::App.send_notifications
|
63
|
+
end
|
64
|
+
end
|
65
|
+
|
34
66
|
describe 'send_group_notifications' do
|
35
67
|
|
36
68
|
it 'should send the unsent group notifications' do
|
@@ -133,7 +165,12 @@ describe APN::App do
|
|
133
165
|
app = AppFactory.create
|
134
166
|
devices = [DeviceFactory.create(:app_id => app.id, :last_registered_at => 1.week.ago, :feedback_at => Time.now),
|
135
167
|
DeviceFactory.create(:app_id => app.id, :last_registered_at => 1.week.from_now, :feedback_at => Time.now)]
|
136
|
-
|
168
|
+
puts "device ids are #{devices[0].id} and #{devices[1].id}"
|
169
|
+
devices[0].last_registered_at = 1.week.ago
|
170
|
+
devices[0].save
|
171
|
+
devices[1].last_registered_at = 1.week.from_now
|
172
|
+
devices[1].save
|
173
|
+
APN::Feedback.should_receive(:devices).twice.and_return(devices)
|
137
174
|
APN::App.should_receive(:all).and_return([app])
|
138
175
|
app.should_receive(:cert).twice.and_return(app.apn_dev_cert)
|
139
176
|
lambda {
|
@@ -143,6 +180,21 @@ describe APN::App do
|
|
143
180
|
|
144
181
|
end
|
145
182
|
|
183
|
+
describe 'process_devices for global app' do
|
184
|
+
|
185
|
+
it 'should destroy devices that have a last_registered_at date that is before the feedback_at date that have no app' do
|
186
|
+
device = DeviceFactory.create(:app_id => nil, :last_registered_at => 1.week.ago, :feedback_at => Time.now)
|
187
|
+
device.app_id = nil
|
188
|
+
device.last_registered_at = 1.week.ago
|
189
|
+
device.save
|
190
|
+
APN::Feedback.should_receive(:devices).and_return([device])
|
191
|
+
APN::App.should_receive(:all).and_return([])
|
192
|
+
lambda {
|
193
|
+
APN::App.process_devices
|
194
|
+
}.should change(APN::Device, :count).by(-1)
|
195
|
+
end
|
196
|
+
end
|
197
|
+
|
146
198
|
describe 'nil cert when processing devices' do
|
147
199
|
|
148
200
|
it 'should raise an exception for processing devices for an app with no cert' do
|
@@ -40,19 +40,19 @@ describe APN::Device do
|
|
40
40
|
|
41
41
|
end
|
42
42
|
|
43
|
-
describe '
|
43
|
+
describe 'before_create' do
|
44
44
|
|
45
|
-
it 'should set the last_registered_at date to Time.now
|
45
|
+
it 'should set the last_registered_at date to Time.now' do
|
46
46
|
time = Time.now
|
47
47
|
Time.stub(:now).and_return(time)
|
48
48
|
device = DeviceFactory.create
|
49
49
|
device.last_registered_at.should_not be_nil
|
50
50
|
device.last_registered_at.to_s.should == time.to_s
|
51
51
|
|
52
|
-
ago = 1.week.ago
|
53
|
-
device = DeviceFactory.create(:last_registered_at => ago)
|
54
|
-
device.last_registered_at.should_not be_nil
|
55
|
-
device.last_registered_at.to_s.should == ago.to_s
|
52
|
+
# ago = 1.week.ago
|
53
|
+
# device = DeviceFactory.create(:last_registered_at => ago)
|
54
|
+
# device.last_registered_at.should_not be_nil
|
55
|
+
# device.last_registered_at.to_s.should == ago.to_s
|
56
56
|
end
|
57
57
|
|
58
58
|
end
|
metadata
CHANGED
@@ -1,13 +1,13 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: apn_on_rails
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
hash:
|
4
|
+
hash: 13
|
5
5
|
prerelease: false
|
6
6
|
segments:
|
7
7
|
- 0
|
8
8
|
- 4
|
9
|
-
-
|
10
|
-
version: 0.4.
|
9
|
+
- 1
|
10
|
+
version: 0.4.1
|
11
11
|
platform: ruby
|
12
12
|
authors:
|
13
13
|
- markbates
|
@@ -16,14 +16,13 @@ autorequire:
|
|
16
16
|
bindir: bin
|
17
17
|
cert_chain: []
|
18
18
|
|
19
|
-
date: 2010-
|
19
|
+
date: 2010-11-09 00:00:00 -05:00
|
20
20
|
default_executable:
|
21
21
|
dependencies:
|
22
22
|
- !ruby/object:Gem::Dependency
|
23
|
-
type: :runtime
|
24
|
-
prerelease: false
|
25
23
|
name: configatron
|
26
|
-
|
24
|
+
prerelease: false
|
25
|
+
requirement: &id001 !ruby/object:Gem::Requirement
|
27
26
|
none: false
|
28
27
|
requirements:
|
29
28
|
- - ">="
|
@@ -32,12 +31,12 @@ dependencies:
|
|
32
31
|
segments:
|
33
32
|
- 0
|
34
33
|
version: "0"
|
35
|
-
|
34
|
+
type: :runtime
|
35
|
+
version_requirements: *id001
|
36
36
|
- !ruby/object:Gem::Dependency
|
37
|
-
|
37
|
+
name: autotest
|
38
38
|
prerelease: false
|
39
|
-
|
40
|
-
version_requirements: &id002 !ruby/object:Gem::Requirement
|
39
|
+
requirement: &id002 !ruby/object:Gem::Requirement
|
41
40
|
none: false
|
42
41
|
requirements:
|
43
42
|
- - ">="
|
@@ -46,30 +45,42 @@ dependencies:
|
|
46
45
|
segments:
|
47
46
|
- 0
|
48
47
|
version: "0"
|
49
|
-
requirement: *id002
|
50
|
-
- !ruby/object:Gem::Dependency
|
51
48
|
type: :development
|
49
|
+
version_requirements: *id002
|
50
|
+
- !ruby/object:Gem::Dependency
|
51
|
+
name: sqlite3-ruby
|
52
52
|
prerelease: false
|
53
|
+
requirement: &id003 !ruby/object:Gem::Requirement
|
54
|
+
none: false
|
55
|
+
requirements:
|
56
|
+
- - ">="
|
57
|
+
- !ruby/object:Gem::Version
|
58
|
+
hash: 3
|
59
|
+
segments:
|
60
|
+
- 0
|
61
|
+
version: "0"
|
62
|
+
type: :development
|
63
|
+
version_requirements: *id003
|
64
|
+
- !ruby/object:Gem::Dependency
|
53
65
|
name: rspec
|
54
|
-
|
66
|
+
prerelease: false
|
67
|
+
requirement: &id004 !ruby/object:Gem::Requirement
|
55
68
|
none: false
|
56
69
|
requirements:
|
57
70
|
- - ">="
|
58
71
|
- !ruby/object:Gem::Version
|
59
|
-
hash:
|
72
|
+
hash: 15
|
60
73
|
segments:
|
61
74
|
- 2
|
62
75
|
- 0
|
63
76
|
- 0
|
64
|
-
|
65
|
-
- 19
|
66
|
-
version: 2.0.0.beta.19
|
67
|
-
requirement: *id003
|
68
|
-
- !ruby/object:Gem::Dependency
|
77
|
+
version: 2.0.0
|
69
78
|
type: :development
|
70
|
-
|
79
|
+
version_requirements: *id004
|
80
|
+
- !ruby/object:Gem::Dependency
|
71
81
|
name: bundler
|
72
|
-
|
82
|
+
prerelease: false
|
83
|
+
requirement: &id005 !ruby/object:Gem::Requirement
|
73
84
|
none: false
|
74
85
|
requirements:
|
75
86
|
- - ">="
|
@@ -82,12 +93,12 @@ dependencies:
|
|
82
93
|
- rc
|
83
94
|
- 5
|
84
95
|
version: 1.0.0.rc.5
|
85
|
-
requirement: *id004
|
86
|
-
- !ruby/object:Gem::Dependency
|
87
96
|
type: :development
|
88
|
-
|
97
|
+
version_requirements: *id005
|
98
|
+
- !ruby/object:Gem::Dependency
|
89
99
|
name: jeweler
|
90
|
-
|
100
|
+
prerelease: false
|
101
|
+
requirement: &id006 !ruby/object:Gem::Requirement
|
91
102
|
none: false
|
92
103
|
requirements:
|
93
104
|
- - ~>
|
@@ -99,12 +110,12 @@ dependencies:
|
|
99
110
|
- 0
|
100
111
|
- pre2
|
101
112
|
version: 1.5.0.pre2
|
102
|
-
requirement: *id005
|
103
|
-
- !ruby/object:Gem::Dependency
|
104
113
|
type: :development
|
105
|
-
|
114
|
+
version_requirements: *id006
|
115
|
+
- !ruby/object:Gem::Dependency
|
106
116
|
name: rcov
|
107
|
-
|
117
|
+
prerelease: false
|
118
|
+
requirement: &id007 !ruby/object:Gem::Requirement
|
108
119
|
none: false
|
109
120
|
requirements:
|
110
121
|
- - ">="
|
@@ -113,12 +124,12 @@ dependencies:
|
|
113
124
|
segments:
|
114
125
|
- 0
|
115
126
|
version: "0"
|
116
|
-
requirement: *id006
|
117
|
-
- !ruby/object:Gem::Dependency
|
118
127
|
type: :development
|
119
|
-
|
128
|
+
version_requirements: *id007
|
129
|
+
- !ruby/object:Gem::Dependency
|
120
130
|
name: actionpack
|
121
|
-
|
131
|
+
prerelease: false
|
132
|
+
requirement: &id008 !ruby/object:Gem::Requirement
|
122
133
|
none: false
|
123
134
|
requirements:
|
124
135
|
- - ~>
|
@@ -129,12 +140,12 @@ dependencies:
|
|
129
140
|
- 3
|
130
141
|
- 8
|
131
142
|
version: 2.3.8
|
132
|
-
requirement: *id007
|
133
|
-
- !ruby/object:Gem::Dependency
|
134
143
|
type: :development
|
135
|
-
|
144
|
+
version_requirements: *id008
|
145
|
+
- !ruby/object:Gem::Dependency
|
136
146
|
name: activerecord
|
137
|
-
|
147
|
+
prerelease: false
|
148
|
+
requirement: &id009 !ruby/object:Gem::Requirement
|
138
149
|
none: false
|
139
150
|
requirements:
|
140
151
|
- - ~>
|
@@ -145,7 +156,8 @@ dependencies:
|
|
145
156
|
- 3
|
146
157
|
- 8
|
147
158
|
version: 2.3.8
|
148
|
-
|
159
|
+
type: :development
|
160
|
+
version_requirements: *id009
|
149
161
|
description: |
|
150
162
|
APN on Rails is a Ruby on Rails gem that allows you to
|
151
163
|
easily add Apple Push Notification (iPhone) support to your Rails application.
|
@@ -171,6 +183,7 @@ files:
|
|
171
183
|
- Rakefile
|
172
184
|
- VERSION
|
173
185
|
- apn_on_rails.gemspec
|
186
|
+
- autotest/discover.rb
|
174
187
|
- generators/apn_migrations_generator.rb
|
175
188
|
- generators/templates/apn_migrations/001_create_apn_devices.rb
|
176
189
|
- generators/templates/apn_migrations/002_create_apn_notifications.rb
|
@@ -181,6 +194,8 @@ files:
|
|
181
194
|
- generators/templates/apn_migrations/007_create_device_groups.rb
|
182
195
|
- generators/templates/apn_migrations/008_create_apn_group_notifications.rb
|
183
196
|
- generators/templates/apn_migrations/009_create_pull_notifications.rb
|
197
|
+
- generators/templates/apn_migrations/010_alter_apn_notifications.rb
|
198
|
+
- generators/templates/apn_migrations/011_make_device_token_index_nonunique.rb
|
184
199
|
- lib/apn_on_rails.rb
|
185
200
|
- lib/apn_on_rails/apn_on_rails.rb
|
186
201
|
- lib/apn_on_rails/app/models/apn/app.rb
|