status_page_ruby 0.0.1

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 (41) hide show
  1. checksums.yaml +7 -0
  2. data/.circleci/config.yml +25 -0
  3. data/.gitignore +3 -0
  4. data/.rubocop.yml +10 -0
  5. data/Gemfile +14 -0
  6. data/Gemfile.lock +61 -0
  7. data/README.md +53 -0
  8. data/bin/status-page +6 -0
  9. data/lib/status_page_ruby.rb +20 -0
  10. data/lib/status_page_ruby/pages/base.rb +52 -0
  11. data/lib/status_page_ruby/pages/bitbucket.rb +14 -0
  12. data/lib/status_page_ruby/pages/cloudflare.rb +29 -0
  13. data/lib/status_page_ruby/pages/github.rb +19 -0
  14. data/lib/status_page_ruby/pages/rubygems.rb +14 -0
  15. data/lib/status_page_ruby/repositories/status.rb +40 -0
  16. data/lib/status_page_ruby/services/backup_data.rb +15 -0
  17. data/lib/status_page_ruby/services/build_history_table.rb +32 -0
  18. data/lib/status_page_ruby/services/build_log_table.rb +14 -0
  19. data/lib/status_page_ruby/services/build_stats_table.rb +79 -0
  20. data/lib/status_page_ruby/services/pull_statuses.rb +44 -0
  21. data/lib/status_page_ruby/services/restore_data.rb +15 -0
  22. data/lib/status_page_ruby/status.rb +36 -0
  23. data/lib/status_page_ruby/storage.rb +55 -0
  24. data/lib/status_page_ruby/version.rb +3 -0
  25. data/lib/status_page_ruby_cli.rb +76 -0
  26. data/spec/lib/status_page_ruby/pages/bitbucket_spec.rb +39 -0
  27. data/spec/lib/status_page_ruby/pages/cloudflare_spec.rb +64 -0
  28. data/spec/lib/status_page_ruby/pages/github_spec.rb +57 -0
  29. data/spec/lib/status_page_ruby/pages/rubygems_spec.rb +39 -0
  30. data/spec/lib/status_page_ruby/repositories/status_spec.rb +124 -0
  31. data/spec/lib/status_page_ruby/services/backup_data_spec.rb +13 -0
  32. data/spec/lib/status_page_ruby/services/build_history_table_spec.rb +71 -0
  33. data/spec/lib/status_page_ruby/services/build_log_table_spec.rb +43 -0
  34. data/spec/lib/status_page_ruby/services/build_stats_table_spec.rb +72 -0
  35. data/spec/lib/status_page_ruby/services/pull_statuses_spec.rb +30 -0
  36. data/spec/lib/status_page_ruby/services/restore_data_spec.rb +13 -0
  37. data/spec/lib/status_page_ruby/status_spec.rb +65 -0
  38. data/spec/lib/status_page_ruby/storage_spec.rb +134 -0
  39. data/spec/spec_helper.rb +15 -0
  40. data/status_page_ruby.gemspec +22 -0
  41. metadata +139 -0
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: bd55bc9c106fe50fdf7a3e8d7f59e5ef94858a6c
4
+ data.tar.gz: 6c8a175fe93f2147c718699ac4f88de729c566e4
5
+ SHA512:
6
+ metadata.gz: 6927704153211ea7ebcdfa2dc60b9afacb77000cf53655a43e46400ce9fe5eb1d8dcea75d740e699a6c61833017faee2ab5fd4a295aa3e726f7eb55b88e0c483
7
+ data.tar.gz: 037b0752070f7fd779eac73d5636ab49a0b46618f57ed6c11631ad77602abef50a385c3a54be9ea2629452eda84e3ca85063ed9eb3bbe4e2a32f4f3653d9fb93
@@ -0,0 +1,25 @@
1
+ version: 2
2
+ jobs:
3
+ build:
4
+ docker:
5
+ - image: circleci/ruby:2.4.1
6
+ steps:
7
+ - checkout
8
+ # Restore bundle cache
9
+ - type: cache-restore
10
+ key: status_page_ruby-{{ checksum "Gemfile.lock" }}
11
+
12
+ # Bundle install dependencies
13
+ - run: bundle install --path vendor/bundle
14
+
15
+ # Store bundle cache
16
+ - type: cache-save
17
+ key: status_page_ruby-{{ checksum "Gemfile.lock" }}
18
+ paths:
19
+ - vendor/bundle
20
+
21
+ # Rubocop
22
+ - run: bundle exec rubocop
23
+
24
+ # Unit tests
25
+ - run: bundle exec rspec
data/.gitignore ADDED
@@ -0,0 +1,3 @@
1
+ .idea
2
+ .ruby-version
3
+ .ruby-gemset
data/.rubocop.yml ADDED
@@ -0,0 +1,10 @@
1
+ Style/FrozenStringLiteralComment:
2
+ Enabled: false
3
+ Style/Documentation:
4
+ Enabled: false
5
+ Metrics/LineLength:
6
+ Enabled: true
7
+ Max: 120
8
+ Metrics/BlockLength:
9
+ Exclude:
10
+ - spec/**/*.rb
data/Gemfile ADDED
@@ -0,0 +1,14 @@
1
+ source 'https://rubygems.org'
2
+
3
+ git_source(:github) { |repo_name| "https://github.com/#{repo_name}" }
4
+
5
+ group :test do
6
+ gem 'rspec'
7
+ gem 'timecop'
8
+ end
9
+
10
+ group :development do
11
+ gem 'rubocop'
12
+ end
13
+
14
+ gemspec
data/Gemfile.lock ADDED
@@ -0,0 +1,61 @@
1
+ PATH
2
+ remote: .
3
+ specs:
4
+ status_page_ruby (0.0.1)
5
+ nokogiri (= 1.8.5)
6
+ terminal-table (= 1.8.0)
7
+ thor (= 0.20.0)
8
+
9
+ GEM
10
+ remote: https://rubygems.org/
11
+ specs:
12
+ ast (2.4.0)
13
+ diff-lcs (1.3)
14
+ jaro_winkler (1.5.1)
15
+ mini_portile2 (2.3.0)
16
+ nokogiri (1.8.5)
17
+ mini_portile2 (~> 2.3.0)
18
+ parallel (1.12.1)
19
+ parser (2.5.1.2)
20
+ ast (~> 2.4.0)
21
+ powerpack (0.1.2)
22
+ rainbow (3.0.0)
23
+ rspec (3.8.0)
24
+ rspec-core (~> 3.8.0)
25
+ rspec-expectations (~> 3.8.0)
26
+ rspec-mocks (~> 3.8.0)
27
+ rspec-core (3.8.0)
28
+ rspec-support (~> 3.8.0)
29
+ rspec-expectations (3.8.2)
30
+ diff-lcs (>= 1.2.0, < 2.0)
31
+ rspec-support (~> 3.8.0)
32
+ rspec-mocks (3.8.0)
33
+ diff-lcs (>= 1.2.0, < 2.0)
34
+ rspec-support (~> 3.8.0)
35
+ rspec-support (3.8.0)
36
+ rubocop (0.59.2)
37
+ jaro_winkler (~> 1.5.1)
38
+ parallel (~> 1.10)
39
+ parser (>= 2.5, != 2.5.1.1)
40
+ powerpack (~> 0.1)
41
+ rainbow (>= 2.2.2, < 4.0)
42
+ ruby-progressbar (~> 1.7)
43
+ unicode-display_width (~> 1.0, >= 1.0.1)
44
+ ruby-progressbar (1.10.0)
45
+ terminal-table (1.8.0)
46
+ unicode-display_width (~> 1.1, >= 1.1.1)
47
+ thor (0.20.0)
48
+ timecop (0.9.1)
49
+ unicode-display_width (1.4.0)
50
+
51
+ PLATFORMS
52
+ ruby
53
+
54
+ DEPENDENCIES
55
+ rspec
56
+ rubocop
57
+ status_page_ruby!
58
+ timecop
59
+
60
+ BUNDLED WITH
61
+ 1.16.6
data/README.md ADDED
@@ -0,0 +1,53 @@
1
+ # Status page
2
+
3
+ [![CircleCI](https://circleci.com/gh/knlynda/status-page-ruby.svg?style=svg)](https://circleci.com/gh/knlynda/status-page-ruby)
4
+
5
+ ## Installation
6
+
7
+ Install nokogiri dependencies, follow the link http://www.nokogiri.org/tutorials/installing_nokogiri.html for details.
8
+
9
+ Install gem.
10
+
11
+ ```bash
12
+ gem install status_page_ruby
13
+ ```
14
+
15
+ ## Usage
16
+
17
+ ```bash
18
+ status-page
19
+ ```
20
+
21
+ ```text
22
+ Commands:
23
+ status-page backup --path=PATH # Backups data.
24
+ status-page help [COMMAND] # Describe available commands or one specific command
25
+ status-page history # Display all the data which was gathered.
26
+ status-page live # Pulls, saves and log statuses every 10 seconds.
27
+ status-page pull # Pulls, saves and optionally log statuses.
28
+ status-page restore --path=PATH # Restores data.
29
+ status-page stats # Summarizes the data and displays it.
30
+ ```
31
+
32
+
33
+ ## Testing
34
+
35
+ ### Setup
36
+
37
+ ```bash
38
+ git clone git@github.com:knlynda/status-page-ruby.git
39
+ gem install bundler
40
+ bundle install
41
+ ```
42
+
43
+ ### Run rubocop
44
+
45
+ ```bash
46
+ bundle exec rubocop
47
+ ```
48
+
49
+ ### Run rspec tests
50
+
51
+ ```bash
52
+ bundle exec rspec
53
+ ```
data/bin/status-page ADDED
@@ -0,0 +1,6 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require 'status_page_ruby'
4
+ require 'status_page_ruby_cli'
5
+
6
+ StatusPageRubyCli.start(ARGV)
@@ -0,0 +1,20 @@
1
+ require 'nokogiri'
2
+ require 'open-uri'
3
+ require 'csv'
4
+ require 'thor'
5
+ require 'terminal-table'
6
+ require 'status_page_ruby/version'
7
+ require 'status_page_ruby/status'
8
+ require 'status_page_ruby/storage'
9
+ require 'status_page_ruby/repositories/status'
10
+ require 'status_page_ruby/pages/base'
11
+ require 'status_page_ruby/pages/bitbucket'
12
+ require 'status_page_ruby/pages/cloudflare'
13
+ require 'status_page_ruby/pages/github'
14
+ require 'status_page_ruby/pages/rubygems'
15
+ require 'status_page_ruby/services/backup_data'
16
+ require 'status_page_ruby/services/restore_data'
17
+ require 'status_page_ruby/services/build_log_table'
18
+ require 'status_page_ruby/services/build_history_table'
19
+ require 'status_page_ruby/services/build_stats_table'
20
+ require 'status_page_ruby/services/pull_statuses'
@@ -0,0 +1,52 @@
1
+ module StatusPageRuby
2
+ module Pages
3
+ class Base
4
+ class << self
5
+ attr_reader :url
6
+
7
+ def open
8
+ new(Nokogiri::HTML(OpenURI.open_uri(url)), Time.now.utc.to_i)
9
+ end
10
+
11
+ private
12
+
13
+ def page_url(url)
14
+ @url = url
15
+ end
16
+
17
+ def page_success_message(success_message)
18
+ define_method :success_message do
19
+ success_message
20
+ end
21
+ end
22
+
23
+ def element(name, type, locator)
24
+ define_method :"#{name}_element" do
25
+ document.public_send("at_#{type}", locator)
26
+ end
27
+
28
+ define_method :"has_#{name}_element?" do
29
+ document.public_send(type, locator).size.positive?
30
+ end
31
+ end
32
+ end
33
+
34
+ attr_reader :document, :time
35
+
36
+ def success?
37
+ status == success_message
38
+ end
39
+
40
+ def status
41
+ raise 'Method not implemented.'
42
+ end
43
+
44
+ private
45
+
46
+ def initialize(document, time)
47
+ @document = document
48
+ @time = time
49
+ end
50
+ end
51
+ end
52
+ end
@@ -0,0 +1,14 @@
1
+ module StatusPageRuby
2
+ module Pages
3
+ class Bitbucket < Base
4
+ page_url 'https://status.bitbucket.org/'
5
+ page_success_message 'All Systems Operational'
6
+
7
+ element :status, :css, '.page-status .status'
8
+
9
+ def status
10
+ @status ||= status_element.text.strip
11
+ end
12
+ end
13
+ end
14
+ end
@@ -0,0 +1,29 @@
1
+ module StatusPageRuby
2
+ module Pages
3
+ class Cloudflare < Base
4
+ page_url 'https://www.cloudflarestatus.com/'
5
+ page_success_message 'All Systems Operational'
6
+
7
+ element :status, :css, '.page-status .status'
8
+ element :failed_status, :xpath, <<-XPATH
9
+ //*[@data-component-id]
10
+ //*[contains(@class,"component-status")]
11
+ [not(contains(.,"Re-routed"))]
12
+ [not(contains(.,"Operational"))]
13
+ [not(contains(.,"Partial Outage"))]
14
+ XPATH
15
+
16
+ def status
17
+ @status ||= parse_status
18
+ end
19
+
20
+ private
21
+
22
+ def parse_status
23
+ return status_element.text.strip if has_failed_status_element?
24
+
25
+ success_message
26
+ end
27
+ end
28
+ end
29
+ end
@@ -0,0 +1,19 @@
1
+ module StatusPageRuby
2
+ module Pages
3
+ class Github < Base
4
+ page_url 'https://status.github.com/messages'
5
+ page_success_message 'All systems reporting at 100%'
6
+
7
+ element :status, :css, '.message .title'
8
+ element :time, :css, '.message .time'
9
+
10
+ def status
11
+ @status ||= status_element.text.strip
12
+ end
13
+
14
+ def time
15
+ DateTime.parse(time_element[:datetime].strip).to_time.to_i
16
+ end
17
+ end
18
+ end
19
+ end
@@ -0,0 +1,14 @@
1
+ module StatusPageRuby
2
+ module Pages
3
+ class Rubygems < Base
4
+ page_url 'https://status.rubygems.org/'
5
+ page_success_message 'All Systems Operational'
6
+
7
+ element :status, :css, '.page-status .status'
8
+
9
+ def status
10
+ @status ||= status_element.text.strip
11
+ end
12
+ end
13
+ end
14
+ end
@@ -0,0 +1,40 @@
1
+ module StatusPageRuby
2
+ module Repositories
3
+ class Status
4
+ attr_reader :storage
5
+
6
+ def initialize(storage)
7
+ @storage = storage
8
+ end
9
+
10
+ def exist?(status)
11
+ storage.include?(status.record)
12
+ end
13
+
14
+ def where(service:)
15
+ storage
16
+ .read
17
+ .select { |record| record.first == service }
18
+ .map { |attrs| StatusPageRuby::Status.new(*attrs) }
19
+ end
20
+
21
+ def all
22
+ storage
23
+ .read
24
+ .map { |attrs| StatusPageRuby::Status.new(*attrs) }
25
+ end
26
+
27
+ def create(status)
28
+ return if exist?(status)
29
+
30
+ storage.write(status.record)
31
+ end
32
+
33
+ def create_batch(statuses)
34
+ return if statuses.empty?
35
+
36
+ storage.merge(statuses.map(&:record))
37
+ end
38
+ end
39
+ end
40
+ end
@@ -0,0 +1,15 @@
1
+ module StatusPageRuby
2
+ module Services
3
+ class BackupData
4
+ attr_reader :storage
5
+
6
+ def initialize(storage)
7
+ @storage = storage
8
+ end
9
+
10
+ def call(path)
11
+ storage.copy(path)
12
+ end
13
+ end
14
+ end
15
+ end
@@ -0,0 +1,32 @@
1
+ module StatusPageRuby
2
+ module Services
3
+ class BuildHistoryTable
4
+ HEADINGS = %w[Service Status Time].freeze
5
+
6
+ attr_reader :status_repository
7
+
8
+ def initialize(status_repository)
9
+ @status_repository = status_repository
10
+ end
11
+
12
+ def call(service = nil)
13
+ Terminal::Table.new(
14
+ headings: HEADINGS,
15
+ rows: build_rows(service)
16
+ ).to_s
17
+ end
18
+
19
+ private
20
+
21
+ def build_rows(service)
22
+ find_records(service).map(&:history_record)
23
+ end
24
+
25
+ def find_records(service)
26
+ return status_repository.all if service.nil?
27
+
28
+ status_repository.where(service: service)
29
+ end
30
+ end
31
+ end
32
+ end