[Bps-public-commit] SD - A distributed issue tracker branch, master, updated. f27fa2d4275322be6b5fef25c5358b42a81c5e4d

jesse jesse at bestpractical.com
Sat Feb 7 02:16:40 EST 2009


The branch, master has been updated
       via  f27fa2d4275322be6b5fef25c5358b42a81c5e4d (commit)
       via  c7dc990a436d2965f8a4718e696c0d1a397d4f2f (commit)
       via  f745190450fcec476c8de4c37a793b6868062a4f (commit)
      from  52350309dde15490d97e52282fefcc68525c5266 (commit)

Summary of changes:
 lib/App/SD/CLI/Command/Ticket/Show.pm  |    3 +
 lib/App/SD/Replica/trac/PullEncoder.pm |  146 ++++++++++++++++----------------
 lib/App/SD/Server/View.pm              |   26 +++++-
 3 files changed, 100 insertions(+), 75 deletions(-)

- Log -----------------------------------------------------------------
commit f745190450fcec476c8de4c37a793b6868062a4f
Author: Jesse Vincent <jesse at bestpractical.com>
Date:   Sat Feb 7 02:15:35 2009 -0500

    Comment ordering fixes; Description display fixes

diff --git a/lib/App/SD/Server/View.pm b/lib/App/SD/Server/View.pm
index 5250333..726e0d7 100644
--- a/lib/App/SD/Server/View.pm
+++ b/lib/App/SD/Server/View.pm
@@ -317,10 +317,22 @@ div.widget.description {
     height: auto;
 }
 
+
+
+div.widget.description .value {
+    white-space: pre;
+    display: block;
+    overflow-x: auto;
+}
+
+
 div.widget.description textarea {
     width: 100%;
     font-size: 0.8em;
     height: 6em;
+    padding-left: 0.5em;
+    padding-top: 0.5em;
+    padding-bottom: 0.5em;
 }
 
 div.widget.status {
@@ -525,6 +537,7 @@ ul.comments li .content {
     padding: 1em;
     margin-top: 1em;
     font-size: 0.9em;
+    overflow-x: auto;
 
 }
 
@@ -1026,7 +1039,7 @@ private template 'ticket_basics' => sub {
             div { { class is 'value uuid'}; $ticket->uuid; } 
             };
         for my $key (qw'status component milestone', 
-                        (grep {$_ ne 'description'} (@BASIC_PROPS, (sort keys %props))), 'description') {
+                        (grep {$_ ne 'description'} (@BASIC_PROPS, (sort keys %props)))){
             next unless defined $props{$key}; 
             next if ($key =~ m{(?:summary)});
             next if ($key =~ /.{8}-.{4}-.{4}-.{12}-id/);
@@ -1038,11 +1051,20 @@ private template 'ticket_basics' => sub {
             delete $props{$key};
         
         };
+
+            div { class is 'widget description';
+                label {'description'};
+                div { { class is 'value description' };
+                        outs($props{description});
+                }
+            };
     };
     script { outs_raw('$("div.created,div.due").prettyDateTag();
 setInterval(function(){ $("div.created,div.due").prettyDateTag(); }, 5000);') };
 
 };
+
+
 template ticket_attachments => sub {
     my $self = shift;
     my $ticket = shift;
@@ -1080,7 +1102,7 @@ setInterval(function(){ $("span.created").prettyDateTag(); }, 5000);') };
 template ticket_comments => sub {
     my $self     = shift;
     my $ticket    = shift;
-    my @comments = sort  @{ $ticket->comments };
+    my @comments = sort {$a->prop('created') cmp $b->prop('created')}  @{ $ticket->comments };
     if (@comments) {
         h2 { { class is 'conmments'};  'Comments'};
         ul {

commit c7dc990a436d2965f8a4718e696c0d1a397d4f2f
Author: Jesse Vincent <jesse at bestpractical.com>
Date:   Sat Feb 7 02:15:57 2009 -0500

    Slightly better de-htmlification of html comments

diff --git a/lib/App/SD/CLI/Command/Ticket/Show.pm b/lib/App/SD/CLI/Command/Ticket/Show.pm
index d2ff83d..70fb48d 100644
--- a/lib/App/SD/CLI/Command/Ticket/Show.pm
+++ b/lib/App/SD/CLI/Command/Ticket/Show.pm
@@ -43,10 +43,13 @@ override run => sub {
             my $content = $comment->prop('content') || '';
             if ($content_type =~ m{text/html}i ){
 
+                $content =~ s|<p.*?>|\n|gismx;
+                $content =~ s|</?pre.*?>|\n|gismx;
                 $content =~ s|</?b\s*>|*|gismx;
                 $content =~ s|</?i\s*>|_|gismx;
                 $content =~ s|<a(?:.*?)href="(.*?)".*?>(.*?)</a.*?>|$2 [link: $1 ]|gismx;
                 $content =~ s|<.*?>||gismx;
+                $content =~ s|\n\n|\n|gismx;
             }
 
             print "$creator: " if $creator;

commit f27fa2d4275322be6b5fef25c5358b42a81c5e4d
Author: Jesse Vincent <jesse at bestpractical.com>
Date:   Sat Feb 7 02:16:17 2009 -0500

    Refactoring toward sanity, dealing with operational bugs from parrot sync

diff --git a/lib/App/SD/Replica/trac/PullEncoder.pm b/lib/App/SD/Replica/trac/PullEncoder.pm
index 667e974..ec71455 100644
--- a/lib/App/SD/Replica/trac/PullEncoder.pm
+++ b/lib/App/SD/Replica/trac/PullEncoder.pm
@@ -20,14 +20,14 @@ sub run {
         }
     );
 
-    my $first_rev = ( $args{'after'} + 1 ) || 1;
-
-    my $tickets = {};
-    my @transactions;
-
     my @tickets = @{ $self->find_matching_tickets() };
-    $self->sync_source->log("No tickets found.") if @tickets == 0;
 
+    if ( @tickets == 0 ) {
+        $self->sync_source->log("No tickets found.");
+        return;
+    }
+
+    my @changesets;
     my $counter = 0;
     $self->sync_source->log("Discovering ticket history");
     my $progress = Time::Progress->new();
@@ -35,20 +35,10 @@ sub run {
     local $| = 1;
 
     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 );
-
-        $tickets->{ $ticket->id } = $ticket;
-    }
-
-    my @changesets;
+        $self->sync_source->log( "Fetching ticket @{[$ticket->id]} - " . $counter++ . " of " . scalar @tickets );
 
-    foreach my $ticket ( values %$tickets ) {
         my $ticket_data = $self->_translate_final_ticket_state($ticket);
-
-        #my $ticket_initial_data = $self->build_initial_ticket_state($ticket_data, $ticket);
         my $ticket_initial_data = {%$ticket_data};
         my $txns                = $self->skip_previously_seen_transactions(
             ticket       => $ticket,
@@ -58,51 +48,44 @@ sub run {
         # Walk transactions newest to oldest.
         for my $txn ( sort { $b->date <=> $a->date } @$txns ) {
             $self->sync_source->log( $ticket->id . " - Transcoding transaction  @{[$txn->date]} " );
-            my $changeset = $self->transcode_one_txn( $txn, $ticket_initial_data );
-            $changeset->created( $txn->date->ymd . " " . $txn->date->hms );
-            next unless $changeset->has_changes;
-
-            # the changeset is older than the one that came before it, so it goes first
-            unshift @changesets, $changeset;
-            $counter++;
+            # the changesets are older than the ones that came before, so they goes first
+            unshift @changesets, grep { defined } $self->transcode_one_txn( $txn, $ticket_initial_data, $ticket_data );
         }
 
         # create is oldest of all
         unshift @changesets, $self->build_create_changeset( $ticket_initial_data, $ticket );
     }
 
-    my $cs_counter = 1;
-    for my $changeset (@changesets) {
-        $changeset->original_sequence_no( $cs_counter++ );
-        $self->sync_source->log( "Applying changeset "
-                . $changeset->original_sequence_no . " of "
-                . scalar @changesets );
-        $args{callback}->($changeset);
-    }
+        $args{callback}->($_) for @changesets;
 }
 
 sub _translate_final_ticket_state {
     my $self          = shift;
     my $ticket_object = shift;
-
+    
+    my $content = $ticket_object->description;
     my $ticket_data = {
 
         $self->sync_source->uuid . '-id' => $ticket_object->id,
 
-        owner => ( $ticket_object->owner || '' ),
+        owner => ( $ticket_object->owner || undef ),
+        type => ($ticket_object->type || undef),
         created     => ( $ticket_object->created->ymd . " " . $ticket_object->created->hms ),
-        reporter    => ( $ticket_object->reporter || '' ),
+        reporter    => ( $ticket_object->reporter || undef ),
         status      => $self->translate_status( $ticket_object->status ),
-        summary     => ( $ticket_object->summary || '' ),
-        description => ( $ticket_object->description || '' ),
-        tags        => ( $ticket_object->keywords || '' ),
-        component   => ( $ticket_object->component || '' ),
-        milestone   => ( $ticket_object->milestone || '' ),
-        priority    => ( $ticket_object->priority || '' ),
-        severity    => ( $ticket_object->severity || '' ),
-        cc          => ( $ticket_object->cc || '' ),
+        summary     => ( $ticket_object->summary || undef ),
+        description => ( $content||undef),
+        tags        => ( $ticket_object->keywords || undef ),
+        component   => ( $ticket_object->component || undef ),
+        milestone   => ( $ticket_object->milestone || undef ),
+        priority    => ( $ticket_object->priority || undef ),
+        severity    => ( $ticket_object->severity || undef ),
+        cc          => ( $ticket_object->cc || undef ),
     };
 
+
+
+
     # delete undefined and empty fields
     delete $ticket_data->{$_}
         for grep !defined $ticket_data->{$_} || $ticket_data->{$_} eq '', keys %$ticket_data;
@@ -120,7 +103,7 @@ sub find_matching_tickets {
     my $self  = shift;
     my %query = (@_);
     my $search
-        = Net::Trac::TicketSearch->new( connection => $self->sync_source->trac, limit => 50 );
+        = Net::Trac::TicketSearch->new( connection => $self->sync_source->trac, limit => 500 );
     $search->query(%query);
     return $search->results;
 }
@@ -133,16 +116,16 @@ Returns a reference to an array of all transactions (as hashes) on ticket $id af
 
 sub skip_previously_seen_transactions {
     my $self = shift;
-    my %args = validate( @_, { ticket => 1, transactions => 1 } );
+    my %args = validate( @_, { ticket => 1, transactions => 1, starting_transaction => 0 } );
     my @txns;
 
     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'} ||0 );
 
         # Skip things we've pushed
-        #next if $self->sync_source->foreign_transaction_originated_locally($txn, $args{'ticket'});
+        next if $self->sync_source->foreign_transaction_originated_locally($txn, $args{'ticket'});
         push @txns, $txn;
     }
     return \@txns;
@@ -176,11 +159,13 @@ sub build_create_changeset {
     my $self        = shift;
     my $create_data = shift;
     my $ticket      = shift;
-    warn "My ticket id is " . $ticket->id;
+             # this sequence_no only works because trac tickets only allow one update 
+             # per ticket per second.
+             # we decrement by 1 on the off chance that someone created and 
+             # updated the ticket in the first second
     my $changeset = Prophet::ChangeSet->new(
         {   original_source_uuid => $self->sync_source->uuid_for_remote_id( $ticket->id ),
-
-            #original_sequence_no => 1, # XXX TODO THIS IS JNOT A VALID SEQUENCE NUMBER
+            original_sequence_no => ( $ticket->created->epoch-1),
             creator => $self->resolve_user_id_to( email_address => $ticket->reporter ),
             created => $ticket->created->ymd ." ".$ticket->created->hms
         }
@@ -195,6 +180,7 @@ sub build_create_changeset {
 
     for my $prop ( keys %$create_data ) {
         next unless defined $create_data->{$prop};
+        next if $prop =~ /^(?:patch)$/;
         $change->add_prop_change( name => $prop, old => '', new => $create_data->{$prop} );
     }
 
@@ -202,35 +188,48 @@ sub build_create_changeset {
     return $changeset;
 }
 
+            # we might get return:
+            # 0 changesets if it was a null txn
+            # 1 changeset if it was a normal txn
+            # 2 changesets if we needed to to some magic fixups.
 sub transcode_one_txn {
-    my ( $self, $txn, $ticket, $txn_number ) = (@_);
-    my $changeset = Prophet::ChangeSet->new(
-        {   original_source_uuid => $self->sync_source->uuid_for_remote_id(
-                $ticket->{ $self->sync_source->uuid . '-id' }
-            ),
+    my ( $self, $txn, $ticket, $ticket_final ) = (@_);
+
+    my $ticket_uuid = $self->sync_source->uuid_for_remote_id( $ticket->{ $self->sync_source->uuid . '-id' } );
 
-         #        original_sequence_no => $txn_number, #XXX TODO THIS IS NOT A VALID SEQUENCE NUMBER
+    my $changeset = Prophet::ChangeSet->new(
+        {   original_source_uuid => $ticket_uuid,
+            original_sequence_no => $txn->date->epoch,    # see comment on ticket
+                                                          # create changeset
             creator => $self->resolve_user_id_to( email_address => $txn->author ),
+            created => $txn->date->ymd . " " . $txn->date->hms
         }
     );
 
     my $change = Prophet::Change->new(
         {   record_type => 'ticket',
-            record_uuid => $self->sync_source->uuid_for_remote_id(
-                $ticket->{ $self->sync_source->uuid . '-id' }
-            ),
+            record_uuid => $ticket_uuid,
             change_type => 'update_file'
         }
     );
 
+    warn "right here, we need to deal with changed data that trac failed to record";
+
     foreach my $prop_change ( values %{ $txn->prop_changes || {} } ) {
         my $new      = $prop_change->new_value;
         my $old      = $prop_change->old_value;
         my $property = $prop_change->property;
+        next if $property =~ /^(?:patch)$/;
 
         $old = undef if ( $old eq '' );
         $new = undef if ( $new eq '' );
 
+        if (!exists $ticket_final->{$property}) {
+                $ticket_final->{$property} = $new;
+                $ticket->{$property} = $new;
+        }
+
+
         # walk back $ticket's state
         if (   ( !defined $new && !defined $ticket->{$property} )
             || ( defined $new && defined $ticket->{$property} && $ticket->{$property} eq $new ) )
@@ -246,24 +245,25 @@ sub transcode_one_txn {
 
     my $comment = Prophet::Change->new(
         {   record_type => 'comment',
-            record_uuid => Data::UUID->new->create_str(),
+            record_uuid => Data::UUID->new->create_str()
+            ,    # comments are never edited, we can have a random uuid
             change_type => 'add_file'
-        });
-
-    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/html' );
-    $comment->add_prop_change(
-        name => 'ticket',
-        new => $self->sync_source->uuid_for_remote_id( $ticket->{ $self->sync_source->uuid . '-id' } )
+        }
     );
 
-    $changeset->add_change({change => $comment});
-    }
+    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/html' );
+            $comment->add_prop_change( name => 'ticket', new  => $ticket_uuid);
+
+            $changeset->add_change( { change => $comment } );
+        }
     }
+
+    return undef unless $changeset->has_changes;
     return $changeset;
 }
 

-----------------------------------------------------------------------



More information about the Bps-public-commit mailing list