summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorjoey <joey@0fa5a96a-9a0e-0410-b3b2-a0fd24251071>2006-04-24 23:09:26 +0000
committerjoey <joey@0fa5a96a-9a0e-0410-b3b2-a0fd24251071>2006-04-24 23:09:26 +0000
commit13e3bf867157226076fcc14a0d3875fd129a66c7 (patch)
tree173e406ad45bd94118d0400f7be91703be8cf0c7
parent698aeb20168b7e22a2ce3618a28fdee32ed4a417 (diff)
commit changes for email subscriptions
-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
-rw-r--r--debian/changelog2
-rwxr-xr-xdebian/postinst2
-rwxr-xr-xikiwiki64
9 files changed, 137 insertions, 64 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"
diff --git a/debian/changelog b/debian/changelog
index 4cc350333..460b260d0 100644
--- a/debian/changelog
+++ b/debian/changelog
@@ -1,4 +1,4 @@
-ikiwiki (0.1) unstable; urgency=low
+ikiwiki (0.2) unstable; urgency=low
* Initial release.
diff --git a/debian/postinst b/debian/postinst
index e84955daf..be5f53939 100755
--- a/debian/postinst
+++ b/debian/postinst
@@ -4,7 +4,7 @@ set -e
# Change this when some incompatible change is made that requires
# rebuilding all wikis.
-firstcompat=0.1
+firstcompat=0.2
wikilist=/etc/ikiwiki/wikilist
diff --git a/ikiwiki b/ikiwiki
index 6bf58017d..3cf2a7cb3 100755
--- a/ikiwiki
+++ b/ikiwiki
@@ -27,6 +27,7 @@ sub getconfig () { #{{{
default_pageext => ".mdwn",
cgi => 0,
svn => 1,
+ notify => 0,
url => '',
cgiurl => '',
historyurl => '',
@@ -39,12 +40,15 @@ sub getconfig () { #{{{
hyperestraier => 0,
wrapper => undef,
wrappermode => undef,
+ svnrepo => undef,
+ svnpath => "trunk",
srcdir => undef,
destdir => undef,
templatedir => "/usr/share/ikiwiki/templates",
underlaydir => "/usr/share/ikiwiki/basewiki",
setup => undef,
adminuser => undef,
+ adminemail => undef,
);
eval q{use Getopt::Long};
@@ -61,10 +65,14 @@ sub getconfig () { #{{{
"hyperestraier" => \$config{hyperestraier},
"rss!" => \$config{rss},
"cgi!" => \$config{cgi},
+ "notify!" => \$config{notify},
"url=s" => \$config{url},
"cgiurl=s" => \$config{cgiurl},
"historyurl=s" => \$config{historyurl},
"diffurl=s" => \$config{diffurl},
+ "svnrepo" => \$config{svnrepo},
+ "svnpath" => \$config{svnpath},
+ "adminemail=s" => \$config{adminemail},
"exclude=s@" => sub {
$config{wiki_file_prune_regexp}=qr/$config{wiki_file_prune_regexp}|$_[1]/;
},
@@ -437,61 +445,6 @@ sub misctemplate ($$) { #{{{
return $template->output;
}#}}}
-sub userinfo_get ($$) { #{{{
- my $user=shift;
- my $field=shift;
-
- eval q{use Storable};
- my $userdata=eval{ Storable::lock_retrieve("$config{wikistatedir}/userdb") };
- if (! defined $userdata || ! ref $userdata ||
- ! exists $userdata->{$user} || ! ref $userdata->{$user} ||
- ! exists $userdata->{$user}->{$field}) {
- return "";
- }
- return $userdata->{$user}->{$field};
-} #}}}
-
-sub userinfo_set ($$$) { #{{{
- my $user=shift;
- my $field=shift;
- my $value=shift;
-
- eval q{use Storable};
- my $userdata=eval{ Storable::lock_retrieve("$config{wikistatedir}/userdb") };
- if (! defined $userdata || ! ref $userdata ||
- ! exists $userdata->{$user} || ! ref $userdata->{$user}) {
- return "";
- }
-
- $userdata->{$user}->{$field}=$value;
- my $oldmask=umask(077);
- my $ret=Storable::lock_store($userdata, "$config{wikistatedir}/userdb");
- umask($oldmask);
- return $ret;
-} #}}}
-
-sub userinfo_setall ($$) { #{{{
- my $user=shift;
- my $info=shift;
-
- eval q{use Storable};
- my $userdata=eval{ Storable::lock_retrieve("$config{wikistatedir}/userdb") };
- if (! defined $userdata || ! ref $userdata) {
- $userdata={};
- }
- $userdata->{$user}=$info;
- my $oldmask=umask(077);
- my $ret=Storable::lock_store($userdata, "$config{wikistatedir}/userdb");
- umask($oldmask);
- return $ret;
-} #}}}
-
-sub is_admin ($) { #{{{
- my $user_name=shift;
-
- return grep { $_ eq $user_name } @{$config{adminuser}};
-} #}}}
-
sub glob_match ($$) { #{{{
my $page=shift;
my $glob=shift;
@@ -544,6 +497,7 @@ sub main () { #{{{
loadindex();
require IkiWiki::Render;
rcs_update();
+ rcs_notify() if $config{notify};
rcs_getctime() if $config{getctime};
refresh();
saveindex();