2 package IkiWiki::Plugin::notifyemail;
9 hook(type => "formbuilder_setup", id => "notifyemail", call => \&formbuilder_setup);
10 hook(type => "formbuilder", id => "notifyemail", call => \&formbuilder);
11 hook(type => "getsetup", id => "notifyemail", call => \&getsetup);
12 hook(type => "changes", id => "notifyemail", call => \¬ify);
23 sub formbuilder_setup (@) {
26 my $form=$params{form};
27 return unless $form->title eq "preferences";
28 my $session=$params{session};
29 $form->field(name => "subscriptions", size => 50,
30 fieldset => "preferences",
31 comment => "(".htmllink("", "", "ikiwiki/PageSpec", noimageinline => 1).")",
32 value => getsubscriptions($session->param("name")));
37 my $form=$params{form};
38 return unless $form->title eq "preferences" &&
39 $form->submitted eq "Save Preferences" && $form->validate &&
40 defined $form->field("subscriptions");
41 setsubscriptions($form->field('name'), $form->field('subscriptions'));
44 sub getsubscriptions ($) {
46 eval q{use IkiWiki::UserInfo};
48 IkiWiki::userinfo_get($user, "subscriptions");
51 sub setsubscriptions ($$) {
53 my $subscriptions=shift;
54 eval q{use IkiWiki::UserInfo};
56 IkiWiki::userinfo_set($user, "subscriptions", $subscriptions);
59 # Called by other plugins to subscribe the user to a pagespec.
62 my $addpagespec=shift;
63 my $pagespec=getsubscriptions($user);
64 setsubscriptions($user, $pagespec." or ".$addpagespec);
71 eval q{use Mail::Sendmail};
73 eval q{use IkiWiki::UserInfo};
78 # Daemonize, in case the mail sending takes a while.
79 defined(my $pid = fork) or error("Can't fork: $!");
80 return if $pid; # parent
82 open STDIN, '/dev/null';
83 open STDOUT, '>/dev/null';
84 POSIX::setsid() or error("Can't start a new session: $!");
85 open STDERR, '>&STDOUT' or error("Can't dup stdout: $!");
87 # Don't need to keep a lock on the wiki as a daemon.
88 IkiWiki::unlockwiki();
90 my $userinfo=IkiWiki::userinfo_retrieve();
91 exit 0 unless defined $userinfo;
93 foreach my $user (keys %$userinfo) {
94 my $pagespec=$userinfo->{$user}->{"subscriptions"};
95 next unless defined $pagespec && length $pagespec;
96 my $email=$userinfo->{$user}->{email};
97 next unless defined $email && length $email;
99 foreach my $file (@files) {
100 my $page=pagename($file);
101 next unless pagespec_match($page, $pagespec);
103 my $showcontent=defined pagetype($file);
105 $content=eval { readfile(srcfile($file)) };
106 $showcontent=0 if $@;
109 if (! IkiWiki::isinternal($page)) {
110 $url=urlto($page, undef, 1);
112 elsif (defined $pagestate{$page}{meta}{permalink}) {
113 # need to use permalink for an internal page
114 $url=URI->new_abs($pagestate{$page}{meta}{permalink}, $config{url});
117 $url=$config{url}; # crummy fallback url
120 if (defined $pagestate{$page}{meta}{title} &&
121 length $pagestate{$page}{meta}{title}) {
122 $pagedesc=qq{"$pagestate{$page}{meta}{title}"};
124 my $subject=gettext("change notification:")." ".$pagedesc;
125 if (pagetype($file) eq '_comment') {
126 $subject=gettext("comment notification:")." ".$pagedesc;
128 my $template=template("notifyemail.tmpl");
130 wikiname => $config{wikiname},
132 prefsurl => $config{cgiurl}."?do=prefs",
133 showcontent => $showcontent,
138 From => "$config{wikiname} <$config{adminemail}>",
140 Message => $template->output,
145 exit 0; # daemon child