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,80 @@
1
+ require File.expand_path('../metric_period', __FILE__)
2
+
3
+ module Nucleo
4
+ module Models
5
+ class MetricPeriodsComparison
6
+ include Comparable
7
+
8
+ # Creates a new instance of the Metric Periods Comparison domain model.
9
+ #
10
+ # @param attributes [Hash]
11
+ #
12
+ # @return [Nucleo::Models::MetricPeriodsComparison]
13
+ def initialize(attributes={})
14
+ @attributes = attributes
15
+ end
16
+
17
+ # Returns the dimension
18
+ #
19
+ # @return [String]
20
+ def dimension
21
+ @attributes['dimension']
22
+ end
23
+
24
+ # Returns the current period value
25
+ #
26
+ # @return [Float]
27
+ def current_value
28
+ @attributes['current_value'].to_f
29
+ end
30
+
31
+ # Returns the prior period value
32
+ #
33
+ # @return [Float]
34
+ def prior_value
35
+ @attributes['prior_value'].to_f
36
+ end
37
+
38
+ # Returns the percent change
39
+ #
40
+ # @return [Integer]
41
+ def change
42
+ @attributes['change'].to_f
43
+ end
44
+
45
+ # Returns true if there is no change
46
+ #
47
+ # @return [Boolean]
48
+ def no_change?
49
+ self.change == 0
50
+ end
51
+
52
+ # Returns true if there is a positive change
53
+ #
54
+ # @return [Boolean]
55
+ def positive_change?
56
+ self.change > 0
57
+ end
58
+
59
+ # Returns true if the change is negative
60
+ #
61
+ # @return [Boolean]
62
+ def negative_change?
63
+ self.change < 0
64
+ end
65
+
66
+ # Returns the direcction of change
67
+ #
68
+ # @return [String]
69
+ def direction
70
+ if self.positive_change?
71
+ 'up'
72
+ elsif self.no_change?
73
+ 'same'
74
+ elsif self.negative_change?
75
+ 'down'
76
+ end
77
+ end
78
+ end
79
+ end
80
+ end
@@ -0,0 +1,73 @@
1
+ require File.expand_path('../metric_periods_comparison', __FILE__)
2
+
3
+ module Nucleo
4
+ module Models
5
+ class MetricPeriodsComparisons
6
+ include Enumerable
7
+
8
+ # Returns a Metrics Comparison domain model
9
+ #
10
+ # @param first_period [Nucleo::Models::MetricPeriod]
11
+ # @param second_period [Nucleo::Models::MetricPeriod]
12
+ #
13
+ # @return [Nucleo::Models::MetricPeriodComparison]
14
+ def initialize(first_period, second_period)
15
+ @first_period = first_period
16
+ @second_period = second_period
17
+ end
18
+
19
+ def each(&block)
20
+ internal_collection.each(&block)
21
+ end
22
+
23
+ private
24
+ def internal_collection
25
+ grouped_periods.map do |dimension, periods|
26
+ current_period = periods.find(&:current?)
27
+ prior_period = periods.find(&:prior?)
28
+
29
+ attributes = {
30
+ 'dimension' => dimension,
31
+ 'current_value' => 0,
32
+ 'prior_value' => 0,
33
+ 'change' => 0,
34
+ }
35
+
36
+ if current_period
37
+ attributes.merge!('current_value' => current_period.value, 'change' => current_period.change)
38
+ end
39
+
40
+ if prior_period
41
+ attributes.merge!('prior_value' => prior_period.value)
42
+ end
43
+
44
+ Nucleo::Models::MetricPeriodsComparison.new(attributes)
45
+ end
46
+ end
47
+
48
+ def grouped_periods
49
+ all_rows.group_by(&:dimension_name)
50
+ end
51
+
52
+ def first_period
53
+ @first_period
54
+ end
55
+
56
+ def first_period_rows
57
+ first_period.rows
58
+ end
59
+
60
+ def second_period
61
+ @second_period
62
+ end
63
+
64
+ def second_period_rows
65
+ second_period.rows
66
+ end
67
+
68
+ def all_rows
69
+ (first_period_rows.to_a + second_period_rows.to_a)
70
+ end
71
+ end
72
+ end
73
+ end
@@ -0,0 +1,58 @@
1
+ module Nucleo
2
+ module Models
3
+ class MetricPeriodsTotals
4
+ # Returns an instance of the MetricPeriodsTotals domain model
5
+ #
6
+ # These are the totals across both `current_period`
7
+ # and `prior_period`.
8
+ #
9
+ # @param attributes [Hash]
10
+ #
11
+ # @return [Nucleo::Models::MetricPeriodsTotals]
12
+ def initialize(attributes={})
13
+ @attributes = attributes
14
+ end
15
+
16
+ # Returns the metric type for the totals
17
+ #
18
+ # @return [String]
19
+ def metric
20
+ @attributes['metric']
21
+ end
22
+
23
+ # Returns the dimension
24
+ #
25
+ # @return [String]
26
+ def dimension
27
+ @attributes['dimension']
28
+ end
29
+
30
+ # Returns the current period totals
31
+ #
32
+ # @return [Nucleo::Models::MetricPeriodTotals]
33
+ def current_period
34
+ params = {
35
+ 'metric' => self.metric,
36
+ 'dimension' => self.dimension,
37
+ 'period' => @attributes['totals']['current_period']
38
+ }
39
+
40
+ Nucleo::Models::MetricPeriodTotals.new(params)
41
+ end
42
+
43
+ # Returns the prior period totals
44
+ #
45
+ # @return [Nucleo::Models::MetricPeriodTotals]
46
+ def prior_period
47
+ params = {
48
+ 'metric' => self.metric,
49
+ 'dimension' => self.dimension,
50
+ 'period' => @attributes['totals']['prior_period']
51
+ }
52
+
53
+ Nucleo::Models::MetricPeriodTotals.new(params)
54
+ end
55
+ alias :previous_period :prior_period
56
+ end
57
+ end
58
+ end
@@ -0,0 +1,147 @@
1
+ module Nucleo
2
+ module Models
3
+ class Page
4
+ # Return an instance of the Page domain model
5
+ #
6
+ # @param attributes [Hash]
7
+ #
8
+ # @return [Nucleo::Models::Page]
9
+ def initialize(attributes={})
10
+ @attributes = attributes
11
+ end
12
+
13
+ # Returns the ID of the page
14
+ #
15
+ # @return [String]
16
+ def id
17
+ @attributes['id']
18
+ end
19
+
20
+ # Returns the title of the page
21
+ #
22
+ # @return [String]
23
+ def title
24
+ @attributes['title']
25
+ end
26
+
27
+ # Returns the path of the page
28
+ #
29
+ # @return [String]
30
+ def path
31
+ @attributes['path']
32
+ end
33
+
34
+ # Returns the hostname of the page
35
+ #
36
+ # @return [String]
37
+ def hostname
38
+ @attributes['hostname']
39
+ end
40
+
41
+ # Returns the URI of the resolved URL
42
+ #
43
+ # @return [URI]
44
+ def url
45
+ URI(self.resolved_url)
46
+ end
47
+
48
+ # Returns the resolved URL of the page
49
+ #
50
+ # @return [String]
51
+ def resolved_url
52
+ @attributes['resolved_url'].to_s
53
+ end
54
+
55
+ # Returns the date the page was crawled
56
+ #
57
+ # @return [DateTime,nil]
58
+ def crawled_at
59
+ begin
60
+ DateTime.parse(@attributes['crawled_at'])
61
+ rescue
62
+ nil
63
+ end
64
+ end
65
+
66
+ # Returns a set of rules
67
+ #
68
+ # @return [Nucleo::Models::Rules]
69
+ def rules
70
+ Nucleo::Models::Rules.new(@attributes.fetch('rules', []))
71
+ end
72
+
73
+ # Returns a Feeds collection of recommendations for this page
74
+ #
75
+ # @return [Nucleo::Models::Feeds]
76
+ def recommendations
77
+ Nucleo::Models::Feeds.new(@attributes.fetch('recommendations', []))
78
+ end
79
+
80
+ # Returns true if there are any recommendations
81
+ #
82
+ # @return [Boolean]
83
+ def recommendations?
84
+ self.recommendations.any?
85
+ end
86
+
87
+ # Returns a Feeds collection of alerts for this page
88
+ #
89
+ # @return [Nucleo::Models::Feeds]
90
+ def alerts
91
+ Nucleo::Models::Feeds.new(@attributes.fetch('alerts', []))
92
+ end
93
+
94
+ # Returns true if there are any alerts
95
+ #
96
+ # @return [Boolean]
97
+ def alerts?
98
+ self.alerts.any?
99
+ end
100
+
101
+ # Returns a collection of Analytics
102
+ #
103
+ # @return [Array]
104
+ def analytics
105
+ Nucleo::Models::Feeds.new(@attributes.fetch('analytics', []))
106
+ end
107
+
108
+ # Returns true if there are any analytics
109
+ #
110
+ # @return [Boolean]
111
+ def analytics?
112
+ self.analytics.any?
113
+ end
114
+
115
+ # Returns metrics for this page
116
+ #
117
+ # @return [Nucleo::Models::PageMetric]
118
+ def metrics
119
+ Nucleo::Models::PageMetric.new(@attributes.fetch('metrics', []))
120
+ end
121
+
122
+ # Returns true if there are any metrics
123
+ #
124
+ # @return [Boolean]
125
+ def metrics?
126
+ self.metrics.any?
127
+ end
128
+
129
+ # Returns the SeoScore domain model for this page
130
+ #
131
+ # @return [Nucleo::Models::SeoScore]
132
+ def seo_score
133
+ Nucleo::Models::SeoScore.new(seo_score_params)
134
+ end
135
+
136
+ private
137
+ def seo_score_params
138
+ reference = @attributes.fetch('seo_score', {})
139
+
140
+ {
141
+ 'score' => reference['seo_score'],
142
+ 'grade' => reference['seo_grade']
143
+ }
144
+ end
145
+ end
146
+ end
147
+ end
@@ -0,0 +1,27 @@
1
+ require File.expand_path('../feeds', __FILE__)
2
+
3
+ module Nucleo
4
+ module Models
5
+ class PageAlerts
6
+ # Returns an instance of Page Alerts
7
+ #
8
+ # @param attributes [Hash]
9
+ #
10
+ # @return [Nucleo::Models::PageAlerts]
11
+ def initialize(attributes={})
12
+ @attributes = attributes
13
+ end
14
+
15
+ def self.retrieve(id, params={})
16
+ response_body = Nucleo::Requests::PageAlerts.retrieve(id, params)
17
+
18
+ self.new(response_body)
19
+ end
20
+
21
+ def alerts
22
+ Nucleo::Models::Feeds.new(@attributes)
23
+ end
24
+
25
+ end
26
+ end
27
+ end
@@ -0,0 +1,58 @@
1
+ module Nucleo
2
+ module Models
3
+ class PageMetric
4
+ METRIC_NAME = 'ga:pageviews'.freeze
5
+
6
+ # Returns an instance of the PageRank domain model
7
+ #
8
+ # @param attributes [Hash]
9
+ #
10
+ # @return [Nucleo::Models::PageRank]
11
+ def initialize(attributes={})
12
+ @attributes = attributes
13
+ end
14
+
15
+ # Returns the metric value
16
+ #
17
+ # @return [Integer]
18
+ def value
19
+ @attributes[METRIC_NAME].to_i
20
+ end
21
+
22
+ # Returns the change
23
+ #
24
+ # @return [Integer]
25
+ def change
26
+ @attributes[translated_key_name(:change)].to_f
27
+ end
28
+
29
+ # Returns the pct total
30
+ #
31
+ # @return [Integer]
32
+ def pct_total
33
+ @attributes[translated_key_name(:pct_total)].to_f
34
+ end
35
+
36
+ # Returns the rank
37
+ #
38
+ # @return [Integer]
39
+ def rank
40
+ @attributes[translated_key_name(:rank)].to_i
41
+ end
42
+
43
+ # Returns the rank
44
+ #
45
+ # @return [Integer]
46
+ def rank_change
47
+ @attributes[translated_key_name(:rank_change)].to_i
48
+ end
49
+
50
+ private
51
+ def translated_key_name(key)
52
+ key = key.to_s
53
+
54
+ [METRIC_NAME, key].join('_')
55
+ end
56
+ end
57
+ end
58
+ end