Merge pull request #42 from solgenomics/topic/duplicate_image_warning
[cxgn-corelibs.git] / lib / CXGN / Tools / Terminal / ETA.pm
blob2b33e393ab075c33eb0922a172f5c3e801dfa61a
1 package CXGN::Tools::Terminal::ETA;
2 $|=1; #does this help?
3 =head1 CXGN::Tools::Terminal::ETA
5 A nice little package for displaying the ETA for a process in a terminal
8 =head1 USAGE
10 my $eta = CXGN::Tools::Terminal::ETA->new();
11 $eta->interval(1.2) #only allow updates 1.2 seconds after the last update
12 my $i=0;
13 $eta->begin(); #sets start time
14 $eta->target(3000); #total # of iterations expected
15 while($row = ...){
16 #doing stuff
17 #whoop-de-do
18 $i++;
19 $eta->update_and_print($i);
22 #Prints something like:
23 #ETA: 01:33:34
25 Don't print any newlines if you want the ETA to be displayed in-place!
27 =cut
30 sub new {
31 my $class = shift;
32 my $self = bless {}, $class;
33 $self->{increment} = 1;
34 $self->{begin} = time();
35 $self->{last_update} = time();
36 $self->{current} = 0;
37 $self->{interval} = 0;
38 return $self;
41 sub begin {
42 my $self = shift;
43 $self->{begin} = time();
46 sub target {
47 my $self = shift;
48 my $target = shift;
49 $self->{target} = $target if $target;
50 return $self->{target};
53 sub interval {
54 my $self = shift;
55 my $interval = shift;
56 $self->{interval} = $interval if $interval;
57 return $self->{interval};
60 sub update {
61 my $self = shift;
62 my $current = shift;
63 if($self->{interval} > 0){
64 $diff = time() - $self->{last_update};
65 return if $diff < $self->{interval};
67 $self->{current} = $current;
68 $self->{elapsed} = time() - $self->{begin};
69 $self->{elapsed} ||= 1; #round up to 1 second, at least
70 $self->{remaining} = $self->{target} - $self->{current};
71 $self->{rate} = ($self->{current})/$self->{elapsed};
72 $self->{eta} = $self->{remaining}/$self->{rate};
73 $self->{last_update} = time();
76 sub update_and_print {
77 my $self = shift;
78 if($self->{interval} > 0) {
79 $diff = time() - $self->{last_update};
80 return if $diff < $self->{interval};
82 $self->update( shift );
83 $self->print();
86 sub print {
87 my $self = shift;
88 print ( " " x 80 . "\r" x 200 );
89 print "ETA: " . $self->format_secs($self->{eta});
92 sub format_secs {
93 my $self = shift;
94 my $sec = int( shift );
95 my $hour = 0;
96 my $min = 0;
97 if($sec > 60){
98 $min = int($sec / 60);
99 $sec = $sec - $min*60;
100 if($min > 60){
101 $hour = int($min / 60);
102 $min = $min - $hour*60;
105 foreach($sec, $hour, $min){
106 next unless $_<10;
107 $_ = "0" . $_;
109 return "$hour:$min:$sec";