|
This page is kept for historical interest. Don't expect its contents to be relevant to the current day. |
#!/usr/bin/perl -w
# Script to pull bug info from SVN and dump them
# to a log to be used for IRC bot.
# Original version by AzaToth 2006-12-23
use strict;
use utf8;
my $TYPES = {
'Log Message' => 'msg',
'Property Changed' => 'prop',
'Modified Paths' => 'mod',
'Added Paths' => 'add',
'Deleted Paths' => 'del',
};
my $FILES = {
'mod' => 'modified',
'add' => 'added',
'del' => 'deleted',
'prop' => 'changed property on',
}; # will contain list of files
my $MAX_COMMENT_LENGTH = 300;
my $LINE_LENGTH = 130;
my $MAX_ONELINE_MODIFIER = 1.5;
my $VIEWVC_URL = "http://svn.wikimedia.org/viewvc/mediawiki?view=rev&revision=";
$/ = undef;
my $output;
my $filelist = '';
my @allfiles;
my %fields;
my ($author, $rev, $date, $path);
my $contents = <STDIN>;
$contents =~ s/\r\n/\n/g;
if ($contents =~ /^Content-Transfer-Encoding: base64/m) {
use MIME::Base64;
$contents =~ s/.*?\n([\S\n]+)\s*$/$1/sg;
$contents = decode_base64($contents);
$contents =~ s/\w+[^\n]*?\n={20,}.*//s;
} else {
$contents =~ s/^\s*.*?\n{2,}(.*?)\w+[^\n]*?\n={20,}.*/$1/s;
}
$contents =~ s/^Author:\s+(\S+)\n//m and $author = $1 or $author = 'none';
$contents =~ s/^Revision:\s+(\d+)\n//m and $rev = $1 or $rev = '0';
$contents =~ s/^Date:\s+(.*?)\n\n//m and $date = $1 or $date = 'now';
chomp($contents);
use Data::Dumper;
my @field = split /\s*\n*(\w+\s\w+):\n-{5,}\n\s*/s, $contents;
shift @field;
foreach (my $i=0; $i <= $#field; $i += 2) {
my $type = $TYPES->{$field[$i]};
if(defined $FILES->{$type}) {
my $file_list = $field[$i + 1];
my @files = split /\s+/, $file_list;
$fields{$type} = \@files;
} else {
$fields{$type} = $field[$i + 1];
}
}
foreach my $key(keys %{$FILES}) {
foreach my $file(@{$fields{$key}}) {
push @allfiles, [split /\//, $file];
}
}
my $nbr_of_files = $#allfiles + 1;
my @base = @{ shift @allfiles };
foreach my $file (@allfiles) {
for my $i(0..$#base) {
pop @base if defined $base[$i] and $$file[$i] ne $base[$i];
}
}
$path = join '/', @base;
my %alldirs;
foreach my $file (@allfiles) {
my @f = @$file;
pop @f;
my $key = join '/', @f;
next if length $key <= length $path;
$key = substr ($key, (length $path)+1);
$alldirs{$key} = 1;
}
my @alldirs = keys %alldirs;
my $nbr_of_dirs = $#alldirs + 1;
$nbr_of_dirs = 1 if $nbr_of_dirs < 1;
if ($nbr_of_files <= 3 and $nbr_of_files > 1) {
my @extra_files;
foreach my $file(@allfiles) {
my $nfile = substr(join('/', @{$file}), (length $path)+1);
$nfile =~ s/\n//g;
push @extra_files, $nfile;
}
$path .= " (" . join( ', ', @extra_files). ")";
} elsif($nbr_of_files > 1) {
$path .= " ($nbr_of_files file".($nbr_of_files>1?'s':'')." in $nbr_of_dirs dir".($nbr_of_dirs>1?'s':'').")";
}
$path = 'strange places' if $path eq '';
my @files;
if( $nbr_of_files > 0 ) {
foreach my $key(keys %{$FILES}) {
if(defined $fields{$key} and $#{$fields{$key}} +1 > 0) {
push @files, "$FILES->{$key} \002".($#{$fields{$key}}+1)."\002";
}
}
$filelist = join( ', ' , @files) . ' ' . ( $nbr_of_files > 1 ? 'files' : 'file');
}
$output = "\002SVN\002 (\00303r$rev\003): \00302$author\003 in \00303$path\003 $filelist";
$fields{'msg'} =~ s/([^\n]{$LINE_LENGTH,}?)\s/$1\n/g;
my $submsg = substr ($fields{'msg'}, 0 , $MAX_COMMENT_LENGTH);
if(length $fields{'msg'} > length $submsg) {
substr( $submsg, -3) = '...';
}
if(length ($output) + length ($submsg) <= $LINE_LENGTH * $MAX_ONELINE_MODIFIER) {
$output .= ": $submsg\n";
} else {
$output .= ":\n". join ("\n", map { $_ = "\002|\002 $_"} split /\n/, $submsg) ."\n";
}
$output .= "$VIEWVC_URL$rev\n";
if ($output)
{
open (OUT, ">>/var/wikisvn/wikisvn.log");
print $output;
#print OUT $output;
close OUT;
}