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,28 @@
1
+ module Nucleo
2
+ module Models
3
+ class PageRank
4
+ # Returns an instance of the PageRank domain model
5
+ #
6
+ # @param attributes [Hash]
7
+ #
8
+ # @return [Nucleo::Models::PageRank]
9
+ def initialize(attributes={})
10
+ @attributes = attributes
11
+ end
12
+
13
+ # Returns the numeric rank
14
+ #
15
+ # @return [Integer]
16
+ def rank
17
+ @attributes['rank'].to_i
18
+ end
19
+
20
+ # Returns the numeric rank max
21
+ #
22
+ # @return [Integer]
23
+ def rank_max
24
+ @attributes['rank_max'].to_i
25
+ end
26
+ end
27
+ end
28
+ end
@@ -0,0 +1,40 @@
1
+ module Nucleo
2
+ module Models
3
+ class Pages
4
+ include Enumerable
5
+
6
+ def initialize(collection)
7
+ @collection = Array(collection)
8
+ end
9
+
10
+ def self.all(site_id)
11
+ response_body = Nucleo::Requests::Page.all(site_id)
12
+
13
+ Nucleo::Models::Feed.for_record(response_body)
14
+ end
15
+
16
+ def self.retrieve(site_id, id)
17
+ response_body = Nucleo::Requests::Page.retrieve(site_id, id)
18
+
19
+ Nucleo::Models::Page.new(response_body)
20
+ end
21
+
22
+ def self.retrieve!(site_id, id)
23
+ response_body = Nucleo::Requests::Page.retrieve!(site_id, id)
24
+
25
+ Nucleo::Models::Page.new(response_body)
26
+ end
27
+
28
+ def each(&block)
29
+ internal_collection.each(&block)
30
+ end
31
+
32
+ private
33
+ def internal_collection
34
+ @collection.map do |r|
35
+ Nucleo::Models::Page.new(r)
36
+ end
37
+ end
38
+ end
39
+ end
40
+ end
@@ -0,0 +1,28 @@
1
+ module Nucleo
2
+ module Models
3
+ class SeoScore
4
+ # Returns an instance of the SeoScore domain model
5
+ #
6
+ # @param attributes [Hash]
7
+ #
8
+ # @return [Nucleo::Models::SeoScore]
9
+ def initialize(attributes={})
10
+ @attributes = attributes
11
+ end
12
+
13
+ # Returns the numeric score
14
+ #
15
+ # @return [Integer]
16
+ def score
17
+ @attributes['score'].to_i
18
+ end
19
+
20
+ # Returns an alpha grade
21
+ #
22
+ # @return [String]
23
+ def grade
24
+ @attributes['grade']
25
+ end
26
+ end
27
+ end
28
+ end
@@ -0,0 +1,82 @@
1
+ require File.expand_path('../feeds', __FILE__)
2
+
3
+ module Nucleo
4
+ module Models
5
+ class SiteFeed
6
+ # Returns an instanc eof the Site Feed domain model
7
+ #
8
+ # @param attributes [Hash]
9
+ #
10
+ # @return [Nucleo::Models::SiteFeed]
11
+ def initialize(attributes={})
12
+ @attributes = attributes
13
+ end
14
+
15
+ def self.retrieve(id, params={})
16
+ response_body = Nucleo::Requests::SiteFeed.retrieve(id, params)
17
+
18
+ self.new(response_body)
19
+ end
20
+
21
+ # Returns the Analytics Pages domain model
22
+ #
23
+ # @return [Nucleo::Models::FeedTypes::Analytics::Pages]
24
+ def pages
25
+ if @attributes.has_key?('pages')
26
+ Nucleo::Models::FeedTypes::Analytics::Site::Pages.new(@attributes.fetch('pages', {}))
27
+ else
28
+ nil
29
+ end
30
+ end
31
+
32
+ # Returns true if there is an Analytics Pages domain model
33
+ #
34
+ # @return [Boolean]
35
+ def pages?
36
+ self.pages.present?
37
+ end
38
+
39
+ # Returns the Metrics as Feeds
40
+ #
41
+ # @return [Nucleo::Models::Feeds]
42
+ def metrics
43
+ Nucleo::Models::Feeds.new(@attributes.fetch('metrics', []))
44
+ end
45
+
46
+ # Returns true if there are any Metric feed items
47
+ #
48
+ # @return [Boolean]
49
+ def metrics?
50
+ self.metrics.any?
51
+ end
52
+
53
+ # Returns the Alerts as Feeds
54
+ #
55
+ # @return [Nucleo::Models::Feeds]
56
+ def alerts
57
+ Nucleo::Models::Feeds.new(@attributes.fetch('alerts', []))
58
+ end
59
+
60
+ # Returns true if there are any alert feed items
61
+ #
62
+ # @return [Boolean]
63
+ def alerts?
64
+ self.alerts.any?
65
+ end
66
+
67
+ # Returns the changes as Rules
68
+ #
69
+ # @return [Nucleo::Models::Rules]
70
+ def changes
71
+ Nucleo::Models::Rules.new(@attributes.fetch('changes', []))
72
+ end
73
+
74
+ # Returns true if there are any change rules
75
+ #
76
+ # @return [Boolean]
77
+ def changes?
78
+ self.changes.any?
79
+ end
80
+ end
81
+ end
82
+ end
@@ -0,0 +1,48 @@
1
+ module Nucleo
2
+ module Models
3
+ class Tag
4
+ include Comparable
5
+
6
+ def initialize(attributes={})
7
+ @attributes = attributes
8
+ end
9
+
10
+ def <=>(other)
11
+ self.length <=> other.length
12
+ end
13
+
14
+ # Returns the full tag content
15
+ #
16
+ # @return [String]
17
+ def full_tag
18
+ @attributes['full_tag']
19
+ end
20
+ alias :raw_content :full_tag
21
+
22
+ # Returns the tag content
23
+ #
24
+ # @return [String]
25
+ def tag_content
26
+ @attributes['tag_content']
27
+ end
28
+ alias :content :tag_content
29
+
30
+ # Returns the content length
31
+ #
32
+ # @return [Integer]
33
+ def content_length
34
+ @attributes['content_length'].to_i
35
+ end
36
+ alias :length :content_length
37
+
38
+ # Returns the HTML wrapped snippet
39
+ #
40
+ # @todo: Extract this to a view helper
41
+ #
42
+ # @return [String]
43
+ def snippet
44
+ "<p><code>%s</code></p>" % [CGI.escapeHTML(self.full_tag)]
45
+ end
46
+ end
47
+ end
48
+ end
@@ -0,0 +1,35 @@
1
+ module Nucleo
2
+ module Models
3
+ class Tags
4
+ include Enumerable
5
+
6
+ def initialize(collection)
7
+ @collection = Array(collection)
8
+ end
9
+
10
+ def each(&block)
11
+ internal_collection.each(&block)
12
+ end
13
+
14
+ # Returns true if there is a snipped
15
+ #
16
+ # @return [Boolean]
17
+ def has_snippet?
18
+ self.any?
19
+ end
20
+ alias :snippet? :has_snippet?
21
+
22
+ # Returns the code snippet
23
+ #
24
+ # @return [String]
25
+ def snippet
26
+ self.map(&:snippet).join("\n")
27
+ end
28
+
29
+ private
30
+ def internal_collection
31
+ @collection.map { |r| Nucleo::Models::Tag.new(r) }
32
+ end
33
+ end
34
+ end
35
+ end
@@ -0,0 +1,14 @@
1
+ require File.expand_path('../requests/analyzer', __FILE__)
2
+ require File.expand_path('../requests/page_alerts', __FILE__)
3
+ require File.expand_path('../requests/site_feed', __FILE__)
4
+ require File.expand_path('../requests/site_changes', __FILE__)
5
+ require File.expand_path('../requests/page_changes', __FILE__)
6
+ require File.expand_path('../requests/site', __FILE__)
7
+ require File.expand_path('../requests/feed', __FILE__)
8
+ require File.expand_path('../requests/page', __FILE__)
9
+ require File.expand_path('../requests/check_js', __FILE__)
10
+
11
+ module Nucleo
12
+ module Requests
13
+ end
14
+ end
@@ -0,0 +1,35 @@
1
+ module Nucleo
2
+ module Requests
3
+ class Analyzer
4
+ def self.analyze!(attributes={})
5
+ route = Nucleo::Client.routes.route_for('analyzer')
6
+ url = route.url_for
7
+
8
+ request_params = attributes
9
+
10
+ response = Nucleo::Client.post(url, MultiJson.dump(request_params))
11
+
12
+ unless response.success?
13
+ raise Nucleo::Errors::InvalidUriError.new("URL is invalid")
14
+ end
15
+
16
+ response.body
17
+ end
18
+
19
+ def self.analyze(attributes={})
20
+ route = Nucleo::Client.routes.route_for('analyzer')
21
+ url = route.url_for
22
+
23
+ request_params = attributes
24
+
25
+ response = Nucleo::Client.post(url, MultiJson.dump(request_params))
26
+
27
+ if response.success?
28
+ response.body
29
+ else
30
+ {}
31
+ end
32
+ end
33
+ end
34
+ end
35
+ end
@@ -0,0 +1,56 @@
1
+ module Nucleo
2
+ module Requests
3
+ class CheckJS
4
+
5
+ # Check if a url has the JS installed
6
+ #
7
+ # @param url [String] The url to check
8
+ #
9
+ # @return [JSON]
10
+ def self.retrieve(params={})
11
+ url = params[:url]
12
+
13
+ default_params = {
14
+ :url => url,
15
+ }
16
+
17
+ request_params = default_params.merge!(params)
18
+
19
+ route = Nucleo::Client.routes.route_for('util-checkjs')
20
+ url = route.url_for(request_params)
21
+
22
+ request = Nucleo::Client.get(url)
23
+
24
+ request.on(:success) do |resp|
25
+ response_body = resp.body
26
+
27
+ if response_body.is_a?(Hash) && response_body.has_key?("errorType")
28
+ Nucleo::Client.configuration.logger.error do
29
+ "ERR: %s" % [response_body]
30
+ end
31
+
32
+ return {}
33
+ else
34
+ return response_body
35
+ end
36
+ end
37
+
38
+ request.on(:failure) do |resp|
39
+ Nucleo::Client.configuration.logger.error do
40
+ "App Error: %s" % [resp.body]
41
+ end
42
+
43
+ return {}
44
+ end
45
+
46
+ request.on(:server_error) do |resp|
47
+ Nucleo::Client.configuration.logger.error do
48
+ "Server Error: %s" % [resp.body]
49
+ end
50
+
51
+ return {}
52
+ end
53
+ end
54
+ end
55
+ end
56
+ end
@@ -0,0 +1,58 @@
1
+ module Nucleo
2
+ module Requests
3
+ class Feed
4
+
5
+ # Retrieve a feed with the specified params
6
+ #
7
+ # @param site_id [String,Integer] The ID of the site for the feed
8
+ # @param max_feed_items [Integer] Max number of feed items
9
+ #
10
+ # @return [JSON]
11
+ def self.retrieve(site_id, params={})
12
+
13
+ default_params = {
14
+ :id => site_id,
15
+ :max_feed_items => 10
16
+ }
17
+
18
+ request_params = default_params.merge!(params)
19
+
20
+ route = Nucleo::Client.routes.route_for('site-feed')
21
+ url = route.url_for(request_params)
22
+
23
+ request = Nucleo::Client.get(url)
24
+
25
+ request.on(:success) do |resp|
26
+ response_body = resp.body
27
+
28
+ if response_body.is_a?(Hash) && response_body.has_key?("errorType")
29
+ Nucleo::Client.configuration.logger.error do
30
+ "ERR: %s" % [response_body]
31
+ end
32
+
33
+ return []
34
+ else
35
+ return response_body
36
+ end
37
+ end
38
+
39
+ request.on(:failure) do |resp|
40
+ Nucleo::Client.configuration.logger.error do
41
+ "App Error: %s" % [resp.body]
42
+ end
43
+
44
+ return []
45
+ end
46
+
47
+ request.on(:server_error) do |resp|
48
+ Nucleo::Client.configuration.logger.error do
49
+ "Server Error: %s" % [resp.body]
50
+ end
51
+
52
+ return []
53
+ end
54
+ end
55
+ end
56
+ end
57
+ end
58
+
@@ -0,0 +1,113 @@
1
+ module Nucleo
2
+ module Requests
3
+ class Page
4
+ def self.all(site_id)
5
+ route = Nucleo::Client.routes.route_for('site-pages')
6
+ url = route.url_for(id: site_id)
7
+
8
+ request = Nucleo::Client.get(url)
9
+
10
+ request.on(:success) do |resp|
11
+ response_body = resp.body
12
+
13
+ if response_body.is_a?(Hash) && response_body.has_key?("errorType")
14
+ Nucleo::Client.configuration.logger.error do
15
+ "ERR: %s" % [response_body]
16
+ end
17
+
18
+ return []
19
+ else
20
+ return response_body
21
+ end
22
+ end
23
+
24
+ request.on(:failure) do |resp|
25
+ Nucleo::Client.configuration.logger.error do
26
+ "App Error: %s" % [resp.body]
27
+ end
28
+
29
+ return []
30
+ end
31
+
32
+ request.on(:server_error) do |resp|
33
+ Nucleo::Client.configuration.logger.error do
34
+ "Server Error: %s" % [resp.body]
35
+ end
36
+
37
+ return []
38
+ end
39
+ end
40
+
41
+ def self.retrieve!(site_id, id)
42
+ route = Nucleo::Client.routes.route_for('site-page-detail')
43
+ url = route.url_for(site_id: site_id, id: id)
44
+
45
+ request = Nucleo::Client.get(url)
46
+
47
+ request.on(:success) do |resp|
48
+ response_body = resp.body
49
+
50
+ if response_body.is_a?(Hash) && response_body.has_key?("errorType")
51
+ msg = "Could not page with id %s" % [id]
52
+ raise Nucleo::Errors::RecordNotFound.new(msg) and return
53
+ else
54
+ # We need to merge in the `page` to be the root object
55
+ page_object = response_body.fetch('page', {})
56
+
57
+ response_body = response_body.merge!(page_object)
58
+
59
+ return response_body
60
+ end
61
+ end
62
+
63
+ request.on(:failure, :server_error) do |resp|
64
+ msg = "Could not find page with id %s" % [id]
65
+ raise Nucleo::Errors::RecordNotFound.new(msg) and return
66
+ end
67
+ end
68
+
69
+ def self.retrieve(site_id, id)
70
+ route = Nucleo::Client.routes.route_for('site-page-detail')
71
+ url = route.url_for(site_id: site_id, id: id)
72
+
73
+ request = Nucleo::Client.get(url)
74
+
75
+ request.on(:success) do |resp|
76
+ response_body = resp.body
77
+
78
+ if response_body.is_a?(Hash) && response_body.has_key?("errorType")
79
+ Nucleo::Client.configuration.logger.error do
80
+ "ERR: %s" % [response_body]
81
+ end
82
+
83
+ return []
84
+ else
85
+ # We need to merge in the `page` to be the root object
86
+ page_object = response_body.fetch('page', {})
87
+
88
+ response_body = response_body.merge!(page_object)
89
+
90
+ return response_body
91
+ end
92
+ end
93
+
94
+ request.on(:failure) do |resp|
95
+ Nucleo::Client.configuration.logger.error do
96
+ "App Error: %s" % [resp.body]
97
+ end
98
+
99
+ return []
100
+ end
101
+
102
+ request.on(:server_error) do |resp|
103
+ Nucleo::Client.configuration.logger.error do
104
+ "Server Error: %s" % [resp.body]
105
+ end
106
+
107
+ return []
108
+ end
109
+ end
110
+ end
111
+ end
112
+ end
113
+