[Bps-public-commit] SD - A distributed issue tracker branch, master, updated. fb27f987c2e81797a6c31ac25ddfb729c29fa1c9
jesse
jesse at bestpractical.com
Thu Jan 22 00:15:26 EST 2009
The branch, master has been updated
via fb27f987c2e81797a6c31ac25ddfb729c29fa1c9 (commit)
via 4a3157df834f6bce64189376b70a4cab92adcfc6 (commit)
from 8fd157776766b24cf96a8eca4fde9882ea00c892 (commit)
Summary of changes:
lib/App/SD/Replica/trac.pm | 18 ++---
lib/App/SD/Replica/trac/PullEncoder.pm | 112 +++++++++++---------------------
lib/App/SD/Server/View.pm | 84 +++++++++++++++++++++--
3 files changed, 121 insertions(+), 93 deletions(-)
- Log -----------------------------------------------------------------
commit 4a3157df834f6bce64189376b70a4cab92adcfc6
Author: Jesse Vincent <jesse at bestpractical.com>
Date: Thu Jan 22 00:14:06 2009 -0500
Ticket list starting to shape up
diff --git a/lib/App/SD/Server/View.pm b/lib/App/SD/Server/View.pm
index d21aebe..7652c93 100644
--- a/lib/App/SD/Server/View.pm
+++ b/lib/App/SD/Server/View.pm
@@ -58,18 +58,28 @@ div.ticket_list ul li span {
}
table.tablesorter thead th {
- color: #1133AA;
+ color: #999;
+ background-color: #fff;
+}
+table.tablesorter thead tr .header {
+ background: none;
+ border-bottom: 1px solid #666;
}
-
table.tablesorter thead tr .headerSortDown,
table.tablesorter thead tr .headerSortUp,
table.tablesorter thead tr th:hover {
- background-color: #ccc;
+ text-decoration: underline;
+ background-color: #fff;
+ color: #666;
+}
+table.tablesorter thead tr th {
+ background-color: #fff;
}
+
th.headerSortUp,
th.headerSortDown {
- background: #ccc;
+ background: #fff;
}
ul.page-nav {
@@ -232,6 +242,63 @@ ul.comments li:nth-child(odd) {
background: #f5f5f5;
}
+table.tablesorter {
+ background: #fff;
+ border: none;
+}
+
+
+table.tablesorter {
+ width: auto;
+}
+
+table.tablesorter thead tr th, table.tablesorter tfoot tr th {
+ padding-right: 2em;
+}
+
+table.tablesorter tbody td {
+ color: #555;
+ font-weight: bold;
+ height: 4.5em;
+ padding-top: 2.5em;
+ margin-top: em;
+
+}
+
+table.tablesorter td.summary {
+ margin-top: 0em;
+ padding: 0;
+ font-weight: normal;
+ right:4em;
+ margin-top: 0.5em;
+ height: 1em;
+ left: 7.5em;
+ position: absolute;
+ padding-bottom: 1em;
+
+
+}
+
+table.tablesorter td.summary a, table.tablesorter td.id a {
+ font-size: 1.7em;
+ color: #700;
+ font-style: italic;
+ text-decoration: none;
+ font-family: serif;
+}
+
+table.tablesorter td.id {
+ padding-top: 1.5em;
+}
+table.tablesorter td.id a {
+ color: #aaa;
+}
+
+table.tablesorter td a:hover {
+ text-decoration: underline;
+}
+
+
' );
};
@@ -481,10 +548,11 @@ private template 'ticket_list' => sub {
thead {
row {
th { 'id'};
- th { 'Summary'};
th {'Status'};
th {'Milestone'};
+ th {'Component'};
th {'Owner'};
+ th {'Reporter'};
th {'Created'};
th {'Due'};
}
@@ -492,11 +560,11 @@ private template 'ticket_list' => sub {
tbody {
for my $ticket (@$tickets) {
row {
- cell { ticket_link( $ticket => $ticket->luid ); };
- cell { class is 'summary'; ticket_link( $ticket => $ticket->prop('summary') ); };
- for (qw(status milestone owner created due)) {
+ cell { class is 'id'; ticket_link( $ticket => $ticket->luid ); };
+ for (qw(status milestone component owner reporter created due)) {
cell { class is $_; $ticket->prop($_) };
}
+ cell { class is 'summary'; ticket_link( $ticket => $ticket->prop('summary') ); };
}
}
commit fb27f987c2e81797a6c31ac25ddfb729c29fa1c9
Author: Jesse Vincent <jesse at bestpractical.com>
Date: Thu Jan 22 00:14:19 2009 -0500
a bit more sketching on the trac replica type
diff --git a/lib/App/SD/Replica/trac.pm b/lib/App/SD/Replica/trac.pm
index c6b92bb..e48e553 100644
--- a/lib/App/SD/Replica/trac.pm
+++ b/lib/App/SD/Replica/trac.pm
@@ -1,4 +1,4 @@
-package App::SD::Replica::rt;
+package App::SD::Replica::trac;
use Moose;
extends qw/App::SD::ForeignReplica/;
@@ -17,13 +17,14 @@ use Prophet::ChangeSet;
has trac => ( isa => 'Net::Trac::Connection', is => 'rw');
has remote_url => ( isa => 'Str', is => 'rw');
+
sub BUILD {
my $self = shift;
# Require rather than use to defer load
require Net::Trac;
- my ( $server, $type, $query ) = $self->{url} =~ m/^trac:(.*?)\|(.*?)\|(.*)$/
+ my ( $server, $type, $query ) = $self->{url} =~ m/^trac:(.*?)$/
or die
"Can't parse Trac server spec. Expected trac:http://example.com";
my $uri = URI->new($server);
@@ -33,19 +34,16 @@ sub BUILD {
$uri->userinfo(undef);
}
$self->remote_url( $uri->as_string );
- $self->rt_queue($type);
- $self->rt_query( ( $query ? "($query) AND " : "" ) . " Queue = '$type'" );
- ( $username, $password ) = $self->prompt_for_login( $uri, $username )
- unless $password;
+ #( $username, $password ) = $self->prompt_for_login( $uri, $username ) unless $password;
$self->trac(
Net::Trac::Connection->new(
- url => 'http://trac.someproject.org',
- user => $username,
- password => $password
+ url => $self->remote_url,
+ user => 'jesse',#$username,
+ password => 'iron' #$password
)
);
-
+ $self->trac->ensure_logged_in;
}
sub record_pushed_transactions {
diff --git a/lib/App/SD/Replica/trac/PullEncoder.pm b/lib/App/SD/Replica/trac/PullEncoder.pm
index f90cd39..853fb1b 100644
--- a/lib/App/SD/Replica/trac/PullEncoder.pm
+++ b/lib/App/SD/Replica/trac/PullEncoder.pm
@@ -24,8 +24,7 @@ sub run {
my $tickets = {};
my @transactions;
- my @tickets = $self->find_matching_tickets();
-
+ my @tickets = @{ $self->find_matching_tickets() };
$self->sync_source->log("No tickets found.") if @tickets == 0;
my $counter = 0;
@@ -33,37 +32,38 @@ sub run {
my $progress = Time::Progress->new();
$progress->attr( max => $#tickets );
local $| = 1;
- for my $id (@tickets) {
+
+ for my $ticket (@tickets) {
$counter++;
print $progress->report( "%30b %p Est: %E\r", $counter );
+ $self->sync_source->log( "Fetching ticket @{[$ticket->id]} - $counter of " . scalar @tickets );
- $self->sync_source->log( "Fetching ticket $id - $counter of " . scalar @tickets);
- $tickets->{ $id } = $self->_translate_final_ticket_state(
- $self->sync_source->trac->show( type => 'ticket', id => $id )
- );
- push @transactions, @{
- $self->find_matching_transactions(
- ticket => $id,
- starting_transaction => $first_rev
- )
- };
+ warn "Loading ticket " . $ticket->id . " " . $ticket->summary;
+
+ $tickets->{ $ticket->id } = $ticket;
}
- my $txn_counter = 0;
my @changesets;
- for my $txn ( sort { $b->{'id'} <=> $a->{'id'} } @transactions ) {
- $txn_counter++;
- $self->sync_source->log("Transcoding transaction @{[$txn->{'id'}]} - $txn_counter of ". scalar @transactions);
- my $changeset = $self->transcode_one_txn( $txn, $tickets->{ $txn->{Ticket} } );
- $changeset->created( $txn->{'Created'} );
- next unless $changeset->has_changes;
- unshift @changesets, $changeset;
+
+ my $ticket_state = { };
+
+ $self->_translate_final_ticket_state($ticket_state);
+
+ foreach my $ticket ( values %$tickets ) {
+ my $txns = $self->skip_previously_seen_transactions( ticket => $ticket, transactions => $ticket->history->entries);
+ for my $txn ( sort { $b->date <=> $a->date } @$txns) {
+ $self->sync_source->log("Transcoding transaction {[$txn->date}]} ");
+ my $changeset = $self->transcode_one_txn( $txn, $ticket_state );
+ $changeset->created( $txn->date );
+ next unless $changeset->has_changes;
+ unshift @changesets, $changeset;
+ }
}
my $cs_counter = 0;
- for ( @changesets ) {
- $self->sync_source->log("Applying changeset ".++$cs_counter . " of ".scalar @changesets);
- $args{callback}->($_)
+ for (@changesets) {
+ $self->sync_source->log( "Applying changeset " . ++$cs_counter . " of " . scalar @changesets );
+ $args{callback}->($_);
}
}
@@ -72,18 +72,12 @@ sub _translate_final_ticket_state {
my $ticket = shift;
# undefine empty fields, we'll delete after cleaning
- $ticket->{$_} = undef for
- grep defined $ticket->{$_} && $ticket->{$_} eq '',
- keys %$ticket;
+ $ticket->{$_} = undef for grep defined $ticket->{$_} && $ticket->{$_} eq '', keys %$ticket;
$ticket->{'id'} =~ s/^ticket\///g;
-
- $ticket->{ $self->sync_source->uuid . '-' . lc($_) } = delete $ticket->{$_}
- for qw(Queue id);
-
+ $ticket->{ $self->sync_source->uuid . '-' . lc($_) } = delete $ticket->{$_} for qw(Queue id);
delete $ticket->{'Owner'} if lc($ticket->{'Owner'}) eq 'nobody';
- $ticket->{'Owner'} = $self->resolve_user_id_to( email_address => $ticket->{'Owner'} )
- if $ticket->{'Owner'};
+ $ticket->{'Owner'} = $self->resolve_user_id_to( email_address => $ticket->{'Owner'} ) if $ticket->{'Owner'};
# normalize names of watchers to variant with suffix 's'
foreach my $field (qw(Requestor Cc AdminCc)) {
@@ -94,18 +88,12 @@ sub _translate_final_ticket_state {
}
}
- $ticket->{$_} = $self->unix_time_to_iso( $ticket->{$_} )
- for grep defined $ticket->{$_}, qw(Created Resolved Told LastUpdated Due Starts Started);
-
- $ticket->{$_} =~ s/ minutes$//
- for grep defined $ticket->{$_}, qw(TimeWorked TimeLeft TimeEstimated);
-
+ $ticket->{$_} = $self->unix_time_to_iso( $ticket->{$_} ) for grep defined $ticket->{$_}, qw(Created Resolved Told LastUpdated Due Starts Started);
+ $ticket->{$_} =~ s/ minutes$// for grep defined $ticket->{$_}, qw(TimeWorked TimeLeft TimeEstimated);
$ticket->{'Status'} =~ $self->translate_status($ticket->{'Status'});
# delete undefined and empty fields
- delete $ticket->{$_} for
- grep !defined $ticket->{$_} || $ticket->{$_} eq '',
- keys %$ticket;
+ delete $ticket->{$_} for grep !defined $ticket->{$_} || $ticket->{$_} eq '', keys %$ticket;
return $ticket;
}
@@ -119,55 +107,29 @@ Returns a Trac::TicketSearch collection for all tickets found matching your QUER
sub find_matching_tickets {
my $self = shift;
my %query = (@_);
- my $search = Net::Trac::TicketSearch->new( connection => $self->sync_source->trac );
-
+ my $search = Net::Trac::TicketSearch->new( connection => $self->sync_source->trac, limit => 2 );
$search->query(%query);
-
- print $_->id, "\n" for @{ $search->results };
-
return $search->results;
}
-=head2 find_matching_transactions { ticket => $id, starting_transaction => $num }
+=head2 skip_previously_seen_transactions { ticket => $id, starting_transaction => $num, transactions => \@txns }
Returns a reference to an array of all transactions (as hashes) on ticket $id after transaction $num.
=cut
-sub find_matching_transactions {
+sub skip_previously_seen_transactions {
my $self = shift;
- my %args = validate( @_, { ticket => 1, starting_transaction => 1 } );
+ my %args = validate( @_, { ticket => 1, transactions => 1 } );
my @txns;
- my $trac_handle = $self->sync_source->trac;
-
- my @transactions = $rt_handle->get_transaction_ids( parent_id => $args{'ticket'} );
- for my $txn ( sort @transactions) {
+ for my $txn ( sort @{$args{transactions}}) {
# Skip things we know we've already pulled
- next if $txn < $args{'starting_transaction'};
+ #next if $txn < $args{'starting_transaction'};
# Skip things we've pushed
next if $self->sync_source->foreign_transaction_originated_locally($txn, $args{'ticket'});
-
-
- my $txn_hash = $rt_handle->get_transaction(
- parent_id => $args{'ticket'},
- id => $txn,
- type => 'ticket'
- );
- if ( my $attachments = delete $txn_hash->{'Attachments'} ) {
- for my $attach ( split( /\n/, $attachments ) ) {
- next unless ( $attach =~ /^(\d+):/ );
- my $id = $1;
- my $a = $rt_handle->get_attachment( parent_id => $args{'ticket'}, id => $id);
-
- push( @{ $txn_hash->{_attachments} }, $a )
- if ( $a->{Filename} );
-
- }
-
- }
- push @txns, $txn_hash;
+ push @txns, $txn;
}
return \@txns;
}
-----------------------------------------------------------------------
More information about the Bps-public-commit
mailing list