c2dm_on_rails 0.1.5

Sign up to get free protection for your applications and to get access to all the features.
data/CHANGELOG ADDED
@@ -0,0 +1 @@
1
+ 0.1.5 Initial release
data/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ The MIT License
2
+
3
+ Copyright (c) 2009 Julius de Bruijn, Digia Plc
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in
13
+ all copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
21
+ THE SOFTWARE.
data/Manifest ADDED
@@ -0,0 +1,17 @@
1
+ CHANGELOG
2
+ LICENSE
3
+ Manifest
4
+ README.textile
5
+ Rakefile
6
+ c2dm_on_rails.gemspec
7
+ generators/c2dm_migrations_generator.rb
8
+ generators/templates/c2dm_migrations/001_create_c2dm_devices.rb
9
+ generators/templates/c2dm_migrations/002_create_c2dm_notifications.rb
10
+ lib/c2dm_on_rails.rb
11
+ lib/c2dm_on_rails/app/models/c2dm/base.rb
12
+ lib/c2dm_on_rails/app/models/c2dm/device.rb
13
+ lib/c2dm_on_rails/app/models/c2dm/notification.rb
14
+ lib/c2dm_on_rails/c2dm_on_rails.rb
15
+ lib/c2dm_on_rails/libs/connection.rb
16
+ lib/c2dm_on_rails/tasks/c2dm.rake
17
+ lib/c2dm_on_rails_tasks.rb
data/README.textile ADDED
@@ -0,0 +1,153 @@
1
+ h1. C2dm on Rails (Android push notifications on Rails)
2
+
3
+ APN on Rails is a Ruby on Rails gem that allows you to easily add Apple Push Notification (iPhone)
4
+ support to your Rails application.
5
+
6
+ C2dm on Rails is a Ruby on Rails gem that allows you to easily add Android push notification
7
+ (Android 2.2> devices) to your Rails application.
8
+
9
+ h2. Acknowledgements:
10
+
11
+ This gem is under construction and is forked from our project. The developer
12
+ has some allocated hours for developing the gem further. The gem is tested
13
+ quite lightly and not in production environment yet.
14
+
15
+ This gem is a re-write of a plugin that was written by Fabien Penso and Sam Soffes.
16
+ Their plugin was a great start, but it just didn't quite reach the level I hoped it would.
17
+ I've re-written, as a gem, added a ton of tests, and I would like to think that I made it
18
+ a little nicer and easier to use.
19
+
20
+ This gem is a re-write of a apn_on_rails gem that was written by Mark Bates and
21
+ before he made it a gem, it was started by Fabien Penso and Sam Soffes. The gem
22
+ installation, migration generation and usage is copied from the original apn_on_rails
23
+ gem. This is also my first rubygem, so please feel free to fix some oditties and please
24
+ comment also.
25
+
26
+ h2. Requirements:
27
+
28
+ First it is necessary to sign up to Android Cloud to Device Messaging service.
29
+ You need a role account email, it's password and the name of your Android app for
30
+ configuring the c2dm gem.
31
+
32
+ Sign up here:
33
+
34
+ "http://code.google.com/android/c2dm/signup.html":http://code.google.com/android/c2dm/signup.html
35
+
36
+ h2. Installing:
37
+
38
+ h3. Stable (RubyForge):
39
+
40
+ <pre><code>
41
+ $ sudo gem install c2dm_on_rails
42
+ </code></pre>
43
+
44
+ h3. Rails Gem Management:
45
+
46
+ If you like to use the built in Rails gem management:
47
+
48
+ <pre><code>
49
+ config.gem 'c2dm_on_rails'
50
+ </code></pre>
51
+
52
+ h2. Setup and Configuration:
53
+
54
+ Once you have the gem installed via your favorite gem installation, you need to require it so you can
55
+ start to use it:
56
+
57
+ Add the following require, wherever it makes sense to you:
58
+
59
+ <pre><code>
60
+ require 'c2dm_on_rails'
61
+ </code></pre>
62
+
63
+ You also need to add the following to your Rakefile so you can use the
64
+ Rake tasks that ship with C2dm on Rails:
65
+
66
+ <pre><code>
67
+ begin
68
+ require 'c2dm_on_rails_tasks'
69
+ rescue MissingSourceFile => e
70
+ puts e.message
71
+ end
72
+ </code></pre>
73
+
74
+ Now, to create the tables you need for C2dm on Rails, run the following task:
75
+
76
+ <pre><code>
77
+ $ ruby script/generate c2dm_migrations
78
+ </code></pre>
79
+
80
+ C2dm on Rails uses the Configatron gem, "http://github.com/markbates/configatron/tree/master":http://github.com/markbates/configatron/tree/master,
81
+ to configure itself. C2dm on Rails has the following default configurations that you change as you
82
+ see fit:
83
+
84
+ <pre><code>
85
+ configatron.c2dm.api_url = 'https://android.apis.google.com/c2dm/send'
86
+ </code></pre>
87
+
88
+ C2dm on Rails uses also the gdata gem for connecting a Google account. The
89
+ config file for Google Connect (config/c2dm.yml) should look like this:
90
+
91
+ <pre><code>
92
+ development:
93
+ username: your_user_name
94
+ password: password_for_the_account
95
+ app_name: your_applications_name
96
+
97
+ production:
98
+ ... etc
99
+ </code></pre>
100
+
101
+ That's it, now you're ready to start creating notifications.
102
+
103
+ h3. Upgrade Notes:
104
+
105
+ If you are upgrading to a new version of APN on Rails you should always run:
106
+
107
+ <pre><code>
108
+ $ ruby script/generate c2dm_migrations
109
+ </code></pre>
110
+
111
+ That way you ensure you have the latest version of the database tables needed.
112
+
113
+ h2. Example:
114
+
115
+ More information about C2dm services should be read from "http://code.google.com/android/c2dm/":http://code.google.com/android/c2dm/
116
+
117
+ <pre><code>
118
+ $ ./script/console
119
+ >> device = C2dm::Device.create(:registration_id => "XXXXXXXXXXXXXXXXXXXXXX")
120
+ >> notification = C2dm::Notification.new
121
+ >> notification.device = device
122
+ >> notification.collapse_key = "private_message"
123
+ >> notification.delay_while_idle = true
124
+ >> notification.data = {"sender_id" => "420", "message_text" => "Wanna go for a ride?"}
125
+ >> notification.save
126
+ </code></pre>
127
+
128
+ You can use the following Rake task to deliver your notifications:
129
+
130
+ <pre><code>
131
+ $ rake c2dm:notifications:deliver
132
+ </code></pre>
133
+
134
+ The Rake task will find any unsent notifications in the database. If there aren't any notifications
135
+ it will simply do nothing. If there are notifications waiting to be delivered it will login with the provided
136
+ login data and send notifications using HTTP POST to Google. The client can get an error from Google. There are
137
+ several possibilities:
138
+
139
+ |code 200| |
140
+ | |Error: QuotaExceeded. It will cancel the notification sending and user should try to send them again after a while.|
141
+ | |Error: DeviceQuotaExceeded. It will cancel the notification sending for the current device and continue from the other devices.|
142
+ | |Error: InvalidRegistration. The devices registration_id is missing or invalid. The device and all its notifications will be deleted.|
143
+ | |Error: NotRegistred. The registration_id is no longer valid. The device and all its notifications will be deleted.|
144
+ | |Error: MessageTooBig. The maximum size of a c2dm push notification is 1024 bytes. User should reduce the size and try again.|
145
+ | |Error: MissingCollapseKey. Google uses a property called collapse_key to collapse a group of like messages when the device is online, so that only the last message is sent to the client. It is required.|
146
+
147
+ |code 503| |
148
+ | |The server is currently unavailable. The sending process is stopped and sender must retry later. Senders that retry too often and too fast risk being blacklisted.|
149
+
150
+ |code 401| |
151
+ | |The ClientLogin auth is invalid. Check the config file.|
152
+
153
+ Released under the MIT license.
data/Rakefile ADDED
@@ -0,0 +1,12 @@
1
+ require 'rubygems'
2
+ require 'rake'
3
+ require 'echoe'
4
+
5
+ Echoe.new('c2dm_on_rails', '0.1.5') do |p|
6
+ p.description = "Android push notifications on Rails."
7
+ p.url = "http://github.com/pimeys/c2dm_on_rails"
8
+ p.author = "Julius de Bruijn"
9
+ p.email = "julius.debruijn@digia.com"
10
+ p.ignore_pattern = ["tmp/*", "script/*"]
11
+ p.development_dependencies = ["gdata >=1.1.1", "configatron >=2.6.3"]
12
+ end
@@ -0,0 +1,36 @@
1
+ # -*- encoding: utf-8 -*-
2
+
3
+ Gem::Specification.new do |s|
4
+ s.name = %q{c2dm_on_rails}
5
+ s.version = "0.1.5"
6
+
7
+ s.required_rubygems_version = Gem::Requirement.new(">= 1.2") if s.respond_to? :required_rubygems_version=
8
+ s.authors = ["Julius de Bruijn"]
9
+ s.date = %q{2010-12-09}
10
+ s.description = %q{Android push notifications on Rails.}
11
+ s.email = %q{julius.debruijn@digia.com}
12
+ s.extra_rdoc_files = ["CHANGELOG", "LICENSE", "README.textile", "lib/c2dm_on_rails.rb", "lib/c2dm_on_rails/app/models/c2dm/base.rb", "lib/c2dm_on_rails/app/models/c2dm/device.rb", "lib/c2dm_on_rails/app/models/c2dm/notification.rb", "lib/c2dm_on_rails/c2dm_on_rails.rb", "lib/c2dm_on_rails/libs/connection.rb", "lib/c2dm_on_rails/tasks/c2dm.rake", "lib/c2dm_on_rails_tasks.rb"]
13
+ s.files = ["CHANGELOG", "LICENSE", "Manifest", "README.textile", "Rakefile", "c2dm_on_rails.gemspec", "generators/c2dm_migrations_generator.rb", "generators/templates/c2dm_migrations/001_create_c2dm_devices.rb", "generators/templates/c2dm_migrations/002_create_c2dm_notifications.rb", "lib/c2dm_on_rails.rb", "lib/c2dm_on_rails/app/models/c2dm/base.rb", "lib/c2dm_on_rails/app/models/c2dm/device.rb", "lib/c2dm_on_rails/app/models/c2dm/notification.rb", "lib/c2dm_on_rails/c2dm_on_rails.rb", "lib/c2dm_on_rails/libs/connection.rb", "lib/c2dm_on_rails/tasks/c2dm.rake", "lib/c2dm_on_rails_tasks.rb"]
14
+ s.homepage = %q{http://github.com/pimeys/c2dm_on_rails}
15
+ s.rdoc_options = ["--line-numbers", "--inline-source", "--title", "C2dm_on_rails", "--main", "README.textile"]
16
+ s.require_paths = ["lib"]
17
+ s.rubyforge_project = %q{c2dm_on_rails}
18
+ s.rubygems_version = %q{1.3.7}
19
+ s.summary = %q{Android push notifications on Rails.}
20
+
21
+ if s.respond_to? :specification_version then
22
+ current_version = Gem::Specification::CURRENT_SPECIFICATION_VERSION
23
+ s.specification_version = 3
24
+
25
+ if Gem::Version.new(Gem::VERSION) >= Gem::Version.new('1.2.0') then
26
+ s.add_development_dependency(%q<gdata>, [">= 1.1.1"])
27
+ s.add_development_dependency(%q<configatron>, [">= 2.6.3"])
28
+ else
29
+ s.add_dependency(%q<gdata>, [">= 1.1.1"])
30
+ s.add_dependency(%q<configatron>, [">= 2.6.3"])
31
+ end
32
+ else
33
+ s.add_dependency(%q<gdata>, [">= 1.1.1"])
34
+ s.add_dependency(%q<configatron>, [">= 2.6.3"])
35
+ end
36
+ end
@@ -0,0 +1,31 @@
1
+ require 'rails_generator'
2
+ # Generates the migrations necessary for C2dm on Rails.
3
+ # This should be run upon install and upgrade of the
4
+ # C2dm on Rails gem.
5
+ #
6
+ # $ ruby script/generate c2dm_migrations
7
+ class C2dmMigrationsGenerator < Rails::Generator::Base
8
+
9
+ def manifest # :nodoc:
10
+ record do |m|
11
+ timestamp = Time.now.utc.strftime("%Y%m%d%H%M%S")
12
+ db_migrate_path = File.join('db', 'migrate')
13
+
14
+ m.directory(db_migrate_path)
15
+
16
+ Dir.glob(File.join(File.dirname(__FILE__), 'templates', 'c2dm_migrations', '*.rb')).sort.each_with_index do |f, i|
17
+ f = File.basename(f)
18
+ f.match(/\d+\_(.+)/)
19
+ timestamp = timestamp.succ
20
+ if Dir.glob(File.join(db_migrate_path, "*_#{$1}")).empty?
21
+ m.file(File.join('c2dm_migrations', f),
22
+ File.join(db_migrate_path, "#{timestamp}_#{$1}"),
23
+ {:collision => :skip})
24
+ end
25
+ end
26
+
27
+ end # record
28
+
29
+ end # manifest
30
+
31
+ end # C2dmMigrationsGenerator
@@ -0,0 +1,16 @@
1
+ class CreateC2dmDevices < ActiveRecord::Migration # :nodoc:
2
+ def self.up
3
+ create_table :c2dm_devices do |t|
4
+ t.string :registration_id, :size => 120, :null => false
5
+ t.datetime :last_registered_at
6
+
7
+ t.timestamps
8
+ end
9
+
10
+ add_index :c2dm_devices, :registration_id, :unique => true
11
+ end
12
+
13
+ def self.down
14
+ drop_table :c2dm_devices
15
+ end
16
+ end
@@ -0,0 +1,21 @@
1
+ class CreateC2dmNotifications < ActiveRecord::Migration # :nodoc:
2
+
3
+ def self.up
4
+
5
+ create_table :c2dm_notifications do |t|
6
+ t.integer :device_id, :null => false
7
+ t.string :collapse_key, :null => false
8
+ t.text :data
9
+ t.boolean :delay_while_idle
10
+ t.datetime :sent_at
11
+ t.timestamps
12
+ end
13
+
14
+ add_index :c2dm_notifications, :device_id
15
+ end
16
+
17
+ def self.down
18
+ drop_table :c2dm_notifications
19
+ end
20
+
21
+ end
@@ -0,0 +1,4 @@
1
+ Dir.glob(File.join(File.dirname(__FILE__), 'c2dm_on_rails', '**/*.rb')).sort.each do |f|
2
+ require File.expand_path(f)
3
+ end
4
+
@@ -0,0 +1,9 @@
1
+ module C2dm
2
+ class Base < ActiveRecord::Base # :nodoc:
3
+
4
+ def self.table_name # :nodoc:
5
+ self.to_s.gsub("::", "_").tableize
6
+ end
7
+
8
+ end
9
+ end
@@ -0,0 +1,30 @@
1
+ # Represents an Android phone.
2
+ # An C2dm::Device can have many C2dm::Notification.
3
+ #
4
+ # In order for the C2dm::Feedback system to work properly you *MUST*
5
+ # touch the <tt>last_registered_at</tt> column everytime someone opens
6
+ # your application. If you do not, then it is possible, and probably likely,
7
+ # that their device will be removed and will no longer receive notifications.
8
+ #
9
+ # Example:
10
+ # Device.create(:registration_id => 'FOOBAR')
11
+ class C2dm::Device < C2dm::Base
12
+
13
+ has_many :notifications, :class_name => 'C2dm::Notification', :dependent => :destroy
14
+
15
+ validates_presence_of :registration_id
16
+ validates_uniqueness_of :registration_id
17
+
18
+ before_save :set_last_registered_at
19
+
20
+ # The <tt>feedback_at</tt> accessor is set when the
21
+ # device is marked as potentially disconnected from your
22
+ # application by Google.
23
+ attr_accessor :feedback_at
24
+
25
+ private
26
+ def set_last_registered_at
27
+ self.last_registered_at = Time.now if self.last_registered_at.nil?
28
+ end
29
+
30
+ end
@@ -0,0 +1,82 @@
1
+ require 'net/http'
2
+ require 'uri'
3
+
4
+ # Represents the message you wish to send.
5
+ # An C2dm::Notification belongs to an C2dm::Device.
6
+ #
7
+ # Example:
8
+ # c2dm = C2dm::Notification.new
9
+ # c2dm.key = "value"
10
+ # c2dm.device = APN::Device.find(1)
11
+ # c2dm.save
12
+ #
13
+ # To deliver call the following method:
14
+ # C2dm::Notification.send_notifications
15
+ #
16
+ # As each C2dm::Notification is sent the <tt>sent_at</tt> column will be timestamped,
17
+ # so as to not be sent again.
18
+ class C2dm::Notification < C2dm::Base
19
+ include ::ActionView::Helpers::TextHelper
20
+ extend ::ActionView::Helpers::TextHelper
21
+ serialize :data
22
+
23
+ belongs_to :device, :class_name => 'C2dm::Device'
24
+
25
+ class << self
26
+
27
+ # Opens a connection to the Google C2dm server and attempts to batch deliver
28
+ # an Array of notifications.
29
+ #
30
+ # This method expects an Array of C2dm::Notifications. If no parameter is passed
31
+ # in then it will use the following:
32
+ # C2dm::Notification.all(:conditions => {:sent_at => nil})
33
+ #
34
+ # As each C2dm::Notification is sent the <tt>sent_at</tt> column will be timestamped,
35
+ # so as to not be sent again.
36
+ #
37
+ # This can be run from the following Rake task:
38
+ # $ rake c2dm:notifications:deliver
39
+ def send_notifications(notifications = C2dm::Notification.all(:conditions => {:sent_at => nil}))
40
+ unless notifications.nil? || notifications.empty?
41
+ C2dm::Connection.open do |token|
42
+ notifications.each do |noty|
43
+ response = C2dm::Connection.send_notification(noty, token)
44
+ if response[:code] == 200
45
+ case response[:message]
46
+ when "Error=QuotaExceeded"
47
+ raise C2dm::Errors::QuotaExceeded.new(response[:message])
48
+ when "Error=DeviceQuotaExceeded"
49
+ ex = C2dm::Errors::DeviceQuotaExceeded.new(response[:message])
50
+ logger.warn(ex.message)
51
+ when "Error=InvalidRegistration"
52
+ ex = C2dm::Errors::InvalidRegistration.new(response[:message])
53
+ logger.warn("#{ex.message}, destroying c2dm_device with id #{noty.device.id}")
54
+ noty.device.destroy
55
+ when "Error=NotRegistered"
56
+ ex = C2dm::Errors::NotRegistered.new(response[:message])
57
+ logger.warn("#{ex.message}, destroying c2dm_device with id #{noty.device.id}")
58
+ noty.device.destroy
59
+ when "Error=MessageTooBig"
60
+ ex = C2dm::Errors::MessageTooBig.new(response[:message])
61
+ logger.warn(ex.message)
62
+ when "Error=MissingCollapseKey"
63
+ ex = C2dm::Errors::MissingCollapseKey.new(response[:message])
64
+ logger.warn(ex.message)
65
+ else
66
+ noty.sent_at = Time.now
67
+ noty.save!
68
+ end
69
+ elsif response[:code] == 503
70
+ raise C2dm::Errors:ServiceUnavailable.new(response[:message])
71
+ elsif response[:code] == 401
72
+ raise C2dm::Errors::InvalidAuthToken.new(response[:message])
73
+ else
74
+ end
75
+ end
76
+ end
77
+ end
78
+ end
79
+
80
+ end # class << self
81
+
82
+ end # C2dm::Notification
@@ -0,0 +1,139 @@
1
+ require 'configatron'
2
+ require 'gdata'
3
+ require 'uri'
4
+
5
+ rails_root = File.join(FileUtils.pwd, 'rails_root')
6
+ if defined?(RAILS_ROOT)
7
+ rails_root = RAILS_ROOT
8
+ end
9
+
10
+ rails_env = 'development'
11
+ if defined?(RAILS_ENV)
12
+ rails_env = RAILS_ENV
13
+ end
14
+
15
+ begin
16
+ APP_CONFIG = YAML.load_file("#{RAILS_ROOT}/config/c2dm.yml")[rails_env]
17
+ rescue ex
18
+ raise C2dm::Errors.ConfigFileNotFound.new(ex.message)
19
+ end
20
+
21
+ begin
22
+ configatron.c2dm.api_url = URI.parse('https://android.apis.google.com/c2dm/send')
23
+ configatron.c2dm.username = APP_CONFIG['username']
24
+ configatron.c2dm.password = APP_CONFIG['password']
25
+ configatron.c2dm.app_name = APP_CONFIG['app_name']
26
+ rescue ex
27
+ raise C2dm::Errors.ConfigFileMissingAttributes.new(ex.message)
28
+ end
29
+
30
+ module C2dm # :nodoc:
31
+
32
+ module Errors # :nodoc:
33
+
34
+ # The payload of the message is too big, the limit is currently 1024
35
+ # bytes. Reduce the size of the message.
36
+ class MessageTooBig < StandardError
37
+
38
+ def initialize(message) # :nodoc:
39
+ super("The maximum size allowed for a notification payload is 1024 bytes: '#{message}'")
40
+ end
41
+
42
+ end
43
+
44
+ # Too many messages sent by the sender. Retry after a while.
45
+ class QuotaExceeded < StandardError
46
+
47
+ def initialize(message) # :nodoc:
48
+ super("Too many messages sent by the sender: '#{message}'")
49
+ end
50
+
51
+ end
52
+
53
+ # Too many messages sent by the sender to a specific device. Retry after a
54
+ # while.
55
+ class DeviceQuotaExceeded < StandardError
56
+
57
+ def initialize(message) # :nodoc:
58
+ super("Too many messages sent by the sender to a specific device: '#{message}'")
59
+ end
60
+
61
+ end
62
+
63
+ # Missing or bad registration_id. Sender should stop sending messages to
64
+ # this device.
65
+ class InvalidRegistration < StandardError
66
+
67
+ def initialize(message) # :nodoc:
68
+ super("Missing or bad registration_id: '#{message}'")
69
+ end
70
+
71
+ end
72
+
73
+ # The registration_id is no longer valid, for example user has uninstalled
74
+ # the application or turned off notifications. Sender should stop sending
75
+ # messages to this device.
76
+ class NotRegistered < StandardError
77
+
78
+ def initialize(message) # :nodoc:
79
+ super("The registration_id is no longer valid: '#{message}'")
80
+ end
81
+
82
+ end
83
+
84
+ # Collapse key is required. Include collapse key in the request.
85
+ class MissingCollapseKey < StandardError
86
+
87
+ def initialize(message) # :nodoc:
88
+ super("Collapse key is required: '#{message}'")
89
+ end
90
+
91
+ end
92
+
93
+ # ClientLogin AUTH_TOKEN is invalid. Check the config
94
+ class InvalidAuthToken < StandardError
95
+
96
+ def initialize(message)
97
+ super("Invalid auth token: '#{message}'")
98
+ end
99
+
100
+ end
101
+
102
+ class ConfigFileNotFound < StandardError
103
+
104
+ def initialize(message)
105
+ super("The config file c2dm.yml not found from config/ directory or contains errors: '#{message}'")
106
+ end
107
+
108
+ end
109
+
110
+ class ConfigFileMissingAttributes < StandardError
111
+
112
+ def initialize(message)
113
+ super("Config file doesn't contain username, password or app_name: '#{message}'")
114
+ end
115
+
116
+ end
117
+
118
+ class ServiceUnavailable < StandardError
119
+
120
+ def initialize(message)
121
+ super("Service is currently unavailable. Try again later: '#{message}'")
122
+ end
123
+
124
+ end
125
+ end # Errors
126
+
127
+ end # APN
128
+
129
+ Dir.glob(File.join(File.dirname(__FILE__), 'app', 'models', 'c2dm', '*.rb')).sort.each do |f|
130
+ require f
131
+ end
132
+
133
+ %w{ models controllers helpers }.each do |dir|
134
+ path = File.join(File.dirname(__FILE__), 'app', dir)
135
+ $LOAD_PATH << path
136
+ # puts "Adding #{path}"
137
+ ActiveSupport::Dependencies.load_paths << path
138
+ ActiveSupport::Dependencies.load_once_paths.delete(path)
139
+ end
@@ -0,0 +1,36 @@
1
+ require 'gdata'
2
+ require 'net/https'
3
+
4
+ module C2dm
5
+ module Connection
6
+
7
+ class << self
8
+ def send_notification(noty, token)
9
+ headers = { "Content-Type" => "application/x-www-form-urlencoded",
10
+ "Authorization" => "GoogleLogin auth=#{token}" }
11
+
12
+ message_data = noty.data.map{|k, v| "&data.#{k}=#{v}"}.reduce{|k, v| k + v}
13
+ data = "registration_id=#{noty.device.registration_id}&collapse_key=#{noty.collapse_key}#{message_data}"
14
+
15
+ data = data + "&delay_while_idle" if noty.delay_while_idle
16
+
17
+ url = configatron.c2dm.api_url
18
+ http = Net::HTTP.new(url.host, url.port)
19
+ http.use_ssl = true
20
+
21
+ resp, dat = http.post(url.path, data, headers)
22
+
23
+ return {:code => resp.code.to_i, :message => dat}
24
+ end
25
+
26
+ def open
27
+ client_login_handler = GData::Auth::ClientLogin.new('ac2dm', :account_type => 'HOSTED_OR_GOOGLE')
28
+ token = client_login_handler.get_token(configatron.c2dm.username,
29
+ configatron.c2dm.password,
30
+ configatron.c2dm.app_name)
31
+
32
+ yield token
33
+ end
34
+ end
35
+ end # Connection
36
+ end # C2dm
@@ -0,0 +1,11 @@
1
+ namespace :c2dm do
2
+
3
+ namespace :notifications do
4
+
5
+ desc "Deliver all unsent C2dm notifications."
6
+ task :deliver => [:environment] do
7
+ C2dm::Notification.send_notifications
8
+ end
9
+
10
+ end # notifications
11
+ end # apn
@@ -0,0 +1,3 @@
1
+ Dir.glob(File.join(File.dirname(__FILE__), 'c2dm_on_rails', 'tasks', '**/*.rake')).each do |f|
2
+ load File.expand_path(f)
3
+ end
metadata ADDED
@@ -0,0 +1,130 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: c2dm_on_rails
3
+ version: !ruby/object:Gem::Version
4
+ hash: 17
5
+ prerelease: false
6
+ segments:
7
+ - 0
8
+ - 1
9
+ - 5
10
+ version: 0.1.5
11
+ platform: ruby
12
+ authors:
13
+ - Julius de Bruijn
14
+ autorequire:
15
+ bindir: bin
16
+ cert_chain: []
17
+
18
+ date: 2010-12-09 00:00:00 +02:00
19
+ default_executable:
20
+ dependencies:
21
+ - !ruby/object:Gem::Dependency
22
+ name: gdata
23
+ prerelease: false
24
+ requirement: &id001 !ruby/object:Gem::Requirement
25
+ none: false
26
+ requirements:
27
+ - - ">="
28
+ - !ruby/object:Gem::Version
29
+ hash: 17
30
+ segments:
31
+ - 1
32
+ - 1
33
+ - 1
34
+ version: 1.1.1
35
+ type: :development
36
+ version_requirements: *id001
37
+ - !ruby/object:Gem::Dependency
38
+ name: configatron
39
+ prerelease: false
40
+ requirement: &id002 !ruby/object:Gem::Requirement
41
+ none: false
42
+ requirements:
43
+ - - ">="
44
+ - !ruby/object:Gem::Version
45
+ hash: 17
46
+ segments:
47
+ - 2
48
+ - 6
49
+ - 3
50
+ version: 2.6.3
51
+ type: :development
52
+ version_requirements: *id002
53
+ description: Android push notifications on Rails.
54
+ email: julius.debruijn@digia.com
55
+ executables: []
56
+
57
+ extensions: []
58
+
59
+ extra_rdoc_files:
60
+ - CHANGELOG
61
+ - LICENSE
62
+ - README.textile
63
+ - lib/c2dm_on_rails.rb
64
+ - lib/c2dm_on_rails/app/models/c2dm/base.rb
65
+ - lib/c2dm_on_rails/app/models/c2dm/device.rb
66
+ - lib/c2dm_on_rails/app/models/c2dm/notification.rb
67
+ - lib/c2dm_on_rails/c2dm_on_rails.rb
68
+ - lib/c2dm_on_rails/libs/connection.rb
69
+ - lib/c2dm_on_rails/tasks/c2dm.rake
70
+ - lib/c2dm_on_rails_tasks.rb
71
+ files:
72
+ - CHANGELOG
73
+ - LICENSE
74
+ - Manifest
75
+ - README.textile
76
+ - Rakefile
77
+ - c2dm_on_rails.gemspec
78
+ - generators/c2dm_migrations_generator.rb
79
+ - generators/templates/c2dm_migrations/001_create_c2dm_devices.rb
80
+ - generators/templates/c2dm_migrations/002_create_c2dm_notifications.rb
81
+ - lib/c2dm_on_rails.rb
82
+ - lib/c2dm_on_rails/app/models/c2dm/base.rb
83
+ - lib/c2dm_on_rails/app/models/c2dm/device.rb
84
+ - lib/c2dm_on_rails/app/models/c2dm/notification.rb
85
+ - lib/c2dm_on_rails/c2dm_on_rails.rb
86
+ - lib/c2dm_on_rails/libs/connection.rb
87
+ - lib/c2dm_on_rails/tasks/c2dm.rake
88
+ - lib/c2dm_on_rails_tasks.rb
89
+ has_rdoc: true
90
+ homepage: http://github.com/pimeys/c2dm_on_rails
91
+ licenses: []
92
+
93
+ post_install_message:
94
+ rdoc_options:
95
+ - --line-numbers
96
+ - --inline-source
97
+ - --title
98
+ - C2dm_on_rails
99
+ - --main
100
+ - README.textile
101
+ require_paths:
102
+ - lib
103
+ required_ruby_version: !ruby/object:Gem::Requirement
104
+ none: false
105
+ requirements:
106
+ - - ">="
107
+ - !ruby/object:Gem::Version
108
+ hash: 3
109
+ segments:
110
+ - 0
111
+ version: "0"
112
+ required_rubygems_version: !ruby/object:Gem::Requirement
113
+ none: false
114
+ requirements:
115
+ - - ">="
116
+ - !ruby/object:Gem::Version
117
+ hash: 11
118
+ segments:
119
+ - 1
120
+ - 2
121
+ version: "1.2"
122
+ requirements: []
123
+
124
+ rubyforge_project: c2dm_on_rails
125
+ rubygems_version: 1.3.7
126
+ signing_key:
127
+ specification_version: 3
128
+ summary: Android push notifications on Rails.
129
+ test_files: []
130
+