[Bps-public-commit] r18260 - in Net-Trac/trunk: .
jesse at bestpractical.com
jesse at bestpractical.com
Thu Feb 5 19:59:31 EST 2009
Author: jesse
Date: Thu Feb 5 19:59:31 2009
New Revision: 18260
Modified:
Net-Trac/trunk/TODO
Net-Trac/trunk/lib/Net/Trac/Ticket.pm
Net-Trac/trunk/lib/Net/Trac/TicketHistory.pm
Net-Trac/trunk/lib/Net/Trac/TicketHistoryEntry.pm
Net-Trac/trunk/lib/Net/Trac/TicketSearch.pm
Log:
* Better caching of ticket history. Properish handling of the keywords filed
Modified: Net-Trac/trunk/TODO
==============================================================================
--- Net-Trac/trunk/TODO (original)
+++ Net-Trac/trunk/TODO Thu Feb 5 19:59:31 2009
@@ -1,8 +1,13 @@
+KNOWN ISSUES
+
+ * reverse engineering a proper history of trac's "Description" field is hard.
+ * Patches welcome
+
+
Samples of failed parses from the Parrot Trac
-My ticket id is 31 at /Users/jesse/git/bps/sd.git/lib/App/SD/Replica/trac/PullEncoder.pm line 165.
could not parse <strong>description</strong>
modified (<a href="/parrot/ticket/35?action=diff&version=1">diff</a>)
Modified: Net-Trac/trunk/lib/Net/Trac/Ticket.pm
==============================================================================
--- Net-Trac/trunk/lib/Net/Trac/Ticket.pm (original)
+++ Net-Trac/trunk/lib/Net/Trac/Ticket.pm Thu Feb 5 19:59:31 2009
@@ -42,6 +42,21 @@
is => 'rw'
);
+
+has history => (
+ isa => 'Net::Trac::TicketHistory',
+ is => 'rw',
+ default => sub {
+ my $self = shift;
+ my $hist = Net::Trac::TicketHistory->new( { connection => $self->connection } );
+ $hist->load($self);
+ return $hist;
+ },
+ lazy => 1
+);
+
+
+
has _attachments => ( isa => 'ArrayRef', is => 'rw' );
class_has _loaded_new_metadata => ( isa => 'Bool', is => 'rw' );
@@ -106,10 +121,23 @@
return unless @{ $search->results };
- my $tid = $self->load_from_hashref( $search->results->[0] );
+ my $ticket_data = $search->results->[0];
+ $self->_tweak_ticket_data_for_load($ticket_data);
+
+ my $tid = $self->load_from_hashref( $ticket_data);
return $tid;
}
+# We force an order on the keywords prop since trac doesn't let us
+# really know what the order used to be
+sub _tweak_ticket_data_for_load {
+ my $self = shift;
+ my $ticket = shift;
+ $ticket->{keywords} = join(' ', sort ( split ( /\s+/,$ticket->{keywords})));
+
+}
+
+
=head2 load_from_hashref HASHREF [SKIP]
You should never need to use this method yourself. Loads a ticket from a hashref
@@ -302,9 +330,9 @@
form_number => $form_num,
fields => { %form, submit => 1 }
);
-
my $reply = $self->connection->mech->response;
if ( $reply->is_success ) {
+ delete $self->{history}; # ICK. I really want a Moose "reset to default"
return $self->load($self->id);
}
else {
@@ -330,12 +358,6 @@
=cut
-sub history {
- my $self = shift;
- my $hist = Net::Trac::TicketHistory->new({ connection => $self->connection });
- $hist->load( $self->id );
- return $hist;
-}
=head2 comments
@@ -393,6 +415,7 @@
my $reply = $self->connection->mech->response;
$self->connection->_warn_on_error( $reply->base->as_string ) and return;
+ delete $self->{history}; # ICK. I really want a Moose "reset to default"
return $self->attachments->[-1];
}
Modified: Net-Trac/trunk/lib/Net/Trac/TicketHistory.pm
==============================================================================
--- Net-Trac/trunk/lib/Net/Trac/TicketHistory.pm (original)
+++ Net-Trac/trunk/lib/Net/Trac/TicketHistory.pm Thu Feb 5 19:59:31 2009
@@ -45,7 +45,7 @@
is => 'ro'
);
-has ticket => ( isa => 'Int', is => 'rw' );
+has ticket => ( isa => 'Net::Trac::Ticket', is => 'rw', weak_ref => 1);
has entries => ( isa => 'ArrayRef', is => 'rw' );
=head1 METHODS
@@ -58,19 +58,24 @@
sub load {
my $self = shift;
- my ($id) = validate_pos( @_, { type => SCALAR } );
+ my ($ticket_obj) = validate_pos( @_, 1);
- $self->ticket( $id );
+ $self->ticket( $ticket_obj );
- my $feed = $self->connection->_fetch_feed( "/ticket/$id?format=rss" )
+ # Clone the ticket state so we can morph it backwards to reverse engineer
+ # keywords
+ my $temp_state = { %{ $ticket_obj->state()}};
+
+ my $feed = $self->connection->_fetch_feed( "/ticket/@{[$ticket_obj->id]}?format=rss" )
or return;
- my @entries = $feed->entries;
my @history;
- foreach my $entry (@entries) {
+ # Work on the newest entry first so we can back-calculate from the current state
+ foreach my $entry (reverse $feed->entries ) {
my $e = Net::Trac::TicketHistoryEntry->new({ connection => $self->connection });
- $e->parse_feed_entry($entry);
- push @history, $e;
+ $e->parse_feed_entry($entry, $temp_state);
+ # newest entry should be at the front of the list in the history later
+ unshift @history, $e;
}
$self->entries( \@history );
Modified: Net-Trac/trunk/lib/Net/Trac/TicketHistoryEntry.pm
==============================================================================
--- Net-Trac/trunk/lib/Net/Trac/TicketHistoryEntry.pm (original)
+++ Net-Trac/trunk/lib/Net/Trac/TicketHistoryEntry.pm Thu Feb 5 19:59:31 2009
@@ -62,6 +62,12 @@
my $self = shift;
my $e = shift; # XML::Feed::Entry
+ # We use a reference to a copy of ticket state as it was after this feed
+ # entry to interpret what "x added, y removed" meant for absolute values
+ # of keywords
+
+ my $ticket_state = shift;
+
$self->author( $e->author );
$self->date( $e->issued );
$self->category( $e->category );
@@ -69,16 +75,17 @@
my $desc = $e->content->body;
if ( $desc =~ s|^\s*?<ul>(.*)</ul>||is) {
my $props = $1;
- $self->prop_changes( $self->_parse_props($props) );
+ $self->prop_changes( $self->_parse_props($props, $ticket_state) );
}
$self->content($desc);
- return 1;
+
}
sub _parse_props {
my $self = shift;
my $raw = shift || '';
+ my $ticket_state = shift;
# throw out the wrapping <li>
$raw =~ s|^\s*?<li>(.*)</li>\s*?$|$1|is;
my @prop_lines = split( m#</li>\s*<li>#s, $raw );
@@ -86,7 +93,33 @@
foreach my $line (@prop_lines) {
my ($prop, $old, $new);
- if ( $line =~ m{<strong>(.*?)</strong>\s+changed\s+from\s+<em>(.*)</em>\s+to\s+<em>(.*)</em>}is ) {
+ if ($line =~ m{<strong>keywords</strong>(.*)$}is ) {
+ my $value_changes = $1;
+ $prop = 'keywords';
+ my (@added, @removed);
+ if ($value_changes =~ m{^\s*<em>(.*?)</em> added;?}is) {
+ my $added = $1;
+ @added = split(m{</em>\s*<em>}is, $added);
+ }
+
+ if ($value_changes =~ m{(?:^|;)\s*<em>(.*)</em> removed}is) {
+ my $removed = $1;
+ @removed = split(m{</em>\s*<em>}is, $removed);
+
+ }
+
+ my @before = ();
+ my @after = grep defined && length, split (/\s+/,$ticket_state->{keywords});
+ for my $value (@after) {
+ next if grep {$_ eq $value} @added;
+ push @before, $value;
+ }
+
+ $old = join(' ', sort (@before, @removed));
+ $new = join(' ', sort (@after));
+ $ticket_state->{keywords} = $old;
+ }
+ elsif ( $line =~ m{<strong>(.*?)</strong>\s+changed\s+from\s+<em>(.*)</em>\s+to\s+<em>(.*)</em>}is ) {
$prop = $1;
$old = $2;
$new = $3;
@@ -101,7 +134,8 @@
} elsif ( $line =~ m{<strong>(.*?)</strong>\s+deleted}is ) {
$prop = $1;
$new = '';
- } else {
+ }
+ else {
warn "could not parse ". $line;
}
Modified: Net-Trac/trunk/lib/Net/Trac/TicketSearch.pm
==============================================================================
--- Net-Trac/trunk/lib/Net/Trac/TicketSearch.pm (original)
+++ Net-Trac/trunk/lib/Net/Trac/TicketSearch.pm Thu Feb 5 19:59:31 2009
@@ -97,9 +97,10 @@
unless ( $no_objects ) {
my @tickets = ();
- for ( @{$data || []} ) {
+ for my $ticket_data ( @{$data || []} ) {
my $ticket = Net::Trac::Ticket->new( connection => $self->connection );
- my $id = $ticket->load_from_hashref( $_ );
+ $ticket->_tweak_ticket_data_for_load($ticket_data);
+ my $id = $ticket->load_from_hashref( $ticket_data );
push @tickets, $ticket if $id;
}
return $self->results( \@tickets );
More information about the Bps-public-commit
mailing list