libisi 0.3.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/LICENSE +677 -0
- data/Manifest +89 -0
- data/Rakefile +34 -0
- data/lib/inifile.rb +119 -0
- data/lib/libisi.rb +948 -0
- data/lib/libisi/attribute.rb +32 -0
- data/lib/libisi/attribute/activerecord.rb +34 -0
- data/lib/libisi/attribute/base.rb +33 -0
- data/lib/libisi/base.rb +109 -0
- data/lib/libisi/bridge.rb +21 -0
- data/lib/libisi/bridge/base.rb +23 -0
- data/lib/libisi/bridge/java.rb +71 -0
- data/lib/libisi/bridge/python.rb +37 -0
- data/lib/libisi/cache.rb +21 -0
- data/lib/libisi/cache/base.rb +67 -0
- data/lib/libisi/cache/file_cache.rb +24 -0
- data/lib/libisi/chart.rb +21 -0
- data/lib/libisi/chart/base.rb +320 -0
- data/lib/libisi/chart/jfreechart.rb +682 -0
- data/lib/libisi/chart/jfreechart_generator.rb +206 -0
- data/lib/libisi/color.rb +21 -0
- data/lib/libisi/color/base.rb +66 -0
- data/lib/libisi/color/colortools.rb +92 -0
- data/lib/libisi/color/java.rb +44 -0
- data/lib/libisi/concept.rb +33 -0
- data/lib/libisi/concept/activerecord.rb +39 -0
- data/lib/libisi/concept/base.rb +58 -0
- data/lib/libisi/doc.rb +35 -0
- data/lib/libisi/doc/base.rb +414 -0
- data/lib/libisi/doc/html.rb +85 -0
- data/lib/libisi/doc/text.rb +98 -0
- data/lib/libisi/doc/wiki.rb +55 -0
- data/lib/libisi/environment.rb +21 -0
- data/lib/libisi/environment/base.rb +36 -0
- data/lib/libisi/environment/http.rb +105 -0
- data/lib/libisi/environment/rails.rb +27 -0
- data/lib/libisi/environment/root.rb +23 -0
- data/lib/libisi/fake_logger/logger.rb +61 -0
- data/lib/libisi/function/base.rb +30 -0
- data/lib/libisi/hal.rb +558 -0
- data/lib/libisi/instance.rb +27 -0
- data/lib/libisi/instance/activerecord.rb +21 -0
- data/lib/libisi/instance/base.rb +42 -0
- data/lib/libisi/log.rb +237 -0
- data/lib/libisi/mail/base.rb +32 -0
- data/lib/libisi/mail/tmail.rb +120 -0
- data/lib/libisi/parameter/base.rb +41 -0
- data/lib/libisi/property.rb +27 -0
- data/lib/libisi/property/base.rb +28 -0
- data/lib/libisi/reciever/base.rb +31 -0
- data/lib/libisi/reciever/socket.rb +31 -0
- data/lib/libisi/relation.rb +23 -0
- data/lib/libisi/request.rb +22 -0
- data/lib/libisi/request/base.rb +29 -0
- data/lib/libisi/request/http.rb +129 -0
- data/lib/libisi/response/base.rb +27 -0
- data/lib/libisi/task/base.rb +27 -0
- data/lib/libisi/task/http.rb +90 -0
- data/lib/libisi/tee.rb +296 -0
- data/lib/libisi/ui/base.rb +116 -0
- data/lib/libisi/ui/console.rb +238 -0
- data/lib/libisi/ui/kde.rb +94 -0
- data/lib/libisi/ui/nobody.rb +29 -0
- data/lib/libisi/ui/rails.rb +150 -0
- data/lib/libisi/ui/x11.rb +55 -0
- data/lib/libisi/uri.rb +42 -0
- data/lib/libisi/uri/activerecord.rb +152 -0
- data/lib/libisi/uri/base.rb +115 -0
- data/lib/libisi/uri/file.rb +43 -0
- data/lib/libisi/uri/ldap.rb +72 -0
- data/lib/libisi/uri/mysql.rb +98 -0
- data/lib/libisi/value.rb +31 -0
- data/lib/libisi/value/attribute_value.rb +19 -0
- data/lib/libisi/value/base.rb +55 -0
- data/lib/libisi/value/property_value.rb +19 -0
- data/lib/libisi/value/relation_value.rb +19 -0
- data/lib/ordered_hash.rb +228 -0
- data/libisi.gemspec +31 -0
- data/test/bridge_test.rb +77 -0
- data/test/cache_test.rb +65 -0
- data/test/chart_test.rb +179 -0
- data/test/color_test.rb +64 -0
- data/test/concept_test.rb +56 -0
- data/test/doc_test.rb +172 -0
- data/test/fixtures/test.db +0 -0
- data/test/ordered_hash_test.rb +39 -0
- data/test/profile_test.rb +36 -0
- data/test/request_test.rb +121 -0
- data/test/test +0 -0
- data/test/ui_test.rb +62 -0
- metadata +244 -0
data/lib/libisi/tee.rb
ADDED
|
@@ -0,0 +1,296 @@
|
|
|
1
|
+
# Copyright (C) 2007-2010 Logintas AG Switzerland
|
|
2
|
+
#
|
|
3
|
+
# This file is part of Libisi.
|
|
4
|
+
#
|
|
5
|
+
# Libisi is free software: you can redistribute it and/or modify
|
|
6
|
+
# it under the terms of the GNU General Public License as published by
|
|
7
|
+
# the Free Software Foundation, either version 3 of the License, or
|
|
8
|
+
# (at your option) any later version.
|
|
9
|
+
#
|
|
10
|
+
# Libisi is distributed in the hope that it will be useful,
|
|
11
|
+
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
12
|
+
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
13
|
+
# GNU General Public License for more details.
|
|
14
|
+
#
|
|
15
|
+
# You should have received a copy of the GNU General Public License
|
|
16
|
+
# along with Libisi. If not, see <http://www.gnu.org/licenses/>.
|
|
17
|
+
|
|
18
|
+
class Tee
|
|
19
|
+
attr_accessor :children
|
|
20
|
+
|
|
21
|
+
def deep_clone(obj)
|
|
22
|
+
case obj
|
|
23
|
+
when NilClass
|
|
24
|
+
obj
|
|
25
|
+
when Fixnum,Bignum,Float,NilClass,FalseClass,
|
|
26
|
+
TrueClass,Continuation, Symbol, Rational
|
|
27
|
+
klone = obj
|
|
28
|
+
when Hash
|
|
29
|
+
klone = obj.clone
|
|
30
|
+
obj.each{|k,v| klone[k] = deep_clone(v)}
|
|
31
|
+
when Array
|
|
32
|
+
klone = obj.clone
|
|
33
|
+
klone.clear
|
|
34
|
+
obj.each{|v| klone << deep_clone(v)}
|
|
35
|
+
else
|
|
36
|
+
klone = obj.clone
|
|
37
|
+
end
|
|
38
|
+
klone.instance_variables.each {|v|
|
|
39
|
+
klone.instance_variable_set(v,deep_clone(klone.instance_variable_get(v)))
|
|
40
|
+
}
|
|
41
|
+
klone
|
|
42
|
+
end
|
|
43
|
+
|
|
44
|
+
|
|
45
|
+
def initialize(children = [])
|
|
46
|
+
@children = children
|
|
47
|
+
end
|
|
48
|
+
|
|
49
|
+
def signature(method_id, *arguments, &block)
|
|
50
|
+
"#{method_id}(#{arguments.map {|a| a.inspect}.join(",")}#{",&block" if block})"
|
|
51
|
+
end
|
|
52
|
+
|
|
53
|
+
def method_missing(method_id, *arguments, &block)
|
|
54
|
+
if block
|
|
55
|
+
function_results, block_results = call_child(0, method_id, arguments, block)
|
|
56
|
+
function_results[0]
|
|
57
|
+
else
|
|
58
|
+
$log.debug{"Calling #{signature(method_id, *arguments, &block)} sequentially"}
|
|
59
|
+
# no block given, we can execute
|
|
60
|
+
# methods sequentially
|
|
61
|
+
result = nil
|
|
62
|
+
children.each_with_index {|child, index|
|
|
63
|
+
if index < (children.length-1)
|
|
64
|
+
child.send(method_id, *(deep_clone(arguments)))
|
|
65
|
+
else
|
|
66
|
+
result = child.send(method_id, *arguments)
|
|
67
|
+
end
|
|
68
|
+
}
|
|
69
|
+
result
|
|
70
|
+
end
|
|
71
|
+
end
|
|
72
|
+
|
|
73
|
+
def call_child(child_id, method_id, arguments, block)
|
|
74
|
+
raise "child with id #{child_id} does not exist" unless
|
|
75
|
+
children[child_id]
|
|
76
|
+
|
|
77
|
+
original_arguments = arguments
|
|
78
|
+
arguments = deep_clone(arguments)
|
|
79
|
+
|
|
80
|
+
raise "no block given" unless block
|
|
81
|
+
signature = signature(method_id, *arguments, &block)
|
|
82
|
+
$log.debug("Child ##{child_id}: Calling #{signature}")
|
|
83
|
+
|
|
84
|
+
vars = []
|
|
85
|
+
if block.arity > 0
|
|
86
|
+
block.arity.times {|i| vars.push("a#{i}")}
|
|
87
|
+
else
|
|
88
|
+
(-block.arity - 1).times {|i| vars.push("a#{i}")}
|
|
89
|
+
vars.push("*a")
|
|
90
|
+
end
|
|
91
|
+
block_text = ""
|
|
92
|
+
block_text += "proc {|#{vars.join(",")}|\n"
|
|
93
|
+
if child_id < (children.length-1)
|
|
94
|
+
block_text += " call_count += 1\n"
|
|
95
|
+
block_text += " function_results, block_results = call_child(child_id + 1, method_id, original_arguments, block) if call_count == 1\n"
|
|
96
|
+
block_text += " br = block_results[(call_count-1)]\n"
|
|
97
|
+
block_text += " br = deep_clone(br)\n"
|
|
98
|
+
# block_text += " p [#{vars.join(",")}]\n"
|
|
99
|
+
block_text += " br\n"
|
|
100
|
+
else
|
|
101
|
+
$log.debug("Last child, collecting results")
|
|
102
|
+
# this is the last child
|
|
103
|
+
# here we must collect all
|
|
104
|
+
# block results
|
|
105
|
+
block_text += " br = block.call(#{vars.join(",")})\n"
|
|
106
|
+
block_text += " $log.debug{\"Result of block is: \#\{br.inspect}\"\}\n"
|
|
107
|
+
block_text += " block_results << deep_clone(br)\n"
|
|
108
|
+
block_text += " call_count += 1\n"
|
|
109
|
+
block_text += " br\n"
|
|
110
|
+
end
|
|
111
|
+
block_text += "}\n"
|
|
112
|
+
block_results = []
|
|
113
|
+
function_results = []
|
|
114
|
+
call_count = 0
|
|
115
|
+
new_block = eval(block_text)
|
|
116
|
+
raise "Not same arity" if new_block.arity != block.arity
|
|
117
|
+
|
|
118
|
+
if child_id < (children.length-1)
|
|
119
|
+
function_results << children[child_id].send(method_id, *(deep_clone(arguments)), &new_block)
|
|
120
|
+
else
|
|
121
|
+
function_results << children[child_id].send(method_id, *original_arguments, &new_block)
|
|
122
|
+
end
|
|
123
|
+
raise "#{signature} master block execute #{block_results.length - 1} " +
|
|
124
|
+
"times child block ##{child_id} #{call_count} times." if
|
|
125
|
+
call_count != (block_results.length)
|
|
126
|
+
[function_results, block_results]
|
|
127
|
+
end
|
|
128
|
+
end
|
|
129
|
+
|
|
130
|
+
=begin
|
|
131
|
+
case @state
|
|
132
|
+
when 0
|
|
133
|
+
# first call
|
|
134
|
+
@state = 1
|
|
135
|
+
@arguments = arguments
|
|
136
|
+
@block = block
|
|
137
|
+
|
|
138
|
+
master.call(method_id, *arguments, &block)
|
|
139
|
+
calling master function
|
|
140
|
+
when 1
|
|
141
|
+
# recall of other function
|
|
142
|
+
# while executing master
|
|
143
|
+
@state = 2
|
|
144
|
+
@second_arguemtns = arguments
|
|
145
|
+
@second_block = block
|
|
146
|
+
calling children with arguments
|
|
147
|
+
# now all children have
|
|
148
|
+
# same calls, going to state 0
|
|
149
|
+
# again
|
|
150
|
+
method_missing(method_id, *arguments, &block)
|
|
151
|
+
when 2
|
|
152
|
+
# ok, this is a child call,
|
|
153
|
+
# should have the same arguments
|
|
154
|
+
# as those in state 1
|
|
155
|
+
raise "Second arguemtns are not equal" unless
|
|
156
|
+
@second_arguments == @arguments
|
|
157
|
+
end
|
|
158
|
+
end
|
|
159
|
+
|
|
160
|
+
|
|
161
|
+
def method_missing(method_id, *arguments, &block)
|
|
162
|
+
if @child_processing_number
|
|
163
|
+
|
|
164
|
+
end
|
|
165
|
+
|
|
166
|
+
signature = "#{method_id}(#{arguments.map {|a| a.inspect}.join(",")})"
|
|
167
|
+
$log.debug("Teeing #{signature} to #{children.length} children (#{children.map{|c| "#{c.class.name}(#{c.object_id})"}.join(",")})")
|
|
168
|
+
|
|
169
|
+
block_args = []
|
|
170
|
+
block_result = nil
|
|
171
|
+
|
|
172
|
+
if block
|
|
173
|
+
end
|
|
174
|
+
|
|
175
|
+
# call first child and get arguments and result of the block
|
|
176
|
+
|
|
177
|
+
children[1..-1].each_with_index {|child,i|
|
|
178
|
+
unless i == 0
|
|
179
|
+
@call_stack.push([method_id, arguments, slave_block])
|
|
180
|
+
else
|
|
181
|
+
@child_processing_number = i
|
|
182
|
+
end
|
|
183
|
+
|
|
184
|
+
if block
|
|
185
|
+
master.send(method_id, *arguments, master_block)
|
|
186
|
+
else
|
|
187
|
+
master.send(method_id, *arguments)
|
|
188
|
+
end
|
|
189
|
+
|
|
190
|
+
my_block = if i == 0
|
|
191
|
+
#print master_block_text
|
|
192
|
+
else
|
|
193
|
+
#print slave_block_text
|
|
194
|
+
end if block
|
|
195
|
+
|
|
196
|
+
$log.debug("Call##{i} #{signature}")
|
|
197
|
+
if my_block
|
|
198
|
+
child.send(method_id, *arguments, &my_block)
|
|
199
|
+
else
|
|
200
|
+
child.send(method_id, *arguments)
|
|
201
|
+
end
|
|
202
|
+
$log.debug("The arguments of child #{i} of #{signature} were #{block_args[i].inspect} with result #{block_result.inspect}")
|
|
203
|
+
}
|
|
204
|
+
end
|
|
205
|
+
|
|
206
|
+
def method_missing_old(method_id, *arguments, &block)
|
|
207
|
+
$log.debug("Teeing #{method_id} to #{children.length} children (#{children.map{|c| "#{c.class.name}(#{c.object_id})"}.join(",")})")
|
|
208
|
+
|
|
209
|
+
o_args = nil
|
|
210
|
+
o_res = nil
|
|
211
|
+
block_result = nil
|
|
212
|
+
|
|
213
|
+
ch = children
|
|
214
|
+
threads = []
|
|
215
|
+
block_args = []
|
|
216
|
+
|
|
217
|
+
mutex = Mutex.new
|
|
218
|
+
state = :new
|
|
219
|
+
def set_state(s)
|
|
220
|
+
mutex.synchronize {
|
|
221
|
+
state = s
|
|
222
|
+
}
|
|
223
|
+
end
|
|
224
|
+
|
|
225
|
+
get_args_block = nil
|
|
226
|
+
i = nil
|
|
227
|
+
if block
|
|
228
|
+
vars = []
|
|
229
|
+
if block.arity > 0
|
|
230
|
+
block.arity.times {|i| vars.push("a#{i}")}
|
|
231
|
+
else
|
|
232
|
+
(-block.arity - 1).times {|i| vars.push("a#{i}")}
|
|
233
|
+
vars.push("*a")
|
|
234
|
+
end
|
|
235
|
+
block_start = "proc {|#{vars.join(",")}| block_args[i] = [#{vars.join(",")}]"
|
|
236
|
+
master_proc_text = block_start + " ; start_lock.unlock ; block_result = yield(#{vars.join(",")})}"
|
|
237
|
+
slave_proc_text = block_start + " master_lock.synchronize {} block_result }"
|
|
238
|
+
master_block = eval(master_block_text)
|
|
239
|
+
slave_block = eval(slave_block_text)
|
|
240
|
+
end
|
|
241
|
+
|
|
242
|
+
first = true
|
|
243
|
+
children.each_with_index {|c,index|
|
|
244
|
+
threads[index] = Thread.fork(index) { |i|
|
|
245
|
+
|
|
246
|
+
master = false
|
|
247
|
+
mutex.synchronize {
|
|
248
|
+
master = true if first
|
|
249
|
+
first = false
|
|
250
|
+
}
|
|
251
|
+
|
|
252
|
+
if master
|
|
253
|
+
# get arguments
|
|
254
|
+
# wati until all got their arguments
|
|
255
|
+
# call
|
|
256
|
+
# return result
|
|
257
|
+
# after call
|
|
258
|
+
else
|
|
259
|
+
# before call
|
|
260
|
+
# call
|
|
261
|
+
# after call
|
|
262
|
+
end
|
|
263
|
+
|
|
264
|
+
|
|
265
|
+
my_block = nil
|
|
266
|
+
start_lock.lock
|
|
267
|
+
if first
|
|
268
|
+
# i am master
|
|
269
|
+
first = false
|
|
270
|
+
return_lock.lock
|
|
271
|
+
my_block = master_block if block
|
|
272
|
+
else
|
|
273
|
+
start_lock.unlock
|
|
274
|
+
my_block = slave_block if block
|
|
275
|
+
end
|
|
276
|
+
|
|
277
|
+
# p [method_id,step_in,block_args,block_result]
|
|
278
|
+
if my_block
|
|
279
|
+
c.send(method_id, *arguments, &get_args_block)
|
|
280
|
+
return_lock.unlock
|
|
281
|
+
else
|
|
282
|
+
c.send(method_id, *arguments)
|
|
283
|
+
start_lock.unlock
|
|
284
|
+
return_lock.unlock
|
|
285
|
+
end
|
|
286
|
+
}
|
|
287
|
+
}
|
|
288
|
+
threads.each {|th| th.join }
|
|
289
|
+
|
|
290
|
+
# call the block
|
|
291
|
+
block.call(*block_args[0])
|
|
292
|
+
|
|
293
|
+
end
|
|
294
|
+
end
|
|
295
|
+
|
|
296
|
+
=end
|
|
@@ -0,0 +1,116 @@
|
|
|
1
|
+
# Copyright (C) 2007-2010 Logintas AG Switzerland
|
|
2
|
+
#
|
|
3
|
+
# This file is part of Libisi.
|
|
4
|
+
#
|
|
5
|
+
# Libisi is free software: you can redistribute it and/or modify
|
|
6
|
+
# it under the terms of the GNU General Public License as published by
|
|
7
|
+
# the Free Software Foundation, either version 3 of the License, or
|
|
8
|
+
# (at your option) any later version.
|
|
9
|
+
#
|
|
10
|
+
# Libisi is distributed in the hope that it will be useful,
|
|
11
|
+
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
12
|
+
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
13
|
+
# GNU General Public License for more details.
|
|
14
|
+
#
|
|
15
|
+
# You should have received a copy of the GNU General Public License
|
|
16
|
+
# along with Libisi. If not, see <http://www.gnu.org/licenses/>.
|
|
17
|
+
|
|
18
|
+
class BaseUI
|
|
19
|
+
|
|
20
|
+
def name
|
|
21
|
+
self.class.name
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
def not_implemented
|
|
25
|
+
raise "Not implemented in UI #{self.name}"
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
def bell(options = {}); not_implemented; end
|
|
29
|
+
def question_yes_no(text, options = {}); info_non_blocking(text);select([:yes,:no],false, options)[0]; end
|
|
30
|
+
def question_yes_no_retry(text, options = {}); info_non_blocking(text); select([:yes,:no,:retry],false,options)[0]; end
|
|
31
|
+
def question(text, options = {}); not_implemented; end
|
|
32
|
+
def info(text, options = {}); not_impelmented; end
|
|
33
|
+
def info_non_blocking(text, options = {}); info(text, options); end
|
|
34
|
+
|
|
35
|
+
def error(text, options = {})
|
|
36
|
+
info("/!\\ ERROR: #{text}")
|
|
37
|
+
end
|
|
38
|
+
def warn(text, options = {})
|
|
39
|
+
info("/!\\ WARNING: #{text}")
|
|
40
|
+
end
|
|
41
|
+
|
|
42
|
+
def select(list, multi_select = false, options = {}) ; not_implemented; end
|
|
43
|
+
def select_index(list, multi_select = false, &block)
|
|
44
|
+
select(list, multi_select, {:return_indexes => true}, &block)
|
|
45
|
+
end
|
|
46
|
+
|
|
47
|
+
def colorize(color, options={}); yield; end
|
|
48
|
+
|
|
49
|
+
def execute_in_console(command, options = {}); not_implemented; end
|
|
50
|
+
|
|
51
|
+
# progress
|
|
52
|
+
def progress_bar(text,elements,&block)
|
|
53
|
+
elements = elements.call if elements.class == Proc
|
|
54
|
+
|
|
55
|
+
raise "Please provide an array if you expect elements for your block." if
|
|
56
|
+
block.arity == 1 and elements.class == Fixnum
|
|
57
|
+
|
|
58
|
+
if progress_bar_enabled?
|
|
59
|
+
if block.arity == 1
|
|
60
|
+
progress_bar_implementation(text, elements.length) {
|
|
61
|
+
index = 0
|
|
62
|
+
elements.map {|el|
|
|
63
|
+
r = yield(el)
|
|
64
|
+
progress(index)
|
|
65
|
+
index += 1
|
|
66
|
+
r
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
else
|
|
70
|
+
progress_bar_implementation(text, elements, &block)
|
|
71
|
+
end
|
|
72
|
+
else
|
|
73
|
+
if block.arity == 1
|
|
74
|
+
elements.map {|el|
|
|
75
|
+
yield(el)
|
|
76
|
+
}
|
|
77
|
+
else
|
|
78
|
+
yield
|
|
79
|
+
end
|
|
80
|
+
end
|
|
81
|
+
end
|
|
82
|
+
|
|
83
|
+
def progress_bar_implementation(text, total, &block); not_implemented if progress_bar_enabled?; end
|
|
84
|
+
def progress(count); not_implemented if progress_bar_enabled?; end
|
|
85
|
+
def progress_message(message); not_implemented if progress_bar_enabled?; end
|
|
86
|
+
def progress_inc ; not_implemented if progress_bar_enabled?; end
|
|
87
|
+
|
|
88
|
+
def pmsg(action = nil,object = nil)
|
|
89
|
+
return unless progress_bar_enabled?
|
|
90
|
+
if action
|
|
91
|
+
@max_action_withs ||= []
|
|
92
|
+
@max_action_withs.insert(0,action.to_s.length)
|
|
93
|
+
@max_action_withs = @max_action_withs[0..5]
|
|
94
|
+
action = action.ljust(@max_action_withs.max)
|
|
95
|
+
end
|
|
96
|
+
message = [action,object].compact.map {|s| s.to_s}.join(": ")
|
|
97
|
+
progress_message(message)
|
|
98
|
+
end
|
|
99
|
+
def pinc(action = nil, object = nil)
|
|
100
|
+
return unless progress_bar_enabled?
|
|
101
|
+
progress_inc
|
|
102
|
+
pmsg(action, object) if action or object
|
|
103
|
+
end
|
|
104
|
+
def enable_progress_bar(val = true)
|
|
105
|
+
old_val = @progress
|
|
106
|
+
@progress = val
|
|
107
|
+
if block_given?
|
|
108
|
+
yield
|
|
109
|
+
@progress = old_val
|
|
110
|
+
end
|
|
111
|
+
end
|
|
112
|
+
def progress_bar_enabled?
|
|
113
|
+
@progress
|
|
114
|
+
end
|
|
115
|
+
|
|
116
|
+
end
|
|
@@ -0,0 +1,238 @@
|
|
|
1
|
+
# Copyright (C) 2007-2010 Logintas AG Switzerland
|
|
2
|
+
#
|
|
3
|
+
# This file is part of Libisi.
|
|
4
|
+
#
|
|
5
|
+
# Libisi is free software: you can redistribute it and/or modify
|
|
6
|
+
# it under the terms of the GNU General Public License as published by
|
|
7
|
+
# the Free Software Foundation, either version 3 of the License, or
|
|
8
|
+
# (at your option) any later version.
|
|
9
|
+
#
|
|
10
|
+
# Libisi is distributed in the hope that it will be useful,
|
|
11
|
+
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
12
|
+
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
13
|
+
# GNU General Public License for more details.
|
|
14
|
+
#
|
|
15
|
+
# You should have received a copy of the GNU General Public License
|
|
16
|
+
# along with Libisi. If not, see <http://www.gnu.org/licenses/>.
|
|
17
|
+
|
|
18
|
+
require "libisi/ui/base.rb"
|
|
19
|
+
class ConsoleUI < BaseUI
|
|
20
|
+
def bell(options = {})
|
|
21
|
+
print "\007"
|
|
22
|
+
end
|
|
23
|
+
def info(text, options = {})
|
|
24
|
+
bell
|
|
25
|
+
print "#{text} [hit ENTER]"
|
|
26
|
+
STDIN.readline
|
|
27
|
+
end
|
|
28
|
+
def info_non_blocking(text, options = {})
|
|
29
|
+
print("#{text}\n")
|
|
30
|
+
end
|
|
31
|
+
def question(text, options = {})
|
|
32
|
+
default = nil
|
|
33
|
+
unless options[:default].nil?
|
|
34
|
+
default = (options[:default] ? "y" : "n")
|
|
35
|
+
end
|
|
36
|
+
|
|
37
|
+
while true
|
|
38
|
+
case default
|
|
39
|
+
when "y"
|
|
40
|
+
print(text + "(Y/n)")
|
|
41
|
+
when "n"
|
|
42
|
+
print(text + "(y/N)")
|
|
43
|
+
else
|
|
44
|
+
print(text + "(y/n)")
|
|
45
|
+
end
|
|
46
|
+
answer = STDIN.readline.to_s.strip.downcase
|
|
47
|
+
answer = default if answer == ""
|
|
48
|
+
case answer
|
|
49
|
+
when "y"
|
|
50
|
+
return true
|
|
51
|
+
when "n"
|
|
52
|
+
return false
|
|
53
|
+
end
|
|
54
|
+
end
|
|
55
|
+
end
|
|
56
|
+
|
|
57
|
+
def password(text)
|
|
58
|
+
begin
|
|
59
|
+
print "#{text}: "
|
|
60
|
+
system "stty -echo"
|
|
61
|
+
pw = STDIN.gets.chomp
|
|
62
|
+
print "\n"
|
|
63
|
+
ensure
|
|
64
|
+
system "stty echo"
|
|
65
|
+
end
|
|
66
|
+
pw
|
|
67
|
+
end
|
|
68
|
+
|
|
69
|
+
# TEXT UI
|
|
70
|
+
def select(list, multi_select = false, options = {})
|
|
71
|
+
texts = []
|
|
72
|
+
list.each_with_index {|val, index|
|
|
73
|
+
if block_given?
|
|
74
|
+
item_text = yield(val)
|
|
75
|
+
else
|
|
76
|
+
item_text = val.to_s
|
|
77
|
+
end
|
|
78
|
+
if item_text.include?("\n")
|
|
79
|
+
item_text = item_text.split("\n").map {|l| " #{l}"}.join("\n")
|
|
80
|
+
end
|
|
81
|
+
print "#{index + 1}: #{item_text}\n"
|
|
82
|
+
texts << item_text
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
ret = nil
|
|
86
|
+
while ret.nil?
|
|
87
|
+
begin
|
|
88
|
+
if multi_select
|
|
89
|
+
print "Please make your choice. (Comma seperated list or 'all' for all.)\n"
|
|
90
|
+
else
|
|
91
|
+
print "Please make your choice:"
|
|
92
|
+
end
|
|
93
|
+
select = STDIN.readline
|
|
94
|
+
|
|
95
|
+
if select.strip == "all" or select.strip == "a"
|
|
96
|
+
indexes = (0..(list.length-1)).to_a
|
|
97
|
+
else
|
|
98
|
+
values = select.split(",").map {|s| s.strip}
|
|
99
|
+
|
|
100
|
+
indexes = values.map {|n| n.strip}.map {|sel| sel.to_i - 1}.sort.uniq
|
|
101
|
+
indexes = indexes.select {|i| i>=0 }
|
|
102
|
+
|
|
103
|
+
if indexes.length < values.length
|
|
104
|
+
indexes = values.map {|s| texts.index(s) }.compact.sort.uniq
|
|
105
|
+
end
|
|
106
|
+
|
|
107
|
+
raise "Not all values could be found!" if indexes.length < values.length
|
|
108
|
+
end
|
|
109
|
+
ret = indexes.map {|sel|
|
|
110
|
+
raise "Unexpected input, please enter a number!" if sel < 0
|
|
111
|
+
raise "Item with index '#{sel + 1}' not found." unless list[sel]
|
|
112
|
+
list[sel]
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
if ret.length > 1 and !multi_select
|
|
116
|
+
raise "Only one item allowe"
|
|
117
|
+
end
|
|
118
|
+
rescue
|
|
119
|
+
print "#{$!}\n"
|
|
120
|
+
ret = nil
|
|
121
|
+
end
|
|
122
|
+
end
|
|
123
|
+
return indexes if options[:return_indexes]
|
|
124
|
+
ret
|
|
125
|
+
end
|
|
126
|
+
|
|
127
|
+
CONSOLE_COLOR_STRINGS = {
|
|
128
|
+
:gray => [1,30], :black => [30],
|
|
129
|
+
:light_red => [1,31], :red => [31],
|
|
130
|
+
:light_green => [1,32], :green => [32],
|
|
131
|
+
:light_yellow => [1,33], :yellow => [33],
|
|
132
|
+
:light_blue => [1,34], :blue => [34],
|
|
133
|
+
:light_purple => [1,35], :purple => [35],
|
|
134
|
+
:light_cyan => [1,36], :cyan => [36],
|
|
135
|
+
:white => [1,37], :light_gray => [37],
|
|
136
|
+
:underscore => [4],
|
|
137
|
+
:blink => [5],
|
|
138
|
+
:inverse => [7],
|
|
139
|
+
:concealed => [8],
|
|
140
|
+
:default => [0]
|
|
141
|
+
}
|
|
142
|
+
CONSOLE_COLORS = CONSOLE_COLOR_STRINGS.keys
|
|
143
|
+
|
|
144
|
+
def test_colors
|
|
145
|
+
CONSOLE_COLORS.sort_by{|n| n.to_s}.each {|color|
|
|
146
|
+
print "#{color}: " + colorize(color) { "****" } + "\n"
|
|
147
|
+
}
|
|
148
|
+
end
|
|
149
|
+
|
|
150
|
+
def console_commands(commands) ; commands.map {|number| "\e[#{number}m"}.join ;end
|
|
151
|
+
|
|
152
|
+
def colorize(color)
|
|
153
|
+
raise "Unexpected color: #{color}" unless CONSOLE_COLORS.include?(color)
|
|
154
|
+
console_commands(CONSOLE_COLOR_STRINGS[color]) +
|
|
155
|
+
yield +
|
|
156
|
+
console_commands(CONSOLE_COLOR_STRINGS[:default])
|
|
157
|
+
end
|
|
158
|
+
|
|
159
|
+
def progress_bar_implementation(text,total)
|
|
160
|
+
ret = nil
|
|
161
|
+
begin
|
|
162
|
+
require "progressbar"
|
|
163
|
+
@pbar = ProgressBar.new(text, total)
|
|
164
|
+
# $pbar.format = "%-#{title.length+10}s %3d%% %s %s"
|
|
165
|
+
ret = yield
|
|
166
|
+
pmsg
|
|
167
|
+
@pbar.finish
|
|
168
|
+
@pbar = nil
|
|
169
|
+
ensure
|
|
170
|
+
if @pbar
|
|
171
|
+
@pbar.halt
|
|
172
|
+
@pbar = nil
|
|
173
|
+
end
|
|
174
|
+
end
|
|
175
|
+
ret
|
|
176
|
+
end
|
|
177
|
+
def progress(count)
|
|
178
|
+
@pbar.set(count) if @pbar
|
|
179
|
+
end
|
|
180
|
+
|
|
181
|
+
def progress_message(message)
|
|
182
|
+
return unless @pbar
|
|
183
|
+
width = (@pbar.instance_eval("get_width")) - 6
|
|
184
|
+
if message.length > width then
|
|
185
|
+
message = message[0..(width/2)] + ">..<" + message[-(width/2)..-1]
|
|
186
|
+
end
|
|
187
|
+
|
|
188
|
+
STDERR.print("\n")
|
|
189
|
+
STDERR.print("\e[K")
|
|
190
|
+
STDERR.print(message.to_s)
|
|
191
|
+
STDERR.print("\e[#{message.to_s.length}D")
|
|
192
|
+
STDERR.print("\e[1A")
|
|
193
|
+
end
|
|
194
|
+
def progress_inc
|
|
195
|
+
return unless @pbar
|
|
196
|
+
@pbar.inc
|
|
197
|
+
end
|
|
198
|
+
|
|
199
|
+
def execute_in_console(command, options = {})
|
|
200
|
+
system(command)
|
|
201
|
+
end
|
|
202
|
+
|
|
203
|
+
def shell
|
|
204
|
+
shell_name = "bash"
|
|
205
|
+
print("\nFallen into #{shell_name} shell\n")
|
|
206
|
+
print("(CTRL-D) for exit\n\n")
|
|
207
|
+
system("/bin/#{shell_name} < /dev/tty > /dev/tty 2> /dev/tty")
|
|
208
|
+
end
|
|
209
|
+
|
|
210
|
+
def diff(file1, file2, options = {})
|
|
211
|
+
text = result_of_system("diff -r -u '#{file1}' '#{file2}'",true)
|
|
212
|
+
color1 = :green
|
|
213
|
+
color2 = :red
|
|
214
|
+
# additional lines
|
|
215
|
+
text = text.gsub(/^\+.*$/) {|l| colorize(color1) { l }}
|
|
216
|
+
# removed lines
|
|
217
|
+
text = text.gsub(/^\-.*$/) {|l| colorize(color2) { l }}
|
|
218
|
+
print text
|
|
219
|
+
$?.success?
|
|
220
|
+
end
|
|
221
|
+
|
|
222
|
+
# single character input
|
|
223
|
+
# require 'termios'
|
|
224
|
+
#
|
|
225
|
+
# # Set up termios so that it returns immediately when you press a key.
|
|
226
|
+
# # (http://blog.rezra.com/articles/2005/12/05/single-character-input)
|
|
227
|
+
# t = Termios.tcgetattr(STDIN)
|
|
228
|
+
# t.lflag &= ~Termios::ICANON
|
|
229
|
+
# Termios.tcsetattr(STDIN,0,t)
|
|
230
|
+
# c = ''
|
|
231
|
+
# while c != 'q' do
|
|
232
|
+
# c = STDIN.getc.chr
|
|
233
|
+
# puts "You entered: " + c.inspect
|
|
234
|
+
# end
|
|
235
|
+
|
|
236
|
+
|
|
237
|
+
end
|
|
238
|
+
|