Class: IS::Term::StatusTable

Inherits:
Object
  • Object
show all
Includes:
Functions, Singleton
Defined in:
lib/is-term/statustable.rb,
lib/is-term/functions.rb

Defined Under Namespace

Modules: Formats, Functions

Constant Summary collapse

INVERT =
"\e[7m"
DEFAULT_IO =
$stdout
DEFAULT_SUMMARY_PREFIX =
INVERT

Constants included from Functions

Functions::AGGREGATE_METHODS, Functions::ROW_METHODS, Functions::TABLE_METHODS

Configuration Info collapse

Data Manipulation collapse

State collapse

Configuration collapse

Configuration DSL collapse

Methods included from Functions

#active, #active?, aggregate_func, #avg, #count, #current, #done, #done?, #elapsed, #empty?, #estimated, #finished, #max, #min, #percent, row_func, #speed, #started, #sum, table_func, #total

Instance Attribute Details

#defsArray<Hash|String> (readonly)

Returns:

  • (Array<Hash|String>)


42
43
44
# File 'lib/is-term/statustable.rb', line 42

def defs
  @defs
end

#termIO (readonly)

Returns:

  • (IO)


39
40
41
# File 'lib/is-term/statustable.rb', line 39

def term
  @term
end

Instance Method Details

#append(**data) {|row| ... } ⇒ Hash

Yields:

Yield Parameters:

  • row (Hash)

Returns:

  • (Hash)

Raises:



102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
# File 'lib/is-term/statustable.rb', line 102

def append **data
  raise IS::Term::StateError, "StatusTable is not ready for work", caller_locations unless available? && configured?
  data.transform_keys!(&:to_sym)
  id = data[@id_field]
  raise ArgumentError, "Row Id must be specified", caller_locations if id.nil?
  raise ArgumentError, "Row with Id = #{ id.inspect } already exists", caller_locations if @rows.any? { |r| r[@id_field] == id }
  row = {}
  row[:_active] = true
  row[:_started] = Time::now
  row[:_mutex] = Thread::Mutex::new
  row.merge! data
  yield row if block_given?
  @mutex.synchronize do
    @rows << row
    @term.puts ''
    render_table
  end
  result = row.dup
  result.delete :_mutex
  result.freeze
end

#available?Boolean

Returns:

  • (Boolean)


70
71
72
# File 'lib/is-term/statustable.rb', line 70

def available?
  !!@term && @term.is_a?(IO) && File.chardev?(@term)
end

#column(name, id: false, func: nil, format: nil, width: nil, align: nil, summary: nil) ⇒ void (private)

This method returns an undefined value.

Raises:

  • (ArgumentError)


339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
# File 'lib/is-term/statustable.rb', line 339

def column name, id: false, func: nil, format: nil, width: nil, align: nil, summary: nil
  raise ArgumentError, "Invalid name value: #{ name.inspect }", caller_locations unless name.is_a?(String) || name.is_a?(Symbol)
  raise ArgumentError, "Name can not be empty", caller_locations if name == '' || name == :''
  name = name.to_sym
  raise ArgumentError, "Column name already exists: #{ name }", caller_locations if @defs.any? { |d| d.is_a?(Hash) && d[:name] == name }
  raise ArgumentError, "Invalid id value: #{ id.inspect }", caller_locations unless id.nil? || id == true || id == false
  id = nil if id == false
  raise ArgumentError, "Id field already exists (#{ @id_field })" if @id_field && id
  func_keys = Set[]
  if self.class.const_defined?(:Functions)
    func_keys |= Set[*Functions::ROW_METHODS]
  end
  raise ArgumentError, "Invalid func value: #{ func.inspect }", caller_locations unless func.nil? || func.respond_to?(:call) || func_keys.include?(func)
  if self.class.const_defined?(:Functions) && func.is_a?(Symbol)
    func = Functions::RF func
  end
  format_keys = Set[]
  if self.class.const_defined?(:Formats)
    format_keys |= Set[*Formats::SPECIAL_FORMATS]
  end
  raise ArgumentError, "Invalid format value: #{ format.inspect }", caller_locations unless format.nil? || format.is_a?(String) || format.is_a?(Array) || format.respond_to?(:call) || format_keys.include?(format)
  if self.class.const_defined?(:Formats) && format && !format.respond_to?(:call)
    format = Formats::fmt format if format.is_a?(Symbol) || format.is_a?(String)
    format = Formats::bar(*format) if format.is_a?(Array) 
  end
  raise ArgumentError, "Invalid width value: #{ width.inspect }", caller_locations unless width.nil? || width.is_a?(Integer)
  raise ArgumentError, "Invalid align value: #{ align.inspect }", caller_locations unless align.nil? || IS::Term::StringHelpers::ALIGN_MODES.include?(align)
  align = IS::Term::StringHelpers::DEFAULT_ALIGN_MODE if align.nil?
  summary_keys = Set[*(SUMMARY_NONE + SUMMARY_VALS)]
  if self.class.const_defined?(:Functions)
    summary_keys |= Set[*(Functions::TABLE_METHODS + Functions::AGGREGATE_METHODS)]
  end
  raise ArgumentError, "Invalid summary value: #{ summary.inspect }", caller_locations unless summary_keys.include?(summary) || summary.is_a?(Proc) || summary.nil?
  summary = nil if SUMMARY_NONE.include?(summary) || summary.nil?
  if self.class.const_defined?(:Functions)
    summary = Functions::TF summary if Functions::TABLE_METHODS.include?(summary)
    summary = Functions::AF summary, name if Functions::AGGREGATE_METHODS.include?(summary)
  end
  definition = { name: name, id: id, func: func, format: format, width: width, _width: (width || 0), align: align, summary: summary }.compact
  @defs << definition
  @id_field = name if id
  self
end

#configure { ... } ⇒ self

Yields:

Returns:

  • (self)


156
157
158
159
160
161
162
163
164
165
166
# File 'lib/is-term/statustable.rb', line 156

def configure &block
  if block_given?
    @mutex.synchronize do
      @in_configure = true
      instance_eval(&block)
      @in_configure = nil
    end
  end
  @term.puts ''
  self
end

#configured?Boolean

Returns:

  • (Boolean)


66
67
68
# File 'lib/is-term/statustable.rb', line 66

def configured?
  !!@id_field && !@defs.empty?
end

#inactivate_if {|row| ... } ⇒ void (private)

This method returns an undefined value.

Yields:

Yield Parameters:

  • row (Hash)

Raises:

  • (ArgumentError)


393
394
395
396
397
# File 'lib/is-term/statustable.rb', line 393

def inactivate_if &block
  raise ArgumentError, "Block condition must be specified", caller_locations unless block_given?
  @inactivate_if = block
  self
end

#reset!self

Returns:

  • (self)


75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
# File 'lib/is-term/statustable.rb', line 75

def reset!
  if @in_configure
    @defs = []
    @id_field = nil
    @inactivate_if = nil
    @term = DEFAULT_IO
    @show_summary = nil
    @summary_prefix = DEFAULT_SUMMARY_PREFIX
    @summary_values = {}
    @started = Time::now
    @rows = []
  else
    @mutex.synchronize do
      @started = Time::now
      @rows = []
    end
  end
  self
end

#row(row_id) ⇒ Hash?

Returns:

  • (Hash, nil)


55
56
57
58
59
60
# File 'lib/is-term/statustable.rb', line 55

def row row_id
  return nil if @id_field.nil?
  result = @rows.find { |r| r[@id_field] == row_id }.dup
  result.delete :_mutex if result
  result.freeze
end

#rowsArray<Hash>

Returns:

  • (Array<Hash>)


49
50
51
52
# File 'lib/is-term/statustable.rb', line 49

def rows
  @rows ||= []
  @rows.dup.freeze
end

#separator(str = ' ') ⇒ void (private)

This method returns an undefined value.

Raises:

  • (ArgumentError)


384
385
386
387
388
# File 'lib/is-term/statustable.rb', line 384

def separator str = ' '
  raise ArgumentError, "Invalid separator: #{ str.inspect }", caller_locations unless str.is_a?(String)
  @defs << str
  self
end

#summary(show = nil, prefix: nil, **values) ⇒ void

This method returns an undefined value.



409
410
411
412
413
414
415
# File 'lib/is-term/statustable.rb', line 409

def summary show = nil, prefix: nil, **values
  @show_summary = show unless show.nil?
  @show_summary = true if @show_summary.nil?
  @summary_prefix = prefix unless prefix.nil?
  @summary_values.merge! values.transform_keys(&:to_sym)
  self
end

#terminal(io) ⇒ void (private)

This method returns an undefined value.

Raises:

  • (ArgumentError)


400
401
402
403
404
# File 'lib/is-term/statustable.rb', line 400

def terminal io
  raise ArgumentError, "Invalid terminal value: #{ io.inspect }", caller_locations unless io.is_a?(IO) && File.chardev?(io)
  @term = io
  self
end

#update(**data) {|row| ... } ⇒ Hash

Yields:

Yield Parameters:

  • row (Hash)

Returns:

  • (Hash)

Raises:



127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
# File 'lib/is-term/statustable.rb', line 127

def update **data
  raise IS::Term::StateError, "StatusTable is not ready for work", caller_locations unless available? && configured?
  data.transform_keys!(&:to_sym)
  id = data[@id_field]
  raise ArgumentError, "Row Id must be specified", caller_locations if id.nil?
  row = find_row id
  raise ArgumentError, "Row with Id = #{id.inspect} must be exists", caller_locations if row.nil?
  row[:_mutex].synchronize do
    row.merge! data
    yield row if block_given?
    if row[:_active] && @inactivate_if && @inactivate_if.call(row)
      row[:_active] = false
      row[:_finished] = Time::now
      render_table
    else
      render_line row
    end
  end
  result = row.dup
  result.delete :_mutex
  result.freeze
end