X-Git-Url: https://sipb.mit.edu/gitweb.cgi/ikiwiki.git/blobdiff_plain/975ae0944cdd18a510d803da7a499c2247ac855e..5cd32c2eeeafc5e9f3feae7983fc48a9711462a3:/IkiWiki/Rcs/SVN.pm diff --git a/IkiWiki/Rcs/SVN.pm b/IkiWiki/Rcs/SVN.pm index 02fc3ed31..358f46948 100644 --- a/IkiWiki/Rcs/SVN.pm +++ b/IkiWiki/Rcs/SVN.pm @@ -7,6 +7,7 @@ use strict; package IkiWiki; my $svn_log_infoline=qr/^r(\d+)\s+\|\s+([^\s]+)\s+\|\s+(\d+-\d+-\d+\s+\d+:\d+:\d+\s+[-+]?\d+).*/; +my $svn_webcommit=qr/^web commit by (\w+):?(.*)/; sub svn_info ($$) { #{{{ my $field=shift; @@ -104,14 +105,10 @@ sub rcs_recentchanges ($) { #{{{ if (-d "$config{srcdir}/.svn") { my $svn_url=svn_info("URL", $config{srcdir}); - # FIXME: currently assumes that the wiki is somewhere - # under trunk in svn, doesn't support other layouts. - my ($svn_base)=$svn_url=~m!(/trunk(?:/.*)?)$!; - my $div=qr/^--------------------+$/; my $state='start'; my ($rev, $user, $when, @pages, @message); - foreach (`LANG=C svn log --limit $num -v '$svn_url'`) { + foreach (`LANG=C svn log -v '$svn_url'`) { chomp; if ($state eq 'start' && /$div/) { $state='header'; @@ -121,7 +118,7 @@ sub rcs_recentchanges ($) { #{{{ $user=$2; $when=concise(ago(time - str2time($3))); } - elsif ($state eq 'header' && /^\s+[A-Z]\s+\Q$svn_base\E\/([^ ]+)(?:$|\s)/) { + elsif ($state eq 'header' && /^\s+[A-Z]+\s+\/\Q$config{svnpath}\E\/([^ ]+)(?:$|\s)/) { my $file=$1; my $diffurl=$config{diffurl}; $diffurl=~s/\[\[file\]\]/$file/g; @@ -138,7 +135,7 @@ sub rcs_recentchanges ($) { #{{{ elsif ($state eq 'body' && /$div/) { my $committype="web"; if (defined $message[0] && - $message[0]->{line}=~/^web commit by (\w+):?(.*)/) { + $message[0]->{line}=~/$svn_webcommit/) { $user="$1"; $message[0]->{line}=$2; } @@ -167,6 +164,68 @@ sub rcs_recentchanges ($) { #{{{ return @ret; } #}}} +sub rcs_notify () { #{{{ + if (! exists $ENV{REV}) { + error("REV is not set, not running from svn post-commit hook, cannot send notifications"); + } + my $rev=int(possibly_foolish_untaint($ENV{REV})); + + my $user=`svnlook author $config{svnrepo} -r $rev`; + chomp $user; + my $message=`svnlook log $config{svnrepo} -r $rev`; + if ($message=~/$svn_webcommit/) { + $user="$1"; + $message=$2; + } + + my @changed_pages; + foreach my $change (`svnlook changed $config{svnrepo} -r $rev`) { + chomp $change; + if ($change =~ /^[A-Z]+\s+\Q$config{svnpath}\E\/(.*)/) { + push @changed_pages, $1; + } + } + + require IkiWiki::UserInfo; + my @email_recipients=commit_notify_list($user, @changed_pages); + if (@email_recipients) { + # TODO: if a commit spans multiple pages, this will send + # subscribers a diff that might contain pages they did not + # sign up for. Should separate the diff per page and + # reassemble into one mail with just the pages subscribed to. + my $diff=`svnlook diff $config{svnrepo} -r $rev --no-diff-deleted`; + + my $subject="$config{wikiname} update of "; + if (@changed_pages > 2) { + $subject.="$changed_pages[0] $changed_pages[1] etc"; + } + else { + $subject.=join(" ", @changed_pages); + } + $subject.=" by $user"; + + my $template=HTML::Template->new( + filename => "$config{templatedir}/notifymail.tmpl" + ); + $template->param( + wikiname => $config{wikiname}, + diff => $diff, + user => $user, + message => $message, + ); + + eval q{use Mail::Sendmail}; + foreach my $email (@email_recipients) { + sendmail( + To => $email, + From => "$config{wikiname} <$config{adminemail}>", + Subject => $subject, + Message => $template->output, + ) or error("Failed to send update notification mail"); + } + } +} #}}} + sub rcs_getctime () { #{{{ eval q{use Date::Parse}; foreach my $page (keys %pagectime) {