App-SD
view release on metacpan or search on metacpan
lib/App/SD/Replica/github/PullEncoder.pm view on Meta::CPAN
package App::SD::Replica::github::PullEncoder;
use Any::Moose;
extends 'App::SD::ForeignReplica::PullEncoder';
use Params::Validate qw(:all);
use Memoize;
use DateTime;
use App::SD::Util;
has sync_source => (
isa => 'App::SD::Replica::github',
is => 'rw',
);
my %PROP_MAP = %App::SD::Replica::github::PROP_MAP;
sub ticket_id {
my $self = shift;
return shift->{number};
}
=head2 translate_ticket_state
=cut
sub translate_ticket_state {
my $self = shift;
my $ticket = shift;
$ticket->{created_at} =
App::SD::Util::string_to_datetime($ticket->{created_at});
$ticket->{updated_at} =
App::SD::Util::string_to_datetime($ticket->{updated_at});
return $ticket;
}
=head2 find_matching_tickets QUERY
Returns a array of all tickets found matching your QUERY hash.
=cut
sub find_matching_tickets {
my $self = shift;
my %query = (@_);
my $last_changeset_seen_dt = $self->_only_pull_tickets_modified_after()
|| DateTime->from_epoch( epoch => 0 );
my $issue = $self->sync_source->github->issue;
my @updated = grep {
App::SD::Util::string_to_datetime($_->{updated_at}) > $last_changeset_seen_dt }
( @{ $issue->list('open') }, @{ $issue->list('closed') } );
return \@updated;
}
sub _only_pull_tickets_modified_after {
my $self = shift;
my $last_pull = $self->sync_source->upstream_last_modified_date();
return unless $last_pull;
my $before = App::SD::Util::string_to_datetime($last_pull);
$self->log_debug( "Failed to parse '" . $self->sync_source->upstream_last_modified_date() . "' as a timestamp. That means we have to sync ALL history") unless ($before);
return $before;
}
=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.
For GitHub, we can't get change history for tickets; we can only get comments.
=cut
sub find_matching_transactions {
my $self = shift;
my %args = validate( @_, { ticket => 1, starting_transaction => 1 } );
my @raw_txns =
@{ $self->sync_source->github->issue->comments( $args{ticket}->{number} ) };
for my $comment (@raw_txns) {
$comment->{updated_at} =
App::SD::Util::string_to_datetime( $comment->{updated_at} );
$comment->{created_at} =
App::SD::Util::string_to_datetime( $comment->{created_at} );
}
my @txns;
for my $txn ( sort { $a->{id} <=> $b->{id} } @raw_txns ) {
my $txn_date = $txn->{updated_at}->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'}->{number}
)
);
# ok. it didn't originate locally. we might want to integrate it
push @txns,
{
timestamp => $txn->{created_at},
serial => $txn->{id},
object => $txn,
};
}
# if the ticket itself hasn't been created, add it to the beginning
# of the list of transactions
my $ticket_created =
App::SD::Util::string_to_datetime( $args{ticket}->{created_at} );
if ( $ticket_created->epoch >= $args{'starting_transaction'} || 0 ) {
unshift @txns,
{
timestamp => $ticket_created,
serial => 0,
object => $args{ticket},
};
}
$self->sync_source->log_debug('Done looking at pulled txns');
return \@txns;
}
sub transcode_create_txn {
my $self = shift;
my $txn = shift;
my $ticket = $txn->{object};
my $ticket_uuid =
$self->sync_source->uuid_for_remote_id($ticket->{number});
my $creator =
$self->resolve_user_id_to( email_address => $ticket->{user} );
my $created = $txn->{timestamp};
my $changeset = Prophet::ChangeSet->new(
{
original_source_uuid => $ticket_uuid,
original_sequence_no => 0,
creator => $creator,
created => $created->ymd . " " . $created->hms
}
);
my $change = Prophet::Change->new(
{
record_type => 'ticket',
( run in 3.175 seconds using v1.01-cache-2.11-cpan-39bf76dae61 )