miteru 2.1.1 → 2.2.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 +4 -4
- data/lib/miteru/cache.rb +45 -0
- data/lib/miteru/concerns/url_truncatable.rb +24 -0
- data/lib/miteru/config.rb +12 -0
- data/lib/miteru/crawler.rb +20 -23
- data/lib/miteru/downloader.rb +1 -1
- data/lib/miteru/kit.rb +2 -11
- data/lib/miteru/notifiers/base.rb +1 -1
- data/lib/miteru/notifiers/slack.rb +4 -4
- data/lib/miteru/notifiers/urlscan.rb +3 -3
- data/lib/miteru/orchestrator.rb +39 -29
- data/lib/miteru/service.rb +44 -0
- data/lib/miteru/version.rb +1 -1
- data/lib/miteru/website.rb +2 -11
- data/lib/miteru.rb +12 -2
- data/miteru.gemspec +51 -50
- metadata +20 -4
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 3767b21d7f569a43215e2fdc0f83f9fc4f29fe2a4bb11fc3548a5d1657812774
|
4
|
+
data.tar.gz: 7877fb357548c619210ec63f3bd26c61c3fda68dc6d21910aa22fc0d7144ebf1
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: '02480c9a5604e5c7959ae4adb9e3a657d4b59f5c668be51b7d1fe120bd46e5548ecc9a26404d88d001729bf19f4f3d1b1545be80820c0717c0e027b7995030cd'
|
7
|
+
data.tar.gz: f2c1adc686393f3979ccf77e87c1bc5dba9cad9023903620ab61bbf6e6a2a4406dbbdd3ffb9ca73f5297c2135436dfd995f9572085fd9fde02fb5b72eac6032b
|
data/lib/miteru/cache.rb
ADDED
@@ -0,0 +1,45 @@
|
|
1
|
+
require "redis"
|
2
|
+
|
3
|
+
module Miteru
|
4
|
+
class Cache < Service
|
5
|
+
# @return [String]
|
6
|
+
attr_reader :url
|
7
|
+
|
8
|
+
#
|
9
|
+
# @param [String] url
|
10
|
+
#
|
11
|
+
def initialize(url)
|
12
|
+
super()
|
13
|
+
@url = url
|
14
|
+
end
|
15
|
+
|
16
|
+
#
|
17
|
+
# @param [String] key
|
18
|
+
# @param [String] value
|
19
|
+
# @param [Integer. nil] ex
|
20
|
+
#
|
21
|
+
def set(key, value, ex:)
|
22
|
+
value = redis.set("#{cache_prefix}:#{key}", value, ex:)
|
23
|
+
logger.info("Cache:#{key} is set.") if verbose?
|
24
|
+
value
|
25
|
+
end
|
26
|
+
|
27
|
+
#
|
28
|
+
# @param [String] key
|
29
|
+
#
|
30
|
+
def cached?(key)
|
31
|
+
value = redis.exists?("#{cache_prefix}:#{key}")
|
32
|
+
logger.info("Cache:#{key} found.") if verbose?
|
33
|
+
value
|
34
|
+
end
|
35
|
+
|
36
|
+
private
|
37
|
+
|
38
|
+
#
|
39
|
+
# @return [Redis]
|
40
|
+
#
|
41
|
+
def redis
|
42
|
+
@redis ||= Redis.new(url:)
|
43
|
+
end
|
44
|
+
end
|
45
|
+
end
|
@@ -0,0 +1,24 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Miteru
|
4
|
+
module Concerns
|
5
|
+
module UrlTruncatable
|
6
|
+
extend ActiveSupport::Concern
|
7
|
+
|
8
|
+
def decoded_url
|
9
|
+
@decoded_url ||= URI.decode_www_form_component(url)
|
10
|
+
end
|
11
|
+
|
12
|
+
#
|
13
|
+
# @return [String]
|
14
|
+
#
|
15
|
+
def truncated_url
|
16
|
+
@truncated_url ||= decoded_url.truncate(64)
|
17
|
+
end
|
18
|
+
|
19
|
+
def defanged_truncated_url
|
20
|
+
@defanged_truncated_url ||= truncated_url.to_s.gsub(".", "[.]")
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
data/lib/miteru/config.rb
CHANGED
@@ -22,6 +22,9 @@ module Miteru
|
|
22
22
|
sentry_dsn: nil,
|
23
23
|
sentry_trace_sample_rate: 0.25,
|
24
24
|
sidekiq_redis_url: nil,
|
25
|
+
cache_redis_url: nil,
|
26
|
+
cache_ex: nil,
|
27
|
+
cache_prefix: "miteru:cache",
|
25
28
|
slack_channel: "#general",
|
26
29
|
slack_webhook_url: nil,
|
27
30
|
threads: Parallel.processor_count,
|
@@ -39,6 +42,15 @@ module Miteru
|
|
39
42
|
# @return [Float]
|
40
43
|
|
41
44
|
# @!attribute [r] sidekiq_redis_url
|
45
|
+
# @return [String, nil]
|
46
|
+
|
47
|
+
# @!attribute [r] cache_redis_url
|
48
|
+
# @return [String, nil]
|
49
|
+
|
50
|
+
# @!attribute [r] cache_ex
|
51
|
+
# @return [Integer, nil]
|
52
|
+
|
53
|
+
# @!attribute [r] cache_prefix
|
42
54
|
# @return [String]
|
43
55
|
|
44
56
|
# @!attribute [r] http_timeout
|
data/lib/miteru/crawler.rb
CHANGED
@@ -11,49 +11,46 @@ module Miteru
|
|
11
11
|
Try[OpenSSL::SSL::SSLError, ::HTTP::Error, Addressable::URI::InvalidURIError] do
|
12
12
|
info = "Website:#{website.info}."
|
13
13
|
info = info.colorize(:red) if website.kits?
|
14
|
-
|
15
|
-
Miteru.logger.info(info)
|
16
|
-
return unless website.kits?
|
17
|
-
|
18
|
-
notify website
|
19
|
-
|
20
|
-
return unless auto_download?
|
14
|
+
logger.info(info)
|
21
15
|
|
22
16
|
website.kits.each do |kit|
|
23
17
|
downloader = Downloader.new(kit)
|
24
18
|
result = downloader.result
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
Miteru.logger.warn("Kit:#{kit.truncated_url} failed to download - #{result.failure}.")
|
19
|
+
unless result.success?
|
20
|
+
logger.warn("Kit:#{kit.truncated_url} failed to download - #{result.failure}.")
|
21
|
+
next
|
29
22
|
end
|
23
|
+
destination = result.value!
|
24
|
+
logger.info("Kit:#{kit.truncated_url} downloaded as #{destination}.")
|
25
|
+
# Remove downloaded file if auto_download is not allowed
|
26
|
+
FileUtils.rm(destination, force: true) unless auto_download?
|
27
|
+
# Notify the kit
|
28
|
+
notify(kit)
|
30
29
|
end
|
30
|
+
|
31
|
+
# Cache the website
|
32
|
+
cache.set(website.url, website.source, ex: cache_ex) if cache?
|
31
33
|
end.recover { nil }.value!
|
32
34
|
end
|
33
35
|
|
34
36
|
private
|
35
37
|
|
36
|
-
def auto_download?
|
37
|
-
Miteru.config.auto_download
|
38
|
-
end
|
39
|
-
|
40
38
|
#
|
41
|
-
# @param [Miteru::
|
39
|
+
# @param [Miteru::Kit] kit
|
42
40
|
#
|
43
|
-
def notify(
|
41
|
+
def notify(kit)
|
44
42
|
notifiers.each do |notifier|
|
45
|
-
result = notifier.result(
|
43
|
+
result = notifier.result(kit)
|
46
44
|
if result.success?
|
47
|
-
|
45
|
+
logger.info("Notifier:#{notifier.name} succeeded.")
|
48
46
|
else
|
49
|
-
|
47
|
+
logger.warn("Notifier:#{notifier.name} failed - #{result.failure}.")
|
50
48
|
end
|
51
49
|
end
|
52
50
|
end
|
53
51
|
|
54
|
-
|
55
|
-
|
56
|
-
#
|
52
|
+
private
|
53
|
+
|
57
54
|
def notifiers
|
58
55
|
@notifiers ||= Miteru.notifiers.map(&:new)
|
59
56
|
end
|
data/lib/miteru/downloader.rb
CHANGED
data/lib/miteru/kit.rb
CHANGED
@@ -2,6 +2,8 @@
|
|
2
2
|
|
3
3
|
module Miteru
|
4
4
|
class Kit < Service
|
5
|
+
include Concerns::UrlTruncatable
|
6
|
+
|
5
7
|
# @return [String]
|
6
8
|
attr_reader :url
|
7
9
|
|
@@ -85,17 +87,6 @@ module Miteru
|
|
85
87
|
@hostname ||= URI(url).hostname
|
86
88
|
end
|
87
89
|
|
88
|
-
def decoded_url
|
89
|
-
@decoded_url ||= URI.decode_www_form_component(url)
|
90
|
-
end
|
91
|
-
|
92
|
-
#
|
93
|
-
# @return [String]
|
94
|
-
#
|
95
|
-
def truncated_url
|
96
|
-
url.truncate(64)
|
97
|
-
end
|
98
|
-
|
99
90
|
private
|
100
91
|
|
101
92
|
def filename_to_download
|
@@ -77,13 +77,13 @@ module Miteru
|
|
77
77
|
#
|
78
78
|
# Notifiy to Slack
|
79
79
|
#
|
80
|
-
# @param [Miteru::
|
80
|
+
# @param [Miteru::Kit] kit
|
81
81
|
#
|
82
|
-
def call(
|
82
|
+
def call(kit)
|
83
83
|
return unless callable?
|
84
84
|
|
85
|
-
attachment = SlackAttachment.new(
|
86
|
-
notifier.post(text:
|
85
|
+
attachment = SlackAttachment.new(kit.url)
|
86
|
+
notifier.post(text: kit.defanged_truncated_url, attachments: attachment.to_a)
|
87
87
|
end
|
88
88
|
|
89
89
|
def callable?
|
@@ -4,12 +4,12 @@ module Miteru
|
|
4
4
|
module Notifiers
|
5
5
|
class UrlScan < Base
|
6
6
|
#
|
7
|
-
# @param [Miteru::
|
7
|
+
# @param [Miteru::Kit] kit
|
8
8
|
#
|
9
|
-
def call(
|
9
|
+
def call(kit)
|
10
10
|
return unless callable?
|
11
11
|
|
12
|
-
|
12
|
+
submit(kit.decoded_url, source: kit.source)
|
13
13
|
end
|
14
14
|
|
15
15
|
def callable?
|
data/lib/miteru/orchestrator.rb
CHANGED
@@ -3,30 +3,37 @@
|
|
3
3
|
module Miteru
|
4
4
|
class Orchestrator < Service
|
5
5
|
def call
|
6
|
-
|
6
|
+
logger.info("#{non_cached_websites.length} websites loaded in total.") if verbose?
|
7
7
|
|
8
|
-
if
|
9
|
-
|
10
|
-
Jobs::CrawleJob.perform_async(website.url, website.source)
|
11
|
-
Miteru.logger.info("Website:#{website.truncated_url} crawler job queued.") if verbose?
|
12
|
-
end
|
8
|
+
if sidekiq?
|
9
|
+
sidekiq_call
|
13
10
|
else
|
14
|
-
|
15
|
-
|
16
|
-
|
11
|
+
parallel_call
|
12
|
+
end
|
13
|
+
end
|
17
14
|
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
15
|
+
def sidekiq_call
|
16
|
+
non_cached_websites.each do |website|
|
17
|
+
Jobs::CrawleJob.perform_async(website.url, website.source)
|
18
|
+
logger.info("Website:#{website.truncated_url} crawler job queued.") if verbose?
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
22
|
+
def parallel_call
|
23
|
+
logger.info("Use #{threads} thread(s).") if verbose?
|
24
|
+
Parallel.each(non_cached_websites, in_threads: threads) do |website|
|
25
|
+
logger.info("Website:#{website.truncated_url} crawling started.") if verbose?
|
26
|
+
result = Crawler.result(website)
|
27
|
+
if result.success?
|
28
|
+
logger.info("Crawler:#{website.truncated_url} succeeded.")
|
29
|
+
else
|
30
|
+
logger.info("Crawler:#{website.truncated_url} failed - #{result.failure}.")
|
24
31
|
end
|
25
32
|
end
|
26
33
|
end
|
27
34
|
|
28
35
|
#
|
29
|
-
# @return [Array<Miteru::
|
36
|
+
# @return [Array<Miteru::Website>]
|
30
37
|
#
|
31
38
|
def websites
|
32
39
|
@websites ||= [].tap do |out|
|
@@ -34,30 +41,33 @@ module Miteru
|
|
34
41
|
result = feed.result
|
35
42
|
if result.success?
|
36
43
|
websites = result.value!
|
37
|
-
|
44
|
+
logger.info("Feed:#{feed.source} has #{websites.length} websites.") if verbose?
|
38
45
|
out << websites
|
39
46
|
else
|
40
|
-
|
47
|
+
logger.warn("Feed:#{feed.source} failed - #{result.failure}")
|
41
48
|
end
|
42
49
|
end
|
43
50
|
end.flatten.uniq(&:url)
|
44
51
|
end
|
45
52
|
|
46
53
|
#
|
47
|
-
# @return [Array<Miteru::
|
54
|
+
# @return [Array<Miteru::Website>]
|
48
55
|
#
|
49
|
-
def
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
56
|
+
def non_cached_websites
|
57
|
+
@non_cached_websites ||= [].tap do |out|
|
58
|
+
out << if cache?
|
59
|
+
websites.reject { |website| cache.cached?(website.url) }
|
60
|
+
else
|
61
|
+
websites
|
62
|
+
end
|
63
|
+
end.flatten.uniq(&:url)
|
57
64
|
end
|
58
65
|
|
59
|
-
|
60
|
-
|
66
|
+
#
|
67
|
+
# @return [Array<Miteru::Feeds::Base>]
|
68
|
+
#
|
69
|
+
def feeds
|
70
|
+
@feeds ||= Miteru.feeds.map(&:new)
|
61
71
|
end
|
62
72
|
end
|
63
73
|
end
|
data/lib/miteru/service.rb
CHANGED
@@ -24,5 +24,49 @@ module Miteru
|
|
24
24
|
new.result(...)
|
25
25
|
end
|
26
26
|
end
|
27
|
+
|
28
|
+
private
|
29
|
+
|
30
|
+
def auto_download?
|
31
|
+
Miteru.config.auto_download
|
32
|
+
end
|
33
|
+
|
34
|
+
#
|
35
|
+
# @return [SemanticLogger]
|
36
|
+
#
|
37
|
+
def logger
|
38
|
+
Miteru.logger
|
39
|
+
end
|
40
|
+
|
41
|
+
def cache?
|
42
|
+
Miteru.cache?
|
43
|
+
end
|
44
|
+
|
45
|
+
def sidekiq?
|
46
|
+
Miteru.sidekiq?
|
47
|
+
end
|
48
|
+
|
49
|
+
#
|
50
|
+
# @return [Miteru::Cache]
|
51
|
+
#
|
52
|
+
def cache
|
53
|
+
Miteru.cache
|
54
|
+
end
|
55
|
+
|
56
|
+
def threads
|
57
|
+
Miteru.config.threads
|
58
|
+
end
|
59
|
+
|
60
|
+
def verbose?
|
61
|
+
Miteru.config.verbose
|
62
|
+
end
|
63
|
+
|
64
|
+
def cache_prefix
|
65
|
+
Miteru.config.cache_prefix
|
66
|
+
end
|
67
|
+
|
68
|
+
def cache_ex
|
69
|
+
Miteru.config.cache_ex
|
70
|
+
end
|
27
71
|
end
|
28
72
|
end
|
data/lib/miteru/version.rb
CHANGED
data/lib/miteru/website.rb
CHANGED
@@ -4,6 +4,8 @@ require "oga"
|
|
4
4
|
|
5
5
|
module Miteru
|
6
6
|
class Website < Service
|
7
|
+
include Concerns::UrlTruncatable
|
8
|
+
|
7
9
|
# @return [String]
|
8
10
|
attr_reader :url
|
9
11
|
|
@@ -41,17 +43,6 @@ module Miteru
|
|
41
43
|
(href_links + possible_file_links).compact.uniq
|
42
44
|
end
|
43
45
|
|
44
|
-
#
|
45
|
-
# @return [String]
|
46
|
-
#
|
47
|
-
def truncated_url
|
48
|
-
url.truncate(64)
|
49
|
-
end
|
50
|
-
|
51
|
-
def defanged_truncated_url
|
52
|
-
truncated_url.to_s.gsub(".", "[.]")
|
53
|
-
end
|
54
|
-
|
55
46
|
def info
|
56
47
|
"#{defanged_truncated_url} has #{kits.length} kit(s) (Source: #{source})"
|
57
48
|
end
|
data/lib/miteru.rb
CHANGED
@@ -31,8 +31,12 @@ require "miteru/errors"
|
|
31
31
|
# Concerns
|
32
32
|
require "miteru/concerns/database_connectable"
|
33
33
|
require "miteru/concerns/error_unwrappable"
|
34
|
+
require "miteru/concerns/url_truncatable"
|
34
35
|
|
35
36
|
# Core classes
|
37
|
+
require "miteru/service"
|
38
|
+
|
39
|
+
require "miteru/cache"
|
36
40
|
require "miteru/config"
|
37
41
|
require "miteru/http"
|
38
42
|
|
@@ -93,6 +97,14 @@ module Miteru
|
|
93
97
|
env == "development"
|
94
98
|
end
|
95
99
|
|
100
|
+
def cache?
|
101
|
+
!Miteru.config.cache_redis_url.nil?
|
102
|
+
end
|
103
|
+
|
104
|
+
def cache
|
105
|
+
@cache ||= Cache.new(Miteru.config.cache_redis_url)
|
106
|
+
end
|
107
|
+
|
96
108
|
#
|
97
109
|
# @return [Boolean]
|
98
110
|
#
|
@@ -117,8 +129,6 @@ module Miteru
|
|
117
129
|
end
|
118
130
|
|
119
131
|
# Services
|
120
|
-
require "miteru/service"
|
121
|
-
|
122
132
|
require "miteru/crawler"
|
123
133
|
require "miteru/downloader"
|
124
134
|
require "miteru/kit"
|
data/miteru.gemspec
CHANGED
@@ -1,67 +1,68 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
lib = File.expand_path(
|
3
|
+
lib = File.expand_path("lib", __dir__)
|
4
4
|
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
5
|
-
require
|
5
|
+
require "miteru/version"
|
6
6
|
|
7
7
|
Gem::Specification.new do |spec|
|
8
|
-
spec.name =
|
8
|
+
spec.name = "miteru"
|
9
9
|
spec.version = Miteru::VERSION
|
10
|
-
spec.authors = [
|
11
|
-
spec.email = [
|
12
|
-
spec.metadata[
|
10
|
+
spec.authors = ["Manabu Niseki"]
|
11
|
+
spec.email = ["manabu.niseki@gmail.com"]
|
12
|
+
spec.metadata["rubygems_mfa_required"] = "true"
|
13
13
|
|
14
|
-
spec.summary =
|
15
|
-
spec.description =
|
16
|
-
spec.homepage =
|
17
|
-
spec.license =
|
14
|
+
spec.summary = "A phishing kit collector for scavengers"
|
15
|
+
spec.description = "A phishing kit collector for scavengers"
|
16
|
+
spec.homepage = "https://github.com/ninoseki/miteru"
|
17
|
+
spec.license = "MIT"
|
18
18
|
|
19
19
|
# Specify which files should be added to the gem when it is released.
|
20
20
|
# The `git ls-files -z` loads the files in the RubyGem that have been added into git.
|
21
21
|
spec.files = Dir.chdir(File.expand_path(__dir__)) do
|
22
22
|
`git ls-files -z`.split("\x0").reject { |f| f.match(%r{^(test|spec|features)/}) }
|
23
23
|
end
|
24
|
-
spec.bindir =
|
24
|
+
spec.bindir = "exe"
|
25
25
|
spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
|
26
|
-
spec.require_paths = [
|
26
|
+
spec.require_paths = ["lib"]
|
27
27
|
|
28
|
-
spec.add_development_dependency
|
29
|
-
spec.add_development_dependency
|
30
|
-
spec.add_development_dependency
|
31
|
-
spec.add_development_dependency
|
32
|
-
spec.add_development_dependency
|
33
|
-
spec.add_development_dependency
|
34
|
-
spec.add_development_dependency
|
35
|
-
spec.add_development_dependency
|
36
|
-
spec.add_development_dependency
|
37
|
-
spec.add_development_dependency
|
38
|
-
spec.add_development_dependency
|
39
|
-
spec.add_development_dependency
|
40
|
-
spec.add_development_dependency
|
28
|
+
spec.add_development_dependency "bundler", "~> 2.5"
|
29
|
+
spec.add_development_dependency "capybara", "~> 3.40"
|
30
|
+
spec.add_development_dependency "coveralls_reborn", "~> 0.28"
|
31
|
+
spec.add_development_dependency "fuubar", "~> 2.5"
|
32
|
+
spec.add_development_dependency "mysql2", "~> 0.5"
|
33
|
+
spec.add_development_dependency "pg", "~> 1.5"
|
34
|
+
spec.add_development_dependency "rake", "~> 13.1"
|
35
|
+
spec.add_development_dependency "rspec", "~> 3.13"
|
36
|
+
spec.add_development_dependency "simplecov-lcov", "~> 0.8"
|
37
|
+
spec.add_development_dependency "standard", "~> 1.33"
|
38
|
+
spec.add_development_dependency "test-prof", "~> 1.3"
|
39
|
+
spec.add_development_dependency "vcr", "~> 6.2"
|
40
|
+
spec.add_development_dependency "webmock", "~> 3.19"
|
41
41
|
|
42
|
-
spec.add_dependency
|
43
|
-
spec.add_dependency
|
44
|
-
spec.add_dependency
|
45
|
-
spec.add_dependency
|
46
|
-
spec.add_dependency
|
47
|
-
spec.add_dependency
|
48
|
-
spec.add_dependency
|
49
|
-
spec.add_dependency
|
50
|
-
spec.add_dependency
|
51
|
-
spec.add_dependency
|
52
|
-
spec.add_dependency
|
53
|
-
spec.add_dependency
|
54
|
-
spec.add_dependency
|
55
|
-
spec.add_dependency
|
56
|
-
spec.add_dependency
|
57
|
-
spec.add_dependency
|
58
|
-
spec.add_dependency
|
59
|
-
spec.add_dependency
|
60
|
-
spec.add_dependency
|
61
|
-
spec.add_dependency
|
62
|
-
spec.add_dependency
|
63
|
-
spec.add_dependency
|
64
|
-
spec.add_dependency
|
65
|
-
spec.add_dependency
|
66
|
-
spec.add_dependency
|
42
|
+
spec.add_dependency "activerecord", "7.1.3"
|
43
|
+
spec.add_dependency "addressable", "2.8.6"
|
44
|
+
spec.add_dependency "anyway_config", "2.6.3"
|
45
|
+
spec.add_dependency "colorize", "1.1.0"
|
46
|
+
spec.add_dependency "dotenv", "2.8.1"
|
47
|
+
spec.add_dependency "down", "5.4.1"
|
48
|
+
spec.add_dependency "dry-files", "1.1.0"
|
49
|
+
spec.add_dependency "dry-monads", "1.6.0"
|
50
|
+
spec.add_dependency "http", "5.2.0"
|
51
|
+
spec.add_dependency "memo_wise", "1.8.0"
|
52
|
+
spec.add_dependency "oga", "3.4"
|
53
|
+
spec.add_dependency "parallel", "1.24.0"
|
54
|
+
spec.add_dependency "puma", "6.4.2"
|
55
|
+
spec.add_dependency "rack", "3.0.9"
|
56
|
+
spec.add_dependency "rack-session", "2.0.0"
|
57
|
+
spec.add_dependency "rackup", "2.1.0"
|
58
|
+
spec.add_dependency "redis", "5.0.8"
|
59
|
+
spec.add_dependency "semantic_logger", "4.15.0"
|
60
|
+
spec.add_dependency "sentry-ruby", "5.16.1"
|
61
|
+
spec.add_dependency "sentry-sidekiq", "5.16.1"
|
62
|
+
spec.add_dependency "sidekiq", "7.2.1"
|
63
|
+
spec.add_dependency "slack-notifier", "2.4.0"
|
64
|
+
spec.add_dependency "sqlite3", "1.7.2"
|
65
|
+
spec.add_dependency "thor", "1.3.0"
|
66
|
+
spec.add_dependency "thor-hollaback", "0.2.1"
|
67
|
+
spec.add_dependency "uuidtools", "2.2.0"
|
67
68
|
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: miteru
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 2.
|
4
|
+
version: 2.2.1
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Manabu Niseki
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date: 2024-02-
|
11
|
+
date: 2024-02-09 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: bundler
|
@@ -226,14 +226,14 @@ dependencies:
|
|
226
226
|
requirements:
|
227
227
|
- - '='
|
228
228
|
- !ruby/object:Gem::Version
|
229
|
-
version: 2.6.
|
229
|
+
version: 2.6.3
|
230
230
|
type: :runtime
|
231
231
|
prerelease: false
|
232
232
|
version_requirements: !ruby/object:Gem::Requirement
|
233
233
|
requirements:
|
234
234
|
- - '='
|
235
235
|
- !ruby/object:Gem::Version
|
236
|
-
version: 2.6.
|
236
|
+
version: 2.6.3
|
237
237
|
- !ruby/object:Gem::Dependency
|
238
238
|
name: colorize
|
239
239
|
requirement: !ruby/object:Gem::Requirement
|
@@ -416,6 +416,20 @@ dependencies:
|
|
416
416
|
- - '='
|
417
417
|
- !ruby/object:Gem::Version
|
418
418
|
version: 2.1.0
|
419
|
+
- !ruby/object:Gem::Dependency
|
420
|
+
name: redis
|
421
|
+
requirement: !ruby/object:Gem::Requirement
|
422
|
+
requirements:
|
423
|
+
- - '='
|
424
|
+
- !ruby/object:Gem::Version
|
425
|
+
version: 5.0.8
|
426
|
+
type: :runtime
|
427
|
+
prerelease: false
|
428
|
+
version_requirements: !ruby/object:Gem::Requirement
|
429
|
+
requirements:
|
430
|
+
- - '='
|
431
|
+
- !ruby/object:Gem::Version
|
432
|
+
version: 5.0.8
|
419
433
|
- !ruby/object:Gem::Dependency
|
420
434
|
name: semantic_logger
|
421
435
|
requirement: !ruby/object:Gem::Requirement
|
@@ -566,6 +580,7 @@ files:
|
|
566
580
|
- exe/miteru
|
567
581
|
- lefthook.yml
|
568
582
|
- lib/miteru.rb
|
583
|
+
- lib/miteru/cache.rb
|
569
584
|
- lib/miteru/cli/application.rb
|
570
585
|
- lib/miteru/cli/base.rb
|
571
586
|
- lib/miteru/cli/database.rb
|
@@ -575,6 +590,7 @@ files:
|
|
575
590
|
- lib/miteru/commands/web.rb
|
576
591
|
- lib/miteru/concerns/database_connectable.rb
|
577
592
|
- lib/miteru/concerns/error_unwrappable.rb
|
593
|
+
- lib/miteru/concerns/url_truncatable.rb
|
578
594
|
- lib/miteru/config.rb
|
579
595
|
- lib/miteru/crawler.rb
|
580
596
|
- lib/miteru/database.rb
|