summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--IkiWiki/Plugin/pingee.pm33
-rw-r--r--IkiWiki/Plugin/pinger.pm100
-rw-r--r--debian/changelog2
-rw-r--r--doc/ikiwiki.setup6
-rw-r--r--doc/plugins/pingee.mdwn11
-rw-r--r--doc/plugins/pinger.mdwn26
-rw-r--r--po/ikiwiki.pot56
7 files changed, 218 insertions, 16 deletions
diff --git a/IkiWiki/Plugin/pingee.pm b/IkiWiki/Plugin/pingee.pm
new file mode 100644
index 000000000..ee799a57a
--- /dev/null
+++ b/IkiWiki/Plugin/pingee.pm
@@ -0,0 +1,33 @@
+#!/usr/bin/perl
+package IkiWiki::Plugin::pingee;
+
+use warnings;
+use strict;
+use IkiWiki 2.00;
+
+sub import { #{{{
+ hook(type => "cgi", id => "aggregate", call => \&cgi);
+} # }}}
+
+sub cgi ($) { #{{{
+ my $cgi=shift;
+
+ if (defined $cgi->param('do') && $cgi->param("do") eq "ping") {
+ $|=1;
+ print "Content-Type: text/plain\n\n";
+ $config{cgi}=0;
+ $config{verbose}=1;
+ $config{syslog}=0;
+ print gettext("Ping received.")."\n\n";
+
+ IkiWiki::lockwiki();
+ IkiWiki::loadindex();
+ require IkiWiki::Render;
+ IkiWiki::rcs_update();
+ IkiWiki::refresh();
+ IkiWiki::saveindex();
+ exit 0;
+ }
+} #}}}
+
+1
diff --git a/IkiWiki/Plugin/pinger.pm b/IkiWiki/Plugin/pinger.pm
new file mode 100644
index 000000000..c6fa76e3f
--- /dev/null
+++ b/IkiWiki/Plugin/pinger.pm
@@ -0,0 +1,100 @@
+#!/usr/bin/perl
+package IkiWiki::Plugin::pinger;
+
+use warnings;
+use strict;
+use IkiWiki 2.00;
+
+my %pages;
+my $pinged=0;
+
+sub import { #{{{
+ hook(type => "needsbuild", id => "pinger", call => \&needsbuild);
+ hook(type => "preprocess", id => "ping", call => \&preprocess);
+ hook(type => "delete", id => "pinger", call => \&ping);
+ hook(type => "change", id => "pinger", call => \&ping);
+} # }}}
+
+sub needsbuild (@) { #{{{
+ my $needsbuild=shift;
+ foreach my $page (keys %pagestate) {
+ if (exists $pagestate{$page}{pinger}) {
+ $pages{$page}=1;
+ if (exists $pagesources{$page} &&
+ grep { $_ eq $pagesources{$page} } @$needsbuild) {
+ # remove state, will be re-added if
+ # the ping directive is still present
+ # on rebuild.
+ delete $pagestate{$page}{pinger};
+ }
+ }
+ }
+} # }}}
+
+sub preprocess (@) { #{{{
+ my %params=@_;
+ if (! exists $params{from} || ! exists $params{to}) {
+ return "[[ping ".gettext("requires 'from' and 'to' parameters")."]]";
+ }
+ if ($params{from} eq $config{url}) {
+ $pagestate{$params{destpage}}{pinger}{$params{to}}=1;
+ $pages{$params{destpage}}=1;
+ return sprintf(gettext("Will ping %s"), $params{to});
+ }
+ else {
+ return sprintf(gettext("Ignoring ping directive for wiki %s (this wiki is %s)"), $params{from}, $config{url});
+ }
+} # }}}
+
+sub ping {
+ if (! $pinged && %pages) {
+ $pinged=1;
+
+ my $ua;
+ eval q{use LWPx::ParanoidAgent};
+ if (!$@) {
+ $ua=LWPx::ParanoidAgent->new;
+ }
+ else {
+ eval q{use LWP};
+ if ($@) {
+ debug(gettext("LWP not found, not pinging"));
+ return;
+ }
+ $ua=LWP::UserAgent->new;
+ }
+ $ua->timeout($config{pinger_timeout} || 15);
+
+ # daemonise here so slow pings don't slow down wiki updates
+ defined(my $pid = fork) or error("Can't fork: $!");
+ return if $pid;
+ chdir '/';
+ open STDIN, '/dev/null';
+ open STDOUT, '>/dev/null';
+ POSIX::setsid() or error("Can't start a new session: $!");
+ open STDERR, '>&STDOUT' or error("Can't dup stdout: $!");
+
+ # Don't need to keep a lock on the wiki as a daemon.
+ IkiWiki::unlockwiki();
+
+ my %urls;
+ foreach my $page (%pages) {
+ if (exists $pagestate{$page}{pinger}) {
+ $urls{$_}=1 foreach keys %{$pagestate{$page}{pinger}};
+ }
+ }
+ foreach my $url (keys %urls) {
+ # Try to avoid pinging ourselves. If this check
+ # fails, it's not the end of the world, since we
+ # only ping when a page was changed, so a ping loop
+ # will still be avoided.
+ next if $url=~/^\Q$config{cgiurl}\E/;
+
+ $ua->head($url);
+ }
+
+ exit 0;
+ }
+}
+
+1
diff --git a/debian/changelog b/debian/changelog
index f131691b9..4eeb6d0ef 100644
--- a/debian/changelog
+++ b/debian/changelog
@@ -3,6 +3,8 @@ ikiwiki (2.46) UNRELEASED; urgency=low
* aggregate: Add support for web-based triggering of aggregation
for people stuck on shared hosting without cron. (Sheesh.) Enabled
via the `aggregate_webtrigger` configuration optiom.
+ * Add pinger and pingee plugins, which allow setting up mirrors and branched
+ wikis that automatically ping one another to stay up to date.
-- Joey Hess <joeyh@debian.org> Mon, 05 May 2008 19:34:51 -0400
diff --git a/doc/ikiwiki.setup b/doc/ikiwiki.setup
index 33710d1d7..a151050e7 100644
--- a/doc/ikiwiki.setup
+++ b/doc/ikiwiki.setup
@@ -99,7 +99,7 @@ use IkiWiki::Setup::Standard {
# Allow generating feeds even if not generated by default?
#allowrss => 1,
#allowatom => 1,
- # Urls to ping with XML-RPC when rss feeds are updated
+ # Urls to ping with XML-RPC when feeds are updated
#pingurl => [qw{http://rpc.technorati.com/rpc/ping}],
# Include discussion links on all pages?
discussion => 1,
@@ -167,4 +167,8 @@ use IkiWiki::Setup::Standard {
# For use with the aggregate plugin, to allow aggregation to be
# triggered via the web.
#aggregate_webtrigger => 1,
+
+ # For use with the pinger plugin, how many seconds to wait before
+ # timing out.
+ #pinger_timeout => 15.
}
diff --git a/doc/plugins/pingee.mdwn b/doc/plugins/pingee.mdwn
new file mode 100644
index 000000000..03eeb581c
--- /dev/null
+++ b/doc/plugins/pingee.mdwn
@@ -0,0 +1,11 @@
+[[template id=plugin name=pingee author="[[Joey]]"]]
+[[tag type/special-purpose]]
+
+This plugin causes ikiwiki to listen for pings, typically delivered from
+another ikiwiki instance using the [[pinger]] plugin. When a ping is
+recieved, ikiwiki will update the wiki, the same as if `ikiwiki --refresh`
+were ran at the command line.
+
+An url such as the following is used to trigger a ping:
+
+ http://mywiki.com/ikiwiki.cgi?do=ping
diff --git a/doc/plugins/pinger.mdwn b/doc/plugins/pinger.mdwn
new file mode 100644
index 000000000..f747a9f0b
--- /dev/null
+++ b/doc/plugins/pinger.mdwn
@@ -0,0 +1,26 @@
+[[template id=plugin name=pinger author="[[Joey]]"]]
+[[tag type/special-purpose]]
+
+This plugin allows ikiwiki to be configured to hit a URL each time it
+updates the wiki. One way to use this is in conjunction with the [[pingee]]
+plugin to set up a loosely coupled mirror network, or a branched version of
+a wiki. By pinging the mirror or branch each time the main wiki changes, it
+can be kept up-to-date.
+
+ \[[!ping from="http://mywiki.com/"
+ to="http://otherwiki.com/ikiwiki.cgi?do=ping"]]
+
+The "from" parameter must be identical to the url of the wiki that is doing
+the pinging. This is used to prevent ping loops.
+
+The "to" parameter is the url to ping. The example shows how to ping
+another ikiwiki instance.
+
+The [[cpan LWP]] perl module is used for pinging. Or the [[cpan
+LWPx::ParanoidAgent]] perl module is used if available, for added security.
+Finally, the [[cpan Crypt::SSLeay]] perl module is needed to support pinging
+"https" urls.
+
+By default the pinger will try to ping a site for 15 seconds before timing
+out. This timeout can be changed by setting the `pinger_timeout`
+configuration setting in the setup file.
diff --git a/po/ikiwiki.pot b/po/ikiwiki.pot
index 38a677eae..f8834be1c 100644
--- a/po/ikiwiki.pot
+++ b/po/ikiwiki.pot
@@ -8,7 +8,7 @@ msgid ""
msgstr ""
"Project-Id-Version: PACKAGE VERSION\n"
"Report-Msgid-Bugs-To: \n"
-"POT-Creation-Date: 2008-05-05 20:05-0400\n"
+"POT-Creation-Date: 2008-05-06 18:15-0400\n"
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
"Language-Team: LANGUAGE <LL@li.org>\n"
@@ -71,67 +71,75 @@ msgstr ""
msgid "You are banned."
msgstr ""
-#: ../IkiWiki/Plugin/aggregate.pm:126
+#: ../IkiWiki/Plugin/aggregate.pm:53
+msgid "Aggregation triggered via web."
+msgstr ""
+
+#: ../IkiWiki/Plugin/aggregate.pm:62
+msgid "Nothing to do right now, all feeds are up-to-date!"
+msgstr ""
+
+#: ../IkiWiki/Plugin/aggregate.pm:134
#, perl-format
msgid "missing %s parameter"
msgstr ""
-#: ../IkiWiki/Plugin/aggregate.pm:153
+#: ../IkiWiki/Plugin/aggregate.pm:161
msgid "new feed"
msgstr ""
-#: ../IkiWiki/Plugin/aggregate.pm:167
+#: ../IkiWiki/Plugin/aggregate.pm:175
msgid "posts"
msgstr ""
-#: ../IkiWiki/Plugin/aggregate.pm:169
+#: ../IkiWiki/Plugin/aggregate.pm:177
msgid "new"
msgstr ""
-#: ../IkiWiki/Plugin/aggregate.pm:332
+#: ../IkiWiki/Plugin/aggregate.pm:340
#, perl-format
msgid "expiring %s (%s days old)"
msgstr ""
-#: ../IkiWiki/Plugin/aggregate.pm:339
+#: ../IkiWiki/Plugin/aggregate.pm:347
#, perl-format
msgid "expiring %s"
msgstr ""
-#: ../IkiWiki/Plugin/aggregate.pm:366
+#: ../IkiWiki/Plugin/aggregate.pm:374
#, perl-format
msgid "processed ok at %s"
msgstr ""
-#: ../IkiWiki/Plugin/aggregate.pm:370
+#: ../IkiWiki/Plugin/aggregate.pm:378
#, perl-format
msgid "checking feed %s ..."
msgstr ""
-#: ../IkiWiki/Plugin/aggregate.pm:375
+#: ../IkiWiki/Plugin/aggregate.pm:383
#, perl-format
msgid "could not find feed at %s"
msgstr ""
-#: ../IkiWiki/Plugin/aggregate.pm:390
+#: ../IkiWiki/Plugin/aggregate.pm:398
msgid "feed not found"
msgstr ""
-#: ../IkiWiki/Plugin/aggregate.pm:401
+#: ../IkiWiki/Plugin/aggregate.pm:409
#, perl-format
msgid "(invalid UTF-8 stripped from feed)"
msgstr ""
-#: ../IkiWiki/Plugin/aggregate.pm:407
+#: ../IkiWiki/Plugin/aggregate.pm:415
#, perl-format
msgid "(feed entities escaped)"
msgstr ""
-#: ../IkiWiki/Plugin/aggregate.pm:413
+#: ../IkiWiki/Plugin/aggregate.pm:421
msgid "feed crashed XML::Feed!"
msgstr ""
-#: ../IkiWiki/Plugin/aggregate.pm:487
+#: ../IkiWiki/Plugin/aggregate.pm:495
#, perl-format
msgid "creating new page %s"
msgstr ""
@@ -300,6 +308,24 @@ msgstr ""
msgid "Your password has been emailed to you."
msgstr ""
+#: ../IkiWiki/Plugin/pingee.pm:21
+msgid "Ping received."
+msgstr ""
+
+#: ../IkiWiki/Plugin/pinger.pm:39
+#, perl-format
+msgid "Updates will ping %s"
+msgstr ""
+
+#: ../IkiWiki/Plugin/pinger.pm:42
+#, perl-format
+msgid "Ignoring ping directive for wiki %s"
+msgstr ""
+
+#: ../IkiWiki/Plugin/pinger.pm:58
+msgid "LWP not found, not pinging"
+msgstr ""
+
#: ../IkiWiki/Plugin/poll.pm:64
msgid "vote"
msgstr ""