gcm_rails_mongo_mapper 0.0.1 → 0.0.2
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/README.md +4 -0
- data/Rakefile +2 -2
- data/VERSION +1 -1
- data/gcm_rails_mongo_mapper.gemspec +63 -0
- metadata +5 -10
- data/lib/gcm_rails_mongo_mapper/app/models/gcm/base.rb +0 -5
- data/lib/gcm_rails_mongo_mapper/app/models/gcm/device.rb +0 -37
- data/lib/gcm_rails_mongo_mapper/app/models/gcm/notification.rb +0 -103
- data/lib/gcm_rails_mongo_mapper/gcm_rails_mongo_mapper.rb +0 -88
- data/lib/gcm_rails_mongo_mapper/libs/connection.rb +0 -44
- data/lib/gcm_rails_mongo_mapper/tasks/gcm.rake +0 -9
- data/lib/gcm_rails_mongo_mapper.rb +0 -3
- data/lib/gcm_rails_mongo_mapper_tasks.rb +0 -3
data/README.md
ADDED
data/Rakefile
CHANGED
@@ -21,7 +21,7 @@ Jeweler::Tasks.new do |gem|
|
|
21
21
|
gem.description = %Q{gcm_rails_mongo_mapper is a Ruby on Rails gem based on dondeng's gcm_on_rails gem (https://github.com/dondeng/gcm_on_rails). Same funcionality except this gem works with MongoMapper. This is my first gem so any feedback is greatly appreciated!}
|
22
22
|
gem.email = "kkelani@gmail.com"
|
23
23
|
gem.authors = ["Kevin Kelani"]
|
24
|
-
gem.version = "0.0.
|
24
|
+
gem.version = "0.0.2"
|
25
25
|
# dependencies defined in Gemfile
|
26
26
|
end
|
27
27
|
Jeweler::RubygemsDotOrgTasks.new
|
@@ -32,7 +32,7 @@ Rake::RDocTask.new do |rdoc|
|
|
32
32
|
version = File.exist?('VERSION') ? File.read('VERSION') : ""
|
33
33
|
|
34
34
|
rdoc.rdoc_dir = 'rdoc'
|
35
|
-
rdoc.title = "
|
35
|
+
rdoc.title = "gcm_rails_mongo_mapper #{version}"
|
36
36
|
rdoc.rdoc_files.include('README*')
|
37
37
|
rdoc.rdoc_files.include('lib/**/*.rb')
|
38
38
|
end
|
data/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
0.1
|
1
|
+
0.0.1
|
@@ -0,0 +1,63 @@
|
|
1
|
+
# Generated by jeweler
|
2
|
+
# DO NOT EDIT THIS FILE DIRECTLY
|
3
|
+
# Instead, edit Jeweler::Tasks in Rakefile, and run 'rake gemspec'
|
4
|
+
# -*- encoding: utf-8 -*-
|
5
|
+
|
6
|
+
Gem::Specification.new do |s|
|
7
|
+
s.name = "gcm_rails_mongo_mapper"
|
8
|
+
s.version = "0.0.2"
|
9
|
+
|
10
|
+
s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
|
11
|
+
s.authors = ["Kevin Kelani"]
|
12
|
+
s.date = "2012-10-04"
|
13
|
+
s.description = "gcm_rails_mongo_mapper is a Ruby on Rails gem based on dondeng's gcm_on_rails gem (https://github.com/dondeng/gcm_on_rails). Same funcionality except this gem works with MongoMapper. This is my first gem so any feedback is greatly appreciated!"
|
14
|
+
s.email = "kkelani@gmail.com"
|
15
|
+
s.extra_rdoc_files = [
|
16
|
+
"LICENSE.txt",
|
17
|
+
"README.md",
|
18
|
+
"README.textile"
|
19
|
+
]
|
20
|
+
s.files = [
|
21
|
+
"Gemfile",
|
22
|
+
"Gemfile.lock",
|
23
|
+
"LICENSE.txt",
|
24
|
+
"README.md",
|
25
|
+
"README.textile",
|
26
|
+
"Rakefile",
|
27
|
+
"VERSION",
|
28
|
+
"gcm_rails_mongo_mapper.gemspec",
|
29
|
+
"lib/generators/gcm_migrations_generator.rb",
|
30
|
+
"lib/generators/templates/gcm_migrations/create_gcm_devices.rb",
|
31
|
+
"lib/generators/templates/gcm_migrations/create_gcm_notifications.rb"
|
32
|
+
]
|
33
|
+
s.homepage = "http://github.com/kkelani/gcm_rails_mongo_mapper"
|
34
|
+
s.licenses = ["MIT"]
|
35
|
+
s.require_paths = ["lib"]
|
36
|
+
s.rubygems_version = "1.8.24"
|
37
|
+
s.summary = "Google Cloud Messaging for Android on Rails using MongoMapper"
|
38
|
+
|
39
|
+
if s.respond_to? :specification_version then
|
40
|
+
s.specification_version = 3
|
41
|
+
|
42
|
+
if Gem::Version.new(Gem::VERSION) >= Gem::Version.new('1.2.0') then
|
43
|
+
s.add_runtime_dependency(%q<configatron>, [">= 0"])
|
44
|
+
s.add_runtime_dependency(%q<json>, [">= 0"])
|
45
|
+
s.add_development_dependency(%q<rdoc>, ["~> 3.12"])
|
46
|
+
s.add_development_dependency(%q<bundler>, ["~> 1.0.0"])
|
47
|
+
s.add_development_dependency(%q<jeweler>, ["~> 1.8.4"])
|
48
|
+
else
|
49
|
+
s.add_dependency(%q<configatron>, [">= 0"])
|
50
|
+
s.add_dependency(%q<json>, [">= 0"])
|
51
|
+
s.add_dependency(%q<rdoc>, ["~> 3.12"])
|
52
|
+
s.add_dependency(%q<bundler>, ["~> 1.0.0"])
|
53
|
+
s.add_dependency(%q<jeweler>, ["~> 1.8.4"])
|
54
|
+
end
|
55
|
+
else
|
56
|
+
s.add_dependency(%q<configatron>, [">= 0"])
|
57
|
+
s.add_dependency(%q<json>, [">= 0"])
|
58
|
+
s.add_dependency(%q<rdoc>, ["~> 3.12"])
|
59
|
+
s.add_dependency(%q<bundler>, ["~> 1.0.0"])
|
60
|
+
s.add_dependency(%q<jeweler>, ["~> 1.8.4"])
|
61
|
+
end
|
62
|
+
end
|
63
|
+
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: gcm_rails_mongo_mapper
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0.
|
4
|
+
version: 0.0.2
|
5
5
|
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -9,7 +9,7 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date: 2012-
|
12
|
+
date: 2012-10-04 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: configatron
|
@@ -99,22 +99,17 @@ executables: []
|
|
99
99
|
extensions: []
|
100
100
|
extra_rdoc_files:
|
101
101
|
- LICENSE.txt
|
102
|
+
- README.md
|
102
103
|
- README.textile
|
103
104
|
files:
|
104
105
|
- Gemfile
|
105
106
|
- Gemfile.lock
|
106
107
|
- LICENSE.txt
|
108
|
+
- README.md
|
107
109
|
- README.textile
|
108
110
|
- Rakefile
|
109
111
|
- VERSION
|
110
|
-
-
|
111
|
-
- lib/gcm_rails_mongo_mapper/app/models/gcm/base.rb
|
112
|
-
- lib/gcm_rails_mongo_mapper/app/models/gcm/device.rb
|
113
|
-
- lib/gcm_rails_mongo_mapper/app/models/gcm/notification.rb
|
114
|
-
- lib/gcm_rails_mongo_mapper/gcm_rails_mongo_mapper.rb
|
115
|
-
- lib/gcm_rails_mongo_mapper/libs/connection.rb
|
116
|
-
- lib/gcm_rails_mongo_mapper/tasks/gcm.rake
|
117
|
-
- lib/gcm_rails_mongo_mapper_tasks.rb
|
112
|
+
- gcm_rails_mongo_mapper.gemspec
|
118
113
|
- lib/generators/gcm_migrations_generator.rb
|
119
114
|
- lib/generators/templates/gcm_migrations/create_gcm_devices.rb
|
120
115
|
- lib/generators/templates/gcm_migrations/create_gcm_notifications.rb
|
@@ -1,37 +0,0 @@
|
|
1
|
-
# Represents an Android phone.
|
2
|
-
# An Gcm::Device can have many Gcm::Notification.
|
3
|
-
#
|
4
|
-
# In order for the Gcm::Feedback system to work properly you *MUST*
|
5
|
-
# touch the <tt>last_registered_at</tt> column every time 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 Gcm::Device < Gcm::Base
|
12
|
-
#self.table_name = "gcm_devices"
|
13
|
-
set_collection_name "gcm_devices"
|
14
|
-
|
15
|
-
# Fields
|
16
|
-
key :registration_id, String
|
17
|
-
key :last_registered_at, DateTime
|
18
|
-
timestamps!
|
19
|
-
|
20
|
-
#has_many :notifications, :class_name => 'Gcm::Notification', :dependent => :destroy
|
21
|
-
many :notifications, :class_name => 'Gcm::Notification', :dependent => :destroy
|
22
|
-
|
23
|
-
validates_presence_of :registration_id
|
24
|
-
validates_uniqueness_of :registration_id
|
25
|
-
|
26
|
-
before_save :set_last_registered_at
|
27
|
-
|
28
|
-
# The <tt>feedback_at</tt> accessor is set when the
|
29
|
-
# device is marked as potentially disconnected from your
|
30
|
-
# application by Google.
|
31
|
-
attr_accessor :feedback_at
|
32
|
-
|
33
|
-
private
|
34
|
-
def set_last_registered_at
|
35
|
-
self.last_registered_at = Time.now if self.last_registered_at.nil?
|
36
|
-
end
|
37
|
-
end
|
@@ -1,103 +0,0 @@
|
|
1
|
-
class Gcm::Notification < Gcm::Base
|
2
|
-
#self.table_name = "gcm_notifications"
|
3
|
-
set_collection_name "gcm_notifications"
|
4
|
-
|
5
|
-
key :collapse_key, String
|
6
|
-
key :delay_while_idle, Boolean
|
7
|
-
key :sent_at, DateTime
|
8
|
-
key :time_to_live, Integer
|
9
|
-
key :data, Hash
|
10
|
-
key :date, String
|
11
|
-
key :park_id, String
|
12
|
-
key :sport_id, String
|
13
|
-
timestamps!
|
14
|
-
|
15
|
-
include ::ActionView::Helpers::TextHelper
|
16
|
-
extend ::ActionView::Helpers::TextHelper
|
17
|
-
#serialize :data
|
18
|
-
|
19
|
-
belongs_to :device, :class_name => 'Gcm::Device'
|
20
|
-
validates_presence_of :collapse_key if :time_to_live?
|
21
|
-
|
22
|
-
class << self
|
23
|
-
# Opens a connection to the Google GCM server and attempts to batch deliver
|
24
|
-
# an Array of notifications.
|
25
|
-
#
|
26
|
-
# This method expects an Array of Gcm::Notifications. If no parameter is passed
|
27
|
-
# in then it will use the following:
|
28
|
-
# Gcm::Notification.all(:conditions => {:sent_at => nil})
|
29
|
-
#
|
30
|
-
# As each Gcm::Notification is sent the <tt>sent_at</tt> column will be timestamped,
|
31
|
-
# so as to not be sent again.
|
32
|
-
#
|
33
|
-
# This can be run from the following Rake task:
|
34
|
-
# $ rake gcm:notifications:deliver
|
35
|
-
def send_notifications(notifications = Gcm::Notification.all(:conditions => {:sent_at => nil}, :joins => :device, :readonly => false))
|
36
|
-
|
37
|
-
if configatron.gcm_on_rails.delivery_format and configatron.gcm_on_rails.delivery_format == 'plain_text'
|
38
|
-
format = "plain_text"
|
39
|
-
else
|
40
|
-
format = "json"
|
41
|
-
end
|
42
|
-
|
43
|
-
unless notifications.nil? || notifications.empty?
|
44
|
-
api_key = Gcm::Connection.open
|
45
|
-
if api_key
|
46
|
-
notifications.each do |notification|
|
47
|
-
#puts "sending notification #{notification.id} to device #{notification.device.registration_id}"
|
48
|
-
response = Gcm::Connection.send_notification(notification, api_key, format)
|
49
|
-
#puts "response: #{response[:code]}; #{response.inspect}"
|
50
|
-
if response[:code] == 200
|
51
|
-
if format == "json"
|
52
|
-
error = ""
|
53
|
-
message_data = JSON.parse response[:message]
|
54
|
-
success = message_data['success']
|
55
|
-
error = message_data['results'][0]['error'] if success == 0
|
56
|
-
else #format is plain text
|
57
|
-
message_data = response[:message]
|
58
|
-
error = response[:message].split('=')[1]
|
59
|
-
end
|
60
|
-
|
61
|
-
|
62
|
-
case error
|
63
|
-
when "MissingRegistration"
|
64
|
-
ex = Gcm::Errors::MissingRegistration.new(response[:message])
|
65
|
-
#logger.warn("#{ex.message}, destroying gcm_device with id #{notification.device.id}")
|
66
|
-
puts "#{ex.message}, destroying gcm_device with id #{notification.device.id}"
|
67
|
-
notification.device.destroy
|
68
|
-
when "InvalidRegistration"
|
69
|
-
ex = Gcm::Errors::InvalidRegistration.new(response[:message])
|
70
|
-
#logger.warn("#{ex.message}, destroying gcm_device with id #{notification.device.id}")
|
71
|
-
puts "#{ex.message}, destroying gcm_device with id #{notification.device.id}"
|
72
|
-
notification.device.destroy
|
73
|
-
when "MismatchedSenderId"
|
74
|
-
ex = Gcm::Errors::MismatchSenderId.new(response[:message])
|
75
|
-
#logger.warn(ex.message)
|
76
|
-
puts ex.message
|
77
|
-
when "NotRegistered"
|
78
|
-
ex = Gcm::Errors::NotRegistered.new(response[:message])
|
79
|
-
#logger.warn("#{ex.message}, destroying gcm_device with id #{notification.device.id}")
|
80
|
-
puts "#{ex.message}, destroying gcm_device with id #{notification.device.id}"
|
81
|
-
notification.device.destroy
|
82
|
-
when "MessageTooBig"
|
83
|
-
ex = Gcm::Errors::MessageTooBig.new(response[:message])
|
84
|
-
#logger.warn(ex.message)
|
85
|
-
puts ex.message
|
86
|
-
else
|
87
|
-
notification.sent_at = Time.now
|
88
|
-
notification.save!
|
89
|
-
end
|
90
|
-
elsif response[:code] == 401
|
91
|
-
raise Gcm::Errors::InvalidAuthToken.new(message_data)
|
92
|
-
elsif response[:code] == 503
|
93
|
-
raise Gcm::Errors::ServiceUnavailable.new(message_data)
|
94
|
-
elsif response[:code] == 500
|
95
|
-
raise Gcm::Errors::InternalServerError.new(message_data)
|
96
|
-
end
|
97
|
-
|
98
|
-
end
|
99
|
-
end
|
100
|
-
end
|
101
|
-
end
|
102
|
-
end
|
103
|
-
end
|
@@ -1,88 +0,0 @@
|
|
1
|
-
require 'configatron'
|
2
|
-
require 'uri'
|
3
|
-
|
4
|
-
module Gcm
|
5
|
-
module Errors
|
6
|
-
|
7
|
-
# Missing registration_id.
|
8
|
-
class MissingRegistration < StandardError
|
9
|
-
def initialize(message) # :nodoc:
|
10
|
-
super("Missing registration_id: '#{message}'")
|
11
|
-
end
|
12
|
-
end
|
13
|
-
|
14
|
-
# Invalid registration_id. Check the formatting of the registration ID that is passed to the server. Make sure
|
15
|
-
# it matches the the registration ID the phone receives in the com.google.android.c2dm.intent.REGISTRATION intent
|
16
|
-
# and that it is not being truncated or additional characters being appended
|
17
|
-
class InvalidRegistration < StandardError
|
18
|
-
def initialize(message) # :nodoc:
|
19
|
-
super("Invalid registration_id: '#{message}'")
|
20
|
-
end
|
21
|
-
end
|
22
|
-
|
23
|
-
# A registration ID is tied to a certain group of senders. When an application registers for GCM usage, it must
|
24
|
-
# specify which senders are allowed to send messages.
|
25
|
-
class MismatchSenderId < StandardError
|
26
|
-
def initialize(message) # :nodoc
|
27
|
-
super("Mismatched Sender Id: '#{message}'")
|
28
|
-
end
|
29
|
-
end
|
30
|
-
|
31
|
-
# From Google:-
|
32
|
-
# An existing registration ID may cease to be valid in a number of scenarios, including:
|
33
|
-
# - If the application manually unregisters
|
34
|
-
# - If the application is automatically unregistered which can (but not guaranteed) to happen if the user
|
35
|
-
# uninstalls the application
|
36
|
-
# - If the registration ID expires. Google might decide to refresh registration IDs
|
37
|
-
#
|
38
|
-
# For all cases above, it is recommended that this registration ID is removed from the 3rd party server
|
39
|
-
class NotRegistered < StandardError
|
40
|
-
def initialize(message) # :nodoc
|
41
|
-
super("The registration_id is no longer valid: '#{message}'")
|
42
|
-
end
|
43
|
-
end
|
44
|
-
|
45
|
-
# The payload of the message is too big, the limit is currently 4096
|
46
|
-
# bytes. Reduce the size of the message.
|
47
|
-
class MessageTooBig < StandardError
|
48
|
-
def initialize(message) # :nodoc:
|
49
|
-
super("The maximum size allowed for a notification payload is 4096 bytes: '#{message}'")
|
50
|
-
end
|
51
|
-
end
|
52
|
-
|
53
|
-
# ClientLogin AUTH_TOKEN is invalid. Check the config
|
54
|
-
class InvalidAuthToken < StandardError
|
55
|
-
def initialize(message)
|
56
|
-
super("Invalid auth token: '#{message}'")
|
57
|
-
end
|
58
|
-
end
|
59
|
-
|
60
|
-
# Indicates that server is temporarily unavailable (i.e because of timeouts, etc.)
|
61
|
-
# Sender must retry later, honoring any Retry-After header included in the response.
|
62
|
-
# Application servers must implement exponential back-off
|
63
|
-
class ServiceUnavailable < StandardError
|
64
|
-
def initialize(message)
|
65
|
-
super("Service is currently unavailable. Try again later: '#{message}'")
|
66
|
-
end
|
67
|
-
end
|
68
|
-
|
69
|
-
# Indicates an internal server error with the GCM server
|
70
|
-
class InternalServerError < StandardError
|
71
|
-
def initialize(message)
|
72
|
-
super("The was an internal error in the GCM server while trying to process the request: '#{message}'")
|
73
|
-
end
|
74
|
-
end
|
75
|
-
end
|
76
|
-
|
77
|
-
Dir.glob(File.join(File.dirname(__FILE__), 'app', 'models', 'gcm', '*.rb')).sort.each do |f|
|
78
|
-
require f
|
79
|
-
end
|
80
|
-
|
81
|
-
%w{ models controllers helpers }.each do |dir|
|
82
|
-
path = File.join(File.dirname(__FILE__), 'app', dir)
|
83
|
-
$LOAD_PATH << path
|
84
|
-
# puts "Adding #{path}"
|
85
|
-
#ActiveSupport::Dependencies.autoload_paths << path
|
86
|
-
#ActiveSupport::Dependencies.autoload_once_paths.delete(path)
|
87
|
-
end
|
88
|
-
end
|
@@ -1,44 +0,0 @@
|
|
1
|
-
require 'net/https'
|
2
|
-
require 'uri'
|
3
|
-
|
4
|
-
module Gcm
|
5
|
-
module Connection
|
6
|
-
class << self
|
7
|
-
def send_notification(notification, api_key, format)
|
8
|
-
|
9
|
-
if format == 'json'
|
10
|
-
headers = {"Content-Type" => "application/json",
|
11
|
-
"Authorization" => "key=#{api_key}"}
|
12
|
-
|
13
|
-
data = notification.data.merge({:collapse_key => notification.collapse_key}) unless notification.collapse_key.nil?
|
14
|
-
data = data.merge({:delay_while_idle => notification.delay_while_idle}) unless notification.delay_while_idle.nil?
|
15
|
-
data = data.merge({:time_to_live => notification.time_to_live}) unless notification.time_to_live.nil?
|
16
|
-
data = data.to_json
|
17
|
-
else #plain text format
|
18
|
-
headers = {"Content-Type" => "application/x-www-form-urlencoded;charset=UTF-8",
|
19
|
-
"Authorization" => "key=#{api_key}"}
|
20
|
-
|
21
|
-
post_data = notification.data[:data].map{|k, v| "&data.#{k}=#{URI.escape(v)}".reduce{|k, v| k + v}}[0]
|
22
|
-
extra_data = "registration_id=#{notification.data[:registration_ids][0]}"
|
23
|
-
extra_data = "#{extra_data}&collapse_key=#{notification.collapse_key}" unless notification.collapse_key.nil?
|
24
|
-
extra_data = "#{extra_data}&delay_while_idle=1" if notification.delay_while_idle
|
25
|
-
data = "#{extra_data}#{post_data}"
|
26
|
-
end
|
27
|
-
|
28
|
-
url_string = configatron.gcm_on_rails.api_url
|
29
|
-
url = URI.parse url_string
|
30
|
-
http = Net::HTTP.new(url.host, url.port)
|
31
|
-
http.use_ssl = true
|
32
|
-
http.verify_mode = OpenSSL::SSL::VERIFY_NONE
|
33
|
-
|
34
|
-
resp, dat = http.post(url.path, data, headers)
|
35
|
-
|
36
|
-
return {:code => resp.code.to_i, :message => dat }
|
37
|
-
end
|
38
|
-
|
39
|
-
def open
|
40
|
-
configatron.gcm_on_rails.api_key
|
41
|
-
end
|
42
|
-
end
|
43
|
-
end
|
44
|
-
end
|