interspire 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
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: