sklik-api 0.0.16 → 0.1.0
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/Rakefile +28 -4
- data/VERSION +1 -1
- data/lib/sklik-api/campaign.rb +112 -67
- data/lib/sklik-api/campaign_parts/adgroup.rb +272 -95
- data/lib/sklik-api/campaign_parts/adtext.rb +165 -31
- data/lib/sklik-api/campaign_parts/keyword.rb +192 -38
- data/lib/sklik-api/client.rb +4 -4
- data/lib/sklik-api/connection.rb +36 -13
- data/lib/sklik-api/exceptions.rb +6 -0
- data/lib/sklik-api/sklik_object.rb +29 -1
- data/lib/sklik-api.rb +20 -3
- data/sklik-api.gemspec +11 -3
- data/test/integration/adgroup_test.rb +126 -0
- data/test/integration/adtext_test.rb +106 -0
- data/test/integration/campaign_test.rb +87 -0
- data/test/integration/errors_test.rb +164 -0
- data/test/integration/keyword_test.rb +131 -0
- data/test/unit/adgroup_test.rb +147 -0
- data/test/unit/campaign_test.rb +318 -0
- data/test/unit/client_test.rb +27 -0
- metadata +12 -4
- data/test/unit/campaign.rb +0 -180
@@ -8,7 +8,7 @@ class SklikApi
|
|
8
8
|
:premiseMode, :premiseID
|
9
9
|
]
|
10
10
|
|
11
|
-
include
|
11
|
+
include SklikObject
|
12
12
|
=begin
|
13
13
|
Example of input hash
|
14
14
|
{
|
@@ -22,10 +22,23 @@ Example of input hash
|
|
22
22
|
|
23
23
|
=end
|
24
24
|
|
25
|
-
def initialize
|
25
|
+
def initialize args, deprecated_args = {}
|
26
|
+
|
27
|
+
#deprecated way to set up new adgroup!
|
28
|
+
if args.is_a?(SklikApi::Adgroup)
|
29
|
+
puts "DEPRECATION WARNING: Please update your code for SklikApi::Adtext.new(adgroup, args) to SklikApi::Adtext.new(args = {}) possible to add parent adgroup by adding :adgroup => your adgroup"
|
30
|
+
#set adgroup owner campaign
|
31
|
+
@adgroup = args
|
32
|
+
args = deprecated_args
|
33
|
+
#new way to set adgroups!
|
34
|
+
else
|
35
|
+
#set adgroup owner campaign
|
36
|
+
#if in input args there is pointer to parent campaign!
|
37
|
+
@adgroup = args.delete(:adgroup)
|
38
|
+
end
|
39
|
+
@args = args
|
40
|
+
|
26
41
|
@adtext_data = nil
|
27
|
-
#set adtext owner adgroup
|
28
|
-
@adgroup = adgroup
|
29
42
|
|
30
43
|
super args
|
31
44
|
end
|
@@ -35,50 +48,106 @@ Example of input hash
|
|
35
48
|
end
|
36
49
|
|
37
50
|
def create_args
|
38
|
-
raise ArgumentError, "Adtexts need's to know adgroup_id" unless @adgroup.args[:adgroup_id]
|
51
|
+
raise ArgumentError, "Adtexts need's to know adgroup_id" unless @args[:adgroup_id] || @adgroup.args[:adgroup_id]
|
39
52
|
out = []
|
40
53
|
#add campaign id to know where to create adgroup
|
41
|
-
out << @adgroup.args[:adgroup_id]
|
54
|
+
out << @args[:adgroup_id] || @adgroup.args[:adgroup_id]
|
42
55
|
|
43
56
|
#add adtext struct
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
57
|
+
c_args = {}
|
58
|
+
c_args[:creative1] = @args[:headline]
|
59
|
+
c_args[:creative2] = @args[:description1]
|
60
|
+
c_args[:creative3] = @args[:description2]
|
61
|
+
c_args[:clickthruText] = @args[:display_url]
|
62
|
+
c_args[:clickthruUrl] = @args[:url]
|
63
|
+
c_args[:status] = status_for_update if status_for_update
|
50
64
|
|
51
65
|
ADDITIONAL_FIELDS.each do |add_info|
|
52
66
|
field_name = add_info.to_s.underscore.to_sym
|
53
|
-
|
67
|
+
c_args[add_info] = @args[field_name] if @args[field_name]
|
54
68
|
end
|
55
69
|
|
56
|
-
out <<
|
70
|
+
out << c_args
|
57
71
|
|
58
72
|
#return output
|
59
73
|
out
|
60
74
|
end
|
61
75
|
|
62
|
-
def
|
63
|
-
|
64
|
-
|
76
|
+
def update_args
|
77
|
+
out = []
|
78
|
+
|
79
|
+
#add campaign id on which will be performed update
|
80
|
+
out << @args[:adtext_id]
|
81
|
+
|
82
|
+
#prepare campaign struct
|
83
|
+
u_args = {}
|
84
|
+
u_args[:status] = status_for_update if status_for_update
|
85
|
+
|
86
|
+
out << u_args
|
87
|
+
ADDITIONAL_FIELDS.each do |add_info|
|
88
|
+
field_name = add_info.to_s.underscore.to_sym
|
89
|
+
u_args[add_info] = @args[field_name] if @args[field_name]
|
90
|
+
end
|
91
|
+
|
92
|
+
out
|
93
|
+
end
|
94
|
+
|
95
|
+
def self.get id
|
96
|
+
if adtext = super(NAME, id)
|
97
|
+
SklikApi::Adtext.new(process_sklik_data adtext)
|
98
|
+
else
|
99
|
+
nil
|
100
|
+
end
|
101
|
+
end
|
102
|
+
|
103
|
+
def self.find args, deprecated_args = {}
|
104
|
+
out = []
|
105
|
+
|
106
|
+
if args.is_a?(Integer)
|
107
|
+
return get args
|
108
|
+
|
109
|
+
#asking for adgroup deprecated way!
|
110
|
+
elsif args.is_a?(SklikApi::Adgroup)
|
111
|
+
puts "DEPRECATION WARNING: Please update your code for SklikApi::Adtext.find(adgroup, args) to SklikApi::Adtext.find(adgroup_id: 1234) possible to add parent adgroup by adding :adgroup => your adgroup"
|
112
|
+
adgroup_id = args.args[:adgroup_id]
|
113
|
+
args = deprecated_args
|
114
|
+
|
115
|
+
#asking for adgroup by hash with keyword_id
|
116
|
+
elsif args.is_a?(Hash) && args[:adtext_id]
|
117
|
+
if adtext = get(args[:adtext_id])
|
118
|
+
return [adtext]
|
119
|
+
else
|
120
|
+
return []
|
121
|
+
end
|
122
|
+
|
123
|
+
#asking for keyword by hash
|
124
|
+
else
|
125
|
+
adgroup_id = args[:adgroup_id]
|
126
|
+
end
|
127
|
+
|
128
|
+
return [] unless adgroup_id
|
129
|
+
|
130
|
+
super(NAME, adgroup_id).each do |adtext|
|
65
131
|
if args[:adtext_id].nil? || (args[:adtext_id] && args[:adtext_id].to_i == adtext[:id].to_i)
|
66
|
-
out << SklikApi::Adtext.new(
|
67
|
-
adgroup,
|
68
|
-
:adtext_id => adtext[:id],
|
69
|
-
:headline => adtext[:creative1],
|
70
|
-
:description1 => adtext[:creative2],
|
71
|
-
:description2 => adtext[:creative3],
|
72
|
-
:display_url =>adtext[:clickthruText],
|
73
|
-
:url => adtext[:clickthruUrl],
|
74
|
-
:name => adtext[:name],
|
75
|
-
:status => fix_status(adtext)
|
76
|
-
)
|
132
|
+
out << SklikApi::Adtext.new(process_sklik_data adtext)
|
77
133
|
end
|
78
134
|
end
|
79
135
|
out
|
80
136
|
end
|
81
137
|
|
138
|
+
def self.process_sklik_data adtext = {}
|
139
|
+
{
|
140
|
+
:adgroup_id => adtext[:groupId],
|
141
|
+
:adtext_id => adtext[:id],
|
142
|
+
:headline => adtext[:creative1],
|
143
|
+
:description1 => adtext[:creative2],
|
144
|
+
:description2 => adtext[:creative3],
|
145
|
+
:display_url =>adtext[:clickthruText],
|
146
|
+
:url => adtext[:clickthruUrl],
|
147
|
+
:status => fix_status(adtext)
|
148
|
+
}
|
149
|
+
end
|
150
|
+
|
82
151
|
def self.fix_status adtext
|
83
152
|
if adtext[:removed] == true
|
84
153
|
return :stopped
|
@@ -99,14 +168,79 @@ Example of input hash
|
|
99
168
|
end
|
100
169
|
end
|
101
170
|
|
171
|
+
def self.get_current_status args = {}
|
172
|
+
raise ArgumentError, "Adtext_id is required" unless args[:adtext_id]
|
173
|
+
if adgroup = self.get(args[:adtext_id])
|
174
|
+
adgroup.args[:status]
|
175
|
+
else
|
176
|
+
raise ArgumentError, "Adtext by #{args.inspect} couldn't be found!"
|
177
|
+
end
|
178
|
+
end
|
179
|
+
|
180
|
+
def get_current_status
|
181
|
+
self.class.get_current_status :adtext_id => @args[:adtext_id]
|
182
|
+
end
|
183
|
+
|
184
|
+
def valid?
|
185
|
+
clear_errors
|
186
|
+
log_error "headline is required or too long" unless args[:headline] && args[:headline].size > 0 && args[:headline].size <= 35
|
187
|
+
log_error "description1 is required or too long" unless args[:description1] && args[:description1].size > 0 && args[:description1].size <= 45
|
188
|
+
log_error "description2 is required or too long" unless args[:description2] && args[:description2].size > 0 && args[:description2].size <= 45
|
189
|
+
log_error "display_url is required or too long" unless args[:display_url] && args[:display_url].size > 0 && args[:display_url].size <= 45
|
190
|
+
log_error "url is required" unless args[:url] && args[:url].size > 0 && args[:url].size <= 45
|
191
|
+
log_error "adgroup_id is required" unless args[:adgroup_id] || (@adgroup && @adgroup.args[:adgroup_id])
|
192
|
+
!errors.any?
|
193
|
+
end
|
194
|
+
|
195
|
+
def update args = {}
|
196
|
+
@args.merge!(args)
|
197
|
+
save
|
198
|
+
end
|
199
|
+
|
102
200
|
def save
|
201
|
+
clear_errors
|
103
202
|
if @args[:adtext_id] #do update
|
104
203
|
|
105
|
-
|
106
|
-
|
107
|
-
|
204
|
+
#get current status of campaign
|
205
|
+
before_status = get_current_status
|
206
|
+
|
207
|
+
#restore campaign before update
|
208
|
+
restore if before_status == :stopped
|
209
|
+
|
210
|
+
begin
|
211
|
+
update_object
|
212
|
+
|
213
|
+
rescue Exception => e
|
214
|
+
log_error e.message
|
215
|
+
end
|
216
|
+
|
217
|
+
#remove it if new status is stopped or status doesn't changed and before it was stopped
|
218
|
+
remove if (@args[:status] == :stopped) || (@args[:status].nil? && before_status == :stopped)
|
219
|
+
|
220
|
+
else #do save
|
221
|
+
@args[:adgroup_id] = @adgroup.args[:adgroup_id] if !@args[:adgroup_id] && @adgroup.args[:adgroup_id]
|
222
|
+
|
223
|
+
begin
|
224
|
+
#create adtext
|
225
|
+
create
|
226
|
+
rescue Exception => e
|
227
|
+
log_error e.message
|
228
|
+
#don't continue with creating campaign!
|
229
|
+
return false
|
230
|
+
end
|
231
|
+
|
232
|
+
#remove it if new status is stopped
|
233
|
+
remove if @args[:status] && @args[:status].to_s.to_sym == :stopped
|
108
234
|
end
|
235
|
+
|
236
|
+
!errors.any?
|
109
237
|
end
|
238
|
+
|
239
|
+
def log_error message
|
240
|
+
@adgroup.log_error "Adtext: #{@args[:headline]} -> #{message}" if @adgroup
|
241
|
+
errors << message
|
242
|
+
end
|
243
|
+
|
110
244
|
end
|
111
245
|
end
|
112
246
|
|
@@ -4,52 +4,109 @@ class SklikApi
|
|
4
4
|
|
5
5
|
NAME = "keyword"
|
6
6
|
|
7
|
-
|
7
|
+
ADDITIONAL_FIELDS = [
|
8
|
+
:cpc, :url
|
9
|
+
]
|
10
|
+
ADDITIONAL_READ_FIELDS = [
|
11
|
+
:disabled, :cpc, :url, :minCpc
|
12
|
+
]
|
13
|
+
|
14
|
+
include SklikObject
|
8
15
|
=begin
|
9
16
|
Example of input hash
|
10
17
|
{
|
11
18
|
:keyword => "\"some funny keyword\""
|
12
19
|
}
|
13
20
|
=end
|
14
|
-
|
15
|
-
def initialize
|
21
|
+
|
22
|
+
def initialize args, deprecated_args = {}
|
23
|
+
|
24
|
+
#deprecated way to set up new adgroup!
|
25
|
+
if args.is_a?(SklikApi::Adgroup)
|
26
|
+
puts "DEPRECATION WARNING: Please update your code for SklikApi::Keyword.new(adgroup, args) to SklikApi::Keyword.new(args = {}) possible to add parent adgroup by adding :adgroup => your adgroup"
|
27
|
+
#set adgroup owner campaign
|
28
|
+
@adgroup = args
|
29
|
+
args = deprecated_args
|
30
|
+
|
31
|
+
#new way to set adgroups!
|
32
|
+
else
|
33
|
+
#set adgroup owner campaign
|
34
|
+
#if in input args there is pointer to parent campaign!
|
35
|
+
@adgroup = args.delete(:adgroup)
|
36
|
+
end
|
37
|
+
@args = args
|
38
|
+
|
16
39
|
@keyword_data = nil
|
17
|
-
#set keyword owner adgroup
|
18
|
-
@adgroup = adgroup
|
19
40
|
|
20
41
|
super args
|
21
42
|
end
|
22
|
-
|
43
|
+
|
23
44
|
def create_args
|
24
|
-
raise ArgumentError, "Keyword need's to know adgroup_id" unless @adgroup.args[:adgroup_id]
|
45
|
+
raise ArgumentError, "Keyword need's to know adgroup_id" unless @args[:adgroup_id] || @adgroup.args[:adgroup_id]
|
25
46
|
out = []
|
26
47
|
#add campaign id to know where to create adgroup
|
27
|
-
out << @adgroup.args[:adgroup_id]
|
28
|
-
|
48
|
+
out << @args[:adgroup_id] || @adgroup.args[:adgroup_id]
|
49
|
+
|
29
50
|
#add adtext struct
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
51
|
+
c_args = {}
|
52
|
+
c_args[:name] = strip_match_type @args[:keyword]
|
53
|
+
c_args[:matchType] = get_math_type @args[:keyword]
|
54
|
+
#Currently not working :(
|
55
|
+
c_args[:status] = status_for_update if status_for_update
|
56
|
+
|
57
|
+
ADDITIONAL_FIELDS.each do |add_info|
|
58
|
+
field_name = add_info.to_s.underscore.to_sym
|
59
|
+
c_args[add_info] = @args[field_name] if @args[field_name]
|
60
|
+
end
|
61
|
+
|
62
|
+
if @args[:cpc]
|
63
|
+
c_args[:cpc] = (@args[:cpc] * 100).to_i
|
64
|
+
end
|
65
|
+
|
66
|
+
|
67
|
+
out << c_args
|
68
|
+
|
35
69
|
#return output
|
36
70
|
out
|
37
71
|
end
|
38
|
-
|
72
|
+
|
73
|
+
def update_args
|
74
|
+
out = []
|
75
|
+
|
76
|
+
#add campaign id on which will be performed update
|
77
|
+
out << @args[:keyword_id]
|
78
|
+
|
79
|
+
#prepare campaign struct
|
80
|
+
u_args = {}
|
81
|
+
u_args[:status] = status_for_update if status_for_update
|
82
|
+
|
83
|
+
ADDITIONAL_FIELDS.each do |add_info|
|
84
|
+
field_name = add_info.to_s.underscore.to_sym
|
85
|
+
u_args[add_info] = @args[field_name] if @args[field_name]
|
86
|
+
end
|
87
|
+
if @args[:cpc]
|
88
|
+
u_args[:cpc] = (@args[:cpc] * 100).to_i
|
89
|
+
end
|
90
|
+
out << u_args
|
91
|
+
|
92
|
+
#return output
|
93
|
+
out
|
94
|
+
end
|
95
|
+
|
39
96
|
def strip_match_type keyword
|
40
97
|
keyword.gsub(/(\[|\]|\")/, "").gsub(/^-/, "")
|
41
98
|
end
|
42
|
-
|
99
|
+
|
43
100
|
def get_math_type keyword
|
44
|
-
if /^-\[.*\]$/ =~ keyword
|
101
|
+
if /^-\[.*\]$/ =~ keyword
|
45
102
|
return "negativeExact"
|
46
|
-
elsif /^\[.*\]$/ =~ keyword
|
103
|
+
elsif /^\[.*\]$/ =~ keyword
|
47
104
|
return "exact"
|
48
|
-
elsif /^-\".*\"$/ =~ keyword
|
105
|
+
elsif /^-\".*\"$/ =~ keyword
|
49
106
|
return "negativePhrase"
|
50
|
-
elsif /^\".*\"$/ =~ keyword
|
107
|
+
elsif /^\".*\"$/ =~ keyword
|
51
108
|
return "phrase"
|
52
|
-
elsif /^-.*$/ =~ keyword
|
109
|
+
elsif /^-.*$/ =~ keyword
|
53
110
|
return "negativeBroad"
|
54
111
|
else
|
55
112
|
return "broad"
|
@@ -67,22 +124,66 @@ Example of input hash
|
|
67
124
|
else keyword
|
68
125
|
end
|
69
126
|
end
|
70
|
-
|
71
|
-
def self.
|
127
|
+
|
128
|
+
def self.get id
|
129
|
+
if keyword = super(NAME, id)
|
130
|
+
SklikApi::Keyword.new(process_sklik_data keyword)
|
131
|
+
else
|
132
|
+
nil
|
133
|
+
end
|
134
|
+
end
|
135
|
+
|
136
|
+
def self.find args, deprecated_args = {}
|
72
137
|
out = []
|
73
|
-
|
138
|
+
|
139
|
+
if args.is_a?(Integer)
|
140
|
+
return get args
|
141
|
+
|
142
|
+
#asking for adgroup deprecated way!
|
143
|
+
elsif args.is_a?(SklikApi::Adgroup)
|
144
|
+
puts "DEPRECATION WARNING: Please update your code for SklikApi::Keyword.find(adgroup, args) to SklikApi::Keyword.find(adgroup_id: 1234) possible to add parent adgroup by adding :adgroup => your adgroup"
|
145
|
+
adgroup_id = args.args[:adgroup_id]
|
146
|
+
args = deprecated_args
|
147
|
+
|
148
|
+
#asking for adgroup by hash with keyword_id
|
149
|
+
elsif args.is_a?(Hash) && args[:keyword_id]
|
150
|
+
if keyword = get(args[:keyword_id])
|
151
|
+
return [keyword]
|
152
|
+
else
|
153
|
+
return []
|
154
|
+
end
|
155
|
+
|
156
|
+
#asking for keyword by hash
|
157
|
+
else
|
158
|
+
adgroup_id = args[:adgroup_id]
|
159
|
+
end
|
160
|
+
|
161
|
+
return [] unless adgroup_id
|
162
|
+
|
163
|
+
super(NAME, adgroup_id).each do |keyword|
|
74
164
|
if args[:keyword_id].nil? || (args[:keyword_id] && args[:keyword_id].to_i == keyword[:id].to_i)
|
75
|
-
out << SklikApi::Keyword.new(
|
76
|
-
adgroup,
|
77
|
-
:keyword_id => keyword[:id],
|
78
|
-
:keyword => apply_math_type(keyword[:name], keyword[:matchType] ),
|
79
|
-
:status => fix_status(keyword)
|
80
|
-
)
|
165
|
+
out << SklikApi::Keyword.new(process_sklik_data keyword)
|
81
166
|
end
|
82
167
|
end
|
83
168
|
out
|
84
169
|
end
|
85
170
|
|
171
|
+
def self.process_sklik_data keyword = {}
|
172
|
+
out = {
|
173
|
+
:adgroup_id => keyword[:groupId],
|
174
|
+
:keyword_id => keyword[:id],
|
175
|
+
:keyword => apply_math_type(keyword[:name], keyword[:matchType] ),
|
176
|
+
:status => fix_status(keyword)
|
177
|
+
}
|
178
|
+
ADDITIONAL_READ_FIELDS.each do |add_info|
|
179
|
+
field_name = add_info.to_s.underscore.to_sym
|
180
|
+
out[field_name] = keyword[add_info] if keyword[add_info]
|
181
|
+
end
|
182
|
+
out[:cpc] = keyword[:cpc].to_f/100.0 if keyword[:cpc]
|
183
|
+
|
184
|
+
out
|
185
|
+
end
|
186
|
+
|
86
187
|
def self.fix_status keyword
|
87
188
|
if keyword[:removed] == true
|
88
189
|
return :stopped
|
@@ -101,18 +202,71 @@ Example of input hash
|
|
101
202
|
if @keyword_data
|
102
203
|
@keyword_data
|
103
204
|
else
|
104
|
-
@keyword_data =
|
205
|
+
@keyword_data = @args end
|
206
|
+
end
|
207
|
+
|
208
|
+
|
209
|
+
def self.get_current_status args = {}
|
210
|
+
raise ArgumentError, "Keyword_id is required" unless args[:keyword_id]
|
211
|
+
if adgroup = self.get(args[:keyword_id])
|
212
|
+
adgroup.args[:status]
|
213
|
+
else
|
214
|
+
raise ArgumentError, "Keyword by #{args.inspect} couldn't be found!"
|
105
215
|
end
|
106
216
|
end
|
107
|
-
|
108
|
-
def
|
217
|
+
|
218
|
+
def get_current_status
|
219
|
+
self.class.get_current_status :keyword_id => @args[:keyword_id]
|
220
|
+
end
|
221
|
+
|
222
|
+
def update args = {}
|
223
|
+
@args.merge!(args)
|
224
|
+
save
|
225
|
+
end
|
226
|
+
|
227
|
+
def save
|
228
|
+
@args[:adgroup_id] = @adgroup.args[:adgroup_id] if !@args[:adgroup_id] && @adgroup.args[:adgroup_id]
|
229
|
+
|
109
230
|
if @args[:keyword_id] #do update
|
110
|
-
|
231
|
+
#get current status of campaign
|
232
|
+
before_status = get_current_status
|
233
|
+
|
234
|
+
#restore campaign before update
|
235
|
+
restore if before_status == :stopped
|
236
|
+
|
237
|
+
begin
|
238
|
+
update_object
|
239
|
+
|
240
|
+
rescue Exception => e
|
241
|
+
log_error e.message
|
242
|
+
end
|
243
|
+
|
244
|
+
#remove it if new status is stopped or status doesn't changed and before it was stopped
|
245
|
+
remove if (@args[:status] == :stopped) || (@args[:status].nil? && before_status == :stopped)
|
111
246
|
else #do save
|
112
|
-
#create
|
113
|
-
|
247
|
+
#create keyword
|
248
|
+
begin
|
249
|
+
create
|
250
|
+
|
251
|
+
rescue Exception => e
|
252
|
+
log_error e.message
|
253
|
+
|
254
|
+
return false
|
255
|
+
end
|
256
|
+
|
257
|
+
#remove it if new status is stopped
|
258
|
+
remove if @args[:status] && @args[:status].to_s.to_sym == :stopped
|
114
259
|
end
|
115
|
-
|
260
|
+
|
261
|
+
!errors.any?
|
262
|
+
end
|
263
|
+
|
264
|
+
def log_error message
|
265
|
+
puts message
|
266
|
+
@adgroup.log_error "Keyword: #{@args[:keyword]} -> #{message}" if @adgroup
|
267
|
+
errors << message
|
268
|
+
end
|
269
|
+
|
116
270
|
end
|
117
271
|
end
|
118
|
-
|
272
|
+
|
data/lib/sklik-api/client.rb
CHANGED
@@ -4,15 +4,15 @@ class SklikApi
|
|
4
4
|
|
5
5
|
NAME = "client"
|
6
6
|
|
7
|
-
include
|
8
|
-
|
7
|
+
include SklikObject
|
8
|
+
|
9
9
|
def initialize args = {}
|
10
10
|
super args
|
11
11
|
end
|
12
|
-
|
12
|
+
|
13
13
|
def self.find args = {}
|
14
14
|
out = connection.call("client.getAttributes") { |param|
|
15
|
-
([param[:user]]|param[:foreignAccounts]).collect{|u|
|
15
|
+
([param[:user]]|param[:foreignAccounts]).collect{|u|
|
16
16
|
u.symbolize_keys!
|
17
17
|
SklikApi::Client.new(
|
18
18
|
:customer_id => u[:userId],
|
data/lib/sklik-api/connection.rb
CHANGED
@@ -1,21 +1,21 @@
|
|
1
1
|
# -*- encoding : utf-8 -*-
|
2
2
|
class SklikApi
|
3
3
|
class Connection
|
4
|
-
|
4
|
+
|
5
5
|
MAX_RETRIES = 3
|
6
6
|
DEFAULTS = {
|
7
7
|
:debug => false,
|
8
8
|
:timeout => 100
|
9
9
|
}
|
10
|
-
|
10
|
+
|
11
11
|
def initialize args = {}
|
12
12
|
@args = DEFAULTS.merge(args)
|
13
13
|
end
|
14
|
-
|
14
|
+
|
15
15
|
def self.connection
|
16
16
|
@connection ||= SklikApi::Connection.new(:debug => false)
|
17
17
|
end
|
18
|
-
|
18
|
+
|
19
19
|
#prepare connection to sklik
|
20
20
|
def connection
|
21
21
|
path = (ENV['RACK_ENV'] || ENV['RAILS']) == "test" ? "/sandbox/RPC2" : "/RPC2"
|
@@ -24,11 +24,11 @@ class SklikApi
|
|
24
24
|
#fix of UTF-8 encoding
|
25
25
|
server.extend(XMLRPCWorkAround)
|
26
26
|
#debug mode to see what XMLRPC is doing
|
27
|
-
server.set_debug(File.open("log/xmlrpc-#{Time.now.strftime("%Y_%m_%d-%H_%M_%S")}.log","a:UTF-8")) if @args[:debug]
|
28
|
-
|
27
|
+
server.set_debug(File.open("log/xmlrpc-#{Time.now.strftime("%Y_%m_%d-%H_%M_%S")}.log","a:UTF-8")) if @args[:debug]
|
28
|
+
|
29
29
|
server
|
30
30
|
end
|
31
|
-
|
31
|
+
|
32
32
|
#Get session is method for login into sklik
|
33
33
|
#save session for other requests until it expires
|
34
34
|
#every taxonomy has its own session!
|
@@ -38,7 +38,10 @@ class SklikApi
|
|
38
38
|
@session[SklikApi::Access.uniq_identifier]
|
39
39
|
else
|
40
40
|
begin
|
41
|
+
SklikApi.log(:debug, "Getting session for #{SklikApi::Access.email}")
|
41
42
|
param = connection.call("client.login", SklikApi::Access.email, SklikApi::Access.password).symbolize_keys
|
43
|
+
SklikApi.log(:debug, "Session received: #{param.inspect}")
|
44
|
+
|
42
45
|
if param[:status] == 401
|
43
46
|
raise ArgumentError, "Invalid login for: #{SklikApi::Access.email}"
|
44
47
|
elsif param[:status] == 200
|
@@ -53,32 +56,52 @@ class SklikApi
|
|
53
56
|
end
|
54
57
|
end
|
55
58
|
end
|
56
|
-
|
59
|
+
|
57
60
|
# method to wrap method call to sklik -> allow retry and problem with session expiration
|
58
61
|
def call method, *args
|
62
|
+
|
63
|
+
SklikApi.log(:debug, "Calling api: #{method} [#{args}]") unless method == "client.login"
|
59
64
|
retry_count = MAX_RETRIES
|
60
|
-
begin
|
65
|
+
begin
|
61
66
|
#get response from sklik
|
62
67
|
param = connection.call( method, get_session, *args ).symbolize_keys
|
63
|
-
|
68
|
+
SklikApi.log(:debug, "Response from api: #{param.inspect}") unless method == "client.login"
|
69
|
+
if [200].include?(param[:status])
|
64
70
|
return yield(param)
|
71
|
+
elsif param[:status] == 400
|
72
|
+
raise SklikApi::InvalidArguments, "Calling method: #{method} with invalid arguments: #{args}, #{param.inspect}"
|
73
|
+
elsif param[:status] == 404
|
74
|
+
raise SklikApi::NotFound, "Calling method: #{method} with params: #{args} was not found"
|
65
75
|
elsif param[:status] == 406
|
66
|
-
raise
|
76
|
+
raise SklikApi::InvalidData, print_errors(param[:errors])
|
67
77
|
elsif param[:statusMessage] == "Session has expired or is malformed."
|
68
78
|
raise ArgumentError, "session has expired"
|
69
79
|
else
|
70
|
-
raise ArgumentError, "There is error from sklik #{method}: #{param
|
80
|
+
raise ArgumentError, "There is error from sklik #{method}: #{param.inspect}: #{args.inspect}"
|
71
81
|
end
|
72
82
|
rescue Exception => e
|
83
|
+
#when know exception which is not fault of sklik don't retry!
|
84
|
+
raise e if e.class.name =~ /SklikApi::/
|
85
|
+
|
73
86
|
retry_count -= 1
|
74
87
|
pp "Rescuing from request by: #{e.class} - #{e.message}"
|
75
88
|
#if session expired then get new one! and retry
|
76
89
|
get_session(true) if e.message == "session has expired"
|
77
90
|
#don't retry if there is problem with Invalid paramaters od Data
|
78
|
-
retry_count = 0 if e.message.include?("Invalid")
|
91
|
+
retry_count = 0 if e.message.include?("Invalid")
|
79
92
|
retry if retry_count > 0
|
80
93
|
raise e
|
81
94
|
end
|
82
95
|
end
|
96
|
+
|
97
|
+
def print_errors error_hash
|
98
|
+
error_hash.collect do |one_error|
|
99
|
+
out = "#{one_error.delete("id").humanize} ("
|
100
|
+
out += one_error.to_a.collect do |key, value|
|
101
|
+
"#{key} = #{value}"
|
102
|
+
end.join(", ")
|
103
|
+
out + ")"
|
104
|
+
end.join("; ")
|
105
|
+
end
|
83
106
|
end
|
84
107
|
end
|