yore 0.0.4 → 0.0.5
Sign up to get free protection for your applications and to get access to all the features.
- data/.document +5 -0
- data/.gitignore +5 -0
- data/LICENSE +23 -0
- data/Rakefile +64 -57
- data/VERSION +1 -0
- data/bin/yore +6 -11
- data/lib/yore/yore_core.rb +70 -43
- data/notes.txt +27 -0
- data/test/S3_test.rb +2 -5
- data/test/test_helper.rb +10 -0
- data/test/test_job_b.xml +1 -1
- data/test/yore_browsercms_loadsave_test.rb +191 -0
- data/test/{loadsave_yore_test.rb → yore_spree_loadsave_test.rb} +9 -10
- data/test/yore_test.rb +1 -4
- data/test.crontab +5 -0
- data/yore.vpj +120 -0
- data/yore.vpw +6 -0
- metadata +38 -82
- data/History.txt +0 -22
- data/Manifest.txt +0 -26
- data/PostInstall.txt +0 -7
- data/lib/ihl_ruby/config.rb +0 -202
- data/lib/ihl_ruby/database_utils.rb +0 -89
- data/lib/ihl_ruby/enum.rb +0 -50
- data/lib/ihl_ruby/extend_base_classes.rb +0 -319
- data/lib/ihl_ruby/logging.rb +0 -159
- data/lib/ihl_ruby/misc_utils.rb +0 -382
- data/lib/ihl_ruby/shell_extras.rb +0 -84
- data/lib/ihl_ruby/string_utils.rb +0 -53
- data/lib/ihl_ruby/xml_utils.rb +0 -177
- data/lib/yore.orig.rb +0 -6
- data/script/console +0 -10
- data/script/destroy +0 -14
- data/script/generate +0 -14
data/lib/ihl_ruby/config.rb
DELETED
@@ -1,202 +0,0 @@
|
|
1
|
-
require 'rubygems'
|
2
|
-
gem 'RequirePaths'; require 'require_paths'
|
3
|
-
require_paths '..'
|
4
|
-
require 'ihl_ruby/xml_utils'
|
5
|
-
|
6
|
-
class ConfigClass < Hash
|
7
|
-
|
8
|
-
attr_reader :default_values
|
9
|
-
|
10
|
-
def initialize(aDefaultValues,aNewValues=nil,&aBlock)
|
11
|
-
self.merge!(@default_values = aDefaultValues.clone)
|
12
|
-
if aNewValues
|
13
|
-
block_given? ? read(aNewValues,&aBlock) : read(aNewValues)
|
14
|
-
end
|
15
|
-
end
|
16
|
-
|
17
|
-
# aBlock allows values to be filtered based on key,default and new values
|
18
|
-
def read(aSource,&aBlock)
|
19
|
-
default_values.each do |k,v|
|
20
|
-
done = false
|
21
|
-
if block_given? && ((newv = yield(k,v,aSource && aSource[k])) != nil)
|
22
|
-
self[k] = newv
|
23
|
-
done = true
|
24
|
-
end
|
25
|
-
copy_item(aSource,k) if !done && aSource && aSource[k]
|
26
|
-
end
|
27
|
-
self
|
28
|
-
end
|
29
|
-
|
30
|
-
# reset values back to defaults
|
31
|
-
def reset
|
32
|
-
self.clear
|
33
|
-
self.merge!(default_values)
|
34
|
-
end
|
35
|
-
|
36
|
-
def set_int(aKey,aValue)
|
37
|
-
case aValue
|
38
|
-
when String then self[aKey] = aValue.to_integer(self[aKey]);
|
39
|
-
when Fixnum then self[aKey] = aValue;
|
40
|
-
when Float then self[aKey] = aValue.to_i;
|
41
|
-
end
|
42
|
-
end
|
43
|
-
|
44
|
-
def set_float(aKey,aValue)
|
45
|
-
case aValue
|
46
|
-
when String then self[aKey] = aValue.to_float(self[aKey]);
|
47
|
-
when Fixnum then self[aKey] = aValue.to_f;
|
48
|
-
when Float then self[aKey] = aValue;
|
49
|
-
end
|
50
|
-
end
|
51
|
-
|
52
|
-
def set_boolean(aKey,aValue)
|
53
|
-
case aValue
|
54
|
-
when TrueClass,FalseClass then self[aKey] = aValue;
|
55
|
-
when String then self[aKey] = (['1','yes','y','true','on'].include?(aValue.downcase))
|
56
|
-
else
|
57
|
-
set_boolean(aKey,aValue.to_s)
|
58
|
-
end
|
59
|
-
end
|
60
|
-
|
61
|
-
def set_symbol(aKey,aValue)
|
62
|
-
case aValue
|
63
|
-
when String then self[aKey] = (aValue.to_sym rescue nil);
|
64
|
-
when Symbol then self[aKey] = aValue;
|
65
|
-
end
|
66
|
-
end
|
67
|
-
|
68
|
-
def copy_item(aHash,aKey)
|
69
|
-
case default_values[aKey]
|
70
|
-
when NilClass then ;
|
71
|
-
when String then self[aKey] = aHash[aKey].to_s unless aHash[aKey].nil?
|
72
|
-
when Float then set_float(aKey,aHash[aKey]);
|
73
|
-
when Fixnum then set_int(aKey,aHash[aKey]);
|
74
|
-
when TrueClass, FalseClass then set_boolean(aKey,aHash[aKey]);
|
75
|
-
when Symbol then self[aKey] = (aHash[aKey].to_sym rescue nil)
|
76
|
-
else
|
77
|
-
raise Error.new('unsupported type')
|
78
|
-
end
|
79
|
-
end
|
80
|
-
|
81
|
-
def copy_strings(aHash,*aKeys)
|
82
|
-
aKeys.each do |k|
|
83
|
-
self[k] = aHash[k].to_s unless aHash[k].nil?
|
84
|
-
end
|
85
|
-
end
|
86
|
-
|
87
|
-
def copy_ints(*aDb)
|
88
|
-
aHash = aDb.shift
|
89
|
-
aKeys = aDb
|
90
|
-
aKeys.each do |k|
|
91
|
-
set_int(k,aHash[k])
|
92
|
-
end
|
93
|
-
end
|
94
|
-
|
95
|
-
def copy_floats(aHash,*aKeys)
|
96
|
-
aKeys.each do |k|
|
97
|
-
set_float(k,aHash[k])
|
98
|
-
end
|
99
|
-
end
|
100
|
-
|
101
|
-
def copy_booleans(aHash,*aKeys)
|
102
|
-
aKeys.each do |k|
|
103
|
-
set_boolean(k,aHash[k])
|
104
|
-
end
|
105
|
-
end
|
106
|
-
|
107
|
-
def to_hash
|
108
|
-
{}.merge(self)
|
109
|
-
end
|
110
|
-
|
111
|
-
end
|
112
|
-
|
113
|
-
class ConfigXmlClass < ConfigClass
|
114
|
-
attr_accessor :xmlRoot
|
115
|
-
def initialize(aDefaultValues,aConfig)
|
116
|
-
return super(aDefaultValues,aConfig) unless aConfig.is_a?(REXML::Element)
|
117
|
-
@xmlRoot = aConfig.deep_clone
|
118
|
-
super(aDefaultValues,XmlUtils.read_simple_items(@xmlRoot,'/Yore/SimpleItems'))
|
119
|
-
end
|
120
|
-
end
|
121
|
-
|
122
|
-
# credentials files look like :
|
123
|
-
#<?xml version="1.0" encoding="UTF-8"?>
|
124
|
-
#<Credentials>
|
125
|
-
# <SimpleItems namespace="global">
|
126
|
-
# <Item name=""></Item>
|
127
|
-
# <Item name=""></Item>
|
128
|
-
# <Item name=""></Item>
|
129
|
-
# </SimpleItems>
|
130
|
-
# <SimpleItems namespace="yore_test">
|
131
|
-
# <Item name=""></Item>
|
132
|
-
# <Item name=""></Item>
|
133
|
-
# <Item name=""></Item>
|
134
|
-
# </SimpleItems>
|
135
|
-
#</Credentials>
|
136
|
-
#
|
137
|
-
# global .credentials.xml file
|
138
|
-
# local .credentials.xml file
|
139
|
-
# cred = Credentials.new() # optionally specify filename or path or hash. if nil then use Dir.pwd
|
140
|
-
#
|
141
|
-
# def initialize(aSource)
|
142
|
-
# # load global namespace from ~/.credentials.xml
|
143
|
-
# # load global namespace from local .credentials.xml
|
144
|
-
# # load given namespace from ~/.credentials.xml
|
145
|
-
# # load given namespace from local .credentials.xml
|
146
|
-
# # merge all top to bottom
|
147
|
-
class Credentials < Hash
|
148
|
-
|
149
|
-
CRED_FILENAME = ".credentials.xml"
|
150
|
-
|
151
|
-
def find_file_upwards(aFilename,aStartPath=nil)
|
152
|
-
aStartPath ||= Dir.pwd
|
153
|
-
return nil if aFilename.nil? || aFilename.empty?
|
154
|
-
arrPath = aStartPath.split(File::SEPARATOR)
|
155
|
-
while arrPath.length > 0
|
156
|
-
path = File.join(arrPath.join(File::SEPARATOR),aFilename)
|
157
|
-
return path if File.exists?(path)
|
158
|
-
arrPath.pop
|
159
|
-
end
|
160
|
-
return nil
|
161
|
-
end
|
162
|
-
|
163
|
-
def get_all_credentials(aXmlRoot)
|
164
|
-
return nil unless aXmlRoot
|
165
|
-
result = {}
|
166
|
-
REXML::XPath.each(aXmlRoot, '/Credentials/SimpleItems') do |si|
|
167
|
-
ns = si.attributes['Namespace']
|
168
|
-
values = XmlUtils.read_simple_items(si)
|
169
|
-
result[ns.to_sym] = values.symbolize_keys if ns && values
|
170
|
-
end
|
171
|
-
return result
|
172
|
-
end
|
173
|
-
|
174
|
-
#XmlUtils.read_simple_items(@xmlRoot,'/Yore/SimpleItems')
|
175
|
-
def get_user_credentials
|
176
|
-
return get_all_credentials(XmlUtils.get_file_root(File.join(HOME_PATH,CRED_FILENAME)))
|
177
|
-
end
|
178
|
-
|
179
|
-
def get_local_credentials(aSource=nil)
|
180
|
-
aSource ||= Dir.pwd
|
181
|
-
# assume source is a directory path, but other types could be supported later
|
182
|
-
return nil unless file=find_file_upwards(CRED_FILENAME,aSource)
|
183
|
-
return get_all_credentials(XmlUtils.get_file_root(file))
|
184
|
-
end
|
185
|
-
|
186
|
-
def initialize(aNamespace=nil,aSource=nil)
|
187
|
-
#HOME_PATH can be preset by tests eg. ::Credentials.const_set('HOME_PATH',@user_dir)
|
188
|
-
Credentials.const_set("HOME_PATH", ENV['HOME']) unless Credentials.const_defined? "HOME_PATH"
|
189
|
-
arrCredentials = []
|
190
|
-
user_credentials = get_user_credentials()
|
191
|
-
local_credentials = get_local_credentials(aSource)
|
192
|
-
arrCredentials << user_credentials[:global] if user_credentials
|
193
|
-
arrCredentials << local_credentials[:global] if local_credentials
|
194
|
-
arrCredentials << user_credentials[aNamespace.to_sym] if aNamespace && user_credentials
|
195
|
-
arrCredentials << local_credentials[aNamespace.to_sym] if aNamespace && local_credentials
|
196
|
-
arrCredentials.compact!
|
197
|
-
arrCredentials.each do |c|
|
198
|
-
self.merge!(c)
|
199
|
-
end
|
200
|
-
end
|
201
|
-
end
|
202
|
-
|
@@ -1,89 +0,0 @@
|
|
1
|
-
require 'rubygems'
|
2
|
-
gem 'RequirePaths'; require 'require_paths'
|
3
|
-
require_paths '..'
|
4
|
-
require 'ihl_ruby/shell_extras'
|
5
|
-
|
6
|
-
module DatabaseUtils
|
7
|
-
def self.execute_sql_file(filename,aUser=nil,aPassword=nil)
|
8
|
-
conf = ActiveRecord::Base.configurations[RAILS_ENV]
|
9
|
-
pw = aPassword || conf['password'].to_s || ''
|
10
|
-
user = aUser || conf['username'].to_s || ''
|
11
|
-
cmd_line = "mysql -h #{conf['host']} -D #{conf['database']} #{user.empty? ? '' : '-u '+user} #{pw.empty? ? '' : '-p'+pw} <#{filename}"
|
12
|
-
if !system(cmd_line)
|
13
|
-
raise Exception, "Error executing "+cmd_line
|
14
|
-
end
|
15
|
-
end
|
16
|
-
|
17
|
-
## http://www.cyberciti.biz/faq/how-do-i-empty-mysql-database/
|
18
|
-
#
|
19
|
-
#
|
20
|
-
## drop all tables :
|
21
|
-
## mysqldump -uusername -ppassword -hhost \
|
22
|
-
##--add-drop-table --no-data database | grep ^DROP | \
|
23
|
-
##mysql -uusername -ppassword -hhost database
|
24
|
-
#
|
25
|
-
|
26
|
-
def self.database_exists(aDbDetails,aDatabase=nil)
|
27
|
-
aDbDetails[:database] = aDatabase if aDatabase
|
28
|
-
return false if !aDbDetails[:database]
|
29
|
-
response = POpen4::shell("mysql -u #{aDbDetails[:username]} -p#{aDbDetails[:password]} -e 'use #{aDbDetails[:database]}'") do |r|
|
30
|
-
if r[:stderr] && r[:stderr].index("ERROR 1049 ")==0 # Unknown database
|
31
|
-
r[:exitcode] = 0
|
32
|
-
return false
|
33
|
-
end
|
34
|
-
end
|
35
|
-
return (response && response[:exitcode]==0)
|
36
|
-
end
|
37
|
-
|
38
|
-
def self.clear_database(aDbDetails)
|
39
|
-
response = POpen4::shell("mysqldump -u #{aDbDetails[:username]} -p#{aDbDetails[:password]} --add-drop-table --no-data #{aDbDetails[:database]} | grep ^DROP | mysql -u #{aDbDetails[:username]} -p#{aDbDetails[:password]} #{aDbDetails[:database]}")
|
40
|
-
end
|
41
|
-
|
42
|
-
def self.create_database(aDbDetails,aDatabase=nil)
|
43
|
-
aDbDetails[:database] = aDatabase if aDatabase
|
44
|
-
return false if !aDbDetails[:database]
|
45
|
-
response = POpen4::shell("mysqladmin -u #{aDbDetails[:username]} -p#{aDbDetails[:password]} create #{aDbDetails[:database]}")
|
46
|
-
end
|
47
|
-
|
48
|
-
def self.ensure_empty_database(aDbDetails,aDatabase=nil)
|
49
|
-
aDbDetails[:database] = aDatabase if aDatabase
|
50
|
-
if database_exists(aDbDetails)
|
51
|
-
clear_database(aDbDetails)
|
52
|
-
else
|
53
|
-
create_database(aDbDetails)
|
54
|
-
end
|
55
|
-
end
|
56
|
-
|
57
|
-
def self.load_database(aDbDetails,aSqlFile)
|
58
|
-
ensure_empty_database(aDbDetails)
|
59
|
-
response = POpen4::shell("mysql -u #{aDbDetails[:username]} -p#{aDbDetails[:password]} #{aDbDetails[:database]} < #{aSqlFile}")
|
60
|
-
end
|
61
|
-
|
62
|
-
def self.save_database(aDbDetails,aSqlFile)
|
63
|
-
response = POpen4::shell("mysqldump --user=#{aDbDetails[:username]} --password=#{aDbDetails[:password]} --skip-extended-insert #{aDbDetails[:database]} > #{aSqlFile}")
|
64
|
-
end
|
65
|
-
|
66
|
-
#
|
67
|
-
## eg. rake metas:spree:data:load from=/tmp/spree_data.tgz to=mysql:fresco_server_d:root:password
|
68
|
-
#desc 'load spree data from a file'
|
69
|
-
#task :load do
|
70
|
-
# from = ENV['from']
|
71
|
-
# to=ENV['to']
|
72
|
-
# db_server,db,user,password = to.split(':')
|
73
|
-
# tmpdir = make_temp_dir('metas')
|
74
|
-
# cmd = "tar -xvzf #{from} -C #{tmpdir}"
|
75
|
-
# puts CapUtilsClass.shell(cmd)
|
76
|
-
#
|
77
|
-
# ensure_empty_database(db_server,db,user,password)
|
78
|
-
#
|
79
|
-
# puts CapUtilsClass.shell("mysql -u #{user} -p#{password} #{db} < #{File.join(tmpdir,'db/dumps/db.sql')}")
|
80
|
-
# FileUtils.mkdir_p('public/assets')
|
81
|
-
# puts CapUtilsClass.shell("cp -rf #{File.join(tmpdir,'public/assets/products')} public/assets/products")
|
82
|
-
#end
|
83
|
-
|
84
|
-
|
85
|
-
|
86
|
-
|
87
|
-
end
|
88
|
-
|
89
|
-
|
data/lib/ihl_ruby/enum.rb
DELETED
@@ -1,50 +0,0 @@
|
|
1
|
-
module Kernel
|
2
|
-
# simple (sequential) enumerated values
|
3
|
-
# usage :
|
4
|
-
#
|
5
|
-
# module Constants
|
6
|
-
# module Gradient
|
7
|
-
# enum :B, :A, :C
|
8
|
-
# end
|
9
|
-
# end
|
10
|
-
#
|
11
|
-
# then :
|
12
|
-
#
|
13
|
-
# puts Constants::Gradient::B -> 0
|
14
|
-
# puts Constants::Gradient::C -> 2
|
15
|
-
# puts Constants::Gradient::MINVALUE -> 0
|
16
|
-
# puts Constants::Gradient::MAXVALUE -> 2
|
17
|
-
# puts Constants::Gradient::NAMES -> [:B, :A, :C]
|
18
|
-
# puts Constants::Gradient[0] -> :B
|
19
|
-
# puts Constants::Gradient[1] -> :A
|
20
|
-
# puts Constants::Gradient[2] -> :C
|
21
|
-
|
22
|
-
def enum(*syms)
|
23
|
-
syms.each_index { |i|
|
24
|
-
const_set(syms[i], i)
|
25
|
-
}
|
26
|
-
const_set(:NAMES, syms || [])
|
27
|
-
const_set(:MINVALUE, syms==nil ? nil : 0)
|
28
|
-
const_set(:MAXVALUE, syms==nil ? nil : syms.length-1)
|
29
|
-
const_set(:VALUECOUNT, syms==nil ? nil : syms.length)
|
30
|
-
const_set(:ALL, syms==nil ? [] : (0..syms.length-1).to_a)
|
31
|
-
const_set(:HUMAN_NAMES, syms.map{|n| n.to_s.humanize} || [])
|
32
|
-
|
33
|
-
# this returns the enum name given the value
|
34
|
-
def self.[]( idx )
|
35
|
-
(idx.is_a? Integer) ? const_get(:NAMES)[idx] : nil
|
36
|
-
end
|
37
|
-
|
38
|
-
def self.valid?(idx)
|
39
|
-
(idx.is_a? Integer) && (idx >= 0) && (idx <= const_get(:MAXVALUE))
|
40
|
-
end
|
41
|
-
|
42
|
-
def self.parse(name,default=nil)
|
43
|
-
return default if name.nil? || name.empty?
|
44
|
-
return default if not name = name.to_sym
|
45
|
-
result = const_get(:NAMES).index(name)
|
46
|
-
return result==nil ? default : result
|
47
|
-
end
|
48
|
-
end
|
49
|
-
end
|
50
|
-
|
@@ -1,319 +0,0 @@
|
|
1
|
-
String.class_eval do
|
2
|
-
def pad_left(value)
|
3
|
-
increase = value-self.length
|
4
|
-
return self if increase==0
|
5
|
-
if increase > 0
|
6
|
-
return self + ' '*increase
|
7
|
-
else
|
8
|
-
return self[0,value]
|
9
|
-
end
|
10
|
-
end
|
11
|
-
|
12
|
-
def pad_right(value)
|
13
|
-
increase = value-self.length
|
14
|
-
return self if increase==0
|
15
|
-
if increase > 0
|
16
|
-
return ' '*increase + self
|
17
|
-
else
|
18
|
-
return self[0,value]
|
19
|
-
end
|
20
|
-
end
|
21
|
-
|
22
|
-
# Like chomp! but operates on the leading characters instead.
|
23
|
-
# The aString parameter would not normally be used.
|
24
|
-
def bite!(aValue=$/,aString=self)
|
25
|
-
if aString[0,aValue.length] == aValue
|
26
|
-
aString[0,aValue.length] = ''
|
27
|
-
return aString
|
28
|
-
else
|
29
|
-
return aString
|
30
|
-
end
|
31
|
-
end
|
32
|
-
|
33
|
-
def bite(aValue=$/)
|
34
|
-
bite!(aValue,self.clone)
|
35
|
-
end
|
36
|
-
|
37
|
-
def begins_with?(aString)
|
38
|
-
self[0,aString.length]==aString
|
39
|
-
end
|
40
|
-
|
41
|
-
def ends_with?(aString)
|
42
|
-
self[-aString.length,aString.length]==aString
|
43
|
-
end
|
44
|
-
|
45
|
-
# for future methods
|
46
|
-
# def centre_bar(aChar = '-', indent = 6)
|
47
|
-
# (' '*indent) + aChar*(@width-(indent*2)) + (' '*indent)
|
48
|
-
# end
|
49
|
-
# def replace_string(aString,aCol,aSubString)
|
50
|
-
# return aString if aSubString==nil || aSubString==''
|
51
|
-
#
|
52
|
-
# aSubString = aSubString.to_s
|
53
|
-
# start_col = aCol < 0 ? 0 : aCol
|
54
|
-
# end_col = aCol+aSubString.length-1
|
55
|
-
# end_col = @width-1 if end_col >= @width
|
56
|
-
# source_len = end_col-start_col+1
|
57
|
-
# return aString if source_len <= 0 || end_col < 0 || start_col >= @width
|
58
|
-
# aString += ' '*((end_col+1) - aString.length) if aString.length < end_col+1
|
59
|
-
# aString[start_col,source_len] = aSubString[start_col-aCol,end_col-start_col+1]
|
60
|
-
# return aString
|
61
|
-
# end
|
62
|
-
|
63
|
-
def to_integer(aDefault=nil)
|
64
|
-
t = self.strip
|
65
|
-
return aDefault if t.empty? || !t.index(/^-{0,1}[0-9]+$/)
|
66
|
-
return t.to_i
|
67
|
-
end
|
68
|
-
|
69
|
-
def is_i?
|
70
|
-
self.to_integer(false) and true
|
71
|
-
end
|
72
|
-
|
73
|
-
def to_float(aDefault=nil)
|
74
|
-
t = self.strip
|
75
|
-
return aDefault if !t =~ /(\+|-)?([0-9]+\.?[0-9]*|\.[0-9]+)([eE](\+|-)?[0-9]+)?/
|
76
|
-
return t.to_f
|
77
|
-
end
|
78
|
-
|
79
|
-
def is_f?
|
80
|
-
self.to_float(false) and true
|
81
|
-
end
|
82
|
-
|
83
|
-
end
|
84
|
-
|
85
|
-
|
86
|
-
Time.class_eval do
|
87
|
-
|
88
|
-
if !respond_to?(:change) # no activesupport loaded
|
89
|
-
def change(options)
|
90
|
-
::Time.send(
|
91
|
-
self.utc? ? :utc : :local,
|
92
|
-
options[:year] || self.year,
|
93
|
-
options[:month] || self.month,
|
94
|
-
options[:day] || self.day,
|
95
|
-
options[:hour] || self.hour,
|
96
|
-
options[:min] || (options[:hour] ? 0 : self.min),
|
97
|
-
options[:sec] || ((options[:hour] || options[:min]) ? 0 : self.sec),
|
98
|
-
options[:usec] || ((options[:hour] || options[:min] || options[:sec]) ? 0 : self.usec)
|
99
|
-
)
|
100
|
-
end
|
101
|
-
|
102
|
-
def seconds_since_midnight
|
103
|
-
self.to_i - self.change(:hour => 0).to_i + (self.usec/1.0e+6)
|
104
|
-
end
|
105
|
-
|
106
|
-
def beginning_of_day
|
107
|
-
(self - self.seconds_since_midnight).change(:usec => 0)
|
108
|
-
end
|
109
|
-
|
110
|
-
alias :midnight :beginning_of_day
|
111
|
-
alias :at_midnight :beginning_of_day
|
112
|
-
alias :at_beginning_of_day :beginning_of_day
|
113
|
-
|
114
|
-
end
|
115
|
-
|
116
|
-
# offset of local machine from UTC, in seconds eg +9.hours
|
117
|
-
def self.local_offset
|
118
|
-
local(2000).utc_offset
|
119
|
-
end
|
120
|
-
|
121
|
-
def date
|
122
|
-
self.at_beginning_of_day
|
123
|
-
end
|
124
|
-
|
125
|
-
# index number of this day, from Time.at(0) + utc_offset
|
126
|
-
def day_number
|
127
|
-
(self.to_i+self.utc_offset) / 86400
|
128
|
-
end
|
129
|
-
|
130
|
-
# index number of this utc day
|
131
|
-
def day_number_utc
|
132
|
-
self.to_i / 86400
|
133
|
-
end
|
134
|
-
|
135
|
-
# the last microsecond of the day
|
136
|
-
def day_end
|
137
|
-
self.at_beginning_of_day + 86399.999999
|
138
|
-
end
|
139
|
-
|
140
|
-
def date_numeric
|
141
|
-
self.strftime('%Y%m%d')
|
142
|
-
end
|
143
|
-
|
144
|
-
# create a new Time from eg. "20081231"
|
145
|
-
def self.from_date_numeric(aString)
|
146
|
-
local(aString[0,4].to_i,aString[4,2].to_i,aString[6,2].to_i)
|
147
|
-
end
|
148
|
-
|
149
|
-
def time_numeric
|
150
|
-
self.strftime('%H%M%S')
|
151
|
-
end
|
152
|
-
|
153
|
-
def datetime_numeric
|
154
|
-
self.strftime('%Y%m%d-%H%M%S')
|
155
|
-
end
|
156
|
-
|
157
|
-
def to_sql
|
158
|
-
self.strftime('%Y-%m-%d %H:%M:%S')
|
159
|
-
end
|
160
|
-
|
161
|
-
def to_w3c
|
162
|
-
utc.strftime("%Y-%m-%dT%H:%M:%S+00:00")
|
163
|
-
end
|
164
|
-
end
|
165
|
-
|
166
|
-
module HashUtils
|
167
|
-
def filter_include!(aKeys,aHash=nil)
|
168
|
-
aHash ||= self
|
169
|
-
|
170
|
-
if aKeys.is_a? Regexp
|
171
|
-
return aHash.delete_if {|k,v| not k =~ aKeys }
|
172
|
-
else
|
173
|
-
aKeys = [aKeys] unless aKeys.is_a? Array
|
174
|
-
return aHash.clear if aKeys.empty?
|
175
|
-
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)))}
|
176
|
-
return aHash # last resort
|
177
|
-
end
|
178
|
-
end
|
179
|
-
|
180
|
-
def filter_include(aKeys,aHash=nil)
|
181
|
-
aHash ||= self
|
182
|
-
filter_include!(aKeys,aHash.clone)
|
183
|
-
end
|
184
|
-
|
185
|
-
def filter_exclude!(aKeys,aHash=nil)
|
186
|
-
aHash ||= self
|
187
|
-
|
188
|
-
if aKeys.is_a? Regexp
|
189
|
-
return aHash.delete_if {|k,v| k =~ aKeys }
|
190
|
-
else
|
191
|
-
aKeys = [aKeys] unless aKeys.is_a? Array
|
192
|
-
return aHash if aKeys.empty?
|
193
|
-
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)))}
|
194
|
-
end
|
195
|
-
end
|
196
|
-
|
197
|
-
def filter_exclude(aKeys,aHash=nil)
|
198
|
-
aHash ||= self
|
199
|
-
filter_exclude!(aKeys,aHash.clone)
|
200
|
-
end
|
201
|
-
|
202
|
-
def has_values_for?(aKeys,aHash=nil)
|
203
|
-
aHash ||= self
|
204
|
-
# check all keys exist in aHash and their values are not nil
|
205
|
-
aKeys.all? { |k,v| aHash[k] }
|
206
|
-
end
|
207
|
-
|
208
|
-
# give a block to execute without the given key in this hash
|
209
|
-
# It will be replaced after the block (guaranteed by ensure)
|
210
|
-
# eg.
|
211
|
-
# hash.without_key(:blah) do |aHash|
|
212
|
-
# puts aHash.inspect
|
213
|
-
# end
|
214
|
-
def without_key(aKey)
|
215
|
-
temp = nil
|
216
|
-
h = self
|
217
|
-
begin
|
218
|
-
if h.include?(aKey)
|
219
|
-
temp = [aKey,h.delete(aKey)]
|
220
|
-
end
|
221
|
-
result = yield(h)
|
222
|
-
ensure
|
223
|
-
h[temp[0]] = temp[1] if temp
|
224
|
-
end
|
225
|
-
return result
|
226
|
-
end
|
227
|
-
|
228
|
-
def symbolize_keys
|
229
|
-
result = {}
|
230
|
-
self.each { |k,v| k.is_a?(String) ? result[k.to_sym] = v : result[k] = v }
|
231
|
-
return result
|
232
|
-
end
|
233
|
-
|
234
|
-
end
|
235
|
-
|
236
|
-
Hash.class_eval do
|
237
|
-
include HashUtils
|
238
|
-
end
|
239
|
-
|
240
|
-
if defined? HashWithIndifferentAccess
|
241
|
-
HashWithIndifferentAccess.class_eval do
|
242
|
-
include HashUtils
|
243
|
-
end
|
244
|
-
end
|
245
|
-
|
246
|
-
module ArrayUtils
|
247
|
-
def filter_include!(aValues,aArray=nil)
|
248
|
-
aArray ||= self
|
249
|
-
if aValues.is_a? Array
|
250
|
-
return aArray if aValues.empty?
|
251
|
-
return aArray.delete_if {|v| not aValues.include? v }
|
252
|
-
elsif aValues.is_a? Regexp
|
253
|
-
return aArray.delete_if {|v| not v =~ aValues }
|
254
|
-
else
|
255
|
-
return filter_include!([aValues],aArray)
|
256
|
-
end
|
257
|
-
end
|
258
|
-
|
259
|
-
def filter_include(aValues,aArray=nil)
|
260
|
-
aArray ||= self
|
261
|
-
filter_include!(aValues,aArray.clone)
|
262
|
-
end
|
263
|
-
|
264
|
-
def filter_exclude!(aValues,aArray=nil)
|
265
|
-
aArray ||= self
|
266
|
-
if aValues.is_a? Array
|
267
|
-
return aArray if aValues.empty?
|
268
|
-
return aArray.delete_if {|v| aValues.include? v }
|
269
|
-
elsif aValues.is_a? Regexp
|
270
|
-
return aArray.delete_if {|v| v =~ aValues }
|
271
|
-
else
|
272
|
-
return filter_exclude!([aValues],aArray)
|
273
|
-
end
|
274
|
-
end
|
275
|
-
|
276
|
-
def filter_exclude(aValues,aArray=nil)
|
277
|
-
aArray ||= self
|
278
|
-
filter_exclude!(aValues,aArray.clone)
|
279
|
-
end
|
280
|
-
end
|
281
|
-
|
282
|
-
Array.class_eval do
|
283
|
-
include ArrayUtils
|
284
|
-
|
285
|
-
# fixes a memory leak in shift in Ruby 1.8 - should be fixed in 1.9
|
286
|
-
# see http://blade.nagaokaut.ac.jp/cgi-bin/scat.rb/ruby/ruby-talk/216055
|
287
|
-
def shift()
|
288
|
-
delete_at(0)
|
289
|
-
end
|
290
|
-
|
291
|
-
end
|
292
|
-
|
293
|
-
Kernel.class_eval do
|
294
|
-
def is_windows?
|
295
|
-
RUBY_PLATFORM =~ /(win|w)32$/ ? true : false
|
296
|
-
end
|
297
|
-
end
|
298
|
-
|
299
|
-
if defined? ActiveRecord
|
300
|
-
ActiveRecord::Base.class_eval do
|
301
|
-
|
302
|
-
def self.find_any_id(aId)
|
303
|
-
with_exclusive_scope { find(:first, {:conditions => {:id => aId}}) }
|
304
|
-
end
|
305
|
-
|
306
|
-
def self.find_any_all(aOptions={})
|
307
|
-
with_exclusive_scope { find(:all, aOptions) }
|
308
|
-
end
|
309
|
-
|
310
|
-
def self.find_ids(aIds)
|
311
|
-
find(:all, {:conditions=> ["id in (?)",aIds.join(',')]})
|
312
|
-
end
|
313
|
-
|
314
|
-
def self.find_any_ids(aIds)
|
315
|
-
with_exclusive_scope { find(:all, {:conditions=> ["id in (?)",aIds.join(',')]}) }
|
316
|
-
end
|
317
|
-
|
318
|
-
end
|
319
|
-
end
|