malechimp 0.0.1
Sign up to get free protection for your applications and to get access to all the features.
- data/.gitignore +5 -0
- data/.rspec +2 -0
- data/Gemfile +4 -0
- data/README.md +19 -0
- data/Rakefile +7 -0
- data/lib/malechimp.rb +54 -0
- data/lib/malechimp/exception.rb +46 -0
- data/lib/malechimp/list.rb +89 -0
- data/lib/malechimp/subscriber.rb +59 -0
- data/lib/malechimp/test_helper.rb +16 -0
- data/lib/malechimp/utils/utils.rb +45 -0
- data/lib/malechimp/version.rb +3 -0
- data/malechimp.gemspec +23 -0
- data/spec/config.yml.sample +8 -0
- data/spec/malechimp_spec.rb +126 -0
- data/spec/spec_helper.rb +16 -0
- metadata +77 -0
data/.gitignore
ADDED
data/.rspec
ADDED
data/Gemfile
ADDED
data/README.md
ADDED
@@ -0,0 +1,19 @@
|
|
1
|
+
# MaleChimp
|
2
|
+
|
3
|
+
The MailChimp API leaves a lot to be desired for modern application development. This gem provides very basic functionality to add users to a mail list:
|
4
|
+
|
5
|
+
```ruby
|
6
|
+
joe = MaleChimp::Subscriber.new do |s|
|
7
|
+
s.first_name = 'Joe'
|
8
|
+
s.last_name = 'Plumber'
|
9
|
+
s.email = 'joe@plumber.com'
|
10
|
+
s.fields['last_logged_in_at'] = Time.now
|
11
|
+
s.fields['occupation'] = "Plumber"
|
12
|
+
end
|
13
|
+
|
14
|
+
Chimp = MaleChimp.new(ENV['MAIL_CHIMP_API_KEY'])
|
15
|
+
|
16
|
+
Chimp.list('The Awesome List').subscribe(joe)
|
17
|
+
```
|
18
|
+
|
19
|
+
Consider this an ugly hack on top of an ugly RPC API, but we run integration tests on this nightly to make sure the API is in working order.
|
data/Rakefile
ADDED
data/lib/malechimp.rb
ADDED
@@ -0,0 +1,54 @@
|
|
1
|
+
require "malechimp/version"
|
2
|
+
require 'xmlrpc/client'
|
3
|
+
|
4
|
+
module MaleChimp
|
5
|
+
module API
|
6
|
+
VERSION = "1.3".freeze
|
7
|
+
URL = "http://api.mailchimp.com/#{API::VERSION}/".freeze
|
8
|
+
end
|
9
|
+
|
10
|
+
autoload :List, 'malechimp/list'
|
11
|
+
autoload :Subscriber, 'malechimp/subscriber'
|
12
|
+
autoload :Exception, 'malechimp/exception'
|
13
|
+
autoload :Utils, 'malechimp/utils'
|
14
|
+
|
15
|
+
class Base
|
16
|
+
attr_reader :url, :api_key
|
17
|
+
|
18
|
+
# Try to grab the API key out of env and use the default end-point URL
|
19
|
+
def initialize(api_key, url=API::URL)
|
20
|
+
@api_key, @url = api_key, url
|
21
|
+
end
|
22
|
+
|
23
|
+
# Returns all of the mailing lists in Chimp.
|
24
|
+
def lists
|
25
|
+
# In MailChimps infinite wisdom, they implemented REST inside of RPC, so you see stupid stuff like the .data root key.
|
26
|
+
@lists ||= call('lists')['data'].map do |list|
|
27
|
+
List.new(self, list)
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
# Find a list by name.
|
32
|
+
def list(name)
|
33
|
+
lists.find{ |l| l.name == name }
|
34
|
+
end
|
35
|
+
|
36
|
+
# Zie oh so wunderful API shinannigans
|
37
|
+
def server
|
38
|
+
@server ||= XMLRPC::Client.new2(url)
|
39
|
+
end
|
40
|
+
|
41
|
+
protected
|
42
|
+
# This is a stupid way of trying to make calls to MailChimps RPC api (Really poopy & crappy)
|
43
|
+
def call(*args)
|
44
|
+
begin
|
45
|
+
args = args.insert(1, api_key) # gotta shove the API key in there
|
46
|
+
puts "Calling with #{args.map{|arg| "#{arg.inspect}" }.join(', ')}"
|
47
|
+
server.call(*args)
|
48
|
+
rescue XMLRPC::FaultException => ex
|
49
|
+
puts "XMLRPC Fault #{ex.faultCode}: #{ex.faultString}"
|
50
|
+
raise Exception.lookup(ex.faultCode) || ex
|
51
|
+
end
|
52
|
+
end
|
53
|
+
end
|
54
|
+
end
|
@@ -0,0 +1,46 @@
|
|
1
|
+
# Error mappings from http://www.mailchimp.com/api/rtfm/exceptions.field.php
|
2
|
+
# This is NOT a comprehensive list errors from the API
|
3
|
+
module MaleChimp
|
4
|
+
module Exception
|
5
|
+
# Exception hierarchy for good ol' MaleChimp
|
6
|
+
MaleChimpError = Class.new(StandardError)
|
7
|
+
AuthorizationError = Class.new(MaleChimpError)
|
8
|
+
ListError = Class.new(MaleChimpError)
|
9
|
+
ListInvalidInterestFieldType = Class.new(ListError)
|
10
|
+
ListInvalidOption = Class.new(ListError)
|
11
|
+
ListInvalidUnsubMember = Class.new(ListError)
|
12
|
+
ListInvalidBounceMember = Class.new(ListError)
|
13
|
+
ListAlreadySubscribed = Class.new(ListError)
|
14
|
+
ListNotSubscribed = Class.new(ListError)
|
15
|
+
ListInvalidImport = Class.new(ListError)
|
16
|
+
EmailError = Class.new(MaleChimpError)
|
17
|
+
EmailAlreadySubscribed = Class.new(EmailError)
|
18
|
+
EmailAlreadyUnsubscribed = Class.new(EmailError)
|
19
|
+
EmailNotExists = Class.new(EmailError)
|
20
|
+
EmailNotSubscribed = Class.new(EmailError)
|
21
|
+
|
22
|
+
# Map our fancy exception hierarchy to MaleChimps XML RPC fault codes
|
23
|
+
FAULT_CODE_MAPPING = {
|
24
|
+
210 => ListInvalidInterestFieldType,
|
25
|
+
211 => ListInvalidOption,
|
26
|
+
212 => ListInvalidUnsubMember,
|
27
|
+
213 => ListInvalidBounceMember,
|
28
|
+
214 => ListAlreadySubscribed,
|
29
|
+
215 => ListNotSubscribed,
|
30
|
+
220 => ListInvalidImport,
|
31
|
+
230 => EmailAlreadySubscribed,
|
32
|
+
231 => EmailAlreadyUnsubscribed,
|
33
|
+
232 => EmailNotExists,
|
34
|
+
233 => EmailNotSubscribed
|
35
|
+
}
|
36
|
+
|
37
|
+
def self.lookup(err)
|
38
|
+
if err.respond_to?(:faultCode)
|
39
|
+
code = err.faultCode.to_i
|
40
|
+
else
|
41
|
+
code = err.to_i
|
42
|
+
end
|
43
|
+
FAULT_CODE_MAPPING[code]
|
44
|
+
end
|
45
|
+
end
|
46
|
+
end
|
@@ -0,0 +1,89 @@
|
|
1
|
+
module MaleChimp
|
2
|
+
class List
|
3
|
+
DEFAULT_MAIL_FORMAT = 'html'
|
4
|
+
|
5
|
+
attr_accessor :base
|
6
|
+
attr_reader :size, :list_id, :name, :created_at
|
7
|
+
|
8
|
+
# The construct will return
|
9
|
+
# [{
|
10
|
+
# "name"=>"New Feature Newsletter (APITEST)",
|
11
|
+
# "date_created"=>"2008-12-12 03:09:17",
|
12
|
+
# "member_count"=>7.0,
|
13
|
+
# "unsubscribe_count"=>4.0,
|
14
|
+
# "id"=>"5757f43cda",
|
15
|
+
# "cleaned_count"=>2.0,
|
16
|
+
# "web_id"=>17191
|
17
|
+
# }]
|
18
|
+
|
19
|
+
def initialize(base, opts={})
|
20
|
+
@base = base
|
21
|
+
@name = opts['name']
|
22
|
+
@created_at = opts['created_at'] || opts['date_created']
|
23
|
+
@size = opts['member_count'] || opts['size']
|
24
|
+
@list_id = opts['id'] || opts['list_id']
|
25
|
+
end
|
26
|
+
|
27
|
+
def subscribe(user, opts={})
|
28
|
+
opts = {:email_type => DEFAULT_MAIL_FORMAT, :double_optin => false, :update_existing => false, :replace_interests => true, :send_welcome => false}.merge(opts)
|
29
|
+
|
30
|
+
email_type = opts[:email_type]
|
31
|
+
double_optin = opts[:double_optin]
|
32
|
+
update_existing = opts[:update_existing]
|
33
|
+
replace_interests = opts[:replace_interests]
|
34
|
+
send_welcome = opts[:send_welcome]
|
35
|
+
|
36
|
+
# listSubscribe(string email_address, array merge_vars, string email_type, boolean double_optin, boolean update_existing, boolean replace_interests)
|
37
|
+
call('listSubscribe', user.email, user.merge_fields, DEFAULT_MAIL_FORMAT, double_optin, update_existing, replace_interests, send_welcome)
|
38
|
+
end
|
39
|
+
|
40
|
+
def unsubscribe(user, opts={})
|
41
|
+
opts = {:destroy => false, :send_goodbye => false, :send_notify => false}.merge(opts)
|
42
|
+
|
43
|
+
destroy = opts[:destroy]
|
44
|
+
send_goodbye = opts[:send_goodbye]
|
45
|
+
send_notify = opts[:send_notify]
|
46
|
+
|
47
|
+
surpress_faults Exception::ListNotSubscribed, Exception::EmailNotExists do
|
48
|
+
call('listUnsubscribe', user.email, destroy, send_goodbye, send_notify)
|
49
|
+
end
|
50
|
+
end
|
51
|
+
|
52
|
+
def update(user, opts={})
|
53
|
+
opts = {:email_type => DEFAULT_MAIL_FORMAT, :replace_interests => true}.merge(opts)
|
54
|
+
|
55
|
+
email_type = opts[:email_type]
|
56
|
+
replace_interests = opts[:replace_interests]
|
57
|
+
|
58
|
+
call('listUpdateMember', user.email, user.merge_fields, email_type, replace_interests)
|
59
|
+
end
|
60
|
+
|
61
|
+
def subscriber(email)
|
62
|
+
call('listMemberInfo', email)
|
63
|
+
end
|
64
|
+
|
65
|
+
def subscribers
|
66
|
+
# listMembers(string apikey, string id, string status, integer since, integer start, integer limit)
|
67
|
+
# returns [{"timestamp"=>"2008-12-12 03:24:05", "email"=>"jeff@jeffvyduna.com"} ...]
|
68
|
+
call('listMembers').map do |s|
|
69
|
+
Subscriber.new(s)
|
70
|
+
end
|
71
|
+
end
|
72
|
+
|
73
|
+
protected
|
74
|
+
# Curry these puppies some more! Woo yeah! XML RPC IS AWESOME!
|
75
|
+
def call(*args)
|
76
|
+
args = args.insert(1, @list_id) # Gotta shove the list ID in there
|
77
|
+
@base.send(:call, *args)
|
78
|
+
end
|
79
|
+
|
80
|
+
# Run a method and surpress certain acceptable errors.
|
81
|
+
def surpress_faults(*faults, &block)
|
82
|
+
begin
|
83
|
+
yield block
|
84
|
+
rescue XMLRPC::FaultException => ex
|
85
|
+
faults.include?(Exception.lookup(ex.faultCode)) ? true : raise
|
86
|
+
end
|
87
|
+
end
|
88
|
+
end
|
89
|
+
end
|
@@ -0,0 +1,59 @@
|
|
1
|
+
module MaleChimp
|
2
|
+
class Subscriber
|
3
|
+
DEFAULT_FIELDS = %w(first_name last_name email id)
|
4
|
+
MERGE_FIELD_SIZE = 10 # Another bullshit constraint imposed by MaleChimp
|
5
|
+
|
6
|
+
attr_accessor *DEFAULT_FIELDS
|
7
|
+
attr_accessor :fields
|
8
|
+
|
9
|
+
# Map these default fields out into the function
|
10
|
+
DEFAULT_FIELDS.each do |field|
|
11
|
+
eval(%{
|
12
|
+
def #{field}
|
13
|
+
@fields['#{field}']
|
14
|
+
end
|
15
|
+
|
16
|
+
def #{field}=(val)
|
17
|
+
@fields['#{field}'] = val
|
18
|
+
end
|
19
|
+
})
|
20
|
+
end
|
21
|
+
|
22
|
+
def initialize(fields={})
|
23
|
+
# Setup our default fields hash
|
24
|
+
@fields = DEFAULT_FIELDS.inject({}) do |h,f|
|
25
|
+
h[f] = '' # Default values to be blank
|
26
|
+
h # Gotta yield this for inject to work
|
27
|
+
end
|
28
|
+
@fields.merge!(fields)
|
29
|
+
yield self if block_given?
|
30
|
+
end
|
31
|
+
|
32
|
+
# Guess what guys? Chimp wants all upper case field names and
|
33
|
+
# no spaces for merge fields. Fine, we'll give 'em that!
|
34
|
+
def merge_fields
|
35
|
+
fields.inject({}) do |hash, field|
|
36
|
+
key, value = encode_merge_field(field)
|
37
|
+
hash[key] = value
|
38
|
+
hash
|
39
|
+
end
|
40
|
+
end
|
41
|
+
|
42
|
+
private
|
43
|
+
# Chimp complains if non-ascii chars.
|
44
|
+
def encode_merge_field_value(val)
|
45
|
+
val.to_s.gsub(/[^\x00-\x7F]/n,'')
|
46
|
+
end
|
47
|
+
|
48
|
+
# Replaces spaces with an underline and truncate
|
49
|
+
def encode_merge_field_name(key)
|
50
|
+
key.upcase.gsub(/\s/, '_')[0...MERGE_FIELD_SIZE]
|
51
|
+
end
|
52
|
+
|
53
|
+
# Clean up the merge field so that chimp and Ruby RPC don't cry
|
54
|
+
def encode_merge_field(field)
|
55
|
+
key, val = field
|
56
|
+
[ encode_merge_field_name(key), encode_merge_field_value(val) ]
|
57
|
+
end
|
58
|
+
end
|
59
|
+
end
|
@@ -0,0 +1,16 @@
|
|
1
|
+
require 'yaml'
|
2
|
+
require 'ostruct'
|
3
|
+
|
4
|
+
module MaleChimp
|
5
|
+
module TestHelper
|
6
|
+
# Load the MailChimp API key
|
7
|
+
def self.config
|
8
|
+
@config ||= begin
|
9
|
+
OpenStruct.new(YAML.load(File.read(File.expand_path('../../../spec/config.yml', __FILE__))))
|
10
|
+
rescue Errno::ENOENT
|
11
|
+
puts "Oops! You didn't run `rake setup` to configure your integration test settings."
|
12
|
+
exit 1
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
@@ -0,0 +1,45 @@
|
|
1
|
+
# Random utilities and scripts for MaleChimp
|
2
|
+
require 'rubygems'
|
3
|
+
require 'hpricot'
|
4
|
+
require 'open-uri'
|
5
|
+
require 'pp'
|
6
|
+
|
7
|
+
module MaleChimp
|
8
|
+
module Utils
|
9
|
+
module Exceptions
|
10
|
+
EXCEPTIONS_SPEC = 'http://www.mailchimp.com/api/rtfm/exceptions.field.php'
|
11
|
+
|
12
|
+
class << self
|
13
|
+
# Screen scrapes the faults from the Chimp API
|
14
|
+
def faults_list(url=EXCEPTIONS_SPEC)
|
15
|
+
doc = Hpricot(open(url))
|
16
|
+
# change the CSS class on links
|
17
|
+
(doc/"table tr").inject({}) do |faults, row|
|
18
|
+
code, error = (row/"td").map{ |cell| cell.inner_text }
|
19
|
+
if code =~ /[0-9-]+/
|
20
|
+
faults[code.to_i] = error
|
21
|
+
end
|
22
|
+
faults
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
DEFAULT_GROUP = 'General'
|
27
|
+
|
28
|
+
def group_faults(faults)
|
29
|
+
groups = { DEFAULT_GROUP => [] }
|
30
|
+
faults.map do |code, message|
|
31
|
+
group, error = message.split(/_/, 2)
|
32
|
+
|
33
|
+
group ||= DEFAULT_GROUP
|
34
|
+
groups[group] ||= []
|
35
|
+
|
36
|
+
groups[group] << [code, error]
|
37
|
+
end
|
38
|
+
groups
|
39
|
+
end
|
40
|
+
end
|
41
|
+
end
|
42
|
+
end
|
43
|
+
end
|
44
|
+
|
45
|
+
include MaleChimp::Utils
|
data/malechimp.gemspec
ADDED
@@ -0,0 +1,23 @@
|
|
1
|
+
# -*- encoding: utf-8 -*-
|
2
|
+
$:.push File.expand_path("../lib", __FILE__)
|
3
|
+
require "malechimp/version"
|
4
|
+
|
5
|
+
Gem::Specification.new do |s|
|
6
|
+
s.name = "malechimp"
|
7
|
+
s.version = MaleChimp::VERSION
|
8
|
+
s.authors = ["Brad Gessler"]
|
9
|
+
s.email = ["brad@bradgessler.com"]
|
10
|
+
s.homepage = ""
|
11
|
+
s.summary = %q{A crappy MailChimp API integration for a crappy API}
|
12
|
+
s.description = %q{MailChimps XMP RPC API is insanity if you're a modern developer. This provides a more OO approach to dealing with the MCAPI.}
|
13
|
+
|
14
|
+
s.rubyforge_project = "malechimp"
|
15
|
+
|
16
|
+
s.files = `git ls-files`.split("\n")
|
17
|
+
s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
|
18
|
+
s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
|
19
|
+
s.require_paths = ["lib"]
|
20
|
+
|
21
|
+
# specify any dependencies here; for example:
|
22
|
+
s.add_development_dependency "rspec"
|
23
|
+
end
|
@@ -0,0 +1,126 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe MaleChimp::Subscriber do
|
4
|
+
before(:each) do
|
5
|
+
@subscriber = MaleChimp::Subscriber.new do |s|
|
6
|
+
s.first_name = 'Brad'
|
7
|
+
s.last_name = 'Gessler'
|
8
|
+
s.email = MaleChimp::TestHelper.config.email
|
9
|
+
s.fields['last_logged_in_at'] = Time.now
|
10
|
+
s.fields['crap'] = "?hey"
|
11
|
+
end
|
12
|
+
end
|
13
|
+
|
14
|
+
it "should have fields" do
|
15
|
+
@subscriber.should respond_to(:fields)
|
16
|
+
@subscriber.fields.values.should include('Gessler', 'Brad', MaleChimp::TestHelper.config.email)
|
17
|
+
end
|
18
|
+
|
19
|
+
it "should have first_name" do
|
20
|
+
@subscriber.should respond_to(:first_name)
|
21
|
+
@subscriber.first_name.should eql('Brad')
|
22
|
+
end
|
23
|
+
|
24
|
+
it "should have last_name" do
|
25
|
+
@subscriber.should respond_to(:last_name)
|
26
|
+
@subscriber.last_name.should eql('Gessler')
|
27
|
+
end
|
28
|
+
|
29
|
+
it "should have email" do
|
30
|
+
@subscriber.should respond_to(:email)
|
31
|
+
@subscriber.email.should eql(MaleChimp::TestHelper.config.email)
|
32
|
+
end
|
33
|
+
|
34
|
+
it "should have merge_fields" do
|
35
|
+
@subscriber.should respond_to(:merge_fields)
|
36
|
+
end
|
37
|
+
|
38
|
+
it "should upcase and strip spaces from merge fields" do
|
39
|
+
@subscriber.merge_fields.keys.should include('FIRST_NAME', 'LAST_NAME', 'EMAIL')
|
40
|
+
end
|
41
|
+
|
42
|
+
it "should truncate long merge fields to 10 characters" do
|
43
|
+
@subscriber.merge_fields.should include('LAST_LOGGE')
|
44
|
+
end
|
45
|
+
end
|
46
|
+
|
47
|
+
describe MaleChimp::List, "initialization" do
|
48
|
+
before(:all) do
|
49
|
+
@chimp = MaleChimp::Base.new(MaleChimp::TestHelper.config.api_key)
|
50
|
+
@subscriber = MaleChimp::Subscriber.new do |s|
|
51
|
+
s.first_name = 'Brad'
|
52
|
+
s.last_name = 'Gessler'
|
53
|
+
s.email = MaleChimp::TestHelper.config.email
|
54
|
+
end
|
55
|
+
@list = @chimp.list(MaleChimp::TestHelper.config.list)
|
56
|
+
end
|
57
|
+
|
58
|
+
it "should add new user to list" do
|
59
|
+
@list.subscribe(@subscriber)
|
60
|
+
end
|
61
|
+
|
62
|
+
it "should update user on list" do
|
63
|
+
@subscriber.email = MaleChimp::TestHelper.config.email
|
64
|
+
@list.update(@subscriber)
|
65
|
+
end
|
66
|
+
|
67
|
+
it "should remove user from list" do
|
68
|
+
@list.unsubscribe(@subscriber)
|
69
|
+
end
|
70
|
+
|
71
|
+
it "should remove user from list silently" do
|
72
|
+
@list.subscribe(@subscriber)
|
73
|
+
@list.unsubscribe(@subscriber, :send_goodbye => false)
|
74
|
+
end
|
75
|
+
end
|
76
|
+
|
77
|
+
describe MaleChimp::List do
|
78
|
+
before(:all) do
|
79
|
+
@chimp = MaleChimp::Base.new(MaleChimp::TestHelper.config.api_key)
|
80
|
+
@hash = {
|
81
|
+
"name" => "New Feature Newsletter (APITEST)",
|
82
|
+
"date_created" => "2008-12-12 03:09:17",
|
83
|
+
"member_count" => 7.0,
|
84
|
+
"unsubscribe_count" => 4.0,
|
85
|
+
"id" =>"5757f43cda",
|
86
|
+
"cleaned_count" => 2.0,
|
87
|
+
"web_id" => 17191
|
88
|
+
}
|
89
|
+
end
|
90
|
+
|
91
|
+
it "should initialize with arguments from MaleChimp::Base#list" do
|
92
|
+
MaleChimp::List.new(@chimp, @hash).should be_instance_of(MaleChimp::List)
|
93
|
+
end
|
94
|
+
|
95
|
+
it "should have created_at" do
|
96
|
+
MaleChimp::List.new(@chimp, @hash).created_at.should eql(@hash['date_created'])
|
97
|
+
end
|
98
|
+
|
99
|
+
it "should have size" do
|
100
|
+
MaleChimp::List.new(@chimp, @hash).size.should eql(@hash['member_count'])
|
101
|
+
end
|
102
|
+
|
103
|
+
it "should have name" do
|
104
|
+
MaleChimp::List.new(@chimp, @hash).name.should eql(@hash['name'])
|
105
|
+
end
|
106
|
+
|
107
|
+
it "should have list_id" do
|
108
|
+
MaleChimp::List.new(@chimp, @hash).list_id.should eql(@hash['id'])
|
109
|
+
end
|
110
|
+
end
|
111
|
+
|
112
|
+
describe MaleChimp::Base do
|
113
|
+
before(:all) do
|
114
|
+
@chimp = MaleChimp::Base.new(MaleChimp::TestHelper.config.api_key)
|
115
|
+
end
|
116
|
+
|
117
|
+
it "should have lists" do
|
118
|
+
@chimp.should respond_to(:lists)
|
119
|
+
@lists = @chimp.lists
|
120
|
+
@lists.first.should be_instance_of(MaleChimp::List)
|
121
|
+
end
|
122
|
+
|
123
|
+
it "should have server" do
|
124
|
+
@chimp.should respond_to(:server)
|
125
|
+
end
|
126
|
+
end
|
data/spec/spec_helper.rb
ADDED
@@ -0,0 +1,16 @@
|
|
1
|
+
# This file was generated by the `rspec --init` command. Conventionally, all
|
2
|
+
# specs live under a `spec` directory, which RSpec adds to the `$LOAD_PATH`.
|
3
|
+
# Require this file using `require "spec_helper.rb"` to ensure that it is only
|
4
|
+
# loaded once.
|
5
|
+
#
|
6
|
+
# See http://rubydoc.info/gems/rspec-core/RSpec/Core/Configuration
|
7
|
+
|
8
|
+
require 'rubygems'
|
9
|
+
require 'malechimp'
|
10
|
+
require 'malechimp/test_helper'
|
11
|
+
|
12
|
+
RSpec.configure do |config|
|
13
|
+
config.treat_symbols_as_metadata_keys_with_true_values = true
|
14
|
+
config.run_all_when_everything_filtered = true
|
15
|
+
config.filter_run :focus
|
16
|
+
end
|
metadata
ADDED
@@ -0,0 +1,77 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: malechimp
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.0.1
|
5
|
+
prerelease:
|
6
|
+
platform: ruby
|
7
|
+
authors:
|
8
|
+
- Brad Gessler
|
9
|
+
autorequire:
|
10
|
+
bindir: bin
|
11
|
+
cert_chain: []
|
12
|
+
date: 2012-02-02 00:00:00.000000000 Z
|
13
|
+
dependencies:
|
14
|
+
- !ruby/object:Gem::Dependency
|
15
|
+
name: rspec
|
16
|
+
requirement: &70308222140160 !ruby/object:Gem::Requirement
|
17
|
+
none: false
|
18
|
+
requirements:
|
19
|
+
- - ! '>='
|
20
|
+
- !ruby/object:Gem::Version
|
21
|
+
version: '0'
|
22
|
+
type: :development
|
23
|
+
prerelease: false
|
24
|
+
version_requirements: *70308222140160
|
25
|
+
description: MailChimps XMP RPC API is insanity if you're a modern developer. This
|
26
|
+
provides a more OO approach to dealing with the MCAPI.
|
27
|
+
email:
|
28
|
+
- brad@bradgessler.com
|
29
|
+
executables: []
|
30
|
+
extensions: []
|
31
|
+
extra_rdoc_files: []
|
32
|
+
files:
|
33
|
+
- .gitignore
|
34
|
+
- .rspec
|
35
|
+
- Gemfile
|
36
|
+
- README.md
|
37
|
+
- Rakefile
|
38
|
+
- lib/malechimp.rb
|
39
|
+
- lib/malechimp/exception.rb
|
40
|
+
- lib/malechimp/list.rb
|
41
|
+
- lib/malechimp/subscriber.rb
|
42
|
+
- lib/malechimp/test_helper.rb
|
43
|
+
- lib/malechimp/utils/utils.rb
|
44
|
+
- lib/malechimp/version.rb
|
45
|
+
- malechimp.gemspec
|
46
|
+
- spec/config.yml.sample
|
47
|
+
- spec/malechimp_spec.rb
|
48
|
+
- spec/spec_helper.rb
|
49
|
+
homepage: ''
|
50
|
+
licenses: []
|
51
|
+
post_install_message:
|
52
|
+
rdoc_options: []
|
53
|
+
require_paths:
|
54
|
+
- lib
|
55
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
56
|
+
none: false
|
57
|
+
requirements:
|
58
|
+
- - ! '>='
|
59
|
+
- !ruby/object:Gem::Version
|
60
|
+
version: '0'
|
61
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
62
|
+
none: false
|
63
|
+
requirements:
|
64
|
+
- - ! '>='
|
65
|
+
- !ruby/object:Gem::Version
|
66
|
+
version: '0'
|
67
|
+
requirements: []
|
68
|
+
rubyforge_project: malechimp
|
69
|
+
rubygems_version: 1.8.11
|
70
|
+
signing_key:
|
71
|
+
specification_version: 3
|
72
|
+
summary: A crappy MailChimp API integration for a crappy API
|
73
|
+
test_files:
|
74
|
+
- spec/config.yml.sample
|
75
|
+
- spec/malechimp_spec.rb
|
76
|
+
- spec/spec_helper.rb
|
77
|
+
has_rdoc:
|