thefox-ext 1.5.1 → 1.7.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 +5 -5
- data/.editorconfig +6 -5
- data/.env.example +2 -0
- data/.github/workflows/ci.yml +42 -0
- data/.github/workflows/release.yml +36 -0
- data/.gitignore +2 -5
- data/CHANGELOG-v1.md +83 -0
- data/LICENSE +21 -0
- data/README.md +17 -13
- data/bin/.gitignore +1 -0
- data/bin/install.sh +51 -0
- data/bin/release.sh +37 -0
- data/bin/setup.sh +17 -0
- data/bin/test.sh +13 -0
- data/bin/uninstall.sh +24 -0
- data/lib/thefox-ext/console.rb +47 -47
- data/lib/thefox-ext/ext/array.rb +35 -31
- data/lib/thefox-ext/ext/date.rb +42 -42
- data/lib/thefox-ext/ext/false.rb +6 -6
- data/lib/thefox-ext/ext/hash.rb +62 -62
- data/lib/thefox-ext/ext/integer.rb +3 -3
- data/lib/thefox-ext/ext/nil.rb +3 -3
- data/lib/thefox-ext/ext/string.rb +63 -63
- data/lib/thefox-ext/ext/true.rb +6 -6
- data/lib/thefox-ext/version.rb +5 -5
- data/thefox-ext.code-workspace +32 -0
- data/thefox-ext.gemspec +5 -5
- metadata +20 -11
- data/.gitlab-ci.yml +0 -56
- data/.travis.yml +0 -19
- data/Makefile +0 -8
- data/Makefile.common +0 -58
- data/thefox-ext.sublime-project +0 -10
data/lib/thefox-ext/ext/array.rb
CHANGED
@@ -1,34 +1,38 @@
|
|
1
1
|
|
2
2
|
class Array
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
3
|
+
|
4
|
+
# Resolve a range string to an array.
|
5
|
+
# A range string can be like '1, 3..5, 9-11, 12+, 14++, 17+++'.
|
6
|
+
# Which will be resolved to [1, 3, 4, 5, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20].
|
7
|
+
def self.resolve_range_str(original_str)
|
8
|
+
rv = Array.new
|
9
|
+
if !original_str.is_a?(String)
|
10
|
+
return rv
|
11
|
+
end
|
12
|
+
|
13
|
+
original_str.split(',').map{ |item|
|
14
|
+
item_striped = item.strip
|
15
|
+
if /\.\./.match(item_striped) # ( . )( . ) <--- BOOBS
|
16
|
+
Range.new(*item_striped.split('..', 2).map{ |range| range.to_i })
|
17
|
+
elsif /-/.match(item_striped)
|
18
|
+
Range.new(*item_striped.split('-', 2).map{ |range| range.to_i })
|
19
|
+
elsif /\+/.match(item_striped)
|
20
|
+
items = item_striped.split('+')
|
21
|
+
range_begin = items[0].to_i
|
22
|
+
range_end = range_begin + item_striped.count('+')
|
23
|
+
Range.new(range_begin, range_end)
|
24
|
+
else
|
25
|
+
item_striped.to_i
|
26
|
+
end
|
27
|
+
}.each do |range|
|
28
|
+
if range.is_a?(Range)
|
29
|
+
rv.push(*range.to_a)
|
30
|
+
else
|
31
|
+
rv << range
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
35
|
+
rv
|
36
|
+
end
|
37
|
+
|
34
38
|
end
|
data/lib/thefox-ext/ext/date.rb
CHANGED
@@ -2,46 +2,46 @@
|
|
2
2
|
require 'date'
|
3
3
|
|
4
4
|
class Date
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
5
|
+
def today?
|
6
|
+
self == Date.today
|
7
|
+
end
|
8
|
+
|
9
|
+
# Get all days (as Date objects) for the current week.
|
10
|
+
def week
|
11
|
+
cweek = self.cweek
|
12
|
+
year = self.year
|
13
|
+
month = self.month
|
14
|
+
|
15
|
+
next_year = year + 1
|
16
|
+
previous_year = year - 1
|
17
|
+
|
18
|
+
days = Date.new(year)
|
19
|
+
.step(Date.new(year, -1, -1))
|
20
|
+
.select{ |d| d.cweek == cweek }
|
21
|
+
|
22
|
+
if cweek == 1 && month == 12 ||
|
23
|
+
cweek == 1 && month == 1 ||
|
24
|
+
cweek >= 52 && month == 12 ||
|
25
|
+
cweek >= 52 && month == 1
|
26
|
+
|
27
|
+
days.keep_if{ |d| d.year == year && d.month == month }
|
28
|
+
end
|
29
|
+
|
30
|
+
if days.count < 7
|
31
|
+
rest = 7 - days.count
|
32
|
+
|
33
|
+
rest_days = nil
|
34
|
+
if month == 1
|
35
|
+
rest_days = Date.new(previous_year, 12, 31 - rest + 1).step(Date.new(previous_year, 12, 31))
|
36
|
+
elsif month == 12
|
37
|
+
rest_days = Date.new(next_year).step(Date.new(next_year, 1, rest))
|
38
|
+
end
|
39
|
+
|
40
|
+
if !rest_days.nil?
|
41
|
+
days += rest_days.to_a
|
42
|
+
end
|
43
|
+
end
|
44
|
+
|
45
|
+
days.sort[0, 7]
|
46
|
+
end
|
47
47
|
end
|
data/lib/thefox-ext/ext/false.rb
CHANGED
data/lib/thefox-ext/ext/hash.rb
CHANGED
@@ -1,65 +1,65 @@
|
|
1
1
|
|
2
2
|
class Hash
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
3
|
+
|
4
|
+
def merge_recursive(h2, level = 0, clone = true)
|
5
|
+
if !h2.is_a?(Hash)
|
6
|
+
raise ArgumentError, "Argument is not a Hash -- #{h2.class} given"
|
7
|
+
end
|
8
|
+
|
9
|
+
has_subhashes = false
|
10
|
+
|
11
|
+
h1 = self
|
12
|
+
if clone
|
13
|
+
# We want to modify only the clone.
|
14
|
+
h1 = self.clone
|
15
|
+
end
|
16
|
+
|
17
|
+
# Iterate Hash 1
|
18
|
+
h1.each do |k, v|
|
19
|
+
if v.is_a?(Hash)
|
20
|
+
has_subhashes = true
|
21
|
+
|
22
|
+
# If Hash 2 also has the same key.
|
23
|
+
if h2.has_key?(k)
|
24
|
+
if h2[k].is_a?(Hash)
|
25
|
+
# Inception! Go one level deeper.
|
26
|
+
h1[k] = v.merge_recursive(h2[k], level + 1)
|
27
|
+
else
|
28
|
+
h1[k] = h2[k]
|
29
|
+
end
|
30
|
+
end
|
31
|
+
else
|
32
|
+
# Value of Hash 1 is no Subhash.
|
33
|
+
|
34
|
+
# Only overwrite Hash 1 Value with Hash 2 Value
|
35
|
+
# if a Hash 2 Key exist.
|
36
|
+
if h2.has_key?(k)
|
37
|
+
h1[k] = h2[k]
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|
41
|
+
|
42
|
+
# Iterate Hash 2
|
43
|
+
# Because we also want Key from Hash 2
|
44
|
+
# which don't exist in Hash 1.
|
45
|
+
h2.each do |k, v|
|
46
|
+
if !h1.has_key?(k)
|
47
|
+
h1[k] = v
|
48
|
+
end
|
49
|
+
end
|
50
|
+
|
51
|
+
if !has_subhashes
|
52
|
+
# If there are no subhashes merge
|
53
|
+
# with existing merge function.
|
54
|
+
h1.merge!(h2)
|
55
|
+
end
|
56
|
+
|
57
|
+
# Return h1 modified clone.
|
58
|
+
return h1
|
59
|
+
end
|
60
|
+
|
61
|
+
def merge_recursive!(h2)
|
62
|
+
self.merge_recursive(h2, 0, false)
|
63
|
+
end
|
64
|
+
|
65
65
|
end
|
data/lib/thefox-ext/ext/nil.rb
CHANGED
@@ -1,66 +1,66 @@
|
|
1
1
|
|
2
2
|
class String
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
3
|
+
|
4
|
+
# Is a String only made of numbers?
|
5
|
+
def is_digit?
|
6
|
+
r = '0'..'9'
|
7
|
+
self.split('').keep_if{ |c| r.include?(c) }.count == self.length
|
8
|
+
end
|
9
|
+
|
10
|
+
# Is a String only made of lower-case charaters.
|
11
|
+
def is_lower?
|
12
|
+
r = 'a'..'z'
|
13
|
+
self.split('').keep_if{ |c| r.include?(c) }.count == self.length
|
14
|
+
end
|
15
|
+
|
16
|
+
# Is a String only made of upper-case charaters.
|
17
|
+
def is_upper?
|
18
|
+
r = 'A'..'Z'
|
19
|
+
self.split('').keep_if{ |c| r.include?(c) }.count == self.length
|
20
|
+
end
|
21
|
+
|
22
|
+
def is_utf8?
|
23
|
+
begin
|
24
|
+
self.unpack('U*')
|
25
|
+
rescue
|
26
|
+
return false
|
27
|
+
end
|
28
|
+
return true
|
29
|
+
end
|
30
|
+
|
31
|
+
# Convert 'hello world' to 'Hello World'.
|
32
|
+
def titlecase
|
33
|
+
self
|
34
|
+
.split(/ /)
|
35
|
+
.map{ |word| word.capitalize }
|
36
|
+
.join(' ')
|
37
|
+
end
|
38
|
+
|
39
|
+
def to_hex
|
40
|
+
self.split('').map{ |c| sprintf '%02x', c.ord }.join
|
41
|
+
end
|
42
|
+
|
43
|
+
# Convert a String to an Integer 32-bit Array.
|
44
|
+
def to_i32a
|
45
|
+
len = self.length
|
46
|
+
len_w = (len >> 2) + (len & 0x3).to_b.to_i
|
47
|
+
|
48
|
+
out = (0..(len_w - 1)).map{ |n| [n, 0] }.to_h
|
49
|
+
|
50
|
+
i = 0
|
51
|
+
self.split('').each do |s|
|
52
|
+
out[i >> 2] |= (s.ord << ((3 - (i & 0x3)) << 3))
|
53
|
+
i += 1
|
54
|
+
end
|
55
|
+
|
56
|
+
out
|
57
|
+
end
|
58
|
+
|
59
|
+
def to_utf8
|
60
|
+
if is_utf8?
|
61
|
+
self.force_encoding('UTF-8')
|
62
|
+
else
|
63
|
+
self.force_encoding('ISO-8859-1').encode('UTF-8')
|
64
|
+
end
|
65
|
+
end
|
66
66
|
end
|