xtify 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
data/Gemfile ADDED
@@ -0,0 +1,11 @@
1
+ source "http://rubygems.org"
2
+
3
+ group :development do
4
+ gem "shoulda-context", ">= 0"
5
+ gem "bundler", "~> 1.2.3"
6
+ gem "jeweler", "~> 1.8.4"
7
+ gem "webmock", "~> 1.9.0"
8
+ end
9
+
10
+ gem 'curb'
11
+ gem 'activesupport'
@@ -0,0 +1,36 @@
1
+ GEM
2
+ remote: http://rubygems.org/
3
+ specs:
4
+ activesupport (3.2.11)
5
+ i18n (~> 0.6)
6
+ multi_json (~> 1.0)
7
+ addressable (2.3.2)
8
+ crack (0.3.2)
9
+ curb (0.8.3)
10
+ git (1.2.5)
11
+ i18n (0.6.1)
12
+ jeweler (1.8.4)
13
+ bundler (~> 1.0)
14
+ git (>= 1.2.5)
15
+ rake
16
+ rdoc
17
+ json (1.7.6)
18
+ multi_json (1.5.0)
19
+ rake (10.0.3)
20
+ rdoc (3.12)
21
+ json (~> 1.4)
22
+ shoulda-context (1.0.2)
23
+ webmock (1.9.0)
24
+ addressable (>= 2.2.7)
25
+ crack (>= 0.1.7)
26
+
27
+ PLATFORMS
28
+ ruby
29
+
30
+ DEPENDENCIES
31
+ activesupport
32
+ bundler (~> 1.2.3)
33
+ curb
34
+ jeweler (~> 1.8.4)
35
+ shoulda-context
36
+ webmock (~> 1.9.0)
@@ -0,0 +1,2 @@
1
+ xtify
2
+ =====
@@ -0,0 +1,32 @@
1
+ require 'rubygems'
2
+ require 'bundler'
3
+
4
+ begin
5
+ Bundler.setup(:default, :development)
6
+ rescue Bundler::BundlerError => e
7
+ $stderr.puts e.message
8
+ $stderr.puts "Run `bundle install` to install missing gems"
9
+ exit e.status_code
10
+ end
11
+
12
+ require 'rake'
13
+
14
+ require 'jeweler'
15
+ Jeweler::Tasks.new do |gem|
16
+ # gem is a Gem::Specification... see http://docs.rubygems.org/read/chapter/20 for more options
17
+ gem.name = "xtify"
18
+ gem.homepage = "http://github.com/moxiespaces/xtify"
19
+ gem.license = "MIT"
20
+ gem.summary = %Q{Client library for Xtify's API}
21
+ gem.description = gem.summary
22
+ gem.email = "jbell@moxiesoft.com"
23
+ gem.authors = ['Jonathan Bell']
24
+ # Do not add dependencies here because Jewler will add them from the Gemfile
25
+ end
26
+
27
+ require 'rake/testtask'
28
+ Rake::TestTask.new(:test) do |test|
29
+ test.libs << 'lib' << 'test'
30
+ test.pattern = 'test/**/*_test.rb'
31
+ test.verbose = true
32
+ end
data/VERSION ADDED
@@ -0,0 +1 @@
1
+ 0.0.1
@@ -0,0 +1,24 @@
1
+ require 'curl'
2
+ require 'active_support/all'
3
+
4
+ module Xtify
5
+ autoload :Config, 'xtify/config'
6
+ autoload :Model, 'xtify/model'
7
+ autoload :Device, 'xtify/device'
8
+ autoload :Action, 'xtify/action'
9
+ autoload :Message, 'xtify/message'
10
+ autoload :Commands, 'xtify/commands'
11
+
12
+ def self.config
13
+ @config
14
+ end
15
+
16
+ def self.configure(&block)
17
+ @config = Config.new
18
+ yield @config
19
+ end
20
+
21
+ extend Commands
22
+ end
23
+
24
+ require 'xtify/errors'
@@ -0,0 +1,24 @@
1
+ module Xtify
2
+ class Action
3
+ include Model
4
+
5
+ xtify_model :type, :data, :label
6
+
7
+ TYPES = {
8
+ :url => "URL",
9
+ :rich => "RICH",
10
+ :custom => "CUSTOM",
11
+ :phone => "PHONE",
12
+ :default => "DEFAULT",
13
+ :none => "NONE"
14
+ }
15
+
16
+ RICH_TYPES = {
17
+ :web => "WEB",
18
+ :phone => "PHN",
19
+ :custom => "CST",
20
+ :default => "DEFAULT",
21
+ :none => "NONE"
22
+ }
23
+ end
24
+ end
@@ -0,0 +1,149 @@
1
+ module Xtify
2
+ module Commands
3
+
4
+ API_V2 = "http://api.xtify.com/2.0"
5
+
6
+ # Register and return a device with the provided details which
7
+ # can be used to refer to this device in the Xtify system.
8
+ # Calling this endpoint with a device that is already
9
+ # registered will result in the existing device being returned.
10
+ #
11
+ # Parameters:
12
+ # - install_id -> (Required) This id along with your application key will
13
+ # uniquely identify your user in our system
14
+ # and is used to manage uninstalls/reinstalls
15
+ # and mapping registrations to existing users.
16
+ # It does not have to be the device’s IMEI or
17
+ # true device identifier. This must be unique
18
+ # for every user of your application.
19
+ #
20
+ # Please note: If you use a custom install ID and
21
+ # call the registration service from the same device
22
+ # (ie same device token) multiple times with the same
23
+ # install ID, the user will receive multiple messages.
24
+ #
25
+ # - type -> (Required) The SDK device type you have implemented in your app.
26
+ #
27
+ # Values restricted to: Xtify::Device::TYPES
28
+ #
29
+ # - device_token -> The Apple provided deviceToken received by registering
30
+ # with APNS
31
+ #
32
+ # - registration_id -> The Google provided registrationId received by
33
+ # registering with google’s cloud to device service.
34
+ #
35
+ # - blackberry_pin -> The RIM provided device PIN received by registering
36
+ # with the BlackBerry Push service.
37
+ #
38
+ # - user_key -> An optional customer defined key which can be
39
+ # associated with this user. Available to premium/enterprise
40
+ # customers.
41
+ #
42
+ # - install_date -> Install date of this user.
43
+ #
44
+ # - badge -> Current badge for iOS only
45
+ #
46
+ # - v_os -> The operating system version of the device.
47
+ #
48
+ # - model -> The model name/number of the device.
49
+ #
50
+ # - carrier -> The carrier in use by the device.
51
+ #
52
+ # - Returns a Xtify ID for device
53
+ def register_device(opts={})
54
+ validate_arguments('register_device', opts, :install_id, :type)
55
+ validate_in_set('register_device', :type, opts, Device::TYPES.values)
56
+
57
+ args = convert_to_args(opts,
58
+ :blackberry_pin => 'blackberryPIN',
59
+ :v_os => 'vOS'
60
+ )
61
+
62
+ result = post('users/register', args)
63
+ Device.new(result)
64
+ end
65
+
66
+ # The Xtify Push API allows you to immediately send a message to a set of users that
67
+ # you can select by Device, positive or negative tags, or a "send to all" flag. By
68
+ # exposing our push interface via API, you can generate timely one-off notifications
69
+ # and event-based messages from within your own service either by hand or automatically.
70
+ #
71
+ # - devices -> A device or array of devices to send message to
72
+ # - has_tags -> All devices with these tags will receive message
73
+ # - not_tags -> All devices without these tags will receive message
74
+ # - send_all -> All users of the application will recieve message
75
+ # - index_only -> Index only indicator for rich message
76
+ # - content -> Message or Hash of message
77
+ def push(opts={})
78
+ xids = Array.wrap(opts.delete(:devices)).map {|d| d.is_a?(Device) ? d.xid : d}
79
+ has_tags = Array.wrap(opts.delete(:has_tags))
80
+ not_tags = Array.wrap(opts.delete(:not_tags))
81
+ content = opts.delete(:content)
82
+ unless content.is_a?(Message)
83
+ content = Message.new(opts)
84
+ end
85
+
86
+ args = convert_to_args(opts)
87
+ args[:apiKey] = config.api_key
88
+ args[:content] = content
89
+ args[:xids] = xids unless xids.empty?
90
+ args[:hasTags] = has_tags unless has_tags.empty?
91
+ args[:notTags] = not_tags unless not_tags.empty?
92
+
93
+ post('push', args)
94
+ end
95
+
96
+ protected
97
+
98
+ def convert_to_args(opts, mappings={})
99
+ args = {}
100
+ opts.each do |key, value|
101
+ mapped_to = mappings[key]
102
+ if mapped_to
103
+ args[mapped_to] = value
104
+ else
105
+ camelized = key.to_s.camelcase(:lower).gsub(/Id/, 'ID')
106
+ args[camelized] = value
107
+ end
108
+ end
109
+ args
110
+ end
111
+
112
+ def validate_arguments(command, args, *keys)
113
+ missing = []
114
+
115
+ keys.each do |key|
116
+ missing << key unless args[key]
117
+ end
118
+
119
+ raise InvalidRequest.new("Must specify #{missing.join(",")} when requesting #{command}.") unless missing.empty?
120
+ true
121
+ end
122
+
123
+ def validate_in_set(command, key, opts, set)
124
+ unless set.include?(opts[key])
125
+ raise InvalidRequest.new("#{key} must be one of: #{set.join(", ")} when requesting #{command}")
126
+ end
127
+ end
128
+
129
+ def post(command, opts)
130
+ args = opts.dup
131
+ raise ConfigError.new("Must specify app_key in Xtify initializer.") unless Xtify.config.app_key
132
+ args[:appKey] = Xtify.config.app_key
133
+
134
+ response = Curl::Easy.perform(File.join(API_V2, command)) do |curl|
135
+ curl.verbose = config.verbose
136
+ curl.headers['Content-Type'] = 'application/json'
137
+ curl.post_body = args.to_json
138
+ end
139
+
140
+ if response.response_code == 200
141
+ JSON.parse(response.body_str)
142
+ elsif response.response_code == 202
143
+ true
144
+ else
145
+ raise CommandFailure.new("Error performing: #{command}: #{response.body_str}")
146
+ end
147
+ end
148
+ end
149
+ end
@@ -0,0 +1,5 @@
1
+ module Xtify
2
+ class Config
3
+ attr_accessor :app_key, :api_key, :verbose
4
+ end
5
+ end
@@ -0,0 +1,13 @@
1
+ module Xtify
2
+ class Device
3
+ include Model
4
+
5
+ xtify_model :xid
6
+
7
+ TYPES = {
8
+ :apple => "IOS",
9
+ :blackberry => "BLACKBERRY",
10
+ :android => "GCM"
11
+ }
12
+ end
13
+ end
@@ -0,0 +1,13 @@
1
+ module Xtify
2
+ class Error < StandardError
3
+ end
4
+
5
+ class ConfigError < Error
6
+ end
7
+
8
+ class InvalidRequest < Error
9
+ end
10
+
11
+ class CommandFailure < Error
12
+ end
13
+ end
@@ -0,0 +1,15 @@
1
+ module Xtify
2
+ class Message
3
+ include Model
4
+
5
+ xtify_model :subject, :message, :payload, :sound, :badge
6
+
7
+ one :action
8
+ one :rich, :type => Message
9
+
10
+ # See Xtify.push
11
+ def push(opts={})
12
+ Xtify.push(opts.merge(:content => self))
13
+ end
14
+ end
15
+ end
@@ -0,0 +1,59 @@
1
+ module Xtify
2
+ module Model
3
+ extend ActiveSupport::Concern
4
+
5
+ included do
6
+ def self.xtify_model(*fields)
7
+ @fields = fields
8
+ attr_accessor *fields
9
+ end
10
+
11
+ def self.one(assoc, opts={})
12
+ @one_associations ||= {}
13
+ @one_associations[assoc] = opts
14
+ attr_accessor assoc
15
+ end
16
+
17
+ def self.fields
18
+ @fields || []
19
+ end
20
+
21
+ def self.one_associations
22
+ @one_associations ||= {}
23
+ end
24
+ end
25
+
26
+ def fields
27
+ self.class.fields
28
+ end
29
+
30
+ def one_associations
31
+ self.class.one_associations
32
+ end
33
+
34
+ def initialize(opts={})
35
+ opts = opts.symbolize_keys
36
+ fields.each do |field|
37
+ self.send("#{field}=", opts[field])
38
+ end
39
+
40
+ one_associations.each do |assoc, assoc_opts|
41
+ value = opts[assoc]
42
+ if value.is_a?(Hash)
43
+ klass = assoc_opts[:type] || File.join("xtify", assoc.to_s).classify.constantize
44
+ value = klass.new(value)
45
+ end
46
+ self.send("#{assoc}=", value)
47
+ end
48
+ end
49
+
50
+ def as_json(opts={})
51
+ json = {}
52
+ (fields + one_associations.keys).each do |field|
53
+ value = send(field)
54
+ json[field] = value unless value.blank?
55
+ end
56
+ json
57
+ end
58
+ end
59
+ end
@@ -0,0 +1,29 @@
1
+ require 'rubygems'
2
+ require 'bundler'
3
+ begin
4
+ Bundler.setup(:default, :development)
5
+ rescue Bundler::BundlerError => e
6
+ $stderr.puts e.message
7
+ $stderr.puts "Run `bundle install` to install missing gems"
8
+ exit e.status_code
9
+ end
10
+ require 'webmock/test_unit'
11
+ require 'shoulda-context'
12
+
13
+
14
+ $LOAD_PATH.unshift(File.join(File.dirname(__FILE__), '..', 'lib'))
15
+ $LOAD_PATH.unshift(File.dirname(__FILE__))
16
+ require 'xtify'
17
+
18
+ Xtify.configure do |config|
19
+ config.app_key = 'FAKE_APP_KEY'
20
+ config.api_key = 'FAKE_API_KEY'
21
+ config.verbose = false
22
+ end
23
+
24
+ class Test::Unit::TestCase
25
+ def stub_xtify_post(url, data)
26
+ stub_http_request(:post, File.join(Xtify::Commands::API_V2, url)).
27
+ with(:body => data)
28
+ end
29
+ end
@@ -0,0 +1,83 @@
1
+ require File.expand_path('../helper', __FILE__)
2
+
3
+ class MessageTest < Test::Unit::TestCase
4
+ context "A new message" do
5
+ setup do
6
+ @message = Xtify::Message.new(
7
+ :subject => "Fake Subject",
8
+ :message => "Fake Message",
9
+ :action => {
10
+ :type => Xtify::Action::TYPES[:rich],
11
+ :data => "fake data",
12
+ :label => "fake label"
13
+ },
14
+ :rich => {
15
+ :subject => "Fake Rich Subject",
16
+ :message => "Fake Rich Message",
17
+ :action => {
18
+ :type => Xtify::Action::RICH_TYPES[:web],
19
+ :data => "fake rich data",
20
+ :label => "fake rich label"
21
+ }
22
+ },
23
+ :payload => {:key1 => 'key2'},
24
+ :sound => 'default.csf',
25
+ :badge => "+1"
26
+ )
27
+ end
28
+
29
+ should "properly set associations" do
30
+ assert @message.action, "Action is missing"
31
+ assert_equal "fake data", @message.action.data, "Action's data is wrong"
32
+
33
+ assert @message.rich, "Rich is missing"
34
+ assert @message.rich.action, "Rich action is missing"
35
+ assert_equal "fake rich data", @message.rich.action.data, "Rich's action's data is wrongs"
36
+ end
37
+
38
+ context "that is pushed" do
39
+ setup do
40
+ stub_xtify_post('push',
41
+ "apiKey" => "FAKE_API_KEY",
42
+ "appKey" => "FAKE_APP_KEY",
43
+ "xids" => ["ABC123"],
44
+ "hasTags" => ["apple", "banana"],
45
+ "sendAll" => true,
46
+ "inboxOnly" => false,
47
+ "content" => {
48
+ "subject" => "Fake Subject",
49
+ "message" => "Fake Message",
50
+ "action" => {
51
+ "type" => "RICH",
52
+ "data" => "fake data",
53
+ "label" => "fake label"
54
+ },
55
+ "rich" => {
56
+ "subject" => "Fake Rich Subject",
57
+ "message" => "Fake Rich Message",
58
+ "action" => {
59
+ "type" => "WEB",
60
+ "data" => "fake rich data",
61
+ "label" => "fake rich label"
62
+ }
63
+ },
64
+ "payload" => {"key1" => "key2"},
65
+ "sound" => "default.csf",
66
+ "badge" => "+1"
67
+ }
68
+ ).to_return(:status => 202)
69
+
70
+ @message.push(
71
+ :devices => "ABC123",
72
+ :has_tags => ["apple", "banana"],
73
+ :send_all => true,
74
+ :inbox_only => false
75
+ )
76
+ end
77
+
78
+ should "return success" do
79
+ true
80
+ end
81
+ end
82
+ end
83
+ end
@@ -0,0 +1,78 @@
1
+ require File.expand_path('../helper', __FILE__)
2
+
3
+ class RegistrationTest < Test::Unit::TestCase
4
+ context "Register an apple device" do
5
+ setup do
6
+ @xid = "ABC123"
7
+
8
+ stub_xtify_post('users/register',
9
+ :appKey => 'FAKE_APP_KEY',
10
+ :installID => 'fake_user',
11
+ :type => 'IOS',
12
+ :deviceToken => 'fake_device_token'
13
+ ).to_return(
14
+ :status => 200,
15
+ :body => "{\"xid\":\"#{@xid}\"}"
16
+ )
17
+
18
+ @device = Xtify.register_device(
19
+ :install_id => 'fake_user',
20
+ :type => Xtify::Device::TYPES[:apple],
21
+ :device_token => 'fake_device_token')
22
+ end
23
+
24
+ should "return expected device" do
25
+ assert @device, "Device was not returned"
26
+ assert_equal @xid, @device.xid, "Unexpected xid returned"
27
+ end
28
+ end
29
+
30
+ context "Register an google device" do
31
+ setup do
32
+ @xid = "ABC123"
33
+
34
+ stub_xtify_post('users/register',
35
+ :appKey => 'FAKE_APP_KEY',
36
+ :installID => 'fake_user',
37
+ :type => 'GCM',
38
+ :registrationID => 'fake_registration_id'
39
+ ).to_return(
40
+ :status => 200,
41
+ :body => "{\"xid\":\"#{@xid}\"}"
42
+ )
43
+
44
+ @device = Xtify.register_device(
45
+ :install_id => 'fake_user',
46
+ :type => Xtify::Device::TYPES[:android],
47
+ :registration_id => 'fake_registration_id')
48
+ end
49
+
50
+ should "return expected device" do
51
+ assert @device, "Device was not returned"
52
+ assert_equal @xid, @device.xid, "Unexpected xid returned"
53
+ end
54
+ end
55
+
56
+ context "Register a device with an invalid type" do
57
+
58
+ should "raise an InvalidRequest" do
59
+ assert_raises Xtify::InvalidRequest do
60
+ @device = Xtify.register_device(
61
+ :install_id => 'fake_user',
62
+ :type => 'FAKE_TYPE',
63
+ :registration_id => 'fake_registration_id')
64
+ end
65
+ end
66
+ end
67
+
68
+ context "Register a device with no install id" do
69
+
70
+ should "raise an InvalidRequest" do
71
+ assert_raises Xtify::InvalidRequest do
72
+ @device = Xtify.register_device(
73
+ :type => Xtify::Device::TYPES[:android],
74
+ :registration_id => 'fake_registration_id')
75
+ end
76
+ end
77
+ end
78
+ end
@@ -0,0 +1,70 @@
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 = "xtify"
8
+ s.version = "0.0.1"
9
+
10
+ s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
11
+ s.authors = ["Jonathan Bell"]
12
+ s.date = "2013-05-07"
13
+ s.description = "Client library for Xtify's API"
14
+ s.email = "jbell@moxiesoft.com"
15
+ s.extra_rdoc_files = [
16
+ "README.md"
17
+ ]
18
+ s.files = [
19
+ "Gemfile",
20
+ "Gemfile.lock",
21
+ "README.md",
22
+ "Rakefile",
23
+ "VERSION",
24
+ "lib/xtify.rb",
25
+ "lib/xtify/action.rb",
26
+ "lib/xtify/commands.rb",
27
+ "lib/xtify/config.rb",
28
+ "lib/xtify/device.rb",
29
+ "lib/xtify/errors.rb",
30
+ "lib/xtify/message.rb",
31
+ "lib/xtify/model.rb",
32
+ "test/helper.rb",
33
+ "test/message_test.rb",
34
+ "test/registration_test.rb",
35
+ "xtify.gemspec"
36
+ ]
37
+ s.homepage = "http://github.com/moxiespaces/xtify"
38
+ s.licenses = ["MIT"]
39
+ s.require_paths = ["lib"]
40
+ s.rubygems_version = "1.8.10"
41
+ s.summary = "Client library for Xtify's API"
42
+
43
+ if s.respond_to? :specification_version then
44
+ s.specification_version = 3
45
+
46
+ if Gem::Version.new(Gem::VERSION) >= Gem::Version.new('1.2.0') then
47
+ s.add_runtime_dependency(%q<curb>, [">= 0"])
48
+ s.add_runtime_dependency(%q<activesupport>, [">= 0"])
49
+ s.add_development_dependency(%q<shoulda-context>, [">= 0"])
50
+ s.add_development_dependency(%q<bundler>, ["~> 1.2.3"])
51
+ s.add_development_dependency(%q<jeweler>, ["~> 1.8.4"])
52
+ s.add_development_dependency(%q<webmock>, ["~> 1.9.0"])
53
+ else
54
+ s.add_dependency(%q<curb>, [">= 0"])
55
+ s.add_dependency(%q<activesupport>, [">= 0"])
56
+ s.add_dependency(%q<shoulda-context>, [">= 0"])
57
+ s.add_dependency(%q<bundler>, ["~> 1.2.3"])
58
+ s.add_dependency(%q<jeweler>, ["~> 1.8.4"])
59
+ s.add_dependency(%q<webmock>, ["~> 1.9.0"])
60
+ end
61
+ else
62
+ s.add_dependency(%q<curb>, [">= 0"])
63
+ s.add_dependency(%q<activesupport>, [">= 0"])
64
+ s.add_dependency(%q<shoulda-context>, [">= 0"])
65
+ s.add_dependency(%q<bundler>, ["~> 1.2.3"])
66
+ s.add_dependency(%q<jeweler>, ["~> 1.8.4"])
67
+ s.add_dependency(%q<webmock>, ["~> 1.9.0"])
68
+ end
69
+ end
70
+
metadata ADDED
@@ -0,0 +1,132 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: xtify
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.1
5
+ prerelease:
6
+ platform: ruby
7
+ authors:
8
+ - Jonathan Bell
9
+ autorequire:
10
+ bindir: bin
11
+ cert_chain: []
12
+ date: 2013-05-07 00:00:00.000000000 Z
13
+ dependencies:
14
+ - !ruby/object:Gem::Dependency
15
+ name: curb
16
+ requirement: &70176322612200 !ruby/object:Gem::Requirement
17
+ none: false
18
+ requirements:
19
+ - - ! '>='
20
+ - !ruby/object:Gem::Version
21
+ version: '0'
22
+ type: :runtime
23
+ prerelease: false
24
+ version_requirements: *70176322612200
25
+ - !ruby/object:Gem::Dependency
26
+ name: activesupport
27
+ requirement: &70176322611720 !ruby/object:Gem::Requirement
28
+ none: false
29
+ requirements:
30
+ - - ! '>='
31
+ - !ruby/object:Gem::Version
32
+ version: '0'
33
+ type: :runtime
34
+ prerelease: false
35
+ version_requirements: *70176322611720
36
+ - !ruby/object:Gem::Dependency
37
+ name: shoulda-context
38
+ requirement: &70176322611240 !ruby/object:Gem::Requirement
39
+ none: false
40
+ requirements:
41
+ - - ! '>='
42
+ - !ruby/object:Gem::Version
43
+ version: '0'
44
+ type: :development
45
+ prerelease: false
46
+ version_requirements: *70176322611240
47
+ - !ruby/object:Gem::Dependency
48
+ name: bundler
49
+ requirement: &70176322610760 !ruby/object:Gem::Requirement
50
+ none: false
51
+ requirements:
52
+ - - ~>
53
+ - !ruby/object:Gem::Version
54
+ version: 1.2.3
55
+ type: :development
56
+ prerelease: false
57
+ version_requirements: *70176322610760
58
+ - !ruby/object:Gem::Dependency
59
+ name: jeweler
60
+ requirement: &70176322610280 !ruby/object:Gem::Requirement
61
+ none: false
62
+ requirements:
63
+ - - ~>
64
+ - !ruby/object:Gem::Version
65
+ version: 1.8.4
66
+ type: :development
67
+ prerelease: false
68
+ version_requirements: *70176322610280
69
+ - !ruby/object:Gem::Dependency
70
+ name: webmock
71
+ requirement: &70176322609800 !ruby/object:Gem::Requirement
72
+ none: false
73
+ requirements:
74
+ - - ~>
75
+ - !ruby/object:Gem::Version
76
+ version: 1.9.0
77
+ type: :development
78
+ prerelease: false
79
+ version_requirements: *70176322609800
80
+ description: Client library for Xtify's API
81
+ email: jbell@moxiesoft.com
82
+ executables: []
83
+ extensions: []
84
+ extra_rdoc_files:
85
+ - README.md
86
+ files:
87
+ - Gemfile
88
+ - Gemfile.lock
89
+ - README.md
90
+ - Rakefile
91
+ - VERSION
92
+ - lib/xtify.rb
93
+ - lib/xtify/action.rb
94
+ - lib/xtify/commands.rb
95
+ - lib/xtify/config.rb
96
+ - lib/xtify/device.rb
97
+ - lib/xtify/errors.rb
98
+ - lib/xtify/message.rb
99
+ - lib/xtify/model.rb
100
+ - test/helper.rb
101
+ - test/message_test.rb
102
+ - test/registration_test.rb
103
+ - xtify.gemspec
104
+ homepage: http://github.com/moxiespaces/xtify
105
+ licenses:
106
+ - MIT
107
+ post_install_message:
108
+ rdoc_options: []
109
+ require_paths:
110
+ - lib
111
+ required_ruby_version: !ruby/object:Gem::Requirement
112
+ none: false
113
+ requirements:
114
+ - - ! '>='
115
+ - !ruby/object:Gem::Version
116
+ version: '0'
117
+ segments:
118
+ - 0
119
+ hash: -928513645534341231
120
+ required_rubygems_version: !ruby/object:Gem::Requirement
121
+ none: false
122
+ requirements:
123
+ - - ! '>='
124
+ - !ruby/object:Gem::Version
125
+ version: '0'
126
+ requirements: []
127
+ rubyforge_project:
128
+ rubygems_version: 1.8.10
129
+ signing_key:
130
+ specification_version: 3
131
+ summary: Client library for Xtify's API
132
+ test_files: []