/
gibbon.rb
131 lines (106 loc) · 3.51 KB
/
gibbon.rb
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
require 'active_support'
require 'httparty'
require 'json'
require 'cgi'
class Gibbon
include HTTParty
format :plain
default_timeout 30
attr_accessor :api_key, :timeout, :throws_exceptions
def initialize(api_key = nil, extra_params = {})
@api_key = api_key || ENV['MC_API_KEY'] || ENV['MAILCHIMP_API_KEY'] || self.class.api_key
@default_params = {:apikey => @api_key}.merge(extra_params)
@throws_exceptions = false
end
def api_key=(value)
@api_key = value
@default_params = @default_params.merge({:apikey => @api_key})
end
def get_exporter
GibbonExport.new(@api_key, @default_params)
end
def base_api_url
"https://#{dc_from_api_key}api.mailchimp.com/1.3/?method="
end
protected
def call(method, params = {})
api_url = base_api_url + method
params = @default_params.merge(params)
response = self.class.post(api_url, :body => CGI::escape(params.to_json), :timeout => @timeout)
begin
response = ActiveSupport::JSON.decode(response.body)
rescue
response = response.body
end
if @throws_exceptions && response.is_a?(Hash) && response["error"]
raise "Error from MailChimp API: #{response["error"]} (code #{response["code"]})"
end
response
end
def method_missing(method, *args)
method = method.to_s.gsub(/\/(.?)/) { "::#{$1.upcase}" }.gsub(/(?:^|_)(.)/) { $1.upcase } #Thanks for the gsub, Rails
method = method[0].chr.downcase + method[1..-1].gsub(/aim$/i, 'AIM')
args = {} unless args.length > 0
args = args[0] if args.is_a?(Array)
call(method, args)
end
class << self
attr_accessor :api_key
def method_missing(sym, *args, &block)
new(self.api_key).send(sym, *args, &block)
end
end
def dc_from_api_key
(@api_key.nil? || @api_key.length == 0 || @api_key !~ /-/) ? '' : "#{@api_key.split("-").last}."
end
end
class GibbonExport < Gibbon
def initialize(api_key = nil, extra_params = {})
super(api_key, extra_params)
end
protected
def export_api_url
"http://#{dc_from_api_key}api.mailchimp.com/export/1.0/"
end
def call(method, params = {})
api_url = export_api_url + method + "/"
response = self.class.post(api_url, :body => params, :timeout => @timeout)
lines = response.body.lines
if @throws_exceptions
first_line_object = ActiveSupport::JSON.decode(lines.first) if lines.first
raise "Error from MailChimp Export API: #{first_line_object["error"]} (code #{first_line_object["code"]})" if first_line_object.is_a?(Hash) && first_line_object["error"]
end
lines
end
end
module HTTParty
module HashConversions
# @param key<Object> The key for the param.
# @param value<Object> The value for the param.
#
# @return <String> This key value pair as a param
#
# @example normalize_param(:name, "Bob Jones") #=> "name=Bob%20Jones&"
def self.normalize_param(key, value)
param = ''
stack = []
if value.is_a?(Array)
param << Hash[*(0...value.length).to_a.zip(value).flatten].map {|i,element| normalize_param("#{key}[#{i}]", element)}.join
elsif value.is_a?(Hash)
stack << [key,value]
else
param << "#{key}=#{URI.encode(value.to_s, Regexp.new("[^#{URI::PATTERN::UNRESERVED}]"))}&"
end
stack.each do |parent, hash|
hash.each do |key, value|
if value.is_a?(Hash)
stack << ["#{parent}[#{key}]", value]
else
param << normalize_param("#{parent}[#{key}]", value)
end
end
end
param
end
end
end