multi_progress_bar 0.0.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/README.rdoc ADDED
@@ -0,0 +1,11 @@
1
+ == MultiProgressBar
2
+
3
+ Displays multiple progress bars using Ncurses. Useful for displaying the status of multiple test runs, say, distributed across different machines. Which is exactly why I wrote it.
4
+
5
+ Uses +ruby-progressbar+ to render the bars.
6
+
7
+ == Credits
8
+
9
+ * Codes by Peter Jaros.
10
+ * Thanks to Nick Evans for the inspiration (http://ekenosen.net/nick/devblog/2008/12/better-progress-bar-for-rspec/).
11
+ * Thanks to Satoru Takabayashi for +ruby-progressbar+ (http://0xcc.net/ruby-progressbar/index.html.en).
data/Rakefile ADDED
@@ -0,0 +1,27 @@
1
+ begin
2
+ require 'jeweler'
3
+ Jeweler::Tasks.new do |gemspec|
4
+ gemspec.name = "multi_progress_bar"
5
+ gemspec.summary = "Displays multiple progress bars using Ncurses."
6
+ gemspec.description = "Displays multiple progress bars using Ncurses. Useful for displaying the status of multiple test runs, say, distributed across different machines. Which is exactly why I wrote it."
7
+ gemspec.email = "peter.a.jaros@gmail.com"
8
+ gemspec.homepage = "http://github.com/Peeja/multi_progress_bar/tree/master/"
9
+ gemspec.authors = ["Peter Jaros"]
10
+ end
11
+ rescue LoadError
12
+ puts "Jeweler not available. For gem tasks, install it with: sudo gem install jeweler"
13
+ end
14
+
15
+
16
+ begin
17
+ require 'hanna/rdoctask'
18
+ rescue LoadError
19
+ require 'rake/rdoctask'
20
+ end
21
+
22
+ desc 'Generate RDoc documentation.'
23
+ Rake::RDocTask.new(:rdoc) do |rdoc|
24
+ rdoc.main = "README.rdoc"
25
+ rdoc.rdoc_dir = 'doc'
26
+ rdoc.options << '--webcvs=http://github.com/Peeja/multi_progress_bar/tree/master/'
27
+ end
@@ -0,0 +1,35 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require 'rubygems'
4
+
5
+ $LOAD_PATH.unshift File.dirname(__FILE__)+"/../lib"
6
+ require 'multi_progress_bar'
7
+
8
+
9
+ begin
10
+ MultiProgressBar.start
11
+
12
+ # Demo.
13
+ make_machine_bar = lambda { MultiProgressBar::Bar.new("(Waiting...)", 100) }
14
+ machine_bars = [make_machine_bar[], make_machine_bar[]]
15
+ total = MultiProgressBar::TotalBar.new("-Total-")
16
+
17
+ machine_names = ["bleeker", "montrose"]
18
+
19
+ until machine_bars.all? { |bar| bar.current == bar.total }
20
+ sleep(0.1)
21
+
22
+ # Simulate machines becoming available.
23
+ machine_bars.each do |bar|
24
+ if bar.title == "(Waiting...)"
25
+ bar.title = machine_names.pop if rand(10) == 0
26
+ else
27
+ bar.inc(rand(10))
28
+ end
29
+ end
30
+
31
+ MultiProgressBar.log(rand(2000))
32
+ end
33
+ ensure
34
+ MultiProgressBar.end
35
+ end
data/examples/loop.rb ADDED
@@ -0,0 +1,40 @@
1
+ #!/usr/local/bin/ruby -w
2
+
3
+ # Not actually an example, but a script to run the example every
4
+ # time a file changes, for testing.
5
+ #
6
+ # example/loop example/example.rb
7
+
8
+ command = ARGV.shift
9
+ file_patterns_to_watch = (ARGV.length > 0 ? ARGV : ['**/*.rb'])
10
+
11
+ files = {}
12
+
13
+ file_patterns_to_watch.each do |arg|
14
+ Dir[arg].each { |file|
15
+ files[file] = File.mtime(file)
16
+ }
17
+ end
18
+
19
+ trap('INT') do
20
+ puts "\nQuitting..."
21
+ exit
22
+ end
23
+
24
+
25
+ loop do
26
+ system command
27
+
28
+ loop do
29
+ sleep 0.1
30
+
31
+ changed_file, last_changed = files.find { |file, last_changed|
32
+ File.mtime(file) > last_changed
33
+ }
34
+
35
+ if changed_file
36
+ files[changed_file] = File.mtime(changed_file)
37
+ break
38
+ end
39
+ end
40
+ end
@@ -0,0 +1,53 @@
1
+ module MultiProgressBar
2
+ # Represents a progress bar at the bottom of the screen.
3
+ #
4
+ # +Bar+ exposes the same interface as +ProgressBar+ from the +progressbar+
5
+ # gem which backs its display.
6
+ #
7
+ # file_progress = MultiProgressBar::Bar.new("file_1", 2596)
8
+ # file_progress.inc # Increment value by 1.
9
+ # file_progress.inc(10) # Increment value by 10.
10
+ # file_progress.set(30) # Set value to 30.
11
+ #
12
+ # # Change bar format.
13
+ # file_progress.format = "%-14s (%s) %3d%% %s"
14
+ # file_progress.format_arguments = [:title, :stat, :percentage, :bar].
15
+ #
16
+ # See the +ruby-progressbar+ gem (http://0xcc.net/ruby-progressbar/index.html.en)
17
+ # for more details.
18
+ class Bar < DelegateClass(BarRenderer)
19
+ # Create a new Bar with a +title+ and a +total+ value.
20
+ def initialize(title, total)
21
+ MultiProgressBar.add_bar(self)
22
+
23
+ @observers = []
24
+
25
+ @renderer = BarRenderer.new(title, total, MultiProgressBar.width) do |rendered_bar|
26
+ MultiProgressBar.update_bar(self, rendered_bar)
27
+ end
28
+
29
+ super @renderer
30
+ end
31
+
32
+ # Increment the current value of the bar.
33
+ def inc(step = 1)
34
+ super
35
+ notify_observers
36
+ end
37
+
38
+ # Set the current value of the bar absolutely.
39
+ def set(count)
40
+ super
41
+ notify_observers
42
+ end
43
+
44
+ def observe(&b) #:nodoc:
45
+ @observers << b
46
+ end
47
+
48
+ private
49
+ def notify_observers
50
+ @observers.each { |b| b.call(self) }
51
+ end
52
+ end
53
+ end
@@ -0,0 +1,22 @@
1
+ module MultiProgressBar
2
+ class BarRenderer < ProgressBar #:nodoc:
3
+ attr_writer :title
4
+
5
+ def initialize(title, total, width, &block)
6
+ @block = block
7
+ @buffer = StringIO.new
8
+ @width = width
9
+ super(title, total, @buffer)
10
+ end
11
+
12
+ def show
13
+ super
14
+ @block.call(@buffer.string)
15
+ @buffer.string = ""
16
+ end
17
+
18
+ def get_width
19
+ @width
20
+ end
21
+ end
22
+ end
@@ -0,0 +1,32 @@
1
+ module MultiProgressBar
2
+ # Works just like +Bar+, but displays the total of other bars.
3
+ # TotalBar#inc and TotalBar#set don't work.
4
+ class TotalBar < Bar
5
+ # Create a new TotalBar. +bars+ is an array of Bar objects, and defaults to
6
+ # all existing bars.
7
+ def initialize(title, bars = MultiProgressBar.bars.dup)
8
+ @bars = bars
9
+
10
+ @bars.each do |bar|
11
+ bar.observe do
12
+ update_total
13
+ end
14
+ end
15
+
16
+ total_total = @bars.inject(0) { |sum, bar| sum + bar.total }
17
+ super title, total_total
18
+ end
19
+
20
+ [:inc, :set].each do |name|
21
+ define_method(name) do
22
+ raise NoMethodError, "NoMethodError: private method `#{name}' called for #{self}"
23
+ end
24
+ end
25
+
26
+ private
27
+ def update_total
28
+ total_current = @bars.inject(0) { |sum, bar| sum + bar.current }
29
+ @renderer.set(total_current)
30
+ end
31
+ end
32
+ end
@@ -0,0 +1,59 @@
1
+ require 'ncurses'
2
+ require 'progressbar'
3
+ require 'delegate'
4
+ require 'abstraction'
5
+
6
+ module MultiProgressBar
7
+ class << self
8
+ attr_reader :bars
9
+
10
+ # Set up the screen. Always call +MultiProgressBar.start+ before using progress bars.
11
+ def start
12
+ @bars = [].freeze
13
+
14
+ Ncurses.initscr
15
+ Ncurses.curs_set(0)
16
+
17
+ @bars_window = Ncurses::WINDOW.new(1, 0, Ncurses.LINES-1, 0)
18
+ @log_window = Ncurses::WINDOW.new(Ncurses.LINES-1, 0, 0, 0)
19
+ @log_window.scrollok(true)
20
+ end
21
+
22
+ # Restore the terminal to normal function. Always call this before exiting.
23
+ def end
24
+ Ncurses.endwin
25
+ puts
26
+ end
27
+
28
+ # Write +text+ to the space above the progress bars.
29
+ def log(text)
30
+ @log_window.addstr("#{text}\n")
31
+ @log_window.refresh
32
+ end
33
+
34
+ def width #:nodoc:
35
+ @bars_window.getmaxx
36
+ end
37
+
38
+ def add_bar(bar) #:nodoc:
39
+ @bars += [bar]
40
+
41
+ @bars_window.mvwin(Ncurses.LINES-bars.size, @bars_window.getbegx)
42
+ @bars_window.resize(bars.size, @bars_window.getmaxx)
43
+ @bars_window.refresh
44
+
45
+ @log_window.resize(Ncurses.LINES-bars.size, @log_window.getmaxx)
46
+ @log_window.refresh
47
+ end
48
+
49
+ def update_bar(bar, rendered_bar) #:nodoc:
50
+ @bars_window.move(bars.index(bar), 0)
51
+ @bars_window.addstr(rendered_bar)
52
+ @bars_window.refresh
53
+ end
54
+ end
55
+ end
56
+
57
+ require 'multi_progress_bar/bar_renderer'
58
+ require 'multi_progress_bar/bar'
59
+ require 'multi_progress_bar/total_bar'
metadata ADDED
@@ -0,0 +1,63 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: multi_progress_bar
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.0
5
+ platform: ruby
6
+ authors:
7
+ - Peter Jaros
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+
12
+ date: 2009-11-15 00:00:00 -05:00
13
+ default_executable:
14
+ dependencies: []
15
+
16
+ description: Displays multiple progress bars using Ncurses. Useful for displaying the status of multiple test runs, say, distributed across different machines. Which is exactly why I wrote it.
17
+ email: peter.a.jaros@gmail.com
18
+ executables: []
19
+
20
+ extensions: []
21
+
22
+ extra_rdoc_files:
23
+ - README.rdoc
24
+ files:
25
+ - README.rdoc
26
+ - Rakefile
27
+ - examples/example.rb
28
+ - examples/loop.rb
29
+ - lib/multi_progress_bar.rb
30
+ - lib/multi_progress_bar/bar.rb
31
+ - lib/multi_progress_bar/bar_renderer.rb
32
+ - lib/multi_progress_bar/total_bar.rb
33
+ has_rdoc: true
34
+ homepage: http://github.com/Peeja/multi_progress_bar/tree/master/
35
+ licenses: []
36
+
37
+ post_install_message:
38
+ rdoc_options:
39
+ - --charset=UTF-8
40
+ require_paths:
41
+ - lib
42
+ required_ruby_version: !ruby/object:Gem::Requirement
43
+ requirements:
44
+ - - ">="
45
+ - !ruby/object:Gem::Version
46
+ version: "0"
47
+ version:
48
+ required_rubygems_version: !ruby/object:Gem::Requirement
49
+ requirements:
50
+ - - ">="
51
+ - !ruby/object:Gem::Version
52
+ version: "0"
53
+ version:
54
+ requirements: []
55
+
56
+ rubyforge_project:
57
+ rubygems_version: 1.3.5
58
+ signing_key:
59
+ specification_version: 3
60
+ summary: Displays multiple progress bars using Ncurses.
61
+ test_files:
62
+ - examples/example.rb
63
+ - examples/loop.rb