subscription nearly done

master
joey 2006-04-25 00:22:41 +00:00
parent a804c92abd
commit b7f64d884c
6 changed files with 67 additions and 19 deletions

View File

@ -217,7 +217,8 @@ sub cgi_prefs ($$) { #{{{
eval q{use CGI::FormBuilder}; eval q{use CGI::FormBuilder};
my $form = CGI::FormBuilder->new( my $form = CGI::FormBuilder->new(
title => "preferences", title => "preferences",
fields => [qw(do name password confirm_password email locked_pages)], fields => [qw(do name password confirm_password email
subscriptions locked_pages)],
header => 0, header => 0,
method => 'POST', method => 'POST',
validate => { validate => {
@ -242,6 +243,8 @@ sub cgi_prefs ($$) { #{{{
value => $user_name, force => 1); value => $user_name, force => 1);
$form->field(name => "password", type => "password"); $form->field(name => "password", type => "password");
$form->field(name => "confirm_password", type => "password"); $form->field(name => "confirm_password", type => "password");
$form->field(name => "subscriptions", size => 50,
comment => "(".htmllink("", "GlobList", 1).")");
$form->field(name => "locked_pages", size => 50, $form->field(name => "locked_pages", size => 50,
comment => "(".htmllink("", "GlobList", 1).")"); comment => "(".htmllink("", "GlobList", 1).")");
@ -252,6 +255,8 @@ sub cgi_prefs ($$) { #{{{
if (! $form->submitted) { if (! $form->submitted) {
$form->field(name => "email", force => 1, $form->field(name => "email", force => 1,
value => userinfo_get($user_name, "email")); value => userinfo_get($user_name, "email"));
$form->field(name => "subscriptions", force => 1,
value => userinfo_get($user_name, "subscriptions"));
$form->field(name => "locked_pages", force => 1, $form->field(name => "locked_pages", force => 1,
value => userinfo_get($user_name, "locked_pages")); value => userinfo_get($user_name, "locked_pages"));
} }
@ -266,7 +271,7 @@ sub cgi_prefs ($$) { #{{{
return; return;
} }
elsif ($form->submitted eq "Save Preferences" && $form->validate) { elsif ($form->submitted eq "Save Preferences" && $form->validate) {
foreach my $field (qw(password email locked_pages)) { foreach my $field (qw(password email subscriptions locked_pages)) {
if (length $form->field($field)) { if (length $form->field($field)) {
userinfo_set($user_name, $field, $form->field($field)) || error("failed to set $field"); userinfo_set($user_name, $field, $form->field($field)) || error("failed to set $field");
} }

View File

@ -7,6 +7,7 @@ use strict;
package IkiWiki; 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_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 ($$) { #{{{ sub svn_info ($$) { #{{{
my $field=shift; my $field=shift;
@ -134,7 +135,7 @@ sub rcs_recentchanges ($) { #{{{
elsif ($state eq 'body' && /$div/) { elsif ($state eq 'body' && /$div/) {
my $committype="web"; my $committype="web";
if (defined $message[0] && if (defined $message[0] &&
$message[0]->{line}=~/^web commit by (\w+):?(.*)/) { $message[0]->{line}=~/$svn_webcommit/) {
$user="$1"; $user="$1";
$message[0]->{line}=$2; $message[0]->{line}=$2;
} }
@ -167,11 +168,12 @@ sub rcs_notify () { #{{{
if (! exists $ENV{REV}) { if (! exists $ENV{REV}) {
error("REV is not set, not running from svn post-commit hook, cannot send notifications"); error("REV is not set, not running from svn post-commit hook, cannot send notifications");
} }
my $rev=int(possibly_foolish_untaint($ENV{REV}));
my @changed_pages; my @changed_pages;
foreach my $change (`svnlook changed $config{svnrepo} -r $ENV{REV}`) { foreach my $change (`svnlook changed $config{svnrepo} -r $rev`) {
chomp; chomp $change;
if (/^[A-Z]+\s+\Q$config{svnpath}\E\/(.*)/) { if ($change =~ /^[A-Z]+\s+\Q$config{svnpath}\E\/(.*)/) {
push @changed_pages, $1; push @changed_pages, $1;
} }
} }
@ -179,18 +181,45 @@ sub rcs_notify () { #{{{
require IkiWiki::UserInfo; require IkiWiki::UserInfo;
my @email_recipients=page_subscribers(@changed_pages); my @email_recipients=page_subscribers(@changed_pages);
if (@email_recipients) { if (@email_recipients) {
eval q{use Mail::Sendmail};
# TODO: if a commit spans multiple pages, this will send # TODO: if a commit spans multiple pages, this will send
# subscribers a diff that might contain pages they did not # subscribers a diff that might contain pages they did not
# sign up for. Should separate the diff per page and # sign up for. Should separate the diff per page and
# reassemble into one mail with just the pages subscribed to. # reassemble into one mail with just the pages subscribed to.
my $body=`LANG=C svnlook diff $config{svnrepo} -r $ENV{REV} --no-diff-deleted`; my $diff=`svnlook diff $config{svnrepo} -r $rev --no-diff-deleted`;
my $user=`svnlook author $config{svnrepo} -r $rev`;
my $message=`svnlook log $config{svnrepo} -r $rev`;
if ($message=~/$svn_webcommit/) {
$user="$1";
$message=$2;
}
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) { foreach my $email (@email_recipients) {
sendmail( sendmail(
To => $email, To => $email,
From => "$config{wikiname} <$config{adminemail}>", From => "$config{wikiname} <$config{adminemail}>",
Subject => "$config{wikiname} $ENV{REV} update notification", Subject => $subject,
Message => $body, Message => $template->output,
) or error("Failed to send update notification mail"); ) or error("Failed to send update notification mail");
} }
} }

View File

@ -70,12 +70,12 @@ sub page_subscribers (@) { #{{{
my @ret; my @ret;
my $userinfo=userinfo_retrieve(); my $userinfo=userinfo_retrieve();
foreach my $user (keys %{$userinfo}) { foreach my $user (keys %{$userinfo}) {
if (exists $user->{subscriptions} && if (exists $userinfo->{$user}->{subscriptions} &&
length $user->{subscriptions} && length $userinfo->{$user}->{subscriptions} &&
exists $user->{email} && exists $userinfo->{$user}->{email} &&
length $user->{email} && length $userinfo->{$user}->{email} &&
grep { globmatch($_, $user->{subscriptions}) } @_) { grep { glob_match($_, $userinfo->{$user}->{subscriptions}) } @_) {
push @ret, $user->{email}; push @ret, $userinfo->{$user}->{email};
} }
} }
return @ret; return @ret;

View File

@ -28,7 +28,6 @@ sub gen_wrapper () { #{{{
push @envsave, qw{REMOTE_ADDR QUERY_STRING REQUEST_METHOD REQUEST_URI push @envsave, qw{REMOTE_ADDR QUERY_STRING REQUEST_METHOD REQUEST_URI
CONTENT_TYPE CONTENT_LENGTH GATEWAY_INTERFACE CONTENT_TYPE CONTENT_LENGTH GATEWAY_INTERFACE
HTTP_COOKIE} if $config{cgi}; HTTP_COOKIE} if $config{cgi};
push @envsave, qw{REV} if $config{svn};
my $envsave=""; my $envsave="";
foreach my $var (@envsave) { foreach my $var (@envsave) {
$envsave.=<<"EOF" $envsave.=<<"EOF"
@ -36,6 +35,16 @@ sub gen_wrapper () { #{{{
asprintf(&newenviron[i++], "%s=%s", "$var", s); asprintf(&newenviron[i++], "%s=%s", "$var", s);
EOF EOF
} }
if ($config{svn} && $config{notify}) {
# Support running directly as hooks/post-commit by passing
# $2 in REV in the environment.
$envsave.=<<"EOF"
if (argc == 3)
asprintf(&newenviron[i++], "REV=%s", argv[2]);
else if ((s=getenv("REV")))
asprintf(&newenviron[i++], "%s=%s", "REV", s);
EOF
}
$Data::Dumper::Indent=0; # no newlines $Data::Dumper::Indent=0; # no newlines
my $configstring=Data::Dumper->Dump([\%config], ['*config']); my $configstring=Data::Dumper->Dump([\%config], ['*config']);
@ -56,7 +65,7 @@ extern char **environ;
int main (int argc, char **argv) { int main (int argc, char **argv) {
/* Sanitize environment. */ /* Sanitize environment. */
char *s; char *s;
char *newenviron[$#envsave+4]; char *newenviron[$#envsave+5];
int i=0; int i=0;
$envsave $envsave
newenviron[i++]="HOME=$ENV{HOME}"; newenviron[i++]="HOME=$ENV{HOME}";

View File

@ -1,5 +1,5 @@
When the wiki stores lists of pages, such as pages that are locked or pages When the wiki stores lists of pages, such as pages that are locked or pages
that you want to be emailed if changed, it uses a GlobList. whose commit emails you want subscribe to, it uses a GlobList.
This is a list of page names, separated by white space. The "glob" bit is This is a list of page names, separated by white space. The "glob" bit is
that as well as full page names, it can contain glob patterns. "`*`" stands that as well as full page names, it can contain glob patterns. "`*`" stands

View File

@ -0,0 +1,5 @@
The following change has been made to <TMPL_VAR WIKINAME>
by <TMPL_VAR USER>:
<TMPL_VAR MESSAGE>
<TMPL_VAR DIFF>