./lib/houston.rb in houston-0.0.1 vs ./lib/houston.rb in houston-0.1.0
- old
+ new
@@ -1,147 +1,7 @@
-require 'uri'
-require 'socket'
-require 'openssl'
-require 'json'
-
module Houston
- Version = "0.0.1"
-
- APPLE_PRODUCTION_GATEWAY_URI = "apn://gateway.push.apple.com:2195"
- APPLE_PRODUCTION_FEEDBACK_URI = "apn://feedback.push.apple.com:2196"
-
- APPLE_DEVELOPMENT_GATEWAY_URI = "apn://gateway.sandbox.push.apple.com:2195"
- APPLE_DEVELOPMENT_FEEDBACK_URI = "apn://feedback.push.apple.com:2196"
-
- class Client
- attr_accessor :gateway_uri, :feedback_uri, :certificate, :passphrase
-
- def initialize
- @gateway_uri = ENV['APN_GATEWAY_URI']
- @feedback_uri = ENV['APN_FEEDBACK_URI']
- @certificate = ENV['APN_CERTIFICATE']
- @passphrase = ENV['APN_CERTIFICATE_PASSPHRASE']
- end
-
- def self.development
- client = self.new
- client.gateway_uri = APPLE_DEVELOPMENT_GATEWAY_URI
- client.feedback_uri = APPLE_DEVELOPMENT_FEEDBACK_URI
- client
- end
-
- def self.production
- client = self.new
- client.gateway_uri = APPLE_PRODUCTION_GATEWAY_URI
- client.feedback_uri = APPLE_PRODUCTION_FEEDBACK_URI
- client
- end
-
- def push(*notifications)
- Connection.open(connection_options_for_endpoint(:gateway)) do |connection, socket|
- notifications.each do |notification|
- next if notification.sent?
-
- connection.write(notification.message)
- notification.mark_as_sent!
- end
- end
- end
-
- def devices
- devices = []
-
- Connection.open(connection_options_for_endpoint(:feedback)) do |connection, socket|
- while line = connection.read(38)
- feedback = line.unpack('N1n1H140')
- token = feedback[2].scan(/.{0,8}/).join(' ').strip
- devices << token if token
- end
- end
-
- devices
- end
-
- private
-
- def connection_options_for_endpoint(endpoint = :gateway)
- uri = case endpoint
- when :gateway then URI(@gateway_uri)
- when :feedback then URI(@feedback_uri)
- else
- raise ArgumentError
- end
-
- {
- certificate: @certificate,
- passphrase: @passphrase,
- host: uri.host,
- port: uri.port
- }
- end
- end
-
- class Notification
- attr_accessor :device, :alert, :badge, :sound, :custom_data
- attr_reader :sent_at
-
- def initialize(options = {})
- @device = options.delete(:device)
- @alert = options.delete(:alert)
- @badge = options.delete(:badge)
- @sound = options.delete(:sound)
-
- @custom_data = options
- end
-
- def payload
- json = {}.merge(@custom_data || {})
- json['aps'] = {}
- json['aps']['alert'] = @alert
- json['aps']['badge'] = @badge.to_i rescue 0
- json['aps']['sound'] = @sound
-
- json
- end
-
- def message
- json = payload.to_json
-
- "\0\0 #{[@device.gsub(/[<\s>]/, '')].pack('H*')}\0#{json.length.chr}#{json}"
- end
-
- def mark_as_sent!
- @sent_at = Time.now
- end
-
- def sent?
- !!@sent_at
- end
- end
-
- class Connection
- class << self
- def open(options = {})
- return unless block_given?
-
- [:certificate, :passphrase, :host, :port].each do |option|
- raise ArgumentError, "Missing connection parameter: #{option}" unless option
- end
-
- socket = TCPSocket.new(options[:host], options[:port])
-
- context = OpenSSL::SSL::SSLContext.new
- context.key = OpenSSL::PKey::RSA.new(options[:certificate], options[:passphrase])
- context.cert = OpenSSL::X509::Certificate.new(options[:certificate])
-
- ssl = OpenSSL::SSL::SSLSocket.new(socket, context)
- ssl.sync = true
- ssl.connect
-
- yield ssl, socket
-
- ssl.close
- socket.close
- end
- end
- end
+ VERSION = "0.1.0"
end
+
+require 'houston/client'
+require 'houston/notification'
+require 'houston/connection'