semrush 3.0.0

Sign up to get free protection for your applications and to get access to all the features.
data/MIT-LICENSE ADDED
@@ -0,0 +1,20 @@
1
+ Copyright 2011 YOURNAME
2
+
3
+ Permission is hereby granted, free of charge, to any person obtaining
4
+ a copy of this software and associated documentation files (the
5
+ "Software"), to deal in the Software without restriction, including
6
+ without limitation the rights to use, copy, modify, merge, publish,
7
+ distribute, sublicense, and/or sell copies of the Software, and to
8
+ permit persons to whom the Software is furnished to do so, subject to
9
+ the following conditions:
10
+
11
+ The above copyright notice and this permission notice shall be
12
+ included in all copies or substantial portions of the Software.
13
+
14
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
15
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
17
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
18
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
19
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
20
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/README.rdoc ADDED
@@ -0,0 +1,88 @@
1
+ = Semrush
2
+
3
+ Semrush is a ruby wrapper for the SEMRush API.
4
+
5
+ == Installation
6
+
7
+ Add the gem to your Gemfile:
8
+
9
+ gem install semrush
10
+
11
+ Create an initializer, for instance semrush.rb with the following:
12
+
13
+ Semrush.config do |config|
14
+ config.api_key = "7899esf6874"
15
+ end
16
+
17
+ Replace '7899esf6874' with your SEMRush api key.
18
+
19
+ == Getting started
20
+
21
+ First, create a report for a domain, a URL or a phrase with:
22
+
23
+ report = Semrush::Report.domain("seobook.com") # for the "seobook.com" domain
24
+ report = Semrush::Report.url("http://tools.seobook.com/") # for the "http://tools.seobook.com/" url
25
+ report = Semrush::Report.phrase("search+engine+optimization") # for the "search+engine+optimization" phrase
26
+
27
+ Then run the report type you need:
28
+
29
+ basic_data = report.basics
30
+
31
+ or
32
+
33
+ keywords_data = report.keywords_organic
34
+
35
+ == Parameters
36
+
37
+ You may use the following parameters:
38
+
39
+ :db # (String) select the google engine ('us' for google.comn 'fr' for google.fr)
40
+ :api_key # (String) change the api_key
41
+ :limit # (Integer) select only the first 'limit' entries
42
+ :offset # (Integer) skip the first 'offset' entries
43
+ :export_columns # (String) select the columns you want to fetch, for instance: :export_columns => "Dn,Rk"
44
+
45
+ Some examples:
46
+
47
+ report = Semrush::Report.domain("seobook.com", :db => 'us', :limit => 100)
48
+ data = report.basics
49
+
50
+ or
51
+
52
+ report = Semrush::Report.domain("seobook.com")
53
+ data = report.basics(:db => 'us', :limit => 100)
54
+
55
+ You will find more information about these parameters at http://www.semrush.com/api.html
56
+
57
+ == Reports
58
+
59
+ === Source of reports
60
+
61
+ They are 3 sources for the reports: domain, url and phrase.
62
+
63
+ report = Semrush::Report.domain("seobook.com") # for the "seobook.com" domain
64
+ report = Semrush::Report.url("http://tools.seobook.com/") # for the "http://tools.seobook.com/" url
65
+ report = Semrush::Report.phrase("search+engine+optimization") # for the "search+engine+optimization" phrase
66
+
67
+ === Report types
68
+
69
+ You may call for one of the following report types:
70
+
71
+ data = report.basics # main report for either a domain or a phrase
72
+ data = report.keywords_organic # keywords organic report for either a domain or a URL
73
+ data = report.keywords_adwords # keywords adwords report for either a domain or a URL
74
+ data = report.competitors_organic # for a domain
75
+ data = report.competitors_adwords # for a domain
76
+ data = report.competitors_organic_by_adwords # for a domain
77
+ data = report.competitors_adwords_by_organic # for a domain
78
+ data = report.related # keywords related report for a phrase
79
+
80
+ For more information about the report types, please read http://www.semrush.com/api.html
81
+
82
+ == About authors
83
+
84
+ This gem is inspired by the work of Cramer Development for the semrush-client plugin (https://github.com/cramerdev/semrush-client).
85
+
86
+ It has been rewritten and gemified for the internal use in Weboglobin (http://fr.weboglobin.com).
87
+
88
+ This project rocks and uses MIT-LICENSE.
data/Rakefile ADDED
@@ -0,0 +1,27 @@
1
+ #!/usr/bin/env rake
2
+
3
+ begin
4
+ require 'rdoc/task'
5
+ rescue LoadError
6
+ require 'rdoc/rdoc'
7
+ require 'rake/rdoctask'
8
+ RDoc::Task = Rake::RDocTask
9
+ end
10
+
11
+ RDoc::Task.new(:rdoc) do |rdoc|
12
+ rdoc.rdoc_dir = 'rdoc'
13
+ rdoc.title = 'Semrush'
14
+ rdoc.options << '--line-numbers'
15
+ rdoc.rdoc_files.include('README.rdoc')
16
+ rdoc.rdoc_files.include('lib/**/*.rb')
17
+ end
18
+
19
+ require "rspec/core/rake_task"
20
+
21
+ desc "Run all test with spec"
22
+ RSpec::Core::RakeTask.new(:spec) do |t|
23
+ t.rspec_opts = %w[--color]
24
+ t.pattern = 'spec/*_spec.rb'
25
+ end
26
+ desc "Run tests"
27
+ task :default => :spec
data/lib/semrush.rb ADDED
@@ -0,0 +1,38 @@
1
+ require 'uri'
2
+ require 'net/http'
3
+ require 'csv'
4
+ require 'rubygems'
5
+ require 'active_support/all'
6
+ require 'pony' #for the warning mails
7
+ require 'semrush/exception'
8
+ require 'semrush/report'
9
+
10
+ module Semrush
11
+ API_REPORT_URL = "http://%DB%.api.semrush.com/?action=report&type=%REPORT_TYPE%&%REQUEST_TYPE%=%REQUEST%&key=%API_KEY%&display_limit=%LIMIT%&display_offset=%OFFSET%&export=api&export_columns=%EXPORT_COLUMNS%"
12
+
13
+ mattr_accessor :api_key
14
+ @@api_key = ""
15
+ mattr_accessor :debug
16
+ @@debug = false
17
+
18
+
19
+ # Email Options (TODO: remove if unnecessary)
20
+ # config.email : recipient for the email notifications (default: nil)
21
+ # config.email_options : Hash with email config (smtp, sendmail, ...). We use the Pony gem to send mails, this hash will be send to Pony.options
22
+ # config.seconds_between_mails : Minimum time (in seconds) between 2 mails with the same subject
23
+ mattr_accessor :email
24
+ mattr_accessor :email_options
25
+ @@email_options = {}
26
+ mattr_accessor :seconds_between_mails
27
+ @@seconds_between_mails = 600
28
+ mattr_accessor :too_many_queries
29
+ @@too_many_queries = {:subject => 'SemRush API: too many queries for the day', :body => 'You made too many requests for today. You should upgrade your plan in order to be able to send more requests to SemRush.'}
30
+ mattr_accessor :too_many_queries_sent_at
31
+
32
+ def self.config
33
+ yield self
34
+ Pony.options = @@email_options
35
+ raise Exception::BadApiKey.new if @@api_key.nil? || @@api_key.empty?
36
+ end
37
+
38
+ end
@@ -0,0 +1,11 @@
1
+ module Semrush
2
+ module Exception
3
+ class Base < ::Exception
4
+ def initialize query = nil, message = ""
5
+ message = "[query=#{query.inspect}] #{message}" if !query.nil?
6
+ super(message)
7
+ end
8
+ end
9
+ end
10
+ end
11
+ Dir[File.expand_path('../exception/', __FILE__)+'/*.rb'].each {|file| require(file) }
@@ -0,0 +1,7 @@
1
+ module Semrush
2
+ module Exception
3
+ class ApiAccessDisabled < Base
4
+
5
+ end
6
+ end
7
+ end
@@ -0,0 +1,7 @@
1
+ module Semrush
2
+ module Exception
3
+ class BadApiKey < Base
4
+
5
+ end
6
+ end
7
+ end
@@ -0,0 +1,11 @@
1
+ module Semrush
2
+ module Exception
3
+ class BadArgument < Base
4
+
5
+ end
6
+ class MandatoryParameterDomainNotSetOrEmtpy < BadArgument; end
7
+ class MandatoryParameterUrlNotSetOrEmtpy < BadArgument; end
8
+ class MandatoryParameterPhraseNotSetOrEmtpy < BadArgument; end
9
+ class WrongFormatOrEmptyKey < BadArgument; end
10
+ end
11
+ end
@@ -0,0 +1,7 @@
1
+ module Semrush
2
+ module Exception
3
+ class BadQuery < Base
4
+
5
+ end
6
+ end
7
+ end
@@ -0,0 +1,7 @@
1
+ module Semrush
2
+ module Exception
3
+ class NothingFound < Base
4
+
5
+ end
6
+ end
7
+ end
@@ -0,0 +1,7 @@
1
+ module Semrush
2
+ module Exception
3
+ class UnknownError < Base
4
+
5
+ end
6
+ end
7
+ end
@@ -0,0 +1,298 @@
1
+ module Semrush
2
+ # =Report Class
3
+ # Most of these methods take a hash parameter that may contain the following keys :
4
+ # * :db (ex: :db => "us")
5
+ # * :api_key (ex: :api_key => 'gt97s6d4a6w')
6
+ # * :limit (ex: :limit => 2000)
7
+ # * :offset (ex: :offset => 5)
8
+ # * :export_columns (ex: :export_columns => "Dn,Rk")
9
+ class Report
10
+ DBS = [:us, :uk, :ru, :de, :fr, :es, :it, :br, :au] #"us" - for Google.com, "uk" - for Google.co.uk, "ru" - for Google.ru, "de" for Google.de, "fr" for Google.fr, "es" for Google.es, "it" for Google.it Beta, "br" for Google.com.br Beta, "au" for Google.com.au Beta.
11
+ REPORT_TYPES = [:domain_rank, :domain_organic, :domain_adwords, :domain_organic_organic, :domain_adwords_adwords, :domain_organic_adwords, :domain_adwords_organic,
12
+ :phrase_this, :phrase_related,
13
+ :url_organic, :url_adwords]
14
+ REQUEST_TYPES = [:domain, :phrase, :url]
15
+
16
+
17
+ # Tries to make the api call for the report called as method (see samples on http://www.semrush.com/api.html).
18
+ # Allows calls like:
19
+ # * Semrush::Report.new.domain_rank(:request_type => :domain, :request => 'thedomain.com')
20
+ # * Semrush::Report.new.domain_organic_organic(:request_type => :domain, :request => 'thedomain.com')
21
+ # * Semrush::Report.new.phrase_related(:request_type => :phrase, :request => 'the phrase')
22
+ def method_missing(method, *args)
23
+ return super unless REPORT_TYPES.include?(method) && args.first.is_a?(Hash)
24
+ request args.first.merge(:report_type => method)
25
+ end
26
+
27
+ def initialize params = {}
28
+ @parameters = params
29
+ end
30
+
31
+ # Initializes a report for a specific domain.
32
+ # Takes a hash parameter that may contain the following keys :
33
+ # * :db (ex: :db => "us")
34
+ # * :api_key (ex: :api_key => 'gt97s6d4a6w')
35
+ # * :limit (ex: :limit => "")
36
+ # * :offset (ex: :offset => "")
37
+ # * :export_columns (ex: :export_columns => "")
38
+ def self.domain domain, params = {}
39
+ self.new(params.merge(:request_type => :domain, :request => domain))
40
+ end
41
+ # Initializes a report for a specific phrase (or keyword).
42
+ # Takes a hash parameter that may contain the following keys :
43
+ # * :db (ex: :db => "us")
44
+ # * :api_key (ex: :api_key => 'gt97s6d4a6w')
45
+ # * :limit (ex: :limit => "")
46
+ # * :offset (ex: :offset => "")
47
+ # * :export_columns (ex: :export_columns => "")
48
+ def self.phrase phrase, params = {}
49
+ self.new(params.merge(:request_type => :phrase, :request => phrase))
50
+ end
51
+ # Initializes a report for a specific domain.
52
+ # Takes a hash parameter that may contain the following keys :
53
+ # * :db (ex: :db => "us")
54
+ # * :api_key (ex: :api_key => 'gt97s6d4a6w')
55
+ # * :limit (ex: :limit => "")
56
+ # * :offset (ex: :offset => "")
57
+ # * :export_columns (ex: :export_columns => "")
58
+ def self.url url, params = {}
59
+ self.new(params.merge(:request_type => :url, :request => url))
60
+ end
61
+
62
+ # Main report.
63
+ # Available for a phrase or a domain.
64
+ # Default columns for a domain:
65
+ # * Dn - A site name.
66
+ # * Rk - Rating of sites by the number of visitors coming from the first 20 Google search results
67
+ # * Or - Keywords that this site has in TOP20 Google Organic results
68
+ # * Ot - Estimated number of visitors coming from the first 20 Google search results (per month)
69
+ # * Oc - Estimated cost of purchasing the same number of visitors
70
+ # * Ad - Keywords that this site has in TOP20 Google AdWords
71
+ # * At - Estimated number of visitors coming from AdWords (per month)
72
+ # * Ac - Estimated expenses of the site for the advertising in AdWords (per month)
73
+ # Default columns for a phrase:
74
+ # * Ph - The search query which the site has within the first 20 Google search results
75
+ # * Nq - Average number of queries of this keyword in a month, for the corresponding local version of Google
76
+ # * Cp - Average price of a click on the AdWords ad for this search query, in U.S. dollars
77
+ # * Co - Competition of advertisers in AdWords for that term, the higher is the number - the higher is the competition
78
+ # * Nr - The number of search results - how many pages does Google know for this query
79
+ def basics params = {}
80
+ domain? ? request(params.merge(:report_type => :domain_rank)) : request(params.merge(:report_type => :phrase_this))
81
+ end
82
+
83
+ # Organic Keywords report
84
+ # Can be called for a domain or a URL.
85
+ # Default columns for a domain:
86
+ # * Ph - The search query which the site has within the first 20 Google search results
87
+ # * Po - The position of the site for the search query in Google, at the moment of data collection
88
+ # * Pp - The position of the site for the search query in Google, for the previous data collection
89
+ # * Nq - Average number of queries of this keyword in a month, for the corresponding local version of Google
90
+ # * Cp - Average price of a click on the AdWords ad for this search query, in U.S. dollars
91
+ # * Ur - URL of a page of the site which is displayed in search results for this query (landing page)
92
+ # * Tr - The ratio of the number of visitors coming to the site from this search request to all visitors coming from Google search results
93
+ # * Tc - The ratio of the estimated cost of buying the same number of visitors for this search query to the estimated cost of purchasing the same number of targeted visitors coming to this site from Google search results
94
+ # * Co - Competition of advertisers in AdWords for that term, the higher is the number - the higher is the competition
95
+ # * Nr - The number of search results - how many pages does Google know for this query
96
+ # * Td - Dynamics of change in the number of search queries in the past 12 months (estimated)
97
+ # Default columns for a URL:
98
+ # * Ph - Search query that the URL has within the first 20 Google Organic or AdWords results
99
+ # * Po - The position of this URL for this keyword in Organic or AdWords results
100
+ # * Nq - Average number of queries of this keyword in a month, for the corresponding local version of Google
101
+ # * Cp - Average price of a click on the AdWords ad for this search query, in U.S. dollars
102
+ # * Co - Competition of advertisers in AdWords for that term, the higher is the number - the higher is the competition
103
+ # * Tr - The ratio of the number of visitors coming to the URL from this keyword to all visitors coming
104
+ # * Tc - The ratio of the estimated cost of buying the same number of visitors for this search query to the estimated cost of purchasing the same number of targeted visitors coming to this URL
105
+ # * Nr - The number of search results - how many pages does Google know for this query
106
+ # * Td - Dynamics of change in the number of search queries in the past 12 months (estimated)
107
+ def keywords_organic params = {}
108
+ url? ? request(params.merge(:report_type => :url_organic)) : request(params.merge(:report_type => :domain_organic))
109
+ end
110
+
111
+ # AdWords keywords report
112
+ # Can be called for a domain or a URL.
113
+ # Default columns for a domain:
114
+ # * Ph - Search query which the site buys in AdWords in Google
115
+ # * Po - The position of the ad at the time of data collection
116
+ # * Pp - The position of the ad at the time of previous data collection
117
+ # * Nq - Average number of queries of this keyword in a month, for the corresponding local version of Google
118
+ # * Cp - Average price of a click on the AdWords ad for this search query, in U.S. dollars
119
+ # * Vu - Display URL. This is the URL displayed on your ad to identify your site to users.
120
+ # * Tr - The ratio of the number of visitors coming to the site from this ad to all visitors coming from Google AdWords
121
+ # * Tc - The ratio of site's expenditures on this particular ad to it's expenditures on all AdWords ads in general
122
+ # * Co - Competition of advertisers in AdWords for that term, the higher is the number - the higher is the competition
123
+ # * Nr - The number of search results - how many pages does Google know for this query
124
+ # * Td - Dynamics of change in the number of search queries in the past 12 months (estimated)
125
+ # * Ur - The destination URL is the exact URL within your website that you want to send users to from your ad.
126
+ # Default columns for a URL:
127
+ # * Ph - Search query that the URL has within the first 20 Google Organic or AdWords results
128
+ # * Po - The position of this URL for this keyword in Organic or AdWords results
129
+ # * Nq - Average number of queries of this keyword in a month, for the corresponding local version of Google
130
+ # * Cp - Average price of a click on the AdWords ad for this search query, in U.S. dollars
131
+ # * Co - Competition of advertisers in AdWords for that term, the higher is the number - the higher is the competition
132
+ # * Tr - The ratio of the number of visitors coming to the URL from this keyword to all visitors coming
133
+ # * Tc - The ratio of the estimated cost of buying the same number of visitors for this search query to the estimated cost of purchasing the same number of targeted visitors coming to this URL
134
+ # * Nr - The number of search results - how many pages does Google know for this query
135
+ # * Td - Dynamics of change in the number of search queries in the past 12 months (estimated)
136
+ def keywords_adwords params = {}
137
+ url? ? request(params.merge(:report_type => :url_adwords)) : request(params.merge(:report_type => :domain_adwords))
138
+ end
139
+
140
+ # Competitors in organic search report
141
+ # Default columns:
142
+ # * Dn - Sites competing with this site in Google search results, sorted by the number of common keywords
143
+ # * Np - The number of keywords on which the site is displayed in search results next to the analyzed site
144
+ # * Or - Keywords that this site has in TOP20 Google Organic results
145
+ # * Ot - Estimated number of visitors coming from the first 20 Google search results (per month)
146
+ # * Oc - Estimated cost of purchasing the same number of visitors
147
+ # * Ad - Keywords that this site has in TOP20 Google AdWords
148
+ def competitors_organic params = {}
149
+ request(params.merge(:report_type => :domain_organic_organic))
150
+ end
151
+
152
+ # Competitors in AdWords search report
153
+ # Default columns:
154
+ # * Dn - Sites competing with this site in AdWords, sorted by the number of common keywords
155
+ # * Np - Number of common keywords in AdWords that these two sites buy
156
+ # * Ad - Keywords that this site has in TOP20 Google AdWords
157
+ # * At - Estimated number of visitors coming from AdWords (per month)
158
+ # * Ac - Estimated expenses of the site for the advertising in AdWords (per month)
159
+ # * Or - Keywords that this site has in TOP20 Google Organic results
160
+ def competitors_adwords params = {}
161
+ request(params.merge(:report_type => :domain_adwords_adwords))
162
+ end
163
+
164
+ # Potential ad/traffic buyers report
165
+ # Default columns:
166
+ # * Dn - The list of sites that buys ads in AdWords for those keywords that the domain under analyzis has within Google TOP20
167
+ # * Np - Number of keywords on which ads of this particular site appear and the analyzed site gets within Google TOP20
168
+ # * Ad - Keywords that this site has in TOP20 Google AdWords
169
+ # * At - Estimated number of visitors coming from AdWords (per month)
170
+ # * Ac - Estimated expenses of the site for the advertising in AdWords (per month)
171
+ # * Or - Keywords that this site has in TOP20 Google Organic results
172
+ def competitors_organic_by_adwords params = {}
173
+ request(params.merge(:report_type => :domain_organic_adwords))
174
+ end
175
+
176
+ # Potential ad/traffic sellers report
177
+ # Default columns:
178
+ # * Dn - Sites that get into Google TOP20 for keyword queries that analyzed site buy in AdWords
179
+ # * Np - The number of keywords which this site has in search results next to the AdWords ads of the analyzed site
180
+ # * Or - Keywords that this site has in TOP20 Google Organic results
181
+ # * Ot - Estimated number of visitors coming from the first 20 Google search results (per month)
182
+ # * Oc - Estimated cost of purchasing the same number of visitors
183
+ # * Ad - Keywords that this site has in TOP20 Google AdWords
184
+ def competitors_adwords_by_organic params = {}
185
+ request(params.merge(:report_type => :domain_adwords_organic))
186
+ end
187
+
188
+ # Related keyword report
189
+ # Default columns:
190
+ # * Ph - The search query which the site has within the first 20 Google search results
191
+ # * Nq - Average number of queries of this keyword in a month, for the corresponding local version of Google
192
+ # * Cp - Average price of a click on the AdWords ad for this search query, in U.S. dollars
193
+ # * Co - Competition of advertisers in AdWords for that term, the higher is the number - the higher is the competition
194
+ # * Nr - The number of search results - how many pages does Google know for this query
195
+ # * Td - Dynamics of change in the number of search queries in the past 12 months (estimated)
196
+ def related params = {}
197
+ request(params.merge(:report_type => :phrase_related))
198
+ end
199
+
200
+ private
201
+
202
+ def request params = {}
203
+ validate_parameters params
204
+ temp_url = "#{API_REPORT_URL}" #do not copy the constant as is or else the constant would be modified !!
205
+ @parameters.each {|k, v|
206
+ if v.blank?
207
+ temp_url.gsub!(/&[^&=]+=%#{k.to_s}%/i, '')
208
+ else
209
+ temp_url.gsub!("%#{k.to_s.upcase}%", URI.escape(v.to_s))
210
+ end
211
+ }
212
+ puts "[Semrush query] URL: #{temp_url}" if Semrush.debug
213
+ url = URI.parse(temp_url)
214
+ response = Net::HTTP.start(url.host, url.port) {|http|
215
+ http.get(url.path+"?"+url.query)
216
+ }.body rescue "ERROR :: RESPONSE ERROR (-1)" # Make this error up
217
+ response.starts_with?("ERROR") ? error(response) : parse(response)
218
+ end
219
+
220
+ # All parameters:
221
+ # * db - requested database
222
+ # * report_type - type of the report
223
+ # * api_key - user identification key, you can find it in your profile on the Semrush site
224
+ # * request_type - type of the request.
225
+ # * request - your request
226
+ # * limit - number of results returned
227
+ # * offset - says to skip that many results before beginning to return results to you
228
+ # * export_columns - list of column names, separated by coma. You may list just the column names you need in an order you need.
229
+ #
230
+ # more details in http://www.semrush.com/api.html
231
+ def validate_parameters params = {}
232
+ params.symbolize_keys!
233
+ params.delete(:db) unless DBS.include?(params[:db].try(:to_sym))
234
+ params.delete(:report_type) unless REPORT_TYPES.include?(params[:report_type].try(:to_sym))
235
+ params.delete(:request_type) unless REQUEST_TYPES.include?(params[:request_type].try(:to_sym))
236
+ @parameters = {:db => "us", :api_key => Semrush.api_key, :limit => "", :offset => "", :export_columns => ""}.merge(@parameters).merge(params)
237
+ raise Semrush::Exception::BadArgument.new(self, "Request parameter is missing: Domain name, URL, or keywords are required.") unless @parameters[:request].present?
238
+ raise Semrush::Exception::BadArgument.new(self, "Bad db: #{@parameters[:db]}") unless DBS.include?(@parameters[:db].try(:to_sym))
239
+ raise Semrush::Exception::BadArgument.new(self, "Bad report type: #{@parameters[:report_type]}") unless REPORT_TYPES.include?(@parameters[:report_type].try(:to_sym))
240
+ raise Semrush::Exception::BadArgument.new(self, "Bad request type: #{@parameters[:request_type]}") unless REQUEST_TYPES.include?(@parameters[:request_type].try(:to_sym))
241
+ end
242
+
243
+ # Format and raise an error
244
+ def error(text = "")
245
+ e = /ERROR\s(\d+)\s::\s(.*)/.match(text) || {}
246
+ name = (e[2] || "UnknownError").titleize
247
+ code = e[1] || -1
248
+ error_class = name.gsub(/\s/, "")
249
+
250
+ if error_class == "NothingFound"
251
+ []
252
+ else
253
+ raise Semrush::Exception.const_get(error_class).new(self, "#{name} (#{code})")
254
+ end
255
+ end
256
+
257
+ def parse(text = "")
258
+ csv = CSV.parse(text.to_s, :col_sep => ";")
259
+ data = {}
260
+ format_key = lambda do |k|
261
+ r = {
262
+ /\s/ => "_",
263
+ /[|\.|\)|\(]/ => "",
264
+ /%/ => "percent",
265
+ /\*/ => "times"
266
+ }
267
+ k = k.to_s.downcase
268
+ r.each_pair {|pattern, replace| k.gsub!(pattern, replace) }
269
+ k.to_sym
270
+ end
271
+
272
+ # (thanks http://snippets.dzone.com/posts/show/3899)
273
+ keys = csv.shift.map(&format_key)
274
+ string_data = csv.map {|row| row.map {|cell| cell.to_s } }
275
+ string_data.map {|row| Hash[*keys.zip(row).flatten] }
276
+ rescue CSV::MalformedCSVError => csvife
277
+ tries ||= 0
278
+ if (tries += 1) < 3
279
+ retry
280
+ else
281
+ raise CSV::MalformedCSVError.new("Bad format for CSV: #{text.inspect}").tap{|e|
282
+ e.set_backtrace(csvife.backtrace)}
283
+ end
284
+ end
285
+
286
+ def domain?
287
+ @parameters[:request_type].present? && REQUEST_TYPES.include?(@parameters[:request_type].to_sym) && @parameters[:request_type].to_sym==:domain
288
+ end
289
+ def url?
290
+ @parameters[:request_type].present? && REQUEST_TYPES.include?(@parameters[:request_type].to_sym) && @parameters[:request_type].to_sym==:url
291
+ end
292
+ def phrase?
293
+ @parameters[:request_type].present? && REQUEST_TYPES.include?(@parameters[:request_type].to_sym) && @parameters[:request_type].to_sym==:phrase
294
+ end
295
+
296
+
297
+ end
298
+ end
@@ -0,0 +1,3 @@
1
+ module Semrush
2
+ VERSION = "3.0.0" # we want to follow the API version: for API 3.0, the gem will be version 3.0.x
3
+ end
@@ -0,0 +1,4 @@
1
+ # desc "Explaining what the task does"
2
+ # task :semrush do
3
+ # # Task goes here
4
+ # end
metadata ADDED
@@ -0,0 +1,100 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: semrush
3
+ version: !ruby/object:Gem::Version
4
+ prerelease:
5
+ version: 3.0.0
6
+ platform: ruby
7
+ authors:
8
+ - arambert
9
+ autorequire:
10
+ bindir: bin
11
+ cert_chain: []
12
+
13
+ date: 2011-10-21 00:00:00 Z
14
+ dependencies:
15
+ - !ruby/object:Gem::Dependency
16
+ name: activesupport
17
+ prerelease: false
18
+ requirement: &id001 !ruby/object:Gem::Requirement
19
+ none: false
20
+ requirements:
21
+ - - ~>
22
+ - !ruby/object:Gem::Version
23
+ version: 3.1.0
24
+ type: :runtime
25
+ version_requirements: *id001
26
+ - !ruby/object:Gem::Dependency
27
+ name: pony
28
+ prerelease: false
29
+ requirement: &id002 !ruby/object:Gem::Requirement
30
+ none: false
31
+ requirements:
32
+ - - ">="
33
+ - !ruby/object:Gem::Version
34
+ version: 1.0.0
35
+ type: :runtime
36
+ version_requirements: *id002
37
+ - !ruby/object:Gem::Dependency
38
+ name: rspec
39
+ prerelease: false
40
+ requirement: &id003 !ruby/object:Gem::Requirement
41
+ none: false
42
+ requirements:
43
+ - - ">="
44
+ - !ruby/object:Gem::Version
45
+ version: 2.0.0
46
+ type: :development
47
+ version_requirements: *id003
48
+ description:
49
+ email:
50
+ - arambert@weboglobin.com
51
+ executables: []
52
+
53
+ extensions: []
54
+
55
+ extra_rdoc_files: []
56
+
57
+ files:
58
+ - lib/semrush/exception/api_access_disabled.rb
59
+ - lib/semrush/exception/bad_api_key.rb
60
+ - lib/semrush/exception/bad_argument.rb
61
+ - lib/semrush/exception/bad_query.rb
62
+ - lib/semrush/exception/nothing_found.rb
63
+ - lib/semrush/exception/unknown_error.rb
64
+ - lib/semrush/exception.rb
65
+ - lib/semrush/report.rb
66
+ - lib/semrush/version.rb
67
+ - lib/semrush.rb
68
+ - lib/tasks/semrush_tasks.rake
69
+ - MIT-LICENSE
70
+ - Rakefile
71
+ - README.rdoc
72
+ homepage: http://www.weboglobin.com
73
+ licenses: []
74
+
75
+ post_install_message:
76
+ rdoc_options: []
77
+
78
+ require_paths:
79
+ - lib
80
+ required_ruby_version: !ruby/object:Gem::Requirement
81
+ none: false
82
+ requirements:
83
+ - - ">="
84
+ - !ruby/object:Gem::Version
85
+ version: "0"
86
+ required_rubygems_version: !ruby/object:Gem::Requirement
87
+ none: false
88
+ requirements:
89
+ - - ">="
90
+ - !ruby/object:Gem::Version
91
+ version: "0"
92
+ requirements: []
93
+
94
+ rubyforge_project:
95
+ rubygems_version: 1.8.9
96
+ signing_key:
97
+ specification_version: 3
98
+ summary: This gem is a ruby client for the SemRush API.
99
+ test_files: []
100
+