]> git.uio.no Git - usit-rt.git/blame - lib/RT/Migrate.pm
Upgrade to 4.2.2
[usit-rt.git] / lib / RT / Migrate.pm
CommitLineData
af59614d
MKG
1# BEGIN BPS TAGGED BLOCK {{{
2#
3# COPYRIGHT:
4#
320f0092 5# This software is Copyright (c) 1996-2014 Best Practical Solutions, LLC
af59614d
MKG
6# <sales@bestpractical.com>
7#
8# (Except where explicitly superseded by other copyright notices)
9#
10#
11# LICENSE:
12#
13# This work is made available to you under the terms of Version 2 of
14# the GNU General Public License. A copy of that license should have
15# been provided with this software, but in any event can be snarfed
16# from www.gnu.org.
17#
18# This work is distributed in the hope that it will be useful, but
19# WITHOUT ANY WARRANTY; without even the implied warranty of
20# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
21# General Public License for more details.
22#
23# You should have received a copy of the GNU General Public License
24# along with this program; if not, write to the Free Software
25# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
26# 02110-1301 or visit their web page on the internet at
27# http://www.gnu.org/licenses/old-licenses/gpl-2.0.html.
28#
29#
30# CONTRIBUTION SUBMISSION POLICY:
31#
32# (The following paragraph is not intended to limit the rights granted
33# to you to modify and distribute this software under the terms of
34# the GNU General Public License and is only of importance to you if
35# you choose to contribute your changes and enhancements to the
36# community by submitting them to Best Practical Solutions, LLC.)
37#
38# By intentionally submitting any modifications, corrections or
39# derivatives to this work, or any other work intended for use with
40# Request Tracker, to Best Practical Solutions, LLC, you confirm that
41# you are the copyright holder for those contributions and you grant
42# Best Practical Solutions, LLC a nonexclusive, worldwide, irrevocable,
43# royalty-free, perpetual, license to use, copy, create derivative
44# works based on those contributions, and sublicense and distribute
45# those contributions and any derivatives thereof.
46#
47# END BPS TAGGED BLOCK }}}
48
49package RT::Migrate;
50
51use strict;
52use warnings;
53
54use Time::HiRes qw//;
55
56sub format_time {
57 my $time = shift;
58 my $s = "";
59
60 $s .= int($time/60/60)."hr "
61 if $time > 60*60;
62 $s .= int(($time % (60*60))/60)."min "
63 if $time > 60;
64 $s .= int($time % 60)."s"
65 if $time < 60*60;
66
67 return $s;
68}
69
70sub progress_bar {
71 my %args = (
72 label => "",
73 now => 0,
74 max => 1,
75 cols => 80,
76 char => "=",
77 @_,
78 );
79 $args{now} ||= 0;
80
81 my $fraction = $args{max} ? $args{now} / $args{max} : 0;
82
83 my $max_width = $args{cols} - 30;
84 my $bar_width = int($max_width * $fraction);
85
86 return sprintf "%20s |%-" . $max_width . "s| %3d%%\n",
87 $args{label}, $args{char} x $bar_width, $fraction*100;
88}
89
90sub progress {
91 my %args = (
92 top => sub { print "\n\n" },
93 bottom => sub {},
94 every => 3,
95 bars => [qw/Ticket Transaction Attachment User Group/],
96 counts => sub {},
97 max => {},
98 @_,
99 );
100
101 my $max_objects = 0;
102 $max_objects += $_ for values %{ $args{max} };
103
104 my $last_time;
105 my $start;
106 my $left;
107 my $offset;
108 return sub {
109 my $obj = shift;
110 my $force = shift;
111 my $now = Time::HiRes::time();
112 return if defined $last_time and $now - $last_time <= $args{every} and not $force;
113
114 $start = $now unless $start;
115 $last_time = $now;
116
117 my $elapsed = $now - $start;
118
119 # Determine terminal size
120 print `clear`;
121 my ($cols, $rows) = (80, 25);
122 eval {
123 require Term::ReadKey;
124 ($cols, $rows) = Term::ReadKey::GetTerminalSize();
125 };
126 $cols -= 1;
127
128 $args{top}->($elapsed, $rows, $cols);
129
130 my %counts = $args{counts}->();
131 for my $class (map {"RT::$_"} @{$args{bars}}) {
132 my $display = $class;
133 $display =~ s/^RT::(.*)/@{[$1]}s:/;
134 print progress_bar(
135 label => $display,
136 now => $counts{$class},
137 max => $args{max}{$class},
138 cols => $cols,
139 );
140 }
141
142 my $total = 0;
143 $total += $_ for map {$counts{$_}} grep {exists $args{max}{$_}} keys %counts;
144 $offset = $total unless defined $offset;
145 print "\n", progress_bar(
146 label => "Total",
147 now => $total,
148 max => $max_objects,
149 cols => $cols,
150 char => "#",
151 );
152
153 # Time estimates
154 my $fraction = $max_objects
155 ? ($total - $offset)/($max_objects - $offset)
156 : 0;
157 if ($fraction > 0.03) {
158 if (defined $left) {
159 $left = 0.75 * $left
160 + 0.25 * ($elapsed / $fraction - $elapsed);
161 } else {
162 $left = ($elapsed / $fraction - $elapsed);
163 }
164 }
165 print "\n";
166 printf "%20s %s\n", "Elapsed time:",
167 format_time($elapsed);
168 printf "%20s %s\n", "Estimated left:",
169 (defined $left) ? format_time($left) : "-";
170
171 $args{bottom}->($elapsed, $rows, $cols);
172 }
173
174}
175
176sub setup_logging {
177 my ($dir, $file) = @_;
178
320f0092
MKG
179
180 RT->Config->Set(LogToSTDERR => 'warning');
181 RT->Config->Set(LogToFile => 'warning');
182 RT->Config->Set(LogDir => $dir);
183 RT->Config->Set(LogToFileNamed => $file);
184 RT->Config->Set(LogStackTraces => 'error');
af59614d
MKG
185
186 undef $RT::Logger;
187 RT->InitLogging();
188
189 my $logger = $RT::Logger->output('file') || $RT::Logger->output("rtlog");
190 return $logger ? $logger->{filename} : undef;
191}
192
1931;