[Bps-public-commit] r11515 - in SVN-PropDB: . lib/Prophet/Sync/Source/RT
jesse at bestpractical.com
jesse at bestpractical.com
Fri Apr 4 20:51:09 EDT 2008
Author: jesse
Date: Fri Apr 4 20:51:06 2008
New Revision: 11515
Added:
SVN-PropDB/lib/Prophet/Sync/Source/RT/
SVN-PropDB/lib/Prophet/Sync/Source/RT/PullEncoder.pm
Modified:
SVN-PropDB/ (props changed)
SVN-PropDB/lib/Prophet/Sync/Source/RT.pm
Log:
r29204 at 68-246-40-124: jesse | 2008-04-04 14:50:29 -1000
* extract out the RT pull encoder
Modified: SVN-PropDB/lib/Prophet/Sync/Source/RT.pm
==============================================================================
--- SVN-PropDB/lib/Prophet/Sync/Source/RT.pm (original)
+++ SVN-PropDB/lib/Prophet/Sync/Source/RT.pm Fri Apr 4 20:51:06 2008
@@ -8,11 +8,13 @@
use RT::Client::REST ();
use RT::Client::REST::User ();
use RT::Client::REST::Ticket;
-
use Memoize;
use Prophet::Handle;
use Prophet::ChangeSet;
use Prophet::Conflict;
+use Prophet::Sync::Source::RT::PullEncoder;
+
+
__PACKAGE__->mk_accessors(qw/prophet_handle ressource is_resdb rt rt_url rt_queue rt_query/);
@@ -338,310 +340,23 @@
my @changesets;
my %tix;
+ my $recoder = Prophet::Sync::Source::RT::PullEncoder->new({ sync_source => $self } );
for my $id ( $self->_find_matching_tickets ) {
# XXX: _recode_transactions should ignore txn-id <= $first_rev
push @changesets,
@{
- $self->_recode_transactions(
+ $recoder->run(
ticket => $self->rt->show( type => 'ticket', id => $id ),
transactions => $self->_find_matching_transactions($id)
)
};
}
- my @results = map { $self->translate_prop_names($_) }
- sort { $a->original_sequence_no <=> $b->original_sequence_no } @changesets;
-
- return \@results;
-}
-
-sub _recode_transactions {
- my $self = shift;
- my %args = validate( @_, { ticket => 1, transactions => 1 } );
-
- my $ticket = $args{'ticket'};
-
- warn "Working on " . $ticket->{id};
- my $create_state = $ticket;
- map { $create_state->{$_} = $self->date_to_iso( $create_state->{$_} ) }
- qw(Created Resolved Told LastUpdated Starts Started);
-
- map { $create_state->{$_} =~ s/ minutes$// } qw(TimeWorked TimeLeft TimeEstimated);
- my @changesets;
- for my $txn ( sort { $b->{'id'} <=> $a->{'id'} } @{ $args{'transactions'} } ) {
- if ( my $sub = $self->can( '_recode_txn_' . $txn->{'Type'} ) ) {
- my $changeset = Prophet::ChangeSet->new(
- { original_source_uuid => $self->uuid,
- original_sequence_no => $txn->{'id'},
- }
- );
-
- if ( ( "ticket/" . $txn->{'Ticket'} ne $ticket->{id} ) && $txn->{'Type'} !~ /^(?:Comment|Correspond)$/ ) {
- warn "Skipping a data change from a merged ticket" . $txn->{'Ticket'} . ' vs ' . $ticket->{id};
- next;
- }
-
- $sub->(
- $self,
- ticket => $ticket,
- create_state => $create_state,
- txn => $txn,
- changeset => $changeset
- );
- unshift @changesets, $changeset unless $changeset->is_empty;
- } else {
- warn "not handling txn type $txn->{Type} for $txn->{id} (Ticket $args{ticket}{id}) yet";
- die YAML::Dump($txn);
- }
-
- }
-
- return \@changesets;
-
-}
-sub _recode_txn_CommentEmailRecord { return; }
-
-sub _recode_txn_EmailRecord { return; }
-sub _recode_txn_AddReminder { return; }
-sub _recode_txn_ResolveReminder { return; }
-sub _recode_txn_DeleteLink { }
-
-sub _recode_txn_Status {
- my $self = shift;
- my %args = validate( @_, { ticket => 1, txn => 1, create_state => 1, changeset => 1 } );
-
- $args{txn}->{'Type'} = 'Set';
- return $self->_recode_txn_Set(%args);
-}
-
-sub _recode_txn_Told {
- my $self = shift;
- my %args = validate( @_, { ticket => 1, txn => 1, create_state => 1, changeset => 1 } );
- $args{txn}->{'Type'} = 'Set';
- return $self->_recode_txn_Set(%args);
-}
-
-sub _recode_txn_Set {
- my $self = shift;
- my %args = validate( @_, { ticket => 1, txn => 1, create_state => 1, changeset => 1 } );
-
- my $change = Prophet::Change->new(
- { node_type => 'ticket',
- node_uuid => $self->uuid_for_url( $self->rt_url . "/ticket/" . $args{'create_state'}->{'id'} ),
- change_type => 'update_file'
- }
- );
-
- if ( $args{txn}->{Field} eq 'Queue' ) {
- my $current_queue = $args{ticket}->{'Queue'};
- my $user = $args{txn}->{Creator};
- if ( $args{txn}->{Description} =~ /Queue changed from (.*) to $current_queue by $user/ ) {
- $args{txn}->{OldValue} = $1;
- $args{txn}->{NewValue} = $current_queue;
- }
-
- } elsif ( $args{txn}->{Field} eq 'Owner' ) {
- $args{'txn'}->{NewValue} = $self->resolve_user_id_to( name => $args{'txn'}->{'NewValue'} ),
- $args{'txn'}->{OldValue}
- = $self->resolve_user_id_to( name => $args{'txn'}->{'OldValue'} )
-
- }
-
- $args{'changeset'}->add_change( { change => $change } );
- if ( $args{'create_state'}->{ $args{txn}->{Field} } eq $args{txn}->{'NewValue'} ) {
- $args{'create_state'}->{ $args{txn}->{Field} } = $args{txn}->{'OldValue'};
- } else {
- $args{'create_state'}->{ $args{txn}->{Field} } = $args{txn}->{'OldValue'};
- warn $args{'create_state'}->{ $args{txn}->{Field} } . " != "
- . $args{txn}->{'NewValue'} . "\n\n"
- . YAML::Dump( \%args );
- }
- $change->add_prop_change(
- name => $args{txn}->{'Field'},
- old => $args{txn}->{'OldValue'},
- new => $args{txn}->{'NewValue'}
-
- );
-
-}
-
-*_recode_txn_Steal = \&_recode_txn_Set;
-*_recode_txn_Take = \&_recode_txn_Set;
-*_recode_txn_Give = \&_recode_txn_Set;
-
-sub _recode_txn_Create {
- my $self = shift;
- my %args = validate( @_, { ticket => 1, txn => 1, create_state => 1, changeset => 1 } );
-
- my $change = Prophet::Change->new(
- { node_type => 'ticket',
- node_uuid => $self->uuid_for_url( $self->rt_url . "/ticket/" . $args{'create_state'}->{'id'} ),
- change_type => 'add_file'
- }
- );
-
- $args{'create_state'}->{'id'} =~ s/^ticket\///g;
- $args{'create_state'}->{ $self->uuid . '-id' } = delete $args{'create_state'}->{'id'};
-
- $args{'changeset'}->add_change( { change => $change } );
- for my $name ( keys %{ $args{'create_state'} } ) {
-
- $change->add_prop_change(
- name => $name,
- old => undef,
- new => $args{'create_state'}->{$name},
- );
-
- }
- $self->_recode_content_update(%args); # add the create content txn as a seperate change in this changeset
+ return [ sort { $a->original_sequence_no <=> $b->original_sequence_no } @changesets];
}
-sub _recode_txn_AddLink {
- my $self = shift;
- my %args = validate( @_, { ticket => 1, txn => 1, create_state => 1, changeset => 1 } );
- my $new_state = $args{'create_state'}->{ $args{'txn'}->{'Field'} };
- $args{'create_state'}->{ $args{'txn'}->{'Field'} } = $self->warp_list_to_old_value(
- $args{'create_state'}->{ $args{'txn'}->{'Field'} },
- $args{'txn'}->{'NewValue'},
- $args{'txn'}->{'OldValue'}
- );
-
- my $change = Prophet::Change->new(
- { node_type => 'ticket',
- node_uuid => $self->uuid_for_url( $self->rt_url . "/ticket/" . $args{'create_state'}->{'id'} ),
- change_type => 'update_file'
- }
- );
- $args{'changeset'}->add_change( { change => $change } );
- $change->add_prop_change(
- name => $args{'txn'}->{'Field'},
- old => $args{'create_state'}->{ $args{'txn'}->{'Field'} },
- new => $new_state
- );
-
-}
-
-sub _recode_content_update {
- my $self = shift;
- my %args = validate( @_, { ticket => 1, txn => 1, create_state => 1, changeset => 1 } );
- my $change = Prophet::Change->new(
- { node_type => 'comment',
- node_uuid => $self->uuid_for_url( $self->rt_url . "/transaction/" . $args{'txn'}->{'id'} ),
- change_type => 'add_file'
- }
- );
- $change->add_prop_change(
- name => 'type',
- old => undef,
- new => $args{'txn'}->{'Type'}
- );
-
- $change->add_prop_change(
- name => 'creator',
- old => undef,
- new => $args{'txn'}->{'Creator'}
- );
- $change->add_prop_change(
- name => 'content',
- old => undef,
- new => $args{'txn'}->{'Content'}
- );
- $change->add_prop_change(
- name => 'ticket',
- old => undef,
- new => $args{ticket}->{uuid},
- );
- $args{'changeset'}->add_change( { change => $change } );
-}
-
-*_recode_txn_Comment = \&_recode_content_update;
-*_recode_txn_Correspond = \&_recode_content_update;
-
-sub _recode_txn_AddWatcher {
- my $self = shift;
- my %args = validate( @_, { ticket => 1, txn => 1, create_state => 1, changeset => 1 } );
-
- my $new_state = $args{'create_state'}->{ $args{'txn'}->{'Field'} };
-
- $args{'create_state'}->{ $args{'txn'}->{'Field'} } = $self->warp_list_to_old_value(
- $args{'create_state'}->{ $args{'txn'}->{'Field'} },
-
- $self->resolve_user_id_to( email => $args{'txn'}->{'NewValue'} ),
- $self->resolve_user_id_to( email => $args{'txn'}->{'OldValue'} )
-
- );
-
- my $change = Prophet::Change->new(
- { node_type => 'ticket',
- node_uuid => $self->uuid_for_url( $self->rt_url . "/ticket/" . $args{'create_state'}->{'id'} ),
- change_type => 'update_file'
- }
- );
- $args{'changeset'}->add_change( { change => $change } );
- $change->add_prop_change(
- name => $args{'txn'}->{'Field'},
- old => $args{'create_state'}->{ $args{'txn'}->{'Field'} },
- new => $new_state
- );
-
-}
-
-*_recode_txn_DelWatcher = \&_recode_txn_AddWatcher;
-
-sub _recode_txn_CustomField {
- my $self = shift;
- my %args = validate( @_, { ticket => 1, txn => 1, create_state => 1, changeset => 1 } );
-
- my $new = $args{'txn'}->{'NewValue'};
- my $old = $args{'txn'}->{'OldValue'};
- my $name;
- if ( $args{'txn'}->{'Description'} =~ /^(.*) $new added by/ ) {
- $name = $1;
-
- } elsif ( $args{'txn'}->{'Description'} =~ /^(.*) $old delete by/ ) {
- $name = $1;
- } else {
- die "Uh. what to do with txn descriotion " . $args{'txn'}->{'Description'};
- }
-
- $args{'txn'}->{'Field'} = "CF-" . $name;
-
- my $new_state = $args{'create_state'}->{ $args{'txn'}->{'Field'} };
- $args{'create_state'}->{ $args{'txn'}->{'Field'} } = $self->warp_list_to_old_value(
- $args{'create_state'}->{ $args{'txn'}->{'Field'} },
- $args{'txn'}->{'NewValue'},
- $args{'txn'}->{'OldValue'}
- );
-
- my $change = Prophet::Change->new(
- { node_type => 'ticket',
- node_uuid => $self->uuid_for_url( $self->url . "/ticket/" . $args{'create_state'}->{'id'} ),
- change_type => 'update_file'
- }
- );
-
- $args{'changeset'}->add_change( { change => $change } );
- $change->add_prop_change(
- name => $args{'txn'}->{'Field'},
- old => $args{'create_state'}->{ $args{'txn'}->{'Field'} },
- new => $new_state
- );
-}
-
-sub resolve_user_id_to {
- my $self = shift;
- my $attr = shift;
- my $id = shift;
- return undef unless ($id);
-
- my $user = RT::Client::REST::User->new( rt => $self->rt, id => $id )->retrieve;
- return $attr eq 'name' ? $user->name : $user->email_address;
-
-}
-
-memoize 'resolve_user_id_to';
sub _find_matching_tickets {
my $self = shift;
@@ -686,107 +401,5 @@
return $cache->get( $self->uuid . '-' . $source_uuid ) || 0;
}
-sub _integration {
- my ( $self, $source_uuid, $source_seq ) = @_;
-
- my $cache = App::Cache->new( { ttl => 60 * 60 } ); # la la la
- return $cache->set( $self->uuid . '-' . $source_uuid, $source_seq );
-}
-
-sub warp_list_to_old_value {
- my $self = shift;
- my $ticket_value = shift || '';
- my $add = shift;
- my $del = shift;
-
- my @new = split( /\s*,\s*/, $ticket_value );
- my @old = grep { $_ ne $add } @new, $del;
- return join( ", ", @old );
-}
-
-our $MONNUM = {
- Jan => 1,
- Feb => 2,
- Mar => 3,
- Apr => 4,
- May => 5,
- Jun => 6,
- Jul => 7,
- Aug => 8,
- Sep => 9,
- Oct => 10,
- Nov => 11,
- Dec => 12
-};
-
-use DateTime::Format::HTTP;
-
-sub date_to_iso {
- my $self = shift;
- my $date = shift;
-
- return '' if $date eq 'Not set';
- my $t = DateTime::Format::HTTP->parse_datetime($date);
- return $t->ymd . " " . $t->hms;
-}
-
-our %PROP_MAP = (
- subject => 'summary',
- status => 'status',
- owner => 'owner',
- initialpriority => '_delete',
- finalpriority => '_delete',
- told => '_delete',
- requestors => 'reported_by',
- admincc => 'admin_cc',
- refersto => 'refers_to',
- referredtoby => 'referred_to_by',
- dependson => 'depends_on',
- dependedonby => 'depended_on_by',
- hasmember => 'members',
- memberof => 'member_of',
- priority => 'priority_integer',
- resolved => 'completed',
- due => 'due',
- creator => 'creator',
- timeworked => 'time_worked',
- timeleft => 'time_left',
- lastupdated => '_delete',
- created => '_delete', # we should be porting the create date as a metaproperty
-
-);
-
-sub translate_prop_names {
- my $self = shift;
- my $changeset = shift;
-
- for my $change ( $changeset->changes ) {
- next unless $change->node_type eq 'ticket';
-
- my @new_props;
- for my $prop ( $change->prop_changes ) {
- next if ( ( $PROP_MAP{ lc( $prop->name ) } || '' ) eq '_delete' );
- $prop->name( $PROP_MAP{ lc( $prop->name ) } ) if $PROP_MAP{ lc( $prop->name ) };
-
- if ( $prop->name eq 'id' ) {
- $prop->old_value( $prop->old_value . '@' . $changeset->original_source_uuid )
- if ( $prop->old_value || '' ) =~ /^\d+$/;
- $prop->old_value( $prop->new_value . '@' . $changeset->original_source_uuid )
- if ( $prop->new_value || '' ) =~ /^\d+$/;
-
- }
-
- if ( $prop->name =~ /^cf-(.*)$/ ) {
- $prop->name( 'custom-' . $1 );
- }
-
- push @new_props, $prop;
-
- }
- $change->prop_changes( \@new_props );
-
- }
- return $changeset;
-}
1;
Added: SVN-PropDB/lib/Prophet/Sync/Source/RT/PullEncoder.pm
==============================================================================
--- (empty file)
+++ SVN-PropDB/lib/Prophet/Sync/Source/RT/PullEncoder.pm Fri Apr 4 20:51:06 2008
@@ -0,0 +1,409 @@
+use warnings;
+use strict;
+
+package Prophet::Sync::Source::RT::PullEncoder;
+use base qw/Prophet::Sync::Source/;
+use Params::Validate qw(:all);
+use UNIVERSAL::require;
+use RT::Client::REST ();
+use RT::Client::REST::User ();
+use RT::Client::REST::Ticket;
+
+use Memoize;
+
+__PACKAGE__->mk_accessors(qw/sync_source/);
+
+our $DEBUG = $Prophet::Handle::DEBUG;
+
+
+
+
+
+sub run {
+ my $self = shift;
+ my %args = validate( @_, { ticket => 1, transactions => 1} );
+
+ my $ticket = $args{'ticket'};
+
+ warn "Working on " . $ticket->{id};
+ my $create_state = $ticket;
+ map { $create_state->{$_} = $self->date_to_iso( $create_state->{$_} ) }
+ qw(Created Resolved Told LastUpdated Starts Started);
+
+ map { $create_state->{$_} =~ s/ minutes$// } qw(TimeWorked TimeLeft TimeEstimated);
+ my @changesets;
+ for my $txn ( sort { $b->{'id'} <=> $a->{'id'} } @{ $args{'transactions'} } ) {
+ if ( my $sub = $self->can( '_recode_txn_' . $txn->{'Type'} ) ) {
+ my $changeset = Prophet::ChangeSet->new(
+ { original_source_uuid => $self->sync_source->uuid,
+ original_sequence_no => $txn->{'id'},
+ }
+ );
+
+ if ( ( "ticket/" . $txn->{'Ticket'} ne $ticket->{id} ) && $txn->{'Type'} !~ /^(?:Comment|Correspond)$/ ) {
+ warn "Skipping a data change from a merged ticket" . $txn->{'Ticket'} . ' vs ' . $ticket->{id};
+ next;
+ }
+
+ $sub->(
+ $self,
+ ticket => $ticket,
+ create_state => $create_state,
+ txn => $txn,
+ changeset => $changeset
+ );
+ $self->translate_prop_names($changeset);
+
+ unshift @changesets, $changeset unless $changeset->is_empty;
+ } else {
+ warn "not handling txn type $txn->{Type} for $txn->{id} (Ticket $args{ticket}{id}) yet";
+ die YAML::Dump($txn);
+ }
+
+
+ }
+ return \@changesets;
+}
+
+sub _recode_txn_CommentEmailRecord { return; }
+
+sub _recode_txn_EmailRecord { return; }
+sub _recode_txn_AddReminder { return; }
+sub _recode_txn_ResolveReminder { return; }
+sub _recode_txn_DeleteLink { }
+
+sub _recode_txn_Status {
+ my $self = shift;
+ my %args = validate( @_, { ticket => 1, txn => 1, create_state => 1, changeset => 1 } );
+
+ $args{txn}->{'Type'} = 'Set';
+ return $self->_recode_txn_Set(%args);
+}
+
+sub _recode_txn_Told {
+ my $self = shift;
+ my %args = validate( @_, { ticket => 1, txn => 1, create_state => 1, changeset => 1 } );
+ $args{txn}->{'Type'} = 'Set';
+ return $self->_recode_txn_Set(%args);
+}
+
+sub _recode_txn_Set {
+ my $self = shift;
+ my %args = validate( @_, { ticket => 1, txn => 1, create_state => 1, changeset => 1 } );
+
+ my $change = Prophet::Change->new(
+ { node_type => 'ticket',
+ node_uuid => $self->sync_source->uuid_for_url( $self->sync_source->rt_url . "/ticket/" . $args{'create_state'}->{'id'} ),
+ change_type => 'update_file'
+ }
+ );
+
+ if ( $args{txn}->{Field} eq 'Queue' ) {
+ my $current_queue = $args{ticket}->{'Queue'};
+ my $user = $args{txn}->{Creator};
+ if ( $args{txn}->{Description} =~ /Queue changed from (.*) to $current_queue by $user/ ) {
+ $args{txn}->{OldValue} = $1;
+ $args{txn}->{NewValue} = $current_queue;
+ }
+
+ } elsif ( $args{txn}->{Field} eq 'Owner' ) {
+ $args{'txn'}->{NewValue} = $self->resolve_user_id_to( name => $args{'txn'}->{'NewValue'} ),
+ $args{'txn'}->{OldValue}
+ = $self->resolve_user_id_to( name => $args{'txn'}->{'OldValue'} )
+
+ }
+
+ $args{'changeset'}->add_change( { change => $change } );
+ if ( $args{'create_state'}->{ $args{txn}->{Field} } eq $args{txn}->{'NewValue'} ) {
+ $args{'create_state'}->{ $args{txn}->{Field} } = $args{txn}->{'OldValue'};
+ } else {
+ $args{'create_state'}->{ $args{txn}->{Field} } = $args{txn}->{'OldValue'};
+ warn $args{'create_state'}->{ $args{txn}->{Field} } . " != "
+ . $args{txn}->{'NewValue'} . "\n\n"
+ . YAML::Dump( \%args );
+ }
+ $change->add_prop_change(
+ name => $args{txn}->{'Field'},
+ old => $args{txn}->{'OldValue'},
+ new => $args{txn}->{'NewValue'}
+
+ );
+
+}
+
+*_recode_txn_Steal = \&_recode_txn_Set;
+*_recode_txn_Take = \&_recode_txn_Set;
+*_recode_txn_Give = \&_recode_txn_Set;
+
+sub _recode_txn_Create {
+ my $self = shift;
+ my %args = validate( @_, { ticket => 1, txn => 1, create_state => 1, changeset => 1 } );
+
+ my $change = Prophet::Change->new(
+ { node_type => 'ticket',
+ node_uuid => $self->sync_source->uuid_for_url( $self->sync_source->rt_url . "/ticket/" . $args{'create_state'}->{'id'} ),
+ change_type => 'add_file'
+ }
+ );
+
+ $args{'create_state'}->{'id'} =~ s/^ticket\///g;
+ $args{'create_state'}->{ $self->sync_source->uuid . '-id' } = delete $args{'create_state'}->{'id'};
+
+ $args{'changeset'}->add_change( { change => $change } );
+ for my $name ( keys %{ $args{'create_state'} } ) {
+
+ $change->add_prop_change(
+ name => $name,
+ old => undef,
+ new => $args{'create_state'}->{$name},
+ );
+
+ }
+
+ $self->_recode_content_update(%args); # add the create content txn as a seperate change in this changeset
+
+}
+
+sub _recode_txn_AddLink {
+ my $self = shift;
+ my %args = validate( @_, { ticket => 1, txn => 1, create_state => 1, changeset => 1 } );
+ my $new_state = $args{'create_state'}->{ $args{'txn'}->{'Field'} };
+ $args{'create_state'}->{ $args{'txn'}->{'Field'} } = $self->warp_list_to_old_value(
+ $args{'create_state'}->{ $args{'txn'}->{'Field'} },
+ $args{'txn'}->{'NewValue'},
+ $args{'txn'}->{'OldValue'}
+ );
+
+ my $change = Prophet::Change->new(
+ { node_type => 'ticket',
+ node_uuid => $self->sync_source->uuid_for_url( $self->sync_source->rt_url . "/ticket/" . $args{'create_state'}->{'id'} ),
+ change_type => 'update_file'
+ }
+ );
+ $args{'changeset'}->add_change( { change => $change } );
+ $change->add_prop_change(
+ name => $args{'txn'}->{'Field'},
+ old => $args{'create_state'}->{ $args{'txn'}->{'Field'} },
+ new => $new_state
+ );
+
+}
+
+sub _recode_content_update {
+ my $self = shift;
+ my %args = validate( @_, { ticket => 1, txn => 1, create_state => 1, changeset => 1 } );
+ my $change = Prophet::Change->new(
+ { node_type => 'comment',
+ node_uuid => $self->sync_source->uuid_for_url( $self->sync_source->rt_url . "/transaction/" . $args{'txn'}->{'id'} ),
+ change_type => 'add_file'
+ }
+ );
+ $change->add_prop_change(
+ name => 'type',
+ old => undef,
+ new => $args{'txn'}->{'Type'}
+ );
+
+ $change->add_prop_change(
+ name => 'creator',
+ old => undef,
+ new => $args{'txn'}->{'Creator'}
+ );
+ $change->add_prop_change(
+ name => 'content',
+ old => undef,
+ new => $args{'txn'}->{'Content'}
+ );
+ $change->add_prop_change(
+ name => 'ticket',
+ old => undef,
+ new => $args{ticket}->{uuid},
+ );
+ $args{'changeset'}->add_change( { change => $change } );
+}
+
+*_recode_txn_Comment = \&_recode_content_update;
+*_recode_txn_Correspond = \&_recode_content_update;
+
+sub _recode_txn_AddWatcher {
+ my $self = shift;
+ my %args = validate( @_, { ticket => 1, txn => 1, create_state => 1, changeset => 1 } );
+
+ my $new_state = $args{'create_state'}->{ $args{'txn'}->{'Field'} };
+
+ $args{'create_state'}->{ $args{'txn'}->{'Field'} } = $self->warp_list_to_old_value(
+ $args{'create_state'}->{ $args{'txn'}->{'Field'} },
+
+ $self->resolve_user_id_to( email => $args{'txn'}->{'NewValue'} ),
+ $self->resolve_user_id_to( email => $args{'txn'}->{'OldValue'} )
+
+ );
+
+ my $change = Prophet::Change->new(
+ { node_type => 'ticket',
+ node_uuid => $self->sync_source->uuid_for_url( $self->sync_source->rt_url . "/ticket/" . $args{'create_state'}->{'id'} ),
+ change_type => 'update_file'
+ }
+ );
+ $args{'changeset'}->add_change( { change => $change } );
+ $change->add_prop_change(
+ name => $args{'txn'}->{'Field'},
+ old => $args{'create_state'}->{ $args{'txn'}->{'Field'} },
+ new => $new_state
+ );
+
+}
+
+*_recode_txn_DelWatcher = \&_recode_txn_AddWatcher;
+
+sub _recode_txn_CustomField {
+ my $self = shift;
+ my %args = validate( @_, { ticket => 1, txn => 1, create_state => 1, changeset => 1 } );
+
+ my $new = $args{'txn'}->{'NewValue'};
+ my $old = $args{'txn'}->{'OldValue'};
+ my $name;
+ if ( $args{'txn'}->{'Description'} =~ /^(.*) $new added by/ ) {
+ $name = $1;
+
+ } elsif ( $args{'txn'}->{'Description'} =~ /^(.*) $old delete by/ ) {
+ $name = $1;
+ } else {
+ die "Uh. what to do with txn descriotion " . $args{'txn'}->{'Description'};
+ }
+
+ $args{'txn'}->{'Field'} = "CF-" . $name;
+
+ my $new_state = $args{'create_state'}->{ $args{'txn'}->{'Field'} };
+ $args{'create_state'}->{ $args{'txn'}->{'Field'} } = $self->warp_list_to_old_value(
+ $args{'create_state'}->{ $args{'txn'}->{'Field'} },
+ $args{'txn'}->{'NewValue'},
+ $args{'txn'}->{'OldValue'}
+ );
+
+ my $change = Prophet::Change->new(
+ { node_type => 'ticket',
+ node_uuid => $self->sync_source->uuid_for_url( $self->url . "/ticket/" . $args{'create_state'}->{'id'} ),
+ change_type => 'update_file'
+ }
+ );
+
+ $args{'changeset'}->add_change( { change => $change } );
+ $change->add_prop_change(
+ name => $args{'txn'}->{'Field'},
+ old => $args{'create_state'}->{ $args{'txn'}->{'Field'} },
+ new => $new_state
+ );
+}
+
+sub resolve_user_id_to {
+ my $self = shift;
+ my $attr = shift;
+ my $id = shift;
+ return undef unless ($id);
+
+ my $user = RT::Client::REST::User->new( rt => $self->sync_source->rt, id => $id )->retrieve;
+ return $attr eq 'name' ? $user->name : $user->email_address;
+
+}
+
+memoize 'resolve_user_id_to';
+
+
+sub warp_list_to_old_value {
+ my $self = shift;
+ my $ticket_value = shift || '';
+ my $add = shift;
+ my $del = shift;
+
+ my @new = split( /\s*,\s*/, $ticket_value );
+ my @old = grep { $_ ne $add } @new, $del;
+ return join( ", ", @old );
+}
+
+our $MONNUM = {
+ Jan => 1,
+ Feb => 2,
+ Mar => 3,
+ Apr => 4,
+ May => 5,
+ Jun => 6,
+ Jul => 7,
+ Aug => 8,
+ Sep => 9,
+ Oct => 10,
+ Nov => 11,
+ Dec => 12
+};
+
+use DateTime::Format::HTTP;
+
+sub date_to_iso {
+ my $self = shift;
+ my $date = shift;
+
+ return '' if $date eq 'Not set';
+ my $t = DateTime::Format::HTTP->parse_datetime($date);
+ return $t->ymd . " " . $t->hms;
+}
+
+our %PROP_MAP = (
+ subject => 'summary',
+ status => 'status',
+ owner => 'owner',
+ initialpriority => '_delete',
+ finalpriority => '_delete',
+ told => '_delete',
+ requestors => 'reported_by',
+ admincc => 'admin_cc',
+ refersto => 'refers_to',
+ referredtoby => 'referred_to_by',
+ dependson => 'depends_on',
+ dependedonby => 'depended_on_by',
+ hasmember => 'members',
+ memberof => 'member_of',
+ priority => 'priority_integer',
+ resolved => 'completed',
+ due => 'due',
+ creator => 'creator',
+ timeworked => 'time_worked',
+ timeleft => 'time_left',
+ lastupdated => '_delete',
+ created => '_delete', # we should be porting the create date as a metaproperty
+
+);
+
+sub translate_prop_names {
+ my $self = shift;
+ my $changeset = shift;
+
+ for my $change ( $changeset->changes ) {
+ next unless $change->node_type eq 'ticket';
+
+ my @new_props;
+ for my $prop ( $change->prop_changes ) {
+ next if ( ( $PROP_MAP{ lc( $prop->name ) } || '' ) eq '_delete' );
+ $prop->name( $PROP_MAP{ lc( $prop->name ) } ) if $PROP_MAP{ lc( $prop->name ) };
+
+ if ( $prop->name eq 'id' ) {
+ $prop->old_value( $prop->old_value . '@' . $changeset->original_source_uuid )
+ if ( $prop->old_value || '' ) =~ /^\d+$/;
+ $prop->old_value( $prop->new_value . '@' . $changeset->original_source_uuid )
+ if ( $prop->new_value || '' ) =~ /^\d+$/;
+
+ }
+
+ if ( $prop->name =~ /^cf-(.*)$/ ) {
+ $prop->name( 'custom-' . $1 );
+ }
+
+ push @new_props, $prop;
+
+ }
+ $change->prop_changes( \@new_props );
+
+ }
+ return $changeset;
+}
+
+1;
More information about the Bps-public-commit
mailing list