Class: ANSI::ProgressBar

Inherits:
Object
  • Object
show all
Defined in:
lib/ansi/progressbar.rb

Overview

Progressbar

Progressbar is a text-based progressbar library.

pbar = Progressbar.new( "Demo", 100 )
100.times { pbar.inc }
pbar.finish

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(title, total, out = STDERR) ⇒ ProgressBar

Returns a new instance of ProgressBar.



22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
# File 'lib/ansi/progressbar.rb', line 22

def initialize(title, total, out=STDERR)
  @title = title
  @total = total
  @out   = out

  @bar_length = 80
  @bar_mark = "|"
  @total_overflow = true
  @current = 0
  @previous = 0
  @is_finished = false
  @start_time = Time.now
  @format = "%-14s %3d%% %s %s"
  @format_arguments = [:title, :percentage, :bar, :stat]
  @styles = {}
  #
  yield self if block_given?
  #
  show_progress
end

Instance Attribute Details

#format(format, *arguments) ⇒ Object

Set format and format arguments.



68
69
70
# File 'lib/ansi/progressbar.rb', line 68

def format
  @format
end

#format_argumentsObject

Returns the value of attribute format_arguments.



46
47
48
# File 'lib/ansi/progressbar.rb', line 46

def format_arguments
  @format_arguments
end

#stylesObject

Returns the value of attribute styles.



47
48
49
# File 'lib/ansi/progressbar.rb', line 47

def styles
  @styles
end

Instance Method Details

#barObject (private)



210
211
212
213
# File 'lib/ansi/progressbar.rb', line 210

def bar
  len = percentage * @bar_length / 100
  sprintf("|%s%s|", @bar_mark * len, " " *  (@bar_length - len))
end

#bar_mark=(mark) ⇒ Object Also known as: barmark=, mark=



54
55
56
# File 'lib/ansi/progressbar.rb', line 54

def bar_mark=(mark)
  @bar_mark = String(mark)[0..0]
end

#bytesObject (private)



166
167
168
# File 'lib/ansi/progressbar.rb', line 166

def bytes
  convert_bytes(@current)
end

#clearObject



138
139
140
# File 'lib/ansi/progressbar.rb', line 138

def clear
  @out.print(" " * get_width + eol)
end

#colorize(part, style) ⇒ Object (private)



280
281
282
283
284
# File 'lib/ansi/progressbar.rb', line 280

def colorize(part, style)
  return part unless style
  #[style].flatten.inject(part){ |pt, st| ANSI::Code.ansi(pt, *st) }
  ANSI::Code.ansi(part, *style)
end

#convert_bytes(bytes) ⇒ Object (private)



149
150
151
152
153
154
155
156
157
158
159
# File 'lib/ansi/progressbar.rb', line 149

def convert_bytes(bytes)
  if bytes < 1024
    sprintf("%6dB", bytes)
  elsif bytes < 1024 * 1000 # 1000kb
    sprintf("%5.1fKB", bytes.to_f / 1024)
  elsif bytes < 1024 * 1024 * 1000  # 1000mb
    sprintf("%5.1fMB", bytes.to_f / 1024 / 1024)
  else
    sprintf("%5.1fGB", bytes.to_f / 1024 / 1024 / 1024)
  end
end

#elapsedObject (private)



189
190
191
192
# File 'lib/ansi/progressbar.rb', line 189

def elapsed
  elapsed = Time.now - @start_time
  sprintf("Time: %s", format_time(elapsed))
end

#eolObject (private)



206
207
208
# File 'lib/ansi/progressbar.rb', line 206

def eol
  if @is_finished then "\n" else "\r" end
end

#etaObject (private)

ETA stands for Estimated Time of Arrival.



179
180
181
182
183
184
185
186
187
# File 'lib/ansi/progressbar.rb', line 179

def eta
  if @current == 0
    "ETA:  --:--:--"
  else
    elapsed = Time.now - @start_time
    eta = elapsed * @total / @current - elapsed;
    sprintf("ETA:  %s", format_time(eta))
  end
end

#finishObject



93
94
95
96
97
# File 'lib/ansi/progressbar.rb', line 93

def finish
  @current = @total
  @is_finished = true
  show_progress
end

#flushObject



99
100
101
# File 'lib/ansi/progressbar.rb', line 99

def flush
  @out.flush
end

#format_time(t) ⇒ Object (private)



170
171
172
173
174
175
176
# File 'lib/ansi/progressbar.rb', line 170

def format_time(t)
  t = t.to_i
  sec = t % 60
  min  = (t / 60) % 60
  hour = t / 3600
  sprintf("%02d:%02d:%02d", hour, min, sec);
end

#get_widthObject (private)

TODO: Use Terminal.terminal_width instead.



228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
# File 'lib/ansi/progressbar.rb', line 228

def get_width
  # FIXME: I don't know how portable it is.
  default_width = 80
  begin
    tiocgwinsz = 0x5413
    data = [0, 0, 0, 0].pack("SSSS")
    if @out.ioctl(tiocgwinsz, data) >= 0 then
      #rows, cols, xpixels, ypixels = data.unpack("SSSS")
      cols = data.unpack("SSSS")[1]
      if cols >= 0 then cols else default_width end
    else
      default_width
    end
  rescue Exception
    default_width
  end
end

#haltObject



103
104
105
106
# File 'lib/ansi/progressbar.rb', line 103

def halt
  @is_finished = true
  show_progress
end

#inc(step = 1) ⇒ Object



130
131
132
133
134
135
# File 'lib/ansi/progressbar.rb', line 130

def inc(step = 1)
  @current += step
  @current = @total if @current > @total
  show_progress
  @previous = @current
end

#inspectObject



142
143
144
# File 'lib/ansi/progressbar.rb', line 142

def inspect
  "(ProgressBar: #{@current}/#{@total})"
end

#percentageObject (private)



215
216
217
218
219
220
221
# File 'lib/ansi/progressbar.rb', line 215

def percentage
  if @total.zero?
    100
  else
    @current  * 100 / @total
  end
end

#resetObject



124
125
126
127
# File 'lib/ansi/progressbar.rb', line 124

def reset
  @current = 0
  @is_finished = false
end

#set(count) ⇒ Object



108
109
110
111
112
113
114
115
116
117
118
119
120
121
# File 'lib/ansi/progressbar.rb', line 108

def set(count)
  if count < 0
    raise "invalid count less than zero: #{count}"
  elsif count > @total
    if @total_overflow
      @total = count + 1
    else
      raise "invalid count greater than total: #{count}"
    end
  end
  @current = count
  show_progress
  @previous = @current
end

#showObject (private)



247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
# File 'lib/ansi/progressbar.rb', line 247

def show
  arguments = @format_arguments.map do |method|
    colorize(send(method), styles[method])
  end
  line      = sprintf(@format, *arguments)
  width     = get_width
  length    = ANSI::Code.uncolor{line}.length
  if length == width - 1
    @out.print(line + eol)
  elsif length >= width
    @bar_length = [@bar_length - (length - width + 1), 0].max
    @bar_length == 0 ?  @out.print(line + eol) : show
  else #line.length < width - 1
    @bar_length += width - length + 1
    show
  end
end

#show_progressObject (private)



266
267
268
269
270
271
272
273
274
275
276
277
# File 'lib/ansi/progressbar.rb', line 266

def show_progress
  if @total.zero?
    cur_percentage = 100
    prev_percentage = 0
  else
    cur_percentage  = (@current  * 100 / @total).to_i
    prev_percentage = (@previous * 100 / @total).to_i
  end
  if cur_percentage > prev_percentage || @is_finished
    show
  end
end

#standard_modeObject



79
80
81
82
# File 'lib/ansi/progressbar.rb', line 79

def standard_mode
  @format = "%-14s %3d%% %s %s"
  @format_arguments = [:title, :percentage, :bar, :stat]
end

#statObject (private)



194
195
196
# File 'lib/ansi/progressbar.rb', line 194

def stat
  if @is_finished then elapsed else eta end
end

#stat_for_file_transferObject (private)



198
199
200
201
202
203
204
# File 'lib/ansi/progressbar.rb', line 198

def stat_for_file_transfer
  if @is_finished then
    sprintf("%s %s %s", bytes, transfer_rate, elapsed)
  else
    sprintf("%s %s %s", bytes, transfer_rate, eta)
  end
end

#style(options) ⇒ Object

Set ANSI styling options.



74
75
76
# File 'lib/ansi/progressbar.rb', line 74

def style(options)
  @styles = options
end

#titleObject (private)



223
224
225
# File 'lib/ansi/progressbar.rb', line 223

def title
  @title[0,13] + ":"
end

#title=(str) ⇒ Object



50
51
52
# File 'lib/ansi/progressbar.rb', line 50

def title=(str)
  @title = str
end

#total_overflow=(boolv) ⇒ Object



60
61
62
# File 'lib/ansi/progressbar.rb', line 60

def total_overflow=(boolv)
  @total_overflow = boolv ? true : false
end

#transfer_modeObject Also known as: file_transfer_mode



85
86
87
88
# File 'lib/ansi/progressbar.rb', line 85

def transfer_mode
  @format = "%-14s %3d%% %s %s"
  @format_arguments = [:title, :percentage, :bar, :stat_for_file_transfer]
end

#transfer_rateObject (private)



161
162
163
164
# File 'lib/ansi/progressbar.rb', line 161

def transfer_rate
  bytes_per_second = @current.to_f / (Time.now - @start_time)
  sprintf("%s/s", convert_bytes(bytes_per_second))
end