#!/usr/bin/perl

use Email::MIME;
use WWW::Mechanize;
use Text::Iconv;
use Encode;

## Change this!!!
my $trac_base = 'http://bugs.yourproject.org/trac/yourproject/';
my $test = 1;

## Also, you may have to change the regex that detects if the mail came from
## Trac itself to prevent loops, and most likely the ->click() line below
## because I renamed the form buttons, hoping to avoid some spam.

my $from, $ticket, $subject, $charset;

my $rawmail, $mail;
{
	local $/;
	undef $/;
	$rawmail = <STDIN>;
}

my $parsed = Email::MIME->new( $rawmail );
for $part ( $parsed->parts )
{
	if( $part->content_type =~ m/^text\/plain\b/ && $part->filename eq '' )
	{
		$mail = $part->body;
		$part->content_type =~ m/charset=['"]?(.+?)['"]?(\s|$)/;
		$charset = $1;
		last;
	}
}

if( $mail eq '' )
{
	print( STDERR 'No suitable message body found.' . "\n" );
	exit( 1 );
}

$mail =~ s/\r//g;
# Strip the .sig
$mail =~ s/\n+-- \n.*$//s;

if( !defined( $subject = $parsed->header( 'Subject' ) ) || $subject !~ m/^.*?#([1-9][0-9]*):/ )
{
	print( STDERR 'Couldn\'t figure out ticket#' . "\n" );
	exit( 1 );
}
$ticket = $1;

if( !defined( $from = $parsed->header( 'From' ) ) )
{
	print( STDERR 'Couldn\'t figure out sender' . "\n" );
	exit( 1 );
}

if( $from =~ m/www-data/ )
{
	# This is from Trac itself, let's not make a loop.
	exit( 0 );
}

# Not too many blank lines.
$mail =~ s/\n{2,}/\n\n/g;

if( $mail =~ m/\n *>[^\n]*$/ )
{
	# There will probably still be a quote header, so let's at least keep
	# some kind of [snip] thingy.
	$mail =~ s/(\n *>[^\n]*)*$/\n> [quote removed]/;
}
elsif( $mail =~ m/^>/m )
{
	# I'll assume that properly quoted mails (hopefully) also have a proper
	# layout that shouldn't be ruined by Trac.
	$mail =~ s/\n/[[BR]]\n/g;
}
else
{
	# No quotes at all in this mail, so let's hope the layout is okay already.
}

$from = Encode::encode( "utf-8", $from );
if( $charset ne '' && $charset !~ m/^(utf-?8|us[-_]?ascii)$/i )
{
	my $converter = Text::Iconv->new( $charset, 'utf-8');
	$mail = $converter->convert( $mail );
}

my $mech = WWW::Mechanize->new();

$mech->get( $trac_base . 'ticket/' . $ticket );
$mech->form_with_fields( 'author', 'comment' );
$mech->set_fields( 'author' => $from,
                   'comment' => $mail );

if( $test )
{
	$mech->click( 'preview' );
	print $mech->content;
}
else
{
	$mech->click( 'submit' );
}
