Downloading RT patches from the command line

I love it when people post patches to RT, but I don’t really like the work required to download them from the web interface. I know there’s an rt command line client somewhere, but the last time I tried it, it didn’t work very well for me. Thankfully, with the help of RT::Client::REST, I whipped up a short program that will take a ticket number, pluck my credentials from my .pause file, and save the attachments into the current directory.

#!/usr/bin/env perl
use 5.010;
use strict;
use warnings;
use autodie;
use Encode qw/decode/;
use Error qw(:try);
use Path::Class;
use RT::Client::REST;
use RT::Client::REST::Ticket;

my %credential = split " ", file($ENV{HOME}, '.pause')->slurp;
my $user = lc $credential{user};
my $pass = $credential{password};
my $id = shift(@ARGV) || die "No ticket # provided";
$id =~ s{^(?:rt#?)}{};
die "Ticket must be an integer" if $id =~ /\D/;

my $rt = RT::Client::REST->new(
  server => 'http://rt.cpan.org/',
  timeout => 30,
);

try {
  $rt->login(username => $user, password => $pass);
} catch Exception::Class::Base with {
  die "problem logging in: ", shift->message;
};

my $ticket;
try {
  $ticket = RT::Client::REST::Ticket->new( rt => $rt, id => $id);
} catch RT::Client::REST::UnauthorizedActionException with {
  print "You are not authorized to view ticket $id\n";
} catch RT::Client::REST::Exception with {
  die "problem getting $id, ", shift->message;
};

try {
  my $iter = $ticket->attachments->get_iterator;
  while ( my $i = $iter->() ) {
    $i->retrieve;
    my $name = $i->file_name or next;
    my $encoding = $i->content_encoding;
    $encoding = '' if $encoding eq 'none';
    my $string = $encoding ? 
      decode( $encoding, $i->content, 1 ) : $i->content; 
    say "Writing $name";
    file($name)->openw->printflush($string);
  }
} catch RT::Client::REST::Exception with {
  die "problem getting attachments from $id, ", shift->message;
};

This is mostly just some cut/paste/modify work with the relevant synopses in the documentation. There was a little trial-and-error required, particularly in how encoding was being passed through, but it seems to work. I was able to download a patch while connected via ssh, which is exactly what I was looking for.

Update: I fixed a hardcoded “#10” in an error message.