nomius 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.
- checksums.yaml +7 -0
- data/.dockerignore +5 -0
- data/.editorconfig +12 -0
- data/.overcommit.yml +29 -0
- data/.rspec +3 -0
- data/.rubocop.yml +27 -0
- data/CHANGELOG.md +5 -0
- data/CODE_OF_CONDUCT.md +133 -0
- data/CONTRIBUTING.md +63 -0
- data/Dockerfile +11 -0
- data/Gemfile +20 -0
- data/LICENSE +21 -0
- data/README.md +297 -0
- data/Rakefile +12 -0
- data/exe/nomius +6 -0
- data/lib/nomius/bulk_checker.rb +39 -0
- data/lib/nomius/checker.rb +30 -0
- data/lib/nomius/cli/command.rb +106 -0
- data/lib/nomius/cli/parser/file_parser/csv_parser.rb +31 -0
- data/lib/nomius/cli/parser/file_parser/txt_parser.rb +40 -0
- data/lib/nomius/cli/parser/file_parser.rb +27 -0
- data/lib/nomius/cli/parser/strings_parser.rb +37 -0
- data/lib/nomius/cli/parser.rb +22 -0
- data/lib/nomius/cli/runner.rb +42 -0
- data/lib/nomius/cli/writer/console_writer.rb +68 -0
- data/lib/nomius/cli/writer/csv_writer.rb +51 -0
- data/lib/nomius/cli.rb +24 -0
- data/lib/nomius/detector/base_domain_name_detector.rb +86 -0
- data/lib/nomius/detector/base_url_detector.rb +46 -0
- data/lib/nomius/detector/dockerhub_detector.rb +26 -0
- data/lib/nomius/detector/domain_com_detector.rb +15 -0
- data/lib/nomius/detector/domain_org_detector.rb +15 -0
- data/lib/nomius/detector/github_detector.rb +26 -0
- data/lib/nomius/detector/npmjs_detector.rb +26 -0
- data/lib/nomius/detector/pypi_detector.rb +26 -0
- data/lib/nomius/detector/rubygems_detector.rb +26 -0
- data/lib/nomius/detector/util/http_requester.rb +78 -0
- data/lib/nomius/detector.rb +28 -0
- data/lib/nomius/logger/silent.rb +31 -0
- data/lib/nomius/logger/verbose.rb +47 -0
- data/lib/nomius/logger.rb +18 -0
- data/lib/nomius/name.rb +26 -0
- data/lib/nomius/status/available.rb +22 -0
- data/lib/nomius/status/base.rb +16 -0
- data/lib/nomius/status/formatter/ascii_mark.rb +24 -0
- data/lib/nomius/status/formatter/mark.rb +24 -0
- data/lib/nomius/status/unavailable.rb +22 -0
- data/lib/nomius/status/unresolved.rb +22 -0
- data/lib/nomius/status.rb +5 -0
- data/lib/nomius/version.rb +5 -0
- data/lib/nomius.rb +13 -0
- metadata +229 -0
@@ -0,0 +1,15 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "uri"
|
4
|
+
require_relative "base_domain_name_detector"
|
5
|
+
|
6
|
+
module Nomius
|
7
|
+
class Detector
|
8
|
+
# Check .org domain name availability
|
9
|
+
class DomainOrgDetector < BaseDomainNameDetector
|
10
|
+
def tld
|
11
|
+
".org"
|
12
|
+
end
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
@@ -0,0 +1,26 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require_relative "base_url_detector"
|
4
|
+
|
5
|
+
module Nomius
|
6
|
+
class Detector
|
7
|
+
# Check name availability for https://github.com/
|
8
|
+
class GithubDetector < BaseURLDetector
|
9
|
+
BASE_URL = "https://github.com"
|
10
|
+
|
11
|
+
def detector_name
|
12
|
+
"GitHub.com"
|
13
|
+
end
|
14
|
+
|
15
|
+
def detector_short_name
|
16
|
+
"GH"
|
17
|
+
end
|
18
|
+
|
19
|
+
private
|
20
|
+
|
21
|
+
def uri
|
22
|
+
"#{BASE_URL}/#{name.name}"
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
@@ -0,0 +1,26 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require_relative "base_url_detector"
|
4
|
+
|
5
|
+
module Nomius
|
6
|
+
class Detector
|
7
|
+
# Check name availability for https://www.npmjs.com/
|
8
|
+
class NpmjsDetector < BaseURLDetector
|
9
|
+
BASE_URL = "https://registry.npmjs.org"
|
10
|
+
|
11
|
+
def detector_name
|
12
|
+
"NPMjs.com"
|
13
|
+
end
|
14
|
+
|
15
|
+
def detector_short_name
|
16
|
+
"npm"
|
17
|
+
end
|
18
|
+
|
19
|
+
private
|
20
|
+
|
21
|
+
def uri
|
22
|
+
"#{BASE_URL}/#{name.name}"
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
@@ -0,0 +1,26 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require_relative "base_url_detector"
|
4
|
+
|
5
|
+
module Nomius
|
6
|
+
class Detector
|
7
|
+
# Check name availability for https://pypi.org/
|
8
|
+
class PypiDetector < BaseURLDetector
|
9
|
+
BASE_URL = "https://pypi.org/project"
|
10
|
+
|
11
|
+
def detector_name
|
12
|
+
"PyPi.org"
|
13
|
+
end
|
14
|
+
|
15
|
+
def detector_short_name
|
16
|
+
"pip"
|
17
|
+
end
|
18
|
+
|
19
|
+
private
|
20
|
+
|
21
|
+
def uri
|
22
|
+
"#{BASE_URL}/#{name.name}"
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
@@ -0,0 +1,26 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require_relative "base_url_detector"
|
4
|
+
|
5
|
+
module Nomius
|
6
|
+
class Detector
|
7
|
+
# Check name availability for https://rubygems.org/
|
8
|
+
class RubygemsDetector < BaseURLDetector
|
9
|
+
BASE_URL = "https://rubygems.org/api/v1/gems"
|
10
|
+
|
11
|
+
def detector_name
|
12
|
+
"RubyGems.org"
|
13
|
+
end
|
14
|
+
|
15
|
+
def detector_short_name
|
16
|
+
"gem"
|
17
|
+
end
|
18
|
+
|
19
|
+
private
|
20
|
+
|
21
|
+
def uri
|
22
|
+
"#{BASE_URL}/#{name.name}"
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
@@ -0,0 +1,78 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "faraday"
|
4
|
+
require "faraday/retry"
|
5
|
+
require "faraday/follow_redirects"
|
6
|
+
|
7
|
+
require_relative "../../version"
|
8
|
+
|
9
|
+
module Nomius
|
10
|
+
class Detector
|
11
|
+
class Util
|
12
|
+
# Encapsulates HTTP request handling.
|
13
|
+
# Using Faraday gem. But could be easily replaced with any other HTTP client.
|
14
|
+
class HTTPRequester
|
15
|
+
# rubocop:disable Lint/EmptyClass
|
16
|
+
class OK; end
|
17
|
+
class NotFound; end
|
18
|
+
class Unresolved; end
|
19
|
+
# rubocop:enable Lint/EmptyClass
|
20
|
+
|
21
|
+
HEADERS = {
|
22
|
+
"User-Agent" => "Nomius/#{Nomius::VERSION}"
|
23
|
+
}.freeze
|
24
|
+
|
25
|
+
FALLBACK_STATUS = Unresolved
|
26
|
+
|
27
|
+
RESPONSE_STATUS_RESOLVER = {
|
28
|
+
200 => OK,
|
29
|
+
404 => NotFound
|
30
|
+
}.freeze
|
31
|
+
|
32
|
+
RETRY_STATUSES = [
|
33
|
+
400, 401, 403, 408, 409, 418, 425, 429,
|
34
|
+
500, 502, 503, 504
|
35
|
+
].freeze
|
36
|
+
|
37
|
+
RETRY_OPTIONS = {
|
38
|
+
max: 5,
|
39
|
+
interval: 1,
|
40
|
+
interval_randomness: 0.5,
|
41
|
+
backoff_factor: 2,
|
42
|
+
retry_statuses: RETRY_STATUSES
|
43
|
+
}.freeze
|
44
|
+
|
45
|
+
attr_reader :uri, :logger
|
46
|
+
|
47
|
+
def self.response_status(uri:, logger:)
|
48
|
+
new(uri: uri, logger: logger).response_status
|
49
|
+
end
|
50
|
+
|
51
|
+
def initialize(uri:, logger:)
|
52
|
+
@uri = uri.to_s
|
53
|
+
@logger = logger
|
54
|
+
end
|
55
|
+
|
56
|
+
def response_status
|
57
|
+
# HEAD request is used to avoid downloading the whole page.
|
58
|
+
response = connection.head
|
59
|
+
|
60
|
+
unless RESPONSE_STATUS_RESOLVER.key?(response.status)
|
61
|
+
logger.log_error(message: uri, details: response.to_hash.to_json)
|
62
|
+
end
|
63
|
+
|
64
|
+
RESPONSE_STATUS_RESOLVER.fetch(response.status, FALLBACK_STATUS)
|
65
|
+
end
|
66
|
+
|
67
|
+
private
|
68
|
+
|
69
|
+
def connection
|
70
|
+
@connection ||= Faraday.new(url: uri, headers: HEADERS) do |faraday|
|
71
|
+
faraday.request :retry, RETRY_OPTIONS
|
72
|
+
faraday.response :follow_redirects
|
73
|
+
end
|
74
|
+
end
|
75
|
+
end
|
76
|
+
end
|
77
|
+
end
|
78
|
+
end
|
@@ -0,0 +1,28 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require_relative "detector/dockerhub_detector"
|
4
|
+
require_relative "detector/domain_com_detector"
|
5
|
+
require_relative "detector/domain_org_detector"
|
6
|
+
require_relative "detector/github_detector"
|
7
|
+
require_relative "detector/npmjs_detector"
|
8
|
+
require_relative "detector/pypi_detector"
|
9
|
+
require_relative "detector/rubygems_detector"
|
10
|
+
|
11
|
+
module Nomius
|
12
|
+
# Detectors
|
13
|
+
class Detector
|
14
|
+
DETECTORS = [
|
15
|
+
DomainComDetector,
|
16
|
+
DomainOrgDetector,
|
17
|
+
GithubDetector,
|
18
|
+
DockerhubDetector,
|
19
|
+
NpmjsDetector,
|
20
|
+
PypiDetector,
|
21
|
+
RubygemsDetector
|
22
|
+
].freeze
|
23
|
+
|
24
|
+
def self.all
|
25
|
+
DETECTORS
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
@@ -0,0 +1,31 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Nomius
|
4
|
+
class Logger
|
5
|
+
# Silent logger
|
6
|
+
class Silent
|
7
|
+
def start_batch_processing(_count)
|
8
|
+
# Intentionally do nothing
|
9
|
+
end
|
10
|
+
|
11
|
+
def batch_record_processing(_name)
|
12
|
+
# Intentionally do nothing
|
13
|
+
yield
|
14
|
+
end
|
15
|
+
|
16
|
+
def log_detector_status
|
17
|
+
# Intentionally do nothing
|
18
|
+
yield
|
19
|
+
end
|
20
|
+
|
21
|
+
def log_info(_message)
|
22
|
+
# Intentionally do nothing
|
23
|
+
end
|
24
|
+
|
25
|
+
def log_error(message: "", details: "")
|
26
|
+
warn message
|
27
|
+
warn details
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
@@ -0,0 +1,47 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "tty-progressbar"
|
4
|
+
require_relative "../status/formatter/mark"
|
5
|
+
|
6
|
+
module Nomius
|
7
|
+
class Logger
|
8
|
+
# Verbose logger
|
9
|
+
class Verbose
|
10
|
+
def start_batch_processing(count)
|
11
|
+
@progress_bar = TTY::ProgressBar.new("[:bar] :current/:total ET::elapsed ETA::eta") do |config|
|
12
|
+
config.total = count
|
13
|
+
config.interval = 5
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
17
|
+
def batch_record_processing(name)
|
18
|
+
log_info("Processing #{name.name}...")
|
19
|
+
result = yield
|
20
|
+
log_info("")
|
21
|
+
progress_bar.advance
|
22
|
+
|
23
|
+
result
|
24
|
+
end
|
25
|
+
|
26
|
+
def log_detector_status
|
27
|
+
status = yield
|
28
|
+
log_info("#{status.detector.detector_short_name} #{Status::Formatter::Mark.for(status)}")
|
29
|
+
|
30
|
+
status
|
31
|
+
end
|
32
|
+
|
33
|
+
def log_info(message)
|
34
|
+
progress_bar.log(message)
|
35
|
+
end
|
36
|
+
|
37
|
+
def log_error(message: "", details: "")
|
38
|
+
warn message
|
39
|
+
warn details
|
40
|
+
end
|
41
|
+
|
42
|
+
private
|
43
|
+
|
44
|
+
attr_reader :progress_bar
|
45
|
+
end
|
46
|
+
end
|
47
|
+
end
|
@@ -0,0 +1,18 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require_relative "logger/silent"
|
4
|
+
require_relative "logger/verbose"
|
5
|
+
|
6
|
+
module Nomius
|
7
|
+
# Logger factory
|
8
|
+
class Logger
|
9
|
+
LOGGER_BY_SILENT = {
|
10
|
+
true => Silent,
|
11
|
+
false => Verbose
|
12
|
+
}.freeze
|
13
|
+
|
14
|
+
def self.for(silent: false)
|
15
|
+
LOGGER_BY_SILENT.fetch(silent).new
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
data/lib/nomius/name.rb
ADDED
@@ -0,0 +1,26 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Nomius
|
4
|
+
# Name object
|
5
|
+
class Name
|
6
|
+
attr_reader :name, :comment
|
7
|
+
|
8
|
+
def self.for(name)
|
9
|
+
return name if name.is_a?(self)
|
10
|
+
|
11
|
+
new(name: name.to_s)
|
12
|
+
end
|
13
|
+
|
14
|
+
def initialize(name:, comment: "")
|
15
|
+
@name = name.to_s.strip.downcase
|
16
|
+
@comment = comment.to_s.strip.downcase
|
17
|
+
validate!
|
18
|
+
end
|
19
|
+
|
20
|
+
private
|
21
|
+
|
22
|
+
def validate!
|
23
|
+
raise ArgumentError, "Name cannot be blank" if name.empty?
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
@@ -0,0 +1,22 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require_relative "base"
|
4
|
+
|
5
|
+
module Nomius
|
6
|
+
module Status
|
7
|
+
# Status for name available.
|
8
|
+
class Available < Base
|
9
|
+
def available?
|
10
|
+
true
|
11
|
+
end
|
12
|
+
|
13
|
+
def unavailalbe?
|
14
|
+
false
|
15
|
+
end
|
16
|
+
|
17
|
+
def unresolved?
|
18
|
+
false
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
@@ -0,0 +1,16 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Nomius
|
4
|
+
module Status
|
5
|
+
# Status for available domains.
|
6
|
+
class Base
|
7
|
+
attr_reader :name, :detector, :exception
|
8
|
+
|
9
|
+
def initialize(name:, detector:, exception: nil)
|
10
|
+
@name = name
|
11
|
+
@detector = detector
|
12
|
+
@exception = exception
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
@@ -0,0 +1,24 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require_relative "../available"
|
4
|
+
require_relative "../unavailable"
|
5
|
+
require_relative "../unresolved"
|
6
|
+
|
7
|
+
module Nomius
|
8
|
+
module Status
|
9
|
+
module Formatter
|
10
|
+
# Generate status text for Status
|
11
|
+
class ASCIIMark
|
12
|
+
STATUS_MAPPER = {
|
13
|
+
Status::Available => "+",
|
14
|
+
Status::Unavailable => "-",
|
15
|
+
Status::Unresolved => "?"
|
16
|
+
}.freeze
|
17
|
+
|
18
|
+
def self.for(status)
|
19
|
+
STATUS_MAPPER.fetch(status.class)
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
@@ -0,0 +1,24 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require_relative "../available"
|
4
|
+
require_relative "../unavailable"
|
5
|
+
require_relative "../unresolved"
|
6
|
+
|
7
|
+
module Nomius
|
8
|
+
module Status
|
9
|
+
module Formatter
|
10
|
+
# Generate status mark for Status
|
11
|
+
class Mark
|
12
|
+
STATUS_MAPPER = {
|
13
|
+
Status::Available => "✅",
|
14
|
+
Status::Unavailable => "❌",
|
15
|
+
Status::Unresolved => "❓"
|
16
|
+
}.freeze
|
17
|
+
|
18
|
+
def self.for(status)
|
19
|
+
STATUS_MAPPER.fetch(status.class)
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
@@ -0,0 +1,22 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require_relative "base"
|
4
|
+
|
5
|
+
module Nomius
|
6
|
+
module Status
|
7
|
+
# Status for name unavailable.
|
8
|
+
class Unavailable < Base
|
9
|
+
def available?
|
10
|
+
false
|
11
|
+
end
|
12
|
+
|
13
|
+
def unavailalbe?
|
14
|
+
true
|
15
|
+
end
|
16
|
+
|
17
|
+
def unresolved?
|
18
|
+
false
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
@@ -0,0 +1,22 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require_relative "base"
|
4
|
+
|
5
|
+
module Nomius
|
6
|
+
module Status
|
7
|
+
# Status for name availability unresolved. Should be checked manually.
|
8
|
+
class Unresolved < Base
|
9
|
+
def available?
|
10
|
+
false
|
11
|
+
end
|
12
|
+
|
13
|
+
def unavailalbe?
|
14
|
+
false
|
15
|
+
end
|
16
|
+
|
17
|
+
def unresolved?
|
18
|
+
true
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
data/lib/nomius.rb
ADDED
@@ -0,0 +1,13 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require_relative "nomius/bulk_checker"
|
4
|
+
require_relative "nomius/checker"
|
5
|
+
require_relative "nomius/detector"
|
6
|
+
require_relative "nomius/logger"
|
7
|
+
require_relative "nomius/name"
|
8
|
+
require_relative "nomius/status"
|
9
|
+
require_relative "nomius/version"
|
10
|
+
|
11
|
+
# Nomius
|
12
|
+
module Nomius
|
13
|
+
end
|