Skip to content

Comparing changes

Choose two branches to see what’s changed or to start a new pull request. If you need to, you can also compare across forks.

Open a pull request

Create a new pull request by comparing changes across two branches. If you need to, you can also compare across forks.
...
  • 19 commits
  • 3 files changed
  • 0 commit comments
  • 1 contributor
Commits on Jul 11, 2012
@afresh1 Perltidy
Make it look good before hacking it to bits.
4ac8c59
Commits on Aug 11, 2012
@afresh1 Revert "Note that this importer doesn't work anymore"
Because now it should.

This reverts commit 2cf673e.

Conflicts:

	rt-ticket-importer
91157b6
@afresh1 Add some notes to the README 10e0436
@afresh1 better "main"
Read tickets from a directory of xml instead of a single file.

Handles what we need it to better than what we had.
be4ba7e
@afresh1 Add some lookup tables of data types
So we can lookup what to do with them rather than large if/else structures
227bd30
@afresh1 New helper method, ConvertQueue
Looks up the new QueueID from the name, defaulting to General if there isn't one that matches.
9438467
@afresh1 a generic _ConvertItem wrapper
Gets things ready and then calls the proper import routine.

Also handles retrying if we had an id collision.

Plus accessor methods for each type.
f5203a3
@afresh1 ConvertTicket -> import_ticket
Just handle the "special" stuff here.
20477e9
@afresh1 ConvertTransaction -> import_transaction
Much fixups to make moar betterer
6f4fc24
@afresh1 ConvertAttachment -> import_attachment
Same as the rest, just different.
502b717
@afresh1 ConvertLink -> import_link
This one actually runs later so it ended up more like the original.
0740cc0
@afresh1 Some helper methods for links
because we need all the old tickets and transactions imported before
we can create the links, we need to queue them until the end.
e4639b7
@afresh1 Cache completed items in a single hash instead of individual
Allows me to put some things in a common routine later.

nitpick my ($user) = @_ instead of my $user = shift;
ea63886
@afresh1 Reorder use line and don't quote hash keys
Just make it a bit tidier
e25c713
@afresh1 Don't need the WARN signal handler either. 7203627
@afresh1 Return 'Id's instead of 'UserObj's
it seems that is what RT likes.
3484e3b
@afresh1 Refactor more stuff into a helper method.
I was going to have to modify several of them, so rather than that, refactor!
31b2f4f
Commits on Aug 12, 2012
@afresh1 Correct key is "Requestor" not "Requestors" 8186b88
@afresh1 reset_rt helper script
It was really useful for me, so may help someone else.
421f5e7
Showing with 372 additions and 243 deletions.
  1. +4 −0 README.md
  2. +12 −0 reset_rt
  3. +356 −243 rt-ticket-importer
View
4 README.md
@@ -5,3 +5,7 @@ Request Tracker Ticket Import/Export scripts
Based on what I originally found at the University of Bath
http://wiki.bath.ac.uk/display/rt/Import+and+Export
+
+
+You should create your Queues, Privileged Users and any Custom Fields before
+running the import script.
View
12 reset_rt
@@ -0,0 +1,12 @@
+#!/bin/sh
+
+# This resets an SQLite RT database on OpenBSD anyway
+# It was very helpful when I was testing my import.
+
+rm /var/www/rt3/rt4
+rt-setup-database --action init --dba-password=x
+if [ -e initialdata ]; then
+ rt-setup-database --action insert --dba-password=x --datafile initialdata
+fi
+/etc/rc.d/rt restart
+
View
599 rt-ticket-importer
@@ -3,41 +3,64 @@
# This script outputs all reminders that are due within the next e.g. two
# days and mails the result to the corresponding owners.
#
-die "This no longer works, please fix it and send me the changes!";
package RT::Importer;
#use lib ("/etc/request-tracker3.6", "/usr/lib/rt/",
# "/usr/local/share/request-tracker3.6/lib");
-use lib ("/etc/request-tracker3.6", "/usr/share/request-tracker3.6/lib",
- "/usr/local/share/request-tracker3.6/lib");
+use lib (
+ "/etc/request-tracker3.6",
+ "/usr/share/request-tracker3.6/lib",
+ "/usr/local/share/request-tracker3.6/lib"
+);
use RT::Interface::CLI qw(CleanEnv GetCurrentUser);
-use RT::Ticket;
-use RT::User;
use RT::Attachment;
+use RT::Ticket;
use RT::Transaction;
-use MIME::Base64;
-
-use Data::Dumper;
+use RT::User;
+use Getopt::Std;
+use MIME::Base64;
use XML::Simple;
use strict;
-
-use Getopt::Std;
+use warnings;
my %opts;
-getopts('c:r:f:h', \%opts);
+getopts( 'c:r:d:h', \%opts );
-my $cf=$opts{'c'};
-my $rtname=$opts{'r'};
-my $file=$opts{'f'};
+my $cf = $opts{c};
+my $rtname = $opts{r};
+my $directory = $opts{d};
-unless (!$opts{'h'} && $cf && $rtname && $file) {
- print "rt-ticket-importer -f <filename> -r <source RT name> -c <CustomfieldId>\n";
- exit;
+unless ( !$opts{h} && $cf && $rtname && $directory ) {
+ print
+ "rt-ticket-importer -d <directory> -r <source RT name> -c <CustomfieldId>\n";
+ exit;
}
+my %user_types = map { $_ => 1 } qw(
+ Owner
+ Creator
+ LastUpdatedBy
+ Requestor
+ Cc
+ AdminCc
+ AddWatcher
+ DelWatcher
+ Take
+);
+
+my %link_types = map { $_ => 1 } qw(
+ DependsOn
+ DependedOnBy
+ RefersTo
+ ReferredToBy
+ MemberOf
+ MergedInto
+ HasMember
+);
+
# clean out all the nasties from the environment..
CleanEnv();
@@ -48,263 +71,353 @@ RT::LoadConfig();
RT::Init();
# reset the RT die signal handler, we don't need the extra info..
-$SIG{__DIE__} = "";
+$SIG{__DIE__} = "";
+$SIG{__WARN__} = "";
# drop setgid permissions, which is version 3.0 specific
eval { RT::DropSetGIDPermissions() };
+# Keep track of what has been converted.
+my %E;
-my $data = XMLin($file);
-
-print STDERR "File Loaded\n";
-
-my $attachments = $data->{'Attachments'};
-my $links = $data->{'Links'};
-my $transactions = $data->{'Transactions'};
-my $tickets = $data->{'Tickets'};
-my %USERS;
-my %TICKETS;
-my %TRANSACTIONS;
-my %LINKS;
-my %ATTACHMENTS;
+$E{Users} = {
+ 1 => $RT::SystemUser->Id,
+ 6 => $RT::Nobody->Id,
+};
sub ConvertUser {
- my $user = shift;
- return $RT::Nobody->Id unless ($user) ;
- return $USERS{$user} if ($USERS{$user});
- my $userObj = new RT::User($RT::SystemUser);
- $userObj->LoadOrCreateByEmail($user);
- $USERS{$user} = $userObj->Id;
- return $USERS{$user};
+ my ($user) = @_;
+ return $RT::Nobody->Id unless $user;
+ return $E{Users}{$user} if $E{Users}{$user};
+ my $userObj = new RT::User($RT::SystemUser);
+ $userObj->LoadOrCreateByEmail($user);
+ return $E{Users}{$user} = $userObj->Id || $RT::Nobody->Id;
}
-sub ConvertTicket {
-
- my $id = shift;
- return $TICKETS{$id} if ($TICKETS{$id});
- return undef unless ($id);
-
- my $ticket = $tickets->{$id};
- return undef unless (defined($ticket));
-
- foreach my $key (keys %$ticket) {
- $ticket->{$key} = undef if (ref($ticket->{$key}));
- }
-
- my $ticketObj = new RT::Ticket($RT::SystemUser);
-
- $ticket->{'Owner'} = ConvertUser($ticket->{'Owner'});
- $ticket->{'Creator'} = ConvertUser($ticket->{'Creator'});
- $ticket->{'LastUpdatedBy'} = ConvertUser($ticket->{'LastUpdatedBy'});
-
- if ($ticket->{'Requestor'}) {
- my $watchers = $ticket->{'Requestor'};
- my @trq = split(/, /, $watchers);
- $ticket->{'Requestor'} = \@trq;
- }
- if ($ticket->{'Cc'}) {
- my $watchers = $ticket->{'Cc'};
- my @tcc = split(/, /, $watchers);
- $ticket->{'Cc'} = \@tcc;
- }
- if ($ticket->{'AdminCc'}) {
- my $watchers = $ticket->{'AdminCc'};
- my @tacc = split(/, /, $watchers);
- $ticket->{'AdminCc'} = \@tacc;
- }
-
- my $eid = $ticket->{'EffectiveId'};
- $ticket->{'EffectiveId'} = '0';
-
- my ($newid, $msg) = $ticketObj->Import( %$ticket );
-
- unless ($newid) {
- print STDERR "Failed to create Ticket $id!!!\n";
- return undef;
- }
-
- print "Created Ticket # $id : as # $newid\n";
- $| = 1;
-
- $ticketObj->SetEffectiveId(ConvertTicket($eid)) if ($eid != $id);
- $ticketObj->{'_AccessibleCache'}{Created} = { 'read' => 1, 'write' => 1, 'auto' => 0 };
- $ticketObj->{'_AccessibleCache'}{Creator} = { 'read' => 1, 'write' => 1, 'auto' => 0 };
- $ticketObj->{'_AccessibleCache'}{LastUpdated} = { 'read' => 1, 'write' => 1, 'auto' => 0 };
- $ticketObj->{'_AccessibleCache'}{LastUpdatedBy} = { 'read' => 1, 'write' => 1, 'auto' => 0 };
- $ticketObj->SetCreated($ticket->{'Created'});
- $ticketObj->SetCreator($ticket->{'Creator'});
- $ticketObj->SetLastUpdated($ticket->{'LastUpdated'});
- $ticketObj->SetLastUpdatedBy($ticket->{'LastUpdatedBy'});
-
- $ticketObj->AddCustomFieldValue(Field => $cf,
- Value => "[$rtname #$id]" );
-
- $TICKETS{$id} = $newid;
- return $newid;
+sub ConvertQueue {
+ my ($queue) = @_;
+ return $E{Queues}{$queue} if $E{Queues}{$queue};
+ my $queueObj = new RT::Queue($RT::SystemUser);
+ $queueObj->Load($queue);
+ return $E{Queues}{$queue} = $queueObj || ConvertQueue('General');
}
-sub ConvertTransaction {
-
- my $id = shift;
-
- return $TRANSACTIONS{$id} if ($TRANSACTIONS{$id});
-
- my $transaction = $transactions->{$id};
-
- my $transactionObj = new RT::Transaction($RT::SystemUser);
-
- foreach my $key (keys %$transaction) {
- $transaction->{$key} = undef if (ref($transaction->{$key}));
- }
-
- # We're cheating and only importing Ticket Transactions
- $transaction->{'ObjectId'} = ConvertTicket($transaction->{'ObjectId'});
- $transaction->{'Creator'} = ConvertUser($transaction->{'Creator'});
- return undef unless (defined($transaction->{'ObjectId'}));
-
- if (
- ($transaction->{'Type'} eq 'Owner') ||
- ($transaction->{'Type'} eq 'Requestor') ||
- ($transaction->{'Type'} eq 'Cc') ||
- ($transaction->{'Type'} eq 'AdminCc') )
- {
- $transaction->{'OldValue'} = ConvertUser($transaction->{'OldValue'});
- $transaction->{'NewValue'} = ConvertUser($transaction->{'NewValue'});
- }
-
- if (
- ($transaction->{'Type'} eq 'DependsOn') ||
- ($transaction->{'Type'} eq 'DependedOnBy') ||
- ($transaction->{'Type'} eq 'RefersTo') ||
- ($transaction->{'Type'} eq 'ReferredToBy') ||
- ($transaction->{'Type'} eq 'MemberOf') ||
- ($transaction->{'Type'} eq 'MergedInto') ||
- ($transaction->{'Type'} eq 'HasMember') )
- {
- $transaction->{'OldValue'} =ConvertTicket($transaction->{'OldValue'});
- $transaction->{'NewValue'} =ConvertTicket($transaction->{'NewValue'});
- }
-
- $transaction->{'ActivateScrips'} = 0;
-
- my ($newid, $msg) = $transactionObj->Create( %$transaction );
-
- unless ($newid) {
- print STDERR "Failed to create Transaction $id ($msg)!!!\n";
- return undef;
- }
-
- print "Created Transaction # $id : as # $newid\n";
- $| = 1;
- $transactionObj->{'_AccessibleCache'}{Created} = { 'read' => 1, 'write' => 1, 'auto' => 0 };
- $transactionObj->{'_AccessibleCache'}{Creator} = { 'read' => 1, 'write' => 1, 'auto' => 0 };
- $transactionObj->SetCreated($transaction->{'Created'});
- $transactionObj->SetCreator($transaction->{'Creator'});
-
- $TRANSACTIONS{$id} = $newid;
- return $newid;
+sub _ConvertItem {
+ my $type = shift;
+ my $item = shift;
+
+ my %T = (
+ Tickets => {
+ import => \&import_ticket,
+ children => 'Transactions',
+ },
+ Transactions => {
+ import => \&import_transaction,
+ children => 'Attachments',
+ parent_id => 'ObjectId',
+ },
+ Attachments => {
+ import => \&import_attachment,
+ parent_id => 'TransactionId',
+ },
+ Links => { import => \&import_link, }
+ );
+
+ die "Unknown type [$type]!" unless $T{$type};
+
+ my $old_id = $item->{id};
+ my $new_id = $E{$type}{$old_id} || $T{$type}{import}( $item, @_ );
+ if ($new_id) {
+ $E{$type}{$old_id} = $new_id;
+ print "Created $type #$old_id\n";
+ }
+ else {
+
+ # Get rid of the old id to try to create with a new id
+ delete $item->{id};
+ $new_id = $T{$type}{import}( $item, @_ );
+ $E{$type}{$old_id} = $new_id;
+ print "Created $type #$old_id as #$new_id\n";
+ }
+ unless ( $E{$type}{$old_id} ) {
+ print STDERR "Failed to create $type $old_id!!!\n";
+ return;
+ }
+
+ my $child_type = $T{$type}{children};
+ if ( $child_type and $item->{$child_type} ) {
+ my $parent_id = $T{$child_type}{parent_id};
+ foreach my $child_id (
+ sort { $a <=> $b }
+ keys %{ $item->{$child_type} }
+ )
+ {
+ my $child = $item->{$child_type}->{$child_id};
+ $child->{$parent_id} = $new_id if $parent_id;
+ _ConvertItem( $child_type, $child, $new_id );
+ }
+ }
+
+ return $new_id;
}
+sub ConvertTicket { _ConvertItem( 'Tickets', @_ ) }
+sub ConvertTransaction { _ConvertItem( 'Transactions', @_ ) }
+sub ConvertAttachment { _ConvertItem( 'Attachments', @_ ) }
+sub ConvertLink { _ConvertItem( 'Links', @_ ) }
+
+sub _pick_apart {
+ my ($item) = @_;
+
+ my %i;
+ foreach my $key ( keys %{$item} ) {
+ my $value = $item->{$key};
+ next unless $value;
+
+ $key = 'Requestor' if $key eq 'Requestors';
+
+ if ( $link_types{$key} ) {
+
+ # have to process these after all the tickets are created
+ queue_links($value);
+ next;
+ }
+ elsif ( ref $value ) {
+ next;
+ }
+ elsif ( $key eq 'Queue' ) {
+ $value = ConvertQueue($value);
+ }
+ elsif ( $user_types{$key} ) {
+ $value = [ grep {$_} map { ConvertUser($_) } split /\s*,\s*/,
+ $value ];
+ next unless @{$value};
+ if ( $key eq 'Owner'
+ or $key eq 'Creator'
+ or $key eq 'LastUpdatedBy'
+ or $key eq 'Take' )
+ {
+ $value = $value->[0];
+ }
+ }
+
+ $i{$key} = $value;
+ }
+
+ return %i;
+}
-sub ConvertAttachment {
- my $id = shift;
+sub import_ticket {
+ my ($ticket) = @_;
+
+ my %t = _pick_apart($ticket);
+ my $eid = $t{EffectiveId};
+ $t{EffectiveId} = 0;
+
+ my $ticketObj = new RT::Ticket($RT::SystemUser);
+ my ( $newid, $msg ) = $ticketObj->Import(%t) or return;
+ print $msg and return unless $newid;
+
+ # My exporter didnt export merged tickets so we dont need to do this
+ # But it may be required and I just dont know about it.
+ #$ticketObj->SetEffectiveId(ConvertTicket($eid)) if ($eid != $ticket->{id});
+
+ $ticketObj->{_AccessibleCache}{Created}
+ = { read => 1, write => 1, auto => 0 };
+ $ticketObj->{_AccessibleCache}{Creator}
+ = { read => 1, write => 1, auto => 0 };
+ $ticketObj->{_AccessibleCache}{LastUpdated}
+ = { read => 1, write => 1, auto => 0 };
+ $ticketObj->{_AccessibleCache}{LastUpdatedBy}
+ = { read => 1, write => 1, auto => 0 };
+ $ticketObj->SetCreated( $ticket->{Created} );
+ $ticketObj->SetCreator( $ticket->{Creator} );
+ $ticketObj->SetLastUpdated( $ticket->{LastUpdated} );
+ $ticketObj->SetLastUpdatedBy( $ticket->{LastUpdatedBy} );
+
+ $ticketObj->AddCustomFieldValue(
+ Field => $cf,
+ Value => "[$rtname #$ticket->{id}]"
+ );
+
+ foreach my $custom_field ( @{ $ticket->{CustomFields} } ) {
+ $ticketObj->AddCustomFieldValue(
+ Field => $custom_field->{Name},
+ Value => $custom_field->{Value},
+ );
+ }
+
+ return $newid;
+}
- return $ATTACHMENTS{$id} if ($ATTACHMENTS{$id});
- my $attachment = $attachments->{$id};
+sub import_transaction {
+ my ( $transaction, $ticket_id ) = @_;
+
+ my %t = _pick_apart( $transaction );
+
+ if ( $link_types{ $t{Type} } ) {
+ if ($ticket_id) { # If this is the first time through don't add
+ queue_link_txn($transaction);
+ return;
+ }
+ $t{OldValue} = $E{Tickets}{ $t{OldValue} };
+ $t{NewValue} = $E{Tickets}{ $t{NewValue} };
+ }
+
+ if ( $t{Type} eq 'Set' and $t{Field} eq 'Queue' ) {
+ $t{OldValue} = ConvertQueue( $t{OldValue} );
+ $t{NewValue} = ConvertQueue( $t{NewValue} );
+ }
+
+ if ( ( $t{Type} eq 'Set' and $user_types{ $t{Field} } )
+ or $user_types{ $t{Type} } )
+ {
+ $t{OldValue} = ConvertUser( $t{OldValue} );
+ $t{NewValue} = ConvertUser( $t{NewValue} );
+ }
+
+ if ( ( $t{Type} eq 'EmailRecord' ) ) {
+ $t{OldValue} = $E{Tickets}{ $t{OldValue} } if $t{OldValue};
+ $t{NewValue} = $E{Tickets}{ $t{NewValue} } if $t{NewValue};
+ }
+
+ $t{ActivateScrips} = 0;
+
+ my $transactionObj = new RT::Transaction($RT::SystemUser);
+ my ( $newid, $msg ) = $transactionObj->Create(%t);
+
+ unless ($newid) {
+ print $msg;
+ return;
+ }
+
+ foreach my $custom_field ( @{ $transaction->{CustomFields} } ) {
+ $transactionObj->AddCustomFieldValue(
+ Field => $custom_field->{Name},
+ Value => $custom_field->{Value},
+ );
+ }
+
+ $| = 1;
+ $transactionObj->{_AccessibleCache}{Created}
+ = { read => 1, write => 1, auto => 0 };
+ $transactionObj->{_AccessibleCache}{Creator}
+ = { read => 1, write => 1, auto => 0 };
+ $transactionObj->SetCreated( $t{Created} );
+ $transactionObj->SetCreator( $t{Creator} );
+
+ return $newid;
+}
- foreach my $key (keys %$attachment) {
- $attachment->{$key} = undef if (ref($attachment->{$key}));
- }
+sub import_attachment {
+ my ($attachment) = @_;
- if ($attachment->{'Parent'}) {
- my $parent = $attachment->{'Parent'} ;
- $attachment->{'Parent'} = ConvertAttachment($parent);
- }
+ my %a = _pick_apart( $attachment );
+ delete $a{Owner};
- my $attachObj = new RT::Attachment($RT::SystemUser);
+ if ( $a{Parent} ) {
- $attachment->{'Creator'} = ConvertUser($attachment->{'Creator'});
+ # I guess we just have to hope this exists
+ my $parent = $a{Parent};
+ $a{Parent} = $E{Attachments}{$parent};
+ }
- $attachment->{'TransactionId'} =
- ConvertTransaction($attachment->{'TransactionId'});
- return undef unless (defined ($attachment->{'TransactionId'}));
+ if ( $a{Content} ) {
+ Encode::_utf8_off( $a{Content} );
+ $a{Content} = decode_base64( $a{Content} );
+ }
+ else { $a{Content} = '' }
- Encode::_utf8_off($attachment->{'Content'});
- $attachment->{'Content'} = decode_base64($attachment->{'Content'});
+ my $attachObj = new RT::Attachment($RT::SystemUser);
+ my ( $newid, $msg ) = $attachObj->Import(%a);
+ print $msg and return unless $newid;
- my ($newid, $msg) = $attachObj->Import( %$attachment );
+ $attachObj->{_AccessibleCache}{Created}
+ = { read => 1, write => 1, auto => 0 };
+ $attachObj->{_AccessibleCache}{Creator}
+ = { read => 1, write => 1, auto => 0 };
+ $attachObj->SetCreated( $a{Created} );
+ $attachObj->SetCreator( $a{Creator} );
- unless ($newid) {
- print STDERR "Failed to create Attachment $id ($msg)!!!\n";
- return undef;
- }
+ return $newid;
+}
- print "Created Attachment # $id : as # $newid\n";
- $| = 1;
- $attachObj->{'_AccessibleCache'}{Created} = { 'read' => 1, 'write' => 1, 'auto' => 0 };
- $attachObj->{'_AccessibleCache'}{Creator} = { 'read' => 1, 'write' => 1, 'auto' => 0 };
- $attachObj->SetCreated($attachment->{'Created'});
- $attachObj->SetCreator($attachment->{'Creator'});
- $ATTACHMENTS{$id} = $newid;
- return $newid;
+sub import_link {
+ my ($link) = @_;
+
+ my $base = $link->{Base};
+ $base =~ /([0-9]*)$/;
+ $base = $1;
+ my $target = $link->{Target};
+ $target =~ /([0-9]*)$/;
+ $target = $1;
+
+ my $linkObj = new RT::Link($RT::SystemUser);
+ my $newid = $linkObj->Create(
+ Base => $E{Tickets}{$base},
+ Target => $E{Tickets}{$target},
+ Type => $link->{Type}
+ );
+
+ return unless $newid;
+
+ $linkObj->{_AccessibleCache}{Created}
+ = { read => 1, write => 1, auto => 0 };
+ $linkObj->{_AccessibleCache}{Creator}
+ = { read => 1, write => 1, auto => 0 };
+ $linkObj->{_AccessibleCache}{LastUpdated}
+ = { read => 1, write => 1, auto => 0 };
+ $linkObj->{_AccessibleCache}{LastUpdatedBy}
+ = { read => 1, write => 1, auto => 0 };
+ $linkObj->SetCreated( $link->{Created} );
+ $linkObj->SetCreator( ConvertUser( $link->{Creator} ) );
+ $linkObj->SetLastUpdated( $link->{LastUpdated} );
+ $linkObj->SetLastUpdatedBy( $link->{LastUpdatedBy} );
+
+ return $newid;
}
-sub ConvertLink {
- my $id = shift;
-
- return $LINKS{$id} if ($LINKS{$id});
-
- my $link = $links->{$id};
- my $linkObj = new RT::Link($RT::SystemUser);
-
- my $base = $link->{'Base'};
- $base =~ /([0-9]*)$/;
- $base = $1;
- my $target = $link->{'Target'};
- $target =~ /([0-9]*)$/;
- $target = $1;
-
- my $newid = $linkObj->Create(
- Base => ConvertTicket($base),
- Target => ConvertTicket($target),
- Type => $link->{'Type'}
- );
-
- if ($newid == 0) {
- print STDERR "Failed to create Link $id!!!\n";
- return undef
- }
-
- print "Created Link # $id : as # $newid\n";
- $| = 1;
- $LINKS{$id} = $newid;
- $linkObj->{'_AccessibleCache'}{Created} = { 'read' => 1, 'write' => 1, 'auto' => 0 };
- $linkObj->{'_AccessibleCache'}{Creator} = { 'read' => 1, 'write' => 1, 'auto' => 0 };
- $linkObj->{'_AccessibleCache'}{LastUpdated} = { 'read' => 1, 'write' => 1, 'auto' => 0 };
- $linkObj->{'_AccessibleCache'}{LastUpdatedBy} = { 'read' => 1, 'write' => 1, 'auto' => 0 };
- $linkObj->SetCreated($link->{'Created'});
- $linkObj->SetCreator(ConvertUser($link->{'Creator'}));
- $linkObj->SetLastUpdated($link->{'LastUpdated'});
- $linkObj->SetLastUpdatedBy($link->{'LastUpdatedBy'});
-
- return $newid;
+{
+ my @link_transactions;
+ my @links;
-}
+ sub queue_link_txn { push @link_transactions, @_ }
-foreach (sort {$a <=> $b} keys %$tickets) {
- ConvertTicket($_);
-}
+ sub queue_links {
+ push @links, grep { ref $_ eq 'HASH' and $_->{id} } @_;
+ }
-foreach (sort {$a <=> $b} keys %$transactions ) {
- next unless ($transactions->{$_}->{'ObjectType'} eq 'RT::Ticket');
- ConvertTransaction($_);
-}
+ sub process_queued_links {
+ while ( my $txn = shift @link_transactions ) {
+ ConvertTransaction($txn);
+ }
-foreach (sort {$a <=> $b} keys %$attachments ) {
- ConvertAttachment($_);
+ while ( my $link = shift @links ) {
+ ConvertLink($link);
+ }
+ }
}
-foreach (sort {$a <=> $b} keys %$links ) {
- ConvertLink($_);
+opendir my $dh, $directory or die $!;
+my @files = map {"$directory/$_"}
+ sort grep { $_ =~ /Ticket_\d+\.xml$/i } readdir $dh;
+closedir $dh;
+
+foreach my $file (@files) {
+ warn "Converting $file\n";
+ my $ticket = XMLin(
+ $file,
+ SuppressEmpty => 1,
+ GroupTags => {
+ Transactions => 'Transaction',
+ Attachments => 'Attachment',
+ CustomFields => 'CustomField',
+ },
+ ForceArray => [qw( Transaction Attachment CustomField )],
+ KeyAttr => { Transaction => '+id', Attachment => '+id' },
+ );
+ ConvertTicket($ticket);
}
+
+process_queued_links();

No commit comments for this range

Something went wrong with that request. Please try again.