useful_utilities 5.4.5
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/README.md +14 -0
- data/Rakefile +21 -0
- data/lib/useful_utilities/api.rb +26 -0
- data/lib/useful_utilities/ar.rb +147 -0
- data/lib/useful_utilities/centos_version.rb +49 -0
- data/lib/useful_utilities/hash.rb +29 -0
- data/lib/useful_utilities/i18n.rb +16 -0
- data/lib/useful_utilities/numeric.rb +52 -0
- data/lib/useful_utilities/redhat_release.rb +72 -0
- data/lib/useful_utilities/size/bit.rb +92 -0
- data/lib/useful_utilities/size/byte.rb +69 -0
- data/lib/useful_utilities/size/cdn_speed.rb +33 -0
- data/lib/useful_utilities/size/frequency.rb +37 -0
- data/lib/useful_utilities/size/percentage.rb +15 -0
- data/lib/useful_utilities/size/standard/binary.rb +69 -0
- data/lib/useful_utilities/size/standard/decimal.rb +69 -0
- data/lib/useful_utilities/size.rb +18 -0
- data/lib/useful_utilities/time.rb +97 -0
- data/lib/useful_utilities/version.rb +3 -0
- data/lib/useful_utilities/yaml.rb +17 -0
- data/lib/useful_utilities.rb +15 -0
- metadata +149 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: e5e4bbec43984ce6756ade1190a5f21e4dfbaf5e
|
4
|
+
data.tar.gz: 236d91abef2bedcfaaab5e49c7c78cc998a5eedd
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 79972ec7576ea4d937a16a113cdf10082c7bad7a0b415b46a6adf56ead972caf76c3edc17286e6640c84b726fc48884726ba276c9647f20358b97b04a4cc94d7
|
7
|
+
data.tar.gz: 35b254e47c6638587ae79491a8eb013cbc39ea5fd5503a668f7847588eee3a8d2af74d32538e7fd52a0bb9f21236b0daf5048f73d4480ac74a4fdc1c92a58cb2
|
data/README.md
ADDED
@@ -0,0 +1,14 @@
|
|
1
|
+
## UsefulUtilities
|
2
|
+
|
3
|
+
A collection of useful utilities
|
4
|
+
|
5
|
+
This package include next tools with new namespaces:
|
6
|
+
|
7
|
+
Api Utilities => UsefulUtilities::Api
|
8
|
+
AR Utilities => UsefulUtilities::AR
|
9
|
+
Hash Utilities => UsefulUtilities::Hash
|
10
|
+
Size Utilities => UsefulUtilities::Size
|
11
|
+
Numeric Utilities => UsefulUtilities::Numeric
|
12
|
+
Time Utilities => UsefulUtilities::Time
|
13
|
+
YAML Utilities => UsefulUtilities::YAML
|
14
|
+
I18n Utilities => UsefulUtilities::I18n
|
data/Rakefile
ADDED
@@ -0,0 +1,21 @@
|
|
1
|
+
#!/usr/bin/env rake
|
2
|
+
|
3
|
+
begin
|
4
|
+
require 'bundler/setup'
|
5
|
+
require 'rubygems'
|
6
|
+
rescue LoadError
|
7
|
+
puts 'You must `gem install bundler` and `bundle install` to run rake tasks'
|
8
|
+
end
|
9
|
+
|
10
|
+
begin
|
11
|
+
require 'rdoc/task'
|
12
|
+
rescue LoadError
|
13
|
+
require 'rdoc/rdoc'
|
14
|
+
require 'rake/rdoctask'
|
15
|
+
RDoc::Task = Rake::RDocTask
|
16
|
+
end
|
17
|
+
|
18
|
+
APP_RAKEFILE = File.expand_path('../spec/dummy/Rakefile', __FILE__)
|
19
|
+
load 'rails/tasks/engine.rake'
|
20
|
+
|
21
|
+
Bundler::GemHelper.install_tasks
|
@@ -0,0 +1,26 @@
|
|
1
|
+
require 'socket'
|
2
|
+
require 'timeout'
|
3
|
+
|
4
|
+
module UsefulUtilities
|
5
|
+
module Api
|
6
|
+
extend self
|
7
|
+
|
8
|
+
RESCUE_PORT_OPEN_EXCEPTIONS = [Errno::ENETUNREACH, Errno::ECONNREFUSED, Errno::EHOSTUNREACH, SocketError, Timeout::Error].freeze
|
9
|
+
|
10
|
+
def convert_limit(value)
|
11
|
+
value == Float::INFINITY ? false : value
|
12
|
+
end
|
13
|
+
|
14
|
+
# checks if a port is open or not on a remote host
|
15
|
+
def port_open?(ip, port, sleep_time: 1, max_attempts: 3)
|
16
|
+
try_to(max_attempts: max_attempts, sleep_time: sleep_time, rescue_what: RESCUE_PORT_OPEN_EXCEPTIONS) do
|
17
|
+
Timeout::timeout(sleep_time) do
|
18
|
+
TCPSocket.new(ip, port).close
|
19
|
+
true
|
20
|
+
end
|
21
|
+
end
|
22
|
+
rescue *RESCUE_PORT_OPEN_EXCEPTIONS
|
23
|
+
false
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
@@ -0,0 +1,147 @@
|
|
1
|
+
require 'active_record'
|
2
|
+
require 'active_support/all'
|
3
|
+
|
4
|
+
module UsefulUtilities
|
5
|
+
module AR
|
6
|
+
module Methods
|
7
|
+
def foreign_key(association_class)
|
8
|
+
reflections.values.find do |reflection|
|
9
|
+
reflection.class_name == association_class.name
|
10
|
+
end.foreign_key
|
11
|
+
end
|
12
|
+
end
|
13
|
+
|
14
|
+
extend self
|
15
|
+
|
16
|
+
NESTED_ASSOCIATIONS = %i( has_one has_many )
|
17
|
+
BASE_ERROR_KEY = :base
|
18
|
+
TYPE_SUFFIX = '%s_type'
|
19
|
+
ID_SUFFIX = '%s_id'
|
20
|
+
|
21
|
+
def value_to_integer(value)
|
22
|
+
return 0 if value.nil?
|
23
|
+
return 0 if value == false
|
24
|
+
return 1 if value == true
|
25
|
+
|
26
|
+
ActiveRecord::Type::Integer.new.type_cast_from_database(value)
|
27
|
+
end
|
28
|
+
|
29
|
+
def value_to_decimal(value)
|
30
|
+
return BigDecimal.new(0) if value.nil?
|
31
|
+
|
32
|
+
ActiveRecord::Type::Decimal.new.type_cast_from_database(value)
|
33
|
+
end
|
34
|
+
|
35
|
+
def value_to_boolean(value)
|
36
|
+
return false if value.nil?
|
37
|
+
|
38
|
+
ActiveRecord::Type::Boolean.new.type_cast_from_database(value)
|
39
|
+
end
|
40
|
+
|
41
|
+
def boolean_to_float(value)
|
42
|
+
value ? 1.0 : 0.0
|
43
|
+
end
|
44
|
+
|
45
|
+
def deep_validation(record)
|
46
|
+
record.valid?
|
47
|
+
nested_associations_validation(record)
|
48
|
+
end
|
49
|
+
|
50
|
+
def nested_associations_validation(record, nested = false)
|
51
|
+
record.class.reflections.each do |name, reflection|
|
52
|
+
next unless NESTED_ASSOCIATIONS.include?(reflection.macro)
|
53
|
+
|
54
|
+
association_records = Array(record.public_send(name))
|
55
|
+
error_key = nested ? BASE_ERROR_KEY : name
|
56
|
+
record.errors.delete(name)
|
57
|
+
|
58
|
+
association_records.each do |nested_record|
|
59
|
+
next unless nested_record.changed?
|
60
|
+
nested_associations_validation(nested_record, :nested)
|
61
|
+
nested_record.errors.full_messages.each { |message| record.errors[error_key] << message }
|
62
|
+
end
|
63
|
+
end
|
64
|
+
end
|
65
|
+
|
66
|
+
def by_polymorphic(scope, key, value)
|
67
|
+
type = to_polymorphic_type(value)
|
68
|
+
type_column, id_column = TYPE_SUFFIX % key, ID_SUFFIX % key
|
69
|
+
scope.where(type_column => type, id_column => value)
|
70
|
+
end
|
71
|
+
|
72
|
+
def to_polymorphic_type(value)
|
73
|
+
klass =
|
74
|
+
if value.is_a?(Class) || value.nil? then value
|
75
|
+
elsif value.respond_to?(:klass) then value.klass
|
76
|
+
else value.class
|
77
|
+
end
|
78
|
+
|
79
|
+
klass.respond_to?(:base_class) ? klass.base_class : klass
|
80
|
+
end
|
81
|
+
|
82
|
+
def [](klass, *columns)
|
83
|
+
columns.map { |column| "#{ klass.table_name }.#{ column }" }.join(', ')
|
84
|
+
end
|
85
|
+
|
86
|
+
def asc(klass, column)
|
87
|
+
"#{ self[klass, column] } ASC"
|
88
|
+
end
|
89
|
+
|
90
|
+
def desc(klass, column)
|
91
|
+
"#{ self[klass, column] } DESC"
|
92
|
+
end
|
93
|
+
|
94
|
+
def older_than(scope, _value)
|
95
|
+
value = _value.is_a?(ActiveRecord::Base) ? _value.id : _value
|
96
|
+
value.present? ? scope.where("#{ self[scope, :id] } < ?", value) : scope
|
97
|
+
end
|
98
|
+
|
99
|
+
def null_to_zero(*args)
|
100
|
+
sql_column =
|
101
|
+
case args.size
|
102
|
+
when 1 then args.first
|
103
|
+
when 2 then self[args[0], args[1]]
|
104
|
+
else
|
105
|
+
raise ArgumentError, "wrong number of arguments (#{ args.size } for 1..2)"
|
106
|
+
end
|
107
|
+
|
108
|
+
"COALESCE(#{ sql_column }, 0)"
|
109
|
+
end
|
110
|
+
|
111
|
+
def ceil(value)
|
112
|
+
"CEILING(#{value})"
|
113
|
+
end
|
114
|
+
|
115
|
+
def sql_sum(*args, result)
|
116
|
+
"SUM(#{ null_to_zero(*args) }) AS #{ result }"
|
117
|
+
end
|
118
|
+
|
119
|
+
# Can be used for not NULL columns only
|
120
|
+
# sum_by_columns(Virtual, :column_1, :column2, column3: :column3_alias...)
|
121
|
+
def sum_by_columns(scope, *all_columns)
|
122
|
+
columns = all_columns.flatten
|
123
|
+
columns_with_aliases = columns.extract_options!
|
124
|
+
|
125
|
+
sql_query =
|
126
|
+
columns.reduce(columns_with_aliases) { |res, column| res.merge!(column => column) }.
|
127
|
+
map { |column, column_alias| "SUM(#{ column }) AS #{ column_alias }" }.join(', ')
|
128
|
+
|
129
|
+
scope.select(sql_query).first
|
130
|
+
end
|
131
|
+
|
132
|
+
def count(table, column, result)
|
133
|
+
"COUNT(#{ self[table, column] }) AS #{ result }"
|
134
|
+
end
|
135
|
+
|
136
|
+
def delete_dependents(owner, self_class, dependent_class)
|
137
|
+
dependent_fk = dependent_class.foreign_key(self_class)
|
138
|
+
self_fk = self_class.foreign_key(owner.class)
|
139
|
+
|
140
|
+
"DELETE #{dependent_class.table_name}
|
141
|
+
FROM #{dependent_class.table_name}
|
142
|
+
INNER JOIN #{self_class.table_name}
|
143
|
+
ON #{self[dependent_class, dependent_fk]} = #{self[self_class, :id]}
|
144
|
+
WHERE #{self[self_class, self_fk]} = #{owner.id}"
|
145
|
+
end
|
146
|
+
end
|
147
|
+
end
|
@@ -0,0 +1,49 @@
|
|
1
|
+
module UsefulUtilities
|
2
|
+
class CentOSVersion
|
3
|
+
attr_reader :version
|
4
|
+
|
5
|
+
def initialize(version)
|
6
|
+
@version = version.to_i
|
7
|
+
end
|
8
|
+
|
9
|
+
class << self
|
10
|
+
def centos5?(*args)
|
11
|
+
new(*args).centos5?
|
12
|
+
end
|
13
|
+
alias_method :five?, :centos5?
|
14
|
+
|
15
|
+
def centos6?(*args)
|
16
|
+
new(*args).centos6?
|
17
|
+
end
|
18
|
+
alias_method :six?, :centos6?
|
19
|
+
|
20
|
+
def centos7?(*args)
|
21
|
+
new(*args).centos7?
|
22
|
+
end
|
23
|
+
alias_method :seven?, :centos7?
|
24
|
+
|
25
|
+
def not_centos5?(*args)
|
26
|
+
new(*args).not_centos5?
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
30
|
+
def centos5?
|
31
|
+
version == 5
|
32
|
+
end
|
33
|
+
alias_method :five?, :centos5?
|
34
|
+
|
35
|
+
def centos6?
|
36
|
+
version == 6
|
37
|
+
end
|
38
|
+
alias_method :six?, :centos6?
|
39
|
+
|
40
|
+
def centos7?
|
41
|
+
version == 7
|
42
|
+
end
|
43
|
+
alias_method :seven?, :centos7?
|
44
|
+
|
45
|
+
def not_centos5?
|
46
|
+
!centos5?
|
47
|
+
end
|
48
|
+
end
|
49
|
+
end
|
@@ -0,0 +1,29 @@
|
|
1
|
+
module UsefulUtilities
|
2
|
+
module Hash
|
3
|
+
extend self
|
4
|
+
|
5
|
+
def sum_values(*list)
|
6
|
+
collect_keys(*list).inject({}) do |result, key|
|
7
|
+
result[key] = 0
|
8
|
+
list.each { |item| result[key] += item[key] if item.has_key?(key) }
|
9
|
+
|
10
|
+
result
|
11
|
+
end
|
12
|
+
end
|
13
|
+
|
14
|
+
def group_by_keys(*list)
|
15
|
+
collect_keys(*list).inject({}) do |result, key|
|
16
|
+
result[key] = []
|
17
|
+
list.each { |item| result[key] << item[key] if item.has_key?(key) }
|
18
|
+
|
19
|
+
result
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
private
|
24
|
+
|
25
|
+
def collect_keys(*list)
|
26
|
+
list.inject([]) { |result, item| result |= item.keys }
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
@@ -0,0 +1,16 @@
|
|
1
|
+
module UsefulUtilities
|
2
|
+
module I18n
|
3
|
+
extend self
|
4
|
+
|
5
|
+
def humanize_type(object)
|
6
|
+
klass = case object
|
7
|
+
when Class then object
|
8
|
+
when object.respond_to?(:klass) then object.klass
|
9
|
+
else
|
10
|
+
object.class
|
11
|
+
end
|
12
|
+
|
13
|
+
klass.respond_to?(:model_name) ? klass.model_name.human : klass.to_s.underscore.humanize
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
@@ -0,0 +1,52 @@
|
|
1
|
+
module UsefulUtilities
|
2
|
+
module Numeric
|
3
|
+
extend self
|
4
|
+
|
5
|
+
ZERO = 0
|
6
|
+
THOUSAND = 1_000
|
7
|
+
MILLION = 1_000_000
|
8
|
+
BILLION = 1_000_000_000
|
9
|
+
|
10
|
+
def positive_or_zero(value)
|
11
|
+
(value > ZERO) ? value : ZERO
|
12
|
+
end
|
13
|
+
|
14
|
+
def float_or_integer(value)
|
15
|
+
value == value.to_i ? value.to_i : value
|
16
|
+
end
|
17
|
+
|
18
|
+
def to_decimal(value, scale: nil)
|
19
|
+
result = value.to_f.to_d
|
20
|
+
|
21
|
+
scale ? result.round(scale) : result
|
22
|
+
end
|
23
|
+
|
24
|
+
# @note: used SI metric prefixes http://en.wikipedia.org/wiki/SI_prefix
|
25
|
+
def to_kilo(value, unit)
|
26
|
+
if unit == :M then value * THOUSAND
|
27
|
+
elsif unit == :G then value * MILLION
|
28
|
+
else unsupported_unit!(unit)
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
def to_giga(value, unit)
|
33
|
+
if unit == :k then value.fdiv(MILLION)
|
34
|
+
elsif unit == :M then value.fdiv(THOUSAND)
|
35
|
+
else unsupported_unit!(unit)
|
36
|
+
end
|
37
|
+
end
|
38
|
+
|
39
|
+
def to_number(value, unit)
|
40
|
+
if unit == :M then value * MILLION
|
41
|
+
elsif unit == :G then value * BILLION
|
42
|
+
else unsupported_unit!(unit)
|
43
|
+
end
|
44
|
+
end
|
45
|
+
|
46
|
+
private
|
47
|
+
|
48
|
+
def unsupported_unit!(unit)
|
49
|
+
raise ArgumentError.new("Unsupported unit - #{ unit }")
|
50
|
+
end
|
51
|
+
end
|
52
|
+
end
|
@@ -0,0 +1,72 @@
|
|
1
|
+
module UsefulUtilities
|
2
|
+
class RedhatRelease
|
3
|
+
LEGACY_DISTRO_TEMPLATE = 'centos%{major_version}'.freeze
|
4
|
+
|
5
|
+
VERSION_SEPARATOR = '.'.freeze # this may change to "dot" and "hyphen" if we allow not only final releases(beta, custom git builds, etc)
|
6
|
+
VERSION_SEPARATOR_REGEXP = Regexp.escape(VERSION_SEPARATOR).freeze # regexp to match single "dot" character
|
7
|
+
|
8
|
+
VERSION_REGEXP = %r{ # /etc/redhat-release samples: "CentOS Linux release 7.1.1503 (Core)", "Red Hat Enterprise Linux Server release 7.2 (Maipo)"
|
9
|
+
(?<=[[:space:]]) # positive lookbehind assertion: ensures that the preceding character matches single "space" character, but doesn't include this character in the matched text
|
10
|
+
(?<major_version>[[:digit:]]) # :major_version named capture group; it matches single digits
|
11
|
+
#{VERSION_SEPARATOR_REGEXP} # regexp for separator of version parts
|
12
|
+
(?<minor_version>[[:digit:]]+) # :minor_version named capture group; it matches one or more sequential digits
|
13
|
+
(?: # grouping without capturing; "monthstamp" version part don't exist for versions of Centos older then 7
|
14
|
+
#{VERSION_SEPARATOR_REGEXP} # regexp for separator of version parts
|
15
|
+
(?<monthstamp>[[:digit:]]{4}) # :monthstamp named capture group; it matches 4 sequential digits
|
16
|
+
)? # zero or one times quantifier(repetition metacharacter)
|
17
|
+
(?=[[:space:]]) # positive lookahead assertion: ensures that the following character matches single "space" character, but doesn't include this character in the matched text
|
18
|
+
}x.freeze
|
19
|
+
|
20
|
+
DEFAULT_VERSION_ARR = [6, 0].freeze
|
21
|
+
|
22
|
+
attr_reader :release_string
|
23
|
+
|
24
|
+
def initialize(release_string)
|
25
|
+
@release_string = release_string.to_s
|
26
|
+
end
|
27
|
+
|
28
|
+
def self.major_version(*args)
|
29
|
+
new(*args).major_version
|
30
|
+
end
|
31
|
+
|
32
|
+
def self.legacy_distro(ver)
|
33
|
+
LEGACY_DISTRO_TEMPLATE % { major_version: ver }
|
34
|
+
end
|
35
|
+
|
36
|
+
def major_version
|
37
|
+
version_arr[0]
|
38
|
+
end
|
39
|
+
|
40
|
+
def minor_version
|
41
|
+
version_arr[1]
|
42
|
+
end
|
43
|
+
|
44
|
+
def monthstamp
|
45
|
+
version_arr[2]
|
46
|
+
end
|
47
|
+
|
48
|
+
def version_string
|
49
|
+
version_arr.join(VERSION_SEPARATOR)
|
50
|
+
end
|
51
|
+
|
52
|
+
private
|
53
|
+
|
54
|
+
def version_arr
|
55
|
+
@version_arr ||= version_match.present? ? match_version_arr : DEFAULT_VERSION_ARR
|
56
|
+
end
|
57
|
+
|
58
|
+
def match_version_arr
|
59
|
+
@match_version_arr ||= [
|
60
|
+
version_match[:major_version],
|
61
|
+
version_match[:minor_version],
|
62
|
+
version_match[:monthstamp]
|
63
|
+
].compact.map(&:to_i)
|
64
|
+
end
|
65
|
+
|
66
|
+
def version_match
|
67
|
+
return @version_match if defined?(@version_match)
|
68
|
+
|
69
|
+
@version_match = VERSION_REGEXP.match(release_string)
|
70
|
+
end
|
71
|
+
end
|
72
|
+
end
|
@@ -0,0 +1,92 @@
|
|
1
|
+
require_relative 'standard/decimal'
|
2
|
+
|
3
|
+
module UsefulUtilities
|
4
|
+
module Size
|
5
|
+
module Bit
|
6
|
+
# @note: used SI standard http://en.wikipedia.org/wiki/Binary_prefix
|
7
|
+
# Decimal
|
8
|
+
# 1 K = 1000
|
9
|
+
include UsefulUtilities::Size::Standard::Decimal
|
10
|
+
|
11
|
+
def to_terabits(size, unit)
|
12
|
+
to_tera(size, bit_prefix(unit))
|
13
|
+
end
|
14
|
+
|
15
|
+
def to_gigabits(size, unit)
|
16
|
+
to_giga(size, bit_prefix(unit))
|
17
|
+
end
|
18
|
+
|
19
|
+
def to_megabits(size, unit)
|
20
|
+
to_mega(size, bit_prefix(unit))
|
21
|
+
end
|
22
|
+
|
23
|
+
def to_kilobits(size, unit)
|
24
|
+
to_kilo(size, bit_prefix(unit))
|
25
|
+
end
|
26
|
+
|
27
|
+
def to_bits(size, unit)
|
28
|
+
to_decimal_bi(size, bit_prefix(unit))
|
29
|
+
end
|
30
|
+
|
31
|
+
# Convert bits to manually defined format
|
32
|
+
# by using parameter 'unit'
|
33
|
+
# ATTENTION: by default round is eq to 3 digits
|
34
|
+
def bits_to_human_size(size, unit, rounder = 3)
|
35
|
+
case unit
|
36
|
+
when :bit then size.round(rounder)
|
37
|
+
when :kbit then to_kilobits(size, :bit).round(rounder)
|
38
|
+
when :Mbit then to_megabits(size, :bit).round(rounder)
|
39
|
+
when :Gbit then to_gigabits(size, :bit).round(rounder)
|
40
|
+
when :Tbit then to_terabits(size, :bit).round(rounder)
|
41
|
+
else unsupported_unit!(unit)
|
42
|
+
end
|
43
|
+
end
|
44
|
+
|
45
|
+
# Ignore any fractional part of the number
|
46
|
+
# Bit can be only integer !!!
|
47
|
+
def suitable_unit_for_bits(value)
|
48
|
+
return not_integer!(value) unless value.is_a?(Integer)
|
49
|
+
return not_positive_integer!(value) unless value > -1
|
50
|
+
|
51
|
+
if value.to_s.length <= 3 then :bit
|
52
|
+
elsif value.to_s.length <= 6 then :kbit
|
53
|
+
elsif value.to_s.length <= 9 then :Mbit
|
54
|
+
elsif value.to_s.length <= 12 then :Gbit
|
55
|
+
else :Tbit
|
56
|
+
end
|
57
|
+
end
|
58
|
+
|
59
|
+
def bits_per_sec_to_human_readable(value_in_bits)
|
60
|
+
unit = suitable_unit_for_bits(value_in_bits)
|
61
|
+
value = bits_to_human_size(value_in_bits, unit.to_sym)
|
62
|
+
|
63
|
+
"#{value} #{unit}/s"
|
64
|
+
end
|
65
|
+
|
66
|
+
private
|
67
|
+
|
68
|
+
def bit_prefix(unit)
|
69
|
+
case unit
|
70
|
+
when :bit then :B
|
71
|
+
when :kbit then :KB
|
72
|
+
when :Mbit then :MB
|
73
|
+
when :Gbit then :GB
|
74
|
+
when :Tbit then :TB
|
75
|
+
else unsupported_unit!(unit)
|
76
|
+
end
|
77
|
+
end
|
78
|
+
|
79
|
+
def unsupported_unit!(unit)
|
80
|
+
raise ArgumentError.new("Unsupported unit - #{ unit }")
|
81
|
+
end
|
82
|
+
|
83
|
+
def not_integer!(value)
|
84
|
+
raise ArgumentError.new("#{value } is not integer")
|
85
|
+
end
|
86
|
+
|
87
|
+
def not_positive_integer!(value)
|
88
|
+
raise ArgumentError.new("#{value } is not positive integer")
|
89
|
+
end
|
90
|
+
end
|
91
|
+
end
|
92
|
+
end
|
@@ -0,0 +1,69 @@
|
|
1
|
+
require_relative 'standard/binary'
|
2
|
+
|
3
|
+
module UsefulUtilities
|
4
|
+
module Size
|
5
|
+
module Byte
|
6
|
+
# @note: used ISO standard http://en.wikipedia.org/wiki/Binary_prefix
|
7
|
+
# Binary
|
8
|
+
# 1 K = 1024
|
9
|
+
include UsefulUtilities::Size::Standard::Binary
|
10
|
+
|
11
|
+
HALF_OF_SECTOR = 0.5
|
12
|
+
|
13
|
+
def to_terabytes(size, unit)
|
14
|
+
to_tebi(size, byte_prefix(unit))
|
15
|
+
end
|
16
|
+
|
17
|
+
def to_gigabytes(size, unit)
|
18
|
+
to_gibi(size, byte_prefix(unit))
|
19
|
+
end
|
20
|
+
|
21
|
+
def to_megabytes(size, unit)
|
22
|
+
to_mebi(size, byte_prefix(unit))
|
23
|
+
end
|
24
|
+
|
25
|
+
def to_kilobytes(size, unit)
|
26
|
+
if unit == :sector
|
27
|
+
return (size * HALF_OF_SECTOR).round # http://en.wikipedia.org/wiki/Disk_sector
|
28
|
+
end
|
29
|
+
|
30
|
+
to_kibi(size, byte_prefix(unit))
|
31
|
+
end
|
32
|
+
|
33
|
+
def to_bytes(size, unit)
|
34
|
+
to_binary_bi(size, byte_prefix(unit))
|
35
|
+
end
|
36
|
+
|
37
|
+
# Convert bytes to manually defined format
|
38
|
+
# by using parameter 'unit'
|
39
|
+
# ATTENTION: by default round is eq to 3 digits
|
40
|
+
def bytes_to_human_size(size, unit, rounder = 3)
|
41
|
+
case unit
|
42
|
+
when :B then size.round(rounder)
|
43
|
+
when :KB then to_kilobytes(size, :B).round(rounder)
|
44
|
+
when :MB then to_megabytes(size, :B).round(rounder)
|
45
|
+
when :GB then to_gigabytes(size, :B).round(rounder)
|
46
|
+
when :TB then to_terabytes(size, :B).round(rounder)
|
47
|
+
else unsupported_unit!(unit)
|
48
|
+
end
|
49
|
+
end
|
50
|
+
|
51
|
+
private
|
52
|
+
|
53
|
+
def byte_prefix(unit)
|
54
|
+
case unit
|
55
|
+
when :B then :B
|
56
|
+
when :KB then :KiB
|
57
|
+
when :MB then :MiB
|
58
|
+
when :GB then :GiB
|
59
|
+
when :TB then :TiB
|
60
|
+
else unsupported_unit!(unit)
|
61
|
+
end
|
62
|
+
end
|
63
|
+
|
64
|
+
def unsupported_unit!(unit)
|
65
|
+
raise ArgumentError.new("Unsupported unit - #{ unit }")
|
66
|
+
end
|
67
|
+
end
|
68
|
+
end
|
69
|
+
end
|
@@ -0,0 +1,33 @@
|
|
1
|
+
require_relative 'standard/decimal'
|
2
|
+
|
3
|
+
module UsefulUtilities
|
4
|
+
module Size
|
5
|
+
module CdnSpeed
|
6
|
+
# @note: used SI standard http://en.wikipedia.org/wiki/Binary_prefix
|
7
|
+
# Decimal
|
8
|
+
# 1 K = 1000
|
9
|
+
include UsefulUtilities::Size::Standard::Decimal
|
10
|
+
|
11
|
+
def to_cdn_gbps(speed, unit)
|
12
|
+
to_giga(speed, bit_prefix(unit))/8
|
13
|
+
end
|
14
|
+
|
15
|
+
private
|
16
|
+
|
17
|
+
def bit_prefix(unit)
|
18
|
+
case unit
|
19
|
+
when :bit then :B
|
20
|
+
when :kbit then :KB
|
21
|
+
when :Mbit then :MB
|
22
|
+
when :Gbit then :GB
|
23
|
+
when :Tbit then :TB
|
24
|
+
else unsupported_unit!(unit)
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
def unsupported_unit!(unit)
|
29
|
+
raise ArgumentError.new("Unsupported unit - #{ unit }")
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
@@ -0,0 +1,37 @@
|
|
1
|
+
require_relative 'standard/decimal'
|
2
|
+
|
3
|
+
module UsefulUtilities
|
4
|
+
module Size
|
5
|
+
module Frequency
|
6
|
+
# @note: used SI standard http://en.wikipedia.org/wiki/Binary_prefix
|
7
|
+
# Decimal
|
8
|
+
# 1 K = 1000
|
9
|
+
include UsefulUtilities::Size::Standard::Decimal
|
10
|
+
|
11
|
+
def to_megahertz(size, unit)
|
12
|
+
to_mega(size, frequency_prefix(unit))
|
13
|
+
end
|
14
|
+
|
15
|
+
def to_gigahertz(size, unit)
|
16
|
+
to_giga(size, frequency_prefix(unit))
|
17
|
+
end
|
18
|
+
|
19
|
+
private
|
20
|
+
|
21
|
+
def frequency_prefix(unit)
|
22
|
+
case unit
|
23
|
+
when :Hz then :B
|
24
|
+
when :KHz then :KB
|
25
|
+
when :MHz then :MB
|
26
|
+
when :GHz then :GB
|
27
|
+
when :THz then :TB
|
28
|
+
else unsupported_unit!(unit)
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
def unsupported_unit!(unit)
|
33
|
+
raise ArgumentError.new("Unsupported unit - #{ unit }")
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|
@@ -0,0 +1,69 @@
|
|
1
|
+
module UsefulUtilities
|
2
|
+
module Size
|
3
|
+
module Standard
|
4
|
+
module Binary
|
5
|
+
# @note: used ISO standard http://en.wikipedia.org/wiki/Binary_prefix
|
6
|
+
|
7
|
+
KIBI = 1024 # KiB
|
8
|
+
MEBI = KIBI ** 2 # MiB
|
9
|
+
GIBI = KIBI ** 3 # GiB
|
10
|
+
TEBI = KIBI ** 4 # TiB
|
11
|
+
|
12
|
+
def to_tebi(val, prefix)
|
13
|
+
case prefix
|
14
|
+
when :B then val.fdiv(TEBI)
|
15
|
+
when :KiB then val.fdiv(GIBI)
|
16
|
+
when :MiB then val.fdiv(MEBI)
|
17
|
+
when :GiB then val.fdiv(KIBI)
|
18
|
+
when :TiB then val
|
19
|
+
else unsupported_unit!(prefix)
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
def to_gibi(val, prefix)
|
24
|
+
case prefix
|
25
|
+
when :B then val.fdiv(GIBI)
|
26
|
+
when :KiB then val.fdiv(MEBI)
|
27
|
+
when :MiB then val.fdiv(KIBI)
|
28
|
+
when :GiB then val
|
29
|
+
when :TiB then val * KIBI
|
30
|
+
else unsupported_unit!(prefix)
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
34
|
+
def to_mebi(val, prefix)
|
35
|
+
case prefix
|
36
|
+
when :B then val.fdiv(MEBI)
|
37
|
+
when :KiB then val.fdiv(KIBI)
|
38
|
+
when :MiB then val
|
39
|
+
when :GiB then val * KIBI
|
40
|
+
when :TiB then val * MEBI
|
41
|
+
else unsupported_unit!(prefix)
|
42
|
+
end
|
43
|
+
end
|
44
|
+
|
45
|
+
def to_kibi(val, prefix)
|
46
|
+
case prefix
|
47
|
+
when :B then val.fdiv(KIBI)
|
48
|
+
when :KiB then val
|
49
|
+
when :MiB then val * KIBI
|
50
|
+
when :GiB then val * MEBI
|
51
|
+
when :TiB then val * GIBI
|
52
|
+
else unsupported_unit!(prefix)
|
53
|
+
end
|
54
|
+
end
|
55
|
+
|
56
|
+
def to_binary_bi(val, prefix)
|
57
|
+
case prefix
|
58
|
+
when :B then val
|
59
|
+
when :KiB then val * KIBI
|
60
|
+
when :MiB then val * MEBI
|
61
|
+
when :GiB then val * GIBI
|
62
|
+
when :TiB then val * TEBI
|
63
|
+
else unsupported_unit!(prefix)
|
64
|
+
end
|
65
|
+
end
|
66
|
+
end
|
67
|
+
end
|
68
|
+
end
|
69
|
+
end
|
@@ -0,0 +1,69 @@
|
|
1
|
+
module UsefulUtilities
|
2
|
+
module Size
|
3
|
+
module Standard
|
4
|
+
module Decimal
|
5
|
+
# @note: used SI standard http://en.wikipedia.org/wiki/Binary_prefix
|
6
|
+
|
7
|
+
KILO = 1000 # KB
|
8
|
+
MEGA = KILO ** 2 # MB
|
9
|
+
GIGA = KILO ** 3 # GB
|
10
|
+
TERA = KILO ** 4 # TB
|
11
|
+
|
12
|
+
def to_tera(val, prefix)
|
13
|
+
case prefix
|
14
|
+
when :B then val.fdiv(TERA)
|
15
|
+
when :KB then val.fdiv(GIGA)
|
16
|
+
when :MB then val.fdiv(MEGA)
|
17
|
+
when :GB then val.fdiv(KILO)
|
18
|
+
when :TB then val
|
19
|
+
else unsupported_unit!(prefix)
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
def to_giga(val, prefix)
|
24
|
+
case prefix
|
25
|
+
when :B then val.fdiv(GIGA)
|
26
|
+
when :KB then val.fdiv(MEGA)
|
27
|
+
when :MB then val.fdiv(KILO)
|
28
|
+
when :GB then val
|
29
|
+
when :TB then val * KILO
|
30
|
+
else unsupported_unit!(prefix)
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
34
|
+
def to_mega(val, prefix)
|
35
|
+
case prefix
|
36
|
+
when :B then val.fdiv(MEGA)
|
37
|
+
when :KB then val.fdiv(KILO)
|
38
|
+
when :MB then val
|
39
|
+
when :GB then val * KILO
|
40
|
+
when :TB then val * MEGA
|
41
|
+
else unsupported_unit!(prefix)
|
42
|
+
end
|
43
|
+
end
|
44
|
+
|
45
|
+
def to_kilo(val, prefix)
|
46
|
+
case prefix
|
47
|
+
when :B then val.fdiv(KILO)
|
48
|
+
when :KB then val
|
49
|
+
when :MB then val * KILO
|
50
|
+
when :GB then val * MEGA
|
51
|
+
when :TB then val * GIGA
|
52
|
+
else unsupported_unit!(prefix)
|
53
|
+
end
|
54
|
+
end
|
55
|
+
|
56
|
+
def to_decimal_bi(val, prefix)
|
57
|
+
case prefix
|
58
|
+
when :B then val
|
59
|
+
when :KB then val * KILO
|
60
|
+
when :MB then val * MEGA
|
61
|
+
when :GB then val * GIGA
|
62
|
+
when :TB then val * TERA
|
63
|
+
else unsupported_unit!(prefix)
|
64
|
+
end
|
65
|
+
end
|
66
|
+
end
|
67
|
+
end
|
68
|
+
end
|
69
|
+
end
|
@@ -0,0 +1,18 @@
|
|
1
|
+
require 'active_support/core_ext/numeric/bytes'
|
2
|
+
require_relative 'size/bit'
|
3
|
+
require_relative 'size/cdn_speed'
|
4
|
+
require_relative 'size/frequency'
|
5
|
+
require_relative 'size/byte'
|
6
|
+
require_relative 'size/percentage'
|
7
|
+
|
8
|
+
module UsefulUtilities
|
9
|
+
module Size
|
10
|
+
include UsefulUtilities::Size::Bit
|
11
|
+
include UsefulUtilities::Size::CdnSpeed
|
12
|
+
include UsefulUtilities::Size::Frequency
|
13
|
+
include UsefulUtilities::Size::Byte
|
14
|
+
include UsefulUtilities::Size::Percentage
|
15
|
+
|
16
|
+
extend self
|
17
|
+
end
|
18
|
+
end
|
@@ -0,0 +1,97 @@
|
|
1
|
+
require 'active_support/all'
|
2
|
+
|
3
|
+
module UsefulUtilities
|
4
|
+
module Time
|
5
|
+
extend self
|
6
|
+
|
7
|
+
SECONDS_IN_HOUR = 3_600
|
8
|
+
MILLISECONDS_IN_SECOND = 1_000
|
9
|
+
|
10
|
+
# Whatever time is passed it will return it without any GMT offset and the passed time will be in UTC
|
11
|
+
# t = Time.now #=> 2013-12-19 14:01:22 +0200
|
12
|
+
# UsefulUtilities::Time.assume_utc(t) #=> 2013-12-19 14:01:22 UTC
|
13
|
+
def assume_utc(time)
|
14
|
+
time.to_datetime.change(offset: 0)
|
15
|
+
end
|
16
|
+
|
17
|
+
# Examples of usage:
|
18
|
+
# 2014-01-04 14:29:59 #=> 2014-01-04 14:00:00
|
19
|
+
# 2014-01-04 14:30:00 #=> 2014-01-04 15:00:00
|
20
|
+
def round_to_hours(time)
|
21
|
+
(time.min < 30) ? time.beginning_of_hour : time.end_of_hour
|
22
|
+
end
|
23
|
+
|
24
|
+
def beginning_of_next_hour(time)
|
25
|
+
time.beginning_of_hour.in(1.hour)
|
26
|
+
end
|
27
|
+
|
28
|
+
def beginning_of_next_day(time)
|
29
|
+
time.beginning_of_day.in(1.day)
|
30
|
+
end
|
31
|
+
|
32
|
+
def beginning_of_next_month(time)
|
33
|
+
time.beginning_of_month.in(1.month)
|
34
|
+
end
|
35
|
+
|
36
|
+
# yields local time of the beginning of each hour
|
37
|
+
# between start time & current time
|
38
|
+
def each_hour_from(from, till = ::Time.now)
|
39
|
+
cursor = from.dup.utc.beginning_of_hour
|
40
|
+
end_time = till.dup.utc.beginning_of_hour
|
41
|
+
|
42
|
+
while cursor < end_time
|
43
|
+
yield cursor, next_hour = beginning_of_next_hour(cursor)
|
44
|
+
|
45
|
+
cursor = next_hour
|
46
|
+
end
|
47
|
+
end
|
48
|
+
|
49
|
+
def each_day_from(from, till = ::Time.now)
|
50
|
+
cursor = from.beginning_of_day
|
51
|
+
end_time = till.beginning_of_day
|
52
|
+
|
53
|
+
while cursor < end_time
|
54
|
+
yield cursor, next_day = beginning_of_next_day(cursor)
|
55
|
+
|
56
|
+
cursor = next_day
|
57
|
+
end
|
58
|
+
end
|
59
|
+
|
60
|
+
# Parse and convert Time to the given time zone. If time zone is
|
61
|
+
# not given, Time is assumed to be given in UTC. Returns result in
|
62
|
+
# UTC
|
63
|
+
def to_utc(time_string, time_zone)
|
64
|
+
time = ::DateTime.parse(time_string) # Wed, 22 Aug 2012 13:34:18 +0000
|
65
|
+
rescue
|
66
|
+
nil
|
67
|
+
else
|
68
|
+
if time_zone.present?
|
69
|
+
current_user_offset = ::Time.now.in_time_zone(::Time.find_zone(time_zone)).strftime("%z") # "+0300"
|
70
|
+
time = time.change(:offset => current_user_offset) # Wed, 22 Aug 2012 13:34:18 +0300
|
71
|
+
time.utc # Wed, 22 Aug 2012 10:34:18 +0000
|
72
|
+
else
|
73
|
+
time
|
74
|
+
end
|
75
|
+
end
|
76
|
+
|
77
|
+
def to_milliseconds(time)
|
78
|
+
time.to_time.to_i * MILLISECONDS_IN_SECOND
|
79
|
+
end
|
80
|
+
|
81
|
+
# takes two objects: Time
|
82
|
+
def diff_in_hours(end_time, start_time)
|
83
|
+
((end_time.to_i - start_time.to_i) / SECONDS_IN_HOUR).abs
|
84
|
+
end
|
85
|
+
|
86
|
+
def valid_date?(date)
|
87
|
+
return true if date.acts_like?(:date)
|
88
|
+
return false if date.blank?
|
89
|
+
|
90
|
+
# http://stackoverflow.com/a/35502357/717336
|
91
|
+
date_hash = Date._parse(date.to_s)
|
92
|
+
Date.valid_date?(date_hash[:year].to_i,
|
93
|
+
date_hash[:mon].to_i,
|
94
|
+
date_hash[:mday].to_i)
|
95
|
+
end
|
96
|
+
end
|
97
|
+
end
|
@@ -0,0 +1,17 @@
|
|
1
|
+
# It was used in outdated rake task, but we decided to leave for the future
|
2
|
+
module UsefulUtilities
|
3
|
+
module YAML
|
4
|
+
extend self
|
5
|
+
|
6
|
+
def rename_keys(file_path, key_map)
|
7
|
+
yaml_hash = ::YAML.load_file(file_path)
|
8
|
+
keys_to_rename = yaml_hash.keys & key_map.keys
|
9
|
+
|
10
|
+
return if keys_to_rename.empty?
|
11
|
+
|
12
|
+
keys_to_rename.each { |old_key| yaml_hash[key_map.fetch(old_key)] = yaml_hash.delete(old_key) }
|
13
|
+
|
14
|
+
File.open(file_path, 'w') { |file| ::YAML.dump(yaml_hash, file) }
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
@@ -0,0 +1,15 @@
|
|
1
|
+
require 'active_support'
|
2
|
+
|
3
|
+
module UsefulUtilities
|
4
|
+
require_relative 'useful_utilities/version'
|
5
|
+
require_relative 'useful_utilities/ar' if defined?(ActiveRecord)
|
6
|
+
require_relative 'useful_utilities/numeric'
|
7
|
+
require_relative 'useful_utilities/time'
|
8
|
+
require_relative 'useful_utilities/size'
|
9
|
+
require_relative 'useful_utilities/api'
|
10
|
+
require_relative 'useful_utilities/i18n'
|
11
|
+
require_relative 'useful_utilities/hash'
|
12
|
+
require_relative 'useful_utilities/yaml'
|
13
|
+
require_relative 'useful_utilities/redhat_release'
|
14
|
+
require_relative 'useful_utilities/centos_version'
|
15
|
+
end
|
metadata
ADDED
@@ -0,0 +1,149 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: useful_utilities
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 5.4.5
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- OnApp Ltd.
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
date: 2018-02-09 00:00:00.000000000 Z
|
12
|
+
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: activesupport
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - ">="
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: '0'
|
20
|
+
type: :runtime
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - ">="
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: '0'
|
27
|
+
- !ruby/object:Gem::Dependency
|
28
|
+
name: timecop
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - ">="
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: '0'
|
34
|
+
type: :development
|
35
|
+
prerelease: false
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
37
|
+
requirements:
|
38
|
+
- - ">="
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
version: '0'
|
41
|
+
- !ruby/object:Gem::Dependency
|
42
|
+
name: pry
|
43
|
+
requirement: !ruby/object:Gem::Requirement
|
44
|
+
requirements:
|
45
|
+
- - ">="
|
46
|
+
- !ruby/object:Gem::Version
|
47
|
+
version: '0'
|
48
|
+
type: :development
|
49
|
+
prerelease: false
|
50
|
+
version_requirements: !ruby/object:Gem::Requirement
|
51
|
+
requirements:
|
52
|
+
- - ">="
|
53
|
+
- !ruby/object:Gem::Version
|
54
|
+
version: '0'
|
55
|
+
- !ruby/object:Gem::Dependency
|
56
|
+
name: factory_girl_rails
|
57
|
+
requirement: !ruby/object:Gem::Requirement
|
58
|
+
requirements:
|
59
|
+
- - ">="
|
60
|
+
- !ruby/object:Gem::Version
|
61
|
+
version: '0'
|
62
|
+
type: :development
|
63
|
+
prerelease: false
|
64
|
+
version_requirements: !ruby/object:Gem::Requirement
|
65
|
+
requirements:
|
66
|
+
- - ">="
|
67
|
+
- !ruby/object:Gem::Version
|
68
|
+
version: '0'
|
69
|
+
- !ruby/object:Gem::Dependency
|
70
|
+
name: rspec-rails
|
71
|
+
requirement: !ruby/object:Gem::Requirement
|
72
|
+
requirements:
|
73
|
+
- - ">="
|
74
|
+
- !ruby/object:Gem::Version
|
75
|
+
version: '0'
|
76
|
+
type: :development
|
77
|
+
prerelease: false
|
78
|
+
version_requirements: !ruby/object:Gem::Requirement
|
79
|
+
requirements:
|
80
|
+
- - ">="
|
81
|
+
- !ruby/object:Gem::Version
|
82
|
+
version: '0'
|
83
|
+
- !ruby/object:Gem::Dependency
|
84
|
+
name: rspec-its
|
85
|
+
requirement: !ruby/object:Gem::Requirement
|
86
|
+
requirements:
|
87
|
+
- - ">="
|
88
|
+
- !ruby/object:Gem::Version
|
89
|
+
version: '0'
|
90
|
+
type: :development
|
91
|
+
prerelease: false
|
92
|
+
version_requirements: !ruby/object:Gem::Requirement
|
93
|
+
requirements:
|
94
|
+
- - ">="
|
95
|
+
- !ruby/object:Gem::Version
|
96
|
+
version: '0'
|
97
|
+
description: |2
|
98
|
+
A bunch of useful modules to work with time/size constants/hashes
|
99
|
+
email: onapp@onapp.com
|
100
|
+
executables: []
|
101
|
+
extensions: []
|
102
|
+
extra_rdoc_files: []
|
103
|
+
files:
|
104
|
+
- README.md
|
105
|
+
- Rakefile
|
106
|
+
- lib/useful_utilities.rb
|
107
|
+
- lib/useful_utilities/api.rb
|
108
|
+
- lib/useful_utilities/ar.rb
|
109
|
+
- lib/useful_utilities/centos_version.rb
|
110
|
+
- lib/useful_utilities/hash.rb
|
111
|
+
- lib/useful_utilities/i18n.rb
|
112
|
+
- lib/useful_utilities/numeric.rb
|
113
|
+
- lib/useful_utilities/redhat_release.rb
|
114
|
+
- lib/useful_utilities/size.rb
|
115
|
+
- lib/useful_utilities/size/bit.rb
|
116
|
+
- lib/useful_utilities/size/byte.rb
|
117
|
+
- lib/useful_utilities/size/cdn_speed.rb
|
118
|
+
- lib/useful_utilities/size/frequency.rb
|
119
|
+
- lib/useful_utilities/size/percentage.rb
|
120
|
+
- lib/useful_utilities/size/standard/binary.rb
|
121
|
+
- lib/useful_utilities/size/standard/decimal.rb
|
122
|
+
- lib/useful_utilities/time.rb
|
123
|
+
- lib/useful_utilities/version.rb
|
124
|
+
- lib/useful_utilities/yaml.rb
|
125
|
+
homepage: https://github.com/OnApp/useful_utilities
|
126
|
+
licenses:
|
127
|
+
- Apache 2.0
|
128
|
+
metadata: {}
|
129
|
+
post_install_message:
|
130
|
+
rdoc_options: []
|
131
|
+
require_paths:
|
132
|
+
- lib
|
133
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
134
|
+
requirements:
|
135
|
+
- - ">="
|
136
|
+
- !ruby/object:Gem::Version
|
137
|
+
version: 2.1.0
|
138
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
139
|
+
requirements:
|
140
|
+
- - ">="
|
141
|
+
- !ruby/object:Gem::Version
|
142
|
+
version: '0'
|
143
|
+
requirements: []
|
144
|
+
rubyforge_project:
|
145
|
+
rubygems_version: 2.4.3
|
146
|
+
signing_key:
|
147
|
+
specification_version: 4
|
148
|
+
summary: Helpful methods for time, sizes, hashes etc.
|
149
|
+
test_files: []
|