App-SD
view release on metacpan or search on metacpan
lib/App/SD/Replica/gcode/PullEncoder.pm view on Meta::CPAN
my $values = delete $updates->{labels};
for my $value (@$values) {
my $is_delete;
if ( $value =~ /^-(.*)$/ ) {
$is_delete = 1;
$value = $1;
}
my $name;
if ( $value =~ /(.*?)-(.*)/ ) {
$name = lc $1;
$value = $2;
}
else {
$name = 'labels';
}
$name = $PROP_MAP{$name} || $name;
$earlier_state{$name} =
$self->warp_list_to_old_value( $earlier_state{$name},
$is_delete ? ( undef, $value ) : ( $value, undef ) );
}
}
$txn->{pre_state} = {%earlier_state};
$pre_txn->{pre_state} = $txn->{post_state} if $pre_txn;
$pre_txn = $txn;
}
# XXX try our best to find historical info
# e.g.
# comemnt 3 has summary: "foo"
# comment 4 and 5 don't have summary changes
# comment 6 has summary: "bar"
# then we can set comment 4 and 5's summary to 'foo'
my @sorted = sort { $b->{'serial'} <=> $a->{'serial'} } @$transactions;
for ( my $i = 0 ; $i < @sorted ; $i++ ) {
for my $prop (qw(owner status summary)) {
if ( !$sorted[$i]->{post_state}{ $PROP_MAP{$prop} } ) {
( $sorted[$i]->{post_state}{ $PROP_MAP{$prop} } ) =
grep { $_ }
map { $_->{post_state}{ $PROP_MAP{$prop} } }
@sorted[ $i + 1 .. $#sorted ];
$sorted[$i]->{post_state}{ $PROP_MAP{$prop} } ||= '';
}
}
}
return \%earlier_state, $final_state;
}
=head2 find_matching_transactions { ticket => $id, starting_transaction => $num }
Returns a reference to an array of all transactions (as hashes) on ticket $id after transaction $num.
=cut
sub find_matching_transactions {
my $self = shift;
my %args = validate( @_, { ticket => 1, starting_transaction => 1 } );
my @raw_txns = @{ $args{ticket}->comments };
my @txns;
for my $txn ( sort { $a->sequence <=> $b->sequence } @raw_txns ) {
my $txn_date = $txn->date->epoch;
# Skip things we know we've already pulled
next if $txn_date < ( $args{'starting_transaction'} || 0 );
# Skip things we've pushed
next if (
$self->sync_source->foreign_transaction_originated_locally(
$txn_date, $args{'ticket'}->id
)
);
# ok. it didn't originate locally. we might want to integrate it
push @txns,
{
timestamp => $txn->date,
serial => $txn->sequence,
object => $txn,
};
}
$self->sync_source->log_debug('Done looking at pulled txns');
return \@txns;
}
sub transcode_create_txn {
my $self = shift;
my $txn = shift;
my $create_data = shift;
my $final_data = shift;
my $ticket_id = $final_data->{ $self->sync_source->uuid . '-id' };
my $ticket_uuid =
$self->sync_source->uuid_for_remote_id($ticket_id);
my $creator =
$self->resolve_user_id_to( email_address => $create_data->{reporter} );
my $created = $final_data->{created};
my $changeset = Prophet::ChangeSet->new(
{
original_source_uuid => $ticket_uuid,
original_sequence_no => 0,
creator => $creator,
created => $created,
}
);
my $change = Prophet::Change->new(
{
record_type => 'ticket',
record_uuid => $ticket_uuid,
change_type => 'add_file',
}
);
for my $prop ( keys %{ $txn->{post_state} } ) {
$change->add_prop_change(
lib/App/SD/Replica/gcode/PullEncoder.pm view on Meta::CPAN
$prop = lc $prop;
$change->add_prop_change(
name => $PROP_MAP{$prop} || $prop,
old => $txn_wrapper->{pre_state}->{$PROP_MAP{$prop}},
new => $txn_wrapper->{post_state}->{$PROP_MAP{$prop}}
);
}
$changeset->add_change( { change => $change } )
if $change->has_prop_changes;
$self->_include_change_comment( $changeset, $ticket_uuid, $txn );
return unless $changeset->has_changes;
return $changeset;
}
sub _include_change_comment {
my $self = shift;
my $changeset = shift;
my $ticket_uuid = shift;
my $txn = shift;
my $comment = $self->new_comment_creation_change();
if ( my $content = $txn->content ) {
if ( $content !~ /^\s*$/s ) {
$comment->add_prop_change(
name => 'created',
new => $txn->date->ymd . ' ' . $txn->date->hms,
);
$comment->add_prop_change(
name => 'creator',
new =>
$self->resolve_user_id_to( email_address => $txn->author ),
);
$comment->add_prop_change( name => 'content', new => $content );
$comment->add_prop_change(
name => 'content_type',
new => 'text/plain',
);
$comment->add_prop_change( name => 'ticket', new => $ticket_uuid, );
$changeset->add_change( { change => $comment } );
}
}
for my $att ( @{ $txn->attachments } ) {
$self->_recode_attachment_create(
ticket_uuid => $ticket_uuid,
txn => $txn,
changeset => $changeset,
attachment => $att,
);
}
}
sub _recode_attachment_create {
my $self = shift;
my %args =
validate( @_,
{ ticket_uuid => 1, txn => 1, changeset => 1, attachment => 1 } );
my $change = Prophet::Change->new(
{
record_type => 'attachment',
record_uuid => $self->sync_source->uuid_for_url(
$self->sync_source->remote_url
. "/attachment/"
. $args{'attachment'}->id,
),
change_type => 'add_file',
}
);
$change->add_prop_change(
name => 'content_type',
old => undef,
new => $args{'attachment'}->content_type,
);
$change->add_prop_change(
name => 'created',
old => undef,
new => $args{'txn'}->date->ymd . ' ' . $args{'txn'}->date->hms,
);
$change->add_prop_change(
name => 'creator',
old => undef,
new =>
$self->resolve_user_id_to( email_address => $args{'txn'}->author )
);
$change->add_prop_change(
name => 'content',
old => undef,
new => $args{'attachment'}->content,
);
$change->add_prop_change(
name => 'name',
old => undef,
new => $args{'attachment'}->name,
);
$change->add_prop_change(
name => 'ticket',
old => undef,
new => $args{ticket_uuid},
);
$args{'changeset'}->add_change( { change => $change } );
}
sub translate_prop_status {
my $self = shift;
my $status = shift;
return lc($status);
}
sub resolve_user_id_to {
my $self = shift;
my $to = shift;
my $id = shift;
return $id . '@gmail.com';
( run in 0.732 second using v1.01-cache-2.11-cpan-39bf76dae61 )