summaryrefslogtreecommitdiff
path: root/IkiWiki
diff options
context:
space:
mode:
Diffstat (limited to 'IkiWiki')
-rw-r--r--IkiWiki/CGI.pm4
-rw-r--r--IkiWiki/Rcs/SVN.pm39
-rw-r--r--IkiWiki/Rcs/Stub.pm3
-rw-r--r--IkiWiki/Render.pm2
-rw-r--r--IkiWiki/UserInfo.pm84
-rw-r--r--IkiWiki/Wrapper.pm1
6 files changed, 126 insertions, 7 deletions
diff --git a/IkiWiki/CGI.pm b/IkiWiki/CGI.pm
index 8201351ca..1d642687b 100644
--- a/IkiWiki/CGI.pm
+++ b/IkiWiki/CGI.pm
@@ -2,6 +2,7 @@
use warnings;
use strict;
+use IkiWiki::UserInfo;
package IkiWiki;
@@ -190,10 +191,9 @@ sub cgi_signin ($$) { #{{{
);
eval q{use Mail::Sendmail};
- my ($fromhost) = $config{cgiurl} =~ m!/([^/]+)!;
sendmail(
To => userinfo_get($user_name, "email"),
- From => "$config{wikiname} admin <".(getpwuid($>))[0]."@".$fromhost.">",
+ From => "$config{wikiname} admin <$config{adminemail}>",
Subject => "$config{wikiname} information",
Message => $template->output,
) or error("Failed to send mail");
diff --git a/IkiWiki/Rcs/SVN.pm b/IkiWiki/Rcs/SVN.pm
index c6f8f2ab1..dd74a0577 100644
--- a/IkiWiki/Rcs/SVN.pm
+++ b/IkiWiki/Rcs/SVN.pm
@@ -104,10 +104,6 @@ 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);
@@ -121,7 +117,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;
@@ -167,6 +163,39 @@ 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 @changed_pages;
+ foreach my $change (`svnlook changed $config{svnrepo} -r $ENV{REV}`) {
+ chomp;
+ if (/^[A-Z]+\s+\Q$config{svnpath}\E\/(.*)/) {
+ push @changed_pages, $1;
+ }
+ }
+
+ require IkiWiki::UserInfo;
+ my @email_recipients=page_subscribers(@changed_pages);
+ if (@email_recipients) {
+ eval q{use Mail::Sendmail};
+ # 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 $body=`LANG=C svnlook diff $config{svnrepo} -r $ENV{REV} --no-diff-deleted`;
+ foreach my $email (@email_recipients) {
+ sendmail(
+ To => $email,
+ From => "$config{wikiname} <$config{adminemail}>",
+ Subject => "$config{wikiname} $ENV{REV} update notification",
+ Message => $body,
+ ) or error("Failed to send update notification mail");
+ }
+ }
+} #}}}
+
sub rcs_getctime () { #{{{
eval q{use Date::Parse};
foreach my $page (keys %pagectime) {
diff --git a/IkiWiki/Rcs/Stub.pm b/IkiWiki/Rcs/Stub.pm
index d2a6ad003..9bbfde352 100644
--- a/IkiWiki/Rcs/Stub.pm
+++ b/IkiWiki/Rcs/Stub.pm
@@ -23,6 +23,9 @@ sub rcs_add ($) {
sub rcs_recentchanges ($) {
}
+sub rcs_notify () {
+}
+
sub rcs_getctime () {
error "getctime not implemented";
}
diff --git a/IkiWiki/Render.pm b/IkiWiki/Render.pm
index 7148d754e..dfa598da0 100644
--- a/IkiWiki/Render.pm
+++ b/IkiWiki/Render.pm
@@ -1,3 +1,5 @@
+#!/usr/bin/perl
+
package IkiWiki;
use warnings;
diff --git a/IkiWiki/UserInfo.pm b/IkiWiki/UserInfo.pm
new file mode 100644
index 000000000..f4e261563
--- /dev/null
+++ b/IkiWiki/UserInfo.pm
@@ -0,0 +1,84 @@
+#!/usr/bin/perl
+
+use warnings;
+use strict;
+use Storable;
+
+package IkiWiki;
+
+sub userinfo_retrieve () { #{{{
+ my $userinfo=eval{ Storable::lock_retrieve("$config{wikistatedir}/userdb") };
+ return $userinfo;
+} #}}}
+
+sub userinfo_store ($) { #{{{
+ my $userinfo=shift;
+
+ my $oldmask=umask(077);
+ my $ret=Storable::lock_store($userinfo, "$config{wikistatedir}/userdb");
+ umask($oldmask);
+ return $ret;
+} #}}}
+
+sub userinfo_get ($$) { #{{{
+ my $user=shift;
+ my $field=shift;
+
+ my $userinfo=userinfo_retrieve();
+ if (! defined $userinfo ||
+ ! exists $userinfo->{$user} || ! ref $userinfo->{$user} ||
+ ! exists $userinfo->{$user}->{$field}) {
+ return "";
+ }
+ return $userinfo->{$user}->{$field};
+} #}}}
+
+sub userinfo_set ($$$) { #{{{
+ my $user=shift;
+ my $field=shift;
+ my $value=shift;
+
+ my $userinfo=userinfo_retrieve();
+ if (! defined $userinfo ||
+ ! exists $userinfo->{$user} || ! ref $userinfo->{$user}) {
+ return "";
+ }
+
+ $userinfo->{$user}->{$field}=$value;
+ return userinfo_store($userinfo);
+} #}}}
+
+sub userinfo_setall ($$) { #{{{
+ my $user=shift;
+ my $info=shift;
+
+ my $userinfo=userinfo_retrieve();
+ if (! defined $userinfo) {
+ $userinfo={};
+ }
+ $userinfo->{$user}=$info;
+ return userinfo_store($userinfo);
+} #}}}
+
+sub is_admin ($) { #{{{
+ my $user_name=shift;
+
+ return grep { $_ eq $user_name } @{$config{adminuser}};
+} #}}}
+
+sub page_subscribers (@) { #{{{
+ my @ret;
+ my $userinfo=userinfo_retrieve();
+ foreach my $user (keys %{$userinfo}) {
+ if (exists $user->{subscriptions} &&
+ length $user->{subscriptions} &&
+ exists $user->{email} &&
+ length $user->{email} &&
+ grep { globmatch($_, $user->{subscriptions}) } @_) {
+ push @ret, $user->{email};
+ }
+ }
+ return @ret;
+} #}}}
+
+1
diff --git a/IkiWiki/Wrapper.pm b/IkiWiki/Wrapper.pm
index 2e4925a1f..238f71a91 100644
--- a/IkiWiki/Wrapper.pm
+++ b/IkiWiki/Wrapper.pm
@@ -28,6 +28,7 @@ sub gen_wrapper () { #{{{
push @envsave, qw{REMOTE_ADDR QUERY_STRING REQUEST_METHOD REQUEST_URI
CONTENT_TYPE CONTENT_LENGTH GATEWAY_INTERFACE
HTTP_COOKIE} if $config{cgi};
+ push @envsave, qw{REV} if $config{svn};
my $envsave="";
foreach my $var (@envsave) {
$envsave.=<<"EOF"