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.
@@ -4,7 +4,7 @@ class SklikApi
4
4
 
5
5
  NAME = "group"
6
6
 
7
- include Object
7
+ include SklikObject
8
8
  =begin
9
9
  Example of input hash
10
10
  {
@@ -30,47 +30,121 @@ Example of input hash
30
30
 
31
31
  =end
32
32
 
33
- def initialize campaign, args
33
+ def initialize args, deprecated_args = {}
34
+
35
+ #deprecated way to set up new adgroup!
36
+ if args.is_a?(SklikApi::Campaign)
37
+ puts "DEPRECATION WARNING: Please update your code for SklikApi::Adgroup.new(campaign, args) to SklikApi::Adgroup.new(args = {}) possible to add parent camapign by adding :campaign => your campaign"
38
+ #set adgroup owner campaign
39
+ @campaign = args
40
+ args = deprecated_args
41
+
42
+ #new way to set adgroups!
43
+ else
44
+ #set adgroup owner campaign
45
+ #if in input args there is pointer to parent campaign!
46
+ if @campaign = args.delete(:campaign)
47
+ # if no cpc was given - try to use campaign cpc
48
+ if !args[:cpc] && @campaign.args[:cpc]
49
+ args[:cpc] = @campaign.args[:cpc]
50
+ end
51
+ end
52
+ end
53
+ @args = args
54
+
34
55
  @adgroup_data = nil
35
- #set adgroup owner campaign
36
- @campaign = campaign
37
56
 
38
57
  #initialize adgroups
39
58
  @adtexts = []
40
59
  if args[:ads] && args[:ads].size > 0
41
60
  args[:ads].each do |adtext|
42
- @adtexts << SklikApi::Adtext.new(self, adtext)
61
+ @adtexts << SklikApi::Adtext.new(adtext.merge(:adgroup => self))
43
62
  end
44
63
  end
64
+
45
65
  #initialize adgroups
46
66
  @keywords = []
47
67
  if args[:keywords] && args[:keywords].size > 0
48
68
  args[:keywords].each do |keyword|
49
- @keywords << SklikApi::Keyword.new(self, :keyword => keyword)
69
+ if keyword.is_a?(Hash)
70
+ @keywords << SklikApi::Keyword.new(keyword.merge(:adgroup => self))
71
+ else
72
+ @keywords << SklikApi::Keyword.new(:keyword => keyword, :adgroup => self)
73
+ end
50
74
  end
51
75
  end
52
76
 
53
77
  super args
54
78
  end
55
79
 
56
- def self.find campaign, args = {}
80
+ def self.get id
81
+ if adgroup = super(NAME, id)
82
+ SklikApi::Adgroup.new(
83
+ process_sklik_data adgroup
84
+ )
85
+ else
86
+ nil
87
+ end
88
+ end
89
+ #
90
+ # Find adgroups in campaign!
91
+ # !Deprecated! by campaign and args
92
+ #
93
+ def self.find args, deprecated_args = {}
57
94
  out = []
58
- super(NAME, campaign.args[:campaign_id]).each do |adgroup|
59
- if args[:adgroup_id].nil? || (args[:adgroup_id] && args[:adgroup_id].to_i == adgroup[:id].to_i)
60
- out << SklikApi::Adgroup.new( campaign,
61
- :adgroup_id => adgroup[:id],
62
- :cpc => adgroup[:cpc].to_f/100.0,
63
- :name => adgroup[:name],
64
- :status => fix_status(adgroup)
95
+ #asking fo adgroup by ID
96
+ if args.is_a?(Integer)
97
+ return get args
98
+
99
+ #asking for adgroup deprecated way!
100
+ elsif args.is_a?(SklikApi::Campaign)
101
+ puts "DEPRECATION WARNING: Please update your code for SklikApi::Adgroup.find(campaign, args) to SklikApi::Adgroup.find(campaign_id: 1234) possible to add parent camapign by adding :campaign => your campaign"
102
+ campaign_id = args.args[:campaign_id]
103
+ args = deprecated_args
104
+
105
+ #asking for adgroup by hash with adgroup_id
106
+ elsif args.is_a?(Hash) && args[:adgroup_id]
107
+ if adgroup = get(args[:adgroup_id])
108
+ return [adgroup]
109
+ else
110
+ return []
111
+ end
112
+
113
+ #asking for adgroup by hash
114
+ else
115
+ campaign_id = args[:campaign_id]
116
+ end
117
+
118
+ raise ArgumentError, "Please provide campaign_id in params" unless campaign_id
119
+
120
+ super(NAME, campaign_id).each do |adgroup|
121
+
122
+ if (args[:status].nil? || (args[:status] == fix_status(adgroup))) && # find by status
123
+ (args[:name].nil? || (args[:name] == adgroup[:name]))
124
+
125
+ out << SklikApi::Adgroup.new(
126
+ process_sklik_data adgroup
65
127
  )
66
128
  end
67
129
  end
68
130
  out
69
131
  end
70
132
 
133
+ def self.process_sklik_data adgroup = {}
134
+ {
135
+ :adgroup_id => adgroup[:id],
136
+ :cpc => adgroup[:cpc].to_f/100.0,
137
+ :name => adgroup[:name],
138
+ :status => fix_status(adgroup),
139
+ :campaign_id => adgroup[:campaignId],
140
+ }
141
+ end
142
+
71
143
  def self.fix_status adgroup
72
144
  if adgroup[:removed] == true
73
145
  return :stopped
146
+ elsif adgroup[:status] == "suspend"
147
+ return :paused
74
148
  else
75
149
  return :running
76
150
  end
@@ -78,7 +152,7 @@ Example of input hash
78
152
 
79
153
  def keywords_stats from, to
80
154
  output = []
81
- keywords = Keyword.find(self)
155
+ keywords = Keyword.find(adgroup_id: self.args[:adgroup_id])
82
156
  keywords.in_groups_of(100, false).each do |keywords_group|
83
157
  out = connection.call("keywords.stats", keywords_group.collect{|k| k.args[:keyword_id]}, from, to ) { |param|
84
158
  param[:keywordStats]
@@ -100,45 +174,80 @@ Example of input hash
100
174
  @adgroup_data
101
175
  else
102
176
  @adgroup_data = @args
103
- if @args[:status] != :stopped
104
- @adgroup_data[:ads] = Adtext.find(self).collect{|a| a.to_hash}
105
- @adgroup_data[:keywords] = Keyword.find(self).collect{|k| k.to_hash}
106
- else
107
- @adgroup_data[:ads] = []
108
- @adgroup_data[:keywords] = []
109
- end
177
+ @adgroup_data[:ads] = self.adtexts.collect{|a| a.to_hash}
178
+ @adgroup_data[:keywords] = self.keywords.collect{|k| k.to_hash}
110
179
  @adgroup_data
111
180
  end
112
181
  end
113
182
 
114
183
 
115
184
  def create_args
116
- raise ArgumentError, "Adgroup need's to know campaign_id" unless @campaign.args[:campaign_id]
117
- raise ArgumentError, "Adgroup need's to know campaigns CPC" unless @campaign.args[:cpc]
185
+ raise ArgumentError, "Adgroup need's to know campaign_id" unless args[:campaign_id]
186
+ raise ArgumentError, "Adgroup need's to know campaigns CPC" unless args[:cpc]
118
187
 
119
188
  out = []
120
189
  #add campaign id to know where to create adgroup
121
- out << @campaign.args[:campaign_id]
190
+ out << @args[:campaign_id] || @campaign.args[:campaign_id]
122
191
 
123
192
  #add adgroup struct
124
- args = {}
125
- args[:name] = @args[:name]
126
- args[:cpc] = (@campaign.args[:cpc] * 100).to_i if @campaign.args[:cpc]
127
- out << args
193
+ c_args = {}
194
+ c_args[:name] = @args[:name]
195
+ if @args[:cpc]
196
+ c_args[:cpc] = (@args[:cpc] * 100).to_i
197
+ elsif @campaign && @campaign.args[:cpc]
198
+ c_args[:cpc] = (@campaign.args[:cpc] * 100).to_i
199
+ else
200
+ raise ArgumentError, "Please provide adgroup or parent campaign with :cpc parameter in CZK"
201
+ end
202
+ c_args[:status] = status_for_update if status_for_update
203
+ out << c_args
128
204
 
129
205
  #return output
130
206
  out
131
207
  end
132
208
 
209
+ def update_args
210
+ out = []
211
+
212
+ #add campaign id on which will be performed update
213
+ out << @args[:adgroup_id]
214
+
215
+ #prepare campaign struct
216
+ u_args = {}
217
+ u_args[:name] = @args[:name] if @args[:name]
218
+ u_args[:status] = status_for_update if status_for_update
219
+ if @args[:cpc]
220
+ u_args[:cpc] = (@args[:cpc] * 100).to_i
221
+ elsif @campaign && @campaign.args[:cpc]
222
+ u_args[:cpc] = (@campaign.args[:cpc] * 100).to_i
223
+ end
224
+ out << u_args
225
+
226
+ out
227
+ end
228
+
133
229
  def adtexts
134
- Adtext.find(self)
230
+ if @args[:adgroup_id] && get_current_status == :stopped
231
+ SklikApi.log :error, "Adgroup: #{@args[:adgroup_id]} - Can't get adtexts for stopped Adgroup!"
232
+ []
233
+ else
234
+ Adtext.find(adgroup_id: self.args[:adgroup_id])
235
+ end
135
236
  end
136
237
 
137
238
  def keywords
138
- Keyword.find(self)
239
+ if @args[:adgroup_id] && get_current_status == :stopped
240
+ SklikApi.log :error, "Adgroup: #{@args[:adgroup_id]} - Can't get keywords for stopped Adgroup!"
241
+ []
242
+ else
243
+ Keyword.find(adgroup_id: self.args[:adgroup_id])
244
+ end
139
245
  end
140
246
 
141
247
  def update args = {}
248
+
249
+ @args.merge!(args)
250
+
142
251
  if args.is_a?(SklikApi::Adgroup)
143
252
  #get data from another adgroup
144
253
  @adtexts = args.instance_variable_get("@adtexts")
@@ -152,7 +261,7 @@ Example of input hash
152
261
  @adtexts = []
153
262
  if args[:ads] && args[:ads].size > 0
154
263
  args[:ads].each do |adtext|
155
- @adtexts << SklikApi::Adtext.new(self, adtext)
264
+ @adtexts << SklikApi::Adtext.new(adtext.merge(:adgroup => self))
156
265
  end
157
266
  end
158
267
 
@@ -160,7 +269,7 @@ Example of input hash
160
269
  @keywords = []
161
270
  if args[:keywords] && args[:keywords].size > 0
162
271
  args[:keywords].each do |keyword|
163
- @keywords << SklikApi::Keyword.new(self, :keyword => keyword)
272
+ @keywords << SklikApi::Keyword.new(:keyword => keyword, :adgroup => self)
164
273
  end
165
274
  end
166
275
  end
@@ -168,83 +277,124 @@ Example of input hash
168
277
  save
169
278
  end
170
279
 
280
+ def valid?
281
+ clear_errors
282
+ log_error "name is required" unless args[:name] && args[:name].size > 0
283
+ log_error "cpc is required and must be higher than 0 CZK" unless !@args[:adgroup_id] && args[:cpc] && args[:cpc] > 0
284
+ log_error "campaign_id is required" unless args[:campaign_id] || (@campaign && @campaign.args[:campaign_id])
285
+ !errors.any?
286
+ end
287
+
288
+
289
+ def self.get_current_status args = {}
290
+ raise ArgumentError, "Adgroup_id is required" unless args[:adgroup_id]
291
+ if adgroup = self.get(args[:adgroup_id])
292
+ adgroup.args[:status]
293
+ else
294
+ raise ArgumentError, "Adgroup by #{args.inspect} couldn't be found!"
295
+ end
296
+ end
297
+
298
+ def get_current_status
299
+ self.class.get_current_status :adgroup_id => @args[:adgroup_id], :customer_id => @customer_id
300
+ end
301
+
171
302
  def save
172
- if @args[:adgroup_id] #do update
303
+ clear_errors
304
+ @args[:campaign_id] = @campaign.args[:campaign_id] if !@args[:campaign_id] && @campaign.args[:campaign_id]
173
305
 
174
- ############
175
- ## KEYWORDS
176
- ############
306
+ if @args[:adgroup_id] #do update
177
307
 
178
- #update keywords
179
- keywords_error = []
180
- @new_keywords = @keywords.clone
181
- delete_first = true
182
- while @new_keywords && @new_keywords.size > 0 do
183
- begin
184
- connection.call('keywords.set', @args[:adgroup_id], @new_keywords[0..199].collect{|k| k.create_args.last }, delete_first) do |params|
185
- @campaign.errors << params[:statusMessage] if params[:statusMessage] != "OK"
308
+ #get current status of campaign
309
+ before_status = get_current_status
310
+
311
+ #restore campaign before update
312
+ restore if before_status == :stopped
313
+
314
+ #rescue from any error to ensure remove will be done when something went wrong
315
+ error = nil
316
+
317
+ begin
318
+ #update adgroup
319
+ update_object
320
+
321
+ ############
322
+ ## KEYWORDS
323
+ ############
324
+
325
+ #update keywords
326
+ keywords_error = []
327
+ @new_keywords = @keywords.clone
328
+ delete_first = true
329
+ while @new_keywords && @new_keywords.size > 0 do
330
+ begin
331
+ connection.call('keywords.set', @args[:adgroup_id], @new_keywords[0..199].collect{|k| k.create_args.last }, delete_first) do |params|
332
+ log_error params[:statusMessage] if params[:statusMessage] != "OK"
333
+ end
334
+ rescue Exception => e
335
+ log_error e.message
186
336
  end
187
- rescue Exception => e
188
- @campaign.errors << e.message
337
+ @new_keywords = @new_keywords[200..-1]
338
+ delete_first = false
189
339
  end
190
- @new_keywords = @new_keywords[200..-1]
191
- delete_first = false
192
- end
193
340
 
194
- ############
195
- ## ADTEXTS
196
- ############
341
+ ############
342
+ ## ADTEXTS
343
+ ############
197
344
 
198
- #create new adtexts and delete old
199
- @saved_adtexts = adtexts.inject({}){|o,a| o[a.uniq_identifier] = a ; o}
200
- @new_adtexts = @adtexts.inject({}){|o,a| o[a.uniq_identifier] = a ; o}
345
+ #create new adtexts and delete old
346
+ @saved_adtexts = adtexts.inject({}){|o,a| o[a.uniq_identifier] = a ; o}
347
+ @new_adtexts = @adtexts.inject({}){|o,a| o[a.uniq_identifier] = a ; o}
201
348
 
202
- #adtexts to be deleted
203
- (@saved_adtexts.keys - @new_adtexts.keys).each do |k|
204
- puts "deleting adtext #{@saved_adtexts[k]} in #{@args[:name]}"
205
- #don't try to remove already removed adtext
206
- @saved_adtexts[k].remove unless @saved_adtexts[k].args[:status] == :stopped
207
- end
349
+ #adtexts to be deleted
350
+ (@saved_adtexts.keys - @new_adtexts.keys).each do |k|
351
+ puts "deleting adtext #{@saved_adtexts[k]} in #{@args[:name]}"
352
+ #don't try to remove already removed adtext
353
+ @saved_adtexts[k].remove unless @saved_adtexts[k].args[:status] == :stopped
354
+ end
208
355
 
209
- #adtexts to be created
210
- (@new_adtexts.keys - @saved_adtexts.keys).each do |k|
211
- puts "creating new adtext #{k} in #{@args[:name]}"
212
- begin
213
- @new_adtexts[k].save
214
- rescue Exception => e
215
- #take care about error message -> do it nicer
216
- if /There is error from sklik ad.create: Invalid parameters/ =~ e.message
217
- @campaign.errors << "Problem with creating #{@new_adtexts[k].args} in adgroup #{@args[:name]}"
218
- else
219
- @campaign.errors << e.message
356
+ #adtexts to be created
357
+ (@new_adtexts.keys - @saved_adtexts.keys).each do |k|
358
+ puts "creating new adtext #{k} in #{@args[:name]}"
359
+ begin
360
+ @new_adtexts[k].save
361
+ rescue Exception => e
362
+ #take care about error message -> do it nicer
363
+ if /There is error from sklik ad.create: Invalid parameters/ =~ e.message
364
+ log_error "Problem with creating #{@new_adtexts[k].args} in adgroup #{@args[:name]}"
365
+ else
366
+ log_error e.message
367
+ end
220
368
  end
221
369
  end
222
- end
223
370
 
224
- #check status to be running
225
- (@new_adtexts.keys & @saved_adtexts.keys).each do |k|
226
- @saved_adtexts[k].restore if @saved_adtexts[k].args[:status] == :stopped
371
+ #check status to be running
372
+ (@new_adtexts.keys & @saved_adtexts.keys).each do |k|
373
+ @saved_adtexts[k].restore if @saved_adtexts[k].args[:status] == :stopped
374
+ end
375
+
376
+ rescue Exception => e
377
+ log_error e.message
227
378
  end
228
379
 
380
+ #remove it if new status is stopped or status doesn't changed and before it was stopped
381
+ remove if (@args[:status] == :stopped) || (@args[:status].nil? && before_status == :stopped)
229
382
 
230
- else #do save
231
- #create adgroup
232
- create
383
+ else #do create
233
384
 
234
- #create adtexts
235
- @adtexts.each do |adtext|
236
- begin
237
- adtext.save
238
- rescue Exception => e
239
- #take care about error message -> do it nicer
240
- if /There is error from sklik ad.create: Invalid parameters/ =~ e.message
241
- @campaign.errors << "Problem with creating #{adtext.args} in adgroup #{@args[:name]}"
242
- else
243
- @campaign.errors << e.message
244
- end
245
- end
385
+ begin
386
+ #create adgroup
387
+ create
388
+ rescue Exception => e
389
+ log_error e.message
390
+ #don't continue with creating campaign!
391
+ return false
246
392
  end
247
393
 
394
+ #create adtexts
395
+ unless @adtexts.all?{|adtext| adtext.save }
396
+ return rollback!
397
+ end
248
398
 
249
399
  #create keywords
250
400
  keywords_error = []
@@ -253,22 +403,49 @@ Example of input hash
253
403
  while @new_keywords && @new_keywords.size > 0 do
254
404
  begin
255
405
  connection.call('keywords.set', @args[:adgroup_id], @new_keywords[0..199].collect{|k| k.create_args.last }, delete_first) do |params|
256
- @campaign.errors << params[:statusMessage] if params[:statusMessage] != "OK"
406
+ keywords_error << params[:statusMessage] if params[:statusMessage] != "OK"
257
407
  end
258
408
  rescue Exception => e
259
- @campaign.errors << e.message
409
+ keywords_error << e.message
260
410
  end
261
411
  @new_keywords = @new_keywords[200..-1]
262
412
  delete_first = false
263
413
  end
264
414
 
265
415
  if keywords_error.size > 0
266
- @campaign.errors << "Problem with creating keywords: #{keywords_error.join(", ")} in adgroup #{@args[:name]}"
416
+ log_error "Problem with creating keywords: #{keywords_error.join(", ")}"
417
+ return rollback!
267
418
  end
268
419
 
420
+ #remove campaign when it was started with stopped status!
421
+ remove if @args[:status] && @args[:status].to_s.to_sym == :stopped
422
+
269
423
  end
424
+ !errors.any?
425
+ end
426
+
427
+ def log_error message
428
+ @campaign.log_error "Adgroup: #{@args[:name]} -> #{message}" if @campaign
429
+ errors << message
270
430
  end
271
431
 
432
+ def rollback!
433
+ #don't rollback if it is disabled!
434
+ return false unless SklikApi.use_rollback?
435
+
436
+ #remember errors!
437
+ old_errors = errors
438
+
439
+ SklikApi.log :info, "Adgroup: #{@args[:adgroup_id]} - ROLLBACK!"
440
+ update :name => "#{@args[:name]} FAILED ON CREATION - #{Time.now.strftime("%Y.%m.%d %H:%M:%S")}"
441
+ #remove adgroup
442
+ remove
443
+
444
+ #return remembered errors!
445
+ @errors = old_errors
446
+ #don't continue with creating adgroup!
447
+ return false
448
+ end
272
449
  end
273
450
  end
274
451