lib/sklik-api/campaign_parts/adgroup.rb in sklik-api-0.0.16 vs lib/sklik-api/campaign_parts/adgroup.rb in sklik-api-0.1.0
- old
+ new
@@ -2,11 +2,11 @@
class SklikApi
class Adgroup
NAME = "group"
- include Object
+ include SklikObject
=begin
Example of input hash
{
:adgroup_id => 1234, #(OPTIONAL) -> when setted it will on save do update of existing adgroup
:name => "my adgroup name",
@@ -28,59 +28,133 @@
}
=end
- def initialize campaign, args
+ def initialize args, deprecated_args = {}
+
+ #deprecated way to set up new adgroup!
+ if args.is_a?(SklikApi::Campaign)
+ 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"
+ #set adgroup owner campaign
+ @campaign = args
+ args = deprecated_args
+
+ #new way to set adgroups!
+ else
+ #set adgroup owner campaign
+ #if in input args there is pointer to parent campaign!
+ if @campaign = args.delete(:campaign)
+ # if no cpc was given - try to use campaign cpc
+ if !args[:cpc] && @campaign.args[:cpc]
+ args[:cpc] = @campaign.args[:cpc]
+ end
+ end
+ end
+ @args = args
+
@adgroup_data = nil
- #set adgroup owner campaign
- @campaign = campaign
#initialize adgroups
@adtexts = []
if args[:ads] && args[:ads].size > 0
args[:ads].each do |adtext|
- @adtexts << SklikApi::Adtext.new(self, adtext)
+ @adtexts << SklikApi::Adtext.new(adtext.merge(:adgroup => self))
end
end
+
#initialize adgroups
@keywords = []
if args[:keywords] && args[:keywords].size > 0
args[:keywords].each do |keyword|
- @keywords << SklikApi::Keyword.new(self, :keyword => keyword)
+ if keyword.is_a?(Hash)
+ @keywords << SklikApi::Keyword.new(keyword.merge(:adgroup => self))
+ else
+ @keywords << SklikApi::Keyword.new(:keyword => keyword, :adgroup => self)
+ end
end
end
super args
end
- def self.find campaign, args = {}
+ def self.get id
+ if adgroup = super(NAME, id)
+ SklikApi::Adgroup.new(
+ process_sklik_data adgroup
+ )
+ else
+ nil
+ end
+ end
+ #
+ # Find adgroups in campaign!
+ # !Deprecated! by campaign and args
+ #
+ def self.find args, deprecated_args = {}
out = []
- super(NAME, campaign.args[:campaign_id]).each do |adgroup|
- if args[:adgroup_id].nil? || (args[:adgroup_id] && args[:adgroup_id].to_i == adgroup[:id].to_i)
- out << SklikApi::Adgroup.new( campaign,
- :adgroup_id => adgroup[:id],
- :cpc => adgroup[:cpc].to_f/100.0,
- :name => adgroup[:name],
- :status => fix_status(adgroup)
+ #asking fo adgroup by ID
+ if args.is_a?(Integer)
+ return get args
+
+ #asking for adgroup deprecated way!
+ elsif args.is_a?(SklikApi::Campaign)
+ 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"
+ campaign_id = args.args[:campaign_id]
+ args = deprecated_args
+
+ #asking for adgroup by hash with adgroup_id
+ elsif args.is_a?(Hash) && args[:adgroup_id]
+ if adgroup = get(args[:adgroup_id])
+ return [adgroup]
+ else
+ return []
+ end
+
+ #asking for adgroup by hash
+ else
+ campaign_id = args[:campaign_id]
+ end
+
+ raise ArgumentError, "Please provide campaign_id in params" unless campaign_id
+
+ super(NAME, campaign_id).each do |adgroup|
+
+ if (args[:status].nil? || (args[:status] == fix_status(adgroup))) && # find by status
+ (args[:name].nil? || (args[:name] == adgroup[:name]))
+
+ out << SklikApi::Adgroup.new(
+ process_sklik_data adgroup
)
end
end
out
end
+ def self.process_sklik_data adgroup = {}
+ {
+ :adgroup_id => adgroup[:id],
+ :cpc => adgroup[:cpc].to_f/100.0,
+ :name => adgroup[:name],
+ :status => fix_status(adgroup),
+ :campaign_id => adgroup[:campaignId],
+ }
+ end
+
def self.fix_status adgroup
if adgroup[:removed] == true
return :stopped
+ elsif adgroup[:status] == "suspend"
+ return :paused
else
return :running
end
end
def keywords_stats from, to
output = []
- keywords = Keyword.find(self)
+ keywords = Keyword.find(adgroup_id: self.args[:adgroup_id])
keywords.in_groups_of(100, false).each do |keywords_group|
out = connection.call("keywords.stats", keywords_group.collect{|k| k.args[:keyword_id]}, from, to ) { |param|
param[:keywordStats]
}
out.each do |kw_stats|
@@ -98,49 +172,84 @@
def to_hash
if @adgroup_data
@adgroup_data
else
@adgroup_data = @args
- if @args[:status] != :stopped
- @adgroup_data[:ads] = Adtext.find(self).collect{|a| a.to_hash}
- @adgroup_data[:keywords] = Keyword.find(self).collect{|k| k.to_hash}
- else
- @adgroup_data[:ads] = []
- @adgroup_data[:keywords] = []
- end
+ @adgroup_data[:ads] = self.adtexts.collect{|a| a.to_hash}
+ @adgroup_data[:keywords] = self.keywords.collect{|k| k.to_hash}
@adgroup_data
end
end
def create_args
- raise ArgumentError, "Adgroup need's to know campaign_id" unless @campaign.args[:campaign_id]
- raise ArgumentError, "Adgroup need's to know campaigns CPC" unless @campaign.args[:cpc]
+ raise ArgumentError, "Adgroup need's to know campaign_id" unless args[:campaign_id]
+ raise ArgumentError, "Adgroup need's to know campaigns CPC" unless args[:cpc]
out = []
#add campaign id to know where to create adgroup
- out << @campaign.args[:campaign_id]
+ out << @args[:campaign_id] || @campaign.args[:campaign_id]
#add adgroup struct
- args = {}
- args[:name] = @args[:name]
- args[:cpc] = (@campaign.args[:cpc] * 100).to_i if @campaign.args[:cpc]
- out << args
+ c_args = {}
+ c_args[:name] = @args[:name]
+ if @args[:cpc]
+ c_args[:cpc] = (@args[:cpc] * 100).to_i
+ elsif @campaign && @campaign.args[:cpc]
+ c_args[:cpc] = (@campaign.args[:cpc] * 100).to_i
+ else
+ raise ArgumentError, "Please provide adgroup or parent campaign with :cpc parameter in CZK"
+ end
+ c_args[:status] = status_for_update if status_for_update
+ out << c_args
#return output
out
end
+ def update_args
+ out = []
+
+ #add campaign id on which will be performed update
+ out << @args[:adgroup_id]
+
+ #prepare campaign struct
+ u_args = {}
+ u_args[:name] = @args[:name] if @args[:name]
+ u_args[:status] = status_for_update if status_for_update
+ if @args[:cpc]
+ u_args[:cpc] = (@args[:cpc] * 100).to_i
+ elsif @campaign && @campaign.args[:cpc]
+ u_args[:cpc] = (@campaign.args[:cpc] * 100).to_i
+ end
+ out << u_args
+
+ out
+ end
+
def adtexts
- Adtext.find(self)
+ if @args[:adgroup_id] && get_current_status == :stopped
+ SklikApi.log :error, "Adgroup: #{@args[:adgroup_id]} - Can't get adtexts for stopped Adgroup!"
+ []
+ else
+ Adtext.find(adgroup_id: self.args[:adgroup_id])
+ end
end
def keywords
- Keyword.find(self)
+ if @args[:adgroup_id] && get_current_status == :stopped
+ SklikApi.log :error, "Adgroup: #{@args[:adgroup_id]} - Can't get keywords for stopped Adgroup!"
+ []
+ else
+ Keyword.find(adgroup_id: self.args[:adgroup_id])
+ end
end
def update args = {}
+
+ @args.merge!(args)
+
if args.is_a?(SklikApi::Adgroup)
#get data from another adgroup
@adtexts = args.instance_variable_get("@adtexts")
@keywords = args.instance_variable_get("@keywords")
@@ -150,125 +259,193 @@
else
#initialize new adtexts
@adtexts = []
if args[:ads] && args[:ads].size > 0
args[:ads].each do |adtext|
- @adtexts << SklikApi::Adtext.new(self, adtext)
+ @adtexts << SklikApi::Adtext.new(adtext.merge(:adgroup => self))
end
end
#initialize new keywords
@keywords = []
if args[:keywords] && args[:keywords].size > 0
args[:keywords].each do |keyword|
- @keywords << SklikApi::Keyword.new(self, :keyword => keyword)
+ @keywords << SklikApi::Keyword.new(:keyword => keyword, :adgroup => self)
end
end
end
save
end
+ def valid?
+ clear_errors
+ log_error "name is required" unless args[:name] && args[:name].size > 0
+ log_error "cpc is required and must be higher than 0 CZK" unless !@args[:adgroup_id] && args[:cpc] && args[:cpc] > 0
+ log_error "campaign_id is required" unless args[:campaign_id] || (@campaign && @campaign.args[:campaign_id])
+ !errors.any?
+ end
+
+
+ def self.get_current_status args = {}
+ raise ArgumentError, "Adgroup_id is required" unless args[:adgroup_id]
+ if adgroup = self.get(args[:adgroup_id])
+ adgroup.args[:status]
+ else
+ raise ArgumentError, "Adgroup by #{args.inspect} couldn't be found!"
+ end
+ end
+
+ def get_current_status
+ self.class.get_current_status :adgroup_id => @args[:adgroup_id], :customer_id => @customer_id
+ end
+
def save
+ clear_errors
+ @args[:campaign_id] = @campaign.args[:campaign_id] if !@args[:campaign_id] && @campaign.args[:campaign_id]
+
if @args[:adgroup_id] #do update
- ############
- ## KEYWORDS
- ############
+ #get current status of campaign
+ before_status = get_current_status
- #update keywords
- keywords_error = []
- @new_keywords = @keywords.clone
- delete_first = true
- while @new_keywords && @new_keywords.size > 0 do
- begin
- connection.call('keywords.set', @args[:adgroup_id], @new_keywords[0..199].collect{|k| k.create_args.last }, delete_first) do |params|
- @campaign.errors << params[:statusMessage] if params[:statusMessage] != "OK"
+ #restore campaign before update
+ restore if before_status == :stopped
+
+ #rescue from any error to ensure remove will be done when something went wrong
+ error = nil
+
+ begin
+ #update adgroup
+ update_object
+
+ ############
+ ## KEYWORDS
+ ############
+
+ #update keywords
+ keywords_error = []
+ @new_keywords = @keywords.clone
+ delete_first = true
+ while @new_keywords && @new_keywords.size > 0 do
+ begin
+ connection.call('keywords.set', @args[:adgroup_id], @new_keywords[0..199].collect{|k| k.create_args.last }, delete_first) do |params|
+ log_error params[:statusMessage] if params[:statusMessage] != "OK"
+ end
+ rescue Exception => e
+ log_error e.message
end
- rescue Exception => e
- @campaign.errors << e.message
+ @new_keywords = @new_keywords[200..-1]
+ delete_first = false
end
- @new_keywords = @new_keywords[200..-1]
- delete_first = false
- end
- ############
- ## ADTEXTS
- ############
+ ############
+ ## ADTEXTS
+ ############
- #create new adtexts and delete old
- @saved_adtexts = adtexts.inject({}){|o,a| o[a.uniq_identifier] = a ; o}
- @new_adtexts = @adtexts.inject({}){|o,a| o[a.uniq_identifier] = a ; o}
+ #create new adtexts and delete old
+ @saved_adtexts = adtexts.inject({}){|o,a| o[a.uniq_identifier] = a ; o}
+ @new_adtexts = @adtexts.inject({}){|o,a| o[a.uniq_identifier] = a ; o}
- #adtexts to be deleted
- (@saved_adtexts.keys - @new_adtexts.keys).each do |k|
- puts "deleting adtext #{@saved_adtexts[k]} in #{@args[:name]}"
- #don't try to remove already removed adtext
- @saved_adtexts[k].remove unless @saved_adtexts[k].args[:status] == :stopped
- end
+ #adtexts to be deleted
+ (@saved_adtexts.keys - @new_adtexts.keys).each do |k|
+ puts "deleting adtext #{@saved_adtexts[k]} in #{@args[:name]}"
+ #don't try to remove already removed adtext
+ @saved_adtexts[k].remove unless @saved_adtexts[k].args[:status] == :stopped
+ end
- #adtexts to be created
- (@new_adtexts.keys - @saved_adtexts.keys).each do |k|
- puts "creating new adtext #{k} in #{@args[:name]}"
- begin
- @new_adtexts[k].save
- rescue Exception => e
- #take care about error message -> do it nicer
- if /There is error from sklik ad.create: Invalid parameters/ =~ e.message
- @campaign.errors << "Problem with creating #{@new_adtexts[k].args} in adgroup #{@args[:name]}"
- else
- @campaign.errors << e.message
+ #adtexts to be created
+ (@new_adtexts.keys - @saved_adtexts.keys).each do |k|
+ puts "creating new adtext #{k} in #{@args[:name]}"
+ begin
+ @new_adtexts[k].save
+ rescue Exception => e
+ #take care about error message -> do it nicer
+ if /There is error from sklik ad.create: Invalid parameters/ =~ e.message
+ log_error "Problem with creating #{@new_adtexts[k].args} in adgroup #{@args[:name]}"
+ else
+ log_error e.message
+ end
end
end
- end
- #check status to be running
- (@new_adtexts.keys & @saved_adtexts.keys).each do |k|
- @saved_adtexts[k].restore if @saved_adtexts[k].args[:status] == :stopped
+ #check status to be running
+ (@new_adtexts.keys & @saved_adtexts.keys).each do |k|
+ @saved_adtexts[k].restore if @saved_adtexts[k].args[:status] == :stopped
+ end
+
+ rescue Exception => e
+ log_error e.message
end
+ #remove it if new status is stopped or status doesn't changed and before it was stopped
+ remove if (@args[:status] == :stopped) || (@args[:status].nil? && before_status == :stopped)
- else #do save
- #create adgroup
- create
+ else #do create
+ begin
+ #create adgroup
+ create
+ rescue Exception => e
+ log_error e.message
+ #don't continue with creating campaign!
+ return false
+ end
+
#create adtexts
- @adtexts.each do |adtext|
- begin
- adtext.save
- rescue Exception => e
- #take care about error message -> do it nicer
- if /There is error from sklik ad.create: Invalid parameters/ =~ e.message
- @campaign.errors << "Problem with creating #{adtext.args} in adgroup #{@args[:name]}"
- else
- @campaign.errors << e.message
- end
- end
+ unless @adtexts.all?{|adtext| adtext.save }
+ return rollback!
end
-
#create keywords
keywords_error = []
@new_keywords = @keywords.clone
delete_first = true
while @new_keywords && @new_keywords.size > 0 do
begin
connection.call('keywords.set', @args[:adgroup_id], @new_keywords[0..199].collect{|k| k.create_args.last }, delete_first) do |params|
- @campaign.errors << params[:statusMessage] if params[:statusMessage] != "OK"
+ keywords_error << params[:statusMessage] if params[:statusMessage] != "OK"
end
rescue Exception => e
- @campaign.errors << e.message
+ keywords_error << e.message
end
@new_keywords = @new_keywords[200..-1]
delete_first = false
end
if keywords_error.size > 0
- @campaign.errors << "Problem with creating keywords: #{keywords_error.join(", ")} in adgroup #{@args[:name]}"
+ log_error "Problem with creating keywords: #{keywords_error.join(", ")}"
+ return rollback!
end
+ #remove campaign when it was started with stopped status!
+ remove if @args[:status] && @args[:status].to_s.to_sym == :stopped
+
end
+ !errors.any?
end
+ def log_error message
+ @campaign.log_error "Adgroup: #{@args[:name]} -> #{message}" if @campaign
+ errors << message
+ end
+
+ def rollback!
+ #don't rollback if it is disabled!
+ return false unless SklikApi.use_rollback?
+
+ #remember errors!
+ old_errors = errors
+
+ SklikApi.log :info, "Adgroup: #{@args[:adgroup_id]} - ROLLBACK!"
+ update :name => "#{@args[:name]} FAILED ON CREATION - #{Time.now.strftime("%Y.%m.%d %H:%M:%S")}"
+ #remove adgroup
+ remove
+
+ #return remembered errors!
+ @errors = old_errors
+ #don't continue with creating adgroup!
+ return false
+ end
end
end