pinger/pingee now tested and working
authorJoey Hess <joey@kodama.kitenet.net>
Tue, 6 May 2008 23:06:53 +0000 (19:06 -0400)
committerJoey Hess <joey@kodama.kitenet.net>
Tue, 6 May 2008 23:06:53 +0000 (19:06 -0400)
IkiWiki/Plugin/pingee.pm [new file with mode: 0644]
IkiWiki/Plugin/pinger.pm [new file with mode: 0644]
debian/changelog
doc/ikiwiki.setup
doc/plugins/pingee.mdwn [new file with mode: 0644]
doc/plugins/pinger.mdwn [new file with mode: 0644]
po/ikiwiki.pot

diff --git a/IkiWiki/Plugin/pingee.pm b/IkiWiki/Plugin/pingee.pm
new file mode 100644 (file)
index 0000000..ee799a5
--- /dev/null
@@ -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 (file)
index 0000000..c6fa76e
--- /dev/null
@@ -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
index f131691b962e1431dba2da80e6f9719b3ea26b3a..4eeb6d0efbe0f09853a8cb28332e5e430580a353 100644 (file)
@@ -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.
   * 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
 
 
  -- Joey Hess <joeyh@debian.org>  Mon, 05 May 2008 19:34:51 -0400
 
index 33710d1d773b2175f77ec84effae0b9d170ef6f5..a151050e734665cf2b0f1351525f82049ab00ef7 100644 (file)
@@ -99,7 +99,7 @@ use IkiWiki::Setup::Standard {
        # Allow generating feeds even if not generated by default?
        #allowrss => 1,
        #allowatom => 1,
        # 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,
        #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 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 (file)
index 0000000..03eeb58
--- /dev/null
@@ -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 (file)
index 0000000..f747a9f
--- /dev/null
@@ -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.
index 38a677eae9cce050c71900297a8c94a947da4f4b..f8834be1cd2d24118860715d1b538c261fa3dd4d 100644 (file)
@@ -8,7 +8,7 @@ msgid ""
 msgstr ""
 "Project-Id-Version: PACKAGE VERSION\n"
 "Report-Msgid-Bugs-To: \n"
 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"
 "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 ""
 
 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 ""
 
 #, perl-format
 msgid "missing %s parameter"
 msgstr ""
 
-#: ../IkiWiki/Plugin/aggregate.pm:153
+#: ../IkiWiki/Plugin/aggregate.pm:161
 msgid "new feed"
 msgstr ""
 
 msgid "new feed"
 msgstr ""
 
-#: ../IkiWiki/Plugin/aggregate.pm:167
+#: ../IkiWiki/Plugin/aggregate.pm:175
 msgid "posts"
 msgstr ""
 
 msgid "posts"
 msgstr ""
 
-#: ../IkiWiki/Plugin/aggregate.pm:169
+#: ../IkiWiki/Plugin/aggregate.pm:177
 msgid "new"
 msgstr ""
 
 msgid "new"
 msgstr ""
 
-#: ../IkiWiki/Plugin/aggregate.pm:332
+#: ../IkiWiki/Plugin/aggregate.pm:340
 #, perl-format
 msgid "expiring %s (%s days old)"
 msgstr ""
 
 #, 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 ""
 
 #, perl-format
 msgid "expiring %s"
 msgstr ""
 
-#: ../IkiWiki/Plugin/aggregate.pm:366
+#: ../IkiWiki/Plugin/aggregate.pm:374
 #, perl-format
 msgid "processed ok at %s"
 msgstr ""
 
 #, 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 ""
 
 #, 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 ""
 
 #, 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 ""
 
 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 ""
 
 #, 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 ""
 
 #, perl-format
 msgid "(feed entities escaped)"
 msgstr ""
 
-#: ../IkiWiki/Plugin/aggregate.pm:413
+#: ../IkiWiki/Plugin/aggregate.pm:421
 msgid "feed crashed XML::Feed!"
 msgstr ""
 
 msgid "feed crashed XML::Feed!"
 msgstr ""
 
-#: ../IkiWiki/Plugin/aggregate.pm:487
+#: ../IkiWiki/Plugin/aggregate.pm:495
 #, perl-format
 msgid "creating new page %s"
 msgstr ""
 #, perl-format
 msgid "creating new page %s"
 msgstr ""
@@ -300,6 +308,24 @@ msgstr ""
 msgid "Your password has been emailed to you."
 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 ""
 #: ../IkiWiki/Plugin/poll.pm:64
 msgid "vote"
 msgstr ""