rapns_rails_2 3.4.3

Sign up to get free protection for your applications and to get access to all the features.
Files changed (113) hide show
  1. checksums.yaml +15 -0
  2. data/CHANGELOG.md +83 -0
  3. data/LICENSE +7 -0
  4. data/README.md +168 -0
  5. data/bin/rapns +37 -0
  6. data/config/database.yml +44 -0
  7. data/lib/generators/rapns_generator.rb +25 -0
  8. data/lib/generators/templates/add_alert_is_json_to_rapns_notifications.rb +9 -0
  9. data/lib/generators/templates/add_app_to_rapns.rb +11 -0
  10. data/lib/generators/templates/add_gcm.rb +95 -0
  11. data/lib/generators/templates/create_rapns_apps.rb +16 -0
  12. data/lib/generators/templates/create_rapns_feedback.rb +15 -0
  13. data/lib/generators/templates/create_rapns_notifications.rb +26 -0
  14. data/lib/generators/templates/rapns.rb +87 -0
  15. data/lib/rapns/TODO +3 -0
  16. data/lib/rapns/apns/app.rb +25 -0
  17. data/lib/rapns/apns/binary_notification_validator.rb +12 -0
  18. data/lib/rapns/apns/device_token_format_validator.rb +12 -0
  19. data/lib/rapns/apns/feedback.rb +16 -0
  20. data/lib/rapns/apns/notification.rb +91 -0
  21. data/lib/rapns/apns_feedback.rb +13 -0
  22. data/lib/rapns/app.rb +16 -0
  23. data/lib/rapns/configuration.rb +89 -0
  24. data/lib/rapns/daemon/apns/app_runner.rb +26 -0
  25. data/lib/rapns/daemon/apns/certificate_expired_error.rb +20 -0
  26. data/lib/rapns/daemon/apns/connection.rb +142 -0
  27. data/lib/rapns/daemon/apns/delivery.rb +64 -0
  28. data/lib/rapns/daemon/apns/delivery_handler.rb +35 -0
  29. data/lib/rapns/daemon/apns/disconnection_error.rb +20 -0
  30. data/lib/rapns/daemon/apns/feedback_receiver.rb +89 -0
  31. data/lib/rapns/daemon/app_runner.rb +179 -0
  32. data/lib/rapns/daemon/batch.rb +112 -0
  33. data/lib/rapns/daemon/delivery.rb +23 -0
  34. data/lib/rapns/daemon/delivery_error.rb +19 -0
  35. data/lib/rapns/daemon/delivery_handler.rb +52 -0
  36. data/lib/rapns/daemon/delivery_handler_collection.rb +33 -0
  37. data/lib/rapns/daemon/feeder.rb +65 -0
  38. data/lib/rapns/daemon/gcm/app_runner.rb +13 -0
  39. data/lib/rapns/daemon/gcm/delivery.rb +228 -0
  40. data/lib/rapns/daemon/gcm/delivery_handler.rb +20 -0
  41. data/lib/rapns/daemon/interruptible_sleep.rb +65 -0
  42. data/lib/rapns/daemon/reflectable.rb +13 -0
  43. data/lib/rapns/daemon/store/active_record/reconnectable.rb +66 -0
  44. data/lib/rapns/daemon/store/active_record.rb +128 -0
  45. data/lib/rapns/daemon.rb +129 -0
  46. data/lib/rapns/deprecatable.rb +23 -0
  47. data/lib/rapns/deprecation.rb +23 -0
  48. data/lib/rapns/embed.rb +28 -0
  49. data/lib/rapns/gcm/app.rb +7 -0
  50. data/lib/rapns/gcm/expiry_collapse_key_mutual_inclusion_validator.rb +11 -0
  51. data/lib/rapns/gcm/notification.rb +37 -0
  52. data/lib/rapns/gcm/payload_data_size_validator.rb +13 -0
  53. data/lib/rapns/gcm/registration_ids_count_validator.rb +13 -0
  54. data/lib/rapns/logger.rb +76 -0
  55. data/lib/rapns/multi_json_helper.rb +16 -0
  56. data/lib/rapns/notification.rb +62 -0
  57. data/lib/rapns/notifier.rb +35 -0
  58. data/lib/rapns/push.rb +17 -0
  59. data/lib/rapns/rails-2-compatibility.rb +34 -0
  60. data/lib/rapns/reflection.rb +44 -0
  61. data/lib/rapns/upgraded.rb +31 -0
  62. data/lib/rapns/version.rb +3 -0
  63. data/lib/rapns_rails_2.rb +67 -0
  64. data/lib/tasks/cane.rake +18 -0
  65. data/lib/tasks/test.rake +38 -0
  66. data/spec/support/cert_with_password.pem +90 -0
  67. data/spec/support/cert_without_password.pem +59 -0
  68. data/spec/support/simplecov_helper.rb +13 -0
  69. data/spec/support/simplecov_quality_formatter.rb +8 -0
  70. data/spec/tmp/.gitkeep +0 -0
  71. data/spec/unit/apns/app_spec.rb +29 -0
  72. data/spec/unit/apns/feedback_spec.rb +9 -0
  73. data/spec/unit/apns/notification_spec.rb +215 -0
  74. data/spec/unit/apns_feedback_spec.rb +21 -0
  75. data/spec/unit/app_spec.rb +16 -0
  76. data/spec/unit/configuration_spec.rb +55 -0
  77. data/spec/unit/daemon/apns/app_runner_spec.rb +45 -0
  78. data/spec/unit/daemon/apns/certificate_expired_error_spec.rb +11 -0
  79. data/spec/unit/daemon/apns/connection_spec.rb +287 -0
  80. data/spec/unit/daemon/apns/delivery_handler_spec.rb +59 -0
  81. data/spec/unit/daemon/apns/delivery_spec.rb +101 -0
  82. data/spec/unit/daemon/apns/disconnection_error_spec.rb +18 -0
  83. data/spec/unit/daemon/apns/feedback_receiver_spec.rb +134 -0
  84. data/spec/unit/daemon/app_runner_shared.rb +83 -0
  85. data/spec/unit/daemon/app_runner_spec.rb +170 -0
  86. data/spec/unit/daemon/batch_spec.rb +219 -0
  87. data/spec/unit/daemon/delivery_error_spec.rb +13 -0
  88. data/spec/unit/daemon/delivery_handler_collection_spec.rb +37 -0
  89. data/spec/unit/daemon/delivery_handler_shared.rb +45 -0
  90. data/spec/unit/daemon/feeder_spec.rb +81 -0
  91. data/spec/unit/daemon/gcm/app_runner_spec.rb +19 -0
  92. data/spec/unit/daemon/gcm/delivery_handler_spec.rb +44 -0
  93. data/spec/unit/daemon/gcm/delivery_spec.rb +289 -0
  94. data/spec/unit/daemon/interruptible_sleep_spec.rb +68 -0
  95. data/spec/unit/daemon/reflectable_spec.rb +27 -0
  96. data/spec/unit/daemon/store/active_record/reconnectable_spec.rb +114 -0
  97. data/spec/unit/daemon/store/active_record_spec.rb +281 -0
  98. data/spec/unit/daemon_spec.rb +157 -0
  99. data/spec/unit/deprecatable_spec.rb +32 -0
  100. data/spec/unit/deprecation_spec.rb +15 -0
  101. data/spec/unit/embed_spec.rb +50 -0
  102. data/spec/unit/gcm/app_spec.rb +4 -0
  103. data/spec/unit/gcm/notification_spec.rb +52 -0
  104. data/spec/unit/logger_spec.rb +180 -0
  105. data/spec/unit/notification_shared.rb +45 -0
  106. data/spec/unit/notification_spec.rb +4 -0
  107. data/spec/unit/notifier_spec.rb +32 -0
  108. data/spec/unit/push_spec.rb +44 -0
  109. data/spec/unit/rapns_spec.rb +9 -0
  110. data/spec/unit/reflection_spec.rb +30 -0
  111. data/spec/unit/upgraded_spec.rb +40 -0
  112. data/spec/unit_spec_helper.rb +137 -0
  113. metadata +232 -0
checksums.yaml ADDED
@@ -0,0 +1,15 @@
1
+ ---
2
+ !binary "U0hBMQ==":
3
+ metadata.gz: !binary |-
4
+ ODdlNDhlOTIzODkyMDZiODdiNzIwYjAyNDJlNjkzZDYyMmYyZDhjNQ==
5
+ data.tar.gz: !binary |-
6
+ NDlhMWY3NGRmOTUwMmQ1NGRjMjg2MjE2ZDY5NmYwNWE5NjgyZWM1MA==
7
+ !binary "U0hBNTEy":
8
+ metadata.gz: !binary |-
9
+ MTkzNDAxZTZmNWM4YTg3OTEzYWJhM2Q1YmE3MzBhZjg0YjUxYWJmMjAwYWMz
10
+ NGZmMGM0Mzk4MDM1MGU3OTFjZWVlNThhZTg1MDhiMmRmNDFhZjk3ZjcxYTA4
11
+ OTllMzFjM2NkZWRmYmVhZTlmOTkwYzlhMGI3NmVkZjQ1NjRiMTE=
12
+ data.tar.gz: !binary |-
13
+ YzQ3ZmMzMzU1MzFmYzczZGI4M2FlYWRjMTY3Y2NmNmJlOTY5Y2UxMWNhODUz
14
+ NTlmY2QwNTEyMmM0MWVkNGExNGJiNjdlYmViNjY3MzkyOWFhM2M3ZWUwY2Jm
15
+ M2Q0ODNlNmJiMmU1MDI2Mjc3ZGIzYjE1ZWQ1YjgxZmZiNGY3MzU=
data/CHANGELOG.md ADDED
@@ -0,0 +1,83 @@
1
+ ## 3.4.2 (unreleased)
2
+ * Fix sqlite3 support (#160).
3
+
4
+ ## 3.4.1 (Aug 30, 2013)
5
+ * Silence unintended airbrake_notify deprecation warning (#158).
6
+ * Add :dependent => :destroy to app notifications (#156).
7
+
8
+ ## 3.4.0 (Aug 28, 2013)
9
+ * Rails 4 support.
10
+ * Add apns_certificate_will_expire reflection.
11
+ * Perform storage update in batches where possible, to increase throughput.
12
+ * airbrake_notify is now deprecated, use the Reflection API instead.
13
+ * Fix calling the notification_delivered reflection twice (#149).
14
+
15
+ ## 3.3.2 (June 30, 2013)
16
+ * Fix Rails 3.0.x compatibility (#138) (@yoppi).
17
+ * Ensure Rails does not set a default value for text columns (#137).
18
+ * Fix error in down action for add_gcm migration (#135) (@alexperto).
19
+
20
+ ## 3.3.1 (June 2, 2013)
21
+ * Fix compatibility with postgres_ext (#104).
22
+ * Add ability to switch the logger (@maxsz).
23
+ * Do not validate presence of alert, badge or sound - not actually required by the APNs (#129) (@wilg).
24
+ * Catch IOError from an APNs connection. (@maxsz).
25
+ * Allow nested hashes in APNs notification attributes (@perezda).
26
+
27
+ ## 3.3.0 (April 21, 2013)
28
+ * GCM: collapse_key is no longer required to set expiry (time_to_live).
29
+ * Add reflection for GCM canonical IDs.
30
+ * Add Rapns::Daemon.store to decouple storage backend.
31
+
32
+ ## 3.2.0 (Apr 1, 2013)
33
+ * Rapns.apns_feedback for one time feedback retrieval. Rapns.push no longer checks for feedback (#117, #105).
34
+ * Lazily connect to the APNs only when a notification is to be delivered (#111).
35
+ * Ensure all notifications are sent when using Rapns.push (#107).
36
+ * Fix issue with running Rapns.push more than once in the same process (#106).
37
+
38
+ ## 3.1.0 (Jan 26, 2013)
39
+ * Rapns.reflect API for fine-grained introspection.
40
+ * Rapns.embed API for embedding Rapns into an existing process.
41
+ * Rapns.push API for using Rapns in scheduled jobs.
42
+ * Fix issue with integration with ActiveScaffold (#98) (@jeffarena).
43
+ * Fix content-available setter for APNs (#95) (@dup2).
44
+ * GCM validation fixes (#96) (@DianthuDia).
45
+
46
+ ## 3.0.1 (Dec 16, 2012)
47
+ * Fix compatibility with Rails 3.0.x. Fixes #89.
48
+
49
+ ## 3.0.0 (Dec 15, 2012)
50
+ * Add support for Google Cloud Messaging.
51
+ * Fix Heroku logging issue.
52
+
53
+ ## 2.0.5 (Nov 4, 2012) ##
54
+ * Support content-available (#68).
55
+ * Append to log files.
56
+ * Fire a callback when Feedback is received.
57
+
58
+ ## 2.0.5.rc1 (Oct 5, 2012) ##
59
+ * Release db connections back into the pool after use (#72).
60
+ * Continue to start daemon if a connection cannot be made during startup (#62) (@mattconnolly).
61
+
62
+ ## 2.0.4 (Aug 6, 2012) ##
63
+ * Don't exit when there aren't any Rapns::App instances, just warn (#55).
64
+
65
+ ## 2.0.3 (July 26, 2012) ##
66
+ * JRuby support.
67
+ * Explicitly list all attributes instead of calling column_names (#53).
68
+
69
+ ## 2.0.2 (July 25, 2012) ##
70
+ * Support MultiJson < 1.3.0.
71
+ * Make all model attributes accessible.
72
+
73
+ ## 2.0.1 (July 7, 2012) ##
74
+ * Fix delivery when using Ruby 1.8.
75
+ * MultiJson support.
76
+
77
+ ## 2.0.0 (June 19, 2012) ##
78
+
79
+ * Support for multiple apps.
80
+ * Hot Updates - add/remove apps without restart.
81
+ * MDM support.
82
+ * Removed rapns.yml in favour of command line options.
83
+ * Started the changelog!
data/LICENSE ADDED
@@ -0,0 +1,7 @@
1
+ Copyright (c) 2012 Ian Leitch
2
+
3
+ Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
4
+
5
+ The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
6
+
7
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,168 @@
1
+ [![Build Status](https://secure.travis-ci.org/ileitch/rapns.png?branch=master)](http://travis-ci.org/ileitch/rapns)
2
+ [![Code Climate](https://codeclimate.com/github/ileitch/rapns.png)](https://codeclimate.com/github/ileitch/rapns)
3
+
4
+ ### Rapns - Professional grade APNs and GCM for Ruby.
5
+
6
+ * Supports both APNs (iOS) and GCM (Google Cloud Messaging, Android).
7
+ * Seamless Rails (3, 4) integration.
8
+ * Scalable - choose the number of persistent connections for each app.
9
+ * Designed for uptime - signal -HUP to add, update apps.
10
+ * Stable - reconnects database and network connections when lost.
11
+ * Run as a daemon or inside an [existing processs](https://github.com/ileitch/rapns/wiki/Embedding-API).
12
+ * Use in a scheduler for low-workload deployments ([Push API](https://github.com/ileitch/rapns/wiki/Push-API)).
13
+ * Reflection API for fine-grained instrumentation and error handling ([Reflection API](https://github.com/ileitch/rapns/wiki/Reflection-API)).
14
+ * Works with MRI, JRuby, Rubinius 1.8 and 1.9.
15
+ * Built with love.
16
+
17
+ ### Who uses Rapns?
18
+
19
+ [GateGuru](http://gateguruapp.com) and [Desk.com](http://desk.com), among others!
20
+
21
+ *I'd love to hear if you use Rapns - @ileitch on twitter.*
22
+
23
+ ## Getting Started
24
+
25
+ Add Rapns to your Gemfile:
26
+
27
+ gem 'rapns'
28
+
29
+ Generate the migrations, rapns.yml and migrate:
30
+
31
+ rails g rapns
32
+ rake db:migrate
33
+
34
+ ## Create an App & Notification
35
+
36
+ #### APNs
37
+
38
+ If this is your first time using the APNs, you will need to generate SSL certificates. See [Generating Certificates](https://github.com/ileitch/rapns/wiki/Generating-Certificates) for instructions.
39
+
40
+ ```ruby
41
+ app = Rapns::Apns::App.new
42
+ app.name = "ios_app"
43
+ app.certificate = File.read("/path/to/sandbox.pem")
44
+ app.environment = "sandbox" # APNs environment.
45
+ app.password = "certificate password"
46
+ app.connections = 1
47
+ app.save!
48
+ ```
49
+
50
+ ```ruby
51
+ n = Rapns::Apns::Notification.new
52
+ n.app = Rapns::Apns::App.find_by_name("ios_app")
53
+ n.device_token = "..."
54
+ n.alert = "hi mom!"
55
+ n.attributes_for_device = {:foo => :bar}
56
+ n.save!
57
+ ```
58
+
59
+ You should also implement the [apns_certificate_will_expire](https://github.com/ileitch/rapns/wiki/Reflection-API) reflection to monitor when your certificate is due to expire.
60
+
61
+ #### GCM
62
+
63
+ ```ruby
64
+ app = Rapns::Gcm::App.new
65
+ app.name = "android_app"
66
+ app.auth_key = "..."
67
+ app.connections = 1
68
+ app.save!
69
+ ```
70
+
71
+ ```ruby
72
+ n = Rapns::Gcm::Notification.new
73
+ n.app = Rapns::Gcm::App.find_by_name("android_app")
74
+ n.registration_ids = ["..."]
75
+ n.data = {:message => "hi mom!"}
76
+ n.save!
77
+ ```
78
+
79
+ GCM also requires you to respond to [Canonical IDs](https://github.com/ileitch/rapns/wiki/Canonical-IDs).
80
+
81
+ ## Starting Rapns
82
+
83
+ As a daemon:
84
+
85
+ cd /path/to/rails/app
86
+ rapns <Rails environment> [options]
87
+
88
+ Inside an existing process (see [Embedding API](https://github.com/ileitch/rapns/wiki/Embedding-API)):
89
+
90
+ ```ruby
91
+ Rapns.embed
92
+ ```
93
+
94
+ *Please note that only ever a single instance of Rapns should be running.*
95
+
96
+ In a scheduler (see [Push API](https://github.com/ileitch/rapns/wiki/Push-API)):
97
+
98
+ ```ruby
99
+ Rapns.push
100
+ Rapns.apns_feedback
101
+ ```
102
+
103
+ See [Configuration](https://github.com/ileitch/rapns/wiki/Configuration) for a list of options, or run `rapns --help`.
104
+
105
+ ## Updating Rapns
106
+
107
+ After updating you should run `rails g rapns` to check for any new migrations.
108
+
109
+ ## Wiki
110
+
111
+ ### General
112
+ * [Configuration](https://github.com/ileitch/rapns/wiki/Configuration)
113
+ * [Upgrading from 2.x to 3.0](https://github.com/ileitch/rapns/wiki/Upgrading-from-version-2.x-to-3.0)
114
+ * [Deploying to Heroku](https://github.com/ileitch/rapns/wiki/Heroku)
115
+ * [Hot App Updates](https://github.com/ileitch/rapns/wiki/Hot-App-Updates)
116
+ * [Signals](https://github.com/ileitch/rapns/wiki/Signals)
117
+ * [Reflection API](https://github.com/ileitch/rapns/wiki/Reflection-API)
118
+ * [Push API](https://github.com/ileitch/rapns/wiki/Push-API)
119
+ * [Embedding API](https://github.com/ileitch/rapns/wiki/Embedding-API)
120
+ * [Implementing your own storage backend](https://github.com/ileitch/rapns/wiki/Implementing-your-own-storage-backend)
121
+
122
+ ### APNs
123
+ * [Generating Certificates](https://github.com/ileitch/rapns/wiki/Generating-Certificates)
124
+ * [Advanced APNs Features](https://github.com/ileitch/rapns/wiki/Advanced-APNs-Features)
125
+ * [APNs Delivery Failure Handling](https://github.com/ileitch/rapns/wiki/APNs-Delivery-Failure-Handling)
126
+ * [Why open multiple connections to the APNs?](https://github.com/ileitch/rapns/wiki/Why-open-multiple-connections-to-the-APNs%3F)
127
+ * [Silent failures might be dropped connections](https://github.com/ileitch/rapns/wiki/Dropped-connections)
128
+
129
+ ### GCM
130
+ * [Notification Options](https://github.com/ileitch/rapns/wiki//GCM-Notification-Options)
131
+ * [Canonical IDs](https://github.com/ileitch/rapns/wiki/Canonical-IDs)
132
+ * [Delivery Failures & Retries](https://github.com/ileitch/rapns/wiki/Delivery-Failures-&-Retries)
133
+
134
+ ## Contributing
135
+
136
+ Fork as usual and go crazy!
137
+
138
+ When running specs, please note that the ActiveRecord adapter can be changed by setting the `ADAPTER` environment variable. For example: `ADAPTER=postgresql rake`.
139
+
140
+ Available adapters for testing are `mysql`, `mysql2` and `postgresql`.
141
+
142
+ Note that the database username is changed at runtime to be the currently logged in user's name. So if you're testing
143
+ with mysql and you're using a user named 'bob', you will need to grant a mysql user 'bob' access to the 'rapns_test'
144
+ mysql database.
145
+
146
+ ### Contributors
147
+
148
+ Thank you to the following wonderful people for contributing:
149
+
150
+ * [@blakewatters](https://github.com/blakewatters)
151
+ * [@forresty](https://github.com/forresty)
152
+ * [@sjmadsen](https://github.com/sjmadsen)
153
+ * [@ivanyv](https://github.com/ivanyv)
154
+ * [@taybenlor](https://github.com/taybenlor)
155
+ * [@tompesman](https://github.com/tompesman)
156
+ * [@EpicDraws](https://github.com/EpicDraws)
157
+ * [@dei79](https://github.com/dei79)
158
+ * [@adorr](https://github.com/adorr)
159
+ * [@mattconnolly](https://github.com/mattconnolly)
160
+ * [@emeitch](https://github.com/emeitch)
161
+ * [@jeffarena](https://github.com/jeffarena)
162
+ * [@DianthuDia](https://github.com/DianthuDia)
163
+ * [@dup2](https://github.com/dup2)
164
+ * [@maxsz](https://github.com/maxsz)
165
+ * [@wilg](https://github.com/wilg)
166
+ * [@perezda](https://github.com/perezda)
167
+ * [@alexperto](https://github.com/alexperto)
168
+ * [@yoppi](https://github.com/yoppi)
data/bin/rapns ADDED
@@ -0,0 +1,37 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require 'optparse'
4
+ require 'rapns_rails_2'
5
+
6
+ environment = ARGV[0]
7
+
8
+ config = Rapns::ConfigurationWithoutDefaults.new
9
+
10
+ options = ARGV.options do |opts|
11
+ opts.banner = 'Usage: rapns <Rails environment> [options]'
12
+ opts.on('-f', '--foreground', 'Run in the foreground.') { config.foreground = true }
13
+ opts.on('-P N', '--db-poll N', Integer, "Frequency in seconds to check for new notifications.") { |n| config.push_poll = n }
14
+ opts.on('-F N', '--feedback-poll N', Integer, "Frequency in seconds to check for feedback.") { |n| config.feedback_poll = n }
15
+ opts.on('-e', '--no-error-checks', 'Disable APNs error checking after notification delivery.') { config.check_for_errors = false }
16
+ opts.on('-n', '--no-airbrake-notify', 'Disables error notifications via Airbrake.') { config.airbrake_notify = false }
17
+ opts.on('-p PATH', '--pid-file PATH', String, 'Path to write PID file. Relative to Rails root unless absolute.') { |path| config.pid_file = path }
18
+ opts.on('-b N', '--batch-size N', Integer, 'Storage backend notification batch size.') { |n| config.batch_size = n }
19
+ opts.on('-B', '--[no-]batch-storage-updates', 'Perform storage updates in batches.') { |v| config.batch_storage_updates = v }
20
+ opts.on('-v', '--version', 'Print the version.') { puts "rapns #{Rapns::VERSION}"; exit }
21
+ opts.on('-h', '--help', 'You\'re looking at it.') { puts opts; exit }
22
+ end
23
+
24
+ if environment.nil? || environment =~ /^-/
25
+ puts options.to_s
26
+ exit 1
27
+ end
28
+
29
+ options.parse!
30
+
31
+ ENV['RAILS_ENV'] = environment
32
+ load 'config/environment.rb'
33
+ load 'config/initializers/rapns.rb' if File.exist?('config/initializers/rapns.rb')
34
+
35
+ Rapns.config.update(config)
36
+ Rapns.require_for_daemon
37
+ Rapns::Daemon.start
@@ -0,0 +1,44 @@
1
+ # postgresql is the default if no ADAPTER environment variable is set when running specs.
2
+
3
+ postgresql:
4
+ adapter: postgresql
5
+ database: rapns_test
6
+ host: localhost
7
+ username: postgres
8
+ password: ""
9
+
10
+ jdbcpostgresql:
11
+ adapter: jdbcpostgresql
12
+ database: rapns_test
13
+ host: localhost
14
+ username: postgres
15
+ password: ""
16
+
17
+ mysql2:
18
+ adapter: mysql
19
+ database: rapns_test
20
+ host: localhost
21
+ username: rapns_test
22
+ password: ""
23
+ encoding: utf8
24
+
25
+ jdbcmysql:
26
+ adapter: jdbcmysql
27
+ database: rapns_test
28
+ host: localhost
29
+ username: rapns_test
30
+ password: ""
31
+ encoding: utf8
32
+
33
+ jdbch2:
34
+ adapter: h2
35
+ url: jdbc:h2:file:/tmp/rapns_test;AUTO_SERVER=TRUE
36
+ username: rapns_test
37
+ password: ""
38
+ pool: 128
39
+ timeout: 5000
40
+ encoding: utf8
41
+
42
+ sqlite3:
43
+ adapter: sqlite3
44
+ database: spec/tmp/rapns_test.sqlite3
@@ -0,0 +1,25 @@
1
+ class RapnsGenerator < Rails::Generator::Base
2
+
3
+ def manifest
4
+ record do |m|
5
+
6
+ puts m.class
7
+
8
+ m.file 'rapns.rb', 'config/initializers/rapns.rb'
9
+
10
+ create_migration m, "create_rapns_notifications"
11
+ create_migration m, "create_rapns_feedback"
12
+ create_migration m, "add_alert_is_json_to_rapns_notifications"
13
+ create_migration m, "add_app_to_rapns"
14
+ create_migration m, "create_rapns_apps"
15
+ create_migration m, "add_gcm"
16
+
17
+ end
18
+
19
+ end
20
+
21
+ def create_migration(m, filename)
22
+ m.migration_template "#{filename}.rb", "db/migrate", :migration_file_name => filename
23
+ end
24
+
25
+ end
@@ -0,0 +1,9 @@
1
+ class AddAlertIsJsonToRapnsNotifications < ActiveRecord::Migration
2
+ def self.up
3
+ add_column :rapns_notifications, :alert_is_json, :boolean, :null => true, :default => false
4
+ end
5
+
6
+ def self.down
7
+ remove_column :rapns_notifications, :alert_is_json
8
+ end
9
+ end
@@ -0,0 +1,11 @@
1
+ class AddAppToRapns < ActiveRecord::Migration
2
+ def self.up
3
+ add_column :rapns_notifications, :app, :string, :null => true
4
+ add_column :rapns_feedback, :app, :string, :null => true
5
+ end
6
+
7
+ def self.down
8
+ remove_column :rapns_notifications, :app
9
+ remove_column :rapns_feedback, :app
10
+ end
11
+ end
@@ -0,0 +1,95 @@
1
+ class AddGcm < ActiveRecord::Migration
2
+ module Rapns
3
+ class App < ActiveRecord::Base
4
+ self.table_name = 'rapns_apps'
5
+ end
6
+
7
+ class Notification < ActiveRecord::Base
8
+ belongs_to :app
9
+ self.table_name = 'rapns_notifications'
10
+ end
11
+ end
12
+
13
+ def self.up
14
+ add_column :rapns_notifications, :type, :string, :null => true
15
+ add_column :rapns_apps, :type, :string, :null => true
16
+
17
+ AddGcm::Rapns::Notification.update_all :type => 'Rapns::Apns::Notification'
18
+ AddGcm::Rapns::App.update_all :type => 'Rapns::Apns::App'
19
+
20
+ change_column :rapns_notifications, :type, :string, :null => false
21
+ change_column :rapns_apps, :type, :string, :null => false
22
+ change_column :rapns_notifications, :device_token, :string, { :null => true, :limit => 64 }
23
+ change_column :rapns_notifications, :expiry, :integer, { :null => true, :default => 1.day.to_i }
24
+ change_column :rapns_apps, :environment, :string, :null => true
25
+ change_column :rapns_apps, :certificate, :text, :null => true, :default => nil
26
+
27
+ change_column :rapns_notifications, :error_description, :text, :null => true, :default => nil
28
+ change_column :rapns_notifications, :sound, :string, :default => 'default'
29
+
30
+ rename_column :rapns_notifications, :attributes_for_device, :data
31
+ rename_column :rapns_apps, :key, :name
32
+
33
+ add_column :rapns_apps, :auth_key, :string, :null => true
34
+
35
+ add_column :rapns_notifications, :collapse_key, :string, :null => true
36
+ add_column :rapns_notifications, :delay_while_idle, :boolean, :null => false, :default => false
37
+
38
+ reg_ids_type = ActiveRecord::Base.connection.adapter_name.include?('Mysql') ? :mediumtext : :text
39
+ add_column :rapns_notifications, :registration_ids, reg_ids_type, :null => true
40
+ add_column :rapns_notifications, :app_id, :integer, :null => true
41
+ add_column :rapns_notifications, :retries, :integer, :null => true, :default => 0
42
+
43
+ Rapns::Notification.reset_column_information
44
+ Rapns::App.reset_column_information
45
+
46
+ Rapns::App.all.each do |app|
47
+ Rapns::Notification.update_all(['app_id = ?', app.id], ['app = ?', app.name])
48
+ end
49
+
50
+ change_column :rapns_notifications, :app_id, :integer, :null => false
51
+ remove_column :rapns_notifications, :app
52
+
53
+ remove_index :rapns_notifications, :name => "index_rapns_notifications_multi"
54
+ add_index :rapns_notifications, [:app_id, :delivered, :failed, :deliver_after], :name => "index_rapns_notifications_multi"
55
+ end
56
+
57
+ def self.down
58
+ AddGcm::Rapns::Notification.deleta_all(:type => 'Rapns::Gcm::Notification')
59
+
60
+ remove_column :rapns_notifications, :type
61
+ remove_column :rapns_apps, :type
62
+
63
+ change_column :rapns_notifications, :device_token, :string, { :null => false, :limit => 64 }
64
+ change_column :rapns_notifications, :expiry, :integer, { :null => false, :default => 1.day.to_i }
65
+ change_column :rapns_apps, :environment, :string, :null => false
66
+ change_column :rapns_apps, :certificate, :text, :null => false
67
+
68
+ change_column :rapns_notifications, :error_description, :string, :null => true, :default => nil
69
+ change_column :rapns_notifications, :sound, :string, :default => '1.aiff'
70
+
71
+ rename_column :rapns_notifications, :data, :attributes_for_device
72
+ rename_column :rapns_apps, :name, :key
73
+
74
+ remove_column :rapns_apps, :auth_key
75
+
76
+ remove_column :rapns_notifications, :collapse_key
77
+ remove_column :rapns_notifications, :delay_while_idle
78
+ remove_column :rapns_notifications, :registration_ids
79
+ remove_column :rapns_notifications, :retries
80
+
81
+ add_column :rapns_notifications, :app, :string, :null => true
82
+
83
+ Rapns::Notification.reset_column_information
84
+ Rapns::App.reset_column_information
85
+
86
+ Rapns::App.all.each do |app|
87
+ Rapns::Notification.update_all(['app = ?', app.key], ['app_id = ?', app.id])
88
+ end
89
+
90
+ remove_column :rapns_notifications, :app_id
91
+
92
+ remove_index :rapns_notifications, :name => "index_rapns_notifications_multi"
93
+ add_index :rapns_notifications, [:delivered, :failed, :deliver_after], :name => "index_rapns_notifications_multi"
94
+ end
95
+ end
@@ -0,0 +1,16 @@
1
+ class CreateRapnsApps < ActiveRecord::Migration
2
+ def self.up
3
+ create_table :rapns_apps do |t|
4
+ t.string :key, :null => false
5
+ t.string :environment, :null => false
6
+ t.text :certificate, :null => false
7
+ t.string :password, :null => true
8
+ t.integer :connections, :null => false, :default => 1
9
+ t.timestamps
10
+ end
11
+ end
12
+
13
+ def self.down
14
+ drop_table :rapns_apps
15
+ end
16
+ end
@@ -0,0 +1,15 @@
1
+ class CreateRapnsFeedback < ActiveRecord::Migration
2
+ def self.up
3
+ create_table :rapns_feedback do |t|
4
+ t.string :device_token, :null => false, :limit => 64
5
+ t.timestamp :failed_at, :null => false
6
+ t.timestamps
7
+ end
8
+
9
+ add_index :rapns_feedback, :device_token
10
+ end
11
+
12
+ def self.down
13
+ drop_table :rapns_feedback
14
+ end
15
+ end
@@ -0,0 +1,26 @@
1
+ class CreateRapnsNotifications < ActiveRecord::Migration
2
+ def self.up
3
+ create_table :rapns_notifications do |t|
4
+ t.integer :badge, :null => true
5
+ t.string :device_token, :null => false, :limit => 64
6
+ t.string :sound, :null => true, :default => "1.aiff"
7
+ t.string :alert, :null => true
8
+ t.text :attributes_for_device, :null => true
9
+ t.integer :expiry, :null => false, :default => 1.day.to_i
10
+ t.boolean :delivered, :null => false, :default => false
11
+ t.timestamp :delivered_at, :null => true
12
+ t.boolean :failed, :null => false, :default => false
13
+ t.timestamp :failed_at, :null => true
14
+ t.integer :error_code, :null => true
15
+ t.string :error_description, :null => true
16
+ t.timestamp :deliver_after, :null => true
17
+ t.timestamps
18
+ end
19
+
20
+ add_index :rapns_notifications, [:delivered, :failed, :deliver_after], :name => "index_rapns_notifications_multi"
21
+ end
22
+
23
+ def self.down
24
+ drop_table :rapns_notifications
25
+ end
26
+ end
@@ -0,0 +1,87 @@
1
+ # Rapns configuration. Options set here are overridden by command-line options.
2
+
3
+ Rapns.configure do |config|
4
+
5
+ # Run in the foreground?
6
+ # config.foreground = false
7
+
8
+ # Frequency in seconds to check for new notifications.
9
+ # config.push_poll = 2
10
+
11
+ # Frequency in seconds to check for feedback
12
+ # config.feedback_poll = 60
13
+
14
+ # Disable APNs error checking after notification delivery.
15
+ # config.check_for_errors = true
16
+
17
+ # ActiveRecord notifications batch size.
18
+ # config.batch_size = 5000
19
+
20
+ # Perform updates to the storage backend in batches to reduce IO.
21
+ # config.batch_storage_updates = true
22
+
23
+ # Path to write PID file. Relative to Rails root unless absolute.
24
+ # config.pid_file = '/path/to/rapns.pid'
25
+
26
+ # Define a custom logger.
27
+ # config.logger = MyLogger.new
28
+
29
+ end
30
+
31
+ Rapns.reflect do |on|
32
+
33
+ # Called with a Rapns::Apns::Feedback instance when feedback is received
34
+ # from the APNs that a notification has failed to be delivered.
35
+ # Further notifications should not be sent to the device.
36
+ # on.apns_feedback do |feedback|
37
+ # end
38
+
39
+ # Called when a notification is queued internally for delivery.
40
+ # The internal queue for each app runner can be inspected:
41
+ #
42
+ # Rapns::Daemon::AppRunner.runners.each do |app_id, runner|
43
+ # runner.app
44
+ # runner.queue_size
45
+ # end
46
+ #
47
+ # on.notification_enqueued do |notification|
48
+ # end
49
+
50
+ # Called when a notification is successfully delivered.
51
+ # on.notification_delivered do |notification|
52
+ # end
53
+
54
+ # Called when notification delivery failed.
55
+ # Call 'error_code' and 'error_description' on the notification for the cause.
56
+ # on.notification_failed do |notification|
57
+ # end
58
+
59
+ # Called when a notification will be retried at a later date.
60
+ # Call 'deliver_after' on the notification for the next delivery date
61
+ # and 'retries' for the number of times this notification has been retried.
62
+ # on.notification_will_retry do |notification|
63
+ # end
64
+
65
+ # Called when an APNs connection is lost and will be reconnected.
66
+ # on.apns_connection_lost do |app, error|
67
+ # end
68
+
69
+ # Called when the GCM returns a canonical registration ID.
70
+ # You will need to replace old_id with canonical_id in your records.
71
+ # on.gcm_canonical_id do |old_id, canonical_id|
72
+ # end
73
+
74
+ # Called when the GCM returns a failure that indicates an invalid tegistration id.
75
+ # You will need to delete the registration_id from your records.
76
+ # on.gcm_invalid_registration_id do |app, error, registration_id|
77
+ # end
78
+
79
+ # Called when an APNs certificate will expire within 1 month.
80
+ # Implement on.error to catch errors raised when the certificate expires.
81
+ # on.apns_certificate_will_expire do |app, expiration_time|
82
+ # end
83
+
84
+ # Called when an exception is raised.
85
+ # on.error do |error|
86
+ # end
87
+ end
data/lib/rapns/TODO ADDED
@@ -0,0 +1,3 @@
1
+ * Should internal errors mark a notification as failed?
2
+ * Check cert expiry when connected.
3
+ * Lazy connect on socket write? - would allow to catch initial expiry error and mark on notification.