DivideTicketIntoSubtasks: Difference between revisions

From Request Tracker Wiki
Jump to navigation Jump to search
m (3 revisions imported)
 
mNo edit summary
 
Line 9: Line 9:
This scrip action creates tickets for each list item for each task the main ticket [[DependsOn]]. It handles lists with dash or asterisk bullets:
This scrip action creates tickets for each list item for each task the main ticket [[DependsOn]]. It handles lists with dash or asterisk bullets:


<nowiki>* thingy 1
<pre>
   - thingy 2
  * thingy 1
 
   - thingy 2  
  </nowiki>
</pre>


=== Scrip Fields ===
=== Scrip Fields ===
Line 24: Line 24:
=== Action preparation code ===
=== Action preparation code ===


  <nowiki>require MIME::Entity;
  <pre>
  require MIME::Entity;
    
    
   my $trans = $self-&gt;TransactionObj;
   my $trans = $self-&gt;TransactionObj;
Line 52: Line 53:
    
    
   return 1;
   return 1;
  </nowiki>
</pre>


=== Action cleanup code ===
=== Action cleanup code ===
Line 62: Line 63:
The version below handles nested bulleted lists, and the bullet character indicates the link relationship, as defied in %links. Note that this scrip will not fire if the bulleted list is preceded by other content.
The version below handles nested bulleted lists, and the bullet character indicates the link relationship, as defied in %links. Note that this scrip will not fire if the bulleted list is preceded by other content.


<nowiki>*starfruit
<pre>
  *starfruit
   * apple
   * apple
   @@ gala
   @@ gala
Line 70: Line 72:
   *** stars &amp; stripes
   *** stars &amp; stripes
   **cantaloupe
   **cantaloupe
 
</pre>
  </nowiki>


This update of [http://wiki.bestpractical.com/view/DivideTicketIntoSubtasks/4012 the initial revision] also handles signatures, long items entered via the UI, and fixes a conflict with [[HideTransactions]].
This update of [http://wiki.bestpractical.com/view/DivideTicketIntoSubtasks/4012 the initial revision] also handles signatures, long items entered via the UI, and fixes a conflict with [[HideTransactions]].
Line 79: Line 80:
require MIME::Entity; require Text::Wrap;
require MIME::Entity; require Text::Wrap;


  <nowiki>#Semi-configurable items, see also 5.10 @ Unwrap below
  <pre>
  #Semi-configurable items, see also 5.10 @ Unwrap below
   local $Text::Wrap::columns = 64;
   local $Text::Wrap::columns = 64;
   #You probably don't want to use '#' without modifying the truncated entry comment char
   #You probably don't want to use '#' without modifying the truncated entry comment char
Line 130: Line 132:
    
    
   return 1;
   return 1;
  </nowiki>
</pre>
 
==Nested Subtickets Variant 3==
==Nested Subtickets Variant 3==
I had problems with Variant 2 in RT 3.8 and I wanted something a little simpler that would created nested subtickets. It does not use the MIME::Entity module since I don't want to put a default comment in the subtickets.
I had problems with Variant 2 in RT 3.8 and I wanted something a little simpler that would created nested subtickets. It does not use the MIME::Entity module since I don't want to put a default comment in the subtickets.


Line 147: Line 151:
  **Level 3-1
  **Level 3-1
Action Preparation Code:
Action Preparation Code:
<pre>
  my $trans = $self->TransactionObj;
  my $trans = $self->TransactionObj;
  my $tkt = $self->TicketObj;
  my $tkt = $self->TicketObj;
Line 206: Line 212:
   
   
  return 1;
  return 1;
</pre>

Latest revision as of 20:14, 13 August 2016

HomePage > Contributions > DivideTicketIntoSubtasks

DivideTicketIntoSubtasks

Often, we have a whole list of related tasks, and wish to create separate tickets for them all at once, perhaps for different people to work on. With these scrips You can do so through the use of bulleted list in the body of the initial ticket.

Original

This scrip action creates tickets for each list item for each task the main ticket DependsOn. It handles lists with dash or asterisk bullets:

  * thingy 1
   - thingy 2 

Scrip Fields

Description:	Split and link sub-tasks
Condition:	OnCreate
Action:        User Defined
Template:	Blank
Stage:	        TransactionCreate #With modern RTs You may need to use TransactionBatch instead.

Action preparation code

  require MIME::Entity;
   
   my $trans = $self->TransactionObj;
   my $tkt = $self->TicketObj;
   
   my $cont = $trans->Content;
   my $requestors = [ $tkt->Requestors->MemberEmailAddresses ];
   
   #Updated to require whitespace between bullet & entry
   if ($cont =~ m/^\s*[-*]\s/m) {
     $cont =~ s/^\n.*//sm;
     my @lines = split(/[\n\r]*^\s*[-*]\s+/m, $cont); #update
     shift(@lines);
     foreach my $line (@lines) {
       my $new_tkt = RT::Ticket->new($RT::SystemUser);
       my ($id, $msg) = $new_tkt->Create(
                     Queue => "General",
                     Subject => $line,
                     Status => 'new',
                     Requestor => $requestors,
                     DependedOnBy => $tkt->Id,
                     MIMEObj => MIME::Entity->build(
                       Type => 'text/plain',
                       Data => $line));
     }
   }
   
   return 1;
 

Action cleanup code

return 1;

New Variant (2)

The version below handles nested bulleted lists, and the bullet character indicates the link relationship, as defied in %links. Note that this scrip will not fire if the bulleted list is preceded by other content.

   *starfruit
   * apple
   @@ gala
   ++ fuji
   @ melons
   ** watermelon
   *** stars & stripes
   **cantaloupe

This update of the initial revision also handles signatures, long items entered via the UI, and fixes a conflict with HideTransactions.

Action preparation code

require MIME::Entity; require Text::Wrap;

   #Semi-configurable items, see also 5.10 @ Unwrap below
   local $Text::Wrap::columns = 64;
   #You probably don't want to use '#' without modifying the truncated entry comment char
   my %links = ('*' => 'DependedOnBy', '+' => 'Parents', '@' => 'RefersTo');
   
   
   #Preparation
   my $tkt = $self->TicketObj;
   my $cont = $self->TransactionObj->Content;
   my $requestors = [ $tkt->Requestors->MemberEmailAddresses ];
   my $sym = qr/[\Q@{[join '', keys %links]}\E]/;
   
   
   #Strip leading comments, e.g; untruncated entry
   $cont =~ s/^\s*(#[^\n]+\n)+\n?//s;
   
   #Strip signature
   $cont =~ s/^-- \n.+$//m;
   
   #Unwrap long lines from RT's hard-wrap textareas, use the one matching your perl
   #1 while $cont =~ s/^\s*$sym\s*[^\n]+\K\n(?!^$sym)/ /m;  #5.10
   1 while $cont =~ s/^(\s*$sym\s*[^\n]+)\n(?!^$sym)/$1 /m; #5.8
   
   #Parse bullets
   while( $cont =~ /\G\s*($sym)\s*([^\n]+)((?:\s*$sym{2,}\s*[^\n]+)+)?/mg ){
       my($link, $subj, $body) = ($1, $2, $3||'');
       $body =~ s/^$sym//mg if length($body);
   
       #Wrap our long item into a body comment before truncating
       if( length($subj) > $Text::Wrap::columns ){
           $body = Text::Wrap::wrap('# ', '# ', $subj) . "\n" . $body;
   
           my($under, $over) = ($Text::Wrap::columns-5, $Text::Wrap::columns+5);
           $subj =~ /(.{$under,$over}(?<!\s)\b)|(.{$Text::Wrap::columns})/;
           $subj = $1 ? "$1..." : ($2||$subj);
       }
   
       #$RT::SystemUser would not play nice with HideTransactions
       my $new_tkt = RT::Ticket->new($RT::Nobody);
       my ($id, $msg) = $new_tkt->Create(
                     Queue => "TODO",
                     Subject => $subj,
                     Status => 'new',
                     Owner => $tkt->Owner,
                     Requestor => $requestors,
                     $links{$link} => $tkt->Id,
                     MIMEObj => MIME::Entity->build(Data => $body)
     );
   }
   
   return 1;

Nested Subtickets Variant 3

I had problems with Variant 2 in RT 3.8 and I wanted something a little simpler that would created nested subtickets. It does not use the MIME::Entity module since I don't want to put a default comment in the subtickets.

This creates DependsOn links with either * or - symbols. Create sublinks by adding *'s or -'s.

Example:

*Level 1
**Level 1-1
**Level 1-1
***Level 1-1-1

*Level 2
** Level 2-1
* Level 3
**Level 3-1

Action Preparation Code:

 my $trans = $self->TransactionObj;
 my $tkt = $self->TicketObj;
 my $cont = $trans->Content;
 my $requestors = [ $tkt->Requestors->MemberEmailAddresses ];
 
 if ($cont =~ m/^\s*[\*-]+/m) {
     my %tickets;
     foreach (split(/[\n\r]/, $cont)) {
 
         #Split number of *'s and actual subject.
         next unless /^\s*([\*-]+)(.+)$/;
         next unless $2;
         my $lvl = $1; my $value=$2;
 
         #Count the number of *'s
         my $count = scalar split //, $lvl;
 
         #Keep track of the tickets' parents
         $tickets{$count}=[$value];
 
         #One line is one ticket
         my $new_tkt =  RT::Ticket->new($RT::SystemUser);
 
         #If there is a parent ticket create dependencies on it
         if (exists $tickets{$count-1}) {
             my ($id, $msg) = $new_tkt->Create(
                 Queue       => $tkt->Queue,     
                 Subject     => $value,
                 Status      => 'new',
                 Requestor   => $requestors,     
                 Owner       => $tkt->Owner,     
                 DependedOnBy    => $tickets{$count-1}[1],
             );          
 
             #Store ticket id for children
             push @{$tickets{$count}}, $id;
 
         #If no parent ticket, create dependencies on the new ticket
         } else {
             my ($id, $msg) = $new_tkt->Create(
                 Queue       => $tkt->Queue,     
                 Subject     => $value,
                 Status      => 'new',
                 Requestor   => $requestors,     
                 Owner       => $tkt->Owner,     
                 DependedOnBy    => $tkt->Id,    
             );          
 
             #Store ticket id for children
             push @{$tickets{$count}}, $id;
 
             #Die if we got here without recording the parent somehow
             return 0 if $count > 1; 
         }       
     }   
 }
 
 
 return 1;