]> sipb.mit.edu Git - ikiwiki.git/blob - IkiWiki/Plugin/changemail.pm
changemail: New plugin, sends emails about changed pages.
[ikiwiki.git] / IkiWiki / Plugin / changemail.pm
1 #!/usr/bin/perl
2 package IkiWiki::Plugin::changemail;
3
4 use warnings;
5 use strict;
6 use IkiWiki 3.00;
7
8 sub import {
9         hook(type => "getsetup", id => "changemail",  call => \&getsetup);
10         hook(type => "change", id => "changemail", call => \&notify);
11 }
12
13 sub getsetup () {
14         return
15                 plugin => {
16                         safe => 1,
17                         rebuild => 0,
18                         section => "misc",
19                 },
20 }
21
22 sub notify (@) {
23         my @files=@_;
24         return unless @files;
25
26         eval q{use Mail::Sendmail};
27         error $@ if $@;
28         eval q{use IkiWiki::UserInfo};
29
30         # Daemonize, in case the mail sending takes a while.
31         defined(my $pid = fork) or error("Can't fork: $!");
32         return if $pid; # parent
33         chdir '/';
34         open STDIN, '/dev/null';
35         open STDOUT, '>/dev/null';
36         POSIX::setsid() or error("Can't start a new session: $!");
37         open STDERR, '>&STDOUT' or error("Can't dup stdout: $!");
38
39         # Don't need to keep a lock on the wiki as a daemon.
40         IkiWiki::unlockwiki();
41
42         my $userinfo=IkiWiki::userinfo_retrieve();
43         exit 0 unless defined $userinfo;
44
45         foreach my $user (keys %$userinfo) {
46                 my $pagespec=$userinfo->{$user}->{"subscriptions"};
47                 next unless defined $pagespec && length $pagespec;
48                 my $email=$userinfo->{$user}->{email};
49                 next unless defined $email && length $email;
50
51                 foreach my $file (@files) {
52                         my $page=pagename($file);
53                         next unless pagespec_match($page, $pagespec);
54                         my $ispage=defined pagetype($file);
55                         my $url;
56                         if (! IkiWiki::isinternal($page)) {
57                                 $url=urlto($page, undef, 1);
58                         }
59                         elsif (defined $pagestate{$page}{meta}{permalink}) {
60                                 # need to use permalink for an internal page
61                                 $url=$pagestate{$page}{meta}{permalink};
62                         }
63                         else {
64                                 $url=$config{wikiurl}; # crummy fallback url
65                         }
66                         my $template=template("changemail.tmpl");
67                         $template->param(
68                                 wikiname => $config{wikiname},
69                                 url => $url,
70                                 prefsurl => IkiWiki::cgiurl(do => "prefs"),
71                                 ispage => $ispage,
72                                 content => $ispage ? readfile(srcfile($file)) : "",
73                         );
74                         #translators: The two variables are the name of the wiki,
75                         #translators: and a page that was changed.
76                         #translators: This is used as the subject of a commit email.
77                         my $subject=sprintf(gettext("%s: change notification for %s"),
78                                 $config{wikiname}, $page);
79                         sendmail(
80                                 To => $email,
81                                 From => "$config{wikiname} <$config{adminemail}>",
82                                 Subject => $subject,
83                                 Message => $template->output,
84                         );
85                 }
86         }
87
88         exit 0; # daemon child
89 }
90
91 1