ihunter-whatcounts 0.3 → 0.3.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/lib/whatcounts/http_client.rb +56 -0
- data/lib/whatcounts/list.rb +69 -0
- data/lib/whatcounts/one_off_message.rb +54 -0
- data/lib/whatcounts/rails/mailer.rb +15 -0
- data/lib/whatcounts/response.rb +32 -0
- metadata +6 -1
@@ -0,0 +1,56 @@
|
|
1
|
+
module WhatCounts
|
2
|
+
class HttpClient
|
3
|
+
|
4
|
+
class InvalidConfiguration < WhatCountsError; end
|
5
|
+
|
6
|
+
VALID_COMMANDS = [:subscribe,:update,:change,:unsubscribe,:delete,:find,
|
7
|
+
:findinlist,:details,:createlist,:show_lists,:createseg,:show_seg,
|
8
|
+
:update_seg,:delete_seg,:createtemplate,:show_templates,:updatetemplate,
|
9
|
+
:show_user_events,:show_optout,:show_optglobal,:show_hard,:show_soft,
|
10
|
+
:send,:launch,:show_campaigns,:show_campaign_stats,:show_campaign_stats_multi]
|
11
|
+
|
12
|
+
class << self
|
13
|
+
# Configure the client
|
14
|
+
# Example:
|
15
|
+
#
|
16
|
+
# WhatCounts::HttpClient.configure do
|
17
|
+
# api_url "http://example.com"
|
18
|
+
# realm "client-realm"
|
19
|
+
# password "superdupersecret"
|
20
|
+
# end
|
21
|
+
def configure(&block)
|
22
|
+
@config = Config.new
|
23
|
+
@config.instance_eval(&block)
|
24
|
+
@config
|
25
|
+
end
|
26
|
+
|
27
|
+
def execute(command,requestable)
|
28
|
+
raise InvalidConfiguration,"Invalid WhatCounts configuration, are you sure it was configured?" unless @config
|
29
|
+
url = [@config.api_url,"?","c=#{command}&",@config.to_param_string,"&",requestable.to_param_string].join
|
30
|
+
res = Curl::Easy.perform(url) do |easy|
|
31
|
+
easy.timeout = 8
|
32
|
+
end
|
33
|
+
WhatCounts::Response.new(url,res.body_str)
|
34
|
+
end
|
35
|
+
end
|
36
|
+
|
37
|
+
private
|
38
|
+
class Config
|
39
|
+
attr_accessor :api_url, :realm, :password
|
40
|
+
def initialize
|
41
|
+
# defaults
|
42
|
+
api_url 'http://api.whatcounts.com/bin/api_web'
|
43
|
+
end
|
44
|
+
def to_param_string
|
45
|
+
@param_string ||= "r=#{realm}&pwd=#{password}"
|
46
|
+
end
|
47
|
+
[:api_url,:realm,:password].each do |name|
|
48
|
+
eval %%
|
49
|
+
def #{name}(*args)
|
50
|
+
@#{name}=args.first unless args.empty?; @#{name}
|
51
|
+
end
|
52
|
+
%
|
53
|
+
end
|
54
|
+
end
|
55
|
+
end
|
56
|
+
end
|
@@ -0,0 +1,69 @@
|
|
1
|
+
module WhatCounts
|
2
|
+
|
3
|
+
class List
|
4
|
+
|
5
|
+
class UnknownListOptionError < WhatCountsError; end
|
6
|
+
class MissingRequiredListOptionError < WhatCountsError; end
|
7
|
+
|
8
|
+
# List of all options this class accepts and their corresponding WC name. I don't agree with
|
9
|
+
# the WC naming scheme so I've renamed them to be something more semantic and meaningful
|
10
|
+
private
|
11
|
+
OPTIONS_TO_HTTP_PARAMS_MAP = {:name => :listname, :template_id => :template_id, :description => :description,
|
12
|
+
:from_address => :from, :reply_to_address => :reply_to, :bounce_address => :error_to,
|
13
|
+
:track_clicks => :track_clicks, :track_opens => :track_opens }
|
14
|
+
attr_writer *(OPTIONS_TO_HTTP_PARAMS_MAP.keys)
|
15
|
+
|
16
|
+
public
|
17
|
+
attr_reader *(OPTIONS_TO_HTTP_PARAMS_MAP.keys)
|
18
|
+
|
19
|
+
# Options which are required for new/create
|
20
|
+
REQUIRED_OPTIONS = [:name]
|
21
|
+
|
22
|
+
# List of options which this class will accept
|
23
|
+
VALID_OPTIONS = OPTIONS_TO_HTTP_PARAMS_MAP.keys
|
24
|
+
|
25
|
+
def initialize(options)
|
26
|
+
options.each_key {|o| raise UnknownOptionError,"Unknown option #{o}" unless VALID_OPTIONS.include? o}
|
27
|
+
REQUIRED_OPTIONS.each {|o| raise MissingRequiredOptionError,"Missing required option #{o}" unless options.has_key? o}
|
28
|
+
options.each_pair {|k,v| self.send :"#{k}=",v}
|
29
|
+
end
|
30
|
+
|
31
|
+
def create!
|
32
|
+
res = WhatCounts::HttpClient.execute('excreatelist',self)
|
33
|
+
if res.success?
|
34
|
+
self.instance_variable_set(:@id,res.body.to_i)
|
35
|
+
return self
|
36
|
+
else
|
37
|
+
raise CreationError, res.body # this is actually the message of why it failed
|
38
|
+
end
|
39
|
+
end
|
40
|
+
|
41
|
+
class << self
|
42
|
+
def create!(options)
|
43
|
+
o = self.new options
|
44
|
+
o.create!
|
45
|
+
end
|
46
|
+
end
|
47
|
+
|
48
|
+
DEPLOY_OPTIONS_TO_HTTP_PARAMS_MAP = {:list => :list_id, :template => :template_id,
|
49
|
+
:subject => :subject, :format => :format,
|
50
|
+
:segmentation_id => :segmentation_id, :campaign_alias => :campaign_alias,
|
51
|
+
:send_rss => :target_rss, :virtual_mta => :vmta,
|
52
|
+
:goodmail_token => :gm_token_type, :notification_email => :notify_email }
|
53
|
+
DEPLOY_REQUIRED_OPTIONS = []
|
54
|
+
def deploy!(options)
|
55
|
+
options.each_key {|o| raise UnknownListOptionError,"Unknown option #{o}" unless VALID_OPTIONS.include? o}
|
56
|
+
res = WhatCounts::HttpClient.execute('excreatelist',o)
|
57
|
+
end
|
58
|
+
|
59
|
+
def id; @id end
|
60
|
+
def to_param_string
|
61
|
+
@param_string ||= OPTIONS_TO_HTTP_PARAMS_MAP.keys.inject([]) do |acc,k|
|
62
|
+
val = self.send :"#{k}"
|
63
|
+
acc << "#{OPTIONS_TO_HTTP_PARAMS_MAP[k]}=#{CGI.escape(val.to_s)}" unless val.nil?
|
64
|
+
acc
|
65
|
+
end.join("&")
|
66
|
+
end
|
67
|
+
|
68
|
+
end
|
69
|
+
end
|
@@ -0,0 +1,54 @@
|
|
1
|
+
module WhatCounts
|
2
|
+
class OneOffMessage
|
3
|
+
|
4
|
+
private
|
5
|
+
OPTIONS_TO_HTTP_PARAMS_MAP = {:list_id => :list_id, :template_id => :template_id, :format => :format, :to => :to, :from => :from,
|
6
|
+
:subject => :subject, :body => :body, :data => :data}
|
7
|
+
attr_writer *(OPTIONS_TO_HTTP_PARAMS_MAP.keys)
|
8
|
+
|
9
|
+
public
|
10
|
+
attr_reader *(OPTIONS_TO_HTTP_PARAMS_MAP.keys)
|
11
|
+
REQUIRED_OPTIONS = [:list_id,:to,:format]
|
12
|
+
IRREGULAR_OPTIONS = [:data]
|
13
|
+
VALID_OPTIONS = OPTIONS_TO_HTTP_PARAMS_MAP.keys
|
14
|
+
|
15
|
+
def initialize(options)
|
16
|
+
options.each_key {|o| raise UnknownOptionError,"Unknown option #{o}" unless VALID_OPTIONS.include? o}
|
17
|
+
REQUIRED_OPTIONS.each {|o| raise MissingRequiredOptionError,"Missing required option #{o}" unless options.has_key? o}
|
18
|
+
options.each_pair {|k,v| self.send :"#{k}=",v}
|
19
|
+
end
|
20
|
+
|
21
|
+
def send!
|
22
|
+
WhatCounts::HttpClient.execute('send',self)
|
23
|
+
end
|
24
|
+
|
25
|
+
class << self
|
26
|
+
def send!(options)
|
27
|
+
self.new(options).send!
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
def to_param_string
|
32
|
+
@param_string ||= begin
|
33
|
+
pairs = (OPTIONS_TO_HTTP_PARAMS_MAP.keys-IRREGULAR_OPTIONS).inject([]) do |acc,k|
|
34
|
+
val = self.send :"#{k}"
|
35
|
+
acc << "#{OPTIONS_TO_HTTP_PARAMS_MAP[k]}=#{CGI.escape(val.to_s)}" unless val.nil?
|
36
|
+
acc
|
37
|
+
end
|
38
|
+
unless self.data.nil?
|
39
|
+
if self.data.kind_of? String
|
40
|
+
pairs << "data=#{CGI.escape(self.data)}"
|
41
|
+
elsif self.data.kind_of? Hash
|
42
|
+
data_pairs = self.data.inject([[],[]]){|acc,(k,v)| acc[0]<<k;acc[1]<<v;acc}
|
43
|
+
data_field = "#{data_pairs[0].join(',')}^#{data_pairs[1].join(',')}"
|
44
|
+
pairs << "data=#{CGI.escape(data_field)}"
|
45
|
+
else
|
46
|
+
# TODO i duno what to do here, probably error? Maybe not since the param isn't required
|
47
|
+
end
|
48
|
+
end
|
49
|
+
pairs
|
50
|
+
end.join("&")
|
51
|
+
end
|
52
|
+
|
53
|
+
end
|
54
|
+
end
|
@@ -0,0 +1,15 @@
|
|
1
|
+
module WhatCounts
|
2
|
+
module Rails
|
3
|
+
class Mailer
|
4
|
+
|
5
|
+
if Object.const_defined?(:ActionController)
|
6
|
+
include ActionController::UrlWriter
|
7
|
+
include ActionView::Helpers::AssetTagHelper
|
8
|
+
include ActionView::Helpers::TagHelper
|
9
|
+
end
|
10
|
+
|
11
|
+
include Helpers
|
12
|
+
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
@@ -0,0 +1,32 @@
|
|
1
|
+
module WhatCounts
|
2
|
+
class Response
|
3
|
+
|
4
|
+
SUCCESS = true
|
5
|
+
FAILURE = false
|
6
|
+
|
7
|
+
attr_reader :result, :body
|
8
|
+
private
|
9
|
+
attr_writer :result, :body
|
10
|
+
|
11
|
+
public
|
12
|
+
|
13
|
+
def initialize(url,document)
|
14
|
+
if document =~ /^(SUCCESS|FAILURE):?(.*)/
|
15
|
+
# simple response
|
16
|
+
self.body = $2.strip
|
17
|
+
case $1
|
18
|
+
when "SUCCESS"
|
19
|
+
self.result = SUCCESS
|
20
|
+
when "FAILURE"
|
21
|
+
self.result = FAILURE
|
22
|
+
end
|
23
|
+
else
|
24
|
+
# TODO data based response
|
25
|
+
self.body = document
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
def success?; self.result end
|
30
|
+
def failure?; !self.result end
|
31
|
+
end
|
32
|
+
end
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: ihunter-whatcounts
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version:
|
4
|
+
version: 0.3.1
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Ian Hunter
|
@@ -43,6 +43,11 @@ files:
|
|
43
43
|
- script/console
|
44
44
|
- script/destroy
|
45
45
|
- script/generate
|
46
|
+
- lib/whatcounts/http_client.rb
|
47
|
+
- lib/whatcounts/list.rb
|
48
|
+
- lib/whatcounts/one_off_message.rb
|
49
|
+
- lib/whatcounts/response.rb
|
50
|
+
- lib/whatcounts/rails/mailer.rb
|
46
51
|
has_rdoc: false
|
47
52
|
homepage: http://github.com/ihunter/whatcounts
|
48
53
|
post_install_message: PostInstall.txt
|