kelredd-useful 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.
- data/README.rdoc +44 -0
- data/Rakefile +40 -0
- data/lib/useful/ruby_extensions/array.rb +45 -0
- data/lib/useful/ruby_extensions/fixnum.rb +30 -0
- data/lib/useful/ruby_extensions/hash.rb +108 -0
- data/lib/useful/ruby_extensions/numeric.rb +255 -0
- data/lib/useful/ruby_extensions/object.rb +23 -0
- data/lib/useful/ruby_extensions/string.rb +51 -0
- data/lib/useful/ruby_extensions.rb +7 -0
- data/lib/useful/sinatra_helpers/environment_tests.rb +17 -0
- data/lib/useful/sinatra_helpers/erb/error_pages.rb +23 -0
- data/lib/useful/sinatra_helpers/erb/partials.rb +42 -0
- data/lib/useful/sinatra_helpers/erb.rb +3 -0
- data/lib/useful/sinatra_helpers/tags.rb +89 -0
- data/lib/useful/sinatra_helpers.rb +4 -0
- data/lib/useful/version.rb +13 -0
- data/lib/useful.rb +2 -0
- data/test/test_helper.rb +10 -0
- data/test/unit/useful_test.rb +13 -0
- metadata +77 -0
data/README.rdoc
ADDED
@@ -0,0 +1,44 @@
|
|
1
|
+
= Useful
|
2
|
+
|
3
|
+
== Description
|
4
|
+
|
5
|
+
A collection of useful helpers for various ruby things. Includes
|
6
|
+
helpers for sinatra, ruby base classes, mysql, rails, erb, etc...
|
7
|
+
|
8
|
+
You probably never want them all, all the time, but just require in
|
9
|
+
the pieces you are interested in.
|
10
|
+
|
11
|
+
== Installation
|
12
|
+
|
13
|
+
sudo gem install kelredd-useful --source http://gems.github.com
|
14
|
+
|
15
|
+
== Usage
|
16
|
+
|
17
|
+
require 'rubygems'
|
18
|
+
require 'useful/sinatra_helpers'
|
19
|
+
require 'useful/mysql_helpers'
|
20
|
+
|
21
|
+
== License
|
22
|
+
|
23
|
+
Copyright (c) 2009 Kelly Redding
|
24
|
+
|
25
|
+
Permission is hereby granted, free of charge, to any person
|
26
|
+
obtaining a copy of this software and associated documentation
|
27
|
+
files (the "Software"), to deal in the Software without
|
28
|
+
restriction, including without limitation the rights to use,
|
29
|
+
copy, modify, merge, publish, distribute, sublicense, and/or sell
|
30
|
+
copies of the Software, and to permit persons to whom the
|
31
|
+
Software is furnished to do so, subject to the following
|
32
|
+
conditions:
|
33
|
+
|
34
|
+
The above copyright notice and this permission notice shall be
|
35
|
+
included in all copies or substantial portions of the Software.
|
36
|
+
|
37
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
38
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
|
39
|
+
OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
40
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
|
41
|
+
HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
|
42
|
+
WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
43
|
+
FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
|
44
|
+
OTHER DEALINGS IN THE SOFTWARE.
|
data/Rakefile
ADDED
@@ -0,0 +1,40 @@
|
|
1
|
+
require 'rubygems'
|
2
|
+
require 'rake/gempackagetask'
|
3
|
+
require 'rake/testtask'
|
4
|
+
|
5
|
+
require 'lib/useful/version'
|
6
|
+
|
7
|
+
task :default => :test
|
8
|
+
|
9
|
+
spec = Gem::Specification.new do |s|
|
10
|
+
s.name = 'useful'
|
11
|
+
s.version = Useful::Version.to_s
|
12
|
+
s.has_rdoc = true
|
13
|
+
s.extra_rdoc_files = %w(README.rdoc)
|
14
|
+
s.rdoc_options = %w(--main README.rdoc)
|
15
|
+
s.summary = "A collection of useful helpers for various ruby things."
|
16
|
+
s.author = 'Kelredd'
|
17
|
+
s.email = ''
|
18
|
+
s.homepage = ''
|
19
|
+
s.files = %w(README.rdoc Rakefile) + Dir.glob("{lib,test}/**/*")
|
20
|
+
# s.executables = ['useful']
|
21
|
+
|
22
|
+
# s.add_dependency('gem_name', '~> 0.0.1')
|
23
|
+
end
|
24
|
+
|
25
|
+
Rake::GemPackageTask.new(spec) do |pkg|
|
26
|
+
pkg.gem_spec = spec
|
27
|
+
end
|
28
|
+
|
29
|
+
Rake::TestTask.new do |t|
|
30
|
+
t.libs << 'test'
|
31
|
+
t.test_files = FileList["test/**/*_test.rb"]
|
32
|
+
t.verbose = true
|
33
|
+
end
|
34
|
+
|
35
|
+
desc 'Generate the gemspec to serve this Gem from Github'
|
36
|
+
task :github do
|
37
|
+
file = File.dirname(__FILE__) + "/#{spec.name}.gemspec"
|
38
|
+
File.open(file, 'w') {|f| f << spec.to_ruby }
|
39
|
+
puts "Created gemspec: #{file}"
|
40
|
+
end
|
@@ -0,0 +1,45 @@
|
|
1
|
+
module Useful
|
2
|
+
module RubyExtensions
|
3
|
+
module Array
|
4
|
+
|
5
|
+
module ClassMethods; end
|
6
|
+
def self.included(klass)
|
7
|
+
klass.extend(ClassMethods) if klass.kind_of?(Class)
|
8
|
+
end
|
9
|
+
|
10
|
+
module ClassMethods
|
11
|
+
|
12
|
+
# adds the contents of a2 to a1, removing duplicates
|
13
|
+
def merge(a1,a2)
|
14
|
+
a2.each{|item| a1 << item unless a1.include?(item)}
|
15
|
+
a1
|
16
|
+
end
|
17
|
+
|
18
|
+
end
|
19
|
+
|
20
|
+
# returns a new array, containing the contents of an_a with the contents of this array, removing duplicates
|
21
|
+
def merge(an_a)
|
22
|
+
self.class.merge(self.clone, an_a)
|
23
|
+
end
|
24
|
+
# adds the contents of an_a to this array, removing duplicates (inline version of #merge)
|
25
|
+
def merge!(an_a)
|
26
|
+
self.class.merge(self, an_a)
|
27
|
+
end
|
28
|
+
|
29
|
+
# split into an array of sized-arrays
|
30
|
+
def groups(size=1)
|
31
|
+
return [] if size <= 0
|
32
|
+
n,r = self.size.divmod(size)
|
33
|
+
grps = (0..(n-1)).collect{|i| self[i*size,size]}
|
34
|
+
r > 0 ? grps << self[-r,r] : grps
|
35
|
+
end
|
36
|
+
alias / groups
|
37
|
+
alias chunks groups
|
38
|
+
|
39
|
+
end
|
40
|
+
end
|
41
|
+
end
|
42
|
+
|
43
|
+
class Array
|
44
|
+
include Useful::RubyExtensions::Array
|
45
|
+
end
|
@@ -0,0 +1,30 @@
|
|
1
|
+
module Useful
|
2
|
+
module RubyExtensions
|
3
|
+
module Fixnum
|
4
|
+
|
5
|
+
# returns a string reprensentation of the number padded with pad_num to a specified length
|
6
|
+
def pad(length = 3, pad_num = 0)
|
7
|
+
self.to_s.rjust(length,pad_num.to_s) rescue self.to_s
|
8
|
+
end
|
9
|
+
|
10
|
+
# return the value in values that is nearest to the number
|
11
|
+
def to_nearest_value(values = [])
|
12
|
+
return self if values.length == 0
|
13
|
+
value = values.first.to_i rescue self
|
14
|
+
diff = (self-value).abs
|
15
|
+
values.each do |val|
|
16
|
+
if (self-val.to_i).abs < diff
|
17
|
+
diff = (self-val.to_i).abs
|
18
|
+
value = val.to_i
|
19
|
+
end
|
20
|
+
end
|
21
|
+
value
|
22
|
+
end
|
23
|
+
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
class Fixnum
|
29
|
+
include Useful::RubyExtensions::Fixnum
|
30
|
+
end
|
@@ -0,0 +1,108 @@
|
|
1
|
+
require 'cgi'
|
2
|
+
|
3
|
+
module Useful
|
4
|
+
module RubyExtensions
|
5
|
+
module Hash
|
6
|
+
|
7
|
+
module ClassMethods; end
|
8
|
+
def self.included(klass)
|
9
|
+
klass.extend(ClassMethods) if klass.kind_of?(Class)
|
10
|
+
end
|
11
|
+
|
12
|
+
module ClassMethods
|
13
|
+
|
14
|
+
# inspired by ActiveSupport::CoreExtensions::Hash::Keys (http://api.rubyonrails.org/)
|
15
|
+
def stringify_keys(hash)
|
16
|
+
hash.keys.each{ |key| hash[(key.to_s rescue key)] ||= hash.delete(key) }
|
17
|
+
hash
|
18
|
+
end
|
19
|
+
|
20
|
+
# inspired by from ActiveSupport::CoreExtensions::Hash::Keys (http://api.rubyonrails.org/)
|
21
|
+
def symbolize_keys(hash)
|
22
|
+
hash.keys.each{ |key| hash[(key.to_sym rescue key)] ||= hash.delete(key) }
|
23
|
+
hash
|
24
|
+
end
|
25
|
+
|
26
|
+
def only(hash, *keys)
|
27
|
+
hash.delete_if{ |k,v| !keys.flatten.include?(k) }
|
28
|
+
hash
|
29
|
+
end
|
30
|
+
|
31
|
+
def except(hash, *keys)
|
32
|
+
hash.delete_if{ |k,v| keys.flatten.include?(k) }
|
33
|
+
hash
|
34
|
+
end
|
35
|
+
|
36
|
+
end
|
37
|
+
|
38
|
+
# Return a new hash with all keys converted to strings.
|
39
|
+
def stringify_keys
|
40
|
+
self.class.stringify_keys(self.clone)
|
41
|
+
end
|
42
|
+
# Destructively convert all keys to strings.
|
43
|
+
def stringify_keys!
|
44
|
+
self.class.stringify_keys(self)
|
45
|
+
end
|
46
|
+
|
47
|
+
# Return a new hash with all keys converted to strings.
|
48
|
+
def symbolize_keys
|
49
|
+
self.class.symbolize_keys(self.clone)
|
50
|
+
end
|
51
|
+
# Destructively convert all keys to strings.
|
52
|
+
def symbolize_keys!
|
53
|
+
self.class.symbolize_keys(self)
|
54
|
+
end
|
55
|
+
|
56
|
+
# Return a new hash with only keys in *keys
|
57
|
+
def only(*keys)
|
58
|
+
self.class.only(self.clone, keys)
|
59
|
+
end
|
60
|
+
# Destructively remove all keys not in *keys
|
61
|
+
def only!(*keys)
|
62
|
+
self.class.only(self, keys)
|
63
|
+
end
|
64
|
+
|
65
|
+
# Return a new hash with only keys not in *keys
|
66
|
+
def except(*keys)
|
67
|
+
self.class.except(self.clone, keys)
|
68
|
+
end
|
69
|
+
# Destructively remove all keys in *keys
|
70
|
+
def except!(*keys)
|
71
|
+
self.class.except(self, keys)
|
72
|
+
end
|
73
|
+
|
74
|
+
# Determines if a value exists for the provided key(s). Allows searching in nested hashes
|
75
|
+
def check_value?(*keys)
|
76
|
+
val = self[keys.first] || self[keys.first.to_s]
|
77
|
+
val = self[keys.first.to_s.intern] unless val || keys.first.kind_of?(Symbol)
|
78
|
+
return val.check_value?(*keys[1..-1]) if val.kind_of?(Hash) && keys.length > 1
|
79
|
+
return true if val && !val.empty?
|
80
|
+
false
|
81
|
+
end
|
82
|
+
|
83
|
+
# takes any empty values and makes them nil inline
|
84
|
+
def nillify!
|
85
|
+
self.each { |key,value| self[key] = nil if !value.nil? && value.to_s.empty? }
|
86
|
+
end
|
87
|
+
|
88
|
+
# Returns string formatted for HTTP URL encoded name-value pairs.
|
89
|
+
# For example,
|
90
|
+
# {:id => 'thomas_hardy'}.to_http_str
|
91
|
+
# # => "id=thomas_hardy"
|
92
|
+
# {:id => 23423, :since => Time.now}.to_http_str
|
93
|
+
# # => "since=Thu,%2021%20Jun%202007%2012:10:05%20-0500&id=23423"
|
94
|
+
def to_http_str
|
95
|
+
self.empty? ? '' : self.collect{|key, val| "#{key.to_s}=#{CGI.escape(val.to_s)}"}.join('&')
|
96
|
+
end
|
97
|
+
|
98
|
+
def to_html_attrs
|
99
|
+
self.empty? ? '' : self.collect{|key, val| "#{key}=\"#{val}\""}.join(' ')
|
100
|
+
end
|
101
|
+
|
102
|
+
end
|
103
|
+
end
|
104
|
+
end
|
105
|
+
|
106
|
+
class Hash
|
107
|
+
include Useful::RubyExtensions::Hash
|
108
|
+
end
|
@@ -0,0 +1,255 @@
|
|
1
|
+
require File.join(File.dirname(__FILE__), 'object')
|
2
|
+
require File.join(File.dirname(__FILE__), 'string')
|
3
|
+
require File.join(File.dirname(__FILE__), 'hash')
|
4
|
+
|
5
|
+
module Useful
|
6
|
+
module RubyExtensions
|
7
|
+
module Numeric #:nodoc:
|
8
|
+
|
9
|
+
LOCALES = {
|
10
|
+
:en => {
|
11
|
+
:currency => {:format => "%u%n", :unit=> '$'},
|
12
|
+
:storage => {:format => "%n %u", :delimiter => ''},
|
13
|
+
:format => {:delimiter => ',', :separator => '.'},
|
14
|
+
:defaults => {:precision => 2}
|
15
|
+
}
|
16
|
+
}.freeze
|
17
|
+
STORAGE_UNITS = [:bytes, :kb, :mb, :gb, :tb].freeze
|
18
|
+
|
19
|
+
module ClassMethods; end
|
20
|
+
def self.included(klass)
|
21
|
+
klass.extend(ClassMethods) if klass.kind_of?(Class)
|
22
|
+
end
|
23
|
+
|
24
|
+
module ClassMethods
|
25
|
+
|
26
|
+
def pad_precision(num, opts = {})
|
27
|
+
opts[:precision] ||= 2
|
28
|
+
opts[:separator] ||= '.'
|
29
|
+
opts[:pad_number] ||= 0
|
30
|
+
num.to_s.ljust(num.to_s.split(opts[:separator])[0].length + num.to_s.count(opts[:separator]) + opts[:precision].to_i, opts[:pad_number].to_s)
|
31
|
+
end
|
32
|
+
|
33
|
+
end
|
34
|
+
|
35
|
+
# Formats a +number+ with grouped thousands using +delimiter+ (e.g., 12,324). You can
|
36
|
+
# customize the format in the +options+ hash.
|
37
|
+
# => taken and inspired from ActionView::Helpers::NumberHelper (http://api.rubyonrails.org/)
|
38
|
+
#
|
39
|
+
# ==== Options
|
40
|
+
# * <tt>:delimiter</tt> - Sets the thousands delimiter (defaults to ",").
|
41
|
+
# * <tt>:separator</tt> - Sets the separator between the units (defaults to ".").
|
42
|
+
#
|
43
|
+
# ==== Examples
|
44
|
+
# 12345678.with_delimiter # => 12,345,678
|
45
|
+
# 12345678.05.with_delimiter # => 12,345,678.05
|
46
|
+
# 12345678.with_delimiter(:delimiter => ".") # => 12.345.678
|
47
|
+
# 12345678.with_delimiter(:seperator => ",") # => 12,345,678
|
48
|
+
# 98765432.98.with_delimiter(:delimiter => " ", :separator => ",")
|
49
|
+
# # => 98 765 432,98
|
50
|
+
def with_delimiter(opts = {})
|
51
|
+
number = self.to_s.strip
|
52
|
+
opts.symbolize_keys!
|
53
|
+
opts[:locale] ||= :en
|
54
|
+
locale = LOCALES[opts.delete(:locale)]
|
55
|
+
opts = locale[:format].merge(opts) unless locale.nil?
|
56
|
+
opts[:delimiter] ||= ','
|
57
|
+
opts[:separator] ||= '.'
|
58
|
+
|
59
|
+
begin
|
60
|
+
parts = number.to_s.split('.')
|
61
|
+
parts[0].gsub!(/(\d)(?=(\d\d\d)+(?!\d))/, "\\1#{opts[:delimiter]}")
|
62
|
+
parts.join(opts[:separator])
|
63
|
+
rescue
|
64
|
+
number
|
65
|
+
end
|
66
|
+
end
|
67
|
+
|
68
|
+
# Converts a +number+ with the specified level of <tt>:precision</tt> (e.g., 112.32 has a precision of 2).
|
69
|
+
# => taken and inspired from ActionView::Helpers::NumberHelper (http://api.rubyonrails.org/)
|
70
|
+
def to_precision(precision = 2)
|
71
|
+
rounded_number = (Float(self) * (10 ** precision)).round
|
72
|
+
rounded_number = rounded_number.to_f if precision > 0
|
73
|
+
(rounded_number / 10 ** precision) rescue self
|
74
|
+
end
|
75
|
+
|
76
|
+
# Formats a +number+ with the specified level of <tt>:precision</tt> (e.g., 112.32 has a precision of 2).
|
77
|
+
# You can customize the format in the +options+ hash.
|
78
|
+
# => taken and inspired from ActionView::Helpers::NumberHelper (http://api.rubyonrails.org/)
|
79
|
+
#
|
80
|
+
# ==== Options
|
81
|
+
# * <tt>:precision</tt> - Sets the level of precision (defaults to 3).
|
82
|
+
# * <tt>:separator</tt> - Sets the separator between the units (defaults to ".").
|
83
|
+
# * <tt>:delimiter</tt> - Sets the thousands delimiter (defaults to "").
|
84
|
+
#
|
85
|
+
# ==== Examples (:locale => :en)
|
86
|
+
# 111.2345.with_precision # => 111.235
|
87
|
+
# 111.2345.with_precision(:precision => 2) # => 111.23
|
88
|
+
# 13.with_precision(:precision => 5) # => 13.00000
|
89
|
+
# 389.32314.with_precision(:precision => 0) # => 389
|
90
|
+
# 1111.2345.with_precision(:precision => 2, :separator => ',', :delimiter => '.')
|
91
|
+
# # => 1,111.23
|
92
|
+
def with_precision(opts = {})
|
93
|
+
opts.symbolize_keys!
|
94
|
+
opts[:locale] ||= :en
|
95
|
+
locale = LOCALES[opts.delete(:locale)]
|
96
|
+
opts = locale[:defaults].merge(locale[:format]).merge(opts) unless locale.nil?
|
97
|
+
opts[:precision] ||= 2
|
98
|
+
|
99
|
+
self.class.pad_precision(self.to_precision(opts[:precision]).with_delimiter(opts.only(:separator, :delimiter)), opts) rescue self
|
100
|
+
end
|
101
|
+
|
102
|
+
# Formats a +number+ as a percentage string (e.g., 65%). You can customize the
|
103
|
+
# format in the +options+ hash.
|
104
|
+
#
|
105
|
+
# ==== Options
|
106
|
+
# * <tt>:precision</tt> - Sets the level of precision (defaults to 2).
|
107
|
+
# * <tt>:separator</tt> - Sets the separator between the units (defaults to ".").
|
108
|
+
# * <tt>:delimiter</tt> - Sets the thousands delimiter (defaults to "").
|
109
|
+
#
|
110
|
+
# ==== Examples
|
111
|
+
# 100.to_percentage # => 100.00%
|
112
|
+
# 100.to_percentage(:precision => 0) # => 100%
|
113
|
+
# 1000.to_percentage(:delimiter => '.', :separator => ',') # => 1.000,00%
|
114
|
+
# 302.24398923423.to_percentage(:precision => 5) # => 302.24399%
|
115
|
+
def to_percentage(opts = {})
|
116
|
+
opts.symbolize_keys!
|
117
|
+
opts[:locale] ||= :en
|
118
|
+
locale = LOCALES[opts.delete(:locale)]
|
119
|
+
opts = locale[:defaults].merge(locale[:format]).merge(opts) unless locale.nil?
|
120
|
+
|
121
|
+
"#{self.with_precision(opts.only(:precision, :separator, :delimiter))}%" rescue self
|
122
|
+
end
|
123
|
+
|
124
|
+
# Formats a +number+ into a currency string (e.g., $13.65). You can customize the format
|
125
|
+
# in the +options+ hash.
|
126
|
+
# => taken and inspired from ActionView::Helpers::NumberHelper (http://api.rubyonrails.org/)
|
127
|
+
#
|
128
|
+
# ==== Options
|
129
|
+
# * <tt>:precision</tt> - Sets the level of precision (defaults to 2).
|
130
|
+
# * <tt>:unit</tt> - Sets the denomination of the currency (defaults to "$").
|
131
|
+
# * <tt>:separator</tt> - Sets the separator between the units (defaults to ".").
|
132
|
+
# * <tt>:delimiter</tt> - Sets the thousands delimiter (defaults to ",").
|
133
|
+
# * <tt>:format</tt> - Sets the format of the output string (defaults to "%u%n"). The field types are:
|
134
|
+
# %u The currency unit
|
135
|
+
# %n The number
|
136
|
+
#
|
137
|
+
# ==== Examples (:locale => :en)
|
138
|
+
# 1234567890.50.to_currency # => $1,234,567,890.50
|
139
|
+
# 1234567890.506.to_currency # => $1,234,567,890.51
|
140
|
+
# 1234567890.506.to_currency(:precision => 3) # => $1,234,567,890.506
|
141
|
+
#
|
142
|
+
# 1234567890.50.to_currency(:unit => "£", :separator => ",", :delimiter => "")
|
143
|
+
# # => £1234567890,50
|
144
|
+
# 1234567890.50.to_currency(:unit => "£", :separator => ",", :delimiter => "", :format => "%n %u")
|
145
|
+
# # => 1234567890,50 £
|
146
|
+
def to_currency(opts = {})
|
147
|
+
opts.symbolize_keys!
|
148
|
+
opts[:locale] ||= :en
|
149
|
+
locale = LOCALES[opts.delete(:locale)]
|
150
|
+
opts = locale[:defaults].merge(locale[:format]).merge(locale[:currency]).merge(opts) unless locale.nil?
|
151
|
+
|
152
|
+
opts[:format].gsub(/%n/, self.with_precision(opts.only(:precision, :delimiter, :separator))).gsub(/%u/, opts[:unit]) #rescue self
|
153
|
+
end
|
154
|
+
|
155
|
+
# Formats the bytes in +size+ into a more understandable representation
|
156
|
+
# (e.g., giving it 1500 yields 1.5 KB). This method is useful for
|
157
|
+
# reporting file sizes to users. This method returns nil if
|
158
|
+
# +size+ cannot be converted into a number. You can customize the
|
159
|
+
# format in the +options+ hash.
|
160
|
+
#
|
161
|
+
# ==== Options
|
162
|
+
# * <tt>:precision</tt> - Sets the level of precision (defaults to 2).
|
163
|
+
# * <tt>:separator</tt> - Sets the separator between the units (defaults to ".").
|
164
|
+
# * <tt>:delimiter</tt> - Sets the thousands delimiter (defaults to "").
|
165
|
+
#
|
166
|
+
# ==== Examples
|
167
|
+
# 123.to_storage_size # => 123 Bytes
|
168
|
+
# 1234.to_storage_size # => 1.2 KB
|
169
|
+
# 12345.to_storage_size # => 12.1 KB
|
170
|
+
# 1234567.to_storage_size # => 1.2 MB
|
171
|
+
# 1234567890.to_storage_size # => 1.1 GB
|
172
|
+
# 1234567890123.to_storage_size # => 1.1 TB
|
173
|
+
# 1234567.to_storage_size(:precision => 2) # => 1.18 MB
|
174
|
+
# 483989.to_storage_size(:precision => 0) # => 473 KB
|
175
|
+
# 1234567.to_storage_size(:precision => 2, :separator => ',') # => 1,18 MB
|
176
|
+
def to_storage_size(opts = {})
|
177
|
+
return nil if self.nil?
|
178
|
+
opts.symbolize_keys!
|
179
|
+
opts[:locale] ||= :en
|
180
|
+
locale = LOCALES[opts.delete(:locale)]
|
181
|
+
opts = locale[:defaults].merge(locale[:format]).merge(locale[:storage]).merge(opts) unless locale.nil?
|
182
|
+
opts[:format] ||= "%n %u"
|
183
|
+
|
184
|
+
value = self.to_f
|
185
|
+
unit = ''
|
186
|
+
STORAGE_UNITS.each do |storage_unit|
|
187
|
+
unit = storage_unit.to_s.capitalize
|
188
|
+
return opts[:format].gsub(/%n/, value.with_precision(opts.only(:precision, :delimiter, :separator))).gsub(/%u/, unit) if value < 1024 || storage_unit == STORAGE_UNITS.last
|
189
|
+
value /= 1024.0
|
190
|
+
end
|
191
|
+
end
|
192
|
+
|
193
|
+
# Returns the string representation of the number's +parity+.
|
194
|
+
#
|
195
|
+
# ==== Examples
|
196
|
+
# 1.to_parity # => "odd"
|
197
|
+
# 2.to_parity # => "even"
|
198
|
+
def to_parity
|
199
|
+
self.to_i.even? ? 'even' : 'odd'
|
200
|
+
end
|
201
|
+
|
202
|
+
# Provides methods for converting numbers into formatted strings.
|
203
|
+
# Methods are provided for phone numbers, currency, percentage,
|
204
|
+
# precision, positional notation, and file size.
|
205
|
+
# => taken and inspired from ActionView::Helpers::NumberHelper (http://api.rubyonrails.org/)
|
206
|
+
|
207
|
+
# Formats a +number+ into a US phone number (e.g., (555) 123-9876). You can customize the format
|
208
|
+
# in the +options+ hash.
|
209
|
+
#
|
210
|
+
# ==== Options
|
211
|
+
# * <tt>:area_code</tt> - Adds parentheses around the area code.
|
212
|
+
# * <tt>:delimiter</tt> - Specifies the delimiter to use (defaults to "-").
|
213
|
+
# * <tt>:extension</tt> - Specifies an extension to add to the end of the
|
214
|
+
# generated number.
|
215
|
+
# * <tt>:country_code</tt> - Sets the country code for the phone number.
|
216
|
+
#
|
217
|
+
# ==== Examples
|
218
|
+
# 5551234.to_phone # => 555-1234
|
219
|
+
# 1235551234.to_phone # => 123-555-1234
|
220
|
+
# 1235551234.to_phone(:area_code => true) # => (123) 555-1234
|
221
|
+
# 1235551234.to_phone(:delimiter => " ") # => 123 555 1234
|
222
|
+
# 1235551234.to_phone(:area_code => true, :extension => 555) # => (123) 555-1234 x 555
|
223
|
+
# 1235551234.to_phone(:country_code => 1) # => +1-123-555-1234
|
224
|
+
# 1235551234.to_phone({ :country_code => 1,
|
225
|
+
# :extension => 1343, :delimiter => "." }) # => +1.123.555.1234 x 1343
|
226
|
+
def to_phone(opts={})
|
227
|
+
number = self.to_s.strip
|
228
|
+
opts.symbolize_keys!
|
229
|
+
opts[:delimiter] ||= '-'
|
230
|
+
opts[:extension] = opts[:extension].to_s.strip unless opts[:extension].nil?
|
231
|
+
|
232
|
+
begin
|
233
|
+
str = ""
|
234
|
+
str << "+#{opts[:country_code]}#{opts[:delimiter]}" unless opts[:country_code].blank?
|
235
|
+
str << if opts[:area_code]
|
236
|
+
number.gsub!(/([0-9]{1,3})([0-9]{3})([0-9]{4}$)/,"(\\1) \\2#{opts[:delimiter]}\\3")
|
237
|
+
else
|
238
|
+
number.gsub!(/([0-9]{0,3})([0-9]{3})([0-9]{4})$/,"\\1#{opts[:delimiter]}\\2#{opts[:delimiter]}\\3")
|
239
|
+
number.starts_with?('-') ? number.slice!(1..-1) : number
|
240
|
+
end
|
241
|
+
str << " x #{opts[:extension]}" unless opts[:extension].blank?
|
242
|
+
str
|
243
|
+
rescue
|
244
|
+
number
|
245
|
+
end
|
246
|
+
end
|
247
|
+
|
248
|
+
end
|
249
|
+
end
|
250
|
+
end
|
251
|
+
|
252
|
+
class Numeric
|
253
|
+
include Useful::RubyExtensions::Numeric
|
254
|
+
end
|
255
|
+
|
@@ -0,0 +1,23 @@
|
|
1
|
+
module Useful
|
2
|
+
module RubyExtensions
|
3
|
+
module Object
|
4
|
+
|
5
|
+
def false?
|
6
|
+
self == false
|
7
|
+
end
|
8
|
+
|
9
|
+
def true?
|
10
|
+
self == true
|
11
|
+
end
|
12
|
+
|
13
|
+
def blank?
|
14
|
+
self.nil? || self.empty? rescue false
|
15
|
+
end
|
16
|
+
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
class Object
|
22
|
+
include Useful::RubyExtensions::Object
|
23
|
+
end
|
@@ -0,0 +1,51 @@
|
|
1
|
+
module Useful
|
2
|
+
module RubyExtensions
|
3
|
+
module String
|
4
|
+
|
5
|
+
module ClassMethods; end
|
6
|
+
def self.included(klass)
|
7
|
+
klass.extend(ClassMethods) if klass.kind_of?(Class)
|
8
|
+
end
|
9
|
+
|
10
|
+
module ClassMethods
|
11
|
+
|
12
|
+
# adds the contents of a2 to a1, removing duplicates
|
13
|
+
def hsub(string, hash)
|
14
|
+
hash.each {|k,v| string.gsub!(":#{k}",v.to_s)}
|
15
|
+
string
|
16
|
+
end
|
17
|
+
|
18
|
+
end
|
19
|
+
|
20
|
+
# returns a new string, with hash values sub'd in where hash keys exist in original string
|
21
|
+
def hsub(hash)
|
22
|
+
self.class.hsub(self.clone, hash)
|
23
|
+
end
|
24
|
+
# substitutes the keys in hash that exist in the string, with values of hash
|
25
|
+
def hsub!(hash)
|
26
|
+
self.class.hsub(self, hash)
|
27
|
+
end
|
28
|
+
|
29
|
+
def match?(pattern)
|
30
|
+
!self.match(pattern).nil?
|
31
|
+
end
|
32
|
+
|
33
|
+
def starts_with?(string)
|
34
|
+
self.match?(Regexp.new("\\A#{string}"))
|
35
|
+
end
|
36
|
+
|
37
|
+
def show_regexp(re)
|
38
|
+
if self =~ re
|
39
|
+
"#{$`}<<#{$&}>>#{$'}"
|
40
|
+
else
|
41
|
+
"no match"
|
42
|
+
end
|
43
|
+
end
|
44
|
+
|
45
|
+
end
|
46
|
+
end
|
47
|
+
end
|
48
|
+
|
49
|
+
class String
|
50
|
+
include Useful::RubyExtensions::String
|
51
|
+
end
|
@@ -0,0 +1,17 @@
|
|
1
|
+
require 'sinatra/base'
|
2
|
+
|
3
|
+
module Sinatra
|
4
|
+
module SinatraHelpers
|
5
|
+
module EnvironmentTests
|
6
|
+
def production?
|
7
|
+
Sinatra::Application.environment.to_s == 'production'
|
8
|
+
end
|
9
|
+
def development?
|
10
|
+
Sinatra::Application.environment.to_s == 'development'
|
11
|
+
end
|
12
|
+
end
|
13
|
+
end
|
14
|
+
|
15
|
+
Sinatra::Application.helpers Sinatra::SinatraHelpers::EnvironmentTests
|
16
|
+
Sinatra::Application.register Sinatra::SinatraHelpers::EnvironmentTests
|
17
|
+
end
|
@@ -0,0 +1,23 @@
|
|
1
|
+
require 'sinatra/base'
|
2
|
+
|
3
|
+
module Sinatra
|
4
|
+
module SinatraHelpers
|
5
|
+
module Erb
|
6
|
+
module ErrorPages
|
7
|
+
def self.registered(app)
|
8
|
+
app.configure :production do
|
9
|
+
app.not_found do
|
10
|
+
erb :'404.html'
|
11
|
+
end
|
12
|
+
app.error do
|
13
|
+
@err = request.env['sinatra_error']
|
14
|
+
erb :'500.html'
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
22
|
+
Sinatra::Application.register Sinatra::SinatraHelpers::Erb::ErrorPages
|
23
|
+
end
|
@@ -0,0 +1,42 @@
|
|
1
|
+
require 'sinatra/base'
|
2
|
+
|
3
|
+
module Sinatra
|
4
|
+
module SinatraHelpers
|
5
|
+
module Erb
|
6
|
+
module Partials
|
7
|
+
|
8
|
+
# helper to emulate rails 'render :partial' helper, using erb
|
9
|
+
# => taken from the sinatra book, http://sinatra-book.gittr.com/#implemention_of_rails_style_partials
|
10
|
+
# Render the page once:
|
11
|
+
# Usage: partial :foo
|
12
|
+
#
|
13
|
+
# foo will be rendered once for each element in the array, passing in a local variable named "foo"
|
14
|
+
# Usage: partial :foo, :collection => @my_foos
|
15
|
+
def partial(template, *args)
|
16
|
+
options = args.extract_options!
|
17
|
+
options.merge!(:layout => false)
|
18
|
+
path = template.to_s.split(File::SEPARATOR)
|
19
|
+
object = path[-1].to_sym
|
20
|
+
path[-1] = "_#{path[-1]}"
|
21
|
+
template = File.join(path).to_sym
|
22
|
+
raise 'partial collection specified but is nil' if options.has_key?(:collection) && options[:collection].nil?
|
23
|
+
if collection = options.delete(:collection)
|
24
|
+
counter = 0
|
25
|
+
collection.inject([]) do |buffer, member|
|
26
|
+
counter += 1
|
27
|
+
buffer << erb(template, options.merge(:locals => {object => member, "#{object}_counter".to_sym => counter}))
|
28
|
+
end.join("\n")
|
29
|
+
else
|
30
|
+
if member = options.delete(:object)
|
31
|
+
options.merge!(:locals => {object => member})
|
32
|
+
end
|
33
|
+
erb(template, options)
|
34
|
+
end
|
35
|
+
end
|
36
|
+
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
40
|
+
|
41
|
+
Sinatra::Application.helpers Sinatra::SinatraHelpers::Erb::Partials
|
42
|
+
end
|
@@ -0,0 +1,89 @@
|
|
1
|
+
require 'sinatra/base'
|
2
|
+
|
3
|
+
module Sinatra
|
4
|
+
module SinatraHelpers
|
5
|
+
module Tags
|
6
|
+
|
7
|
+
# helper to emulate action view's 'link_to'
|
8
|
+
# => inspired from vanntastic-sinatra-gen gem, http://github.com/vanntastic/sinatra-gen/tree/master
|
9
|
+
# EX : link_to "google", "http://google.com"
|
10
|
+
# => <a href="http://google.com">google</a>
|
11
|
+
def link_to(content,href,options={})
|
12
|
+
options.update :href => href
|
13
|
+
tag(:a, options) { content }
|
14
|
+
end
|
15
|
+
|
16
|
+
# helper to emulate 'image_tag'
|
17
|
+
# => inspired from vanntastic-sinatra-gen gem, http://github.com/vanntastic/sinatra-gen/tree/master
|
18
|
+
# helper for image_tags
|
19
|
+
# EX : image_tag 'logo.jpg'
|
20
|
+
# => <img src="images/logo.jpg" />
|
21
|
+
def image_tag(src,options={})
|
22
|
+
options[:src] = ['/'].include?(src.first) ? src : "/images/#{src}"
|
23
|
+
tag(:img, options)
|
24
|
+
end
|
25
|
+
|
26
|
+
def clear_tag(options={})
|
27
|
+
options[:tag] ||= :div
|
28
|
+
options[:style] ||= ''
|
29
|
+
options[:style] = "clear: both;#{options[:style]}"
|
30
|
+
tag(options.delete(:tag), options) { '' }
|
31
|
+
end
|
32
|
+
|
33
|
+
include Rack::Utils
|
34
|
+
alias_method :h, :escape_html
|
35
|
+
|
36
|
+
# helper to emulate 'stylesheet_link_tag'
|
37
|
+
# => inspired from vanntastic-sinatra-gen gem, http://github.com/vanntastic/sinatra-gen/tree/master
|
38
|
+
# EX : stylesheet_link_tag 'default'
|
39
|
+
# => <link rel="stylesheet" href="/stylesheets/default.css" type="text/css" media="all" title="no title" charset="utf-8">
|
40
|
+
def stylesheet_link_tag(srcs,options={})
|
41
|
+
options[:media] ||= "screen"
|
42
|
+
options[:type] ||= "text/css"
|
43
|
+
options[:rel] ||= "stylesheet"
|
44
|
+
srcs.to_a.collect do |src|
|
45
|
+
options[:href] = "/stylesheets/#{src}.css#{"?#{Time.now.to_i}" if Sinatra::Application.environment.to_s == 'development'}"
|
46
|
+
tag(:link, options)
|
47
|
+
end.join("\n")
|
48
|
+
end
|
49
|
+
|
50
|
+
# helper to emulate 'javascript_include_tag'
|
51
|
+
# => inspired from vanntastic-sinatra-gen gem, http://github.com/vanntastic/sinatra-gen/tree/master
|
52
|
+
# EX : javascript_include_tag 'app'
|
53
|
+
# => <script src="/js/app.js" type="text/javascript" />
|
54
|
+
# EX : javascript_include_tag ['app', 'jquery']
|
55
|
+
# => <script src="/js/app.js" type="text/javascript" />
|
56
|
+
# => <script src="/js/jquery.js" type="text/javascript" />
|
57
|
+
def javascript_include_tag(srcs,options={})
|
58
|
+
options[:type] ||= "text/javascript"
|
59
|
+
srcs.to_a.collect do |src|
|
60
|
+
options[:src] = "/javascripts/#{src}.js#{"?#{Time.now.to_i}" if Sinatra::Application.environment.to_s == 'development'}"
|
61
|
+
tag(:script, options) { '' }
|
62
|
+
end.join("\n")
|
63
|
+
end
|
64
|
+
|
65
|
+
# helper to emulate 'javascript_tag'
|
66
|
+
def javascript_tag(options={})
|
67
|
+
options[:type] ||= "text/javascript"
|
68
|
+
tag(:script, options) { yield }
|
69
|
+
end
|
70
|
+
|
71
|
+
# emulator for 'tag'
|
72
|
+
# => inspired from vanntastic-sinatra-gen gem, http://github.com/vanntastic/sinatra-gen/tree/master
|
73
|
+
# EX : tag :h1, "shizam", :title => "shizam"
|
74
|
+
# => <h1 title="shizam">shizam</h1>
|
75
|
+
def tag(name,options={})
|
76
|
+
"<#{name.to_s} #{hash_to_html_attrs(options)} #{block_given? ? ">#{yield}</#{name}" : "/"}>"
|
77
|
+
end
|
78
|
+
|
79
|
+
private
|
80
|
+
|
81
|
+
def hash_to_html_attrs(a_hash)
|
82
|
+
a_hash.collect{|key, val| "#{key}=\"#{val}\""}.join(' ')
|
83
|
+
end
|
84
|
+
|
85
|
+
end
|
86
|
+
end
|
87
|
+
|
88
|
+
Sinatra::Application.helpers Sinatra::SinatraHelpers::Tags
|
89
|
+
end
|
data/lib/useful.rb
ADDED
data/test/test_helper.rb
ADDED
metadata
ADDED
@@ -0,0 +1,77 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: kelredd-useful
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.1.0
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Kelredd
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
|
12
|
+
date: 2009-06-02 00:00:00 -07:00
|
13
|
+
default_executable:
|
14
|
+
dependencies: []
|
15
|
+
|
16
|
+
description:
|
17
|
+
email: ""
|
18
|
+
executables: []
|
19
|
+
|
20
|
+
extensions: []
|
21
|
+
|
22
|
+
extra_rdoc_files:
|
23
|
+
- README.rdoc
|
24
|
+
files:
|
25
|
+
- README.rdoc
|
26
|
+
- Rakefile
|
27
|
+
- lib/useful
|
28
|
+
- lib/useful/ruby_extensions
|
29
|
+
- lib/useful/ruby_extensions/array.rb
|
30
|
+
- lib/useful/ruby_extensions/fixnum.rb
|
31
|
+
- lib/useful/ruby_extensions/hash.rb
|
32
|
+
- lib/useful/ruby_extensions/numeric.rb
|
33
|
+
- lib/useful/ruby_extensions/object.rb
|
34
|
+
- lib/useful/ruby_extensions/string.rb
|
35
|
+
- lib/useful/ruby_extensions.rb
|
36
|
+
- lib/useful/sinatra_helpers
|
37
|
+
- lib/useful/sinatra_helpers/environment_tests.rb
|
38
|
+
- lib/useful/sinatra_helpers/erb
|
39
|
+
- lib/useful/sinatra_helpers/erb/error_pages.rb
|
40
|
+
- lib/useful/sinatra_helpers/erb/partials.rb
|
41
|
+
- lib/useful/sinatra_helpers/erb.rb
|
42
|
+
- lib/useful/sinatra_helpers/tags.rb
|
43
|
+
- lib/useful/sinatra_helpers.rb
|
44
|
+
- lib/useful/version.rb
|
45
|
+
- lib/useful.rb
|
46
|
+
- test/test_helper.rb
|
47
|
+
- test/unit
|
48
|
+
- test/unit/useful_test.rb
|
49
|
+
has_rdoc: true
|
50
|
+
homepage: ""
|
51
|
+
post_install_message:
|
52
|
+
rdoc_options:
|
53
|
+
- --main
|
54
|
+
- README.rdoc
|
55
|
+
require_paths:
|
56
|
+
- lib
|
57
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
58
|
+
requirements:
|
59
|
+
- - ">="
|
60
|
+
- !ruby/object:Gem::Version
|
61
|
+
version: "0"
|
62
|
+
version:
|
63
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
64
|
+
requirements:
|
65
|
+
- - ">="
|
66
|
+
- !ruby/object:Gem::Version
|
67
|
+
version: "0"
|
68
|
+
version:
|
69
|
+
requirements: []
|
70
|
+
|
71
|
+
rubyforge_project:
|
72
|
+
rubygems_version: 1.2.0
|
73
|
+
signing_key:
|
74
|
+
specification_version: 2
|
75
|
+
summary: A collection of useful helpers for various ruby things.
|
76
|
+
test_files: []
|
77
|
+
|