apns_polite 0.9.0

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 ADDED
@@ -0,0 +1,17 @@
1
+ *.gem
2
+ *.rbc
3
+ .bundle
4
+ .config
5
+ .yardoc
6
+ Gemfile.lock
7
+ InstalledFiles
8
+ _yardoc
9
+ coverage
10
+ doc/
11
+ lib/bundler/man
12
+ pkg
13
+ rdoc
14
+ spec/reports
15
+ test/tmp
16
+ test/version_tmp
17
+ tmp
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source 'https://rubygems.org'
2
+
3
+ # Specify your gem's dependencies in apns_polite.gemspec
4
+ gemspec
data/LICENSE.txt ADDED
@@ -0,0 +1,22 @@
1
+ Copyright (c) 2012 sugiyama-mitsunari
2
+
3
+ MIT License
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining
6
+ a copy of this software and associated documentation files (the
7
+ "Software"), to deal in the Software without restriction, including
8
+ without limitation the rights to use, copy, modify, merge, publish,
9
+ distribute, sublicense, and/or sell copies of the Software, and to
10
+ permit persons to whom the Software is furnished to do so, subject to
11
+ the following conditions:
12
+
13
+ The above copyright notice and this permission notice shall be
14
+ included in all copies or substantial portions of the Software.
15
+
16
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
20
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
21
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
22
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,34 @@
1
+ # ApnsPolite
2
+
3
+ Apple Push Notification Service
4
+
5
+ ## Installation
6
+
7
+ Add this line to your application's Gemfile:
8
+
9
+ gem 'apns_polite'
10
+
11
+ And then execute:
12
+
13
+ $ bundle
14
+
15
+ Or install it yourself as:
16
+
17
+ $ gem install apns_polite
18
+
19
+ ## Usage
20
+
21
+ m = ApnsPolite::Message.new 'device_token', alert: 'message sample', badge: 3
22
+ n = ApnsPolite::Notification.new host: "gateway.push.apple.com", port: 2195, pem: "pem path", password: "pem password"
23
+
24
+ n.push m
25
+
26
+ n.close
27
+
28
+ ## Contributing
29
+
30
+ 1. Fork it
31
+ 2. Create your feature branch (`git checkout -b my-new-feature`)
32
+ 3. Commit your changes (`git commit -am 'Add some feature'`)
33
+ 4. Push to the branch (`git push origin my-new-feature`)
34
+ 5. Create new Pull Request
data/Rakefile ADDED
@@ -0,0 +1,2 @@
1
+ require "bundler/gem_tasks"
2
+
@@ -0,0 +1,19 @@
1
+ # -*- encoding: utf-8 -*-
2
+ lib = File.expand_path('../lib', __FILE__)
3
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
+ require 'apns_polite/version'
5
+
6
+ Gem::Specification.new do |gem|
7
+ gem.name = "apns_polite"
8
+ gem.version = ApnsPolite::VERSION
9
+ gem.authors = ["unchi"]
10
+ gem.email = ["unchi.he.meil.wo.okuru@gmail.com"]
11
+ gem.description = %q{apns}
12
+ gem.summary = %q{apns}
13
+ gem.homepage = "https://github.com/unchi/apns_polite"
14
+
15
+ gem.files = `git ls-files`.split($/)
16
+ gem.executables = gem.files.grep(%r{^bin/}).map{ |f| File.basename(f) }
17
+ gem.test_files = gem.files.grep(%r{^(test|spec|features)/})
18
+ gem.require_paths = ["lib"]
19
+ end
@@ -0,0 +1,6 @@
1
+ $:.unshift File.dirname(__FILE__)
2
+
3
+ require 'apns_polite/message'
4
+ require 'apns_polite/feedback'
5
+ require 'apns_polite/notification'
6
+
@@ -0,0 +1,69 @@
1
+ # encoding: utf-8
2
+
3
+ module ApnsPolite
4
+
5
+ require 'socket'
6
+ require 'openssl'
7
+
8
+ class Feedback
9
+ # 初期化
10
+ def initialize(options=nil)
11
+ if options
12
+ host = options[:host]
13
+ pem = options[:pem]
14
+ port = options[:port]
15
+ password = options[:password]
16
+
17
+ connection host, port, pem, password
18
+ end
19
+ end
20
+ # 接続
21
+ def connection(host, port, pem, password=nil)
22
+ @host = host || 'gateway.sandbox.push.apple.com'
23
+ @port = port || 2195
24
+ @pem = pem
25
+ @password = password
26
+
27
+ reconnection
28
+ end
29
+ # 再接続
30
+ def reconnection
31
+ close
32
+
33
+ raise "The path to your pem file is not set." unless @pem
34
+ raise "The path to your pem file does not exist!" unless File.exist?(@pem)
35
+
36
+ pemText = File.read @pem
37
+
38
+ context = OpenSSL::SSL::SSLContext.new
39
+ context.cert = OpenSSL::X509::Certificate.new pemText
40
+ context.key = OpenSSL::PKey::RSA.new pemText, @password
41
+
42
+ sock = TCPSocket.new @host, @port
43
+ ssl = OpenSSL::SSL::SSLSocket.new sock, context
44
+ ssl.connect
45
+
46
+ @sock = sock
47
+ @ssl = ssl
48
+ end
49
+ # 切断
50
+ def close
51
+ @ssl.close if @ssl
52
+ @sock.close if @sock
53
+ end
54
+ # 取得
55
+ def stream(&block)
56
+
57
+ while line = @sock.gets
58
+ payload = line.strip.unpack('N1n1H140')
59
+ if payload and payload.length >= 3
60
+ yield payload[2], payload[0]
61
+ end
62
+ end
63
+
64
+ end
65
+
66
+ end
67
+
68
+ end # end of module
69
+
@@ -0,0 +1,44 @@
1
+ # encoding: utf-8
2
+
3
+ module ApnsPolite
4
+
5
+ require 'json'
6
+
7
+ class Message
8
+
9
+ # 初期化
10
+ def initialize(device_token, message)
11
+
12
+ t = package_device_token device_token
13
+
14
+ if message.is_a? Hash
15
+ m = package_message message[:alert], message[:badge], message[:sound], message[:other]
16
+ else
17
+ m = package_message message.to_s
18
+ end
19
+
20
+ @pack = [0, 0, 32, t, 0, m.bytesize, m].pack("ccca*cca*")
21
+ end
22
+ # パックしたメッセージ取得
23
+ def pack
24
+ @pack
25
+ end
26
+
27
+ private
28
+ # device token パッケージ化
29
+ def package_device_token(device_token)
30
+ [device_token.gsub(/[\s|<|>]/,'')].pack('H*')
31
+ end
32
+ # message パッケージ化
33
+ def package_message(alert, badge=nil, sound=nil, options=nil)
34
+ a = { 'aps' => {} }
35
+ a['aps']['alert'] = alert if alert
36
+ a['aps']['badge'] = badge if badge
37
+ a['aps']['sound'] = sound if sound
38
+ a.merge! options if options
39
+ a.to_json
40
+ end
41
+ end
42
+
43
+ end # end of module
44
+
@@ -0,0 +1,63 @@
1
+ # encoding: utf-8
2
+
3
+ module ApnsPolite
4
+
5
+ require 'socket'
6
+ require 'openssl'
7
+
8
+ class Notification
9
+ # 初期化
10
+ def initialize(options = nil)
11
+ if options
12
+ host = options[:host]
13
+ pem = options[:pem]
14
+ port = options[:port]
15
+ password = options[:password]
16
+
17
+ connection host, port, pem, password
18
+ end
19
+ end
20
+ # 接続
21
+ def connection(host, port, pem, password=nil)
22
+
23
+ @host = host || 'gateway.sandbox.push.apple.com'
24
+ @port = port || 2195
25
+ @pem = pem
26
+ @password = password
27
+
28
+ reconnection
29
+ end
30
+ # 再接続
31
+ def reconnection
32
+ close
33
+
34
+ raise "The path to your pem file is not set." unless @pem
35
+ raise "The path to your pem file does not exist!" unless File.exist?(@pem)
36
+
37
+ pemText = File.read @pem
38
+
39
+ context = OpenSSL::SSL::SSLContext.new
40
+ context.cert = OpenSSL::X509::Certificate.new pemText
41
+ context.key = OpenSSL::PKey::RSA.new pemText, @password
42
+
43
+ sock = TCPSocket.new @host, @port
44
+ ssl = OpenSSL::SSL::SSLSocket.new sock, context
45
+ ssl.connect
46
+
47
+ @sock = sock
48
+ @ssl = ssl
49
+ end
50
+ # 切断
51
+ def close
52
+ @ssl.close if @ssl
53
+ @sock.close if @sock
54
+ end
55
+ # 通知
56
+ def push(message)
57
+ @ssl.write message.pack
58
+ end
59
+
60
+ end
61
+
62
+ end # end of module
63
+
@@ -0,0 +1,3 @@
1
+ module ApnsPolite
2
+ VERSION = "0.9.0"
3
+ end
@@ -0,0 +1,37 @@
1
+ require File.dirname(__FILE__) + '/../spec_helper'
2
+
3
+ describe ApnsPolite::Feedback do
4
+ module F
5
+ PEM = '/home/homepage/html/apns.pem'
6
+ HOST = 'feedback.push.apple.com'
7
+ PORT = 2196
8
+ PASSWORD = nil
9
+ end
10
+
11
+ it "new arg 0" do
12
+ ApnsPolite::Feedback.new
13
+ end
14
+
15
+ it "new" do
16
+ ApnsPolite::Feedback.new host: F::HOST, port: F::PORT, pem: F::PEM, password: F::PASSWORD
17
+ end
18
+
19
+ it "connect" do
20
+ a = ApnsPolite::Feedback.new
21
+ a.connection F::HOST, F::PORT, F::PEM, F::PASSWORD
22
+ end
23
+
24
+ it "reconnect" do
25
+ a = ApnsPolite::Feedback.new host: F::HOST, port: F::PORT, pem: F::PEM, password: F::PASSWORD
26
+ a.reconnection
27
+ end
28
+
29
+ it 'stream' do
30
+ a = ApnsPolite::Feedback.new host: F::HOST, port: F::PORT, pem: F::PEM, password: F::PASSWORD
31
+ a.stream do |token, time|
32
+ p token
33
+ p time
34
+ end
35
+ end
36
+ end
37
+
@@ -0,0 +1,19 @@
1
+ require File.dirname(__FILE__) + '/../spec_helper'
2
+
3
+
4
+ describe ApnsPolite::Message do
5
+
6
+ it "new string" do
7
+ m = ApnsPolite::Message.new('device_token', 'hello wowrld')
8
+ end
9
+
10
+ it "new hash" do
11
+ m = ApnsPolite::Message.new('device_token', alert: 'message sample', badge: 3, sound: 'awesome.caf')
12
+ end
13
+
14
+ it "new hash with origin param" do
15
+ m = ApnsPolite::Message.new('device_token', alert: 'message sample', badge: 3, sound: 'awesome.caf', other: { hoge: 0 })
16
+ end
17
+
18
+ end
19
+
@@ -0,0 +1,36 @@
1
+ require File.dirname(__FILE__) + '/../spec_helper'
2
+
3
+ describe ApnsPolite::Notification do
4
+
5
+ module N
6
+ PEM = '/home/homepage/html/apns.pem'
7
+ HOST = 'gateway.push.apple.com'
8
+ PORT = 2195
9
+ PASSWORD = nil
10
+ DEVICE_TOKEN = '...'
11
+ end
12
+
13
+ it "new arg 0" do
14
+ ApnsPolite::Notification.new
15
+ end
16
+
17
+ it "new" do
18
+ ApnsPolite::Notification.new host: N::HOST, port: N::PORT, pem: N::PEM, password: N::PASSWORD
19
+ end
20
+
21
+ it "connect" do
22
+ a = ApnsPolite::Notification.new
23
+ a.connection N::HOST, N::PORT, N::PEM, N::PASSWORD
24
+ end
25
+
26
+ it "reconnect" do
27
+ a = ApnsPolite::Notification.new host: N::HOST, port: N::PORT, pem: N::PEM, password: N::PASSWORD
28
+ a.reconnection
29
+ end
30
+
31
+ it 'push' do
32
+ m = ApnsPolite::Message.new(N::DEVICE_TOKEN, 'aiueo')
33
+ a = ApnsPolite::Notification.new host: N::HOST, port: N::PORT, pem: N::PEM, password: N::PASSWORD
34
+ a.push m
35
+ end
36
+ end
@@ -0,0 +1,4 @@
1
+ require 'rubygems'
2
+ require 'rspec'
3
+ require File.join(File.dirname(__FILE__), '..', 'lib', 'apns_polite')
4
+
metadata ADDED
@@ -0,0 +1,64 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: apns_polite
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.9.0
5
+ prerelease:
6
+ platform: ruby
7
+ authors:
8
+ - unchi
9
+ autorequire:
10
+ bindir: bin
11
+ cert_chain: []
12
+ date: 2012-11-26 00:00:00.000000000 Z
13
+ dependencies: []
14
+ description: apns
15
+ email:
16
+ - unchi.he.meil.wo.okuru@gmail.com
17
+ executables: []
18
+ extensions: []
19
+ extra_rdoc_files: []
20
+ files:
21
+ - .gitignore
22
+ - Gemfile
23
+ - LICENSE.txt
24
+ - README.md
25
+ - Rakefile
26
+ - apns_polite.gemspec
27
+ - lib/apns_polite.rb
28
+ - lib/apns_polite/feedback.rb
29
+ - lib/apns_polite/message.rb
30
+ - lib/apns_polite/notification.rb
31
+ - lib/apns_polite/version.rb
32
+ - spec/apns_polite/feedback_spec.rb
33
+ - spec/apns_polite/message_spec.rb
34
+ - spec/apns_polite/notification_spec.rb
35
+ - spec/spec_helper.rb
36
+ homepage: https://github.com/unchi/apns_polite
37
+ licenses: []
38
+ post_install_message:
39
+ rdoc_options: []
40
+ require_paths:
41
+ - lib
42
+ required_ruby_version: !ruby/object:Gem::Requirement
43
+ none: false
44
+ requirements:
45
+ - - ! '>='
46
+ - !ruby/object:Gem::Version
47
+ version: '0'
48
+ required_rubygems_version: !ruby/object:Gem::Requirement
49
+ none: false
50
+ requirements:
51
+ - - ! '>='
52
+ - !ruby/object:Gem::Version
53
+ version: '0'
54
+ requirements: []
55
+ rubyforge_project:
56
+ rubygems_version: 1.8.24
57
+ signing_key:
58
+ specification_version: 3
59
+ summary: apns
60
+ test_files:
61
+ - spec/apns_polite/feedback_spec.rb
62
+ - spec/apns_polite/message_spec.rb
63
+ - spec/apns_polite/notification_spec.rb
64
+ - spec/spec_helper.rb