xtify 0.0.1

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/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: []