rmtools 1.0.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,90 @@
1
+ # encoding: utf-8
2
+ module Enumerable
3
+
4
+ def import(arr, index)
5
+ self[index] = arr[index]
6
+ end
7
+
8
+ def export(arr, index)
9
+ arr[index] = self[index]
10
+ end
11
+
12
+ def foldl(o, m=nil)
13
+ block_given? ?
14
+ reduce(m ? yield(m) : nil) {|m, i| m ? m.send(o, yield(i)) : yield(i)} :
15
+ reduce(m) {|m, i| m ? m.send(o, i) : i}
16
+ end
17
+
18
+ def foldr(o, m=nil)
19
+ block_given? ?
20
+ reverse.reduce(m ? yield(m) : nil) {|m, i| m ? yield(i).send(o, m) : yield(i)} :
21
+ reverse.reduce(m) {|m, i| m ? i.send(o, m) : i}
22
+ end
23
+
24
+ if RUBY_VERSION < "1.8.7"
25
+ def xprod(obj, inverse=false)
26
+ size = self.size
27
+ if obj.kinda Array or obj.is Set
28
+ objsize = obj.size
29
+ raise ArgumentError, "can't complement #{self.class} with void container" if objsize == 0
30
+ if size == 1
31
+ case objsize
32
+ when 1 then inverse ? [[obj.first, first]] : [[first, obj.first]]
33
+ else obj.xprod_one first, !inverse
34
+ end
35
+ else
36
+ case objsize
37
+ when 1 then xprod_one obj.first, inverse
38
+ else xprod_many obj, inverse
39
+ end
40
+ end
41
+ else xprod_one obj, inverse
42
+ end
43
+ end
44
+
45
+ protected
46
+ def xprod_one(obj, inverse)
47
+ inverse ? map {|te| [obj, te]} : map {|te| [te, obj]}
48
+ end
49
+
50
+ def xprod_many(obj, inverse)
51
+ a = []
52
+ inverse ?
53
+ obj.each {|oe| each {|te| a << [oe, te]}} :
54
+ each {|te| obj.each {|oe| a << [te, oe]}}
55
+ a
56
+ end
57
+ else
58
+ def xprod(obj, inverse=false)
59
+ obj = obj.to_a if obj.is Set
60
+ obj = [obj] if !obj.kinda(Array)
61
+ inverse ? obj.to_a.product(self) : product(obj)
62
+ end
63
+ end
64
+
65
+ end
66
+
67
+ module ObjectSpace
68
+ extend Enumerable
69
+
70
+ def self.each(&b) self.each_object(&b) end
71
+
72
+ end
73
+
74
+ class Object
75
+
76
+ # block must return a pair
77
+ def unfold(break_if=lambda{|x|x==0}, &splitter)
78
+ obj, container = self, []
79
+ until begin
80
+ result = splitter[obj]
81
+ container.unshift result[1]
82
+ break_if[result[0]]
83
+ end
84
+ obj = result[0]
85
+ end
86
+ container
87
+ end
88
+
89
+ end
90
+
@@ -0,0 +1,40 @@
1
+ # encoding: utf-8
2
+ class Hash
3
+
4
+ def +(other_hash)
5
+ merge(other_hash || {})
6
+ end
7
+
8
+ def concat(other_hash)
9
+ merge!(other_hash || {})
10
+ end
11
+
12
+ def unify_strs
13
+ each {|k, v|
14
+ if k.is String
15
+ sk = k.to_sym
16
+ self[sk] = v if !self[sk]
17
+ elsif k.is Symbol
18
+ sk = k.to_s
19
+ self[sk] = v if !self[sk]
20
+ end
21
+ }
22
+ end
23
+
24
+ def max; [(m = keys.max), self[m]] end
25
+
26
+ def min; [(m = keys.min), self[m]] end
27
+
28
+ # should be overriden by extension maps
29
+ def map2
30
+ h = {}
31
+ each {|k, v| h[k] = yield(k,v)}
32
+ h
33
+ end
34
+
35
+ def map!
36
+ each {|k, v| self[k] = yield(k,v)}
37
+ self
38
+ end
39
+
40
+ end
data/lib/rmtools/io.rb ADDED
@@ -0,0 +1,303 @@
1
+ # encoding: utf-8
2
+ class Dir
3
+
4
+ def include?(name)
5
+ #content.map {|f| File.split(f)[1]}.include? name
6
+ entries.include? name
7
+ end
8
+
9
+ def recursive_content(flat=true)
10
+ list = []
11
+ cont = content.map {|f|
12
+ if File.directory?(f)
13
+ rc = Dir.new(f).recursive_content.map {|f| f.sub(/^\.\//, '')}
14
+ flat ? list.concat(rc) : rc
15
+ else flat ? (list << f) : f
16
+ end
17
+ }
18
+ (flat ? list : cont)
19
+ end
20
+
21
+ def content
22
+ Dir["#{path}/**"].b || to_a[2..-1].sort.map {|c| File.join path, c}
23
+ end
24
+
25
+ def parent
26
+ newpath = File.dirname(path)
27
+ Dir.new(newpath) if newpath != path
28
+ end
29
+
30
+ def child(idx)
31
+ df = content[idx]
32
+ if File.file?(df)
33
+ File.new(df)
34
+ elsif File.directory?(df)
35
+ Dir.new(df)
36
+ end
37
+ end
38
+
39
+ def children
40
+ content.map {|df|
41
+ if File.file?(df)
42
+ File.new(df)
43
+ elsif File.directory?(df)
44
+ Dir.new(df)
45
+ end
46
+ }
47
+ end
48
+
49
+ def refresh
50
+ return if !File.directory?(path)
51
+ Dir.new(path)
52
+ end
53
+
54
+ def inspect
55
+ displaypath = case path
56
+ when /^(\/|\w:)/ then path
57
+ when /^\./ then File.join(Dir.pwd, path[1..-1])
58
+ else File.join(Dir.pwd, path)
59
+ end
60
+ "<#Dir \"#{displaypath}\" #{to_a.size - 2} elements>"
61
+ end
62
+
63
+ def name
64
+ File.basename(path)
65
+ end
66
+
67
+ # Fixing windoze path problems
68
+ # requires amatch gem for better performance
69
+ def real_name
70
+ n, p, count = name, parent, []
71
+ return n if !p
72
+ pp, pc, sc = parent.path, parent.to_a[2..-1], to_a
73
+ if defined? Amatch
74
+ ms = pc.sizes.max
75
+ count = [:hamming_similar, :levenshtein_similar, :jaro_similar].sum {|m| pc.group_by {|_| _.upcase.ljust(ms).send(m, n)}.max[1]}.count.to_a
76
+ max = count.lasts.max
77
+ res = count.find {|c|
78
+ c[1] == max and File.directory?(df=File.join(pp, c[0])) and Dir.new(df).to_a == sc
79
+ }
80
+ return res[0] if res
81
+ end
82
+ (pc - count).find {|c|
83
+ File.directory?(df=File.join(pp, c)) and Dir.new(df).to_a == sc
84
+ }
85
+ end
86
+
87
+ end
88
+
89
+ class File
90
+
91
+ def inspect
92
+ "<#File \"#{path}\" #{closed? ? 'closed' : stat.size.bytes}>"
93
+ end
94
+
95
+ def self.include?(name, str)
96
+ f = new name, 'r'
97
+ incl = f.include? str
98
+ f.close
99
+ incl
100
+ end
101
+
102
+ def include?(str)
103
+ while s = gets do return true if s.include? str end
104
+ end
105
+
106
+ def parent
107
+ newpath = File.dirname(path)
108
+ Dir.new(newpath) if newpath != path
109
+ end
110
+
111
+ def name
112
+ File.basename(path)
113
+ end
114
+
115
+ def ext
116
+ name[/[^.]+$/]
117
+ end
118
+
119
+ def refresh
120
+ return if !File.file?(path)
121
+ close
122
+ File.new(path,'r')
123
+ end
124
+
125
+ def self.modify(file, bak=true)
126
+ orig_text = read file
127
+ text = yield orig_text
128
+ rename file, file+'.bak' if bak
129
+ RMTools.rw(file, text.is(String) ? text : orig_text)
130
+ end
131
+
132
+ def cp(df)
133
+ dir = File.dirname df
134
+ FileUtils.mkpath dir unless File.directory? dir
135
+ FileUtils.cp path, df
136
+ end
137
+
138
+ def mv(df)
139
+ dir = File.dirname df
140
+ FileUtils.mkpath dir unless File.directory? dir
141
+ rename df
142
+ end
143
+
144
+ # Fixing windoze path problems
145
+ # requires amatch gem for better performance
146
+ def real_name
147
+ n, p, count = name, parent, []
148
+ pp, pc, ss = parent.path, parent.to_a[2..-1], stat
149
+ ms = pc.sizes.max
150
+ n, ext = n.rsplit('.', 2)
151
+ if ext
152
+ re = /\.#{ext}$/i
153
+ pc.reject! {|f| !f[re]}
154
+ end
155
+ if defined? Amatch
156
+ count = [:hamming_similar, :levenshtein_similar, :jaro_similar].sum {|m| pc.group_by {|f| (ext ? f[0..-(ext.size+2)] : f).upcase.ljust(ms).send(m, n)}.max[1]}.count.to_a
157
+ max = count.lasts.max
158
+ res = count.find {|c|
159
+ c[1] == max and File.file?(df=File.join(pp, c[0])) and File.stat(df) == ss
160
+ }
161
+ return res[0] if res
162
+ end
163
+ (pc - count).find {|c|
164
+ File.file?(df=File.join(pp, c)) and File.stat(df) == ss
165
+ }
166
+ end
167
+
168
+ PathMemo = {} if !defined? PathMemo
169
+ def self.real_path path, memo=1
170
+ a = expand_path(path).split(/[\/\\]/)
171
+ a.each_index {|i|
172
+ if a[j=-(i+1)]['~']
173
+ n = i+2>a.size ? a[j] : join(a[0..-(i+2)], a[j])
174
+ a[j] = PathMemo[n] || real_name(n)
175
+ PathMemo[n] = a[j] if memo
176
+ else break
177
+ end
178
+ }
179
+ a*'/'
180
+ end
181
+
182
+ def self.real_name(df)
183
+ if file?(df)
184
+ new(df).real_name
185
+ elsif directory?(df)
186
+ Dir.new(df).real_name
187
+ end
188
+ end
189
+
190
+ end
191
+
192
+ class IO
193
+
194
+ def gets2
195
+ str = ''
196
+ str << (c = read 1) until c and "\r\n\b".include? c or eof?
197
+ str
198
+ end
199
+
200
+ end
201
+
202
+ module RMTools
203
+
204
+ def tick!
205
+ print %W{|\b /\b -\b \\\b +\b X\b}.rand
206
+ end
207
+
208
+ def executing? file
209
+ caller(0)[0] =~ /^#{file}:/
210
+ end
211
+
212
+ def rw(df, value=nil)
213
+ return false if value.nil?
214
+ df.gsub!('\\', '/')
215
+ path = File.dirname(df)
216
+ FileUtils.mkpath(path) if !File.directory?(path)
217
+ mode = RUBY_VERSION > '1.9' ? :wb : 'wb'
218
+ File.open(df, mode) {|f| f << value}
219
+ value.size
220
+ end
221
+
222
+ def write(df, value='', pos=0)
223
+ return false if value.nil?
224
+ df.gsub!('\\', '/')
225
+ path = File.dirname(df)
226
+ FileUtils.mkpath(path) if !File.directory?(path)
227
+ if pos == 0
228
+ mode = RUBY_VERSION > '1.9' ? :ab : 'ab'
229
+ File.open(df, mode) {|f| f << value}
230
+ else
231
+ if pos < 0
232
+ raise IndexError, "file #{df} does not exist, can't write from position #{pos}" if !File.file?(df)
233
+ raise IndexError, "file #{df} is shorter than #{(-pos).bytes}, can't write from position #{pos}" if (size = File.size(df)) < -pos
234
+ pos = size + pos
235
+ end
236
+ File.open(df, 'r+') {|f| f.pos = pos; f << value}
237
+ end
238
+ value.size
239
+ end
240
+
241
+ def read(df, mode='rb')
242
+ df.gsub!('\\', '/')
243
+ if !File.file?(df)
244
+ $log.debug "#{df} is missed!"
245
+ else
246
+ File.open(df, mode) {|f| f.read}
247
+ end
248
+ end
249
+
250
+ def read_lines(df, *lines)
251
+ return if !lines or lines.empty?
252
+ str = ""
253
+ last = lines.max
254
+ if !File.file?(df)
255
+ puts "#{df} is missed!"
256
+ else
257
+ File.open(df, 'r') {|f|
258
+ f.each {|line|
259
+ no = f.lineno
260
+ str << line if no.in lines
261
+ break if no == last
262
+ }}
263
+ str
264
+ end
265
+ end
266
+
267
+ def highlighted_line(file, line)
268
+ if defined? SCRIPT_LINES__
269
+ " >> #{Painter.green SCRIPT_LINES__[file][line.to_i - 1].chop}" if SCRIPT_LINES__[file]
270
+ else
271
+ file = Readline::TEMPLOG if file == '(irb)' and defined? Readline::TEMPLOG
272
+ " >> #{Painter.green read_lines(file, line.to_i).chop}" if File.file? file
273
+ end
274
+ end
275
+
276
+ def tail(file, bytes=1000)
277
+ if !File.file?(file)
278
+ puts "#{file} is missed!"
279
+ else
280
+ IO.read(file, bytes, File.size(file)-bytes)
281
+ end
282
+ end
283
+
284
+ def tail_n(file, qty=10)
285
+ if !File.file?(file)
286
+ return puts "#{file} is missed!"
287
+ end
288
+ size = File.size(file)
289
+ lines = []
290
+ strlen = 0
291
+ step = qty*100
292
+ while qty > 0 and (offset = size-strlen-step) >= 0 and (str = IO.read(file, step, offset)).b
293
+ i = str.index("\n") || str.size
294
+ strlen += step - i
295
+ new_lines = str[i+1..-1]/"\n"
296
+ qty -= new_lines.size
297
+ lines = new_lines.concat(lines)
298
+ end
299
+ lines[-qty..-1]
300
+ end
301
+
302
+ module_function :tick!, :executing?, :rw, :write, :read, :read_lines, :highlighted_line, :tail, :tail_n
303
+ end
data/lib/rmtools/js.rb ADDED
@@ -0,0 +1,25 @@
1
+ # encoding: utf-8
2
+ class Hash
3
+
4
+ def method_missing(met, *args)
5
+ str = met.id2name
6
+ if str[/=$/]
7
+ self[str[0..-2]] = args[0]
8
+ else
9
+ raise NoMethodError, "undefined method `#{str}' for #{self}:#{(self.class)}" if !args.empty?
10
+ a = self[str]
11
+ (a == default) ? self[met] : a
12
+ end
13
+ end
14
+
15
+ end
16
+
17
+ class String
18
+ if !method_defined? :plus
19
+ alias :plus :+ end
20
+
21
+ def +(str)
22
+ plus str.to_s
23
+ end
24
+
25
+ end