[rt-users] Importing from Mantis
Andy Lester
andy at petdance.com
Wed Aug 7 14:46:17 EDT 2002
I just made the switch from Mantis (mantisbt.sf.net) to RT, and I'm
loving RT more and more every day. To switch over, I had to write a
convert script which I present below. Use it as you like.
xoxo,
Andy
#!/usr/bin/perl -w
#$Id: import-mantis,v 1.18 2002/08/02 01:51:19 alester Exp $
# import-mantis
# Created by: Andy Lester <andy at petdance.com>
# Hacked from Jesse's import-gnats script
#
# Please go thru and change all the values to what's appropriate.
use strict;
use Carp qw( cluck confess );
my $EMAILDOMAIN = "flr.follett.com"; # user_id at EMAILDOMAIN for missing RT1 emails
my $DEFAULTQUEUE = 'general'; # Qeuue to put tickets from deleted queues in.
# IF YOU DO NOT SET THE ABOVE VALUE TO A VALID QUEUE NAME, YOUR IMPORT WILL
# FAIL AND YOU'LL BE REALLY REALLY UNHAPPY.
# Mantis DB variables
my $dbname = "bugtracker";
my $dbuser = "root";
my $dbpass = "fish";
my $Debug = 1;
our %mantis_name_by_id;
# Replace this with the path to your RT lib directory
use lib "/usr/local/rt2/lib/";
# Replace this with the path to your RT etc directory
use lib "/usr/local/rt2/etc/";
use Data::Dumper;
use RT::Interface::CLI qw( CleanEnv LoadConfig DBConnect GetCurrentUser GetMessageContent );
use Date::Format;
use MIME::Entity;
use Mail::Internet;
use MIME::Parser;
use RT::User;
use RT::Queue;
use RT::Ticket;
use RT::Transaction;
warn "Loaded modules\n";
#Clean out all the nasties from the environment
CleanEnv();
warn "CleanEnv() done\n";
#Load etc/config.pm and drop privs
LoadConfig();
warn "LoadConfig() done\n";
# This is an inlined version of RT::Init().
# Calling RT::Init() would lock up, but pulling the guts out here
# worked. I don't know why.
use RT;
#Get a database connection
$RT::Handle = new RT::Handle($RT::DatabaseType);
$RT::Handle->Connect();
#RT's system user is a genuine database user. its id lives here
$RT::SystemUser = new RT::CurrentUser();
$RT::SystemUser->LoadByName('RT_System');
#RT's "nobody user" is a genuine database user. its ID lives here.
$RT::Nobody = new RT::CurrentUser();
$RT::Nobody->LoadByName('Nobody');
warn "Did DBConnect();\n";
# Mantis-specific handle
our $dbh =
DBI->connect(
"DBI:mysql:host=localhost;database=$dbname",
$dbuser, $dbpass,
{PrintError => 0, RaiseError => 1}
);
warn "Created Mantis DBH\n";
# Returns a queue object based on a Mantis project name
sub get_queue {
my $name = shift;
my $queue = new RT::Queue($RT::SystemUser);
$queue->Load($name);
my ($val,$msg);
unless ($queue->Id) {
($val, $msg) =
$queue->Create(
Name => $name,
Description => $name . " imported from Mantis",
CorrespondAddress => $name.'@'. $EMAILDOMAIN );
warn "Fired up the RT queue $name\n";
}
unless ($queue->Id) {
die "Couldn't create a queue called '$name'\n$msg";
}
return $queue;
}
IMPORT_USERS: {
my $sql = q{
select id, username, email
from mantis_user_table
};
my $sth = $dbh->prepare( $sql ) or die;
$sth->execute() or die;
my $root = new RT::User($RT::SystemUser);
$root->Load('root');
while ( my $row = $sth->fetchrow_hashref ) {
my $name = $row->{username};
my $result = $root->Create(
Name => $name,
RealName => $name,
Gecos => $name,
EmailAddress => $row->{email},
Privileged => 1,
);
$mantis_name_by_id{ $row->{id} } = $name;
warn "Created $name: $result\n";
}
$sth->finish;
}
# Import all the top-level bugs
IMPORT_BUGS: {
my $sql = q{
select B.*, T.*, P.name as project_name
from mantis_bug_table B, mantis_bug_text_table T, mantis_project_table P
where B.id = T.id
and
P.id = B.project_id
order by B.id
};
my $sth = $dbh->prepare( $sql ) or die;
$sth->execute() or die;
while ( my $row = $sth->fetchrow_hashref ) {
my $ticket = bug_to_ticket( $row );
}
$sth->finish;
}
# Import all the notes
IMPORT_NOTES: {
my $sql = q{
select *
from mantis_bugnote_table N, mantis_bugnote_text_table T
where N.id = T.id
order by bug_id
};
my $sth = $dbh->prepare( $sql ) or die;
$sth->execute() or die;
while ( my $row = $sth->fetchrow_hashref ) {
my $id = $row->{bug_id};
my $ticket = new RT::Ticket( $RT::SystemUser );
if ( $ticket->Load( $id ) ) {
my $email = username_from_mantis_id( $row->{reporter_id} );
add_comment( $ticket, $email, $row->{note}, $row->{date_submitted} );
warn "Attached to bug $id\n";
} else {
warn "***>>> Couldn't load $id";
}
}
$sth->finish;
}
sub bug_to_ticket {
my $bug = shift;
my $queue = get_queue( $bug->{project_name} );
my $ticket = new RT::Ticket( $RT::SystemUser );
my $status = status_convert( $bug->{status} );
my ($id,$error);
{ # Needed a more verbose dump if anything went wrong here.
local $SIG{__WARN__} = \&confess;
($id,$error) =
$ticket->Import(
id => $bug->{id},
Subject => clean( $bug->{summary} ),
Queue => $queue->id,
Priority => $bug->{priority},
Status => $status,
);
}
warn $error unless $id;
warn "Created ticket #$id as $status\n" if $id;
my $email = username_from_mantis_id( $bug->{reporter_id} );
for my $field ( qw( description steps_to_reproduce additional_information ) ) {
my $text = $bug->{$field};
if ( $text ) {
my $header = ucfirst $field;
$header =~ s/_/ /g;
add_comment( $ticket, $email, "$header:\n$text", $bug->{date_submitted} );
warn " Added $header\n";
}
}
warn " \n";
return $ticket;
}
sub add_comment {
my $ticket = shift;
my $email = shift;
my $text = shift;
my $date = shift;
$text = clean( $text );
# Squeeze the user info into the top of the text
my $mime = MIME::Entity->build(
Data => "From: $email\nDate: $date\n$text"
);
$ticket->Comment( MIMEObj => $mime );
}
sub username_from_mantis_id {
my $mantis_id = shift;
return $mantis_name_by_id{ $mantis_id } || "Unknown Mantis user #$mantis_id";
}
# Undo all the goofy stuff that Mantis does with its text fields.
sub clean {
my $str = shift;
$str =~ s/</</g;
$str =~ s/>/>/g;
$str =~ s/"/"/g;
$str =~ s/&/\&/g;
# The order of translation is important here.
$str =~ s/\\\\/\\/g;
$str =~ s/\\'/'/g;
$str =~ s/\\"/"/g;
return $str;
}
#$g_access_levels_enum_string = "10:viewer,25:reporter,40:updater,55:developer,70:manager,90:administrator";
#$g_project_status_enum_string = "10:development,30:release,50:stable,70:obsolete";
#$g_priority_enum_string = "10:none,20:low,30:normal,40:high,50:urgent,60:immediate";
#$g_severity_enum_string = "10:feature,20:trivial,30:text,40:tweak,50:minor,60:major,70:crash,80:block";
#$g_reproducibility_enum_string = "10:always,30:sometimes,50:random,70:have not tried,90:unable to duplicate,100:N/A";
#$g_status_enum_string = "10:new,20:feedback,30:acknowledged,40:confirmed,50:assigned,80:resolved,90:closed";
#$g_resolution_enum_string = "10:open,20:fixed,30:reopened,40:unable to duplicate,50:not fixable,60:duplicate,70:not a bug,80:suspended,90:won't fix";
sub status_convert {
my $status = shift;
my %map = (
10 => 'new',
20 => 'open',
30 => 'open',
40 => 'open',
50 => 'open',
80 => 'resolved',
90 => 'resolved',
);
return $map{$status} or die "Unknown status \"$status\"";
}
--
'Andy Lester andy at petdance.com
Programmer/author petdance.com
Daddy parsley.org/quinn Jk'=~/.+/s;print((split//,$&)
[unpack'C*',"n2]3%+>\"34.'%&.'^%4+!o.'"])
More information about the rt-users
mailing list