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