nucleo-client 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +7 -0
- data/.env.sample +2 -0
- data/.gitignore +16 -0
- data/Gemfile +4 -0
- data/LICENSE.txt +22 -0
- data/README.md +31 -0
- data/Rakefile +37 -0
- data/lib/nucleo/client.rb +172 -0
- data/lib/nucleo/client/version.rb +5 -0
- data/lib/nucleo/configuration.rb +83 -0
- data/lib/nucleo/configurations.rb +6 -0
- data/lib/nucleo/configurations/default.rb +100 -0
- data/lib/nucleo/connection.rb +44 -0
- data/lib/nucleo/errors.rb +7 -0
- data/lib/nucleo/errors/invalid_uri_error.rb +6 -0
- data/lib/nucleo/errors/record_not_found.rb +6 -0
- data/lib/nucleo/logger.rb +36 -0
- data/lib/nucleo/models.rb +50 -0
- data/lib/nucleo/models/change_types.rb +10 -0
- data/lib/nucleo/models/change_types/base.rb +81 -0
- data/lib/nucleo/models/change_types/seo.rb +13 -0
- data/lib/nucleo/models/change_types/seo/base.rb +50 -0
- data/lib/nucleo/models/change_types/seo/meta_description.rb +10 -0
- data/lib/nucleo/models/change_types/seo/page_title.rb +10 -0
- data/lib/nucleo/models/changes.rb +50 -0
- data/lib/nucleo/models/check_js.rb +41 -0
- data/lib/nucleo/models/check_types.rb +11 -0
- data/lib/nucleo/models/check_types/base.rb +25 -0
- data/lib/nucleo/models/check_types/count.rb +26 -0
- data/lib/nucleo/models/check_types/length.rb +26 -0
- data/lib/nucleo/models/check_types/not_exists.rb +8 -0
- data/lib/nucleo/models/checks.rb +56 -0
- data/lib/nucleo/models/concerns.rb +7 -0
- data/lib/nucleo/models/concerns/count.rb +57 -0
- data/lib/nucleo/models/concerns/length.rb +57 -0
- data/lib/nucleo/models/date_range.rb +66 -0
- data/lib/nucleo/models/element.rb +40 -0
- data/lib/nucleo/models/elements.rb +47 -0
- data/lib/nucleo/models/feed.rb +141 -0
- data/lib/nucleo/models/feed_types.rb +11 -0
- data/lib/nucleo/models/feed_types/analytics.rb +18 -0
- data/lib/nucleo/models/feed_types/analytics/base.rb +12 -0
- data/lib/nucleo/models/feed_types/analytics/page/channels.rb +61 -0
- data/lib/nucleo/models/feed_types/analytics/page/pages.rb +58 -0
- data/lib/nucleo/models/feed_types/analytics/page/referrers.rb +61 -0
- data/lib/nucleo/models/feed_types/analytics/page/social.rb +61 -0
- data/lib/nucleo/models/feed_types/analytics/site/channels.rb +61 -0
- data/lib/nucleo/models/feed_types/analytics/site/pages.rb +61 -0
- data/lib/nucleo/models/feed_types/analytics/site/referrers.rb +61 -0
- data/lib/nucleo/models/feed_types/analytics/site/social.rb +61 -0
- data/lib/nucleo/models/feed_types/base.rb +182 -0
- data/lib/nucleo/models/feed_types/seo.rb +22 -0
- data/lib/nucleo/models/feed_types/seo/page/base.rb +47 -0
- data/lib/nucleo/models/feed_types/seo/page/img_alt.rb +90 -0
- data/lib/nucleo/models/feed_types/seo/page/meta_description.rb +49 -0
- data/lib/nucleo/models/feed_types/seo/page/meta_robots.rb +48 -0
- data/lib/nucleo/models/feed_types/seo/page/page_title.rb +48 -0
- data/lib/nucleo/models/feed_types/seo/page/seo_summary.rb +53 -0
- data/lib/nucleo/models/feed_types/seo/page/summary.rb +52 -0
- data/lib/nucleo/models/feed_types/seo/site/base.rb +22 -0
- data/lib/nucleo/models/feed_types/seo/site/img_alt.rb +14 -0
- data/lib/nucleo/models/feed_types/seo/site/meta_description.rb +14 -0
- data/lib/nucleo/models/feed_types/seo/site/meta_robots.rb +14 -0
- data/lib/nucleo/models/feed_types/seo/site/page_title.rb +14 -0
- data/lib/nucleo/models/feeds.rb +126 -0
- data/lib/nucleo/models/metric.rb +54 -0
- data/lib/nucleo/models/metric_period.rb +97 -0
- data/lib/nucleo/models/metric_period_row.rb +125 -0
- data/lib/nucleo/models/metric_period_rows.rb +34 -0
- data/lib/nucleo/models/metric_period_totals.rb +121 -0
- data/lib/nucleo/models/metric_periods.rb +78 -0
- data/lib/nucleo/models/metric_periods_comparison.rb +80 -0
- data/lib/nucleo/models/metric_periods_comparisons.rb +73 -0
- data/lib/nucleo/models/metric_periods_totals.rb +58 -0
- data/lib/nucleo/models/page.rb +147 -0
- data/lib/nucleo/models/page_alerts.rb +27 -0
- data/lib/nucleo/models/page_metric.rb +58 -0
- data/lib/nucleo/models/page_rank.rb +28 -0
- data/lib/nucleo/models/pages.rb +40 -0
- data/lib/nucleo/models/seo_score.rb +28 -0
- data/lib/nucleo/models/site_feed.rb +82 -0
- data/lib/nucleo/models/tag.rb +48 -0
- data/lib/nucleo/models/tags.rb +35 -0
- data/lib/nucleo/requests.rb +14 -0
- data/lib/nucleo/requests/analyzer.rb +35 -0
- data/lib/nucleo/requests/check_js.rb +56 -0
- data/lib/nucleo/requests/feed.rb +58 -0
- data/lib/nucleo/requests/page.rb +113 -0
- data/lib/nucleo/requests/page_alerts.rb +36 -0
- data/lib/nucleo/requests/page_changes.rb +44 -0
- data/lib/nucleo/requests/site.rb +26 -0
- data/lib/nucleo/requests/site_changes.rb +56 -0
- data/lib/nucleo/requests/site_feed.rb +41 -0
- data/lib/nucleo/response.rb +52 -0
- data/lib/nucleo/utilities.rb +7 -0
- data/lib/nucleo/utilities/status_code_mapper.rb +53 -0
- data/lib/nucleo/webhook.rb +26 -0
- data/nucleo-client.gemspec +35 -0
- data/spec/data/models/feed_types/seo/heading_tag_length.json +55 -0
- data/spec/data/models/feed_types/seo/internal_link_count.json +149 -0
- data/spec/data/models/feed_types/seo/no_follow_link_count.json +142 -0
- data/spec/spec_helper.rb +15 -0
- data/spec/unit/nucleo/models/concerns/count_spec.rb +103 -0
- data/spec/unit/nucleo/models/concerns/length_spec.rb +79 -0
- data/spec/unit/nucleo/models/feed_types/analytics/site/pages_no_data_spec.rb +39 -0
- data/spec/unit/nucleo/models/metric_periods_comparison_spec.rb +50 -0
- data/spec/unit/nucleo/models/metric_periods_comparisons_spec.rb +58 -0
- metadata +341 -0
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
module Nucleo
|
|
2
|
+
module Requests
|
|
3
|
+
class PageAlerts
|
|
4
|
+
def self.retrieve(site_id, params={})
|
|
5
|
+
type = params.fetch(:type)
|
|
6
|
+
|
|
7
|
+
route = Nucleo::Client.routes.route_for('site-page-alerts')
|
|
8
|
+
url = route.url_for(site_id: site_id, type: type)
|
|
9
|
+
|
|
10
|
+
request = Nucleo::Client.get(url)
|
|
11
|
+
|
|
12
|
+
request.on(:success) do |resp|
|
|
13
|
+
response_body = resp.body
|
|
14
|
+
|
|
15
|
+
return response_body
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
request.on(:failure) do |resp|
|
|
19
|
+
Nucleo::Client.configuration.logger.error do
|
|
20
|
+
"App Error: %s" % [resp.body]
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
return nil
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
request.on(:server_error) do |resp|
|
|
27
|
+
Nucleo::Client.configuration.logger.error do
|
|
28
|
+
"Server Error: %s" % [resp.body]
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
return nil
|
|
32
|
+
end
|
|
33
|
+
end
|
|
34
|
+
end
|
|
35
|
+
end
|
|
36
|
+
end
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
module Nucleo
|
|
2
|
+
module Requests
|
|
3
|
+
class PageChanges
|
|
4
|
+
def self.create(site_id, page_id, attributes={})
|
|
5
|
+
route = Nucleo::Client.routes.route_for('site-page-changes')
|
|
6
|
+
url = route.url_for(site_id: site_id, page_id: page_id)
|
|
7
|
+
|
|
8
|
+
request_params = attributes
|
|
9
|
+
|
|
10
|
+
request = Nucleo::Client.post(url, MultiJson.dump(request_params))
|
|
11
|
+
|
|
12
|
+
request
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
def self.update(site_id, page_id, attributes={})
|
|
16
|
+
route = Nucleo::Client.routes.route_for('site-page-changes')
|
|
17
|
+
url = route.url_for(site_id: site_id, page_id: page_id)
|
|
18
|
+
|
|
19
|
+
request = Nucleo::Client.patch(url, MultiJson.dump(request_params))
|
|
20
|
+
|
|
21
|
+
request
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
def self.delete(site_id, page_id, attributes={})
|
|
25
|
+
route = Nucleo::Client.routes.route_for('site-page-changes')
|
|
26
|
+
url = route.url_for(site_id: site_id, page_id: page_id)
|
|
27
|
+
|
|
28
|
+
request = Nucleo::Client.delete(url, MultiJson.dump(request_params))
|
|
29
|
+
|
|
30
|
+
request
|
|
31
|
+
end
|
|
32
|
+
|
|
33
|
+
def self.index(site_id, page_id)
|
|
34
|
+
route = Nucleo::Client.routes.route_for('site-page-changes')
|
|
35
|
+
url = route.url_for(site_id: site_id, page_id: page_id)
|
|
36
|
+
|
|
37
|
+
request = Nucleo::Client.get(url)
|
|
38
|
+
|
|
39
|
+
request
|
|
40
|
+
end
|
|
41
|
+
|
|
42
|
+
end
|
|
43
|
+
end
|
|
44
|
+
end
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
module Nucleo
|
|
2
|
+
module Requests
|
|
3
|
+
class Site
|
|
4
|
+
def self.register(attributes={})
|
|
5
|
+
route = Nucleo::Client.routes.route_for('sites')
|
|
6
|
+
url = route.url_for
|
|
7
|
+
|
|
8
|
+
request_params = attributes
|
|
9
|
+
|
|
10
|
+
request = Nucleo::Client.post(url, MultiJson.dump(request_params))
|
|
11
|
+
|
|
12
|
+
request
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
def self.process(site_id)
|
|
16
|
+
route = Nucleo::Client.routes.route_for('site-process')
|
|
17
|
+
url = route.url_for(id: site_id)
|
|
18
|
+
|
|
19
|
+
request = Nucleo::Client.get(url)
|
|
20
|
+
|
|
21
|
+
request
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
end
|
|
25
|
+
end
|
|
26
|
+
end
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
module Nucleo
|
|
2
|
+
module Requests
|
|
3
|
+
class SiteChanges
|
|
4
|
+
def self.create(site_id, attributes={})
|
|
5
|
+
route = Nucleo::Client.routes.route_for('site-page-changes')
|
|
6
|
+
url = route.url_for(site_id: site_id)
|
|
7
|
+
|
|
8
|
+
request_params = attributes
|
|
9
|
+
|
|
10
|
+
request = Nucleo::Client.post(url, MultiJson.dump(request_params))
|
|
11
|
+
|
|
12
|
+
request
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
def self.batch(site_id, attributes={})
|
|
16
|
+
route = Nucleo::Client.routes.route_for('site-changes-batch')
|
|
17
|
+
url = route.url_for(site_id: site_id)
|
|
18
|
+
request_params = attributes
|
|
19
|
+
|
|
20
|
+
request = Nucleo::Client.post(url, MultiJson.dump(request_params))
|
|
21
|
+
|
|
22
|
+
request
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
def self.update(site_id, attributes={})
|
|
26
|
+
route = Nucleo::Client.routes.route_for('site-page-changes')
|
|
27
|
+
url = route.url_for(site_id: site_id)
|
|
28
|
+
request_params = attributes
|
|
29
|
+
|
|
30
|
+
request = Nucleo::Client.patch(url, MultiJson.dump(request_params))
|
|
31
|
+
|
|
32
|
+
request
|
|
33
|
+
end
|
|
34
|
+
|
|
35
|
+
def self.delete(site_id, attributes={})
|
|
36
|
+
route = Nucleo::Client.routes.route_for('site-page-changes')
|
|
37
|
+
url = route.url_for(site_id: site_id)
|
|
38
|
+
request_params = attributes
|
|
39
|
+
|
|
40
|
+
request = Nucleo::Client.delete(url, MultiJson.dump(request_params))
|
|
41
|
+
|
|
42
|
+
request
|
|
43
|
+
end
|
|
44
|
+
|
|
45
|
+
def self.index(site_id)
|
|
46
|
+
route = Nucleo::Client.routes.route_for('site-page-changes')
|
|
47
|
+
url = route.url_for(site_id: site_id)
|
|
48
|
+
|
|
49
|
+
request = Nucleo::Client.get(url)
|
|
50
|
+
|
|
51
|
+
request
|
|
52
|
+
end
|
|
53
|
+
|
|
54
|
+
end
|
|
55
|
+
end
|
|
56
|
+
end
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
module Nucleo
|
|
2
|
+
module Requests
|
|
3
|
+
class SiteFeed
|
|
4
|
+
def self.retrieve(id, params={})
|
|
5
|
+
included_models = params.fetch(:includes, [])
|
|
6
|
+
includes = "[%s]" % [included_models.join(';')]
|
|
7
|
+
|
|
8
|
+
route = Nucleo::Client.routes.route_for('site')
|
|
9
|
+
url = route.url_for(id: id, includes: includes)
|
|
10
|
+
|
|
11
|
+
request = Nucleo::Client.get(url)
|
|
12
|
+
|
|
13
|
+
request.on(:success) do |resp|
|
|
14
|
+
response_body = resp.body
|
|
15
|
+
|
|
16
|
+
if response_body.has_key?('pages') && response_body['pages'].kind_of?(Array)
|
|
17
|
+
response_body.merge!({ 'pages' => {} })
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
return response_body
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
request.on(:failure) do |resp|
|
|
24
|
+
Nucleo::Client.configuration.logger.error do
|
|
25
|
+
"App Error: %s" % [resp.body]
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
return nil
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
request.on(:server_error) do |resp|
|
|
32
|
+
Nucleo::Client.configuration.logger.error do
|
|
33
|
+
"Server Error: %s" % [resp.body]
|
|
34
|
+
end
|
|
35
|
+
|
|
36
|
+
return nil
|
|
37
|
+
end
|
|
38
|
+
end
|
|
39
|
+
end
|
|
40
|
+
end
|
|
41
|
+
end
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
require File.expand_path('../utilities/status_code_mapper', __FILE__)
|
|
2
|
+
require 'faraday_middleware'
|
|
3
|
+
require 'delegate'
|
|
4
|
+
|
|
5
|
+
module Nucleo
|
|
6
|
+
class Response < SimpleDelegator
|
|
7
|
+
|
|
8
|
+
def initialize(response)
|
|
9
|
+
@_response = response
|
|
10
|
+
end
|
|
11
|
+
|
|
12
|
+
# Returns true if the method is allowed
|
|
13
|
+
#
|
|
14
|
+
# @return [Boolean]
|
|
15
|
+
def allowed?(method)
|
|
16
|
+
self.allowed_methods.include?(method.upcase)
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
def on(*statuses, &block)
|
|
20
|
+
status_code_mapper = Nucleo::Utilities::StatusCodeMapper.new(statuses)
|
|
21
|
+
|
|
22
|
+
return unless status_code_mapper.includes?(@_response.status)
|
|
23
|
+
|
|
24
|
+
if block_given?
|
|
25
|
+
yield(self) and return
|
|
26
|
+
else
|
|
27
|
+
self
|
|
28
|
+
end
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
# Specify the class for Simple Delegator
|
|
32
|
+
#
|
|
33
|
+
# @return [Faraday::Response]
|
|
34
|
+
def __getobj__
|
|
35
|
+
@_response
|
|
36
|
+
end
|
|
37
|
+
|
|
38
|
+
# Extracts the ALLOW header from the HTTP Response
|
|
39
|
+
#
|
|
40
|
+
# @return [String]
|
|
41
|
+
def allow_header
|
|
42
|
+
self.headers.fetch('allow', '')
|
|
43
|
+
end
|
|
44
|
+
|
|
45
|
+
# Returns an array of allowed methods
|
|
46
|
+
#
|
|
47
|
+
# @return [Array]
|
|
48
|
+
def allowed_methods
|
|
49
|
+
self.allow_header.split(',').map(&:strip).map(&:upcase)
|
|
50
|
+
end
|
|
51
|
+
end
|
|
52
|
+
end
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
module Nucleo
|
|
2
|
+
module Utilities
|
|
3
|
+
class StatusCodeMapper
|
|
4
|
+
STATUS_MAP = {
|
|
5
|
+
:failure => (400...500),
|
|
6
|
+
:redirect => (300...400),
|
|
7
|
+
:success => (200...300),
|
|
8
|
+
:server_error => (500...600)
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
# Returns a utility object to map HTTP
|
|
12
|
+
# status codes to their corresponding
|
|
13
|
+
# ranges
|
|
14
|
+
#
|
|
15
|
+
# @param statuses [Array] Symbols or status codes
|
|
16
|
+
#
|
|
17
|
+
# @return [Nucleo::StatusCodeMapper] Instance of the object
|
|
18
|
+
def initialize(*statuses)
|
|
19
|
+
@statuses = Array(statuses).flatten
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
# Returns a collection of all available codes
|
|
23
|
+
#
|
|
24
|
+
# This merges the STATUS_MAP with specified codes
|
|
25
|
+
#
|
|
26
|
+
# @return [Array] Collection of status codes
|
|
27
|
+
def codes
|
|
28
|
+
all_codes = []
|
|
29
|
+
@statuses.inject(all_codes) do |collection,status|
|
|
30
|
+
if status.is_a?(Symbol)
|
|
31
|
+
collection.concat(STATUS_MAP[status].to_a)
|
|
32
|
+
else
|
|
33
|
+
collection.concat([status.to_i])
|
|
34
|
+
end
|
|
35
|
+
|
|
36
|
+
collection
|
|
37
|
+
end
|
|
38
|
+
|
|
39
|
+
Set.new(all_codes).to_a
|
|
40
|
+
end
|
|
41
|
+
|
|
42
|
+
# Checks to see if the codes includes a specific code
|
|
43
|
+
#
|
|
44
|
+
# @param code [String,Integer] An HTTP code
|
|
45
|
+
#
|
|
46
|
+
# @return [Boolean]
|
|
47
|
+
def includes?(code)
|
|
48
|
+
self.codes.include?(code.to_i)
|
|
49
|
+
end
|
|
50
|
+
end
|
|
51
|
+
end
|
|
52
|
+
end
|
|
53
|
+
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
module Nucleo
|
|
2
|
+
class Webhook
|
|
3
|
+
# Registers a new site. Responds true or false if the webhook was successful.
|
|
4
|
+
#
|
|
5
|
+
# @param Hash :site (dump of Site model expected)
|
|
6
|
+
#
|
|
7
|
+
# @return [Boolean]
|
|
8
|
+
def self.register_site(site)
|
|
9
|
+
method = :post
|
|
10
|
+
path = 'sites'
|
|
11
|
+
|
|
12
|
+
# Convert id into site_id (as expected from Site model)
|
|
13
|
+
site['site_id'] = site['id']
|
|
14
|
+
|
|
15
|
+
body = site.to_json
|
|
16
|
+
|
|
17
|
+
begin
|
|
18
|
+
response = Nucleo::request(method, path, body)
|
|
19
|
+
rescue NucleoRequestError => e
|
|
20
|
+
print e.message
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
response
|
|
24
|
+
end
|
|
25
|
+
end
|
|
26
|
+
end
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
# coding: utf-8
|
|
2
|
+
lib = File.expand_path('../lib', __FILE__)
|
|
3
|
+
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
|
4
|
+
require 'nucleo/client/version'
|
|
5
|
+
|
|
6
|
+
Gem::Specification.new do |spec|
|
|
7
|
+
spec.name = "nucleo-client"
|
|
8
|
+
spec.version = Nucleo::Client::VERSION
|
|
9
|
+
spec.authors = ["Nate Klaiber"]
|
|
10
|
+
spec.email = ["nate@deviceindependent.com"]
|
|
11
|
+
spec.summary = %q{ Ruby client for interacting with the Nucleo service.}
|
|
12
|
+
spec.description = %q{ Ruby client for interacting with the Nucleo service.}
|
|
13
|
+
spec.homepage = "https://github.com/quicksprout/ruby-nucleo-client"
|
|
14
|
+
spec.license = "MIT"
|
|
15
|
+
|
|
16
|
+
spec.files = `git ls-files -z`.split("\x0")
|
|
17
|
+
spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
|
|
18
|
+
spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
|
|
19
|
+
spec.require_paths = ["lib"]
|
|
20
|
+
|
|
21
|
+
spec.add_development_dependency("bundler", "~> 1.7")
|
|
22
|
+
spec.add_development_dependency("rake", "~> 10.0")
|
|
23
|
+
spec.add_development_dependency("terminal-table")
|
|
24
|
+
spec.add_development_dependency("rspec")
|
|
25
|
+
spec.add_development_dependency("yard")
|
|
26
|
+
spec.add_development_dependency("webmock")
|
|
27
|
+
|
|
28
|
+
spec.add_dependency('faraday')
|
|
29
|
+
spec.add_dependency('faraday_middleware')
|
|
30
|
+
spec.add_dependency('faraday-detailed_logger')
|
|
31
|
+
spec.add_dependency('multi_json')
|
|
32
|
+
spec.add_dependency('dotenv')
|
|
33
|
+
spec.add_dependency('addressable')
|
|
34
|
+
spec.add_dependency('restless_router')
|
|
35
|
+
end
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
{
|
|
2
|
+
"category": "seo",
|
|
3
|
+
"page_recommendation_id": "e968f4ca1eba27230ec501d68e843b3ed87bfcc9d8a2e17757e166ad0b302661",
|
|
4
|
+
"data": {
|
|
5
|
+
"min_length": 15,
|
|
6
|
+
"identified_at": "2016-10-11T04:05:57.444550",
|
|
7
|
+
"tags": [
|
|
8
|
+
{
|
|
9
|
+
"content_length": 73,
|
|
10
|
+
"full_tag": "<h3>Liking other people’s photos generates more followers and likes for you</h3>\n",
|
|
11
|
+
"tag_content": "Liking other people’s photos generates more followers and likes for you"
|
|
12
|
+
},
|
|
13
|
+
{
|
|
14
|
+
"content_length": 10,
|
|
15
|
+
"full_tag": "<h3>Conclusion</h3>\n",
|
|
16
|
+
"tag_content": "Conclusion"
|
|
17
|
+
},
|
|
18
|
+
{
|
|
19
|
+
"content_length": 8,
|
|
20
|
+
"full_tag": "<h3>Comments</h3>",
|
|
21
|
+
"tag_content": "Comments"
|
|
22
|
+
},
|
|
23
|
+
{
|
|
24
|
+
"content_length": 78,
|
|
25
|
+
"full_tag": "<h3><strong>Free Course:</strong> \"Double Your Traffic<br /> in 30 Days\" <strong>+ Secret Bonus</strong> <br /> (Valued at $300)</h3>\n\t\t\n\t\t",
|
|
26
|
+
"tag_content": "Free Course: \"Double Your Traffic in 30 Days\" + Secret Bonus (Valued at $300)"
|
|
27
|
+
},
|
|
28
|
+
{
|
|
29
|
+
"content_length": 6,
|
|
30
|
+
"full_tag": "<h4 class=\"widget-title widgettitle\">Search</h4>\n",
|
|
31
|
+
"tag_content": "Search"
|
|
32
|
+
},
|
|
33
|
+
{
|
|
34
|
+
"content_length": 9,
|
|
35
|
+
"full_tag": "<h4 class=\"widget-title widgettitle\">Subscribe</h4>\n\t\t\t",
|
|
36
|
+
"tag_content": "Subscribe"
|
|
37
|
+
}
|
|
38
|
+
],
|
|
39
|
+
"last_checked_at": "2016-10-11T04:05:57.444582",
|
|
40
|
+
"points": 1,
|
|
41
|
+
"max_length": 65
|
|
42
|
+
},
|
|
43
|
+
"site_id": 292,
|
|
44
|
+
"executed_at": "2016-10-11T04:05:57.444620",
|
|
45
|
+
"status": "unresolved",
|
|
46
|
+
"context": "page",
|
|
47
|
+
"page_id": "2fe54e1ad6fc42ea86b804dd376e30763efbe53f981d14b2f40ccdf857e749ea",
|
|
48
|
+
"type": "heading_tag_length",
|
|
49
|
+
"page": {
|
|
50
|
+
"path": "/2012/11/19/the-science-of-instagram-how-to-get-more-followers-and-likes",
|
|
51
|
+
"hostname": "www.quicksprout.com",
|
|
52
|
+
"id": "2fe54e1ad6fc42ea86b804dd376e30763efbe53f981d14b2f40ccdf857e749ea",
|
|
53
|
+
"title": "The Science of Instagram: How to Get More Followers and Likes"
|
|
54
|
+
}
|
|
55
|
+
}
|
|
@@ -0,0 +1,149 @@
|
|
|
1
|
+
{
|
|
2
|
+
"category": "seo",
|
|
3
|
+
"page_recommendation_id": "defab3f6a1957c3a3d710c0c7f21a8ede8f07768329e211c32961bcb64aec439",
|
|
4
|
+
"data": {
|
|
5
|
+
"count": 1316,
|
|
6
|
+
"identified_at": "2016-10-11T04:05:59.221997",
|
|
7
|
+
"tags": [
|
|
8
|
+
{
|
|
9
|
+
"content_length": 12,
|
|
10
|
+
"full_tag": "<a href=\"https://www.quicksprout.com/\">Quick Sprout</a>",
|
|
11
|
+
"tag_content": "Quick Sprout"
|
|
12
|
+
},
|
|
13
|
+
{
|
|
14
|
+
"content_length": 4,
|
|
15
|
+
"full_tag": "<a href=\"https://www.quicksprout.com/blog/\">Blog</a>",
|
|
16
|
+
"tag_content": "Blog"
|
|
17
|
+
},
|
|
18
|
+
{
|
|
19
|
+
"content_length": 10,
|
|
20
|
+
"full_tag": "<a href=\"https://www.quicksprout.com/pro/\">Start Here</a>",
|
|
21
|
+
"tag_content": "Start Here"
|
|
22
|
+
},
|
|
23
|
+
{
|
|
24
|
+
"content_length": 10,
|
|
25
|
+
"full_tag": "<a href=\"http://www.quicksprout.com/pro/\">Consulting</a>",
|
|
26
|
+
"tag_content": "Consulting"
|
|
27
|
+
},
|
|
28
|
+
{
|
|
29
|
+
"content_length": 10,
|
|
30
|
+
"full_tag": "<a title=\"University\" href=\"http://www.quicksprout.com/university/\">University</a>",
|
|
31
|
+
"tag_content": "University"
|
|
32
|
+
},
|
|
33
|
+
{
|
|
34
|
+
"content_length": 7,
|
|
35
|
+
"full_tag": "<a href=\"https://www.quicksprout.com/webinar/\">Webinar</a>",
|
|
36
|
+
"tag_content": "Webinar"
|
|
37
|
+
},
|
|
38
|
+
{
|
|
39
|
+
"content_length": 7,
|
|
40
|
+
"full_tag": "<a title=\"Contact\" href=\"https://www.quicksprout.com/contact/\">Contact</a>",
|
|
41
|
+
"tag_content": "Contact"
|
|
42
|
+
},
|
|
43
|
+
{
|
|
44
|
+
"content_length": 68,
|
|
45
|
+
"full_tag": "<a href=\"http://www.quicksprout.com/2007/10/24/the-difference-between-marketing-pr-advertising-and-personal-branding/\">personal brand</a>, but you can use it to promote your business as well.",
|
|
46
|
+
"tag_content": "personal brand, but you can use it to promote your business as well."
|
|
47
|
+
},
|
|
48
|
+
{
|
|
49
|
+
"full_tag": "<a href=\"#\" onclick=\"javascript: document.getElementById('YesGiveMe').submit(); return false;\"></a>"
|
|
50
|
+
},
|
|
51
|
+
{
|
|
52
|
+
"content_length": 28,
|
|
53
|
+
"full_tag": "<a href=\"https://www.quicksprout.com/2012/11/19/the-science-of-instagram-how-to-get-more-followers-and-likes/#comment-137898\">November 19, 2012 at 8:02 AM</a> \n\t\t\t\t\t\t\t",
|
|
54
|
+
"tag_content": "November 19, 2012 at 8:02 AM"
|
|
55
|
+
},
|
|
56
|
+
{
|
|
57
|
+
"content_length": 5,
|
|
58
|
+
"full_tag": "<a rel=\"nofollow\" class=\"comment-reply-link\" href=\"https://www.quicksprout.com/2012/11/19/the-science-of-instagram-how-to-get-more-followers-and-likes/?replytocom=137898#respond\" onclick=\"return addComment.moveForm( "comment-137898", "137898", "respond", "6201" )\" aria-label=\"Reply to Leith\">Reply</a>\t\t",
|
|
59
|
+
"tag_content": "Reply"
|
|
60
|
+
},
|
|
61
|
+
{
|
|
62
|
+
"content_length": 10,
|
|
63
|
+
"full_tag": "<a href=\"http://www.quicksprout.com\" rel=\"external nofollow\" class=\"url\">Neil Patel</a>",
|
|
64
|
+
"tag_content": "Neil Patel"
|
|
65
|
+
},
|
|
66
|
+
{
|
|
67
|
+
"content_length": 28,
|
|
68
|
+
"full_tag": "<a href=\"https://www.quicksprout.com/2012/11/19/the-science-of-instagram-how-to-get-more-followers-and-likes/#comment-137942\">November 19, 2012 at 5:47 PM</a> \n\t\t\t\t\t\t\t",
|
|
69
|
+
"tag_content": "November 19, 2012 at 5:47 PM"
|
|
70
|
+
},
|
|
71
|
+
{
|
|
72
|
+
"content_length": 5,
|
|
73
|
+
"full_tag": "<a rel=\"nofollow\" class=\"comment-reply-link\" href=\"https://www.quicksprout.com/2012/11/19/the-science-of-instagram-how-to-get-more-followers-and-likes/?replytocom=137942#respond\" onclick=\"return addComment.moveForm( "comment-137942", "137942", "respond", "6201" )\" aria-label=\"Reply to Neil Patel\">Reply</a>\t\t",
|
|
74
|
+
"tag_content": "Reply"
|
|
75
|
+
},
|
|
76
|
+
{
|
|
77
|
+
"content_length": 28,
|
|
78
|
+
"full_tag": "<a href=\"https://www.quicksprout.com/2012/11/19/the-science-of-instagram-how-to-get-more-followers-and-likes/#comment-137991\">November 19, 2012 at 8:41 PM</a> \n\t\t\t\t\t\t\t",
|
|
79
|
+
"tag_content": "November 19, 2012 at 8:41 PM"
|
|
80
|
+
},
|
|
81
|
+
{
|
|
82
|
+
"content_length": 5,
|
|
83
|
+
"full_tag": "<a rel=\"nofollow\" class=\"comment-reply-link\" href=\"https://www.quicksprout.com/2012/11/19/the-science-of-instagram-how-to-get-more-followers-and-likes/?replytocom=137991#respond\" onclick=\"return addComment.moveForm( "comment-137991", "137991", "respond", "6201" )\" aria-label=\"Reply to Lorna\">Reply</a>\t\t",
|
|
84
|
+
"tag_content": "Reply"
|
|
85
|
+
},
|
|
86
|
+
{
|
|
87
|
+
"content_length": 10,
|
|
88
|
+
"full_tag": "<a href=\"http://www.quicksprout.com\" rel=\"external nofollow\" class=\"url\">Neil Patel</a>",
|
|
89
|
+
"tag_content": "Neil Patel"
|
|
90
|
+
},
|
|
91
|
+
{
|
|
92
|
+
"content_length": 29,
|
|
93
|
+
"full_tag": "<a href=\"https://www.quicksprout.com/2012/11/19/the-science-of-instagram-how-to-get-more-followers-and-likes/#comment-137998\">November 19, 2012 at 10:39 PM</a> \n\t\t\t\t\t\t\t",
|
|
94
|
+
"tag_content": "November 19, 2012 at 10:39 PM"
|
|
95
|
+
},
|
|
96
|
+
{
|
|
97
|
+
"content_length": 5,
|
|
98
|
+
"full_tag": "<a rel=\"nofollow\" class=\"comment-reply-link\" href=\"https://www.quicksprout.com/2012/11/19/the-science-of-instagram-how-to-get-more-followers-and-likes/?replytocom=137998#respond\" onclick=\"return addComment.moveForm( "comment-137998", "137998", "respond", "6201" )\" aria-label=\"Reply to Neil Patel\">Reply</a>\t\t",
|
|
99
|
+
"tag_content": "Reply"
|
|
100
|
+
},
|
|
101
|
+
{
|
|
102
|
+
"content_length": 10,
|
|
103
|
+
"full_tag": "<a href=\"http://www.quicksprout.com\" rel=\"external nofollow\" class=\"url\">Neil Patel</a>",
|
|
104
|
+
"tag_content": "Neil Patel"
|
|
105
|
+
},
|
|
106
|
+
{
|
|
107
|
+
"content_length": 24,
|
|
108
|
+
"full_tag": "<a href=\"https://www.quicksprout.com/2012/11/19/the-science-of-instagram-how-to-get-more-followers-and-likes/#comment-214516\">April 7, 2013 at 9:42 PM</a> \n\t\t\t\t\t\t\t",
|
|
109
|
+
"tag_content": "April 7, 2013 at 9:42 PM"
|
|
110
|
+
},
|
|
111
|
+
{
|
|
112
|
+
"content_length": 5,
|
|
113
|
+
"full_tag": "<a rel=\"nofollow\" class=\"comment-reply-link\" href=\"https://www.quicksprout.com/2012/11/19/the-science-of-instagram-how-to-get-more-followers-and-likes/?replytocom=214516#respond\" onclick=\"return addComment.moveForm( "comment-214516", "214516", "respond", "6201" )\" aria-label=\"Reply to Neil Patel\">Reply</a>\t\t",
|
|
114
|
+
"tag_content": "Reply"
|
|
115
|
+
},
|
|
116
|
+
{
|
|
117
|
+
"content_length": 27,
|
|
118
|
+
"full_tag": "<a href=\"https://www.quicksprout.com/2012/11/19/the-science-of-instagram-how-to-get-more-followers-and-likes/#comment-2461656\">February 4, 2016 at 3:39 PM</a> \n\t\t\t\t\t\t\t",
|
|
119
|
+
"tag_content": "February 4, 2016 at 3:39 PM"
|
|
120
|
+
},
|
|
121
|
+
{
|
|
122
|
+
"content_length": 5,
|
|
123
|
+
"full_tag": "<a rel=\"nofollow\" class=\"comment-reply-link\" href=\"https://www.quicksprout.com/2012/11/19/the-science-of-instagram-how-to-get-more-followers-and-likes/?replytocom=2461656#respond\" onclick=\"return addComment.moveForm( "comment-2461656", "2461656", "respond", "6201" )\" aria-label=\"Reply to Annamonnika\">Reply</a>\t\t",
|
|
124
|
+
"tag_content": "Reply"
|
|
125
|
+
},
|
|
126
|
+
{
|
|
127
|
+
"content_length": 10,
|
|
128
|
+
"full_tag": "<a href=\"http://www.quicksprout.com\" rel=\"external nofollow\" class=\"url\">Neil Patel</a>",
|
|
129
|
+
"tag_content": "Neil Patel"
|
|
130
|
+
}
|
|
131
|
+
],
|
|
132
|
+
"last_checked_at": "2016-10-11T04:05:59.222022",
|
|
133
|
+
"max_count": 100,
|
|
134
|
+
"points": 5,
|
|
135
|
+
"min_count": 5
|
|
136
|
+
},
|
|
137
|
+
"site_id": 292,
|
|
138
|
+
"executed_at": "2016-10-11T04:05:59.222055",
|
|
139
|
+
"status": "unresolved",
|
|
140
|
+
"context": "page",
|
|
141
|
+
"page_id": "2fe54e1ad6fc42ea86b804dd376e30763efbe53f981d14b2f40ccdf857e749ea",
|
|
142
|
+
"type": "internal_link_count",
|
|
143
|
+
"page": {
|
|
144
|
+
"path": "/2012/11/19/the-science-of-instagram-how-to-get-more-followers-and-likes",
|
|
145
|
+
"hostname": "www.quicksprout.com",
|
|
146
|
+
"id": "2fe54e1ad6fc42ea86b804dd376e30763efbe53f981d14b2f40ccdf857e749ea",
|
|
147
|
+
"title": "The Science of Instagram: How to Get More Followers and Likes"
|
|
148
|
+
}
|
|
149
|
+
}
|