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.
Files changed (108) hide show
  1. checksums.yaml +7 -0
  2. data/.env.sample +2 -0
  3. data/.gitignore +16 -0
  4. data/Gemfile +4 -0
  5. data/LICENSE.txt +22 -0
  6. data/README.md +31 -0
  7. data/Rakefile +37 -0
  8. data/lib/nucleo/client.rb +172 -0
  9. data/lib/nucleo/client/version.rb +5 -0
  10. data/lib/nucleo/configuration.rb +83 -0
  11. data/lib/nucleo/configurations.rb +6 -0
  12. data/lib/nucleo/configurations/default.rb +100 -0
  13. data/lib/nucleo/connection.rb +44 -0
  14. data/lib/nucleo/errors.rb +7 -0
  15. data/lib/nucleo/errors/invalid_uri_error.rb +6 -0
  16. data/lib/nucleo/errors/record_not_found.rb +6 -0
  17. data/lib/nucleo/logger.rb +36 -0
  18. data/lib/nucleo/models.rb +50 -0
  19. data/lib/nucleo/models/change_types.rb +10 -0
  20. data/lib/nucleo/models/change_types/base.rb +81 -0
  21. data/lib/nucleo/models/change_types/seo.rb +13 -0
  22. data/lib/nucleo/models/change_types/seo/base.rb +50 -0
  23. data/lib/nucleo/models/change_types/seo/meta_description.rb +10 -0
  24. data/lib/nucleo/models/change_types/seo/page_title.rb +10 -0
  25. data/lib/nucleo/models/changes.rb +50 -0
  26. data/lib/nucleo/models/check_js.rb +41 -0
  27. data/lib/nucleo/models/check_types.rb +11 -0
  28. data/lib/nucleo/models/check_types/base.rb +25 -0
  29. data/lib/nucleo/models/check_types/count.rb +26 -0
  30. data/lib/nucleo/models/check_types/length.rb +26 -0
  31. data/lib/nucleo/models/check_types/not_exists.rb +8 -0
  32. data/lib/nucleo/models/checks.rb +56 -0
  33. data/lib/nucleo/models/concerns.rb +7 -0
  34. data/lib/nucleo/models/concerns/count.rb +57 -0
  35. data/lib/nucleo/models/concerns/length.rb +57 -0
  36. data/lib/nucleo/models/date_range.rb +66 -0
  37. data/lib/nucleo/models/element.rb +40 -0
  38. data/lib/nucleo/models/elements.rb +47 -0
  39. data/lib/nucleo/models/feed.rb +141 -0
  40. data/lib/nucleo/models/feed_types.rb +11 -0
  41. data/lib/nucleo/models/feed_types/analytics.rb +18 -0
  42. data/lib/nucleo/models/feed_types/analytics/base.rb +12 -0
  43. data/lib/nucleo/models/feed_types/analytics/page/channels.rb +61 -0
  44. data/lib/nucleo/models/feed_types/analytics/page/pages.rb +58 -0
  45. data/lib/nucleo/models/feed_types/analytics/page/referrers.rb +61 -0
  46. data/lib/nucleo/models/feed_types/analytics/page/social.rb +61 -0
  47. data/lib/nucleo/models/feed_types/analytics/site/channels.rb +61 -0
  48. data/lib/nucleo/models/feed_types/analytics/site/pages.rb +61 -0
  49. data/lib/nucleo/models/feed_types/analytics/site/referrers.rb +61 -0
  50. data/lib/nucleo/models/feed_types/analytics/site/social.rb +61 -0
  51. data/lib/nucleo/models/feed_types/base.rb +182 -0
  52. data/lib/nucleo/models/feed_types/seo.rb +22 -0
  53. data/lib/nucleo/models/feed_types/seo/page/base.rb +47 -0
  54. data/lib/nucleo/models/feed_types/seo/page/img_alt.rb +90 -0
  55. data/lib/nucleo/models/feed_types/seo/page/meta_description.rb +49 -0
  56. data/lib/nucleo/models/feed_types/seo/page/meta_robots.rb +48 -0
  57. data/lib/nucleo/models/feed_types/seo/page/page_title.rb +48 -0
  58. data/lib/nucleo/models/feed_types/seo/page/seo_summary.rb +53 -0
  59. data/lib/nucleo/models/feed_types/seo/page/summary.rb +52 -0
  60. data/lib/nucleo/models/feed_types/seo/site/base.rb +22 -0
  61. data/lib/nucleo/models/feed_types/seo/site/img_alt.rb +14 -0
  62. data/lib/nucleo/models/feed_types/seo/site/meta_description.rb +14 -0
  63. data/lib/nucleo/models/feed_types/seo/site/meta_robots.rb +14 -0
  64. data/lib/nucleo/models/feed_types/seo/site/page_title.rb +14 -0
  65. data/lib/nucleo/models/feeds.rb +126 -0
  66. data/lib/nucleo/models/metric.rb +54 -0
  67. data/lib/nucleo/models/metric_period.rb +97 -0
  68. data/lib/nucleo/models/metric_period_row.rb +125 -0
  69. data/lib/nucleo/models/metric_period_rows.rb +34 -0
  70. data/lib/nucleo/models/metric_period_totals.rb +121 -0
  71. data/lib/nucleo/models/metric_periods.rb +78 -0
  72. data/lib/nucleo/models/metric_periods_comparison.rb +80 -0
  73. data/lib/nucleo/models/metric_periods_comparisons.rb +73 -0
  74. data/lib/nucleo/models/metric_periods_totals.rb +58 -0
  75. data/lib/nucleo/models/page.rb +147 -0
  76. data/lib/nucleo/models/page_alerts.rb +27 -0
  77. data/lib/nucleo/models/page_metric.rb +58 -0
  78. data/lib/nucleo/models/page_rank.rb +28 -0
  79. data/lib/nucleo/models/pages.rb +40 -0
  80. data/lib/nucleo/models/seo_score.rb +28 -0
  81. data/lib/nucleo/models/site_feed.rb +82 -0
  82. data/lib/nucleo/models/tag.rb +48 -0
  83. data/lib/nucleo/models/tags.rb +35 -0
  84. data/lib/nucleo/requests.rb +14 -0
  85. data/lib/nucleo/requests/analyzer.rb +35 -0
  86. data/lib/nucleo/requests/check_js.rb +56 -0
  87. data/lib/nucleo/requests/feed.rb +58 -0
  88. data/lib/nucleo/requests/page.rb +113 -0
  89. data/lib/nucleo/requests/page_alerts.rb +36 -0
  90. data/lib/nucleo/requests/page_changes.rb +44 -0
  91. data/lib/nucleo/requests/site.rb +26 -0
  92. data/lib/nucleo/requests/site_changes.rb +56 -0
  93. data/lib/nucleo/requests/site_feed.rb +41 -0
  94. data/lib/nucleo/response.rb +52 -0
  95. data/lib/nucleo/utilities.rb +7 -0
  96. data/lib/nucleo/utilities/status_code_mapper.rb +53 -0
  97. data/lib/nucleo/webhook.rb +26 -0
  98. data/nucleo-client.gemspec +35 -0
  99. data/spec/data/models/feed_types/seo/heading_tag_length.json +55 -0
  100. data/spec/data/models/feed_types/seo/internal_link_count.json +149 -0
  101. data/spec/data/models/feed_types/seo/no_follow_link_count.json +142 -0
  102. data/spec/spec_helper.rb +15 -0
  103. data/spec/unit/nucleo/models/concerns/count_spec.rb +103 -0
  104. data/spec/unit/nucleo/models/concerns/length_spec.rb +79 -0
  105. data/spec/unit/nucleo/models/feed_types/analytics/site/pages_no_data_spec.rb +39 -0
  106. data/spec/unit/nucleo/models/metric_periods_comparison_spec.rb +50 -0
  107. data/spec/unit/nucleo/models/metric_periods_comparisons_spec.rb +58 -0
  108. 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,7 @@
1
+ require File.expand_path('../utilities/status_code_mapper', __FILE__)
2
+
3
+ module Nucleo
4
+ module Utilities
5
+ end
6
+ end
7
+
@@ -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&#8217;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>&#13;\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( &quot;comment-137898&quot;, &quot;137898&quot;, &quot;respond&quot;, &quot;6201&quot; )\" 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>&#13;\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( &quot;comment-137942&quot;, &quot;137942&quot;, &quot;respond&quot;, &quot;6201&quot; )\" 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>&#13;\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( &quot;comment-137991&quot;, &quot;137991&quot;, &quot;respond&quot;, &quot;6201&quot; )\" 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>&#13;\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( &quot;comment-137998&quot;, &quot;137998&quot;, &quot;respond&quot;, &quot;6201&quot; )\" 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>&#13;\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( &quot;comment-214516&quot;, &quot;214516&quot;, &quot;respond&quot;, &quot;6201&quot; )\" 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>&#13;\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( &quot;comment-2461656&quot;, &quot;2461656&quot;, &quot;respond&quot;, &quot;6201&quot; )\" 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
+ }