buzztools 0.0.3
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 +15 -0
- data/.gitignore +18 -0
- data/Gemfile +4 -0
- data/LICENSE.txt +22 -0
- data/README.md +6 -0
- data/Rakefile +1 -0
- data/buzztools.gemspec +22 -0
- data/lib/buzztools.rb +9 -0
- data/lib/buzztools/extend_array.rb +53 -0
- data/lib/buzztools/extend_bignum.rb +19 -0
- data/lib/buzztools/extend_fixnum.rb +15 -0
- data/lib/buzztools/extend_hash.rb +86 -0
- data/lib/buzztools/extend_more.rb +50 -0
- data/lib/buzztools/extend_object.rb +54 -0
- data/lib/buzztools/extend_string.rb +225 -0
- data/lib/buzztools/extend_time.rb +84 -0
- data/lib/buzztools/version.rb +3 -0
- metadata +88 -0
checksums.yaml
ADDED
@@ -0,0 +1,15 @@
|
|
1
|
+
---
|
2
|
+
!binary "U0hBMQ==":
|
3
|
+
metadata.gz: !binary |-
|
4
|
+
NTI2MDkwZmY0Mjc1NTllMzk0NzgyMGY3YzBlNTAwNDlkNWRlOTJkNA==
|
5
|
+
data.tar.gz: !binary |-
|
6
|
+
OTg3MWE5YTQ3ODU3NGU1YmU4YjdkNGVjYzA1NGU0M2VjZDRhMDgxNA==
|
7
|
+
SHA512:
|
8
|
+
metadata.gz: !binary |-
|
9
|
+
MDhiZTMwNmQyYWVjNmIwZDE2NjY5OTMwZmQ5NjNmNTcxZmEyOTg0YTYxZDE3
|
10
|
+
NzA4MDY3MDJiMDM0ZjkzMDYzNGVhYzhhYmM1MzlhOTlhNzQ1N2FjN2RlZjI2
|
11
|
+
ODQxYTVkMzQwMDI2YTg3ZTAxZTBkYTU1YTFkNmQ4Y2MzMDY4YzM=
|
12
|
+
data.tar.gz: !binary |-
|
13
|
+
OGZmYjZiMDllNmVkMDlmMTY0YzQ3YTFlNmJhYTQyOGU1NDYxZTZiOGZhYTJk
|
14
|
+
MDlmNDNmNjVmOTdiMzY0NjI0ZDA2ZmVmYTM1NTg2ZDM1ZDM0MTJjZTEwOTZh
|
15
|
+
YTM0MjFmMjY3ODkwYjU0NjY1OTUzMTgzNDFkMjVkZGY5ZTk2MTY=
|
data/.gitignore
ADDED
data/Gemfile
ADDED
data/LICENSE.txt
ADDED
@@ -0,0 +1,22 @@
|
|
1
|
+
Copyright (c) 2013 Gary McGhee
|
2
|
+
|
3
|
+
MIT License
|
4
|
+
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
6
|
+
a copy of this software and associated documentation files (the
|
7
|
+
"Software"), to deal in the Software without restriction, including
|
8
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
9
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
10
|
+
permit persons to whom the Software is furnished to do so, subject to
|
11
|
+
the following conditions:
|
12
|
+
|
13
|
+
The above copyright notice and this permission notice shall be
|
14
|
+
included in all copies or substantial portions of the Software.
|
15
|
+
|
16
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
17
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
18
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
19
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
20
|
+
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
21
|
+
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
22
|
+
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/README.md
ADDED
data/Rakefile
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
require "bundler/gem_tasks"
|
data/buzztools.gemspec
ADDED
@@ -0,0 +1,22 @@
|
|
1
|
+
# coding: utf-8
|
2
|
+
lib = File.expand_path('../lib', __FILE__)
|
3
|
+
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
4
|
+
require 'buzztools/version'
|
5
|
+
|
6
|
+
Gem::Specification.new do |spec|
|
7
|
+
spec.name = "buzztools"
|
8
|
+
spec.version = Buzztools::VERSION
|
9
|
+
spec.authors = ["Gary McGhee"]
|
10
|
+
spec.email = ["contact@buzzware.com.au"]
|
11
|
+
spec.description = "reusable function library"
|
12
|
+
spec.summary = "reusable function library"
|
13
|
+
spec.homepage = "https://github.com/buzzware/buzztools"
|
14
|
+
spec.license = "MIT"
|
15
|
+
|
16
|
+
spec.files = `git ls-files`.split($/)
|
17
|
+
spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
|
18
|
+
spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
|
19
|
+
spec.require_paths = ["lib"]
|
20
|
+
spec.add_development_dependency "bundler", ">= 1.3"
|
21
|
+
spec.add_development_dependency "rake"
|
22
|
+
end
|
data/lib/buzztools.rb
ADDED
@@ -0,0 +1,53 @@
|
|
1
|
+
module ExtendArray
|
2
|
+
|
3
|
+
module_function # this makes the methods accessible on the module as well as instances when the module is included into a class
|
4
|
+
|
5
|
+
public
|
6
|
+
|
7
|
+
def filter_include!(aValues,aArray=nil)
|
8
|
+
aArray ||= self
|
9
|
+
if aValues.is_a? Array
|
10
|
+
return aArray if aValues.empty?
|
11
|
+
return aArray.delete_if {|v| not aValues.include? v }
|
12
|
+
elsif aValues.is_a? Regexp
|
13
|
+
return aArray.delete_if {|v| not v =~ aValues }
|
14
|
+
else
|
15
|
+
return filter_include!([aValues],aArray)
|
16
|
+
end
|
17
|
+
end
|
18
|
+
|
19
|
+
def filter_include(aValues,aArray=nil)
|
20
|
+
aArray ||= self
|
21
|
+
filter_include!(aValues,aArray.clone)
|
22
|
+
end
|
23
|
+
|
24
|
+
def filter_exclude!(aValues,aArray=nil)
|
25
|
+
aArray ||= self
|
26
|
+
if aValues.is_a? Array
|
27
|
+
return aArray if aValues.empty?
|
28
|
+
return aArray.delete_if {|v| aValues.include? v }
|
29
|
+
elsif aValues.is_a? Regexp
|
30
|
+
return aArray.delete_if {|v| v =~ aValues }
|
31
|
+
else
|
32
|
+
return filter_exclude!([aValues],aArray)
|
33
|
+
end
|
34
|
+
end
|
35
|
+
|
36
|
+
def filter_exclude(aValues,aArray=nil)
|
37
|
+
aArray ||= self
|
38
|
+
filter_exclude!(aValues,aArray.clone)
|
39
|
+
end
|
40
|
+
|
41
|
+
def to_nil
|
42
|
+
self.empty? ? nil : self
|
43
|
+
end
|
44
|
+
end
|
45
|
+
|
46
|
+
Array.class_eval do
|
47
|
+
include ExtendArray
|
48
|
+
# fixes a memory leak in shift in Ruby 1.8 - should be fixed in 1.9
|
49
|
+
# see http://blade.nagaokaut.ac.jp/cgi-bin/scat.rb/ruby/ruby-talk/216055
|
50
|
+
#def shift()
|
51
|
+
# delete_at(0)
|
52
|
+
#end
|
53
|
+
end
|
@@ -0,0 +1,15 @@
|
|
1
|
+
Fixnum.class_eval do
|
2
|
+
|
3
|
+
def to_nil
|
4
|
+
self==0 ? nil : self
|
5
|
+
end
|
6
|
+
|
7
|
+
def to_b(aDefault=false)
|
8
|
+
self==0 ? false : true
|
9
|
+
end
|
10
|
+
|
11
|
+
def to_range(aMin,aMax=nil,aDefault=nil)
|
12
|
+
(!aMin || (self >= aMin)) && (!aMax || (self <= aMax)) ? self : aDefault
|
13
|
+
end
|
14
|
+
|
15
|
+
end
|
@@ -0,0 +1,86 @@
|
|
1
|
+
module HashUtils
|
2
|
+
|
3
|
+
public
|
4
|
+
|
5
|
+
def filter_include!(aKeys,aHash=nil)
|
6
|
+
aHash ||= self
|
7
|
+
|
8
|
+
if aKeys.is_a? Regexp
|
9
|
+
return aHash.delete_if {|k,v| not k =~ aKeys }
|
10
|
+
else
|
11
|
+
aKeys = [aKeys] unless aKeys.is_a? Array
|
12
|
+
return aHash.clear if aKeys.empty?
|
13
|
+
return aHash.delete_if {|key, value| !((aKeys.include?(key)) || (key.is_a?(Symbol) and aKeys.include?(key.to_s)) || (key.is_a?(String) and aKeys.include?(key.to_sym)))}
|
14
|
+
return aHash # last resort
|
15
|
+
end
|
16
|
+
end
|
17
|
+
|
18
|
+
def filter_include(aKeys,aHash=nil)
|
19
|
+
aHash ||= self
|
20
|
+
filter_include!(aKeys,aHash.clone)
|
21
|
+
end
|
22
|
+
|
23
|
+
def filter_exclude!(aKeys,aHash=nil)
|
24
|
+
aHash ||= self
|
25
|
+
|
26
|
+
if aKeys.is_a? Regexp
|
27
|
+
return aHash.delete_if {|k,v| k =~ aKeys }
|
28
|
+
else
|
29
|
+
aKeys = [aKeys] unless aKeys.is_a? Array
|
30
|
+
return aHash if aKeys.empty?
|
31
|
+
return aHash.delete_if {|key, value| ((aKeys.include?(key)) || (key.is_a?(Symbol) and aKeys.include?(key.to_s)) || (key.is_a?(String) and aKeys.include?(key.to_sym)))}
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
35
|
+
def filter_exclude(aKeys,aHash=nil)
|
36
|
+
aHash ||= self
|
37
|
+
filter_exclude!(aKeys,aHash.clone)
|
38
|
+
end
|
39
|
+
|
40
|
+
def has_values_for?(aKeys,aHash=nil)
|
41
|
+
aHash ||= self
|
42
|
+
# check all keys exist in aHash and their values are not nil
|
43
|
+
aKeys.all? { |k,v| aHash[k] }
|
44
|
+
end
|
45
|
+
|
46
|
+
# give a block to execute without the given key in this hash
|
47
|
+
# It will be replaced after the block (guaranteed by ensure)
|
48
|
+
# eg.
|
49
|
+
# hash.without_key(:blah) do |aHash|
|
50
|
+
# puts aHash.inspect
|
51
|
+
# end
|
52
|
+
def without_key(aKey)
|
53
|
+
temp = nil
|
54
|
+
h = self
|
55
|
+
begin
|
56
|
+
if h.include?(aKey)
|
57
|
+
temp = [aKey,h.delete(aKey)]
|
58
|
+
end
|
59
|
+
result = yield(h)
|
60
|
+
ensure
|
61
|
+
h[temp[0]] = temp[1] if temp
|
62
|
+
end
|
63
|
+
return result
|
64
|
+
end
|
65
|
+
|
66
|
+
def symbolize_keys
|
67
|
+
result = {}
|
68
|
+
self.each { |k,v| k.is_a?(String) ? result[k.to_sym] = v : result[k] = v }
|
69
|
+
return result
|
70
|
+
end
|
71
|
+
|
72
|
+
def to_nil
|
73
|
+
self.empty? ? nil : self
|
74
|
+
end
|
75
|
+
|
76
|
+
end
|
77
|
+
|
78
|
+
Hash.class_eval do
|
79
|
+
include HashUtils
|
80
|
+
end
|
81
|
+
|
82
|
+
if defined? HashWithIndifferentAccess
|
83
|
+
HashWithIndifferentAccess.class_eval do
|
84
|
+
include HashUtils
|
85
|
+
end
|
86
|
+
end
|
@@ -0,0 +1,50 @@
|
|
1
|
+
NilClass.class_eval do
|
2
|
+
|
3
|
+
def to_nil
|
4
|
+
nil
|
5
|
+
end
|
6
|
+
|
7
|
+
def to_b(aDefault=false)
|
8
|
+
false
|
9
|
+
end
|
10
|
+
|
11
|
+
def g?(*args)
|
12
|
+
nil
|
13
|
+
end
|
14
|
+
|
15
|
+
end
|
16
|
+
|
17
|
+
TrueClass.class_eval do
|
18
|
+
|
19
|
+
def to_nil
|
20
|
+
self
|
21
|
+
end
|
22
|
+
|
23
|
+
def to_b(aDefault=false)
|
24
|
+
self
|
25
|
+
end
|
26
|
+
|
27
|
+
end
|
28
|
+
|
29
|
+
FalseClass.class_eval do
|
30
|
+
|
31
|
+
def to_nil
|
32
|
+
nil
|
33
|
+
end
|
34
|
+
|
35
|
+
def to_b(aDefault=false)
|
36
|
+
self
|
37
|
+
end
|
38
|
+
|
39
|
+
end
|
40
|
+
|
41
|
+
|
42
|
+
Math.module_eval do
|
43
|
+
def self.max(a, b)
|
44
|
+
a > b ? a : b
|
45
|
+
end
|
46
|
+
|
47
|
+
def self.min(a, b)
|
48
|
+
a < b ? a : b
|
49
|
+
end
|
50
|
+
end
|
@@ -0,0 +1,54 @@
|
|
1
|
+
# this pattern of declaring methods in a module and then including into a class means that the methods can be used directly from the module
|
2
|
+
# eg. ExtendObject::attr_from_json(json,object)
|
3
|
+
# or on the class it is included into
|
4
|
+
# eg. model.attr_from_json(json)
|
5
|
+
module ExtendObject
|
6
|
+
|
7
|
+
module_function # this makes the methods accessible on the module as well as instances when the module is included into a class
|
8
|
+
|
9
|
+
public
|
10
|
+
|
11
|
+
def attr_from_json(aJsonObject,aObject=nil) # only give second argument when used like ExtendObject::attr_from_json
|
12
|
+
aObject ||= self
|
13
|
+
rubyObj = JSON.parse!(aJsonObject)
|
14
|
+
rubyObj.each do |k,v|
|
15
|
+
aObject.send k.to_sym,v
|
16
|
+
end
|
17
|
+
aObject
|
18
|
+
end
|
19
|
+
|
20
|
+
def g?(*args)
|
21
|
+
if args.length==1
|
22
|
+
path = args.first
|
23
|
+
else
|
24
|
+
path = args
|
25
|
+
end
|
26
|
+
if path.is_a?(String)
|
27
|
+
segments = path.split('.').map!(&:to_sym)
|
28
|
+
segment = segments.shift
|
29
|
+
elsif path.is_a?(Symbol)
|
30
|
+
segments = []
|
31
|
+
segment = path
|
32
|
+
elsif path.is_a?(Array)
|
33
|
+
segments = path
|
34
|
+
segment = segments.shift
|
35
|
+
segment = segment.to_sym if segment
|
36
|
+
end
|
37
|
+
return self unless segment.to_nil
|
38
|
+
value = if self.respond_to?(segment)
|
39
|
+
self.send(segment)
|
40
|
+
elsif self.respond_to?(:[])
|
41
|
+
(self[segment] || self[segment.to_s]) rescue nil
|
42
|
+
end
|
43
|
+
if segments.empty?
|
44
|
+
value
|
45
|
+
else
|
46
|
+
value.respond_to?(:g?) ? value.g?(segments) : nil
|
47
|
+
end
|
48
|
+
end
|
49
|
+
|
50
|
+
end
|
51
|
+
|
52
|
+
Object.class_eval do
|
53
|
+
include ExtendObject
|
54
|
+
end
|
@@ -0,0 +1,225 @@
|
|
1
|
+
String.class_eval do
|
2
|
+
|
3
|
+
def self.random_word(min=4,max=8)
|
4
|
+
len = min + rand(max-min+1)
|
5
|
+
result = ' '*len
|
6
|
+
(len-1).downto(0) {|i| result[i] = (?a.ord + rand(?z.ord-?a.ord+1)).chr}
|
7
|
+
return result
|
8
|
+
end
|
9
|
+
|
10
|
+
def pad_left(value)
|
11
|
+
increase = value-self.length
|
12
|
+
return self if increase==0
|
13
|
+
if increase > 0
|
14
|
+
return self + ' '*increase
|
15
|
+
else
|
16
|
+
return self[0,value]
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
def pad_right(value)
|
21
|
+
increase = value-self.length
|
22
|
+
return self if increase==0
|
23
|
+
if increase > 0
|
24
|
+
return ' '*increase + self
|
25
|
+
else
|
26
|
+
return self[0,value]
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
30
|
+
# Like bite, but returns the first match instead of the subject, and removes the match from the subject, modifying it
|
31
|
+
def extract!(aValue=$/,aString=self)
|
32
|
+
if aValue.is_a? String
|
33
|
+
if i = aString.index(aValue)
|
34
|
+
aString[i,aValue.length] = ''
|
35
|
+
return aValue
|
36
|
+
else
|
37
|
+
return nil
|
38
|
+
end
|
39
|
+
elsif aValue.is_a? Regexp
|
40
|
+
if md = aValue.match(aString)
|
41
|
+
aString[md.begin(0),md.end(0)-md.begin(0)] = ''
|
42
|
+
return md.to_s
|
43
|
+
else
|
44
|
+
return nil
|
45
|
+
end
|
46
|
+
else
|
47
|
+
return aString
|
48
|
+
end
|
49
|
+
end
|
50
|
+
|
51
|
+
def extract(aValue=$/)
|
52
|
+
extract!(aValue,self.clone)
|
53
|
+
end
|
54
|
+
|
55
|
+
# Like chomp! but operates on the leading characters instead.
|
56
|
+
# The aString parameter would not normally be used.
|
57
|
+
def bite!(aValue=$/,aString=self)
|
58
|
+
if aValue.is_a? String
|
59
|
+
if aString[0,aValue.length] == aValue
|
60
|
+
aString[0,aValue.length] = ''
|
61
|
+
return aString
|
62
|
+
else
|
63
|
+
return aString
|
64
|
+
end
|
65
|
+
elsif aValue.is_a? Regexp
|
66
|
+
return aString.sub!(aValue,'') if aString.index(aValue)==0
|
67
|
+
else
|
68
|
+
return aString
|
69
|
+
end
|
70
|
+
end
|
71
|
+
|
72
|
+
def bite(aValue=$/)
|
73
|
+
bite!(aValue,self.clone)
|
74
|
+
end
|
75
|
+
|
76
|
+
def deprefix!(aPrefix=$/,aString=self)
|
77
|
+
if aString[0,aPrefix.length] == aPrefix
|
78
|
+
aString[0,aPrefix.length] = ''
|
79
|
+
return aString
|
80
|
+
else
|
81
|
+
return aString
|
82
|
+
end
|
83
|
+
end
|
84
|
+
|
85
|
+
def deprefix(aValue=$/)
|
86
|
+
deprefix!(aValue,self.clone)
|
87
|
+
end
|
88
|
+
|
89
|
+
def desuffix!(aString,aSuffix)
|
90
|
+
if aString[-aSuffix.length,aSuffix.length] == aSuffix
|
91
|
+
aString[-aSuffix.length,aSuffix.length] = ''
|
92
|
+
return aString
|
93
|
+
else
|
94
|
+
return aString
|
95
|
+
end
|
96
|
+
end
|
97
|
+
|
98
|
+
def desuffix(aValue=$/)
|
99
|
+
desuffix!(aValue,self.clone)
|
100
|
+
end
|
101
|
+
|
102
|
+
def begins_with?(aString)
|
103
|
+
self[0,aString.length]==aString
|
104
|
+
end
|
105
|
+
|
106
|
+
def ends_with?(aString)
|
107
|
+
self[-aString.length,aString.length]==aString
|
108
|
+
end
|
109
|
+
|
110
|
+
def ensure_prefix!(aPrefix=$/,aString=self)
|
111
|
+
aString[0,0]=aPrefix unless aString.begins_with?(aPrefix)
|
112
|
+
aString
|
113
|
+
end
|
114
|
+
|
115
|
+
def ensure_prefix(aValue=$/)
|
116
|
+
ensure_prefix!(aValue,self.clone)
|
117
|
+
end
|
118
|
+
|
119
|
+
def ensure_suffix!(aSuffix=$/,aString=self)
|
120
|
+
aString.insert(-1,aSuffix) unless aString.ends_with?(aSuffix)
|
121
|
+
aString
|
122
|
+
end
|
123
|
+
|
124
|
+
def ensure_suffix(aValue=$/)
|
125
|
+
ensure_suffix!(aValue,self.clone)
|
126
|
+
end
|
127
|
+
|
128
|
+
def to_integer(aDefault=nil)
|
129
|
+
t = self.strip
|
130
|
+
return aDefault if t.empty? || !t.index(/^-{0,1}[0-9]+$/)
|
131
|
+
return t.to_i
|
132
|
+
end
|
133
|
+
|
134
|
+
def is_i?
|
135
|
+
self.to_integer(false) and true
|
136
|
+
end
|
137
|
+
|
138
|
+
def to_float(aDefault=nil)
|
139
|
+
t = self.strip
|
140
|
+
return aDefault if !t =~ /(\+|-)?([0-9]+\.?[0-9]*|\.[0-9]+)([eE](\+|-)?[0-9]+)?/
|
141
|
+
return t.to_f
|
142
|
+
end
|
143
|
+
|
144
|
+
def is_f?
|
145
|
+
self.to_float(false) and true
|
146
|
+
end
|
147
|
+
|
148
|
+
# like scan but returns array of MatchData's.
|
149
|
+
# doesn't yet support blocks
|
150
|
+
def scan_md(aPattern)
|
151
|
+
result = []
|
152
|
+
self.scan(aPattern) {|s| result << $~ }
|
153
|
+
result
|
154
|
+
end
|
155
|
+
|
156
|
+
def to_nil(aPattern=nil)
|
157
|
+
return nil if self.empty?
|
158
|
+
if aPattern
|
159
|
+
return nil if (aPattern.is_a? Regexp) && (self =~ aPattern)
|
160
|
+
return nil if aPattern.to_s == self
|
161
|
+
end
|
162
|
+
self
|
163
|
+
end
|
164
|
+
|
165
|
+
def to_b(aDefault=false)
|
166
|
+
return true if ['1','yes','y','true','on'].include?(self.downcase)
|
167
|
+
return false if ['0','no','n','false','off'].include?(self.downcase)
|
168
|
+
aDefault
|
169
|
+
end
|
170
|
+
|
171
|
+
# "...Only alphanumerics [0-9a-zA-Z], the special characters "$-_.+!*'()," [not including the quotes - ed], and reserved characters used for their reserved purposes may be used unencoded within a URL."
|
172
|
+
|
173
|
+
URLIZE_SEPARATORS = /[ \\\(\)\[\]\.*,]/ # was /[ \\\(\)\[\]\.*,]/
|
174
|
+
URLIZE_EXTENSIONS = %w(html htm jpg jpeg png gif bmp mov avi mp3 zip pdf css js doc xdoc)
|
175
|
+
URLIZE_REMOVE = /[^a-z0-9\_\-+~\/]/ # was 'a-z0-9_-+~/'
|
176
|
+
# aKeepExtensions may be an array of extensions to keep, or :none (will remove periods) or :all (any extension <= 4 chars)
|
177
|
+
def urlize(aSlashChar='+',aRemove=nil,aKeepExtensions=nil)
|
178
|
+
aKeepExtensions=URLIZE_EXTENSIONS if !aKeepExtensions
|
179
|
+
aRemove=URLIZE_REMOVE if !aRemove
|
180
|
+
return self if self.empty?
|
181
|
+
result = self.downcase
|
182
|
+
ext = nil
|
183
|
+
if (aKeepExtensions!=:none) && last_dot = result.rindex('.')
|
184
|
+
if (ext_len = result.length-last_dot-1) <= 4 # preserve extension without dot if <= 4 chars long
|
185
|
+
ext = result[last_dot+1..-1]
|
186
|
+
ext = nil unless aKeepExtensions==:all || (aKeepExtensions.is_a?(Array) && aKeepExtensions.include?(ext))
|
187
|
+
result = result[0,last_dot] if ext
|
188
|
+
end
|
189
|
+
end
|
190
|
+
|
191
|
+
result = result.gsub(URLIZE_SEPARATORS,'-')
|
192
|
+
result = result.gsub(aRemove,'').sub(/-+$/,'').sub(/^-+/,'')
|
193
|
+
result.gsub!('/',aSlashChar) unless aSlashChar=='/'
|
194
|
+
result.gsub!(/-{2,}/,'-')
|
195
|
+
result += '.'+ext if ext
|
196
|
+
result
|
197
|
+
end
|
198
|
+
|
199
|
+
def has_tags?
|
200
|
+
index(/<[a-zA-Z\-:0-9]+(\b|>)/) && (index('/>') || index('</')) # contains an opening and closing tag
|
201
|
+
end
|
202
|
+
|
203
|
+
def snake_case
|
204
|
+
underscore.tr(' ','_')
|
205
|
+
end
|
206
|
+
|
207
|
+
def relative_url?
|
208
|
+
!begins_with?('http') || !begins_with?('/')
|
209
|
+
end
|
210
|
+
|
211
|
+
def to_file(aFilename)
|
212
|
+
File.open(aFilename,'wb') {|file| file.write self }
|
213
|
+
end
|
214
|
+
|
215
|
+
def self.from_file(aFilename)
|
216
|
+
File.open(aFilename, "rb") { |f| f.read }
|
217
|
+
end
|
218
|
+
end
|
219
|
+
|
220
|
+
|
221
|
+
Symbol.class_eval do
|
222
|
+
def to_nil
|
223
|
+
self
|
224
|
+
end
|
225
|
+
end
|
@@ -0,0 +1,84 @@
|
|
1
|
+
Time.class_eval do
|
2
|
+
|
3
|
+
if !respond_to?(:change) # no activesupport loaded
|
4
|
+
def change(options)
|
5
|
+
::Time.send(
|
6
|
+
self.utc? ? :utc : :local,
|
7
|
+
options[:year] || self.year,
|
8
|
+
options[:month] || self.month,
|
9
|
+
options[:day] || self.day,
|
10
|
+
options[:hour] || self.hour,
|
11
|
+
options[:min] || (options[:hour] ? 0 : self.min),
|
12
|
+
options[:sec] || ((options[:hour] || options[:min]) ? 0 : self.sec),
|
13
|
+
options[:usec] || ((options[:hour] || options[:min] || options[:sec]) ? 0 : self.usec)
|
14
|
+
)
|
15
|
+
end
|
16
|
+
|
17
|
+
def seconds_since_midnight
|
18
|
+
self.to_i - self.change(:hour => 0).to_i + (self.usec/1.0e+6)
|
19
|
+
end
|
20
|
+
|
21
|
+
def beginning_of_day
|
22
|
+
(self - self.seconds_since_midnight).change(:usec => 0)
|
23
|
+
end
|
24
|
+
|
25
|
+
alias :midnight :beginning_of_day
|
26
|
+
alias :at_midnight :beginning_of_day
|
27
|
+
alias :at_beginning_of_day :beginning_of_day
|
28
|
+
|
29
|
+
end
|
30
|
+
|
31
|
+
# offset of local machine from UTC, in seconds eg +9.hours
|
32
|
+
def self.local_offset
|
33
|
+
local(2000).utc_offset
|
34
|
+
end
|
35
|
+
|
36
|
+
def date
|
37
|
+
self.at_beginning_of_day
|
38
|
+
end
|
39
|
+
|
40
|
+
# index number of this day, from Time.at(0) + utc_offset
|
41
|
+
def day_number
|
42
|
+
(self.to_i+self.utc_offset) / 86400
|
43
|
+
end
|
44
|
+
|
45
|
+
# index number of this utc day
|
46
|
+
def day_number_utc
|
47
|
+
self.to_i / 86400
|
48
|
+
end
|
49
|
+
|
50
|
+
# the last microsecond of the day
|
51
|
+
def day_end
|
52
|
+
self.at_beginning_of_day + 86399.999999
|
53
|
+
end
|
54
|
+
|
55
|
+
def date_numeric
|
56
|
+
self.strftime('%Y%m%d')
|
57
|
+
end
|
58
|
+
|
59
|
+
def to_universal
|
60
|
+
self.strftime("%d %b %Y")
|
61
|
+
end
|
62
|
+
|
63
|
+
# create a new Time from eg. "20081231"
|
64
|
+
def self.from_date_numeric(aString)
|
65
|
+
return nil unless aString
|
66
|
+
local(aString[0,4].to_i,aString[4,2].to_i,aString[6,2].to_i)
|
67
|
+
end
|
68
|
+
|
69
|
+
def time_numeric
|
70
|
+
self.strftime('%H%M%S')
|
71
|
+
end
|
72
|
+
|
73
|
+
def datetime_numeric
|
74
|
+
self.strftime('%Y%m%d-%H%M%S')
|
75
|
+
end
|
76
|
+
|
77
|
+
def to_sql_format # was to_sql, but clashed with Rails 3
|
78
|
+
self.strftime('%Y-%m-%d %H:%M:%S')
|
79
|
+
end
|
80
|
+
|
81
|
+
def to_w3c
|
82
|
+
utc.strftime("%Y-%m-%dT%H:%M:%S+00:00")
|
83
|
+
end
|
84
|
+
end
|
metadata
ADDED
@@ -0,0 +1,88 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: buzztools
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.0.3
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Gary McGhee
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
date: 2013-12-12 00:00:00.000000000 Z
|
12
|
+
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: bundler
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - ! '>='
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: '1.3'
|
20
|
+
type: :development
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - ! '>='
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: '1.3'
|
27
|
+
- !ruby/object:Gem::Dependency
|
28
|
+
name: rake
|
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
|
+
description: reusable function library
|
42
|
+
email:
|
43
|
+
- contact@buzzware.com.au
|
44
|
+
executables: []
|
45
|
+
extensions: []
|
46
|
+
extra_rdoc_files: []
|
47
|
+
files:
|
48
|
+
- .gitignore
|
49
|
+
- Gemfile
|
50
|
+
- LICENSE.txt
|
51
|
+
- README.md
|
52
|
+
- Rakefile
|
53
|
+
- buzztools.gemspec
|
54
|
+
- lib/buzztools.rb
|
55
|
+
- lib/buzztools/extend_array.rb
|
56
|
+
- lib/buzztools/extend_bignum.rb
|
57
|
+
- lib/buzztools/extend_fixnum.rb
|
58
|
+
- lib/buzztools/extend_hash.rb
|
59
|
+
- lib/buzztools/extend_more.rb
|
60
|
+
- lib/buzztools/extend_object.rb
|
61
|
+
- lib/buzztools/extend_string.rb
|
62
|
+
- lib/buzztools/extend_time.rb
|
63
|
+
- lib/buzztools/version.rb
|
64
|
+
homepage: https://github.com/buzzware/buzztools
|
65
|
+
licenses:
|
66
|
+
- MIT
|
67
|
+
metadata: {}
|
68
|
+
post_install_message:
|
69
|
+
rdoc_options: []
|
70
|
+
require_paths:
|
71
|
+
- lib
|
72
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
73
|
+
requirements:
|
74
|
+
- - ! '>='
|
75
|
+
- !ruby/object:Gem::Version
|
76
|
+
version: '0'
|
77
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
78
|
+
requirements:
|
79
|
+
- - ! '>='
|
80
|
+
- !ruby/object:Gem::Version
|
81
|
+
version: '0'
|
82
|
+
requirements: []
|
83
|
+
rubyforge_project:
|
84
|
+
rubygems_version: 2.1.11
|
85
|
+
signing_key:
|
86
|
+
specification_version: 4
|
87
|
+
summary: reusable function library
|
88
|
+
test_files: []
|