malechimp 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/.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:
|