Class: Semrush::Base

Inherits:
Object
  • Object
show all
Defined in:
lib/semrush/base.rb

Overview

Base Class for all Semrush API classes

Direct Known Subclasses

Analytics, Report

Instance Method Summary collapse

Instance Method Details

#error(text = "") ⇒ Object

Format and raise an error



32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
# File 'lib/semrush/base.rb', line 32

def error(text = "")
  e = /ERROR\s(\d+)\s::\s(.*)/.match(text) || {}
  name = (e[2] || "UnknownError").titleize
  code = e[1] || -1
  error_class = name.gsub(/\s/, "")

  if error_class == "NothingFound"
    []
  else
    begin
      raise Semrush::Exception.const_get(error_class).new(self, "#{name} (#{code})")
    rescue
      raise Semrush::Exception::Base.new(self, "#{name} (#{code}) *** error_class=#{error_class} not implemented ***")
    end
  end
end

#parse(text = "") ⇒ Object



49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
# File 'lib/semrush/base.rb', line 49

def parse(text = "")
  return [] if text.empty?
  csv = CSV.parse(text.to_s, :col_sep => ";")
  format_key = lambda do |k|
    r = {
      /\s/ => "_",
      /[|\.|\)|\(]/ => "",
      /%/ => "percent",
      /\*/ => "times"
    }
    k = k.to_s.downcase
    r.each_pair {|pattern, replace| k.gsub!(pattern, replace) }
    k.to_sym
  end

  # (thanks http://snippets.dzone.com/posts/show/3899)
  keys = csv.shift.map(&format_key)
  string_data = csv.map {|row| row.map {|cell| cell.to_s } }
  string_data.map {|row| Hash[*keys.zip(row).flatten] }
rescue CSV::MalformedCSVError => csvife
  tries ||= 0
  if (tries += 1) < 3
    retry
  else
    raise CSV::MalformedCSVError.new("Bad format for CSV: #{text.inspect}").tap{|e|
      e.set_backtrace(csvife.backtrace)}
  end
end

#request(params = {}) ⇒ Object



4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
# File 'lib/semrush/base.rb', line 4

def request params = {}
  validate_parameters params
  temp_url = "#{@api_report_url}" #do not copy the constant as is or else the constant would be modified !!
  @parameters.each {|k, v|
    if v.blank?
      temp_url.gsub!(/&[^&=]+=%#{k.to_s}%/i, '')
    elsif k.to_sym==:display_filter
      temp_url.gsub!("%#{k.to_s.upcase}%", CGI.escape(v.to_s).gsub('&', '%26').gsub('+', '%2B'))
    elsif v.is_a?(Array)
      # remove placeholder with value into query string of array of values
      temp_url.gsub!("#{k}=%#{k.to_s.upcase}%", v.to_query(k.to_s))
    else
      temp_url.gsub!("%#{k.to_s.upcase}%", CGI.escape(v.to_s).gsub('&', '%26'))
    end
  }
  puts "[Semrush query] URL: #{temp_url}" if Semrush.debug
  url = URI.parse(temp_url)
  Semrush.before.call(@parameters.merge(:url => url))
  response = Net::HTTP.start(url.host, url.port, :use_ssl => true) {|http|
    http.get(url.path+"?"+url.query)
  }.body rescue "ERROR :: RESPONSE ERROR (-1)" # Make this error up
  response.force_encoding("utf-8")
  output = response.starts_with?("ERROR") ? error(response) : parse(response)
  Semrush.after.call(@parameters.merge(:url => url), output)
  output
end