A Paper Trail For Trac Tickets
This doesn’t have much to do with Phaxio, but I thought I’d share it anyway.
Finishing a sprint is awesome. There’s excitment, adrenaline, loud music (in our office), cars being set ablaze (but not really) and an unidentified man standing on my desk yelling “Let’s Do This Thang!”; it’s a bit much to handle. But, before all hell breaks loose in our office, Josh will appear at my office door with a piece of paper in hand - the final ticket of the sprint. He has a certain swagger as he gives me a huge toothy smile while pinning the final ticket to the “QA” board in my office - it’s a nice moment.
Anyway, Josh recently wrote a Symfony task that will take a Trac CSV and turn it into an HTML file (which in turn you can print to a PDF, or straight to your printer).
You may wonder why you’d want to print Trac tickets. Here’s Josh’s answer:
I wanted a way to make Trac tickets into a printable PDF so I could hang up tickets for a sprint on a bulletin board. Even though the whole point of Trac is to keep all of this information in digital form and avoid a paper trail, it’s always helpful to be able to actually physically move tickets between stages (i.e. staging, qa, production, etc.) Where I previouslt worked, we had bulletin boards for each stage of the process, and in addition to changing a ticket’s progress in the issue tracking software, you’d also move the ticket to the appropriate bulletin board and write notes on it etc. This process worked really well, so I’ve picked it up for my own projects.
I could’ve used wkhtmltopdf
, but I figured html was good enough for now.
You’ll probably have to tweak this just a little, as this includes some custom fields from plugins I’m running (time tracking and QA).
Enjoy!
Here’s the code:
class TracTicketsToPdfTask extends sfBaseTask {
/**
* @see sfTask
*/
protected function configure() {
$this->addOptions(array(
new sfCommandOption('application', null, sfCommandOption::PARAMETER_REQUIRED, 'The application name', 'public'),
new sfCommandOption('env', null, sfCommandOption::PARAMETER_REQUIRED, 'The environment', 'prod'),
new sfCommandOption('filename', null, sfCommandOption::PARAMETER_REQUIRED, 'Filename containing the trac csv report', 'query.csv'),
new sfCommandOption('outfile', null, sfCommandOption::PARAMETER_REQUIRED, 'Filename where report will be written to', 'tickets.html'),
new sfCommandOption('min_id', null, sfCommandOption::PARAMETER_REQUIRED, 'Only include ticket ids greater than or equal to x', 0),
new sfCommandOption('include_tickets', null, sfCommandOption::PARAMETER_REQUIRED, 'Only include ticket ids in this list (separated by commas)', '')
));
$this->namespace = 'yourapp';
$this->name = 'tracTicketsToPdf';
$this->briefDescription = 'Makes a trac report into a printable pdf for sprint tickets';
$this->detailedDescription = "";
}
/**
* @see sfTask
*/
protected function execute($arguments = array(), $options = array()) {
sfContext::createInstance($this->configuration);
$minTicketId = $options['min_id'];
$ticketsToInclude = !$options['include_tickets']) ? null : explode(',', $options['include_tickets']);
ob_start();?>
<link rel="stylesheet" type="text/css" href="<a%20href=" http: target="_blank" style="color: #2a5db0;">http://fonts.googleapis.com/css?family=PT+Sans:regular,bold&subset=latin" />
<style></style>
body {
margin: 0px;
padding: 20px;
font-family: 'PT Sans', Arial, Helvetica, sans-serif;
font-size: 14px;
}
td {
width: 200px;
font-weight: bold;
border: 1px solid black;
padding: 10px;
}
tr.blank td {
height: 100px;
vertical-align: top;
font-weight: normal;
}
<?php <div> //skip the field title line
if (($handle = fopen($options['filename'], "r")) !== FALSE) {
fgetcsv($handle);
$row = 1;
while (($data = fgetcsv($handle)) !== FALSE) {
list($id,$summary,$milestone,$owner,$type,$status,$priority,$qacomplete,$estimatedhours) = $data;
if ($minTicketId && $id
else if ($ticketsToInclude && array_search($id, $ticketsToInclude) === false) continue;
?>
<div>
=$id;?>
=$summary;?>
**Milestone:** =$milestone;?> **Owner:** =$owner;?>
<img src="yourlogo.png" align="right">
&nbsp
<table align="center" style="border-collapse: collapse; border: 1px solid black;">
<tr>
<td>Type</td>
<td>Priority</td>
<td>Est. Hours</td>
<td>QA</td>
</tr>
<tr class="blank">
<td>=$type;?></td>
<td>=$priority;?></td>
<td>=$estimatedhours;?></td>
<td></td>
</tr>
</table>
if ($row % 2 == 0) : ?>
else: ?>
endif; ?>
$row++;
}
fclose($handle);
}
?>
$html = ob_get_clean();
file_put_contents($options['outfile'], $html);
}
}