status_page_ruby 0.0.1

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