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.
8 Comments
Cool! Haven't used it yet, but you hardcode ticket #10 in one of your error messages.
Good catch. That was left over from my copy/paste of the example code. Fixed above and in the code I actually use.
Nice one, I'll definitely find this useful and it worked like a treat when I worked out what your .pause file looked like.
Of course! I forget that not everyone automates CPAN uploads with cpan_upload. (And actually, I now let Dist::Zilla do it for me.)
hmm.... it downloads attachments... I'll have to see if I can modify it to download the email with full headers for git am patches. http://xenoterracide.blogspot.com/2010/06/rt-git-workflow.html which are great if you use git ;)
That would be great. I did see that there are "attachments" without names, which looked like it might have been an email, but I didn't really investigate.
why on earth does this... 'name' field ( for posting comments ) either not allow spaces, or perhaps parenthesis.... and while denying it it gives no error...
The next step would be to create have a tool that can generate a distropref from an RT ticket.
Distroprefs are metadata that can be used by CPAN.pm to apply a patch to a distribution before building it.
One Trackback
[...] A useful tip for module maintainers from David Golden: how to download RT patches from the command line. [...]