# BEGIN BPS TAGGED BLOCK {{{ # # COPYRIGHT: # # This software is Copyright (c) 1996-2015 Best Practical Solutions, LLC # # # (Except where explicitly superseded by other copyright notices) # # # LICENSE: # # This work is made available to you under the terms of Version 2 of # the GNU General Public License. A copy of that license should have # been provided with this software, but in any event can be snarfed # from www.gnu.org. # # This work is distributed in the hope that it will be useful, but # WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU # General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA # 02110-1301 or visit their web page on the internet at # http://www.gnu.org/licenses/old-licenses/gpl-2.0.html. # # # CONTRIBUTION SUBMISSION POLICY: # # (The following paragraph is not intended to limit the rights granted # to you to modify and distribute this software under the terms of # the GNU General Public License and is only of importance to you if # you choose to contribute your changes and enhancements to the # community by submitting them to Best Practical Solutions, LLC.) # # By intentionally submitting any modifications, corrections or # derivatives to this work, or any other work intended for use with # Request Tracker, to Best Practical Solutions, LLC, you confirm that # you are the copyright holder for those contributions and you grant # Best Practical Solutions, LLC a nonexclusive, worldwide, irrevocable, # royalty-free, perpetual, license to use, copy, create derivative # works based on those contributions, and sublicense and distribute # those contributions and any derivatives thereof. # # END BPS TAGGED BLOCK }}} package RT::Migrate; use strict; use warnings; use Time::HiRes qw//; sub format_time { my $time = shift; my $s = ""; $s .= int($time/60/60)."hr " if $time > 60*60; $s .= int(($time % (60*60))/60)."min " if $time > 60; $s .= int($time % 60)."s" if $time < 60*60; return $s; } sub progress_bar { my %args = ( label => "", now => 0, max => 1, cols => 80, char => "=", @_, ); $args{now} ||= 0; my $fraction = $args{max} ? $args{now} / $args{max} : 0; my $max_width = $args{cols} - 30; my $bar_width = int($max_width * $fraction); return sprintf "%20s |%-" . $max_width . "s| %3d%%\n", $args{label}, $args{char} x $bar_width, $fraction*100; } sub progress { my %args = ( top => sub { print "\n\n" }, bottom => sub {}, every => 3, bars => [qw/Ticket Transaction Attachment User Group/], counts => sub {}, max => {}, @_, ); my $max_objects = 0; $max_objects += $_ for values %{ $args{max} }; my $last_time; my $start; my $left; my $offset; return sub { my $obj = shift; my $force = shift; my $now = Time::HiRes::time(); return if defined $last_time and $now - $last_time <= $args{every} and not $force; $start = $now unless $start; $last_time = $now; my $elapsed = $now - $start; # Determine terminal size print `clear`; my ($cols, $rows) = (80, 25); eval { require Term::ReadKey; ($cols, $rows) = Term::ReadKey::GetTerminalSize(); }; $cols -= 1; $args{top}->($elapsed, $rows, $cols); my %counts = $args{counts}->(); for my $class (map {"RT::$_"} @{$args{bars}}) { my $display = $class; $display =~ s/^RT::(.*)/@{[$1]}s:/; print progress_bar( label => $display, now => $counts{$class}, max => $args{max}{$class}, cols => $cols, ); } my $total = 0; $total += $_ for map {$counts{$_}} grep {exists $args{max}{$_}} keys %counts; $offset = $total unless defined $offset; print "\n", progress_bar( label => "Total", now => $total, max => $max_objects, cols => $cols, char => "#", ); # Time estimates my $fraction = $max_objects ? ($total - $offset)/($max_objects - $offset) : 0; if ($fraction > 0.03) { if (defined $left) { $left = 0.75 * $left + 0.25 * ($elapsed / $fraction - $elapsed); } else { $left = ($elapsed / $fraction - $elapsed); } } print "\n"; printf "%20s %s\n", "Elapsed time:", format_time($elapsed); printf "%20s %s\n", "Estimated left:", (defined $left) ? format_time($left) : "-"; $args{bottom}->($elapsed, $rows, $cols); } } sub setup_logging { my ($dir, $file) = @_; RT->Config->Set(LogToSTDERR => 'warning'); RT->Config->Set(LogToFile => 'warning'); RT->Config->Set(LogDir => $dir); RT->Config->Set(LogToFileNamed => $file); RT->Config->Set(LogStackTraces => 'error'); undef $RT::Logger; RT->InitLogging(); my $logger = $RT::Logger->output('file') || $RT::Logger->output("rtlog"); return $logger ? $logger->{filename} : undef; } 1;