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.
- checksums.yaml +7 -0
- data/.circleci/config.yml +25 -0
- data/.gitignore +3 -0
- data/.rubocop.yml +10 -0
- data/Gemfile +14 -0
- data/Gemfile.lock +61 -0
- data/README.md +53 -0
- data/bin/status-page +6 -0
- data/lib/status_page_ruby.rb +20 -0
- data/lib/status_page_ruby/pages/base.rb +52 -0
- data/lib/status_page_ruby/pages/bitbucket.rb +14 -0
- data/lib/status_page_ruby/pages/cloudflare.rb +29 -0
- data/lib/status_page_ruby/pages/github.rb +19 -0
- data/lib/status_page_ruby/pages/rubygems.rb +14 -0
- data/lib/status_page_ruby/repositories/status.rb +40 -0
- data/lib/status_page_ruby/services/backup_data.rb +15 -0
- data/lib/status_page_ruby/services/build_history_table.rb +32 -0
- data/lib/status_page_ruby/services/build_log_table.rb +14 -0
- data/lib/status_page_ruby/services/build_stats_table.rb +79 -0
- data/lib/status_page_ruby/services/pull_statuses.rb +44 -0
- data/lib/status_page_ruby/services/restore_data.rb +15 -0
- data/lib/status_page_ruby/status.rb +36 -0
- data/lib/status_page_ruby/storage.rb +55 -0
- data/lib/status_page_ruby/version.rb +3 -0
- data/lib/status_page_ruby_cli.rb +76 -0
- data/spec/lib/status_page_ruby/pages/bitbucket_spec.rb +39 -0
- data/spec/lib/status_page_ruby/pages/cloudflare_spec.rb +64 -0
- data/spec/lib/status_page_ruby/pages/github_spec.rb +57 -0
- data/spec/lib/status_page_ruby/pages/rubygems_spec.rb +39 -0
- data/spec/lib/status_page_ruby/repositories/status_spec.rb +124 -0
- data/spec/lib/status_page_ruby/services/backup_data_spec.rb +13 -0
- data/spec/lib/status_page_ruby/services/build_history_table_spec.rb +71 -0
- data/spec/lib/status_page_ruby/services/build_log_table_spec.rb +43 -0
- data/spec/lib/status_page_ruby/services/build_stats_table_spec.rb +72 -0
- data/spec/lib/status_page_ruby/services/pull_statuses_spec.rb +30 -0
- data/spec/lib/status_page_ruby/services/restore_data_spec.rb +13 -0
- data/spec/lib/status_page_ruby/status_spec.rb +65 -0
- data/spec/lib/status_page_ruby/storage_spec.rb +134 -0
- data/spec/spec_helper.rb +15 -0
- data/status_page_ruby.gemspec +22 -0
- 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
data/.rubocop.yml
ADDED
data/Gemfile
ADDED
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
|
+
[](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,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,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
|