<html><head><meta name="color-scheme" content="light dark"></head><body><pre style="word-wrap: break-word; white-space: pre-wrap;">#!/usr/bin/perl
package IkiWiki::Plugin::notifyemail;

use warnings;
use strict;
use IkiWiki 3.00;

sub import {
	hook(type =&gt; "formbuilder", id =&gt; "notifyemail", call =&gt; \&amp;formbuilder);
	hook(type =&gt; "getsetup", id =&gt; "notifyemail",  call =&gt; \&amp;getsetup);
	hook(type =&gt; "changes", id =&gt; "notifyemail", call =&gt; \&amp;notify);
}

sub getsetup () {
	return
		plugin =&gt; {
			safe =&gt; 1,
			rebuild =&gt; 0,
		},
}

sub formbuilder (@) {
	my %params=@_;
	my $form=$params{form};
	return unless $form-&gt;title eq "preferences";
	my $session=$params{session};
	my $username=$session-&gt;param("name");
	$form-&gt;field(name =&gt; "subscriptions", size =&gt; 50,
		fieldset =&gt; "preferences",
		comment =&gt; "(".htmllink("", "", "ikiwiki/PageSpec", noimageinline =&gt; 1).")");
	if (! $form-&gt;submitted) {
		$form-&gt;field(name =&gt; "subscriptions", force =&gt; 1,
			value =&gt; getsubscriptions($username));
	}
	elsif ($form-&gt;submitted eq "Save Preferences" &amp;&amp; $form-&gt;validate &amp;&amp;
	       defined $form-&gt;field("subscriptions")) {
		setsubscriptions($username, $form-&gt;field('subscriptions'));
	}
}

sub getsubscriptions ($) {
	my $user=shift;
	eval q{use IkiWiki::UserInfo};
	error $@ if $@;
	IkiWiki::userinfo_get($user, "subscriptions");
}

sub setsubscriptions ($$) {
	my $user=shift;
	my $subscriptions=shift;
	eval q{use IkiWiki::UserInfo};
	error $@ if $@;
	IkiWiki::userinfo_set($user, "subscriptions", $subscriptions);
}

# Called by other plugins to subscribe the user to a pagespec.
sub subscribe ($$) {
	my $user=shift;
	my $addpagespec=shift;
	my $pagespec=getsubscriptions($user);
	setsubscriptions($user,
		length $pagespec ? $pagespec." or ".$addpagespec : $addpagespec);
}

# Called by other plugins to subscribe an email to a pagespec.
sub anonsubscribe ($$) {
	my $email=shift;
	my $addpagespec=shift;
	if (IkiWiki::Plugin::passwordauth-&gt;can("anonuser")) {
		my $user=IkiWiki::Plugin::passwordauth::anonuser($email);
		if (! defined $user) {
			error(gettext("Cannot subscribe your email address without logging in."));
		}
		subscribe($user, $addpagespec);
	}
}

sub notify (@) {
	my @files=@_;
	return unless @files;
	return if $config{rebuild};

	eval q{use Mail::Sendmail};
	error $@ if $@;
	eval q{use IkiWiki::UserInfo};
	error $@ if $@;
	eval q{use URI};
	error($@) if $@;

	# Daemonize, in case the mail sending takes a while.
	defined(my $pid = fork) or error("Can't fork: $!");
	return if $pid; # parent
	chdir '/';
	open STDIN, '/dev/null';
	open STDOUT, '&gt;/dev/null';
	POSIX::setsid() or error("Can't start a new session: $!");
	open STDERR, '&gt;&amp;STDOUT' or error("Can't dup stdout: $!");

	# Don't need to keep a lock on the wiki as a daemon.
	IkiWiki::unlockwiki();

	my $userinfo=IkiWiki::userinfo_retrieve();
	exit 0 unless defined $userinfo;

	foreach my $user (keys %$userinfo) {
		my $pagespec=$userinfo-&gt;{$user}-&gt;{"subscriptions"};
		next unless defined $pagespec &amp;&amp; length $pagespec;
		my $email=$userinfo-&gt;{$user}-&gt;{email};
		next unless defined $email &amp;&amp; length $email;

		foreach my $file (@files) {
			my $page=pagename($file);
			next unless pagespec_match($page, $pagespec);
			my $content="";
			my $showcontent=defined pagetype($file);
			if ($showcontent) {
				$content=eval { readfile(srcfile($file)) };
				$showcontent=0 if $@;
			}
			my $url;
			if (! IkiWiki::isinternal($page)) {
				$url=urlto($page, undef, 1);
			}
			elsif (defined $pagestate{$page}{meta}{permalink}) {
				# need to use permalink for an internal page
				$url=URI-&gt;new_abs($pagestate{$page}{meta}{permalink}, $config{url});
			}
			else {
				$url=$config{url}; # crummy fallback url
			}
			my $pagedesc=$page;
			if (defined $pagestate{$page}{meta}{title} &amp;&amp;
			    length $pagestate{$page}{meta}{title}) {
				$pagedesc=qq{"$pagestate{$page}{meta}{title}"};
			}
			my $subject=gettext("change notification:")." ".$pagedesc;
			if (pagetype($file) eq '_comment') {
				$subject=gettext("comment notification:")." ".$pagedesc;
			}
			my $prefsurl=IkiWiki::cgiurl_abs(do =&gt; 'prefs');
			if (IkiWiki::Plugin::passwordauth-&gt;can("anonusertoken")) {
				my $token=IkiWiki::Plugin::passwordauth::anonusertoken($userinfo-&gt;{$user});
				$prefsurl=IkiWiki::cgiurl_abs(
					do =&gt; 'tokenauth',
					name =&gt; $user,
					token =&gt; $token,
				) if defined $token;
			}
			my $template=template("notifyemail.tmpl");
			$template-&gt;param(
				wikiname =&gt; $config{wikiname},
				url =&gt; $url,
				prefsurl =&gt; $prefsurl,
				showcontent =&gt; $showcontent,
				content =&gt; $content,
			);
			sendmail(
				To =&gt; $email,
				From =&gt; "$config{wikiname} &lt;$config{adminemail}&gt;",
				Subject =&gt; $subject,
				Message =&gt; $template-&gt;output,
			);
		}
	}

	exit 0; # daemon child
}

1
</pre></body></html>