commit changes for email subscriptions
authorjoey <joey@0fa5a96a-9a0e-0410-b3b2-a0fd24251071>
Mon, 24 Apr 2006 23:09:26 +0000 (23:09 +0000)
committerjoey <joey@0fa5a96a-9a0e-0410-b3b2-a0fd24251071>
Mon, 24 Apr 2006 23:09:26 +0000 (23:09 +0000)
IkiWiki/CGI.pm
IkiWiki/Rcs/SVN.pm
IkiWiki/Rcs/Stub.pm
IkiWiki/Render.pm
IkiWiki/UserInfo.pm [new file with mode: 0644]
IkiWiki/Wrapper.pm
debian/changelog
debian/postinst
ikiwiki

index 8201351ca0e54608d983dbd5030e989e37f3d0e8..1d642687bbefa7820257fce1dc9994ed42476959 100644 (file)
@@ -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");
index c6f8f2ab1c53fddef977507f68f985a158eb48c6..dd74a05773fec68d477c94aca0666892ec74615b 100644 (file)
@@ -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) {
index d2a6ad003afca02868e0e587d22d8e0649e1703d..9bbfde3527619aa8d32d1609c76ebbb2e5ae3e79 100644 (file)
@@ -23,6 +23,9 @@ sub rcs_add ($) {
 sub rcs_recentchanges ($) {
 }
 
+sub rcs_notify () {
+}
+
 sub rcs_getctime () {
        error "getctime not implemented";
 }
index 7148d754ec54e21524f4700efa43fe243678ef67..dfa598da0e4e0f8773d9b19a83464ea52f408f13 100644 (file)
@@ -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 (file)
index 0000000..f4e2615
--- /dev/null
@@ -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
index 2e4925a1f049c4d032a853c6443b8bce433b9401..238f71a91bdc28360e6a0910b1d391c8d45e25d0 100644 (file)
@@ -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"
index 4cc350333d09cb7881476b0aa7ee773d179f23c8..460b260d0dfbcc2ebd4a7954a333b436ac664e6a 100644 (file)
@@ -1,4 +1,4 @@
-ikiwiki (0.1) unstable; urgency=low
+ikiwiki (0.2) unstable; urgency=low
 
   * Initial release.
 
index e84955daf62ba5b3d6921259765436b82d2baa19..be5f539396741fac81cbe3f878e870b9cdd98e58 100755 (executable)
@@ -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 6bf58017d1246ed774b6c9e03ccfd584658c3372..3cf2a7cb3a0f49fc27c2197a34391602524d17d0 100755 (executable)
--- 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();