buzzcore 0.2.5

Sign up to get free protection for your applications and to get access to all the features.
@@ -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
+