mosaic-lyris 1.0.1
Sign up to get free protection for your applications and to get access to all the features.
- data/Gemfile +3 -0
- data/README +4 -0
- data/Rakefile +31 -0
- data/VERSION +1 -0
- data/init.rb +4 -0
- data/lib/lyris.rb +2 -0
- data/lib/mosaic/lyris.rb +12 -0
- data/lib/mosaic/lyris/demographic.rb +65 -0
- data/lib/mosaic/lyris/filter.rb +6 -0
- data/lib/mosaic/lyris/list.rb +73 -0
- data/lib/mosaic/lyris/message.rb +95 -0
- data/lib/mosaic/lyris/object.rb +227 -0
- data/lib/mosaic/lyris/partner.rb +6 -0
- data/lib/mosaic/lyris/record.rb +101 -0
- data/lib/mosaic/lyris/trigger.rb +113 -0
- data/lib/mosaic/lyris/upload.rb +89 -0
- data/lib/mosaic/lyris_mailer.rb +102 -0
- data/mosaic-lyris.gemspec +143 -0
- data/test/demographic_test.rb +176 -0
- data/test/filter_test.rb +6 -0
- data/test/http_responder.rb +88 -0
- data/test/list_test.rb +49 -0
- data/test/message_test.rb +6 -0
- data/test/partner_test.rb +6 -0
- data/test/record_test.rb +177 -0
- data/test/responses/demographic/add_error_name_already_exists.xml +2 -0
- data/test/responses/demographic/add_success_12345.xml +2 -0
- data/test/responses/demographic/query_all_success.xml +19 -0
- data/test/responses/demographic/query_enabled_details_success.xml +12 -0
- data/test/responses/demographic/query_enabled_success.xml +13 -0
- data/test/responses/list/add_error_name_already_exists.xml +2 -0
- data/test/responses/list/add_success_12345.xml +2 -0
- data/test/responses/list/delete_error_not_found_99999.xml +2 -0
- data/test/responses/list/delete_success_12345.xml +2 -0
- data/test/responses/list/query_list_data_success.xml +20 -0
- data/test/responses/record/add_error_email_already_exists.xml +2 -0
- data/test/responses/record/add_success.xml +2 -0
- data/test/responses/record/query_all_success.xml +94 -0
- data/test/responses/record/query_all_success_empty.xml +2 -0
- data/test/responses/record/query_all_success_page_1.xml +54 -0
- data/test/responses/record/query_all_success_page_2.xml +34 -0
- data/test/responses/record/query_all_success_page_3.xml +14 -0
- data/test/responses/record/query_email_error_not_found.xml +2 -0
- data/test/responses/record/query_email_success_active.xml +14 -0
- data/test/responses/record/query_email_success_admin_trashed.xml +14 -0
- data/test/responses/record/query_email_success_bounced.xml +14 -0
- data/test/responses/record/query_email_success_unsubscribed.xml +14 -0
- data/test/responses/record/update_error_not_found.xml +2 -0
- data/test/responses/record/update_success.xml +2 -0
- data/test/responses/triggers/fire_error_invalid_recipients.xml +2 -0
- data/test/responses/triggers/fire_error_invalid_trigger_id.xml +2 -0
- data/test/responses/triggers/fire_success.xml +2 -0
- data/test/test_helper.rb +68 -0
- data/test/trigger_test.rb +45 -0
- metadata +342 -0
data/Gemfile
ADDED
data/README
ADDED
data/Rakefile
ADDED
@@ -0,0 +1,31 @@
|
|
1
|
+
require 'rake'
|
2
|
+
require 'rake/testtask'
|
3
|
+
|
4
|
+
task :default => [:test]
|
5
|
+
|
6
|
+
Rake::TestTask.new(:test) do |t|
|
7
|
+
t.pattern = 'test/*_test.rb'
|
8
|
+
t.verbose = true
|
9
|
+
end
|
10
|
+
|
11
|
+
Rake::Task[:test].comment = "Run all tests"
|
12
|
+
|
13
|
+
begin
|
14
|
+
require 'jeweler'
|
15
|
+
Jeweler::Tasks.new do |gemspec|
|
16
|
+
gemspec.name = "mosaic-lyris"
|
17
|
+
gemspec.summary = "Lyris/EmailLabs API"
|
18
|
+
gemspec.description = "A wrapper for the Lyris/EmailLabs API to simplify integration"
|
19
|
+
gemspec.email = "brent.faulkner@mosaic.com"
|
20
|
+
gemspec.homepage = "http://github.com/mosaicxm/mosaic-lyris"
|
21
|
+
gemspec.authors = ["S. Brent Faulkner"]
|
22
|
+
gemspec.add_dependency('builder')
|
23
|
+
gemspec.add_dependency('active_support')
|
24
|
+
gemspec.add_dependency('htmlentities')
|
25
|
+
gemspec.add_dependency('nokogiri')
|
26
|
+
gemspec.add_dependency('tzinfo')
|
27
|
+
gemspec.add_development_dependency('mocha')
|
28
|
+
end
|
29
|
+
rescue LoadError
|
30
|
+
puts "Jeweler not available. Install it with: sudo gem install jeweler"
|
31
|
+
end
|
data/VERSION
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
1.0.1
|
data/init.rb
ADDED
data/lib/lyris.rb
ADDED
data/lib/mosaic/lyris.rb
ADDED
@@ -0,0 +1,65 @@
|
|
1
|
+
module Mosaic
|
2
|
+
module Lyris
|
3
|
+
class Demographic < Object
|
4
|
+
attr_reader :enabled,
|
5
|
+
:group,
|
6
|
+
:id,
|
7
|
+
:list_id,
|
8
|
+
:name,
|
9
|
+
:options,
|
10
|
+
:size,
|
11
|
+
:type
|
12
|
+
|
13
|
+
class << self
|
14
|
+
def add(type, name, options = {})
|
15
|
+
validate_options!(type, options)
|
16
|
+
reply = post('demographic', 'add') do |request|
|
17
|
+
request.MLID options[:list_id] if options[:list_id]
|
18
|
+
put_data(request, demographic_type(type), name)
|
19
|
+
put_array_data(request, 'option', options[:option])
|
20
|
+
put_data(request, 'state', 'enabled') if options[:enabled]
|
21
|
+
put_data(request, 'size', options[:size]) if options[:size]
|
22
|
+
end
|
23
|
+
new(options.merge(:id => reply.at('/DATASET/DATA').inner_html.to_i, :name => name, :type => type))
|
24
|
+
end
|
25
|
+
|
26
|
+
def query(what, options = {})
|
27
|
+
reply = post('demographic', query_type(what)) do |request|
|
28
|
+
request.MLID options[:list_id] if options[:list_id]
|
29
|
+
end
|
30
|
+
reply.search('/DATASET/RECORD').collect do |record|
|
31
|
+
new :enabled => ([:enabled, :enabled_details].include?(what) || get_boolean_data(record, 'state', 'enabled')),
|
32
|
+
:group => get_data(record, "group"),
|
33
|
+
:id => get_integer_data(record, 'id'),
|
34
|
+
:list_id => options[:list_id],
|
35
|
+
:name => get_data(record, 'name'),
|
36
|
+
:options => get_array_data(record, 'option'),
|
37
|
+
:size => get_integer_data(record, 'size'),
|
38
|
+
:type => get_data(record, 'type').downcase.gsub(/ /,'_').to_sym
|
39
|
+
end
|
40
|
+
end
|
41
|
+
|
42
|
+
protected
|
43
|
+
def demographic_type(type)
|
44
|
+
raise ArgumentError, "expected :checkbox, :date, :multiple_checkbox, :multiple_select_list, :radio_button, :select_list, :text or :textarea; got #{type.inspect}" unless %w(checkbox date multiple_checkbox multiple_select_list radio_button select_list text textarea).include?(type.to_s)
|
45
|
+
type.to_s.gsub(/_/,' ')
|
46
|
+
end
|
47
|
+
|
48
|
+
def query_type(what)
|
49
|
+
raise ArgumentError, "expected :all, :enabled or :enabled_details; got #{what.inspect}" unless %w(all enabled enabled_details).include?(what.to_s)
|
50
|
+
"query-#{what}".gsub(/_/,'-')
|
51
|
+
end
|
52
|
+
|
53
|
+
def validate_options!(type, options)
|
54
|
+
if %w(multiple_checkbox multiple_select_list radio_button select_list).include?(type.to_s)
|
55
|
+
raise ArgumentError, "missing options for #{type.inspect} demographic" unless options[:options]
|
56
|
+
else
|
57
|
+
raise ArgumentError, "#{type.inspect} demographic does not support options" if options[:options]
|
58
|
+
end
|
59
|
+
raise ArgumentError, "#{type.inspect} demographic does not support :size option" if options[:size] unless %w(multiple_select_list select_list).include?(type.to_s)
|
60
|
+
end
|
61
|
+
end
|
62
|
+
end
|
63
|
+
end
|
64
|
+
end
|
65
|
+
|
@@ -0,0 +1,73 @@
|
|
1
|
+
require 'time'
|
2
|
+
|
3
|
+
module Mosaic
|
4
|
+
module Lyris
|
5
|
+
class List < Object
|
6
|
+
attr_reader :cache_time,
|
7
|
+
:clickthru_url,
|
8
|
+
:footer_html,
|
9
|
+
:footer_text,
|
10
|
+
:handle_autoreply,
|
11
|
+
:handle_autoreply_email,
|
12
|
+
:handle_unsubscribe,
|
13
|
+
:handle_unsubscribe_email,
|
14
|
+
:id,
|
15
|
+
:last_sent,
|
16
|
+
:members,
|
17
|
+
:messages,
|
18
|
+
:name,
|
19
|
+
:reply_forward_email,
|
20
|
+
:reply_forward_subject,
|
21
|
+
:reply_from_email,
|
22
|
+
:reply_from_name,
|
23
|
+
:status
|
24
|
+
|
25
|
+
def active?
|
26
|
+
status == 'active'
|
27
|
+
end
|
28
|
+
|
29
|
+
def archived?
|
30
|
+
status == 'archived'
|
31
|
+
end
|
32
|
+
|
33
|
+
class << self
|
34
|
+
def add(name, attributes = {})
|
35
|
+
reply = post('list', 'add') do |request|
|
36
|
+
put_data(request, 'name', name)
|
37
|
+
put_extra_data(request, 'CLICKTHRU_URL', attributes[:clickthru_url])
|
38
|
+
end
|
39
|
+
new attributes.merge(:id => reply.at('/DATASET/DATA').inner_html.to_i, :name => name)
|
40
|
+
end
|
41
|
+
|
42
|
+
def delete(id)
|
43
|
+
reply = post('list', 'delete') do |request|
|
44
|
+
request.MLID id
|
45
|
+
end
|
46
|
+
new :id => id
|
47
|
+
end
|
48
|
+
|
49
|
+
def query(what)
|
50
|
+
reply = post('list', query_type(what))
|
51
|
+
reply.search('/DATASET/RECORD').collect do |record|
|
52
|
+
new :cache_time => get_xml_time_data(record, 'cache-time'),
|
53
|
+
:id => get_integer_data(record, 'name', :id),
|
54
|
+
:last_sent => get_date_data(record, 'last-sent'),
|
55
|
+
:members => get_integer_data(record, 'members'),
|
56
|
+
:messages => get_integer_data(record, 'messages'),
|
57
|
+
:name => get_data(record, 'name'),
|
58
|
+
:status => get_data(record, 'status')
|
59
|
+
end
|
60
|
+
end
|
61
|
+
|
62
|
+
protected
|
63
|
+
def query_type(what)
|
64
|
+
if what == :all
|
65
|
+
'query-listdata'
|
66
|
+
else
|
67
|
+
raise ArgumentError, "expected :all, got #{what.inspect}"
|
68
|
+
end
|
69
|
+
end
|
70
|
+
end
|
71
|
+
end
|
72
|
+
end
|
73
|
+
end
|
@@ -0,0 +1,95 @@
|
|
1
|
+
module Mosaic
|
2
|
+
module Lyris
|
3
|
+
class Message < Object
|
4
|
+
attr_reader :id,
|
5
|
+
:aol,
|
6
|
+
:category,
|
7
|
+
:charset,
|
8
|
+
:clickthru,
|
9
|
+
:clickthru_text,
|
10
|
+
:edited_at,
|
11
|
+
:format,
|
12
|
+
:from_email,
|
13
|
+
:from_name,
|
14
|
+
:html,
|
15
|
+
:htmlencoding,
|
16
|
+
:name,
|
17
|
+
:rule,
|
18
|
+
:segment,
|
19
|
+
:segment_id,
|
20
|
+
:sent,
|
21
|
+
:sent_at,
|
22
|
+
:stats_sent,
|
23
|
+
:subject,
|
24
|
+
:text,
|
25
|
+
:type
|
26
|
+
|
27
|
+
class << self
|
28
|
+
def query(what, options = {})
|
29
|
+
if what == :all
|
30
|
+
query_all(options)
|
31
|
+
else
|
32
|
+
query_one(what, options)
|
33
|
+
end
|
34
|
+
end
|
35
|
+
|
36
|
+
protected
|
37
|
+
def query_all(options)
|
38
|
+
reply = post('message', 'query-listdata') do |request|
|
39
|
+
request.MLID options[:list_id] if options[:list_id]
|
40
|
+
end
|
41
|
+
reply.search('/DATASET/RECORD').collect do |record|
|
42
|
+
edit_time = get_time_data(record, 'last-edit-time')
|
43
|
+
edit_date = get_date_data(record, 'last-edit-date')
|
44
|
+
sent = get_data(record, 'sent')
|
45
|
+
sent_at = (sent == 'yes') ? get_date_data(record, 'date').to_time + get_time_offset_data(record, 'delivery') : nil
|
46
|
+
subject = get_data(record, 'subject')
|
47
|
+
new :id => get_integer_data(record, 'mid'),
|
48
|
+
:category => get_data(record, 'category'),
|
49
|
+
:edited_at => edit_date && (edit_date.to_time + edit_time.to_i - edit_time.to_date.to_time.to_i),
|
50
|
+
:format => get_data(record, 'message-format'),
|
51
|
+
:segment_id => get_integer_data(record, 'segment-id'),
|
52
|
+
:segment => get_data(record, 'segment'),
|
53
|
+
:sent => sent,
|
54
|
+
:sent_at => sent_at,
|
55
|
+
:stats_sent => get_integer_data(record, 'stats-sent'),
|
56
|
+
:subject => subject,
|
57
|
+
:type => get_data(record, 'mlid').blank? ? 'system' : (subject =~ /\APROOF: / ? 'test' : 'user')
|
58
|
+
end
|
59
|
+
end
|
60
|
+
|
61
|
+
def query_one(id, options)
|
62
|
+
reply = post('message', 'query-data') do |request|
|
63
|
+
request.MLID options[:list_id] if options[:list_id]
|
64
|
+
request.MID id
|
65
|
+
end
|
66
|
+
record = reply.at('/DATASET/RECORD')
|
67
|
+
sent = get_data(record, 'sent')
|
68
|
+
sent_at = (sent == 'yes') ? get_date_data(record, 'date').to_time + get_time_offset_data(record, 'delivery') : nil
|
69
|
+
new :id => id,
|
70
|
+
:aol => get_data(record, 'message-aol'),
|
71
|
+
:category => get_data(record, 'category'),
|
72
|
+
:charset => get_data(record, 'charset'),
|
73
|
+
:clickthru => get_boolean_data(record, 'clickthru', 'on'),
|
74
|
+
:clickthru_text => get_boolean_data(record, 'clickthru-text', 'on'),
|
75
|
+
:format => get_data(record, 'message-format'),
|
76
|
+
:from_email => get_data(record, 'from-email'),
|
77
|
+
:from_name => get_data(record, 'from-name'),
|
78
|
+
:html => get_data(record, 'message-html'),
|
79
|
+
:htmlencoding => get_data(record, 'htmlencoding'),
|
80
|
+
:segment_id => get_integer_data(record, 'rule'),
|
81
|
+
:segment => get_data(record, 'rule-name'),
|
82
|
+
:name => get_data(record, 'name'),
|
83
|
+
:sent => sent,
|
84
|
+
:sent_at => sent_at,
|
85
|
+
:subject => get_data(record, 'subject'),
|
86
|
+
:text => get_data(record, 'message-text')
|
87
|
+
end
|
88
|
+
end
|
89
|
+
|
90
|
+
def sent?
|
91
|
+
sent == 'yes'
|
92
|
+
end
|
93
|
+
end
|
94
|
+
end
|
95
|
+
end
|
@@ -0,0 +1,227 @@
|
|
1
|
+
require 'builder'
|
2
|
+
require 'net/https'
|
3
|
+
require 'nokogiri'
|
4
|
+
require 'uri'
|
5
|
+
require 'htmlentities'
|
6
|
+
|
7
|
+
require 'active_support/core_ext/object/blank'
|
8
|
+
require 'active_support/core_ext/time/calculations'
|
9
|
+
|
10
|
+
module Mosaic
|
11
|
+
module Lyris
|
12
|
+
class Error < RuntimeError; end
|
13
|
+
|
14
|
+
class Object
|
15
|
+
private_class_method :new
|
16
|
+
|
17
|
+
@@logger = nil
|
18
|
+
|
19
|
+
def initialize(attributes)
|
20
|
+
attributes.each do |attribute,value|
|
21
|
+
instance_variable_set "@#{attribute}", value unless value.nil?
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
def to_param
|
26
|
+
id && id.to_s
|
27
|
+
end
|
28
|
+
|
29
|
+
class << self
|
30
|
+
def configuration
|
31
|
+
@@configuration ||= load_configuration
|
32
|
+
end
|
33
|
+
|
34
|
+
def configuration=(value)
|
35
|
+
@@configuration = value
|
36
|
+
end
|
37
|
+
|
38
|
+
def load_configuration
|
39
|
+
configuration = YAML.load_file(File.join(::Rails.root.to_s,'config','lyris.yml')) rescue {}
|
40
|
+
configuration = configuration[::Rails.env] if configuration.include?(::Rails.env)
|
41
|
+
configuration
|
42
|
+
end
|
43
|
+
end
|
44
|
+
|
45
|
+
protected
|
46
|
+
class << self
|
47
|
+
def callback_url
|
48
|
+
configuration['callback_url']
|
49
|
+
end
|
50
|
+
|
51
|
+
def default_list_id
|
52
|
+
configuration['list_id']
|
53
|
+
end
|
54
|
+
|
55
|
+
def default_trigger_id
|
56
|
+
configuration['trigger_id']
|
57
|
+
end
|
58
|
+
|
59
|
+
def get_array_data(record, type)
|
60
|
+
if record.at("DATA[@type='#{type}']")
|
61
|
+
record.search("DATA[@type='#{type}']").collect do |data|
|
62
|
+
if block_given?
|
63
|
+
yield data
|
64
|
+
else
|
65
|
+
data.inner_html
|
66
|
+
end
|
67
|
+
end
|
68
|
+
end
|
69
|
+
end
|
70
|
+
|
71
|
+
def get_boolean_data(record, type, value, attribute = nil, conditions = {})
|
72
|
+
if data = get_data(record, type, attribute, conditions)
|
73
|
+
data == value
|
74
|
+
end
|
75
|
+
end
|
76
|
+
|
77
|
+
def get_data(record, type, attribute = nil, conditions = {})
|
78
|
+
xpath = "DATA[@type='#{type}']"
|
79
|
+
xpath << conditions.collect { |a,v| "[@#{a}='#{v}']" }.join
|
80
|
+
if element = record.at(xpath)
|
81
|
+
data = attribute ? element[attribute] : element.inner_html
|
82
|
+
# TODO: fix encoding if necessary... seems like we should need to convert to UTF-8 here, but this works for now
|
83
|
+
HTMLEntities.new.decode(data.gsub(/&#(\d+);/) { Integer($1).chr })
|
84
|
+
end
|
85
|
+
end
|
86
|
+
|
87
|
+
def get_date_data(record, type, attribute = nil, conditions = {})
|
88
|
+
data = get_data(record, type, attribute, conditions)
|
89
|
+
Date.parse(data) unless data.blank?
|
90
|
+
end
|
91
|
+
|
92
|
+
def get_demographic_data(record)
|
93
|
+
if data = get_array_data(record, 'demographic') { |d| [ d[:id].to_i, d.inner_html ] }
|
94
|
+
data.inject({}) do |h,(k,v)|
|
95
|
+
case h[k]
|
96
|
+
when NilClass
|
97
|
+
h[k] = v
|
98
|
+
when Array
|
99
|
+
h[k] << v
|
100
|
+
else
|
101
|
+
h[k] = Array(h[k])
|
102
|
+
h[k] << v
|
103
|
+
end
|
104
|
+
h
|
105
|
+
end
|
106
|
+
end
|
107
|
+
end
|
108
|
+
|
109
|
+
def get_element(record, element)
|
110
|
+
if data = record.at("/#{element}")
|
111
|
+
data.inner_html
|
112
|
+
end
|
113
|
+
end
|
114
|
+
|
115
|
+
def get_integer_data(record, type, attribute = nil, conditions = {})
|
116
|
+
if data = get_data(record, type, attribute, conditions)
|
117
|
+
data.gsub(/,/,'').to_i
|
118
|
+
end
|
119
|
+
end
|
120
|
+
|
121
|
+
def get_integer_element(record, element)
|
122
|
+
get_element(record, element).to_i
|
123
|
+
end
|
124
|
+
|
125
|
+
def get_time_data(record, type, attribute = nil, conditions = {})
|
126
|
+
if data = get_data(record, type, attribute, conditions)
|
127
|
+
Time.use_zone('Pacific Time (US & Canada)') do
|
128
|
+
Time.zone.parse(data)
|
129
|
+
end
|
130
|
+
end
|
131
|
+
end
|
132
|
+
|
133
|
+
def get_time_element(record, element)
|
134
|
+
if data = get_element(record, element)
|
135
|
+
Time.parse(data) + (Time.zone.utc_offset - Time.zone_offset('PST'))
|
136
|
+
end
|
137
|
+
end
|
138
|
+
|
139
|
+
def get_time_offset_data(record, type, attribute = nil, conditions = {})
|
140
|
+
if offset = get_integer_data(record, type, attribute, conditions)
|
141
|
+
offset + (Time.zone.utc_offset - Time.zone_offset('PST'))
|
142
|
+
end
|
143
|
+
end
|
144
|
+
|
145
|
+
def get_xml_time_data(record, type, attribute = nil, conditions = {})
|
146
|
+
if data = get_data(record, type, attribute, conditions)
|
147
|
+
Time.xmlschema(data)
|
148
|
+
end
|
149
|
+
end
|
150
|
+
|
151
|
+
def logger
|
152
|
+
@@logger ||= nil
|
153
|
+
end
|
154
|
+
|
155
|
+
def logger=(logger)
|
156
|
+
@@logger = logger
|
157
|
+
end
|
158
|
+
|
159
|
+
def password
|
160
|
+
configuration['password']
|
161
|
+
end
|
162
|
+
|
163
|
+
def post(type, activity, &block)
|
164
|
+
xml = Builder::XmlMarkup.new(:indent => 2)
|
165
|
+
xml.instruct!
|
166
|
+
xml.DATASET do
|
167
|
+
xml.SITE_ID site_id
|
168
|
+
put_extra_data(xml, 'password', password)
|
169
|
+
block.call(xml) if block
|
170
|
+
end
|
171
|
+
input = xml.target!
|
172
|
+
|
173
|
+
request = Net::HTTP::Post.new("/API/mailing_list.html")
|
174
|
+
logger.debug ">>>>> REQUEST:\ntype=#{type}\nactivity=#{activity}\ninput=#{input}\n>>>>>" if logger
|
175
|
+
request.set_form_data('type' => type, 'activity' => activity, 'input' => input)
|
176
|
+
|
177
|
+
conn = Net::HTTP.new(server, 443)
|
178
|
+
conn.use_ssl = true
|
179
|
+
conn.verify_mode = OpenSSL::SSL::VERIFY_NONE
|
180
|
+
|
181
|
+
conn.start do |http|
|
182
|
+
# TODO: parse encoding from declaration? update declaration after conversion?
|
183
|
+
reply = http.request(request).body
|
184
|
+
logger.debug ">>>>> REPLY:\n#{reply}\n>>>>>" if logger
|
185
|
+
document = Nokogiri.XML(reply)
|
186
|
+
raise Error, (document % '/DATASET/DATA').inner_html unless document % "/DATASET/TYPE[.='success']"
|
187
|
+
document
|
188
|
+
end
|
189
|
+
end
|
190
|
+
|
191
|
+
def put_array_data(request, type, values)
|
192
|
+
Array(values).each do |value|
|
193
|
+
put_data(request, type, value)
|
194
|
+
end
|
195
|
+
end
|
196
|
+
|
197
|
+
def put_data(request, type, value, attributes = {})
|
198
|
+
request.DATA value, {:type => type}.merge(attributes) unless value.nil?
|
199
|
+
end
|
200
|
+
|
201
|
+
def put_demographic_data(request, demographics)
|
202
|
+
Array(demographics).each do |id, value|
|
203
|
+
Array(value).each do |v|
|
204
|
+
put_data(request, 'demographic', v, :id => id)
|
205
|
+
end
|
206
|
+
end
|
207
|
+
end
|
208
|
+
|
209
|
+
def put_extra_data(request, id, value)
|
210
|
+
put_data(request, 'extra', value, :id => id)
|
211
|
+
end
|
212
|
+
|
213
|
+
def server
|
214
|
+
configuration['server']
|
215
|
+
end
|
216
|
+
|
217
|
+
def site_id
|
218
|
+
configuration['site_id']
|
219
|
+
end
|
220
|
+
|
221
|
+
def triggers
|
222
|
+
configuration['triggers']
|
223
|
+
end
|
224
|
+
end
|
225
|
+
end
|
226
|
+
end
|
227
|
+
end
|