buzzcore 0.2.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/README.rdoc +46 -0
- data/Rakefile +63 -0
- data/VERSION +1 -0
- data/buzzcore.gemspec +77 -0
- data/buzzcore.vpj +93 -0
- data/buzzcore.vpw +93 -0
- data/lib/buzzcore/config.rb +239 -0
- data/lib/buzzcore/database_utils.rb +86 -0
- data/lib/buzzcore/enum.rb +50 -0
- data/lib/buzzcore/extend_base_classes.rb +328 -0
- data/lib/buzzcore/html_utils.rb +29 -0
- data/lib/buzzcore/logging.rb +159 -0
- data/lib/buzzcore/misc_utils.rb +387 -0
- data/lib/buzzcore/require_paths.rb +39 -0
- data/lib/buzzcore/shell_extras.rb +80 -0
- data/lib/buzzcore/string_utils.rb +66 -0
- data/lib/buzzcore/text_doc.rb +70 -0
- data/lib/buzzcore/thread_utils.rb +709 -0
- data/lib/buzzcore/xml_utils.rb +203 -0
- data/lib/buzzcore.rb +2 -0
- data/lib/buzzcore_dev.rb +6 -0
- data/test/buzzcore_test.rb +7 -0
- data/test/config_test.rb +201 -0
- data/test/credentials_test.rb +71 -0
- data/test/shell_test.rb +54 -0
- data/test/test_helper.rb +10 -0
- metadata +95 -0
@@ -0,0 +1,86 @@
|
|
1
|
+
require 'buzzcore/shell_extras'
|
2
|
+
|
3
|
+
module DatabaseUtils
|
4
|
+
def self.execute_sql_file(filename,aUser=nil,aPassword=nil)
|
5
|
+
conf = ActiveRecord::Base.configurations[RAILS_ENV]
|
6
|
+
pw = aPassword || conf['password'].to_s || ''
|
7
|
+
user = aUser || conf['username'].to_s || ''
|
8
|
+
cmd_line = "mysql -h #{conf['host']} -D #{conf['database']} #{user.empty? ? '' : '-u '+user} #{pw.empty? ? '' : '-p'+pw} <#{filename}"
|
9
|
+
if !system(cmd_line)
|
10
|
+
raise Exception, "Error executing "+cmd_line
|
11
|
+
end
|
12
|
+
end
|
13
|
+
|
14
|
+
## http://www.cyberciti.biz/faq/how-do-i-empty-mysql-database/
|
15
|
+
#
|
16
|
+
#
|
17
|
+
## drop all tables :
|
18
|
+
## mysqldump -uusername -ppassword -hhost \
|
19
|
+
##--add-drop-table --no-data database | grep ^DROP | \
|
20
|
+
##mysql -uusername -ppassword -hhost database
|
21
|
+
#
|
22
|
+
|
23
|
+
def self.database_exists(aDbDetails,aDatabase=nil)
|
24
|
+
aDbDetails[:database] = aDatabase if aDatabase
|
25
|
+
return false if !aDbDetails[:database]
|
26
|
+
response = POpen4::shell("mysql -u #{aDbDetails[:username]} -p#{aDbDetails[:password]} -e 'use #{aDbDetails[:database]}'") do |r|
|
27
|
+
if r[:stderr] && r[:stderr].index("ERROR 1049 ")==0 # Unknown database
|
28
|
+
r[:exitcode] = 0
|
29
|
+
return false
|
30
|
+
end
|
31
|
+
end
|
32
|
+
return (response && response[:exitcode]==0)
|
33
|
+
end
|
34
|
+
|
35
|
+
def self.clear_database(aDbDetails)
|
36
|
+
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]}")
|
37
|
+
end
|
38
|
+
|
39
|
+
def self.create_database(aDbDetails,aDatabase=nil)
|
40
|
+
aDbDetails[:database] = aDatabase if aDatabase
|
41
|
+
return false if !aDbDetails[:database]
|
42
|
+
response = POpen4::shell("mysqladmin -u #{aDbDetails[:username]} -p#{aDbDetails[:password]} create #{aDbDetails[:database]}")
|
43
|
+
end
|
44
|
+
|
45
|
+
def self.ensure_empty_database(aDbDetails,aDatabase=nil)
|
46
|
+
aDbDetails[:database] = aDatabase if aDatabase
|
47
|
+
if database_exists(aDbDetails)
|
48
|
+
clear_database(aDbDetails)
|
49
|
+
else
|
50
|
+
create_database(aDbDetails)
|
51
|
+
end
|
52
|
+
end
|
53
|
+
|
54
|
+
def self.load_database(aDbDetails,aSqlFile)
|
55
|
+
ensure_empty_database(aDbDetails)
|
56
|
+
response = POpen4::shell("mysql -u #{aDbDetails[:username]} -p#{aDbDetails[:password]} #{aDbDetails[:database]} < #{aSqlFile}")
|
57
|
+
end
|
58
|
+
|
59
|
+
def self.save_database(aDbDetails,aSqlFile)
|
60
|
+
response = POpen4::shell("mysqldump --user=#{aDbDetails[:username]} --password=#{aDbDetails[:password]} --skip-extended-insert #{aDbDetails[:database]} > #{aSqlFile}")
|
61
|
+
end
|
62
|
+
|
63
|
+
#
|
64
|
+
## eg. rake metas:spree:data:load from=/tmp/spree_data.tgz to=mysql:fresco_server_d:root:password
|
65
|
+
#desc 'load spree data from a file'
|
66
|
+
#task :load do
|
67
|
+
# from = ENV['from']
|
68
|
+
# to=ENV['to']
|
69
|
+
# db_server,db,user,password = to.split(':')
|
70
|
+
# tmpdir = make_temp_dir('metas')
|
71
|
+
# cmd = "tar -xvzf #{from} -C #{tmpdir}"
|
72
|
+
# puts CapUtilsClass.shell(cmd)
|
73
|
+
#
|
74
|
+
# ensure_empty_database(db_server,db,user,password)
|
75
|
+
#
|
76
|
+
# puts CapUtilsClass.shell("mysql -u #{user} -p#{password} #{db} < #{File.join(tmpdir,'db/dumps/db.sql')}")
|
77
|
+
# FileUtils.mkdir_p('public/assets')
|
78
|
+
# puts CapUtilsClass.shell("cp -rf #{File.join(tmpdir,'public/assets/products')} public/assets/products")
|
79
|
+
#end
|
80
|
+
|
81
|
+
|
82
|
+
|
83
|
+
|
84
|
+
end
|
85
|
+
|
86
|
+
|
@@ -0,0 +1,50 @@
|
|
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
|
+
|
@@ -0,0 +1,328 @@
|
|
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
|
+
# like scan but returns array of MatchData's.
|
84
|
+
# doesn't yet support blocks
|
85
|
+
def scan_md(aPattern)
|
86
|
+
result = []
|
87
|
+
self.scan(aPattern) {|s| result << $~ }
|
88
|
+
result
|
89
|
+
end
|
90
|
+
|
91
|
+
end
|
92
|
+
|
93
|
+
|
94
|
+
Time.class_eval do
|
95
|
+
|
96
|
+
if !respond_to?(:change) # no activesupport loaded
|
97
|
+
def change(options)
|
98
|
+
::Time.send(
|
99
|
+
self.utc? ? :utc : :local,
|
100
|
+
options[:year] || self.year,
|
101
|
+
options[:month] || self.month,
|
102
|
+
options[:day] || self.day,
|
103
|
+
options[:hour] || self.hour,
|
104
|
+
options[:min] || (options[:hour] ? 0 : self.min),
|
105
|
+
options[:sec] || ((options[:hour] || options[:min]) ? 0 : self.sec),
|
106
|
+
options[:usec] || ((options[:hour] || options[:min] || options[:sec]) ? 0 : self.usec)
|
107
|
+
)
|
108
|
+
end
|
109
|
+
|
110
|
+
def seconds_since_midnight
|
111
|
+
self.to_i - self.change(:hour => 0).to_i + (self.usec/1.0e+6)
|
112
|
+
end
|
113
|
+
|
114
|
+
def beginning_of_day
|
115
|
+
(self - self.seconds_since_midnight).change(:usec => 0)
|
116
|
+
end
|
117
|
+
|
118
|
+
alias :midnight :beginning_of_day
|
119
|
+
alias :at_midnight :beginning_of_day
|
120
|
+
alias :at_beginning_of_day :beginning_of_day
|
121
|
+
|
122
|
+
end
|
123
|
+
|
124
|
+
# offset of local machine from UTC, in seconds eg +9.hours
|
125
|
+
def self.local_offset
|
126
|
+
local(2000).utc_offset
|
127
|
+
end
|
128
|
+
|
129
|
+
def date
|
130
|
+
self.at_beginning_of_day
|
131
|
+
end
|
132
|
+
|
133
|
+
# index number of this day, from Time.at(0) + utc_offset
|
134
|
+
def day_number
|
135
|
+
(self.to_i+self.utc_offset) / 86400
|
136
|
+
end
|
137
|
+
|
138
|
+
# index number of this utc day
|
139
|
+
def day_number_utc
|
140
|
+
self.to_i / 86400
|
141
|
+
end
|
142
|
+
|
143
|
+
# the last microsecond of the day
|
144
|
+
def day_end
|
145
|
+
self.at_beginning_of_day + 86399.999999
|
146
|
+
end
|
147
|
+
|
148
|
+
def date_numeric
|
149
|
+
self.strftime('%Y%m%d')
|
150
|
+
end
|
151
|
+
|
152
|
+
# create a new Time from eg. "20081231"
|
153
|
+
def self.from_date_numeric(aString)
|
154
|
+
return nil unless aString
|
155
|
+
local(aString[0,4].to_i,aString[4,2].to_i,aString[6,2].to_i)
|
156
|
+
end
|
157
|
+
|
158
|
+
def time_numeric
|
159
|
+
self.strftime('%H%M%S')
|
160
|
+
end
|
161
|
+
|
162
|
+
def datetime_numeric
|
163
|
+
self.strftime('%Y%m%d-%H%M%S')
|
164
|
+
end
|
165
|
+
|
166
|
+
def to_sql
|
167
|
+
self.strftime('%Y-%m-%d %H:%M:%S')
|
168
|
+
end
|
169
|
+
|
170
|
+
def to_w3c
|
171
|
+
utc.strftime("%Y-%m-%dT%H:%M:%S+00:00")
|
172
|
+
end
|
173
|
+
end
|
174
|
+
|
175
|
+
module HashUtils
|
176
|
+
def filter_include!(aKeys,aHash=nil)
|
177
|
+
aHash ||= self
|
178
|
+
|
179
|
+
if aKeys.is_a? Regexp
|
180
|
+
return aHash.delete_if {|k,v| not k =~ aKeys }
|
181
|
+
else
|
182
|
+
aKeys = [aKeys] unless aKeys.is_a? Array
|
183
|
+
return aHash.clear if aKeys.empty?
|
184
|
+
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)))}
|
185
|
+
return aHash # last resort
|
186
|
+
end
|
187
|
+
end
|
188
|
+
|
189
|
+
def filter_include(aKeys,aHash=nil)
|
190
|
+
aHash ||= self
|
191
|
+
filter_include!(aKeys,aHash.clone)
|
192
|
+
end
|
193
|
+
|
194
|
+
def filter_exclude!(aKeys,aHash=nil)
|
195
|
+
aHash ||= self
|
196
|
+
|
197
|
+
if aKeys.is_a? Regexp
|
198
|
+
return aHash.delete_if {|k,v| k =~ aKeys }
|
199
|
+
else
|
200
|
+
aKeys = [aKeys] unless aKeys.is_a? Array
|
201
|
+
return aHash if aKeys.empty?
|
202
|
+
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)))}
|
203
|
+
end
|
204
|
+
end
|
205
|
+
|
206
|
+
def filter_exclude(aKeys,aHash=nil)
|
207
|
+
aHash ||= self
|
208
|
+
filter_exclude!(aKeys,aHash.clone)
|
209
|
+
end
|
210
|
+
|
211
|
+
def has_values_for?(aKeys,aHash=nil)
|
212
|
+
aHash ||= self
|
213
|
+
# check all keys exist in aHash and their values are not nil
|
214
|
+
aKeys.all? { |k,v| aHash[k] }
|
215
|
+
end
|
216
|
+
|
217
|
+
# give a block to execute without the given key in this hash
|
218
|
+
# It will be replaced after the block (guaranteed by ensure)
|
219
|
+
# eg.
|
220
|
+
# hash.without_key(:blah) do |aHash|
|
221
|
+
# puts aHash.inspect
|
222
|
+
# end
|
223
|
+
def without_key(aKey)
|
224
|
+
temp = nil
|
225
|
+
h = self
|
226
|
+
begin
|
227
|
+
if h.include?(aKey)
|
228
|
+
temp = [aKey,h.delete(aKey)]
|
229
|
+
end
|
230
|
+
result = yield(h)
|
231
|
+
ensure
|
232
|
+
h[temp[0]] = temp[1] if temp
|
233
|
+
end
|
234
|
+
return result
|
235
|
+
end
|
236
|
+
|
237
|
+
def symbolize_keys
|
238
|
+
result = {}
|
239
|
+
self.each { |k,v| k.is_a?(String) ? result[k.to_sym] = v : result[k] = v }
|
240
|
+
return result
|
241
|
+
end
|
242
|
+
|
243
|
+
end
|
244
|
+
|
245
|
+
Hash.class_eval do
|
246
|
+
include HashUtils
|
247
|
+
end
|
248
|
+
|
249
|
+
if defined? HashWithIndifferentAccess
|
250
|
+
HashWithIndifferentAccess.class_eval do
|
251
|
+
include HashUtils
|
252
|
+
end
|
253
|
+
end
|
254
|
+
|
255
|
+
module ArrayUtils
|
256
|
+
def filter_include!(aValues,aArray=nil)
|
257
|
+
aArray ||= self
|
258
|
+
if aValues.is_a? Array
|
259
|
+
return aArray if aValues.empty?
|
260
|
+
return aArray.delete_if {|v| not aValues.include? v }
|
261
|
+
elsif aValues.is_a? Regexp
|
262
|
+
return aArray.delete_if {|v| not v =~ aValues }
|
263
|
+
else
|
264
|
+
return filter_include!([aValues],aArray)
|
265
|
+
end
|
266
|
+
end
|
267
|
+
|
268
|
+
def filter_include(aValues,aArray=nil)
|
269
|
+
aArray ||= self
|
270
|
+
filter_include!(aValues,aArray.clone)
|
271
|
+
end
|
272
|
+
|
273
|
+
def filter_exclude!(aValues,aArray=nil)
|
274
|
+
aArray ||= self
|
275
|
+
if aValues.is_a? Array
|
276
|
+
return aArray if aValues.empty?
|
277
|
+
return aArray.delete_if {|v| aValues.include? v }
|
278
|
+
elsif aValues.is_a? Regexp
|
279
|
+
return aArray.delete_if {|v| v =~ aValues }
|
280
|
+
else
|
281
|
+
return filter_exclude!([aValues],aArray)
|
282
|
+
end
|
283
|
+
end
|
284
|
+
|
285
|
+
def filter_exclude(aValues,aArray=nil)
|
286
|
+
aArray ||= self
|
287
|
+
filter_exclude!(aValues,aArray.clone)
|
288
|
+
end
|
289
|
+
end
|
290
|
+
|
291
|
+
Array.class_eval do
|
292
|
+
include ArrayUtils
|
293
|
+
|
294
|
+
# fixes a memory leak in shift in Ruby 1.8 - should be fixed in 1.9
|
295
|
+
# see http://blade.nagaokaut.ac.jp/cgi-bin/scat.rb/ruby/ruby-talk/216055
|
296
|
+
def shift()
|
297
|
+
delete_at(0)
|
298
|
+
end
|
299
|
+
|
300
|
+
end
|
301
|
+
|
302
|
+
Kernel.class_eval do
|
303
|
+
def is_windows?
|
304
|
+
RUBY_PLATFORM =~ /(win|w)32$/ ? true : false
|
305
|
+
end
|
306
|
+
end
|
307
|
+
|
308
|
+
if defined? ActiveRecord
|
309
|
+
ActiveRecord::Base.class_eval do
|
310
|
+
|
311
|
+
def self.find_any_id(aId)
|
312
|
+
with_exclusive_scope { find(:first, {:conditions => {:id => aId}}) }
|
313
|
+
end
|
314
|
+
|
315
|
+
def self.find_any_all(aOptions={})
|
316
|
+
with_exclusive_scope { find(:all, aOptions) }
|
317
|
+
end
|
318
|
+
|
319
|
+
def self.find_ids(aIds)
|
320
|
+
find(:all, {:conditions=> ["id in (?)",aIds.join(',')]})
|
321
|
+
end
|
322
|
+
|
323
|
+
def self.find_any_ids(aIds)
|
324
|
+
with_exclusive_scope { find(:all, {:conditions=> ["id in (?)",aIds.join(',')]}) }
|
325
|
+
end
|
326
|
+
|
327
|
+
end
|
328
|
+
end
|
@@ -0,0 +1,29 @@
|
|
1
|
+
require 'net/http'
|
2
|
+
require 'buzzcore/misc_utils'
|
3
|
+
require 'buzzcore/xml_utils'
|
4
|
+
|
5
|
+
module HtmlUtils
|
6
|
+
|
7
|
+
#browser-safe inline block
|
8
|
+
INLINE_BLOCK_SAFE_STYLE = "display: -moz-inline-box; display: inline-block; zoom: 1; *display:inline"
|
9
|
+
|
10
|
+
# see fixed_frame_image
|
11
|
+
RIGID_CRR_BLOCK_STYLE = "margin: 0; padding: 0; position: relative; top: 0pt; left: 0pt; display: table-cell; vertical-align: middle; overflow: hidden"
|
12
|
+
IMAGE_CRD_STYLE = "display: block; margin: auto; vertical-align: middle;"
|
13
|
+
|
14
|
+
def self.fixed_frame_image(aImgTag,aFrameW,aFrameH,aImgW=nil,aImgH=nil)
|
15
|
+
style = RIGID_CRR_BLOCK_STYLE+";width: #{aFrameW}px; height: #{aFrameH}px"
|
16
|
+
result = "<div style=\"#{INLINE_BLOCK_SAFE_STYLE}\"><div style=\"#{style}\">"
|
17
|
+
aImgTag = XmlUtils.quick_remove_att(aImgTag,'width') if aImgW
|
18
|
+
aImgTag = XmlUtils.quick_remove_att(aImgTag,'height') if aImgH
|
19
|
+
style = XmlUtils.quick_att_from_tag(aImgTag,'style').to_s
|
20
|
+
style += IMAGE_CRD_STYLE
|
21
|
+
style += ";width: #{aImgW}px; height: #{aImgH}px"
|
22
|
+
aImgTag = XmlUtils.quick_set_att(aImgTag,'style',style)
|
23
|
+
result << aImgTag
|
24
|
+
result << "</div></div>"
|
25
|
+
result
|
26
|
+
end
|
27
|
+
|
28
|
+
end
|
29
|
+
|
@@ -0,0 +1,159 @@
|
|
1
|
+
require 'logger'
|
2
|
+
require 'buzzcore/misc_utils'
|
3
|
+
|
4
|
+
class Logger
|
5
|
+
attr_reader :logdev
|
6
|
+
end
|
7
|
+
|
8
|
+
module LogUtils
|
9
|
+
|
10
|
+
# eg.
|
11
|
+
# {
|
12
|
+
# 'destination' => 'STDERR|STDOUT|FILE',
|
13
|
+
# 'filename' => '/path/to/file.ext',
|
14
|
+
# 'level' => 'DEBUG|INFO|...',
|
15
|
+
#
|
16
|
+
# 'age' = 'daily|weekly|monthly',
|
17
|
+
# OR
|
18
|
+
# 'max_files' => 3,
|
19
|
+
# 'max_bytes' => 1024000
|
20
|
+
# }
|
21
|
+
def self.create_logger_from_config(aConfigHash)
|
22
|
+
if not aConfigHash
|
23
|
+
result = Logger.new(STDERR)
|
24
|
+
result.level = Logger::INFO
|
25
|
+
return result
|
26
|
+
end
|
27
|
+
|
28
|
+
result = nil
|
29
|
+
case aConfigHash['destination']
|
30
|
+
when 'STDERR' then
|
31
|
+
result = Logger.new(STDERR)
|
32
|
+
when 'STDOUT' then
|
33
|
+
result = Logger.new(STDOUT)
|
34
|
+
when 'FILE' then
|
35
|
+
result = aConfigHash['age'] ?
|
36
|
+
Logger.new(aConfigHash['filename'],aConfigHash['age']) :
|
37
|
+
Logger.new(
|
38
|
+
aConfigHash['filename'],
|
39
|
+
(aConfigHash['max_files'] || 3).to_i,
|
40
|
+
(aConfigHash['max_bytes'] || 1024000).to_i
|
41
|
+
)
|
42
|
+
else
|
43
|
+
result = Logger.new(STDERR)
|
44
|
+
end
|
45
|
+
puts valstr = "Logger::#{(aConfigHash['level'] || 'INFO').upcase}"
|
46
|
+
result.level = eval(valstr)
|
47
|
+
return result
|
48
|
+
end
|
49
|
+
|
50
|
+
# use this to trunc a log file to 0 bytes
|
51
|
+
def self.trunc(aFilename)
|
52
|
+
f = File.open(aFilename, "w")
|
53
|
+
f.close
|
54
|
+
end
|
55
|
+
|
56
|
+
class ReportFormatter < Logger::Formatter
|
57
|
+
def call(severity, time, progname, msg)
|
58
|
+
"|%s %1s %s\n" % [(time.strftime('%H%M%S.')<<"%03d" % (time.usec/1000)),severity[0..0],msg2str(msg)]
|
59
|
+
end
|
60
|
+
end
|
61
|
+
|
62
|
+
class Reporter < Logger
|
63
|
+
def initialize(logdev)
|
64
|
+
super(logdev)
|
65
|
+
end
|
66
|
+
|
67
|
+
end
|
68
|
+
|
69
|
+
def self.create_reporter(aFilename=nil)
|
70
|
+
aFilename ||= MiscUtils::temp_file()
|
71
|
+
result = Logger.new(aFilename)
|
72
|
+
result.formatter = ReportFormatter.new
|
73
|
+
result
|
74
|
+
end
|
75
|
+
end
|
76
|
+
|
77
|
+
|
78
|
+
|
79
|
+
class MultiLogger < Logger
|
80
|
+
|
81
|
+
attr_reader :loggers
|
82
|
+
|
83
|
+
def initialize(aLoggers)
|
84
|
+
@loggers = aLoggers.is_a?(Array) ? aLoggers : [aLoggers]
|
85
|
+
end
|
86
|
+
|
87
|
+
def add(severity, message = nil, progname = nil, &block)
|
88
|
+
return true if !@loggers
|
89
|
+
severity ||= UNKNOWN
|
90
|
+
@loggers.each do |lr|
|
91
|
+
block_given? ? lr.add(severity,message,progname,&block) : lr.add(severity,message,progname)
|
92
|
+
end
|
93
|
+
true
|
94
|
+
end
|
95
|
+
alias log add
|
96
|
+
|
97
|
+
def <<(msg)
|
98
|
+
@loggers.each do |lr|
|
99
|
+
lr << msg
|
100
|
+
end
|
101
|
+
end
|
102
|
+
|
103
|
+
def close
|
104
|
+
@loggers.each do |lr|
|
105
|
+
lr.close
|
106
|
+
end
|
107
|
+
end
|
108
|
+
|
109
|
+
end
|
110
|
+
|
111
|
+
#DEBUG D
|
112
|
+
#INFO
|
113
|
+
#WARN ?
|
114
|
+
#ERROR !
|
115
|
+
#FATAL F
|
116
|
+
#UNKNOWN U
|
117
|
+
|
118
|
+
# Logger that mostly works like a STDOUT logger, except that warnings and above get sent to STDERR instead
|
119
|
+
class ConsoleLogger < Logger
|
120
|
+
|
121
|
+
class ReportFormatter < Logger::Formatter
|
122
|
+
def call(severity, time, progname, msg)
|
123
|
+
msg2str(msg)+"\n"
|
124
|
+
end
|
125
|
+
end
|
126
|
+
|
127
|
+
def initialize(aErrLevel = Severity::WARN)
|
128
|
+
super(STDOUT)
|
129
|
+
self.formatter = ReportFormatter.new
|
130
|
+
self.level = Severity::INFO
|
131
|
+
self << "\n"
|
132
|
+
@err_logger = Logger.new(STDERR)
|
133
|
+
@err_level = aErrLevel
|
134
|
+
@err_logger.formatter = ReportFormatter.new
|
135
|
+
end
|
136
|
+
|
137
|
+
alias_method :orig_add, :add
|
138
|
+
def add(severity, message = nil, progname = nil, &block)
|
139
|
+
if severity >= @err_level
|
140
|
+
block_given? ? @err_logger.add(severity,message,progname,&block) : @err_logger.add(severity,message,progname)
|
141
|
+
else
|
142
|
+
block_given? ? orig_add(severity,message,progname,&block) : orig_add(severity,message,progname)
|
143
|
+
end
|
144
|
+
end
|
145
|
+
alias log add
|
146
|
+
|
147
|
+
#
|
148
|
+
# Close the logging device.
|
149
|
+
#
|
150
|
+
def close
|
151
|
+
begin
|
152
|
+
@logdev.close if @logdev
|
153
|
+
ensure
|
154
|
+
@err_logger.close
|
155
|
+
end
|
156
|
+
end
|
157
|
+
|
158
|
+
end
|
159
|
+
|