nucleo-client 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
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
+ }