interspire 0.1.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,19 @@
1
+ *.gem
2
+ *.rbc
3
+ .bundle
4
+ .config
5
+ .rbenv-gemsets
6
+ .rbenv-version
7
+ .yardoc
8
+ Gemfile.lock
9
+ InstalledFiles
10
+ _yardoc
11
+ coverage
12
+ doc/
13
+ lib/bundler/man
14
+ pkg
15
+ rdoc
16
+ spec/reports
17
+ test/tmp
18
+ test/version_tmp
19
+ tmp
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source 'https://rubygems.org'
2
+
3
+ # Specify your gem's dependencies in interspire.gemspec
4
+ gemspec
data/LICENSE.txt ADDED
@@ -0,0 +1,13 @@
1
+ DO WHAT THE FUCK YOU WANT TO PUBLIC LICENSE
2
+ Version 2, December 2004
3
+
4
+ Copyright (C) 2013 Dale Campbell <oshuma@gmail.com>
5
+
6
+ Everyone is permitted to copy and distribute verbatim or modified
7
+ copies of this license document, and changing it is allowed as long
8
+ as the name is changed.
9
+
10
+ DO WHAT THE FUCK YOU WANT TO PUBLIC LICENSE
11
+ TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
12
+
13
+ 0. You just DO WHAT THE FUCK YOU WANT TO.
data/README.md ADDED
@@ -0,0 +1,31 @@
1
+ # Interspire
2
+
3
+ Ruby library for the {http://www.interspire.com/ Interspire} API ({https://www.interspire.com/support/kb/questions/1224/Email+Marketer+XML+API+Documentation pdf}).
4
+
5
+ See the {Interspire::API} class for detailed documentation.
6
+
7
+ ## Installation
8
+
9
+ Add this line to your application's Gemfile:
10
+
11
+ gem 'interspire'
12
+
13
+ And then execute:
14
+
15
+ $ bundle
16
+
17
+ Or install it yourself as:
18
+
19
+ $ gem install interspire
20
+
21
+ ## Usage
22
+
23
+ TODO: Write usage instructions here
24
+
25
+ ## Contributing
26
+
27
+ 1. Fork it
28
+ 2. Create your feature branch (`git checkout -b my-new-feature`)
29
+ 3. Commit your changes (`git commit -am 'Add some feature'`)
30
+ 4. Push to the branch (`git push origin my-new-feature`)
31
+ 5. Create new Pull Request
data/Rakefile ADDED
@@ -0,0 +1,6 @@
1
+ require "bundler/gem_tasks"
2
+ require 'rspec/core/rake_task'
3
+
4
+ RSpec::Core::RakeTask.new(:spec)
5
+
6
+ task :default => :spec
data/bin/interspire ADDED
@@ -0,0 +1,6 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require 'interspire'
4
+
5
+ # TODO: Write some sort of command or REPL thingy.
6
+ raise "Not yet implemented."
@@ -0,0 +1,25 @@
1
+ # -*- encoding: utf-8 -*-
2
+ lib = File.expand_path('../lib', __FILE__)
3
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
+ require 'interspire'
5
+
6
+ Gem::Specification.new do |gem|
7
+ gem.name = "interspire"
8
+ gem.version = Interspire::VERSION
9
+ gem.authors = ["Dale Campbell"]
10
+ gem.email = ["oshuma@gmail.com"]
11
+ gem.description = %q{Ruby library for the Interspire API.}
12
+ gem.summary = %q{Ruby library for the Interspire API.}
13
+ gem.homepage = "https://github.com/Oshuma/interspire"
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
+
20
+ gem.add_runtime_dependency 'nokogiri'
21
+
22
+ gem.add_development_dependency 'rspec'
23
+ gem.add_development_dependency 'webmock'
24
+ gem.add_development_dependency 'yard'
25
+ end
data/lib/interspire.rb ADDED
@@ -0,0 +1,8 @@
1
+ require "interspire/api"
2
+ require "interspire/contact_list"
3
+ require "interspire/interspire_exception"
4
+ require "interspire/subscriber"
5
+
6
+ module Interspire
7
+ VERSION = "0.1.0"
8
+ end
@@ -0,0 +1,222 @@
1
+ require 'net/http'
2
+ require 'nokogiri'
3
+
4
+ module Interspire
5
+ class API
6
+
7
+ # @param api_url [String] The XML API of your Interspire installation; ex. http://example.com/xml.php
8
+ # @param user [String] The Interspire user's login name.
9
+ # @param token [String] The Interspire user's API token.
10
+ #
11
+ # @return [Inter::API] An instance of the Interspire API for the given parameters.
12
+ def initialize(api_url, user, token)
13
+ @api_url = api_url
14
+ @user = user
15
+ @token = token
16
+ end
17
+
18
+ # @param list_id [Integer] The id of the contact list.
19
+ # @param email [String] The subscriber's email address.
20
+ # @param confirmed [boolean] (optional) +true+ if the subscriber should be set as confirmed; defaults to +false+.
21
+ # @param format [String] (optional) The email format; either +html+ or +text+; defaults to +html+.
22
+ #
23
+ # @return [Integer] Returns the subscriber's ID upon success.
24
+ def add_subscriber(list_id, email, confirmed = false, format = 'html')
25
+ xml = %Q[
26
+ <xmlrequest>
27
+ <username>#{@user}</username>
28
+ <usertoken>#{@token}</usertoken>
29
+ <requesttype>subscribers</requesttype>
30
+ <requestmethod>AddSubscriberToList</requestmethod>
31
+ <details>
32
+ <emailaddress>#{email}</emailaddress>
33
+ <mailinglist>#{list_id}</mailinglist>
34
+ <format>#{format}</format>
35
+ <confirmed>#{confirmed}</confirmed>
36
+ </details>
37
+ </xmlrequest>
38
+ ]
39
+
40
+ response = get_response(xml)
41
+
42
+ if success?(response)
43
+ response.xpath('response/data').first.content.to_i
44
+ else
45
+ error!(response)
46
+ end
47
+ end
48
+
49
+ # @return [boolean] Returns +true+ if the user is authenticated.
50
+ def authenticated?
51
+ xml = %Q[
52
+ <xmlrequest>
53
+ <username>#{@user}</username>
54
+ <usertoken>#{@token}</usertoken>
55
+ <requesttype>authentication</requesttype>
56
+ <requestmethod>xmlapitest</requestmethod>
57
+ <details>
58
+ </details>
59
+ </xmlrequest>
60
+ ]
61
+
62
+ response = get_response(xml)
63
+ success?(response)
64
+ end
65
+
66
+ # @param list_id [Integer] The id of the contact list.
67
+ # @param email [String] The subscriber's email address.
68
+ #
69
+ # @return [boolean] Returns +true+ upon success or raises an {Interspire::InterspireException} on failure.
70
+ def delete_subscriber(list_id, email)
71
+ xml = %Q[
72
+ <xmlrequest>
73
+ <username>#{@user}</username>
74
+ <usertoken>#{@token}</usertoken>
75
+ <requesttype>subscribers</requesttype>
76
+ <requestmethod>DeleteSubscriber</requestmethod>
77
+ <details>
78
+ <list>#{list_id}</list>
79
+ <emailaddress>#{email}</emailaddress>
80
+ </details>
81
+ </xmlrequest>
82
+ ]
83
+
84
+ response = get_response(xml)
85
+ success?(response) ? true : error!(response)
86
+ end
87
+
88
+ # @return [Array] An Array of {Interspire::ContactList} objects.
89
+ def get_lists
90
+ xml = %Q[
91
+ <xmlrequest>
92
+ <username>#{@user}</username>
93
+ <usertoken>#{@token}</usertoken>
94
+ <requesttype>user</requesttype>
95
+ <requestmethod>GetLists</requestmethod>
96
+ <details>
97
+ </details>
98
+ </xmlrequest>
99
+ ]
100
+
101
+ response = get_response(xml)
102
+
103
+ if success?(response)
104
+ lists = []
105
+ response.xpath('response/data/item').each do |list|
106
+ lists << Interspire::ContactList.new({
107
+ id: list.xpath('listid').first.content,
108
+ name: list.xpath('name').first.content,
109
+ subscribe_count: list.xpath('subscribecount').first.content,
110
+ unsubscribe_count: list.xpath('unsubscribecount').first.content,
111
+ auto_responder_count: list.xpath('autorespondercount').first.content,
112
+ })
113
+ end
114
+
115
+ lists
116
+ else
117
+ error!(response)
118
+ end
119
+ end
120
+
121
+ # @param list_id [Integer] The ID of the contact list.
122
+ # @param email [String] The domain (including '@') of subscribers to filter by; ex. '@example.com' would only return subscribers like 'foo@example.com'; defaults to an empty String (returns all subscribers).
123
+ #
124
+ # @return [Hash] A Hash containing a +:count+ key and a +:subscribers+ Array with {Interspire::Subscriber} objects.
125
+ def get_subscribers(list_id, email = '')
126
+ xml = %Q[
127
+ <xmlrequest>
128
+ <username>#{@user}</username>
129
+ <usertoken>#{@token}</usertoken>
130
+ <requesttype>subscribers</requesttype>
131
+ <requestmethod>GetSubscribers</requestmethod>
132
+ <details>
133
+ <searchinfo>
134
+ <List>#{list_id}</List>
135
+ <Email>#{email}</Email>
136
+ </searchinfo>
137
+ </details>
138
+ </xmlrequest>
139
+ ]
140
+
141
+ response = get_response(xml)
142
+
143
+ if success?(response)
144
+ subscribers = {}
145
+ subscribers[:count] = response.xpath('response/data/count').first.content
146
+ subscribers[:subscribers] = []
147
+
148
+ response.xpath('response/data').each do |data|
149
+ data.xpath('subscriberlist/item').each do |item|
150
+ id = item.xpath('subscriberid').first.content.to_i
151
+ email = item.xpath('emailaddress').first.content
152
+ subscribers[:subscribers] << Interspire::Subscriber.new(id, email)
153
+ end
154
+ end
155
+
156
+ subscribers
157
+ else
158
+ error!(response)
159
+ end
160
+ end
161
+
162
+ # @param list_id [Integer] The ID of the contact list.
163
+ # @param email [String] The subscriber's email address.
164
+ #
165
+ # @return [boolean] +true+ or +false+ if the +email+ is on the given contact list.
166
+ def in_contact_list?(list_id, email)
167
+ xml = %Q[
168
+ <xmlrequest>
169
+ <username>#{@user}</username>
170
+ <usertoken>#{@token}</usertoken>
171
+ <requesttype>subscribers</requesttype>
172
+ <requestmethod>IsSubscriberOnList</requestmethod>
173
+ <details>
174
+ <emailaddress>#{email}</emailaddress>
175
+ <listids>#{list_id}</listids>
176
+ </details>
177
+ </xmlrequest>
178
+ ]
179
+
180
+ response = get_response(xml)
181
+
182
+ if success?(response)
183
+ # The 'data' element will contain the subscriber ID.
184
+ ! response.xpath('response/data').first.content.empty?
185
+ else
186
+ false
187
+ end
188
+ end
189
+
190
+ private
191
+
192
+ # @param xml [String] A String containing the XML request.
193
+ #
194
+ # @return [Nokogiri::Document] A +Nokogiri::Document+ build from the API response.
195
+ def get_response(xml)
196
+ url = URI.parse(@api_url)
197
+ request = Net::HTTP::Post.new(url.path)
198
+ request.body = xml
199
+
200
+ response = Net::HTTP.new(url.host, url.port).start { |http| http.request(request) }
201
+
202
+ Nokogiri::XML.parse(response.body)
203
+ end
204
+
205
+ # @param response [Nokogiri::Document] A +Nokogiri::Document+ parsed from the API response.
206
+ #
207
+ # @return [boolean] +true+ or +false+ if the +response+ was a success.
208
+ def success?(response)
209
+ response.xpath('response/status').first.content == 'SUCCESS'
210
+ end
211
+
212
+ # Raises an {Interspire::InterspireException} with details from the API +response+.
213
+ #
214
+ # @param response [Nokogiri::Document] A +Nokogiri::Document+ parsed from the API response.
215
+ def error!(response)
216
+ type = response.xpath('response/status').first.content
217
+ error = response.xpath('response/errormessage').first.content
218
+ raise InterspireException, "#{type}: #{error.empty? ? 'No error message given.' : error}"
219
+ end
220
+
221
+ end
222
+ end
@@ -0,0 +1,24 @@
1
+ module Interspire
2
+ class ContactList
3
+ attr_reader :id, :name, :subscribe_count, :unsubscribe_count, :auto_responder_count
4
+
5
+ # Instantiate with hash of contact list details that should look like this:
6
+ #
7
+ # {
8
+ # :id => '42', # Contact list ID.
9
+ # :name => 'Serious Contacts',
10
+ # :subscribe_count => '6420',
11
+ # :unsubscribe_count => '421',
12
+ # :auto_responder_count => '124'
13
+ # }
14
+ #
15
+ # @param details [Hash] A hash of contact list info.
16
+ def initialize(details)
17
+ @id = details[:id]
18
+ @name = details[:name]
19
+ @subscribe_count = details[:subscribe_count]
20
+ @unsubscribe_count = details[:unsubscribe_count]
21
+ @auto_responder_count = details[:auto_responder_count]
22
+ end
23
+ end
24
+ end
@@ -0,0 +1,4 @@
1
+ module Interspire
2
+ class InterspireException < Exception
3
+ end
4
+ end
@@ -0,0 +1,12 @@
1
+ module Interspire
2
+ class Subscriber
3
+ attr_reader :id, :email
4
+
5
+ # @param id [Integer] The ID of the subscriber.
6
+ # @param email [String] The email of the subscriber.
7
+ def initialize(id, email)
8
+ @id = id
9
+ @email = email
10
+ end
11
+ end
12
+ end
@@ -0,0 +1,5 @@
1
+ <?xml version="1.0" encoding="UTF-8" ?>
2
+ <response>
3
+ <status>SUCCESS</status>
4
+ <data>764963</data>
5
+ </response>
@@ -0,0 +1,8 @@
1
+ <?xml version="1.0" encoding="UTF-8" ?>
2
+ <response>
3
+ <status>SUCCESS</status>
4
+ <data>
5
+ <userid>5</userid>
6
+ <username>luser</username>
7
+ </data>
8
+ </response>
@@ -0,0 +1,5 @@
1
+ <?xml version="1.0" encoding="UTF-8" ?>
2
+ <response>
3
+ <status>SUCCESS</status>
4
+ <data></data>
5
+ </response>
@@ -0,0 +1,5 @@
1
+ <?xml version="1.0" encoding="UTF-8" ?>
2
+ <response>
3
+ <status>SUCCESS</status>
4
+ <data>764964</data>
5
+ </response>
@@ -0,0 +1,63 @@
1
+ <?xml version="1.0" encoding="UTF-8" ?>
2
+ <response>
3
+ <status>SUCCESS</status>
4
+ <data>
5
+ <item>
6
+ <listid>7</listid>
7
+ <name>Neighborhood Newsletter</name>
8
+ <ownername>Jane Doe</ownername>
9
+ <owneremail>jane.doe@example.com</owneremail>
10
+ <bounceemail>jane.doe@example.com</bounceemail>
11
+ <replytoemail>jane.doe@example.com</replytoemail>
12
+ <bounceserver></bounceserver>
13
+ <bounceusername></bounceusername>
14
+ <bouncepassword></bouncepassword>
15
+ <extramailsettings></extramailsettings>
16
+ <companyname>ExampleCorp</companyname>
17
+ <companyaddress>123 Main St, Anytown, FL 30635</companyaddress>
18
+ <companyphone></companyphone>
19
+ <format>b</format>
20
+ <notifyowner>1</notifyowner>
21
+ <imapaccount>0</imapaccount>
22
+ <createdate>1348502776</createdate>
23
+ <subscribecount>666</subscribecount>
24
+ <unsubscribecount>4</unsubscribecount>
25
+ <bouncecount>0</bouncecount>
26
+ <processbounce>0</processbounce>
27
+ <agreedelete>1</agreedelete>
28
+ <agreedeleteall>0</agreedeleteall>
29
+ <visiblefields>emailaddress,subscribedate,status,confirmed</visiblefields>
30
+ <ownerid>3</ownerid>
31
+ <autorespondercount></autorespondercount>
32
+ </item>
33
+
34
+ <item>
35
+ <listid>84</listid>
36
+ <name>Totes Bitchin Email List</name>
37
+ <ownername>John Doe</ownername>
38
+ <owneremail>john.doe@example.com</owneremail>
39
+ <bounceemail>john.doe@example.com</bounceemail>
40
+ <replytoemail>john.doe@example.com</replytoemail>
41
+ <bounceserver></bounceserver>
42
+ <bounceusername></bounceusername>
43
+ <bouncepassword></bouncepassword>
44
+ <extramailsettings></extramailsettings>
45
+ <companyname>ExampleCorp</companyname>
46
+ <companyaddress>123 Main St, Anytown, FL 30635</companyaddress>
47
+ <companyphone></companyphone>
48
+ <format>b</format>
49
+ <notifyowner>1</notifyowner>
50
+ <imapaccount>0</imapaccount>
51
+ <createdate>1348552776</createdate>
52
+ <subscribecount>12345</subscribecount>
53
+ <unsubscribecount>20</unsubscribecount>
54
+ <bouncecount>0</bouncecount>
55
+ <processbounce>0</processbounce>
56
+ <agreedelete>1</agreedelete>
57
+ <agreedeleteall>0</agreedeleteall>
58
+ <visiblefields>emailaddress,subscribedate,status,confirmed</visiblefields>
59
+ <ownerid>12</ownerid>
60
+ <autorespondercount></autorespondercount>
61
+ </item>
62
+ </data>
63
+ </response>
@@ -0,0 +1,5 @@
1
+ <?xml version="1.0" encoding="UTF-8" ?>
2
+ <response>
3
+ <status>FAILED</status>
4
+ <errormessage>Unable to check user details.</errormessage>
5
+ </response>
@@ -0,0 +1,5 @@
1
+ <?xml version="1.0" encoding="UTF-8" ?>
2
+ <response>
3
+ <status>FAILED</status>
4
+ <errormessage></errormessage>
5
+ </response>
@@ -0,0 +1,29 @@
1
+ <?xml version="1.0" encoding="UTF-8" ?>
2
+ <response>
3
+ <status>SUCCESS</status>
4
+ <data>
5
+ <count>2</count>
6
+ <subscriberlist>
7
+ <item>
8
+ <subscriberid>283206</subscriberid>
9
+ <emailaddress>jane.doe@example.com</emailaddress>
10
+ <format>h</format>
11
+ <subscribedate>1348602753</subscribedate>
12
+ <confirmed>1</confirmed>
13
+ <unsubscribed>0</unsubscribed>
14
+ <bounced>0</bounced>
15
+ <listid>8</listid>
16
+ </item>
17
+ <item>
18
+ <subscriberid>283207</subscriberid>
19
+ <emailaddress>john.doe@example.com</emailaddress>
20
+ <format>h</format>
21
+ <subscribedate>1348602763</subscribedate>
22
+ <confirmed>1</confirmed>
23
+ <unsubscribed>0</unsubscribed>
24
+ <bounced>0</bounced>
25
+ <listid>8</listid>
26
+ </item>
27
+ </subscriberlist>
28
+ </data>
29
+ </response>
@@ -0,0 +1,84 @@
1
+ require 'spec_helper'
2
+
3
+ describe Interspire::API do
4
+
5
+ before do
6
+ @api_url = 'http://example.com/xml.php'
7
+ @user = 'luser'
8
+ @token = 'some_totally_valid_token'
9
+
10
+ @api = Interspire::API.new(@api_url, @user, @token)
11
+ end
12
+
13
+ context 'authentication' do
14
+ it 'should be authenticated' do
15
+ stub_request(:post, @api_url).to_return(:body => fixture("authenticated.xml"))
16
+
17
+ @api.should be_authenticated # @api.authenticated? should return true
18
+ end
19
+
20
+ it 'should not be authenticated' do
21
+ stub_request(:post, @api_url).to_return(:body => fixture("not_authenticated.xml"))
22
+
23
+ @api.should_not be_authenticated # @api.authenticated? should return false
24
+ end
25
+ end
26
+
27
+ context 'lists' do
28
+ it 'should get all lists' do
29
+ stub_request(:post, @api_url).to_return(:body => fixture("lists.xml"))
30
+
31
+ lists = @api.get_lists
32
+
33
+ # Make sure each list has expected values:
34
+ lists.each do |list|
35
+ list.id.should_not be_nil
36
+ list.name.should_not be_nil
37
+ list.subscribe_count.should_not be_nil
38
+ list.unsubscribe_count.should_not be_nil
39
+ list.auto_responder_count.should_not be_nil
40
+ end
41
+ end
42
+
43
+ it 'should get all subscribers on a list' do
44
+ stub_request(:post, @api_url).to_return(:body => fixture("subscribers.xml"))
45
+
46
+ subscribers = @api.get_subscribers(1) # Contact list ID is arbitrary for this test.
47
+
48
+ # Make sure there's a count.
49
+ subscribers[:count].should_not be_nil
50
+
51
+ # Make sure the required values are there:
52
+ subscribers[:subscribers].each do |subscriber|
53
+ subscriber.id.should_not be_nil
54
+ subscriber.id.should be_a(Integer)
55
+
56
+ subscriber.email.should_not be_nil
57
+ end
58
+ end
59
+ end
60
+
61
+ context 'subscribers' do
62
+ it 'should add the subscriber' do
63
+ stub_request(:post, @api_url).to_return(:body => fixture("add_subscriber.xml"))
64
+ subscriber_id = @api.add_subscriber(1, 'foo@example.com') # '1' is the (fake) contact list ID.
65
+ subscriber_id.should be_a(Integer)
66
+ end
67
+
68
+ it 'should delete the subscriber' do
69
+ stub_request(:post, @api_url).to_return(:body => fixture("delete_subscriber.xml"))
70
+ @api.delete_subscriber(1, 'foo@example.com').should be_true
71
+ end
72
+
73
+ it 'should be in contact list' do
74
+ stub_request(:post, @api_url).to_return(:body => fixture("in_contact_list.xml"))
75
+ @api.in_contact_list?(1, 'foo@example.com').should be_true
76
+ end
77
+
78
+ it 'should not be in contact list' do
79
+ stub_request(:post, @api_url).to_return(:body => fixture("not_in_contact_list.xml"))
80
+ @api.in_contact_list?(1, 'foo@example.com').should_not be_true
81
+ end
82
+ end
83
+
84
+ end
@@ -0,0 +1,25 @@
1
+ require 'spec_helper'
2
+
3
+ describe Interspire::ContactList do
4
+
5
+ before do
6
+ @details = {
7
+ :id => 4,
8
+ :name => 'List Foo',
9
+ :subscribe_count => 321,
10
+ :unsubscribe_count => 123,
11
+ :auto_responder_count => 4,
12
+ }
13
+
14
+ @list = Interspire::ContactList.new(@details)
15
+ end
16
+
17
+ context 'accessors' do
18
+ it 'id' do; @list.id.should == @details[:id]; end
19
+ it 'name' do; @list.name.should == @details[:name]; end
20
+ it 'subscribe_count' do; @list.subscribe_count.should == @details[:subscribe_count]; end
21
+ it 'unsubscribe_count' do; @list.unsubscribe_count.should == @details[:unsubscribe_count]; end
22
+ it 'auto_responder_count' do; @list.auto_responder_count.should == @details[:auto_responder_count]; end
23
+ end
24
+
25
+ end
@@ -0,0 +1,10 @@
1
+ require 'rspec'
2
+ require 'webmock/rspec'
3
+
4
+ def fixture_path
5
+ File.expand_path('../fixtures', __FILE__)
6
+ end
7
+
8
+ def fixture(file)
9
+ File.new(File.join(fixture_path, file))
10
+ end
metadata ADDED
@@ -0,0 +1,131 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: interspire
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.0
5
+ prerelease:
6
+ platform: ruby
7
+ authors:
8
+ - Dale Campbell
9
+ autorequire:
10
+ bindir: bin
11
+ cert_chain: []
12
+ date: 2013-02-20 00:00:00.000000000 Z
13
+ dependencies:
14
+ - !ruby/object:Gem::Dependency
15
+ name: nokogiri
16
+ requirement: &82085980 !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: *82085980
25
+ - !ruby/object:Gem::Dependency
26
+ name: rspec
27
+ requirement: &82085610 !ruby/object:Gem::Requirement
28
+ none: false
29
+ requirements:
30
+ - - ! '>='
31
+ - !ruby/object:Gem::Version
32
+ version: '0'
33
+ type: :development
34
+ prerelease: false
35
+ version_requirements: *82085610
36
+ - !ruby/object:Gem::Dependency
37
+ name: webmock
38
+ requirement: &82085360 !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: *82085360
47
+ - !ruby/object:Gem::Dependency
48
+ name: yard
49
+ requirement: &82085080 !ruby/object:Gem::Requirement
50
+ none: false
51
+ requirements:
52
+ - - ! '>='
53
+ - !ruby/object:Gem::Version
54
+ version: '0'
55
+ type: :development
56
+ prerelease: false
57
+ version_requirements: *82085080
58
+ description: Ruby library for the Interspire API.
59
+ email:
60
+ - oshuma@gmail.com
61
+ executables:
62
+ - interspire
63
+ extensions: []
64
+ extra_rdoc_files: []
65
+ files:
66
+ - .gitignore
67
+ - Gemfile
68
+ - LICENSE.txt
69
+ - README.md
70
+ - Rakefile
71
+ - bin/interspire
72
+ - interspire.gemspec
73
+ - lib/interspire.rb
74
+ - lib/interspire/api.rb
75
+ - lib/interspire/contact_list.rb
76
+ - lib/interspire/interspire_exception.rb
77
+ - lib/interspire/subscriber.rb
78
+ - spec/fixtures/add_subscriber.xml
79
+ - spec/fixtures/authenticated.xml
80
+ - spec/fixtures/delete_subscriber.xml
81
+ - spec/fixtures/in_contact_list.xml
82
+ - spec/fixtures/lists.xml
83
+ - spec/fixtures/not_authenticated.xml
84
+ - spec/fixtures/not_in_contact_list.xml
85
+ - spec/fixtures/subscribers.xml
86
+ - spec/interspire/api_spec.rb
87
+ - spec/interspire/contact_list_spec.rb
88
+ - spec/spec_helper.rb
89
+ homepage: https://github.com/Oshuma/interspire
90
+ licenses: []
91
+ post_install_message:
92
+ rdoc_options: []
93
+ require_paths:
94
+ - lib
95
+ required_ruby_version: !ruby/object:Gem::Requirement
96
+ none: false
97
+ requirements:
98
+ - - ! '>='
99
+ - !ruby/object:Gem::Version
100
+ version: '0'
101
+ segments:
102
+ - 0
103
+ hash: 942893455
104
+ required_rubygems_version: !ruby/object:Gem::Requirement
105
+ none: false
106
+ requirements:
107
+ - - ! '>='
108
+ - !ruby/object:Gem::Version
109
+ version: '0'
110
+ segments:
111
+ - 0
112
+ hash: 942893455
113
+ requirements: []
114
+ rubyforge_project:
115
+ rubygems_version: 1.8.10
116
+ signing_key:
117
+ specification_version: 3
118
+ summary: Ruby library for the Interspire API.
119
+ test_files:
120
+ - spec/fixtures/add_subscriber.xml
121
+ - spec/fixtures/authenticated.xml
122
+ - spec/fixtures/delete_subscriber.xml
123
+ - spec/fixtures/in_contact_list.xml
124
+ - spec/fixtures/lists.xml
125
+ - spec/fixtures/not_authenticated.xml
126
+ - spec/fixtures/not_in_contact_list.xml
127
+ - spec/fixtures/subscribers.xml
128
+ - spec/interspire/api_spec.rb
129
+ - spec/interspire/contact_list_spec.rb
130
+ - spec/spec_helper.rb
131
+ has_rdoc: