2 package IkiWiki::Plugin::notifyemail;
9 hook(type => "formbuilder", id => "notifyemail", call => \&formbuilder);
10 hook(type => "getsetup", id => "notifyemail", call => \&getsetup);
11 hook(type => "changes", id => "notifyemail", call => \¬ify);
24 my $form=$params{form};
25 return unless $form->title eq "preferences";
26 my $session=$params{session};
27 my $username=$session->param("name");
28 $form->field(name => "subscriptions", size => 50,
29 fieldset => "preferences",
30 comment => "(".htmllink("", "", "ikiwiki/PageSpec", noimageinline => 1).")");
31 if (! $form->submitted) {
32 $form->field(name => "subscriptions", force => 1,
33 value => getsubscriptions($username));
35 elsif ($form->submitted eq "Save Preferences" && $form->validate &&
36 defined $form->field("subscriptions")) {
37 setsubscriptions($username, scalar $form->field('subscriptions'));
41 sub getsubscriptions ($) {
43 eval q{use IkiWiki::UserInfo};
45 IkiWiki::userinfo_get($user, "subscriptions");
48 sub setsubscriptions ($$) {
50 my $subscriptions=shift;
51 eval q{use IkiWiki::UserInfo};
53 IkiWiki::userinfo_set($user, "subscriptions", $subscriptions);
56 # Called by other plugins to subscribe the user to a pagespec.
59 my $addpagespec=shift;
60 my $pagespec=getsubscriptions($user);
61 setsubscriptions($user,
62 length $pagespec ? $pagespec." or ".$addpagespec : $addpagespec);
65 # Called by other plugins to subscribe an email to a pagespec.
66 sub anonsubscribe ($$) {
68 my $addpagespec=shift;
69 if (IkiWiki::Plugin::passwordauth->can("anonuser")) {
70 my $user=IkiWiki::Plugin::passwordauth::anonuser($email);
71 if (! defined $user) {
72 error(gettext("Cannot subscribe your email address without logging in."));
74 subscribe($user, $addpagespec);
81 return if $config{rebuild};
83 eval q{use Mail::Sendmail};
85 eval q{use IkiWiki::UserInfo};
90 # Daemonize, in case the mail sending takes a while.
91 defined(my $pid = fork) or error("Can't fork: $!");
92 return if $pid; # parent
94 open STDIN, '/dev/null';
95 open STDOUT, '>/dev/null';
96 POSIX::setsid() or error("Can't start a new session: $!");
97 open STDERR, '>&STDOUT' or error("Can't dup stdout: $!");
99 # Don't need to keep a lock on the wiki as a daemon.
100 IkiWiki::unlockwiki();
102 my $userinfo=IkiWiki::userinfo_retrieve();
103 exit 0 unless defined $userinfo;
105 foreach my $user (keys %$userinfo) {
106 my $pagespec=$userinfo->{$user}->{"subscriptions"};
107 next unless defined $pagespec && length $pagespec;
108 my $email=$userinfo->{$user}->{email};
109 next unless defined $email && length $email;
111 foreach my $file (@files) {
112 my $page=pagename($file);
113 next unless pagespec_match($page, $pagespec);
115 my $showcontent=defined pagetype($file);
117 $content=eval { readfile(srcfile($file)) };
118 $showcontent=0 if $@;
121 if (! IkiWiki::isinternal($page)) {
122 $url=urlto($page, undef, 1);
124 elsif (defined $pagestate{$page}{meta}{permalink}) {
125 # need to use permalink for an internal page
126 $url=URI->new_abs($pagestate{$page}{meta}{permalink}, $config{url});
129 $url=$config{url}; # crummy fallback url
132 if (defined $pagestate{$page}{meta}{title} &&
133 length $pagestate{$page}{meta}{title}) {
134 $pagedesc=qq{"$pagestate{$page}{meta}{title}"};
136 my $subject=gettext("change notification:")." ".$pagedesc;
137 if (pagetype($file) eq '_comment') {
138 $subject=gettext("comment notification:")." ".$pagedesc;
140 my $prefsurl=IkiWiki::cgiurl_abs(do => 'prefs');
141 if (IkiWiki::Plugin::passwordauth->can("anonusertoken")) {
142 my $token=IkiWiki::Plugin::passwordauth::anonusertoken($userinfo->{$user});
143 $prefsurl=IkiWiki::cgiurl_abs(
149 my $template=template("notifyemail.tmpl");
151 wikiname => $config{wikiname},
153 prefsurl => $prefsurl,
154 showcontent => $showcontent,
159 From => "$config{wikiname} <$config{adminemail}>",
161 Message => $template->output,
166 exit 0; # daemon child