Module: Eft
- Defined in:
- lib/eft.rb,
lib/eft/version.rb
Defined Under Namespace
Modules: CfgCancel, CfgEsc, CfgNo, CfgOK, CfgYes Classes: Cfg, CfgAsk, CfgAskPass, CfgAskYesNo, CfgCheck, CfgGauge, CfgMenu, CfgRadio, CfgShowInfo, CfgShowMsg, CfgShowText, Error
Constant Summary collapse
- OU =
Obfusk::Util
- WHIPTAIL =
NB: dialog works as well as whiptail, but these options will be incompatible: ---button (is: ---label), --scrolltext
'whiptail'- EXIT =
{ ok_yes: 0, cancel_no: 1, esc: 255 }
- CHECK_OPTS =
['--separate-output']
- OPT =
->(o,x) { o.select { |k,v| OPTS[x][k] } .map { |k,v| OPTS[x][k][v] } }
- ON_OFF =
->(x) { x ? 'on' : 'off' }
- WHAT =
translate method to option
{ # {{{1 show_info: '--infobox' , show_msg: '--msgbox' , show_text: '--textbox' , ask: '--inputbox' , ask_pass: '--passwordbox' , ask_yesno: '--yesno' , menu: '--menu' , check: '--checklist' , radio: '--radiolist' , gauge: '--gauge' , }
- OPTS =
options per category
{ # {{{1 all: { title: ->(t) { ['--title', t] }, backtitle: ->(t) { ['--backtitle', t] }, scroll: ->(b) { b ? ['--scrolltext'] : [] }, # ???? }, ok: { ok_button: ->(t) { ['--ok-button', t] }, }, cancel: { cancel_button: ->(t) { ['--cancel-button', t] }, no_cancel: ->(b) { b ? ['--nocancel'] : [] }, }, yes: { yes_button: ->(t) { ['--yes-button', t] }, }, no: { no_button: ->(t) { ['--no-button', t] }, default_no: ->(b) { b ? ['--default-no'] : [] }, }, menu: { selected: ->(i) { ['--default-item', i] }, }, }
- VERSION =
'0.4.0'- DATE =
'2014-02-20'
Class Method Summary collapse
-
._file_or_temp(opts, &b) ⇒ Object
call block w/ either
opts[:file]or a tempfile w/ contentsopts[:text]. -
._run_whip(args) ⇒ Hash
run whiptail.
-
._whip(what, text, cfg, opts, args = [], &b) ⇒ Object
process options, run whiptail, call
b[lines]oron_{cancel,no,esc}[]. -
._whip_cmd(text, opts, opt_args, args) ⇒ Object
whiptail command.
-
._whip_opts(what, cfg, opts) ⇒ Object
process whiptail options.
-
.ask(text, opts = {}, &b) ⇒ Object
ask for input w/ OK/Cancel buttons (and default).
-
.ask_pass(text, opts = {}, &b) ⇒ Object
ask for password w/ OK/Cancel buttons.
-
.ask_yesno(text, opts = {}, &b) ⇒ Object
ask w/ Yes/No buttons.
-
.check(text, opts = {}, &b) ⇒ Object
choose checkboxes w/ OK/Cancel buttons.
-
.gauge(text, percent, opts = {}, &b) ⇒ Object
show gauge; use lambda passed to block to move it forward by passing it
percent[, message]. -
.menu(text, opts = {}, &b) ⇒ Object
choose from menu w/ OK/Cancel buttons.
-
.radio(text, opts = {}, &b) ⇒ Object
choose radiobutton w/ OK/Cancel buttons.
-
.show_info(text, opts = {}) ⇒ Object
show message w/o buttons, don't clear screen.
-
.show_msg(text, opts = {}, &b) ⇒ Object
show message w/ OK button.
-
.show_text(opts = {}, &b) ⇒ Object
show file contents or text w/ OK button.
Class Method Details
._file_or_temp(opts, &b) ⇒ Object
call block w/ either opts[:file] or a tempfile w/ contents
opts[:text]
309 310 311 312 313 314 315 316 317 318 |
# File 'lib/eft.rb', line 309 def self._file_or_temp(opts, &b) # {{{1 file = opts[:file]; text = opts[:text] raise Error, 'can\'t have file and text' if file && text raise Error, 'must have file or text' if !file && !text if file b[file] else Tempfile.open('eft') { |f| f.write text; f.close; b[f.path] } end end |
._run_whip(args) ⇒ Hash
run whiptail
298 299 300 301 302 303 |
# File 'lib/eft.rb', line 298 def self._run_whip(args) IO.pipe do |r, w| s = OU.spawn_w(*args, err: w); w.close { exit: s.exitstatus, lines: r.readlines.map(&:chomp) } end end |
._whip(what, text, cfg, opts, args = [], &b) ⇒ Object
process options, run whiptail, call b[lines] or
on_{cancel,no,esc}[]
264 265 266 267 268 269 270 271 272 273 274 |
# File 'lib/eft.rb', line 264 def self._whip(what, text, cfg, opts, args = [], &b) # {{{1 o = _whip_opts what, cfg, opts; c = _whip_cmd text, opts, o, args r = _run_whip c case r[:exit] when EXIT[:ok_yes] ; b[r[:lines]] if b when EXIT[:cancel_no] ; cfg.call :on_cancel; cfg.call :on_no when EXIT[:esc] ; cfg.call :on_esc else raise Error, 'unknown exitstatus' end nil end |
._whip_cmd(text, opts, opt_args, args) ⇒ Object
whiptail command
288 289 290 291 292 293 294 |
# File 'lib/eft.rb', line 288 def self._whip_cmd(text, opts, opt_args, args) # {{{1 h = opts[:height] || OU::Term.lines - 4 w = opts[:width] || OU::Term.columns - 4 s = opts.has_key?(:subheight) ? [opts[:subheight] || h - 8] : [] a = [WHIPTAIL] + opt_args + ['--', text, h, w] + s + args a.map(&:to_s) end |
._whip_opts(what, cfg, opts) ⇒ Object
process whiptail options
277 278 279 280 281 282 283 284 285 |
# File 'lib/eft.rb', line 277 def self._whip_opts(what, cfg, opts) # {{{1 cfg._opts + [ OPT[opts,:all], cfg.respond_to?(:on_ok) ? OPT[opts,:ok] : [], cfg.respond_to?(:on_cancel) ? OPT[opts,:cancel] : [], cfg.respond_to?(:on_yes) ? OPT[opts,:yes] : [], cfg.respond_to?(:on_no) ? OPT[opts,:no] : [], what == :menu ? OPT[opts,:menu] : [], ] .flatten + [WHAT[what]] end |
.ask(text, opts = {}, &b) ⇒ Object
ask for input w/ OK/Cancel buttons (and default)
184 185 186 187 188 189 |
# File 'lib/eft.rb', line 184 def self.ask(text, opts = {}, &b) c = CfgAsk.new(&b); a = opts[:default] ? [opts[:default]] : [] _whip(:ask, text, c, opts, a) do |lines| c.call :on_ok, lines.first end end |
.ask_pass(text, opts = {}, &b) ⇒ Object
ask for password w/ OK/Cancel buttons
192 193 194 195 196 197 |
# File 'lib/eft.rb', line 192 def self.ask_pass(text, opts = {}, &b) c = CfgAskPass.new(&b) _whip(:ask_pass, text, c, opts) do |lines| c.call :on_ok, lines.first end end |
.ask_yesno(text, opts = {}, &b) ⇒ Object
ask w/ Yes/No buttons
200 201 202 203 |
# File 'lib/eft.rb', line 200 def self.ask_yesno(text, opts = {}, &b) c = CfgAskYesNo.new(&b) _whip(:ask_yesno, text, c, opts) { c.call :on_yes } end |
.check(text, opts = {}, &b) ⇒ Object
choose checkboxes w/ OK/Cancel buttons
221 222 223 224 225 226 227 228 |
# File 'lib/eft.rb', line 221 def self.check(text, opts = {}, &b) # {{{1 c = CfgCheck.new(&b); i = c._check o = opts.merge(subheight: opts[:list_height]).freeze a = i.map { |x| [x[:tag],x[:item],ON_OFF[x[:selected]]] } .flatten _whip(:check, text, c, o, a) do |lines| c.call :on_ok, lines end end |
.gauge(text, percent, opts = {}, &b) ⇒ Object
show gauge; use lambda passed to block to move it forward by
passing it percent[, message]
245 246 247 248 249 250 251 252 253 254 255 256 257 |
# File 'lib/eft.rb', line 245 def self.gauge(text, percent, opts = {}, &b) # {{{1 IO.pipe do |r, w| mv = ->(pct, msg = nil) { msg ? w.puts('XXX', pct, msg, 'XXX', pct) : w.puts(pct) # WTF! } c = CfgGauge.new o = _whip_opts :gauge, c, opts c = _whip_cmd text, opts, o, [percent] pid = OU.spawn(*c, in: r) r.close; b[mv]; w.close; Process.wait pid raise Error, 'exitstatus != 0' if $?.exitstatus != 0 end # }}}1 end |
.menu(text, opts = {}, &b) ⇒ Object
choose from menu w/ OK/Cancel buttons
208 209 210 211 212 213 214 215 216 |
# File 'lib/eft.rb', line 208 def self.(text, opts = {}, &b) # {{{1 c = CfgMenu.new(&b); m = c. o = opts.merge(subheight: opts[:menu_height]).freeze a = m.map { |x| [x[:tag],x[:item]] } .flatten t = Hash[m.map { |x| [x[:tag],x] }] _whip(:menu, text, c, o, a) do |lines| tag = lines.first; t[tag][:block][tag] end end |
.radio(text, opts = {}, &b) ⇒ Object
choose radiobutton w/ OK/Cancel buttons
231 232 233 234 235 236 237 238 239 |
# File 'lib/eft.rb', line 231 def self.radio(text, opts = {}, &b) # {{{1 s = opts[:selected] ; f = ->(x) { ON_OFF[x == s] } c = CfgRadio.new(&b); i = c._radio o = opts.merge(subheight: opts[:list_height]).freeze a = i.map { |x| [x[:tag],x[:item],f[x[:tag]]] } .flatten _whip(:radio, text, c, o, a) do |lines| c.call :on_ok, lines.first end # }}}1 end |
.show_info(text, opts = {}) ⇒ Object
show message w/o buttons, don't clear screen
163 164 165 |
# File 'lib/eft.rb', line 163 def self.show_info(text, opts = {}) _whip :show_info, text, CfgShowInfo.new, opts end |
.show_msg(text, opts = {}, &b) ⇒ Object
show message w/ OK button
168 169 170 171 |
# File 'lib/eft.rb', line 168 def self.show_msg(text, opts = {}, &b) c = CfgShowMsg.new(&b) _whip(:show_msg, text, c, opts) { c.call :on_ok } end |
.show_text(opts = {}, &b) ⇒ Object
show file contents or text w/ OK button
174 175 176 177 178 179 |
# File 'lib/eft.rb', line 174 def self.show_text(opts = {}, &b) _file_or_temp opts do |f| c = CfgShowText.new(&b) _whip(:show_text, f, c, opts) { c.call :on_ok } end end |