]> git.uio.no Git - usit-rt.git/blobdiff - lib/RT/Migrate.pm
Upgrade to 4.2.8
[usit-rt.git] / lib / RT / Migrate.pm
diff --git a/lib/RT/Migrate.pm b/lib/RT/Migrate.pm
new file mode 100644 (file)
index 0000000..9f04294
--- /dev/null
@@ -0,0 +1,193 @@
+# BEGIN BPS TAGGED BLOCK {{{
+#
+# COPYRIGHT:
+#
+# This software is Copyright (c) 1996-2014 Best Practical Solutions, LLC
+#                                          <sales@bestpractical.com>
+#
+# (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;