serp_metrics 0.0.2

Sign up to get free protection for your applications and to get access to all the features.
Files changed (43) hide show
  1. data/.gitignore +18 -0
  2. data/.rspec +2 -0
  3. data/Gemfile +8 -0
  4. data/LICENSE +22 -0
  5. data/README.md +25 -0
  6. data/Rakefile +1 -0
  7. data/lib/serp_metrics.rb +25 -0
  8. data/lib/serp_metrics/client.rb +34 -0
  9. data/lib/serp_metrics/command_sets/account.rb +13 -0
  10. data/lib/serp_metrics/command_sets/base.rb +47 -0
  11. data/lib/serp_metrics/command_sets/engines.rb +9 -0
  12. data/lib/serp_metrics/command_sets/flux.rb +13 -0
  13. data/lib/serp_metrics/command_sets/keywords.rb +41 -0
  14. data/lib/serp_metrics/command_sets/priorities.rb +23 -0
  15. data/lib/serp_metrics/commands.rb +23 -0
  16. data/lib/serp_metrics/response.rb +5 -0
  17. data/lib/serp_metrics/version.rb +3 -0
  18. data/serp_metrics.gemspec +22 -0
  19. data/spec/api_credentials.yml.sample +2 -0
  20. data/spec/cassettes/serp_metrics__command_sets__account/credit_fetches_credit_information.yml +46 -0
  21. data/spec/cassettes/serp_metrics__command_sets__account/time_fetches_time.yml +38 -0
  22. data/spec/cassettes/serp_metrics__command_sets__engines/codes_fetches_search_engine_codes.yml +221 -0
  23. data/spec/cassettes/serp_metrics__command_sets__flux/flux_fetches_flux_trend.yml +46 -0
  24. data/spec/cassettes/serp_metrics__command_sets__keywords/add_adds_keyword.yml +163 -0
  25. data/spec/cassettes/serp_metrics__command_sets__keywords/all_retrieves_keywords.yml +206 -0
  26. data/spec/cassettes/serp_metrics__command_sets__keywords/check_retrieves_checks.yml +206 -0
  27. data/spec/cassettes/serp_metrics__command_sets__keywords/remove_removes_keyword.yml +200 -0
  28. data/spec/cassettes/serp_metrics__command_sets__keywords/serp_retrieves_serp_for_check.yml +165 -0
  29. data/spec/cassettes/serp_metrics__command_sets__priorities/add_with_location_adds_priority.yml +40 -0
  30. data/spec/cassettes/serp_metrics__command_sets__priorities/add_without_location_adds_priority.yml +40 -0
  31. data/spec/cassettes/serp_metrics__command_sets__priorities/get_checks_priority.yml +79 -0
  32. data/spec/lib/serp_metrics/client_spec.rb +27 -0
  33. data/spec/lib/serp_metrics/command_sets/account_spec.rb +27 -0
  34. data/spec/lib/serp_metrics/command_sets/engines_spec.rb +22 -0
  35. data/spec/lib/serp_metrics/command_sets/flux_spec.rb +23 -0
  36. data/spec/lib/serp_metrics/command_sets/keywords_spec.rb +90 -0
  37. data/spec/lib/serp_metrics/command_sets/priorities_spec.rb +51 -0
  38. data/spec/lib/serp_metrics/commands_spec.rb +62 -0
  39. data/spec/lib/serp_metrics/response_spec.rb +9 -0
  40. data/spec/lib/serp_metrics/version_spec.rb +8 -0
  41. data/spec/lib/serp_metrics_spec.rb +14 -0
  42. data/spec/spec_helper.rb +61 -0
  43. metadata +143 -0
data/.gitignore ADDED
@@ -0,0 +1,18 @@
1
+ *.gem
2
+ *.rbc
3
+ .bundle
4
+ .config
5
+ .yardoc
6
+ spec/api_credentials.yml
7
+ Gemfile.lock
8
+ InstalledFiles
9
+ _yardoc
10
+ coverage
11
+ doc/
12
+ lib/bundler/man
13
+ pkg
14
+ rdoc
15
+ spec/reports
16
+ test/tmp
17
+ test/version_tmp
18
+ tmp
data/.rspec ADDED
@@ -0,0 +1,2 @@
1
+ --color
2
+ --format documentation
data/Gemfile ADDED
@@ -0,0 +1,8 @@
1
+ source 'http://rubygems.org'
2
+
3
+ gemspec
4
+
5
+ gem 'rspec'
6
+ gem 'vcr'
7
+ gem 'webmock'
8
+ gem 'timecop'
data/LICENSE ADDED
@@ -0,0 +1,22 @@
1
+ Copyright (c) 2013 SEHabitat. http://sehabitat.com
2
+
3
+ MIT License
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining
6
+ a copy of this software and associated documentation files (the
7
+ "Software"), to deal in the Software without restriction, including
8
+ without limitation the rights to use, copy, modify, merge, publish,
9
+ distribute, sublicense, and/or sell copies of the Software, and to
10
+ permit persons to whom the Software is furnished to do so, subject to
11
+ the following conditions:
12
+
13
+ The above copyright notice and this permission notice shall be
14
+ included in all copies or substantial portions of the Software.
15
+
16
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
20
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
21
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
22
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,25 @@
1
+ # SerpMetrics
2
+
3
+ Ruby interface to the SERP Metrics API
4
+
5
+ ## Installation
6
+
7
+ Add this line to your application's Gemfile:
8
+
9
+ gem 'serp_metrics'
10
+
11
+ And then execute:
12
+
13
+ $ bundle
14
+
15
+ Or install it yourself as:
16
+
17
+ $ gem install serp_metrics
18
+
19
+ ## Contributing
20
+
21
+ 1. Fork it
22
+ 2. Create your feature branch (`git checkout -b my-new-feature`)
23
+ 3. Commit your changes (`git commit -am 'Add some feature'`)
24
+ 4. Push to the branch (`git push origin my-new-feature`)
25
+ 5. Create new Pull Request
data/Rakefile ADDED
@@ -0,0 +1 @@
1
+ require "bundler/gem_tasks"
@@ -0,0 +1,25 @@
1
+ require 'base64'
2
+ require 'openssl'
3
+ require 'json'
4
+
5
+ require 'serp_metrics/version'
6
+ require 'serp_metrics/response'
7
+ require 'serp_metrics/command_sets/base'
8
+ require 'serp_metrics/command_sets/account'
9
+ require 'serp_metrics/command_sets/engines'
10
+ require 'serp_metrics/command_sets/flux'
11
+ require 'serp_metrics/command_sets/keywords'
12
+ require 'serp_metrics/command_sets/priorities'
13
+ require 'serp_metrics/commands'
14
+ require 'serp_metrics/client'
15
+
16
+ module SerpMetrics
17
+ API_URI = 'http://api.serpmetrics.com'
18
+ USER_AGENT = 'SERPMetrics Ruby Library'
19
+
20
+ class << self
21
+ def client
22
+ @client ||= Client.new
23
+ end
24
+ end
25
+ end
@@ -0,0 +1,34 @@
1
+ module SerpMetrics
2
+ class Client
3
+ include SerpMetrics::Commands
4
+
5
+ attr_accessor :key, :secret
6
+
7
+ def initialize(key = nil, secret = nil)
8
+ self.key = key
9
+ self.secret = secret
10
+ end
11
+
12
+ def configure
13
+ yield self
14
+ self
15
+ end
16
+
17
+ protected
18
+
19
+ def generate_signature(timestamp = nil)
20
+ Base64.strict_encode64(OpenSSL::HMAC.digest('sha256', secret, timestamp.to_i.to_s))
21
+ end
22
+
23
+ def generate_signature_hash(timestamp = nil)
24
+ timestamp ||= Time.now.utc
25
+ signature = generate_signature(timestamp)
26
+
27
+ {
28
+ :key => key,
29
+ :ts => timestamp.to_i.to_s,
30
+ :auth => signature
31
+ }
32
+ end
33
+ end
34
+ end
@@ -0,0 +1,13 @@
1
+ module SerpMetrics
2
+ module CommandSets
3
+ class Account < Base
4
+ def credit
5
+ transact(:post, '/users/credit')
6
+ end
7
+
8
+ def time
9
+ transact(:post, '/users/time')
10
+ end
11
+ end
12
+ end
13
+ end
@@ -0,0 +1,47 @@
1
+ require 'httpclient'
2
+
3
+ module SerpMetrics
4
+ module CommandSets
5
+ class Base
6
+ attr_accessor :client
7
+
8
+ def initialize(client)
9
+ self.client = client
10
+ end
11
+
12
+ protected
13
+
14
+ def transact(method, path, options = {})
15
+ signature_hash = client.send(:generate_signature_hash)
16
+
17
+ query = signature_hash
18
+ query = query.merge(:params => options.to_json) unless options.empty?
19
+
20
+ res = case method
21
+ when :get
22
+ HTTPClient.get(SerpMetrics::API_URI + path, {
23
+ :query => (to_query(query) unless query.empty?)
24
+ })
25
+ when :post
26
+ inner_res = HTTPClient.post(SerpMetrics::API_URI + path, {
27
+ :body => (to_query(query) unless query.empty?)
28
+ })
29
+
30
+ if inner_res.redirect?
31
+ inner_res = HTTPClient.get(inner_res.http_header['Location'].first)
32
+ end
33
+
34
+ inner_res
35
+ end
36
+
37
+ JSON.parse(res.body)
38
+ end
39
+
40
+ private
41
+
42
+ def to_query(query)
43
+ URI.encode_www_form(query)
44
+ end
45
+ end
46
+ end
47
+ end
@@ -0,0 +1,9 @@
1
+ module SerpMetrics
2
+ module CommandSets
3
+ class Engines < Base
4
+ def codes
5
+ transact(:post, '/engines/codes')
6
+ end
7
+ end
8
+ end
9
+ end
@@ -0,0 +1,13 @@
1
+ module SerpMetrics
2
+ module CommandSets
3
+ class Flux < Base
4
+ def flux(engine_code, type = 'daily')
5
+ transaction_options = {
6
+ :engine_code => engine_code,
7
+ :type => type
8
+ }
9
+ transact(:post, '/flux/trend', transaction_options)
10
+ end
11
+ end
12
+ end
13
+ end
@@ -0,0 +1,41 @@
1
+ module SerpMetrics
2
+ module CommandSets
3
+ class Keywords < Base
4
+ def add(keyword, engines)
5
+ transaction_options = {
6
+ :keyword => keyword,
7
+ :engines => engines
8
+ }
9
+ transact(:post, '/keywords/add', transaction_options)
10
+ end
11
+
12
+ def remove(keyword_id)
13
+ transaction_options = {
14
+ :keyword_id => keyword_id,
15
+ }
16
+ transact(:post, '/keywords/delete', transaction_options)
17
+ end
18
+
19
+ def check(keyword_id, engine, limit = 10)
20
+ transaction_options = {
21
+ :keyword_id => keyword_id,
22
+ :engine => engine,
23
+ :limit => limit
24
+ }
25
+ transact(:post, '/keywords/check', transaction_options)
26
+ end
27
+
28
+ def serp(check_id, domain = nil)
29
+ transaction_options = {
30
+ :check_id => check_id,
31
+ :domain => domain
32
+ }
33
+ transact(:post, '/keywords/serp', transaction_options)
34
+ end
35
+
36
+ def all
37
+ transact(:post, '/keywords/all')
38
+ end
39
+ end
40
+ end
41
+ end
@@ -0,0 +1,23 @@
1
+ module SerpMetrics
2
+ module CommandSets
3
+ class Priorities < Base
4
+ def add(keyword, engines, location = nil)
5
+ transaction_options = {
6
+ :keyword => keyword,
7
+ :engines => engines
8
+ }
9
+ unless location.nil?
10
+ transaction_options[:location] = location
11
+ end
12
+ transact(:post, '/priority/add', transaction_options)
13
+ end
14
+
15
+ def get(priority_id)
16
+ transaction_options = {
17
+ :priority_id => priority_id
18
+ }
19
+ transact(:post, '/priority/status', transaction_options)
20
+ end
21
+ end
22
+ end
23
+ end
@@ -0,0 +1,23 @@
1
+ module SerpMetrics
2
+ module Commands
3
+ def keywords
4
+ @keywords ||= SerpMetrics::CommandSets::Keywords.new(self)
5
+ end
6
+
7
+ def account
8
+ @account ||= SerpMetrics::CommandSets::Account.new(self)
9
+ end
10
+
11
+ def priorities
12
+ @priorities ||= SerpMetrics::CommandSets::Priorities.new(self)
13
+ end
14
+
15
+ def flux
16
+ @flux ||= SerpMetrics::CommandSets::Flux.new(self)
17
+ end
18
+
19
+ def engines
20
+ @engines ||= SerpMetrics::CommandSets::Engines.new(self)
21
+ end
22
+ end
23
+ end
@@ -0,0 +1,5 @@
1
+ module SerpMetrics
2
+ class Response
3
+ attr_accessor :status
4
+ end
5
+ end
@@ -0,0 +1,3 @@
1
+ module SerpMetrics
2
+ VERSION = '0.0.2'
3
+ end
@@ -0,0 +1,22 @@
1
+ # -*- encoding: utf-8 -*-
2
+ lib = File.expand_path('../lib', __FILE__)
3
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
+ require 'serp_metrics/version'
5
+
6
+ Gem::Specification.new do |gem|
7
+ gem.name = "serp_metrics"
8
+ gem.version = SerpMetrics::VERSION
9
+ gem.authors = ["Kristina Lim"]
10
+ gem.email = ["kristinalim.ph@gmail.com"]
11
+ gem.description = %q{Ruby interface to the SERP Metrics API}
12
+ gem.summary = %q{Ruby interface to the SERP Metrics API}
13
+ gem.homepage = "https://github.com/wearetribe/serp_metrics.git"
14
+
15
+ gem.files = `git ls-files`.split($/)
16
+ gem.executables = gem.files.grep(%r{^bin/}).map{ |f| File.basename(f) }
17
+ gem.test_files = gem.files.grep(%r{^(test|spec|features)/})
18
+ gem.require_paths = ["lib"]
19
+
20
+ gem.add_runtime_dependency 'multi_json', '~> 1.3'
21
+ gem.add_runtime_dependency 'httpclient', '~> 2.3'
22
+ end
@@ -0,0 +1,2 @@
1
+ key: ''
2
+ secret: ''
@@ -0,0 +1,46 @@
1
+ ---
2
+ http_interactions:
3
+ - request:
4
+ method: post
5
+ uri: http://api.serpmetrics.com/users/credit
6
+ body:
7
+ encoding: US-ASCII
8
+ string: key=h31x%25sd22hgjd2s&ts=1363584772&auth=lROO29qiF4QDoLetbhqb2gKopwnfB%2Bo%2F3g7RGDPcXx8%3D
9
+ headers:
10
+ Content-Type:
11
+ - application/x-www-form-urlencoded
12
+ response:
13
+ status:
14
+ code: 200
15
+ message: OK
16
+ headers:
17
+ Server:
18
+ - nginx
19
+ Date:
20
+ - Mon, 18 Mar 2013 05:35:30 GMT
21
+ Content-Type:
22
+ - application/json; charset=UTF-8
23
+ Content-Length:
24
+ - '128'
25
+ Connection:
26
+ - keep-alive
27
+ Vary:
28
+ - Accept-Encoding
29
+ Cache-Control:
30
+ - no-store, no-cache, must-revalidate, post-check=0, pre-check=0
31
+ Expires:
32
+ - Thu, 19 Nov 1981 08:52:00 GMT
33
+ Pragma:
34
+ - no-cache
35
+ Set-Cookie:
36
+ - app=6npjarla1sk78thkood2id09i7; path=/; HttpOnly
37
+ X-Cache:
38
+ - OrchestraCache
39
+ X-Orchestra-Scheme:
40
+ - http
41
+ body:
42
+ encoding: US-ASCII
43
+ string: ! '{"status":"ok","data":{"api_key":"<SERP_METRICS_KEY>","balance":0,"api_credit":-98.5,"serp_credit":2892},"request_time":1363585088}'
44
+ http_version: !!null
45
+ recorded_at: Mon, 18 Mar 2013 05:32:52 GMT
46
+ recorded_with: VCR 2.4.0
@@ -0,0 +1,38 @@
1
+ ---
2
+ http_interactions:
3
+ - request:
4
+ method: post
5
+ uri: http://api.serpmetrics.com/users/time
6
+ body:
7
+ encoding: US-ASCII
8
+ string: key=h31x%25sd22hgjd2s&ts=1363584772&auth=lROO29qiF4QDoLetbhqb2gKopwnfB%2Bo%2F3g7RGDPcXx8%3D
9
+ headers:
10
+ Content-Type:
11
+ - application/x-www-form-urlencoded
12
+ response:
13
+ status:
14
+ code: 200
15
+ message: OK
16
+ headers:
17
+ Server:
18
+ - nginx
19
+ Date:
20
+ - Mon, 18 Mar 2013 05:35:29 GMT
21
+ Content-Type:
22
+ - application/json; charset=UTF-8
23
+ Content-Length:
24
+ - '27'
25
+ Connection:
26
+ - keep-alive
27
+ Vary:
28
+ - Accept-Encoding
29
+ X-Cache:
30
+ - OrchestraCache
31
+ X-Orchestra-Scheme:
32
+ - http
33
+ body:
34
+ encoding: US-ASCII
35
+ string: ! '{"request_time":1363585086}'
36
+ http_version: !!null
37
+ recorded_at: Mon, 18 Mar 2013 05:32:52 GMT
38
+ recorded_with: VCR 2.4.0