commit
8e92468eae
|
@ -16,17 +16,17 @@ perl -MCPAN -e 'install Bundle::IkiWiki'
|
||||||
|
|
||||||
=head1 CONTENTS
|
=head1 CONTENTS
|
||||||
|
|
||||||
XML::Simple
|
|
||||||
Text::Markdown
|
Text::Markdown
|
||||||
Date::Parse
|
|
||||||
HTML::Template
|
|
||||||
HTML::Scrubber
|
HTML::Scrubber
|
||||||
CGI
|
HTML::Template
|
||||||
|
HTML::Parser
|
||||||
|
URI
|
||||||
|
XML::Simple
|
||||||
|
Date::Parse
|
||||||
CGI::FormBuilder
|
CGI::FormBuilder
|
||||||
CGI::Session
|
CGI::Session
|
||||||
Mail::Sendmail
|
Mail::Sendmail
|
||||||
HTML::Parser
|
CGI
|
||||||
URI
|
|
||||||
Data::Dumper
|
Data::Dumper
|
||||||
|
|
||||||
=head1 AUTHOR
|
=head1 AUTHOR
|
||||||
|
|
|
@ -31,6 +31,11 @@ Text::Textile
|
||||||
Text::WikiFormat
|
Text::WikiFormat
|
||||||
XML::Feed
|
XML::Feed
|
||||||
Net::Amazon::S3
|
Net::Amazon::S3
|
||||||
|
Text::WikiCreole
|
||||||
|
Term::ReadLine::Gnu
|
||||||
|
HTML::Tree
|
||||||
|
Authen::Passphrase
|
||||||
|
Sort::Naturally
|
||||||
|
|
||||||
=head1 AUTHOR
|
=head1 AUTHOR
|
||||||
|
|
||||||
|
|
692
IkiWiki.pm
692
IkiWiki.pm
File diff suppressed because it is too large
Load Diff
133
IkiWiki/CGI.pm
133
IkiWiki/CGI.pm
|
@ -9,7 +9,7 @@ use IkiWiki::UserInfo;
|
||||||
use open qw{:utf8 :std};
|
use open qw{:utf8 :std};
|
||||||
use Encode;
|
use Encode;
|
||||||
|
|
||||||
sub printheader ($) { #{{{
|
sub printheader ($) {
|
||||||
my $session=shift;
|
my $session=shift;
|
||||||
|
|
||||||
if ($config{sslcookie}) {
|
if ($config{sslcookie}) {
|
||||||
|
@ -19,9 +19,9 @@ sub printheader ($) { #{{{
|
||||||
print $session->header(-charset => 'utf-8',
|
print $session->header(-charset => 'utf-8',
|
||||||
-cookie => $session->cookie(-httponly => 1));
|
-cookie => $session->cookie(-httponly => 1));
|
||||||
}
|
}
|
||||||
} #}}}
|
}
|
||||||
|
|
||||||
sub showform ($$$$;@) { #{{{
|
sub showform ($$$$;@) {
|
||||||
my $form=shift;
|
my $form=shift;
|
||||||
my $buttons=shift;
|
my $buttons=shift;
|
||||||
my $session=shift;
|
my $session=shift;
|
||||||
|
@ -38,7 +38,7 @@ sub showform ($$$$;@) { #{{{
|
||||||
print misctemplate($form->title, $form->render(submit => $buttons), @_);
|
print misctemplate($form->title, $form->render(submit => $buttons), @_);
|
||||||
}
|
}
|
||||||
|
|
||||||
sub redirect ($$) { #{{{
|
sub redirect ($$) {
|
||||||
my $q=shift;
|
my $q=shift;
|
||||||
my $url=shift;
|
my $url=shift;
|
||||||
if (! $config{w3mmode}) {
|
if (! $config{w3mmode}) {
|
||||||
|
@ -48,9 +48,9 @@ sub redirect ($$) { #{{{
|
||||||
print "Content-type: text/plain\n";
|
print "Content-type: text/plain\n";
|
||||||
print "W3m-control: GOTO $url\n\n";
|
print "W3m-control: GOTO $url\n\n";
|
||||||
}
|
}
|
||||||
} #}}}
|
}
|
||||||
|
|
||||||
sub decode_cgi_utf8 ($) { #{{{
|
sub decode_cgi_utf8 ($) {
|
||||||
# decode_form_utf8 method is needed for 5.10
|
# decode_form_utf8 method is needed for 5.10
|
||||||
if ($] < 5.01) {
|
if ($] < 5.01) {
|
||||||
my $cgi = shift;
|
my $cgi = shift;
|
||||||
|
@ -58,9 +58,9 @@ sub decode_cgi_utf8 ($) { #{{{
|
||||||
$cgi->param($f, map { decode_utf8 $_ } $cgi->param($f));
|
$cgi->param($f, map { decode_utf8 $_ } $cgi->param($f));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} #}}}
|
}
|
||||||
|
|
||||||
sub decode_form_utf8 ($) { #{{{
|
sub decode_form_utf8 ($) {
|
||||||
if ($] >= 5.01) {
|
if ($] >= 5.01) {
|
||||||
my $form = shift;
|
my $form = shift;
|
||||||
foreach my $f ($form->field) {
|
foreach my $f ($form->field) {
|
||||||
|
@ -70,11 +70,11 @@ sub decode_form_utf8 ($) { #{{{
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} #}}}
|
}
|
||||||
|
|
||||||
# Check if the user is signed in. If not, redirect to the signin form and
|
# Check if the user is signed in. If not, redirect to the signin form and
|
||||||
# save their place to return to later.
|
# save their place to return to later.
|
||||||
sub needsignin ($$) { #{{{
|
sub needsignin ($$) {
|
||||||
my $q=shift;
|
my $q=shift;
|
||||||
my $session=shift;
|
my $session=shift;
|
||||||
|
|
||||||
|
@ -85,9 +85,9 @@ sub needsignin ($$) { #{{{
|
||||||
cgi_savesession($session);
|
cgi_savesession($session);
|
||||||
exit;
|
exit;
|
||||||
}
|
}
|
||||||
} #}}}
|
}
|
||||||
|
|
||||||
sub cgi_signin ($$) { #{{{
|
sub cgi_signin ($$) {
|
||||||
my $q=shift;
|
my $q=shift;
|
||||||
my $session=shift;
|
my $session=shift;
|
||||||
|
|
||||||
|
@ -127,9 +127,9 @@ sub cgi_signin ($$) { #{{{
|
||||||
}
|
}
|
||||||
|
|
||||||
showform($form, $buttons, $session, $q);
|
showform($form, $buttons, $session, $q);
|
||||||
} #}}}
|
}
|
||||||
|
|
||||||
sub cgi_postsignin ($$) { #{{{
|
sub cgi_postsignin ($$) {
|
||||||
my $q=shift;
|
my $q=shift;
|
||||||
my $session=shift;
|
my $session=shift;
|
||||||
|
|
||||||
|
@ -142,11 +142,16 @@ sub cgi_postsignin ($$) { #{{{
|
||||||
exit;
|
exit;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
error(gettext("login failed, perhaps you need to turn on cookies?"));
|
if ($config{sslcookie} && ! $q->https()) {
|
||||||
|
error(gettext("probable misconfiguration: sslcookie is set, but you are attepting to login via http, not https"));
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
error(gettext("login failed, perhaps you need to turn on cookies?"));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
} #}}}
|
}
|
||||||
|
|
||||||
sub cgi_prefs ($$) { #{{{
|
sub cgi_prefs ($$) {
|
||||||
my $q=shift;
|
my $q=shift;
|
||||||
my $session=shift;
|
my $session=shift;
|
||||||
|
|
||||||
|
@ -203,25 +208,9 @@ sub cgi_prefs ($$) { #{{{
|
||||||
|
|
||||||
my $user_name=$session->param("name");
|
my $user_name=$session->param("name");
|
||||||
|
|
||||||
# XXX deprecated, should be removed eventually
|
|
||||||
$form->field(name => "banned_users", size => 50, fieldset => "admin");
|
|
||||||
if (! is_admin($user_name)) {
|
|
||||||
$form->field(name => "banned_users", type => "hidden");
|
|
||||||
}
|
|
||||||
if (! $form->submitted) {
|
if (! $form->submitted) {
|
||||||
$form->field(name => "email", force => 1,
|
$form->field(name => "email", force => 1,
|
||||||
value => userinfo_get($user_name, "email"));
|
value => userinfo_get($user_name, "email"));
|
||||||
if (is_admin($user_name)) {
|
|
||||||
my $value=join(" ", get_banned_users());
|
|
||||||
if (length $value) {
|
|
||||||
$form->field(name => "banned_users", force => 1,
|
|
||||||
value => join(" ", get_banned_users()),
|
|
||||||
comment => "deprecated; please move to banned_users in setup file");
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
$form->field(name => "banned_users", type => "hidden");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if ($form->submitted eq 'Logout') {
|
if ($form->submitted eq 'Logout') {
|
||||||
|
@ -239,48 +228,48 @@ sub cgi_prefs ($$) { #{{{
|
||||||
error("failed to set email");
|
error("failed to set email");
|
||||||
}
|
}
|
||||||
|
|
||||||
# XXX deprecated, should be removed eventually
|
|
||||||
if (is_admin($user_name)) {
|
|
||||||
set_banned_users(grep { ! is_admin($_) }
|
|
||||||
split(' ',
|
|
||||||
$form->field("banned_users"))) ||
|
|
||||||
error("failed saving changes");
|
|
||||||
if (! length $form->field("banned_users")) {
|
|
||||||
$form->field(name => "banned_users", type => "hidden");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
$form->text(gettext("Preferences saved."));
|
$form->text(gettext("Preferences saved."));
|
||||||
}
|
}
|
||||||
|
|
||||||
showform($form, $buttons, $session, $q);
|
showform($form, $buttons, $session, $q);
|
||||||
} #}}}
|
}
|
||||||
|
|
||||||
sub check_banned ($$) { #{{{
|
sub cgi_custom_failure ($$) {
|
||||||
|
my $header=shift;
|
||||||
|
my $message=shift;
|
||||||
|
|
||||||
|
print $header;
|
||||||
|
print $message;
|
||||||
|
|
||||||
|
# Internet Explod^Hrer won't show custom 404 responses
|
||||||
|
# unless they're >= 512 bytes
|
||||||
|
print ' ' x 512;
|
||||||
|
|
||||||
|
exit;
|
||||||
|
}
|
||||||
|
|
||||||
|
sub check_banned ($$) {
|
||||||
my $q=shift;
|
my $q=shift;
|
||||||
my $session=shift;
|
my $session=shift;
|
||||||
|
|
||||||
my $name=$session->param("name");
|
my $name=$session->param("name");
|
||||||
if (defined $name) {
|
if (defined $name) {
|
||||||
# XXX banned in userinfo is deprecated, should be removed
|
if (grep { $name eq $_ } @{$config{banned_users}}) {
|
||||||
# eventually, and only banned_users be checked.
|
|
||||||
if (userinfo_get($session->param("name"), "banned") ||
|
|
||||||
grep { $name eq $_ } @{$config{banned_users}}) {
|
|
||||||
print $q->header(-status => "403 Forbidden");
|
|
||||||
$session->delete();
|
$session->delete();
|
||||||
print gettext("You are banned.");
|
|
||||||
cgi_savesession($session);
|
cgi_savesession($session);
|
||||||
exit;
|
cgi_custom_failure(
|
||||||
|
$q->header(-status => "403 Forbidden"),
|
||||||
|
gettext("You are banned."));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
sub cgi_getsession ($) { #{{{
|
sub cgi_getsession ($) {
|
||||||
my $q=shift;
|
my $q=shift;
|
||||||
|
|
||||||
eval q{use CGI::Session};
|
eval q{use CGI::Session; use HTML::Entities};
|
||||||
error($@) if $@;
|
error($@) if $@;
|
||||||
CGI::Session->name("ikiwiki_session_".encode_utf8($config{wikiname}));
|
CGI::Session->name("ikiwiki_session_".encode_entities($config{wikiname}));
|
||||||
|
|
||||||
my $oldmask=umask(077);
|
my $oldmask=umask(077);
|
||||||
my $session = eval {
|
my $session = eval {
|
||||||
|
@ -294,18 +283,34 @@ sub cgi_getsession ($) { #{{{
|
||||||
umask($oldmask);
|
umask($oldmask);
|
||||||
|
|
||||||
return $session;
|
return $session;
|
||||||
} #}}}
|
}
|
||||||
|
|
||||||
sub cgi_savesession ($) { #{{{
|
# To guard against CSRF, the user's session id (sid)
|
||||||
|
# can be stored on a form. This function will check
|
||||||
|
# (for logged in users) that the sid on the form matches
|
||||||
|
# the session id in the cookie.
|
||||||
|
sub checksessionexpiry ($$) {
|
||||||
|
my $q=shift;
|
||||||
|
my $session = shift;
|
||||||
|
|
||||||
|
if (defined $session->param("name")) {
|
||||||
|
my $sid=$q->param('sid');
|
||||||
|
if (! defined $sid || $sid ne $session->id) {
|
||||||
|
error(gettext("Your login session has expired."));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
sub cgi_savesession ($) {
|
||||||
my $session=shift;
|
my $session=shift;
|
||||||
|
|
||||||
# Force session flush with safe umask.
|
# Force session flush with safe umask.
|
||||||
my $oldmask=umask(077);
|
my $oldmask=umask(077);
|
||||||
$session->flush;
|
$session->flush;
|
||||||
umask($oldmask);
|
umask($oldmask);
|
||||||
} #}}}
|
}
|
||||||
|
|
||||||
sub cgi (;$$) { #{{{
|
sub cgi (;$$) {
|
||||||
my $q=shift;
|
my $q=shift;
|
||||||
my $session=shift;
|
my $session=shift;
|
||||||
|
|
||||||
|
@ -331,7 +336,7 @@ sub cgi (;$$) { #{{{
|
||||||
error("\"do\" parameter missing");
|
error("\"do\" parameter missing");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
# Need to lock the wiki before getting a session.
|
# Need to lock the wiki before getting a session.
|
||||||
lockwiki();
|
lockwiki();
|
||||||
loadindex();
|
loadindex();
|
||||||
|
@ -375,16 +380,16 @@ sub cgi (;$$) { #{{{
|
||||||
else {
|
else {
|
||||||
error("unknown do parameter");
|
error("unknown do parameter");
|
||||||
}
|
}
|
||||||
} #}}}
|
}
|
||||||
|
|
||||||
# Does not need to be called directly; all errors will go through here.
|
# Does not need to be called directly; all errors will go through here.
|
||||||
sub cgierror ($) { #{{{
|
sub cgierror ($) {
|
||||||
my $message=shift;
|
my $message=shift;
|
||||||
|
|
||||||
print "Content-type: text/html\n\n";
|
print "Content-type: text/html\n\n";
|
||||||
print misctemplate(gettext("Error"),
|
print misctemplate(gettext("Error"),
|
||||||
"<p class=\"error\">".gettext("Error").": $message</p>");
|
"<p class=\"error\">".gettext("Error").": $message</p>");
|
||||||
die $@;
|
die $@;
|
||||||
} #}}}
|
}
|
||||||
|
|
||||||
1
|
1
|
||||||
|
|
|
@ -0,0 +1,78 @@
|
||||||
|
#!/usr/bin/perl
|
||||||
|
# Copyright © 2009 Simon McVittie <http://smcv.pseudorandom.co.uk/>
|
||||||
|
# Licensed under the GNU GPL, version 2, or any later version published by the
|
||||||
|
# Free Software Foundation
|
||||||
|
package IkiWiki::Plugin::404;
|
||||||
|
|
||||||
|
use warnings;
|
||||||
|
use strict;
|
||||||
|
use IkiWiki 3.00;
|
||||||
|
|
||||||
|
sub import {
|
||||||
|
hook(type => "cgi", id => '404', call => \&cgi);
|
||||||
|
IkiWiki::loadplugin("goto");
|
||||||
|
}
|
||||||
|
|
||||||
|
sub getsetup () {
|
||||||
|
return
|
||||||
|
plugin => {
|
||||||
|
# not really a matter of safety, but enabling/disabling
|
||||||
|
# through a web interface is useless - it needs web
|
||||||
|
# server admin action too
|
||||||
|
safe => 0,
|
||||||
|
rebuild => 0,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
sub cgi_page_from_404 ($$$) {
|
||||||
|
my $path = shift;
|
||||||
|
my $baseurl = shift;
|
||||||
|
my $usedirs = shift;
|
||||||
|
|
||||||
|
# fail if missing from environment or whatever
|
||||||
|
return undef unless defined $path;
|
||||||
|
return undef unless defined $baseurl;
|
||||||
|
|
||||||
|
# with usedirs on, path is like /~fred/foo/bar/ or /~fred/foo/bar or
|
||||||
|
# /~fred/foo/bar/index.html
|
||||||
|
# with usedirs off, path is like /~fred/foo/bar.html
|
||||||
|
# baseurl is like 'http://people.example.com/~fred'
|
||||||
|
|
||||||
|
# convert baseurl to ~fred
|
||||||
|
unless ($baseurl =~ s{^https?://[^/]+/?}{}) {
|
||||||
|
return undef;
|
||||||
|
}
|
||||||
|
|
||||||
|
# convert path to /~fred/foo/bar
|
||||||
|
if ($usedirs) {
|
||||||
|
$path =~ s/\/*(?:index\.$config{htmlext})?$//;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
$path =~ s/\.$config{htmlext}$//;
|
||||||
|
}
|
||||||
|
|
||||||
|
# remove /~fred/
|
||||||
|
unless ($path =~ s{^/*\Q$baseurl\E/*}{}) {
|
||||||
|
return undef;
|
||||||
|
}
|
||||||
|
|
||||||
|
# special case for the index
|
||||||
|
unless ($path) {
|
||||||
|
return 'index';
|
||||||
|
}
|
||||||
|
|
||||||
|
return $path;
|
||||||
|
}
|
||||||
|
|
||||||
|
sub cgi ($) {
|
||||||
|
my $cgi=shift;
|
||||||
|
|
||||||
|
if (exists $ENV{REDIRECT_STATUS} &&
|
||||||
|
$ENV{REDIRECT_STATUS} eq '404') {
|
||||||
|
my $page = cgi_page_from_404($ENV{REDIRECT_URL},
|
||||||
|
$config{url}, $config{usedirs});
|
||||||
|
IkiWiki::Plugin::goto::cgi_goto($cgi, $page);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
1;
|
|
@ -4,7 +4,7 @@ package IkiWiki::Plugin::aggregate;
|
||||||
|
|
||||||
use warnings;
|
use warnings;
|
||||||
use strict;
|
use strict;
|
||||||
use IkiWiki 2.00;
|
use IkiWiki 3.00;
|
||||||
use HTML::Parser;
|
use HTML::Parser;
|
||||||
use HTML::Tagset;
|
use HTML::Tagset;
|
||||||
use HTML::Entities;
|
use HTML::Entities;
|
||||||
|
@ -14,7 +14,7 @@ use open qw{:utf8 :std};
|
||||||
my %feeds;
|
my %feeds;
|
||||||
my %guids;
|
my %guids;
|
||||||
|
|
||||||
sub import { #{{{
|
sub import {
|
||||||
hook(type => "getopt", id => "aggregate", call => \&getopt);
|
hook(type => "getopt", id => "aggregate", call => \&getopt);
|
||||||
hook(type => "getsetup", id => "aggregate", call => \&getsetup);
|
hook(type => "getsetup", id => "aggregate", call => \&getsetup);
|
||||||
hook(type => "checkconfig", id => "aggregate", call => \&checkconfig);
|
hook(type => "checkconfig", id => "aggregate", call => \&checkconfig);
|
||||||
|
@ -26,9 +26,9 @@ sub import { #{{{
|
||||||
if (exists $config{aggregate_webtrigger} && $config{aggregate_webtrigger}) {
|
if (exists $config{aggregate_webtrigger} && $config{aggregate_webtrigger}) {
|
||||||
hook(type => "cgi", id => "aggregate", call => \&cgi);
|
hook(type => "cgi", id => "aggregate", call => \&cgi);
|
||||||
}
|
}
|
||||||
} # }}}
|
}
|
||||||
|
|
||||||
sub getopt () { #{{{
|
sub getopt () {
|
||||||
eval q{use Getopt::Long};
|
eval q{use Getopt::Long};
|
||||||
error($@) if $@;
|
error($@) if $@;
|
||||||
Getopt::Long::Configure('pass_through');
|
Getopt::Long::Configure('pass_through');
|
||||||
|
@ -36,9 +36,9 @@ sub getopt () { #{{{
|
||||||
"aggregate" => \$config{aggregate},
|
"aggregate" => \$config{aggregate},
|
||||||
"aggregateinternal!" => \$config{aggregateinternal},
|
"aggregateinternal!" => \$config{aggregateinternal},
|
||||||
);
|
);
|
||||||
} #}}}
|
}
|
||||||
|
|
||||||
sub getsetup () { #{{{
|
sub getsetup () {
|
||||||
return
|
return
|
||||||
plugin => {
|
plugin => {
|
||||||
safe => 1,
|
safe => 1,
|
||||||
|
@ -46,7 +46,7 @@ sub getsetup () { #{{{
|
||||||
},
|
},
|
||||||
aggregateinternal => {
|
aggregateinternal => {
|
||||||
type => "boolean",
|
type => "boolean",
|
||||||
example => 0,
|
example => 1,
|
||||||
description => "enable aggregation to internal pages?",
|
description => "enable aggregation to internal pages?",
|
||||||
safe => 0, # enabling needs manual transition
|
safe => 0, # enabling needs manual transition
|
||||||
rebuild => 0,
|
rebuild => 0,
|
||||||
|
@ -58,16 +58,20 @@ sub getsetup () { #{{{
|
||||||
safe => 1,
|
safe => 1,
|
||||||
rebuild => 0,
|
rebuild => 0,
|
||||||
},
|
},
|
||||||
} #}}}
|
}
|
||||||
|
|
||||||
|
sub checkconfig () {
|
||||||
|
if (! defined $config{aggregateinternal}) {
|
||||||
|
$config{aggregateinternal}=1;
|
||||||
|
}
|
||||||
|
|
||||||
sub checkconfig () { #{{{
|
|
||||||
if ($config{aggregate} && ! ($config{post_commit} &&
|
if ($config{aggregate} && ! ($config{post_commit} &&
|
||||||
IkiWiki::commit_hook_enabled())) {
|
IkiWiki::commit_hook_enabled())) {
|
||||||
launchaggregation();
|
launchaggregation();
|
||||||
}
|
}
|
||||||
} #}}}
|
}
|
||||||
|
|
||||||
sub cgi ($) { #{{{
|
sub cgi ($) {
|
||||||
my $cgi=shift;
|
my $cgi=shift;
|
||||||
|
|
||||||
if (defined $cgi->param('do') &&
|
if (defined $cgi->param('do') &&
|
||||||
|
@ -90,9 +94,9 @@ sub cgi ($) { #{{{
|
||||||
}
|
}
|
||||||
exit 0;
|
exit 0;
|
||||||
}
|
}
|
||||||
} #}}}
|
}
|
||||||
|
|
||||||
sub launchaggregation () { #{{{
|
sub launchaggregation () {
|
||||||
# See if any feeds need aggregation.
|
# See if any feeds need aggregation.
|
||||||
loadstate();
|
loadstate();
|
||||||
my @feeds=needsaggregate();
|
my @feeds=needsaggregate();
|
||||||
|
@ -135,16 +139,16 @@ sub launchaggregation () { #{{{
|
||||||
unlockaggregate();
|
unlockaggregate();
|
||||||
|
|
||||||
return 1;
|
return 1;
|
||||||
} #}}}
|
}
|
||||||
|
|
||||||
# Pages with extension _aggregated have plain html markup, pass through.
|
# Pages with extension _aggregated have plain html markup, pass through.
|
||||||
sub htmlize (@) { #{{{
|
sub htmlize (@) {
|
||||||
my %params=@_;
|
my %params=@_;
|
||||||
return $params{content};
|
return $params{content};
|
||||||
} #}}}
|
}
|
||||||
|
|
||||||
# Used by ikiwiki-transition aggregateinternal.
|
# Used by ikiwiki-transition aggregateinternal.
|
||||||
sub migrate_to_internal { #{{{
|
sub migrate_to_internal {
|
||||||
if (! lockaggregate()) {
|
if (! lockaggregate()) {
|
||||||
error("an aggregation process is currently running");
|
error("an aggregation process is currently running");
|
||||||
}
|
}
|
||||||
|
@ -190,9 +194,9 @@ sub migrate_to_internal { #{{{
|
||||||
IkiWiki::unlockwiki;
|
IkiWiki::unlockwiki;
|
||||||
|
|
||||||
unlockaggregate();
|
unlockaggregate();
|
||||||
} #}}}
|
}
|
||||||
|
|
||||||
sub needsbuild (@) { #{{{
|
sub needsbuild (@) {
|
||||||
my $needsbuild=shift;
|
my $needsbuild=shift;
|
||||||
|
|
||||||
loadstate();
|
loadstate();
|
||||||
|
@ -206,9 +210,9 @@ sub needsbuild (@) { #{{{
|
||||||
markunseen($feed->{sourcepage});
|
markunseen($feed->{sourcepage});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} # }}}
|
}
|
||||||
|
|
||||||
sub preprocess (@) { #{{{
|
sub preprocess (@) {
|
||||||
my %params=@_;
|
my %params=@_;
|
||||||
|
|
||||||
foreach my $required (qw{name url}) {
|
foreach my $required (qw{name url}) {
|
||||||
|
@ -245,6 +249,7 @@ sub preprocess (@) { #{{{
|
||||||
$feed->{template}=$params{template} . ".tmpl";
|
$feed->{template}=$params{template} . ".tmpl";
|
||||||
delete $feed->{unseen};
|
delete $feed->{unseen};
|
||||||
$feed->{lastupdate}=0 unless defined $feed->{lastupdate};
|
$feed->{lastupdate}=0 unless defined $feed->{lastupdate};
|
||||||
|
$feed->{lasttry}=$feed->{lastupdate} unless defined $feed->{lasttry};
|
||||||
$feed->{numposts}=0 unless defined $feed->{numposts};
|
$feed->{numposts}=0 unless defined $feed->{numposts};
|
||||||
$feed->{newposts}=0 unless defined $feed->{newposts};
|
$feed->{newposts}=0 unless defined $feed->{newposts};
|
||||||
$feed->{message}=gettext("new feed") unless defined $feed->{message};
|
$feed->{message}=gettext("new feed") unless defined $feed->{message};
|
||||||
|
@ -265,9 +270,9 @@ sub preprocess (@) { #{{{
|
||||||
($feed->{newposts} ? "; ".$feed->{newposts}.
|
($feed->{newposts} ? "; ".$feed->{newposts}.
|
||||||
" ".gettext("new") : "").
|
" ".gettext("new") : "").
|
||||||
")";
|
")";
|
||||||
} # }}}
|
}
|
||||||
|
|
||||||
sub delete (@) { #{{{
|
sub delete (@) {
|
||||||
my @files=@_;
|
my @files=@_;
|
||||||
|
|
||||||
# Remove feed data for removed pages.
|
# Remove feed data for removed pages.
|
||||||
|
@ -275,9 +280,9 @@ sub delete (@) { #{{{
|
||||||
my $page=pagename($file);
|
my $page=pagename($file);
|
||||||
markunseen($page);
|
markunseen($page);
|
||||||
}
|
}
|
||||||
} #}}}
|
}
|
||||||
|
|
||||||
sub markunseen ($) { #{{{
|
sub markunseen ($) {
|
||||||
my $page=shift;
|
my $page=shift;
|
||||||
|
|
||||||
foreach my $id (keys %feeds) {
|
foreach my $id (keys %feeds) {
|
||||||
|
@ -285,11 +290,11 @@ sub markunseen ($) { #{{{
|
||||||
$feeds{$id}->{unseen}=1;
|
$feeds{$id}->{unseen}=1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} #}}}
|
}
|
||||||
|
|
||||||
my $state_loaded=0;
|
my $state_loaded=0;
|
||||||
|
|
||||||
sub loadstate () { #{{{
|
sub loadstate () {
|
||||||
return if $state_loaded;
|
return if $state_loaded;
|
||||||
$state_loaded=1;
|
$state_loaded=1;
|
||||||
if (-e "$config{wikistatedir}/aggregate") {
|
if (-e "$config{wikistatedir}/aggregate") {
|
||||||
|
@ -323,9 +328,9 @@ sub loadstate () { #{{{
|
||||||
|
|
||||||
close IN;
|
close IN;
|
||||||
}
|
}
|
||||||
} #}}}
|
}
|
||||||
|
|
||||||
sub savestate () { #{{{
|
sub savestate () {
|
||||||
return unless $state_loaded;
|
return unless $state_loaded;
|
||||||
garbage_collect();
|
garbage_collect();
|
||||||
my $newfile="$config{wikistatedir}/aggregate.new";
|
my $newfile="$config{wikistatedir}/aggregate.new";
|
||||||
|
@ -342,7 +347,8 @@ sub savestate () { #{{{
|
||||||
push @line, "tag=$_" foreach @{$data->{tags}};
|
push @line, "tag=$_" foreach @{$data->{tags}};
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
push @line, "$field=".$data->{$field};
|
push @line, "$field=".$data->{$field}
|
||||||
|
if defined $data->{$field};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
print OUT join(" ", @line)."\n" || error("write $newfile: $!", $cleanup);
|
print OUT join(" ", @line)."\n" || error("write $newfile: $!", $cleanup);
|
||||||
|
@ -350,9 +356,9 @@ sub savestate () { #{{{
|
||||||
close OUT || error("save $newfile: $!", $cleanup);
|
close OUT || error("save $newfile: $!", $cleanup);
|
||||||
rename($newfile, "$config{wikistatedir}/aggregate") ||
|
rename($newfile, "$config{wikistatedir}/aggregate") ||
|
||||||
error("rename $newfile: $!", $cleanup);
|
error("rename $newfile: $!", $cleanup);
|
||||||
} #}}}
|
}
|
||||||
|
|
||||||
sub garbage_collect () { #{{{
|
sub garbage_collect () {
|
||||||
foreach my $name (keys %feeds) {
|
foreach my $name (keys %feeds) {
|
||||||
# remove any feeds that were not seen while building the pages
|
# remove any feeds that were not seen while building the pages
|
||||||
# that used to contain them
|
# that used to contain them
|
||||||
|
@ -375,9 +381,9 @@ sub garbage_collect () { #{{{
|
||||||
delete $guid->{md5};
|
delete $guid->{md5};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} #}}}
|
}
|
||||||
|
|
||||||
sub mergestate () { #{{{
|
sub mergestate () {
|
||||||
# Load the current state in from disk, and merge into it
|
# Load the current state in from disk, and merge into it
|
||||||
# values from the state in memory that might have changed
|
# values from the state in memory that might have changed
|
||||||
# during aggregation.
|
# during aggregation.
|
||||||
|
@ -390,8 +396,8 @@ sub mergestate () { #{{{
|
||||||
# fields.
|
# fields.
|
||||||
foreach my $name (keys %myfeeds) {
|
foreach my $name (keys %myfeeds) {
|
||||||
if (exists $feeds{$name}) {
|
if (exists $feeds{$name}) {
|
||||||
foreach my $field (qw{message lastupdate numposts
|
foreach my $field (qw{message lastupdate lasttry
|
||||||
newposts error}) {
|
numposts newposts error}) {
|
||||||
$feeds{$name}->{$field}=$myfeeds{$name}->{$field};
|
$feeds{$name}->{$field}=$myfeeds{$name}->{$field};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -407,15 +413,15 @@ sub mergestate () { #{{{
|
||||||
$guids{$guid}=$myguids{$guid};
|
$guids{$guid}=$myguids{$guid};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} #}}}
|
}
|
||||||
|
|
||||||
sub clearstate () { #{{{
|
sub clearstate () {
|
||||||
%feeds=();
|
%feeds=();
|
||||||
%guids=();
|
%guids=();
|
||||||
$state_loaded=0;
|
$state_loaded=0;
|
||||||
} #}}}
|
}
|
||||||
|
|
||||||
sub expire () { #{{{
|
sub expire () {
|
||||||
foreach my $feed (values %feeds) {
|
foreach my $feed (values %feeds) {
|
||||||
next unless $feed->{expireage} || $feed->{expirecount};
|
next unless $feed->{expireage} || $feed->{expirecount};
|
||||||
my $count=0;
|
my $count=0;
|
||||||
|
@ -444,24 +450,24 @@ sub expire () { #{{{
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} #}}}
|
}
|
||||||
|
|
||||||
sub needsaggregate () { #{{{
|
sub needsaggregate () {
|
||||||
return values %feeds if $config{rebuild};
|
return values %feeds if $config{rebuild};
|
||||||
return grep { time - $_->{lastupdate} >= $_->{updateinterval} } values %feeds;
|
return grep { time - $_->{lastupdate} >= $_->{updateinterval} } values %feeds;
|
||||||
} #}}}
|
}
|
||||||
|
|
||||||
sub aggregate (@) { #{{{
|
sub aggregate (@) {
|
||||||
eval q{use XML::Feed};
|
eval q{use XML::Feed};
|
||||||
error($@) if $@;
|
error($@) if $@;
|
||||||
eval q{use URI::Fetch};
|
eval q{use URI::Fetch};
|
||||||
error($@) if $@;
|
error($@) if $@;
|
||||||
|
|
||||||
foreach my $feed (@_) {
|
foreach my $feed (@_) {
|
||||||
$feed->{lastupdate}=time;
|
$feed->{lasttry}=time;
|
||||||
$feed->{newposts}=0;
|
$feed->{newposts}=0;
|
||||||
$feed->{message}=sprintf(gettext("processed ok at %s"),
|
$feed->{message}=sprintf(gettext("last checked %s"),
|
||||||
displaytime($feed->{lastupdate}));
|
displaytime($feed->{lasttry}));
|
||||||
$feed->{error}=0;
|
$feed->{error}=0;
|
||||||
|
|
||||||
debug(sprintf(gettext("checking feed %s ..."), $feed->{name}));
|
debug(sprintf(gettext("checking feed %s ..."), $feed->{name}));
|
||||||
|
@ -483,6 +489,10 @@ sub aggregate (@) { #{{{
|
||||||
debug($feed->{message});
|
debug($feed->{message});
|
||||||
next;
|
next;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
# lastupdate is only set if we were able to contact the server
|
||||||
|
$feed->{lastupdate}=$feed->{lasttry};
|
||||||
|
|
||||||
if ($res->status == URI::Fetch::URI_GONE()) {
|
if ($res->status == URI::Fetch::URI_GONE()) {
|
||||||
$feed->{message}=gettext("feed not found");
|
$feed->{message}=gettext("feed not found");
|
||||||
$feed->{error}=1;
|
$feed->{error}=1;
|
||||||
|
@ -496,15 +506,19 @@ sub aggregate (@) { #{{{
|
||||||
# that contains invalid UTF-8 sequences. Convert
|
# that contains invalid UTF-8 sequences. Convert
|
||||||
# feed to ascii to try to work around.
|
# feed to ascii to try to work around.
|
||||||
$feed->{message}.=" ".sprintf(gettext("(invalid UTF-8 stripped from feed)"));
|
$feed->{message}.=" ".sprintf(gettext("(invalid UTF-8 stripped from feed)"));
|
||||||
$content=Encode::decode_utf8($content, 0);
|
$f=eval {
|
||||||
$f=eval{XML::Feed->parse(\$content)};
|
$content=Encode::decode_utf8($content, 0);
|
||||||
|
XML::Feed->parse(\$content)
|
||||||
|
};
|
||||||
}
|
}
|
||||||
if ($@) {
|
if ($@) {
|
||||||
# Another possibility is badly escaped entities.
|
# Another possibility is badly escaped entities.
|
||||||
$feed->{message}.=" ".sprintf(gettext("(feed entities escaped)"));
|
$feed->{message}.=" ".sprintf(gettext("(feed entities escaped)"));
|
||||||
$content=~s/\&(?!amp)(\w+);/&$1;/g;
|
$content=~s/\&(?!amp)(\w+);/&$1;/g;
|
||||||
$content=Encode::decode_utf8($content, 0);
|
$f=eval {
|
||||||
$f=eval{XML::Feed->parse(\$content)};
|
$content=Encode::decode_utf8($content, 0);
|
||||||
|
XML::Feed->parse(\$content)
|
||||||
|
};
|
||||||
}
|
}
|
||||||
if ($@) {
|
if ($@) {
|
||||||
$feed->{message}=gettext("feed crashed XML::Feed!")." ($@)";
|
$feed->{message}=gettext("feed crashed XML::Feed!")." ($@)";
|
||||||
|
@ -520,10 +534,15 @@ sub aggregate (@) { #{{{
|
||||||
}
|
}
|
||||||
|
|
||||||
foreach my $entry ($f->entries) {
|
foreach my $entry ($f->entries) {
|
||||||
my $content=$content=$entry->content->body;
|
# XML::Feed doesn't work around XML::Atom's bizarre
|
||||||
|
# API, so we will. Real unicode strings? Yes please.
|
||||||
|
# See [[bugs/Aggregated_Atom_feeds_are_double-encoded]]
|
||||||
|
local $XML::Atom::ForceUnicode = 1;
|
||||||
|
|
||||||
|
my $c=$entry->content;
|
||||||
# atom feeds may have no content, only a summary
|
# atom feeds may have no content, only a summary
|
||||||
if (! defined $content && ref $entry->summary) {
|
if (! defined $c && ref $entry->summary) {
|
||||||
$content=$entry->summary->body;
|
$c=$entry->summary;
|
||||||
}
|
}
|
||||||
|
|
||||||
add_page(
|
add_page(
|
||||||
|
@ -531,15 +550,16 @@ sub aggregate (@) { #{{{
|
||||||
copyright => $f->copyright,
|
copyright => $f->copyright,
|
||||||
title => defined $entry->title ? decode_entities($entry->title) : "untitled",
|
title => defined $entry->title ? decode_entities($entry->title) : "untitled",
|
||||||
link => $entry->link,
|
link => $entry->link,
|
||||||
content => defined $content ? $content : "",
|
content => (defined $c && defined $c->body) ? $c->body : "",
|
||||||
guid => defined $entry->id ? $entry->id : time."_".$feed->{name},
|
guid => defined $entry->id ? $entry->id : time."_".$feed->{name},
|
||||||
ctime => $entry->issued ? ($entry->issued->epoch || time) : time,
|
ctime => $entry->issued ? ($entry->issued->epoch || time) : time,
|
||||||
|
base => (defined $c && $c->can("base")) ? $c->base : undef,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} #}}}
|
}
|
||||||
|
|
||||||
sub add_page (@) { #{{{
|
sub add_page (@) {
|
||||||
my %params=@_;
|
my %params=@_;
|
||||||
|
|
||||||
my $feed=$params{feed};
|
my $feed=$params{feed};
|
||||||
|
@ -605,7 +625,8 @@ sub add_page (@) { #{{{
|
||||||
my $template=template($feed->{template}, blind_cache => 1);
|
my $template=template($feed->{template}, blind_cache => 1);
|
||||||
$template->param(title => $params{title})
|
$template->param(title => $params{title})
|
||||||
if defined $params{title} && length($params{title});
|
if defined $params{title} && length($params{title});
|
||||||
$template->param(content => htmlescape(htmlabs($params{content}, $feed->{feedurl})));
|
$template->param(content => wikiescape(htmlabs($params{content},
|
||||||
|
defined $params{base} ? $params{base} : $feed->{feedurl})));
|
||||||
$template->param(name => $feed->{name});
|
$template->param(name => $feed->{name});
|
||||||
$template->param(url => $feed->{url});
|
$template->param(url => $feed->{url});
|
||||||
$template->param(copyright => $params{copyright})
|
$template->param(copyright => $params{copyright})
|
||||||
|
@ -625,23 +646,25 @@ sub add_page (@) { #{{{
|
||||||
# Store it in pagectime for expiry code to use also.
|
# Store it in pagectime for expiry code to use also.
|
||||||
$IkiWiki::pagectime{$guid->{page}}=$mtime;
|
$IkiWiki::pagectime{$guid->{page}}=$mtime;
|
||||||
}
|
}
|
||||||
} #}}}
|
else {
|
||||||
|
# Dummy value for expiry code.
|
||||||
|
$IkiWiki::pagectime{$guid->{page}}=time;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
sub htmlescape ($) { #{{{
|
sub wikiescape ($) {
|
||||||
# escape accidental wikilinks and preprocessor stuff
|
# escape accidental wikilinks and preprocessor stuff
|
||||||
my $html=shift;
|
return encode_entities(shift, '\[\]');
|
||||||
$html=~s/(?<!\\)\[\[/\\\[\[/g;
|
}
|
||||||
return $html;
|
|
||||||
} #}}}
|
|
||||||
|
|
||||||
sub urlabs ($$) { #{{{
|
sub urlabs ($$) {
|
||||||
my $url=shift;
|
my $url=shift;
|
||||||
my $urlbase=shift;
|
my $urlbase=shift;
|
||||||
|
|
||||||
URI->new_abs($url, $urlbase)->as_string;
|
URI->new_abs($url, $urlbase)->as_string;
|
||||||
} #}}}
|
}
|
||||||
|
|
||||||
sub htmlabs ($$) { #{{{
|
sub htmlabs ($$) {
|
||||||
# Convert links in html from relative to absolute.
|
# Convert links in html from relative to absolute.
|
||||||
# Note that this is a heuristic, which is not specified by the rss
|
# Note that this is a heuristic, which is not specified by the rss
|
||||||
# spec and may not be right for all feeds. Also, see Debian
|
# spec and may not be right for all feeds. Also, see Debian
|
||||||
|
@ -677,15 +700,15 @@ sub htmlabs ($$) { #{{{
|
||||||
$p->eof;
|
$p->eof;
|
||||||
|
|
||||||
return $ret;
|
return $ret;
|
||||||
} #}}}
|
}
|
||||||
|
|
||||||
sub htmlfn ($) { #{{{
|
sub htmlfn ($) {
|
||||||
return shift().".".($config{aggregateinternal} ? "_aggregated" : $config{htmlext});
|
return shift().".".($config{aggregateinternal} ? "_aggregated" : $config{htmlext});
|
||||||
} #}}}
|
}
|
||||||
|
|
||||||
my $aggregatelock;
|
my $aggregatelock;
|
||||||
|
|
||||||
sub lockaggregate () { #{{{
|
sub lockaggregate () {
|
||||||
# Take an exclusive lock to prevent multiple concurrent aggregators.
|
# Take an exclusive lock to prevent multiple concurrent aggregators.
|
||||||
# Returns true if the lock was aquired.
|
# Returns true if the lock was aquired.
|
||||||
if (! -d $config{wikistatedir}) {
|
if (! -d $config{wikistatedir}) {
|
||||||
|
@ -698,11 +721,11 @@ sub lockaggregate () { #{{{
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
return 1;
|
return 1;
|
||||||
} #}}}
|
}
|
||||||
|
|
||||||
sub unlockaggregate () { #{{{
|
sub unlockaggregate () {
|
||||||
return close($aggregatelock) if $aggregatelock;
|
return close($aggregatelock) if $aggregatelock;
|
||||||
return;
|
return;
|
||||||
} #}}}
|
}
|
||||||
|
|
||||||
1
|
1
|
||||||
|
|
|
@ -4,7 +4,7 @@ package IkiWiki::Plugin::amazon_s3;
|
||||||
use warnings;
|
use warnings;
|
||||||
no warnings 'redefine';
|
no warnings 'redefine';
|
||||||
use strict;
|
use strict;
|
||||||
use IkiWiki 2.00;
|
use IkiWiki 3.00;
|
||||||
use IkiWiki::Render;
|
use IkiWiki::Render;
|
||||||
use Net::Amazon::S3;
|
use Net::Amazon::S3;
|
||||||
|
|
||||||
|
@ -16,13 +16,13 @@ BEGIN {
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
sub import { #{{{
|
sub import {
|
||||||
hook(type => "getopt", id => "amazon_s3", call => \&getopt);
|
hook(type => "getopt", id => "amazon_s3", call => \&getopt);
|
||||||
hook(type => "getsetup", id => "amazon_s3", call => \&getsetup);
|
hook(type => "getsetup", id => "amazon_s3", call => \&getsetup);
|
||||||
hook(type => "checkconfig", id => "amazon_s3", call => \&checkconfig);
|
hook(type => "checkconfig", id => "amazon_s3", call => \&checkconfig);
|
||||||
} # }}}
|
}
|
||||||
|
|
||||||
sub getopt () { #{{{
|
sub getopt () {
|
||||||
eval q{use Getopt::Long};
|
eval q{use Getopt::Long};
|
||||||
error($@) if $@;
|
error($@) if $@;
|
||||||
Getopt::Long::Configure('pass_through');
|
Getopt::Long::Configure('pass_through');
|
||||||
|
@ -38,9 +38,9 @@ sub getopt () { #{{{
|
||||||
debug(gettext("done"));
|
debug(gettext("done"));
|
||||||
exit(0);
|
exit(0);
|
||||||
});
|
});
|
||||||
} #}}}
|
}
|
||||||
|
|
||||||
sub getsetup () { #{{{
|
sub getsetup () {
|
||||||
return
|
return
|
||||||
plugin => {
|
plugin => {
|
||||||
safe => 0,
|
safe => 0,
|
||||||
|
@ -88,9 +88,9 @@ sub getsetup () { #{{{
|
||||||
safe => 1,
|
safe => 1,
|
||||||
rebuild => 1,
|
rebuild => 1,
|
||||||
},
|
},
|
||||||
} #}}}
|
}
|
||||||
|
|
||||||
sub checkconfig { #{{{
|
sub checkconfig {
|
||||||
foreach my $field (qw{amazon_s3_key_id amazon_s3_key_file
|
foreach my $field (qw{amazon_s3_key_id amazon_s3_key_file
|
||||||
amazon_s3_bucket}) {
|
amazon_s3_bucket}) {
|
||||||
if (! exists $config{$field} || ! defined $config{$field}) {
|
if (! exists $config{$field} || ! defined $config{$field}) {
|
||||||
|
@ -101,11 +101,11 @@ sub checkconfig { #{{{
|
||||||
! defined $config{amazon_s3_prefix}) {
|
! defined $config{amazon_s3_prefix}) {
|
||||||
$config{amazon_s3_prefix}="wiki/";
|
$config{amazon_s3_prefix}="wiki/";
|
||||||
}
|
}
|
||||||
} #}}}
|
}
|
||||||
|
|
||||||
{
|
{
|
||||||
my $bucket;
|
my $bucket;
|
||||||
sub getbucket { #{{{
|
sub getbucket {
|
||||||
return $bucket if defined $bucket;
|
return $bucket if defined $bucket;
|
||||||
|
|
||||||
open(IN, "<", $config{amazon_s3_key_file}) || error($config{amazon_s3_key_file}.": ".$!);
|
open(IN, "<", $config{amazon_s3_key_file}) || error($config{amazon_s3_key_file}.": ".$!);
|
||||||
|
@ -138,11 +138,11 @@ sub getbucket { #{{{
|
||||||
}
|
}
|
||||||
|
|
||||||
return $bucket;
|
return $bucket;
|
||||||
} #}}}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
# Given a file, return any S3 keys associated with it.
|
# Given a file, return any S3 keys associated with it.
|
||||||
sub file2keys ($) { #{{{
|
sub file2keys ($) {
|
||||||
my $file=shift;
|
my $file=shift;
|
||||||
|
|
||||||
my @keys;
|
my @keys;
|
||||||
|
@ -162,14 +162,14 @@ sub file2keys ($) { #{{{
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return @keys;
|
return @keys;
|
||||||
} #}}}
|
}
|
||||||
|
|
||||||
package IkiWiki;
|
package IkiWiki;
|
||||||
use File::MimeInfo;
|
use File::MimeInfo;
|
||||||
use Encode;
|
use Encode;
|
||||||
|
|
||||||
# This is a wrapper around the real writefile.
|
# This is a wrapper around the real writefile.
|
||||||
sub writefile ($$$;$$) { #{{{
|
sub writefile ($$$;$$) {
|
||||||
my $file=shift;
|
my $file=shift;
|
||||||
my $destdir=shift;
|
my $destdir=shift;
|
||||||
my $content=shift;
|
my $content=shift;
|
||||||
|
@ -225,10 +225,10 @@ sub writefile ($$$;$$) { #{{{
|
||||||
}
|
}
|
||||||
|
|
||||||
return $ret;
|
return $ret;
|
||||||
} #}}}
|
}
|
||||||
|
|
||||||
# This is a wrapper around the real prune.
|
# This is a wrapper around the real prune.
|
||||||
sub prune ($) { #{{{
|
sub prune ($) {
|
||||||
my $file=shift;
|
my $file=shift;
|
||||||
|
|
||||||
my @keys=IkiWiki::Plugin::amazon_s3::file2keys($file);
|
my @keys=IkiWiki::Plugin::amazon_s3::file2keys($file);
|
||||||
|
@ -247,6 +247,6 @@ sub prune ($) { #{{{
|
||||||
}
|
}
|
||||||
|
|
||||||
return $IkiWiki::Plugin::amazon_s3::subs{'IkiWiki::prune'}->($file);
|
return $IkiWiki::Plugin::amazon_s3::subs{'IkiWiki::prune'}->($file);
|
||||||
} #}}}
|
}
|
||||||
|
|
||||||
1
|
1
|
||||||
|
|
|
@ -3,14 +3,14 @@ package IkiWiki::Plugin::anonok;
|
||||||
|
|
||||||
use warnings;
|
use warnings;
|
||||||
use strict;
|
use strict;
|
||||||
use IkiWiki 2.00;
|
use IkiWiki 3.00;
|
||||||
|
|
||||||
sub import { #{{{
|
sub import {
|
||||||
hook(type => "getsetup", id => "anonok", call => \&getsetup);
|
hook(type => "getsetup", id => "anonok", call => \&getsetup);
|
||||||
hook(type => "canedit", id => "anonok", call => \&canedit);
|
hook(type => "canedit", id => "anonok", call => \&canedit);
|
||||||
} # }}}
|
}
|
||||||
|
|
||||||
sub getsetup () { #{{{
|
sub getsetup () {
|
||||||
return
|
return
|
||||||
plugin => {
|
plugin => {
|
||||||
safe => 1,
|
safe => 1,
|
||||||
|
@ -24,9 +24,9 @@ sub getsetup () { #{{{
|
||||||
safe => 1,
|
safe => 1,
|
||||||
rebuild => 0,
|
rebuild => 0,
|
||||||
},
|
},
|
||||||
} #}}}
|
}
|
||||||
|
|
||||||
sub canedit ($$$) { #{{{
|
sub canedit ($$$) {
|
||||||
my $page=shift;
|
my $page=shift;
|
||||||
my $cgi=shift;
|
my $cgi=shift;
|
||||||
my $session=shift;
|
my $session=shift;
|
||||||
|
@ -45,6 +45,6 @@ sub canedit ($$$) { #{{{
|
||||||
else {
|
else {
|
||||||
return "";
|
return "";
|
||||||
}
|
}
|
||||||
} #}}}
|
}
|
||||||
|
|
||||||
1
|
1
|
||||||
|
|
|
@ -3,17 +3,18 @@ package IkiWiki::Plugin::attachment;
|
||||||
|
|
||||||
use warnings;
|
use warnings;
|
||||||
use strict;
|
use strict;
|
||||||
use IkiWiki 2.00;
|
use IkiWiki 3.00;
|
||||||
|
|
||||||
sub import { #{{{
|
sub import {
|
||||||
|
add_underlay("javascript");
|
||||||
hook(type => "getsetup", id => "attachment", call => \&getsetup);
|
hook(type => "getsetup", id => "attachment", call => \&getsetup);
|
||||||
hook(type => "checkconfig", id => "attachment", call => \&checkconfig);
|
hook(type => "checkconfig", id => "attachment", call => \&checkconfig);
|
||||||
hook(type => "formbuilder_setup", id => "attachment", call => \&formbuilder_setup);
|
hook(type => "formbuilder_setup", id => "attachment", call => \&formbuilder_setup);
|
||||||
hook(type => "formbuilder", id => "attachment", call => \&formbuilder);
|
hook(type => "formbuilder", id => "attachment", call => \&formbuilder);
|
||||||
IkiWiki::loadplugin("filecheck");
|
IkiWiki::loadplugin("filecheck");
|
||||||
} # }}}
|
}
|
||||||
|
|
||||||
sub getsetup () { #{{{
|
sub getsetup () {
|
||||||
return
|
return
|
||||||
plugin => {
|
plugin => {
|
||||||
safe => 1,
|
safe => 1,
|
||||||
|
@ -34,9 +35,9 @@ sub getsetup () { #{{{
|
||||||
safe => 0, # executed
|
safe => 0, # executed
|
||||||
rebuild => 0,
|
rebuild => 0,
|
||||||
},
|
},
|
||||||
} #}}}
|
}
|
||||||
|
|
||||||
sub check_canattach ($$;$) { #{{{
|
sub check_canattach ($$;$) {
|
||||||
my $session=shift;
|
my $session=shift;
|
||||||
my $dest=shift; # where it's going to be put, under the srcdir
|
my $dest=shift; # where it's going to be put, under the srcdir
|
||||||
my $file=shift; # the path to the attachment currently
|
my $file=shift; # the path to the attachment currently
|
||||||
|
@ -60,36 +61,19 @@ sub check_canattach ($$;$) { #{{{
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
# XXX deprecated, should be removed eventually
|
|
||||||
if ($allowed) {
|
|
||||||
foreach my $admin (@{$config{adminuser}}) {
|
|
||||||
my $allowed_attachments=IkiWiki::userinfo_get($admin, "allowed_attachments");
|
|
||||||
if (defined $allowed_attachments &&
|
|
||||||
length $allowed_attachments) {
|
|
||||||
$allowed=pagespec_match($dest,
|
|
||||||
$allowed_attachments,
|
|
||||||
file => $file,
|
|
||||||
user => $session->param("name"),
|
|
||||||
ip => $ENV{REMOTE_ADDR},
|
|
||||||
);
|
|
||||||
last if $allowed;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (! $allowed) {
|
if (! $allowed) {
|
||||||
error(gettext("prohibited by allowed_attachments")." ($allowed)");
|
error(gettext("prohibited by allowed_attachments")." ($allowed)");
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
} #}}}
|
}
|
||||||
|
|
||||||
sub checkconfig () { #{{{
|
sub checkconfig () {
|
||||||
$config{cgi_disable_uploads}=0;
|
$config{cgi_disable_uploads}=0;
|
||||||
} #}}}
|
}
|
||||||
|
|
||||||
sub formbuilder_setup (@) { #{{{
|
sub formbuilder_setup (@) {
|
||||||
my %params=@_;
|
my %params=@_;
|
||||||
my $form=$params{form};
|
my $form=$params{form};
|
||||||
my $q=$params{cgi};
|
my $q=$params{cgi};
|
||||||
|
@ -104,10 +88,10 @@ sub formbuilder_setup (@) { #{{{
|
||||||
$form->tmpl_param("field-upload" => '<input name="_submit" type="submit" value="Upload Attachment" />');
|
$form->tmpl_param("field-upload" => '<input name="_submit" type="submit" value="Upload Attachment" />');
|
||||||
$form->tmpl_param("field-link" => '<input name="_submit" type="submit" value="Insert Links" />');
|
$form->tmpl_param("field-link" => '<input name="_submit" type="submit" value="Insert Links" />');
|
||||||
|
|
||||||
# Add the javascript from the toggle plugin;
|
# Add the toggle javascript; the attachments interface uses
|
||||||
# the attachments interface uses it to toggle visibility.
|
# it to toggle visibility.
|
||||||
require IkiWiki::Plugin::toggle;
|
require IkiWiki::Plugin::toggle;
|
||||||
$form->tmpl_param("javascript" => $IkiWiki::Plugin::toggle::javascript);
|
$form->tmpl_param("javascript" => IkiWiki::Plugin::toggle::include_javascript($params{page}, 1));
|
||||||
# Start with the attachments interface toggled invisible,
|
# Start with the attachments interface toggled invisible,
|
||||||
# but if it was used, keep it open.
|
# but if it was used, keep it open.
|
||||||
if ($form->submitted ne "Upload Attachment" &&
|
if ($form->submitted ne "Upload Attachment" &&
|
||||||
|
@ -119,42 +103,9 @@ sub formbuilder_setup (@) { #{{{
|
||||||
$form->tmpl_param("attachments-class" => "toggleable-open");
|
$form->tmpl_param("attachments-class" => "toggleable-open");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
elsif ($form->title eq "preferences") {
|
}
|
||||||
# XXX deprecated, should remove eventually
|
|
||||||
my $session=$params{session};
|
|
||||||
my $user_name=$session->param("name");
|
|
||||||
|
|
||||||
$form->field(name => "allowed_attachments", size => 50,
|
sub formbuilder (@) {
|
||||||
fieldset => "admin",
|
|
||||||
comment => "deprecated; please move to allowed_attachments in setup file",
|
|
||||||
);
|
|
||||||
if (! IkiWiki::is_admin($user_name)) {
|
|
||||||
$form->field(name => "allowed_attachments", type => "hidden");
|
|
||||||
}
|
|
||||||
if (! $form->submitted) {
|
|
||||||
my $value=IkiWiki::userinfo_get($user_name, "allowed_attachments");
|
|
||||||
if (length $value) {
|
|
||||||
$form->field(name => "allowed_attachments", force => 1,
|
|
||||||
value => IkiWiki::userinfo_get($user_name, "allowed_attachments"));
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
$form->field(name => "allowed_attachments", type => "hidden");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if ($form->submitted && $form->submitted eq 'Save Preferences') {
|
|
||||||
if (defined $form->field("allowed_attachments")) {
|
|
||||||
IkiWiki::userinfo_set($user_name, "allowed_attachments",
|
|
||||||
$form->field("allowed_attachments")) ||
|
|
||||||
error("failed to set allowed_attachments");
|
|
||||||
if (! length $form->field("allowed_attachments")) {
|
|
||||||
$form->field(name => "allowed_attachments", type => "hidden");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} #}}}
|
|
||||||
|
|
||||||
sub formbuilder (@) { #{{{
|
|
||||||
my %params=@_;
|
my %params=@_;
|
||||||
my $form=$params{form};
|
my $form=$params{form};
|
||||||
my $q=$params{cgi};
|
my $q=$params{cgi};
|
||||||
|
@ -252,9 +203,9 @@ sub formbuilder (@) { #{{{
|
||||||
# Generate the attachment list only after having added any new
|
# Generate the attachment list only after having added any new
|
||||||
# attachments.
|
# attachments.
|
||||||
$form->tmpl_param("attachment_list" => [attachment_list($form->field('page'))]);
|
$form->tmpl_param("attachment_list" => [attachment_list($form->field('page'))]);
|
||||||
} # }}}
|
}
|
||||||
|
|
||||||
sub attachment_location ($) { #{{{
|
sub attachment_location ($) {
|
||||||
my $page=shift;
|
my $page=shift;
|
||||||
|
|
||||||
# Put the attachment in a subdir of the page it's attached
|
# Put the attachment in a subdir of the page it's attached
|
||||||
|
@ -263,9 +214,9 @@ sub attachment_location ($) { #{{{
|
||||||
$page.="/" if length $page;
|
$page.="/" if length $page;
|
||||||
|
|
||||||
return $page;
|
return $page;
|
||||||
} #}}}
|
}
|
||||||
|
|
||||||
sub attachment_list ($) { #{{{
|
sub attachment_list ($) {
|
||||||
my $page=shift;
|
my $page=shift;
|
||||||
my $loc=attachment_location($page);
|
my $loc=attachment_location($page);
|
||||||
|
|
||||||
|
@ -279,7 +230,6 @@ sub attachment_list ($) { #{{{
|
||||||
link => htmllink($page, $page, $f, noimageinline => 1),
|
link => htmllink($page, $page, $f, noimageinline => 1),
|
||||||
size => IkiWiki::Plugin::filecheck::humansize((stat(_))[7]),
|
size => IkiWiki::Plugin::filecheck::humansize((stat(_))[7]),
|
||||||
mtime => displaytime($IkiWiki::pagemtime{$f}),
|
mtime => displaytime($IkiWiki::pagemtime{$f}),
|
||||||
mtime_raw => $IkiWiki::pagemtime{$f},
|
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -287,6 +237,6 @@ sub attachment_list ($) { #{{{
|
||||||
# Sort newer attachments to the top of the list, so a newly-added
|
# Sort newer attachments to the top of the list, so a newly-added
|
||||||
# attachment appears just before the form used to add it.
|
# attachment appears just before the form used to add it.
|
||||||
return sort { $b->{mtime_raw} <=> $a->{mtime_raw} || $a->{link} cmp $b->{link} } @ret;
|
return sort { $b->{mtime_raw} <=> $a->{mtime_raw} || $a->{link} cmp $b->{link} } @ret;
|
||||||
} #}}}
|
}
|
||||||
|
|
||||||
1
|
1
|
||||||
|
|
|
@ -3,23 +3,23 @@ package IkiWiki::Plugin::autoindex;
|
||||||
|
|
||||||
use warnings;
|
use warnings;
|
||||||
use strict;
|
use strict;
|
||||||
use IkiWiki 2.00;
|
use IkiWiki 3.00;
|
||||||
use Encode;
|
use Encode;
|
||||||
|
|
||||||
sub import { #{{{
|
sub import {
|
||||||
hook(type => "getsetup", id => "autoindex", call => \&getsetup);
|
hook(type => "getsetup", id => "autoindex", call => \&getsetup);
|
||||||
hook(type => "refresh", id => "autoindex", call => \&refresh);
|
hook(type => "refresh", id => "autoindex", call => \&refresh);
|
||||||
} # }}}
|
}
|
||||||
|
|
||||||
sub getsetup () { #{{{
|
sub getsetup () {
|
||||||
return
|
return
|
||||||
plugin => {
|
plugin => {
|
||||||
safe => 1,
|
safe => 1,
|
||||||
rebuild => 0,
|
rebuild => 0,
|
||||||
},
|
},
|
||||||
} #}}}
|
}
|
||||||
|
|
||||||
sub genindex ($) { #{{{
|
sub genindex ($) {
|
||||||
my $page=shift;
|
my $page=shift;
|
||||||
my $file=newpagefile($page, $config{default_pageext});
|
my $file=newpagefile($page, $config{default_pageext});
|
||||||
my $template=template("autoindex.tmpl");
|
my $template=template("autoindex.tmpl");
|
||||||
|
@ -28,9 +28,9 @@ sub genindex ($) { #{{{
|
||||||
if ($config{rcs}) {
|
if ($config{rcs}) {
|
||||||
IkiWiki::rcs_add($file);
|
IkiWiki::rcs_add($file);
|
||||||
}
|
}
|
||||||
} #}}}
|
}
|
||||||
|
|
||||||
sub refresh () { #{{{
|
sub refresh () {
|
||||||
eval q{use File::Find};
|
eval q{use File::Find};
|
||||||
error($@) if $@;
|
error($@) if $@;
|
||||||
|
|
||||||
|
@ -107,6 +107,6 @@ sub refresh () { #{{{
|
||||||
IkiWiki::enable_commit_hook();
|
IkiWiki::enable_commit_hook();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} #}}}
|
}
|
||||||
|
|
||||||
1
|
1
|
||||||
|
|
|
@ -0,0 +1,116 @@
|
||||||
|
#!/usr/bin/perl
|
||||||
|
package IkiWiki::Plugin::blogspam;
|
||||||
|
|
||||||
|
use warnings;
|
||||||
|
use strict;
|
||||||
|
use IkiWiki 3.00;
|
||||||
|
|
||||||
|
my $defaulturl='http://test.blogspam.net:8888/';
|
||||||
|
|
||||||
|
sub import {
|
||||||
|
hook(type => "getsetup", id => "blogspam", call => \&getsetup);
|
||||||
|
hook(type => "checkcontent", id => "blogspam", call => \&checkcontent);
|
||||||
|
}
|
||||||
|
|
||||||
|
sub getsetup () {
|
||||||
|
return
|
||||||
|
plugin => {
|
||||||
|
safe => 1,
|
||||||
|
rebuild => 0,
|
||||||
|
},
|
||||||
|
blogspam_pagespec => {
|
||||||
|
type => 'pagespec',
|
||||||
|
example => 'postcomment(*)',
|
||||||
|
description => 'PageSpec of pages to check for spam',
|
||||||
|
link => 'ikiwiki/PageSpec',
|
||||||
|
safe => 1,
|
||||||
|
rebuild => 0,
|
||||||
|
},
|
||||||
|
blogspam_options => {
|
||||||
|
type => "string",
|
||||||
|
example => "blacklist=1.2.3.4,blacklist=8.7.6.5,max-links=10",
|
||||||
|
description => "options to send to blogspam server",
|
||||||
|
link => "http://blogspam.net/api/testComment.html#options",
|
||||||
|
safe => 1,
|
||||||
|
rebuild => 0,
|
||||||
|
},
|
||||||
|
blogspam_server => {
|
||||||
|
type => "string",
|
||||||
|
default => $defaulturl,
|
||||||
|
description => "blogspam server XML-RPC url",
|
||||||
|
safe => 1,
|
||||||
|
rebuild => 0,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
sub checkcontent (@) {
|
||||||
|
my %params=@_;
|
||||||
|
|
||||||
|
eval q{
|
||||||
|
use RPC::XML;
|
||||||
|
use RPC::XML::Client;
|
||||||
|
};
|
||||||
|
if ($@) {
|
||||||
|
warn($@);
|
||||||
|
return undef;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (exists $config{blogspam_pagespec}) {
|
||||||
|
return undef
|
||||||
|
if ! pagespec_match($params{page}, $config{blogspam_pagespec},
|
||||||
|
location => $params{page});
|
||||||
|
}
|
||||||
|
|
||||||
|
my $url=$defaulturl;
|
||||||
|
$url = $config{blogspam_server} if exists $config{blogspam_server};
|
||||||
|
my $client = RPC::XML::Client->new($url);
|
||||||
|
|
||||||
|
my @options = split(",", $config{blogspam_options})
|
||||||
|
if exists $config{blogspam_options};
|
||||||
|
|
||||||
|
# Allow short comments and whitespace-only edits, unless the user
|
||||||
|
# has overridden min-words themselves.
|
||||||
|
push @options, "min-words=0"
|
||||||
|
unless grep /^min-words=/i, @options;
|
||||||
|
# Wiki pages can have a lot of urls, unless the user specifically
|
||||||
|
# wants to limit them.
|
||||||
|
push @options, "exclude=lotsaurls"
|
||||||
|
unless grep /^max-links/i, @options;
|
||||||
|
# Unless the user specified a size check, disable such checking.
|
||||||
|
push @options, "exclude=size"
|
||||||
|
unless grep /^(?:max|min)-size/i, @options;
|
||||||
|
# This test has absurd false positives on words like "alpha"
|
||||||
|
# and "buy".
|
||||||
|
push @options, "exclude=stopwords";
|
||||||
|
|
||||||
|
my %req=(
|
||||||
|
ip => $ENV{REMOTE_ADDR},
|
||||||
|
comment => $params{content},
|
||||||
|
subject => defined $params{subject} ? $params{subject} : "",
|
||||||
|
name => defined $params{author} ? $params{author} : "",
|
||||||
|
link => exists $params{url} ? $params{url} : "",
|
||||||
|
options => join(",", @options),
|
||||||
|
site => $config{url},
|
||||||
|
version => "ikiwiki ".$IkiWiki::version,
|
||||||
|
);
|
||||||
|
my $res = $client->send_request('testComment', \%req);
|
||||||
|
|
||||||
|
if (! ref $res || ! defined $res->value) {
|
||||||
|
debug("failed to get response from blogspam server ($url)");
|
||||||
|
return undef;
|
||||||
|
}
|
||||||
|
elsif ($res->value =~ /^SPAM:(.*)/) {
|
||||||
|
eval q{use Data::Dumper};
|
||||||
|
debug("blogspam server reports ".$res->value.": ".Dumper(\%req));
|
||||||
|
return gettext("Sorry, but that looks like spam to <a href=\"http://blogspam.net/\">blogspam</a>: ").$1;
|
||||||
|
}
|
||||||
|
elsif ($res->value ne 'OK') {
|
||||||
|
debug("blogspam server failure: ".$res->value);
|
||||||
|
return undef;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
return undef;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
1
|
|
@ -4,22 +4,22 @@ package IkiWiki::Plugin::brokenlinks;
|
||||||
|
|
||||||
use warnings;
|
use warnings;
|
||||||
use strict;
|
use strict;
|
||||||
use IkiWiki 2.00;
|
use IkiWiki 3.00;
|
||||||
|
|
||||||
sub import { #{{{
|
sub import {
|
||||||
hook(type => "getsetup", id => "brokenlinks", call => \&getsetup);
|
hook(type => "getsetup", id => "brokenlinks", call => \&getsetup);
|
||||||
hook(type => "preprocess", id => "brokenlinks", call => \&preprocess);
|
hook(type => "preprocess", id => "brokenlinks", call => \&preprocess);
|
||||||
} # }}}
|
}
|
||||||
|
|
||||||
sub getsetup { #{{{
|
sub getsetup {
|
||||||
return
|
return
|
||||||
plugin => {
|
plugin => {
|
||||||
safe => 1,
|
safe => 1,
|
||||||
rebuild => undef,
|
rebuild => undef,
|
||||||
},
|
},
|
||||||
} #}}}
|
}
|
||||||
|
|
||||||
sub preprocess (@) { #{{{
|
sub preprocess (@) {
|
||||||
my %params=@_;
|
my %params=@_;
|
||||||
$params{pages}="*" unless defined $params{pages};
|
$params{pages}="*" unless defined $params{pages};
|
||||||
|
|
||||||
|
@ -61,6 +61,6 @@ sub preprocess (@) { #{{{
|
||||||
}
|
}
|
||||||
sort @broken)
|
sort @broken)
|
||||||
."</ul>\n";
|
."</ul>\n";
|
||||||
} # }}}
|
}
|
||||||
|
|
||||||
1
|
1
|
||||||
|
|
|
@ -7,7 +7,7 @@ use IkiWiki;
|
||||||
use Encode;
|
use Encode;
|
||||||
use open qw{:utf8 :std};
|
use open qw{:utf8 :std};
|
||||||
|
|
||||||
sub import { #{{{
|
sub import {
|
||||||
hook(type => "checkconfig", id => "bzr", call => \&checkconfig);
|
hook(type => "checkconfig", id => "bzr", call => \&checkconfig);
|
||||||
hook(type => "getsetup", id => "bzr", call => \&getsetup);
|
hook(type => "getsetup", id => "bzr", call => \&getsetup);
|
||||||
hook(type => "rcs", id => "rcs_update", call => \&rcs_update);
|
hook(type => "rcs", id => "rcs_update", call => \&rcs_update);
|
||||||
|
@ -20,18 +20,18 @@ sub import { #{{{
|
||||||
hook(type => "rcs", id => "rcs_recentchanges", call => \&rcs_recentchanges);
|
hook(type => "rcs", id => "rcs_recentchanges", call => \&rcs_recentchanges);
|
||||||
hook(type => "rcs", id => "rcs_diff", call => \&rcs_diff);
|
hook(type => "rcs", id => "rcs_diff", call => \&rcs_diff);
|
||||||
hook(type => "rcs", id => "rcs_getctime", call => \&rcs_getctime);
|
hook(type => "rcs", id => "rcs_getctime", call => \&rcs_getctime);
|
||||||
} #}}}
|
}
|
||||||
|
|
||||||
sub checkconfig () { #{{{
|
sub checkconfig () {
|
||||||
if (defined $config{bzr_wrapper} && length $config{bzr_wrapper}) {
|
if (defined $config{bzr_wrapper} && length $config{bzr_wrapper}) {
|
||||||
push @{$config{wrappers}}, {
|
push @{$config{wrappers}}, {
|
||||||
wrapper => $config{bzr_wrapper},
|
wrapper => $config{bzr_wrapper},
|
||||||
wrappermode => (defined $config{bzr_wrappermode} ? $config{bzr_wrappermode} : "06755"),
|
wrappermode => (defined $config{bzr_wrappermode} ? $config{bzr_wrappermode} : "06755"),
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
} #}}}
|
}
|
||||||
|
|
||||||
sub getsetup () { #{{{
|
sub getsetup () {
|
||||||
return
|
return
|
||||||
plugin => {
|
plugin => {
|
||||||
safe => 0, # rcs plugin
|
safe => 0, # rcs plugin
|
||||||
|
@ -65,9 +65,9 @@ sub getsetup () { #{{{
|
||||||
safe => 1,
|
safe => 1,
|
||||||
rebuild => 1,
|
rebuild => 1,
|
||||||
},
|
},
|
||||||
} #}}}
|
}
|
||||||
|
|
||||||
sub bzr_log ($) { #{{{
|
sub bzr_log ($) {
|
||||||
my $out = shift;
|
my $out = shift;
|
||||||
my @infos = ();
|
my @infos = ();
|
||||||
my $key = undef;
|
my $key = undef;
|
||||||
|
@ -99,20 +99,20 @@ sub bzr_log ($) { #{{{
|
||||||
close $out;
|
close $out;
|
||||||
|
|
||||||
return @infos;
|
return @infos;
|
||||||
} #}}}
|
}
|
||||||
|
|
||||||
sub rcs_update () { #{{{
|
sub rcs_update () {
|
||||||
my @cmdline = ("bzr", "update", "--quiet", $config{srcdir});
|
my @cmdline = ("bzr", "update", "--quiet", $config{srcdir});
|
||||||
if (system(@cmdline) != 0) {
|
if (system(@cmdline) != 0) {
|
||||||
warn "'@cmdline' failed: $!";
|
warn "'@cmdline' failed: $!";
|
||||||
}
|
}
|
||||||
} #}}}
|
}
|
||||||
|
|
||||||
sub rcs_prepedit ($) { #{{{
|
sub rcs_prepedit ($) {
|
||||||
return "";
|
return "";
|
||||||
} #}}}
|
}
|
||||||
|
|
||||||
sub bzr_author ($$) { #{{{
|
sub bzr_author ($$) {
|
||||||
my ($user, $ipaddr) = @_;
|
my ($user, $ipaddr) = @_;
|
||||||
|
|
||||||
if (defined $user) {
|
if (defined $user) {
|
||||||
|
@ -124,9 +124,9 @@ sub bzr_author ($$) { #{{{
|
||||||
else {
|
else {
|
||||||
return "Anonymous";
|
return "Anonymous";
|
||||||
}
|
}
|
||||||
} #}}}
|
}
|
||||||
|
|
||||||
sub rcs_commit ($$$;$$) { #{{{
|
sub rcs_commit ($$$;$$) {
|
||||||
my ($file, $message, $rcstoken, $user, $ipaddr) = @_;
|
my ($file, $message, $rcstoken, $user, $ipaddr) = @_;
|
||||||
|
|
||||||
$user = bzr_author($user, $ipaddr);
|
$user = bzr_author($user, $ipaddr);
|
||||||
|
@ -143,7 +143,7 @@ sub rcs_commit ($$$;$$) { #{{{
|
||||||
}
|
}
|
||||||
|
|
||||||
return undef; # success
|
return undef; # success
|
||||||
} #}}}
|
}
|
||||||
|
|
||||||
sub rcs_commit_staged ($$$) {
|
sub rcs_commit_staged ($$$) {
|
||||||
# Commits all staged changes. Changes can be staged using rcs_add,
|
# Commits all staged changes. Changes can be staged using rcs_add,
|
||||||
|
@ -164,27 +164,27 @@ sub rcs_commit_staged ($$$) {
|
||||||
}
|
}
|
||||||
|
|
||||||
return undef; # success
|
return undef; # success
|
||||||
} #}}}
|
}
|
||||||
|
|
||||||
sub rcs_add ($) { # {{{
|
sub rcs_add ($) {
|
||||||
my ($file) = @_;
|
my ($file) = @_;
|
||||||
|
|
||||||
my @cmdline = ("bzr", "add", "--quiet", "$config{srcdir}/$file");
|
my @cmdline = ("bzr", "add", "--quiet", "$config{srcdir}/$file");
|
||||||
if (system(@cmdline) != 0) {
|
if (system(@cmdline) != 0) {
|
||||||
warn "'@cmdline' failed: $!";
|
warn "'@cmdline' failed: $!";
|
||||||
}
|
}
|
||||||
} #}}}
|
}
|
||||||
|
|
||||||
sub rcs_remove ($) { # {{{
|
sub rcs_remove ($) {
|
||||||
my ($file) = @_;
|
my ($file) = @_;
|
||||||
|
|
||||||
my @cmdline = ("bzr", "rm", "--force", "--quiet", "$config{srcdir}/$file");
|
my @cmdline = ("bzr", "rm", "--force", "--quiet", "$config{srcdir}/$file");
|
||||||
if (system(@cmdline) != 0) {
|
if (system(@cmdline) != 0) {
|
||||||
warn "'@cmdline' failed: $!";
|
warn "'@cmdline' failed: $!";
|
||||||
}
|
}
|
||||||
} #}}}
|
}
|
||||||
|
|
||||||
sub rcs_rename ($$) { # {{{
|
sub rcs_rename ($$) {
|
||||||
my ($src, $dest) = @_;
|
my ($src, $dest) = @_;
|
||||||
|
|
||||||
my $parent = IkiWiki::dirname($dest);
|
my $parent = IkiWiki::dirname($dest);
|
||||||
|
@ -196,9 +196,9 @@ sub rcs_rename ($$) { # {{{
|
||||||
if (system(@cmdline) != 0) {
|
if (system(@cmdline) != 0) {
|
||||||
warn "'@cmdline' failed: $!";
|
warn "'@cmdline' failed: $!";
|
||||||
}
|
}
|
||||||
} #}}}
|
}
|
||||||
|
|
||||||
sub rcs_recentchanges ($) { #{{{
|
sub rcs_recentchanges ($) {
|
||||||
my ($num) = @_;
|
my ($num) = @_;
|
||||||
|
|
||||||
my @cmdline = ("bzr", "log", "-v", "--show-ids", "--limit", $num,
|
my @cmdline = ("bzr", "log", "-v", "--show-ids", "--limit", $num,
|
||||||
|
@ -246,16 +246,36 @@ sub rcs_recentchanges ($) { #{{{
|
||||||
rev => $info->{"revno"},
|
rev => $info->{"revno"},
|
||||||
user => $user,
|
user => $user,
|
||||||
committype => "bzr",
|
committype => "bzr",
|
||||||
when => time - str2time($info->{"timestamp"}),
|
when => str2time($info->{"timestamp"}),
|
||||||
message => [@message],
|
message => [@message],
|
||||||
pages => [@pages],
|
pages => [@pages],
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
return @ret;
|
return @ret;
|
||||||
} #}}}
|
}
|
||||||
|
|
||||||
sub rcs_getctime ($) { #{{{
|
sub rcs_diff ($) {
|
||||||
|
my $taintedrev=shift;
|
||||||
|
my ($rev) = $taintedrev =~ /^(\d+(\.\d+)*)$/; # untaint
|
||||||
|
|
||||||
|
my $prevspec = "before:" . $rev;
|
||||||
|
my $revspec = "revno:" . $rev;
|
||||||
|
my @cmdline = ("bzr", "diff", "--old", $config{srcdir},
|
||||||
|
"--new", $config{srcdir},
|
||||||
|
"-r", $prevspec . ".." . $revspec);
|
||||||
|
open (my $out, "@cmdline |");
|
||||||
|
|
||||||
|
my @lines = <$out>;
|
||||||
|
if (wantarray) {
|
||||||
|
return @lines;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
return join("", @lines);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
sub rcs_getctime ($) {
|
||||||
my ($file) = @_;
|
my ($file) = @_;
|
||||||
|
|
||||||
# XXX filename passes through the shell here, should try to avoid
|
# XXX filename passes through the shell here, should try to avoid
|
||||||
|
@ -274,6 +294,6 @@ sub rcs_getctime ($) { #{{{
|
||||||
|
|
||||||
my $ctime = str2time($log[0]->{"timestamp"});
|
my $ctime = str2time($log[0]->{"timestamp"});
|
||||||
return $ctime;
|
return $ctime;
|
||||||
} #}}}
|
}
|
||||||
|
|
||||||
1
|
1
|
||||||
|
|
|
@ -20,7 +20,7 @@ package IkiWiki::Plugin::calendar;
|
||||||
|
|
||||||
use warnings;
|
use warnings;
|
||||||
use strict;
|
use strict;
|
||||||
use IkiWiki 2.00;
|
use IkiWiki 3.00;
|
||||||
use Time::Local;
|
use Time::Local;
|
||||||
use POSIX;
|
use POSIX;
|
||||||
|
|
||||||
|
@ -29,13 +29,13 @@ my %linkcache;
|
||||||
my $time=time;
|
my $time=time;
|
||||||
my @now=localtime($time);
|
my @now=localtime($time);
|
||||||
|
|
||||||
sub import { #{{{
|
sub import {
|
||||||
hook(type => "getsetup", id => "calendar", call => \&getsetup);
|
hook(type => "getsetup", id => "calendar", call => \&getsetup);
|
||||||
hook(type => "needsbuild", id => "calendar", call => \&needsbuild);
|
hook(type => "needsbuild", id => "calendar", call => \&needsbuild);
|
||||||
hook(type => "preprocess", id => "calendar", call => \&preprocess);
|
hook(type => "preprocess", id => "calendar", call => \&preprocess);
|
||||||
} #}}}
|
}
|
||||||
|
|
||||||
sub getsetup () { #{{{
|
sub getsetup () {
|
||||||
return
|
return
|
||||||
plugin => {
|
plugin => {
|
||||||
safe => 1,
|
safe => 1,
|
||||||
|
@ -48,23 +48,23 @@ sub getsetup () { #{{{
|
||||||
safe => 1,
|
safe => 1,
|
||||||
rebuild => 1,
|
rebuild => 1,
|
||||||
},
|
},
|
||||||
} #}}}
|
}
|
||||||
|
|
||||||
sub is_leap_year (@) { #{{{
|
sub is_leap_year (@) {
|
||||||
my %params=@_;
|
my %params=@_;
|
||||||
return ($params{year} % 4 == 0 && (($params{year} % 100 != 0) || $params{year} % 400 == 0));
|
return ($params{year} % 4 == 0 && (($params{year} % 100 != 0) || $params{year} % 400 == 0));
|
||||||
} #}}}
|
}
|
||||||
|
|
||||||
sub month_days { #{{{
|
sub month_days {
|
||||||
my %params=@_;
|
my %params=@_;
|
||||||
my $days_in_month = (31,28,31,30,31,30,31,31,30,31,30,31)[$params{month}-1];
|
my $days_in_month = (31,28,31,30,31,30,31,31,30,31,30,31)[$params{month}-1];
|
||||||
if ($params{month} == 2 && is_leap_year(%params)) {
|
if ($params{month} == 2 && is_leap_year(%params)) {
|
||||||
$days_in_month++;
|
$days_in_month++;
|
||||||
}
|
}
|
||||||
return $days_in_month;
|
return $days_in_month;
|
||||||
} #}}}
|
}
|
||||||
|
|
||||||
sub format_month (@) { #{{{
|
sub format_month (@) {
|
||||||
my %params=@_;
|
my %params=@_;
|
||||||
|
|
||||||
my $pagespec = $params{pages};
|
my $pagespec = $params{pages};
|
||||||
|
@ -215,9 +215,9 @@ EOF
|
||||||
add_depends($params{page}, join(" or ", @list));
|
add_depends($params{page}, join(" or ", @list));
|
||||||
|
|
||||||
return $calendar;
|
return $calendar;
|
||||||
} #}}}
|
}
|
||||||
|
|
||||||
sub format_year (@) { #{{{
|
sub format_year (@) {
|
||||||
my %params=@_;
|
my %params=@_;
|
||||||
|
|
||||||
my $pagespec = $params{pages};
|
my $pagespec = $params{pages};
|
||||||
|
@ -318,9 +318,9 @@ EOF
|
||||||
EOF
|
EOF
|
||||||
|
|
||||||
return $calendar;
|
return $calendar;
|
||||||
} #}}}
|
}
|
||||||
|
|
||||||
sub preprocess (@) { #{{{
|
sub preprocess (@) {
|
||||||
my %params=@_;
|
my %params=@_;
|
||||||
$params{pages} = "*" unless defined $params{pages};
|
$params{pages} = "*" unless defined $params{pages};
|
||||||
$params{type} = "month" unless defined $params{type};
|
$params{type} = "month" unless defined $params{type};
|
||||||
|
@ -397,7 +397,7 @@ sub preprocess (@) { #{{{
|
||||||
return "\n<div><div class=\"calendar\">$calendar</div></div>\n";
|
return "\n<div><div class=\"calendar\">$calendar</div></div>\n";
|
||||||
} #}}
|
} #}}
|
||||||
|
|
||||||
sub needsbuild (@) { #{{{
|
sub needsbuild (@) {
|
||||||
my $needsbuild=shift;
|
my $needsbuild=shift;
|
||||||
foreach my $page (keys %pagestate) {
|
foreach my $page (keys %pagestate) {
|
||||||
if (exists $pagestate{$page}{calendar}{nextchange}) {
|
if (exists $pagestate{$page}{calendar}{nextchange}) {
|
||||||
|
@ -415,6 +415,6 @@ sub needsbuild (@) { #{{{
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} # }}}
|
}
|
||||||
|
|
||||||
1
|
1
|
||||||
|
|
|
@ -4,7 +4,7 @@ package IkiWiki::Plugin::camelcase;
|
||||||
|
|
||||||
use warnings;
|
use warnings;
|
||||||
use strict;
|
use strict;
|
||||||
use IkiWiki 2.00;
|
use IkiWiki 3.00;
|
||||||
|
|
||||||
# This regexp is based on the one in Text::WikiFormat.
|
# This regexp is based on the one in Text::WikiFormat.
|
||||||
my $link_regexp=qr{
|
my $link_regexp=qr{
|
||||||
|
@ -22,40 +22,52 @@ my $link_regexp=qr{
|
||||||
)
|
)
|
||||||
}x;
|
}x;
|
||||||
|
|
||||||
sub import { #{{{
|
sub import {
|
||||||
hook(type => "getsetup", id => "camelcase", call => \&getsetup);
|
hook(type => "getsetup", id => "camelcase", call => \&getsetup);
|
||||||
hook(type => "linkify", id => "camelcase", call => \&linkify);
|
hook(type => "linkify", id => "camelcase", call => \&linkify);
|
||||||
hook(type => "scan", id => "camelcase", call => \&scan);
|
hook(type => "scan", id => "camelcase", call => \&scan);
|
||||||
} # }}}
|
}
|
||||||
|
|
||||||
sub getsetup () { #{{{
|
sub getsetup () {
|
||||||
return
|
return
|
||||||
plugin => {
|
plugin => {
|
||||||
safe => 1,
|
safe => 1,
|
||||||
rebuild => undef,
|
rebuild => undef,
|
||||||
};
|
},
|
||||||
} #}}}
|
camelcase_ignore => {
|
||||||
|
type => "string",
|
||||||
|
example => [],
|
||||||
|
description => "list of words to not turn into links",
|
||||||
|
safe => 1,
|
||||||
|
rebuild => undef, # might change links
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
sub linkify (@) { #{{{
|
sub linkify (@) {
|
||||||
my %params=@_;
|
my %params=@_;
|
||||||
my $page=$params{page};
|
my $page=$params{page};
|
||||||
my $destpage=$params{destpage};
|
my $destpage=$params{destpage};
|
||||||
|
|
||||||
$params{content}=~s{$link_regexp}{
|
$params{content}=~s{$link_regexp}{
|
||||||
htmllink($page, $destpage, linkpage($1))
|
ignored($1) ? $1 : htmllink($page, $destpage, linkpage($1))
|
||||||
}eg;
|
}eg;
|
||||||
|
|
||||||
return $params{content};
|
return $params{content};
|
||||||
} #}}}
|
}
|
||||||
|
|
||||||
sub scan (@) { #{{{
|
sub scan (@) {
|
||||||
my %params=@_;
|
my %params=@_;
|
||||||
my $page=$params{page};
|
my $page=$params{page};
|
||||||
my $content=$params{content};
|
my $content=$params{content};
|
||||||
|
|
||||||
while ($content =~ /$link_regexp/g) {
|
while ($content =~ /$link_regexp/g) {
|
||||||
push @{$links{$page}}, linkpage($1);
|
push @{$links{$page}}, linkpage($1) unless ignored($1)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
sub ignored ($) {
|
||||||
|
my $word=lc shift;
|
||||||
|
grep { $word eq lc $_ } @{$config{'camelcase_ignore'}}
|
||||||
|
}
|
||||||
|
|
||||||
1
|
1
|
||||||
|
|
|
@ -5,14 +5,14 @@ package IkiWiki::Plugin::color;
|
||||||
|
|
||||||
use warnings;
|
use warnings;
|
||||||
use strict;
|
use strict;
|
||||||
use IkiWiki 2.00;
|
use IkiWiki 3.00;
|
||||||
|
|
||||||
sub import { #{{{
|
sub import {
|
||||||
hook(type => "preprocess", id => "color", call => \&preprocess);
|
hook(type => "preprocess", id => "color", call => \&preprocess);
|
||||||
hook(type => "format", id => "color", call => \&format);
|
hook(type => "format", id => "color", call => \&format);
|
||||||
} #}}}
|
}
|
||||||
|
|
||||||
sub preserve_style ($$$) { #{{{
|
sub preserve_style ($$$) {
|
||||||
my $foreground = shift;
|
my $foreground = shift;
|
||||||
my $background = shift;
|
my $background = shift;
|
||||||
my $text = shift;
|
my $text = shift;
|
||||||
|
@ -37,18 +37,18 @@ sub preserve_style ($$$) { #{{{
|
||||||
|
|
||||||
return $preserved;
|
return $preserved;
|
||||||
|
|
||||||
} #}}}
|
}
|
||||||
|
|
||||||
sub replace_preserved_style ($) { #{{{
|
sub replace_preserved_style ($) {
|
||||||
my $content = shift;
|
my $content = shift;
|
||||||
|
|
||||||
$content =~ s!<span class="color">((color: ([a-z]+|\#[0-9a-f]{3,6})?)?((; )?(background-color: ([a-z]+|\#[0-9a-f]{3,6})?)?)?)</span>!<span class="color" style="$1">!g;
|
$content =~ s!<span class="color">((color: ([a-z]+|\#[0-9a-f]{3,6})?)?((; )?(background-color: ([a-z]+|\#[0-9a-f]{3,6})?)?)?)</span>!<span class="color" style="$1">!g;
|
||||||
$content =~ s!<span class="colorend">!!g;
|
$content =~ s!<span class="colorend">!!g;
|
||||||
|
|
||||||
return $content;
|
return $content;
|
||||||
} #}}}
|
}
|
||||||
|
|
||||||
sub preprocess (@) { #{{{
|
sub preprocess (@) {
|
||||||
my %params = @_;
|
my %params = @_;
|
||||||
|
|
||||||
# Preprocess the text to expand any preprocessor directives
|
# Preprocess the text to expand any preprocessor directives
|
||||||
|
@ -57,13 +57,13 @@ sub preprocess (@) { #{{{
|
||||||
IkiWiki::filter($params{page}, $params{destpage}, $params{text}));
|
IkiWiki::filter($params{page}, $params{destpage}, $params{text}));
|
||||||
|
|
||||||
return preserve_style($params{foreground}, $params{background}, $params{text});
|
return preserve_style($params{foreground}, $params{background}, $params{text});
|
||||||
} #}}}
|
}
|
||||||
|
|
||||||
sub format (@) { #{{{
|
sub format (@) {
|
||||||
my %params = @_;
|
my %params = @_;
|
||||||
|
|
||||||
$params{content} = replace_preserved_style($params{content});
|
$params{content} = replace_preserved_style($params{content});
|
||||||
return $params{content};
|
return $params{content};
|
||||||
} #}}}
|
}
|
||||||
|
|
||||||
1
|
1
|
||||||
|
|
|
@ -0,0 +1,840 @@
|
||||||
|
#!/usr/bin/perl
|
||||||
|
# Copyright © 2006-2008 Joey Hess <joey@ikiwiki.info>
|
||||||
|
# Copyright © 2008 Simon McVittie <http://smcv.pseudorandom.co.uk/>
|
||||||
|
# Licensed under the GNU GPL, version 2, or any later version published by the
|
||||||
|
# Free Software Foundation
|
||||||
|
package IkiWiki::Plugin::comments;
|
||||||
|
|
||||||
|
use warnings;
|
||||||
|
use strict;
|
||||||
|
use IkiWiki 3.00;
|
||||||
|
use Encode;
|
||||||
|
use POSIX qw(strftime);
|
||||||
|
|
||||||
|
use constant PREVIEW => "Preview";
|
||||||
|
use constant POST_COMMENT => "Post comment";
|
||||||
|
use constant CANCEL => "Cancel";
|
||||||
|
|
||||||
|
my $postcomment;
|
||||||
|
my %commentstate;
|
||||||
|
|
||||||
|
sub import {
|
||||||
|
hook(type => "checkconfig", id => 'comments', call => \&checkconfig);
|
||||||
|
hook(type => "getsetup", id => 'comments', call => \&getsetup);
|
||||||
|
hook(type => "preprocess", id => '_comment', call => \&preprocess);
|
||||||
|
hook(type => "sessioncgi", id => 'comment', call => \&sessioncgi);
|
||||||
|
hook(type => "htmlize", id => "_comment", call => \&htmlize);
|
||||||
|
hook(type => "pagetemplate", id => "comments", call => \&pagetemplate);
|
||||||
|
hook(type => "formbuilder_setup", id => "comments", call => \&formbuilder_setup);
|
||||||
|
# Load goto to fix up user page links for logged-in commenters
|
||||||
|
IkiWiki::loadplugin("goto");
|
||||||
|
IkiWiki::loadplugin("inline");
|
||||||
|
}
|
||||||
|
|
||||||
|
sub getsetup () {
|
||||||
|
return
|
||||||
|
plugin => {
|
||||||
|
safe => 1,
|
||||||
|
rebuild => 1,
|
||||||
|
},
|
||||||
|
comments_pagespec => {
|
||||||
|
type => 'pagespec',
|
||||||
|
example => 'blog/* and !*/Discussion',
|
||||||
|
description => 'PageSpec of pages where comments are allowed',
|
||||||
|
link => 'ikiwiki/PageSpec',
|
||||||
|
safe => 1,
|
||||||
|
rebuild => 1,
|
||||||
|
},
|
||||||
|
comments_closed_pagespec => {
|
||||||
|
type => 'pagespec',
|
||||||
|
example => 'blog/controversial or blog/flamewar',
|
||||||
|
description => 'PageSpec of pages where posting new comments is not allowed',
|
||||||
|
link => 'ikiwiki/PageSpec',
|
||||||
|
safe => 1,
|
||||||
|
rebuild => 1,
|
||||||
|
},
|
||||||
|
comments_pagename => {
|
||||||
|
type => 'string',
|
||||||
|
default => 'comment_',
|
||||||
|
description => 'Base name for comments, e.g. "comment_" for pages like "sandbox/comment_12"',
|
||||||
|
safe => 0, # manual page moving required
|
||||||
|
rebuild => undef,
|
||||||
|
},
|
||||||
|
comments_allowdirectives => {
|
||||||
|
type => 'boolean',
|
||||||
|
example => 0,
|
||||||
|
description => 'Interpret directives in comments?',
|
||||||
|
safe => 1,
|
||||||
|
rebuild => 0,
|
||||||
|
},
|
||||||
|
comments_allowauthor => {
|
||||||
|
type => 'boolean',
|
||||||
|
example => 0,
|
||||||
|
description => 'Allow anonymous commenters to set an author name?',
|
||||||
|
safe => 1,
|
||||||
|
rebuild => 0,
|
||||||
|
},
|
||||||
|
comments_commit => {
|
||||||
|
type => 'boolean',
|
||||||
|
example => 1,
|
||||||
|
description => 'commit comments to the VCS',
|
||||||
|
# old uncommitted comments are likely to cause
|
||||||
|
# confusion if this is changed
|
||||||
|
safe => 0,
|
||||||
|
rebuild => 0,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
sub checkconfig () {
|
||||||
|
$config{comments_commit} = 1
|
||||||
|
unless defined $config{comments_commit};
|
||||||
|
$config{comments_pagespec} = ''
|
||||||
|
unless defined $config{comments_pagespec};
|
||||||
|
$config{comments_closed_pagespec} = ''
|
||||||
|
unless defined $config{comments_closed_pagespec};
|
||||||
|
$config{comments_pagename} = 'comment_'
|
||||||
|
unless defined $config{comments_pagename};
|
||||||
|
}
|
||||||
|
|
||||||
|
sub htmlize {
|
||||||
|
my %params = @_;
|
||||||
|
return $params{content};
|
||||||
|
}
|
||||||
|
|
||||||
|
# FIXME: copied verbatim from meta
|
||||||
|
sub safeurl ($) {
|
||||||
|
my $url=shift;
|
||||||
|
if (exists $IkiWiki::Plugin::htmlscrubber::{safe_url_regexp} &&
|
||||||
|
defined $IkiWiki::Plugin::htmlscrubber::safe_url_regexp) {
|
||||||
|
return $url=~/$IkiWiki::Plugin::htmlscrubber::safe_url_regexp/;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
sub preprocess {
|
||||||
|
my %params = @_;
|
||||||
|
my $page = $params{page};
|
||||||
|
|
||||||
|
my $format = $params{format};
|
||||||
|
if (defined $format && ! exists $IkiWiki::hooks{htmlize}{$format}) {
|
||||||
|
error(sprintf(gettext("unsupported page format %s"), $format));
|
||||||
|
}
|
||||||
|
|
||||||
|
my $content = $params{content};
|
||||||
|
if (! defined $content) {
|
||||||
|
error(gettext("comment must have content"));
|
||||||
|
}
|
||||||
|
$content =~ s/\\"/"/g;
|
||||||
|
|
||||||
|
$content = IkiWiki::filter($page, $params{destpage}, $content);
|
||||||
|
|
||||||
|
if ($config{comments_allowdirectives}) {
|
||||||
|
$content = IkiWiki::preprocess($page, $params{destpage},
|
||||||
|
$content);
|
||||||
|
}
|
||||||
|
|
||||||
|
# no need to bother with htmlize if it's just HTML
|
||||||
|
$content = IkiWiki::htmlize($page, $params{destpage}, $format, $content)
|
||||||
|
if defined $format;
|
||||||
|
|
||||||
|
IkiWiki::run_hooks(sanitize => sub {
|
||||||
|
$content = shift->(
|
||||||
|
page => $page,
|
||||||
|
destpage => $params{destpage},
|
||||||
|
content => $content,
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
|
# set metadata, possibly overriding [[!meta]] directives from the
|
||||||
|
# comment itself
|
||||||
|
|
||||||
|
my $commentuser;
|
||||||
|
my $commentip;
|
||||||
|
my $commentauthor;
|
||||||
|
my $commentauthorurl;
|
||||||
|
my $commentopenid;
|
||||||
|
if (defined $params{username}) {
|
||||||
|
$commentuser = $params{username};
|
||||||
|
|
||||||
|
my $oiduser = eval { IkiWiki::openiduser($commentuser) };
|
||||||
|
|
||||||
|
if (defined $oiduser) {
|
||||||
|
# looks like an OpenID
|
||||||
|
$commentauthorurl = $commentuser;
|
||||||
|
$commentauthor = $oiduser;
|
||||||
|
$commentopenid = $commentuser;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
$commentauthorurl = IkiWiki::cgiurl(
|
||||||
|
do => 'goto',
|
||||||
|
page => (length $config{userdir}
|
||||||
|
? "$config{userdir}/$commentuser"
|
||||||
|
: "$commentuser"));
|
||||||
|
|
||||||
|
$commentauthor = $commentuser;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
if (defined $params{ip}) {
|
||||||
|
$commentip = $params{ip};
|
||||||
|
}
|
||||||
|
$commentauthor = gettext("Anonymous");
|
||||||
|
}
|
||||||
|
|
||||||
|
$commentstate{$page}{commentuser} = $commentuser;
|
||||||
|
$commentstate{$page}{commentopenid} = $commentopenid;
|
||||||
|
$commentstate{$page}{commentip} = $commentip;
|
||||||
|
$commentstate{$page}{commentauthor} = $commentauthor;
|
||||||
|
$commentstate{$page}{commentauthorurl} = $commentauthorurl;
|
||||||
|
if (! defined $pagestate{$page}{meta}{author}) {
|
||||||
|
$pagestate{$page}{meta}{author} = $commentauthor;
|
||||||
|
}
|
||||||
|
if (! defined $pagestate{$page}{meta}{authorurl}) {
|
||||||
|
$pagestate{$page}{meta}{authorurl} = $commentauthorurl;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($config{comments_allowauthor}) {
|
||||||
|
if (defined $params{claimedauthor}) {
|
||||||
|
$pagestate{$page}{meta}{author} = $params{claimedauthor};
|
||||||
|
}
|
||||||
|
|
||||||
|
if (defined $params{url}) {
|
||||||
|
my $url=$params{url};
|
||||||
|
|
||||||
|
eval q{use URI::Heuristic};
|
||||||
|
if (! $@) {
|
||||||
|
$url=URI::Heuristic::uf_uristr($url);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (safeurl($url)) {
|
||||||
|
$pagestate{$page}{meta}{authorurl} = $url;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
$pagestate{$page}{meta}{author} = $commentauthor;
|
||||||
|
$pagestate{$page}{meta}{authorurl} = $commentauthorurl;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (defined $params{subject}) {
|
||||||
|
$pagestate{$page}{meta}{title} = $params{subject};
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($params{page} =~ m/\/(\Q$config{comments_pagename}\E\d+)$/) {
|
||||||
|
$pagestate{$page}{meta}{permalink} = urlto(IkiWiki::dirname($params{page}), undef, 1).
|
||||||
|
"#".page_to_id($params{page});
|
||||||
|
}
|
||||||
|
|
||||||
|
eval q{use Date::Parse};
|
||||||
|
if (! $@) {
|
||||||
|
my $time = str2time($params{date});
|
||||||
|
$IkiWiki::pagectime{$page} = $time if defined $time;
|
||||||
|
}
|
||||||
|
|
||||||
|
return $content;
|
||||||
|
}
|
||||||
|
|
||||||
|
sub sessioncgi ($$) {
|
||||||
|
my $cgi=shift;
|
||||||
|
my $session=shift;
|
||||||
|
|
||||||
|
my $do = $cgi->param('do');
|
||||||
|
if ($do eq 'comment') {
|
||||||
|
editcomment($cgi, $session);
|
||||||
|
}
|
||||||
|
elsif ($do eq 'commentmoderation') {
|
||||||
|
commentmoderation($cgi, $session);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
# Mostly cargo-culted from IkiWiki::plugin::editpage
|
||||||
|
sub editcomment ($$) {
|
||||||
|
my $cgi=shift;
|
||||||
|
my $session=shift;
|
||||||
|
|
||||||
|
IkiWiki::decode_cgi_utf8($cgi);
|
||||||
|
|
||||||
|
eval q{use CGI::FormBuilder};
|
||||||
|
error($@) if $@;
|
||||||
|
|
||||||
|
my @buttons = (POST_COMMENT, PREVIEW, CANCEL);
|
||||||
|
my $form = CGI::FormBuilder->new(
|
||||||
|
fields => [qw{do sid page subject editcontent type author url}],
|
||||||
|
charset => 'utf-8',
|
||||||
|
method => 'POST',
|
||||||
|
required => [qw{editcontent}],
|
||||||
|
javascript => 0,
|
||||||
|
params => $cgi,
|
||||||
|
action => $config{cgiurl},
|
||||||
|
header => 0,
|
||||||
|
table => 0,
|
||||||
|
template => scalar IkiWiki::template_params('editcomment.tmpl'),
|
||||||
|
);
|
||||||
|
|
||||||
|
IkiWiki::decode_form_utf8($form);
|
||||||
|
IkiWiki::run_hooks(formbuilder_setup => sub {
|
||||||
|
shift->(title => "comment", form => $form, cgi => $cgi,
|
||||||
|
session => $session, buttons => \@buttons);
|
||||||
|
});
|
||||||
|
IkiWiki::decode_form_utf8($form);
|
||||||
|
|
||||||
|
my $type = $form->param('type');
|
||||||
|
if (defined $type && length $type && $IkiWiki::hooks{htmlize}{$type}) {
|
||||||
|
$type = IkiWiki::possibly_foolish_untaint($type);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
$type = $config{default_pageext};
|
||||||
|
}
|
||||||
|
my @page_types;
|
||||||
|
if (exists $IkiWiki::hooks{htmlize}) {
|
||||||
|
@page_types = grep { ! /^_/ } keys %{$IkiWiki::hooks{htmlize}};
|
||||||
|
}
|
||||||
|
|
||||||
|
$form->field(name => 'do', type => 'hidden');
|
||||||
|
$form->field(name => 'sid', type => 'hidden', value => $session->id,
|
||||||
|
force => 1);
|
||||||
|
$form->field(name => 'page', type => 'hidden');
|
||||||
|
$form->field(name => 'subject', type => 'text', size => 72);
|
||||||
|
$form->field(name => 'editcontent', type => 'textarea', rows => 10);
|
||||||
|
$form->field(name => "type", value => $type, force => 1,
|
||||||
|
type => 'select', options => \@page_types);
|
||||||
|
|
||||||
|
$form->tmpl_param(username => $session->param('name'));
|
||||||
|
|
||||||
|
if ($config{comments_allowauthor} and
|
||||||
|
! defined $session->param('name')) {
|
||||||
|
$form->tmpl_param(allowauthor => 1);
|
||||||
|
$form->field(name => 'author', type => 'text', size => '40');
|
||||||
|
$form->field(name => 'url', type => 'text', size => '40');
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
$form->tmpl_param(allowauthor => 0);
|
||||||
|
$form->field(name => 'author', type => 'hidden', value => '',
|
||||||
|
force => 1);
|
||||||
|
$form->field(name => 'url', type => 'hidden', value => '',
|
||||||
|
force => 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
# The untaint is OK (as in editpage) because we're about to pass
|
||||||
|
# it to file_pruned anyway
|
||||||
|
my $page = $form->field('page');
|
||||||
|
$page = IkiWiki::possibly_foolish_untaint($page);
|
||||||
|
if (! defined $page || ! length $page ||
|
||||||
|
IkiWiki::file_pruned($page, $config{srcdir})) {
|
||||||
|
error(gettext("bad page name"));
|
||||||
|
}
|
||||||
|
|
||||||
|
my $baseurl = urlto($page, undef, 1);
|
||||||
|
|
||||||
|
$form->title(sprintf(gettext("commenting on %s"),
|
||||||
|
IkiWiki::pagetitle($page)));
|
||||||
|
|
||||||
|
$form->tmpl_param('helponformattinglink',
|
||||||
|
htmllink($page, $page, 'ikiwiki/formatting',
|
||||||
|
noimageinline => 1,
|
||||||
|
linktext => 'FormattingHelp'),
|
||||||
|
allowdirectives => $config{allow_directives});
|
||||||
|
|
||||||
|
if ($form->submitted eq CANCEL) {
|
||||||
|
# bounce back to the page they wanted to comment on, and exit.
|
||||||
|
# CANCEL need not be considered in future
|
||||||
|
IkiWiki::redirect($cgi, urlto($page, undef, 1));
|
||||||
|
exit;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (not exists $pagesources{$page}) {
|
||||||
|
error(sprintf(gettext(
|
||||||
|
"page '%s' doesn't exist, so you can't comment"),
|
||||||
|
$page));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (pagespec_match($page, $config{comments_closed_pagespec},
|
||||||
|
location => $page)) {
|
||||||
|
error(sprintf(gettext(
|
||||||
|
"comments on page '%s' are closed"),
|
||||||
|
$page));
|
||||||
|
}
|
||||||
|
|
||||||
|
# Set a flag to indicate that we're posting a comment,
|
||||||
|
# so that postcomment() can tell it should match.
|
||||||
|
$postcomment=1;
|
||||||
|
IkiWiki::check_canedit($page, $cgi, $session);
|
||||||
|
$postcomment=0;
|
||||||
|
|
||||||
|
my $location=unique_comment_location($page, $config{srcdir});
|
||||||
|
|
||||||
|
my $content = "[[!_comment format=$type\n";
|
||||||
|
|
||||||
|
# FIXME: handling of double quotes probably wrong?
|
||||||
|
if (defined $session->param('name')) {
|
||||||
|
my $username = $session->param('name');
|
||||||
|
$username =~ s/"/"/g;
|
||||||
|
$content .= " username=\"$username\"\n";
|
||||||
|
}
|
||||||
|
elsif (defined $ENV{REMOTE_ADDR}) {
|
||||||
|
my $ip = $ENV{REMOTE_ADDR};
|
||||||
|
if ($ip =~ m/^([.0-9]+)$/) {
|
||||||
|
$content .= " ip=\"$1\"\n";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($config{comments_allowauthor}) {
|
||||||
|
my $author = $form->field('author');
|
||||||
|
if (defined $author && length $author) {
|
||||||
|
$author =~ s/"/"/g;
|
||||||
|
$content .= " claimedauthor=\"$author\"\n";
|
||||||
|
}
|
||||||
|
my $url = $form->field('url');
|
||||||
|
if (defined $url && length $url) {
|
||||||
|
$url =~ s/"/"/g;
|
||||||
|
$content .= " url=\"$url\"\n";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
my $subject = $form->field('subject');
|
||||||
|
if (defined $subject && length $subject) {
|
||||||
|
$subject =~ s/"/"/g;
|
||||||
|
$content .= " subject=\"$subject\"\n";
|
||||||
|
}
|
||||||
|
|
||||||
|
$content .= " date=\"" . decode_utf8(strftime('%Y-%m-%dT%H:%M:%SZ', gmtime)) . "\"\n";
|
||||||
|
|
||||||
|
my $editcontent = $form->field('editcontent') || '';
|
||||||
|
$editcontent =~ s/\r\n/\n/g;
|
||||||
|
$editcontent =~ s/\r/\n/g;
|
||||||
|
$editcontent =~ s/"/\\"/g;
|
||||||
|
$content .= " content=\"\"\"\n$editcontent\n\"\"\"]]\n";
|
||||||
|
|
||||||
|
# This is essentially a simplified version of editpage:
|
||||||
|
# - the user does not control the page that's created, only the parent
|
||||||
|
# - it's always a create operation, never an edit
|
||||||
|
# - this means that conflicts should never happen
|
||||||
|
# - this means that if they do, rocks fall and everyone dies
|
||||||
|
|
||||||
|
if ($form->submitted eq PREVIEW) {
|
||||||
|
my $preview=previewcomment($content, $location, $page, time);
|
||||||
|
IkiWiki::run_hooks(format => sub {
|
||||||
|
$preview = shift->(page => $page,
|
||||||
|
content => $preview);
|
||||||
|
});
|
||||||
|
$form->tmpl_param(page_preview => $preview);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
$form->tmpl_param(page_preview => "");
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($form->submitted eq POST_COMMENT && $form->validate) {
|
||||||
|
IkiWiki::checksessionexpiry($cgi, $session);
|
||||||
|
|
||||||
|
$postcomment=1;
|
||||||
|
my $ok=IkiWiki::check_content(content => $form->field('editcontent'),
|
||||||
|
subject => $form->field('subject'),
|
||||||
|
$config{comments_allowauthor} ? (
|
||||||
|
author => $form->field('author'),
|
||||||
|
url => $form->field('url'),
|
||||||
|
) : (),
|
||||||
|
page => $location,
|
||||||
|
cgi => $cgi,
|
||||||
|
session => $session,
|
||||||
|
nonfatal => 1,
|
||||||
|
);
|
||||||
|
$postcomment=0;
|
||||||
|
|
||||||
|
if (! $ok) {
|
||||||
|
my $penddir=$config{wikistatedir}."/comments_pending";
|
||||||
|
$location=unique_comment_location($page, $penddir);
|
||||||
|
writefile("$location._comment", $penddir, $content);
|
||||||
|
IkiWiki::printheader($session);
|
||||||
|
print IkiWiki::misctemplate(gettext(gettext("comment stored for moderation")),
|
||||||
|
"<p>".
|
||||||
|
gettext("Your comment will be posted after moderator review").
|
||||||
|
"</p>");
|
||||||
|
exit;
|
||||||
|
}
|
||||||
|
|
||||||
|
# FIXME: could probably do some sort of graceful retry
|
||||||
|
# on error? Would require significant unwinding though
|
||||||
|
my $file = "$location._comment";
|
||||||
|
writefile($file, $config{srcdir}, $content);
|
||||||
|
|
||||||
|
my $conflict;
|
||||||
|
|
||||||
|
if ($config{rcs} and $config{comments_commit}) {
|
||||||
|
my $message = gettext("Added a comment");
|
||||||
|
if (defined $form->field('subject') &&
|
||||||
|
length $form->field('subject')) {
|
||||||
|
$message = sprintf(
|
||||||
|
gettext("Added a comment: %s"),
|
||||||
|
$form->field('subject'));
|
||||||
|
}
|
||||||
|
|
||||||
|
IkiWiki::rcs_add($file);
|
||||||
|
IkiWiki::disable_commit_hook();
|
||||||
|
$conflict = IkiWiki::rcs_commit_staged($message,
|
||||||
|
$session->param('name'), $ENV{REMOTE_ADDR});
|
||||||
|
IkiWiki::enable_commit_hook();
|
||||||
|
IkiWiki::rcs_update();
|
||||||
|
}
|
||||||
|
|
||||||
|
# Now we need a refresh
|
||||||
|
require IkiWiki::Render;
|
||||||
|
IkiWiki::refresh();
|
||||||
|
IkiWiki::saveindex();
|
||||||
|
|
||||||
|
# this should never happen, unless a committer deliberately
|
||||||
|
# breaks it or something
|
||||||
|
error($conflict) if defined $conflict;
|
||||||
|
|
||||||
|
# Jump to the new comment on the page.
|
||||||
|
# The trailing question mark tries to avoid broken
|
||||||
|
# caches and get the most recent version of the page.
|
||||||
|
IkiWiki::redirect($cgi, urlto($page, undef, 1).
|
||||||
|
"?updated#".page_to_id($location));
|
||||||
|
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
IkiWiki::showform ($form, \@buttons, $session, $cgi,
|
||||||
|
forcebaseurl => $baseurl);
|
||||||
|
}
|
||||||
|
|
||||||
|
exit;
|
||||||
|
}
|
||||||
|
|
||||||
|
sub commentmoderation ($$) {
|
||||||
|
my $cgi=shift;
|
||||||
|
my $session=shift;
|
||||||
|
|
||||||
|
IkiWiki::needsignin($cgi, $session);
|
||||||
|
if (! IkiWiki::is_admin($session->param("name"))) {
|
||||||
|
error(gettext("you are not logged in as an admin"));
|
||||||
|
}
|
||||||
|
|
||||||
|
IkiWiki::decode_cgi_utf8($cgi);
|
||||||
|
|
||||||
|
if (defined $cgi->param('sid')) {
|
||||||
|
IkiWiki::checksessionexpiry($cgi, $session);
|
||||||
|
|
||||||
|
my $rejectalldefer=$cgi->param('rejectalldefer');
|
||||||
|
|
||||||
|
my %vars=$cgi->Vars;
|
||||||
|
my $added=0;
|
||||||
|
foreach my $id (keys %vars) {
|
||||||
|
if ($id =~ /(.*)\Q._comment\E$/) {
|
||||||
|
my $action=$cgi->param($id);
|
||||||
|
next if $action eq 'Defer' && ! $rejectalldefer;
|
||||||
|
|
||||||
|
# Make sure that the id is of a legal
|
||||||
|
# pending comment before untainting.
|
||||||
|
my ($f)= $id =~ /$config{wiki_file_regexp}/;
|
||||||
|
if (! defined $f || ! length $f ||
|
||||||
|
IkiWiki::file_pruned($f, $config{srcdir})) {
|
||||||
|
error("illegal file");
|
||||||
|
}
|
||||||
|
|
||||||
|
my $page=IkiWiki::possibly_foolish_untaint(IkiWiki::dirname($1));
|
||||||
|
my $file="$config{wikistatedir}/comments_pending/".
|
||||||
|
IkiWiki::possibly_foolish_untaint($id);
|
||||||
|
|
||||||
|
if ($action eq 'Accept') {
|
||||||
|
my $content=eval { readfile($file) };
|
||||||
|
next if $@; # file vanished since form was displayed
|
||||||
|
my $dest=unique_comment_location($page, $config{srcdir})."._comment";
|
||||||
|
writefile($dest, $config{srcdir}, $content);
|
||||||
|
if ($config{rcs} and $config{comments_commit}) {
|
||||||
|
IkiWiki::rcs_add($dest);
|
||||||
|
}
|
||||||
|
$added++;
|
||||||
|
}
|
||||||
|
|
||||||
|
# This removes empty subdirs, so the
|
||||||
|
# .ikiwiki/comments_pending dir will
|
||||||
|
# go away when all are moderated.
|
||||||
|
require IkiWiki::Render;
|
||||||
|
IkiWiki::prune($file);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($added) {
|
||||||
|
my $conflict;
|
||||||
|
if ($config{rcs} and $config{comments_commit}) {
|
||||||
|
my $message = gettext("Comment moderation");
|
||||||
|
IkiWiki::disable_commit_hook();
|
||||||
|
$conflict=IkiWiki::rcs_commit_staged($message,
|
||||||
|
$session->param('name'), $ENV{REMOTE_ADDR});
|
||||||
|
IkiWiki::enable_commit_hook();
|
||||||
|
IkiWiki::rcs_update();
|
||||||
|
}
|
||||||
|
|
||||||
|
# Now we need a refresh
|
||||||
|
require IkiWiki::Render;
|
||||||
|
IkiWiki::refresh();
|
||||||
|
IkiWiki::saveindex();
|
||||||
|
|
||||||
|
error($conflict) if defined $conflict;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
my @comments=map {
|
||||||
|
my ($id, $ctime)=@{$_};
|
||||||
|
my $file="$config{wikistatedir}/comments_pending/$id";
|
||||||
|
my $content=readfile($file);
|
||||||
|
my $preview=previewcomment($content, $id,
|
||||||
|
IkiWiki::dirname($_), $ctime);
|
||||||
|
{
|
||||||
|
id => $id,
|
||||||
|
view => $preview,
|
||||||
|
}
|
||||||
|
} sort { $b->[1] <=> $a->[1] } comments_pending();
|
||||||
|
|
||||||
|
my $template=template("commentmoderation.tmpl");
|
||||||
|
$template->param(
|
||||||
|
sid => $session->id,
|
||||||
|
comments => \@comments,
|
||||||
|
);
|
||||||
|
IkiWiki::printheader($session);
|
||||||
|
my $out=$template->output;
|
||||||
|
IkiWiki::run_hooks(format => sub {
|
||||||
|
$out = shift->(page => "", content => $out);
|
||||||
|
});
|
||||||
|
print IkiWiki::misctemplate(gettext("comment moderation"), $out);
|
||||||
|
exit;
|
||||||
|
}
|
||||||
|
|
||||||
|
sub formbuilder_setup (@) {
|
||||||
|
my %params=@_;
|
||||||
|
|
||||||
|
my $form=$params{form};
|
||||||
|
if ($form->title eq "preferences" &&
|
||||||
|
IkiWiki::is_admin($params{session}->param("name"))) {
|
||||||
|
push @{$params{buttons}}, "Comment Moderation";
|
||||||
|
if ($form->submitted && $form->submitted eq "Comment Moderation") {
|
||||||
|
commentmoderation($params{cgi}, $params{session});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
sub comments_pending () {
|
||||||
|
my $dir="$config{wikistatedir}/comments_pending/";
|
||||||
|
return unless -d $dir;
|
||||||
|
|
||||||
|
my @ret;
|
||||||
|
eval q{use File::Find};
|
||||||
|
error($@) if $@;
|
||||||
|
find({
|
||||||
|
no_chdir => 1,
|
||||||
|
wanted => sub {
|
||||||
|
$_=decode_utf8($_);
|
||||||
|
if (IkiWiki::file_pruned($_, $dir)) {
|
||||||
|
$File::Find::prune=1;
|
||||||
|
}
|
||||||
|
elsif (! -l $_ && ! -d _) {
|
||||||
|
$File::Find::prune=0;
|
||||||
|
my ($f)=/$config{wiki_file_regexp}/; # untaint
|
||||||
|
if (defined $f && $f =~ /\Q._comment\E$/) {
|
||||||
|
my $ctime=(stat($f))[10];
|
||||||
|
$f=~s/^\Q$dir\E\/?//;
|
||||||
|
push @ret, [$f, $ctime];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}, $dir);
|
||||||
|
|
||||||
|
return @ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
sub previewcomment ($$$) {
|
||||||
|
my $content=shift;
|
||||||
|
my $location=shift;
|
||||||
|
my $page=shift;
|
||||||
|
my $time=shift;
|
||||||
|
|
||||||
|
my $preview = IkiWiki::htmlize($location, $page, '_comment',
|
||||||
|
IkiWiki::linkify($location, $page,
|
||||||
|
IkiWiki::preprocess($location, $page,
|
||||||
|
IkiWiki::filter($location, $page, $content), 0, 1)));
|
||||||
|
|
||||||
|
my $template = template("comment.tmpl");
|
||||||
|
$template->param(content => $preview);
|
||||||
|
$template->param(ctime => displaytime($time));
|
||||||
|
|
||||||
|
IkiWiki::run_hooks(pagetemplate => sub {
|
||||||
|
shift->(page => $location,
|
||||||
|
destpage => $page,
|
||||||
|
template => $template);
|
||||||
|
});
|
||||||
|
|
||||||
|
$template->param(have_actions => 0);
|
||||||
|
|
||||||
|
return $template->output;
|
||||||
|
}
|
||||||
|
|
||||||
|
sub commentsshown ($) {
|
||||||
|
my $page=shift;
|
||||||
|
|
||||||
|
return ! pagespec_match($page, "internal(*/$config{comments_pagename}*)",
|
||||||
|
location => $page) &&
|
||||||
|
pagespec_match($page, $config{comments_pagespec},
|
||||||
|
location => $page);
|
||||||
|
}
|
||||||
|
|
||||||
|
sub commentsopen ($) {
|
||||||
|
my $page = shift;
|
||||||
|
|
||||||
|
return length $config{cgiurl} > 0 &&
|
||||||
|
(! length $config{comments_closed_pagespec} ||
|
||||||
|
! pagespec_match($page, $config{comments_closed_pagespec},
|
||||||
|
location => $page));
|
||||||
|
}
|
||||||
|
|
||||||
|
sub pagetemplate (@) {
|
||||||
|
my %params = @_;
|
||||||
|
|
||||||
|
my $page = $params{page};
|
||||||
|
my $template = $params{template};
|
||||||
|
my $shown = ($template->query(name => 'commentslink') ||
|
||||||
|
$template->query(name => 'commentsurl') ||
|
||||||
|
$template->query(name => 'atomcommentsurl') ||
|
||||||
|
$template->query(name => 'comments')) &&
|
||||||
|
commentsshown($page);
|
||||||
|
|
||||||
|
if ($template->query(name => 'comments')) {
|
||||||
|
my $comments = undef;
|
||||||
|
if ($shown) {
|
||||||
|
$comments = IkiWiki::preprocess_inline(
|
||||||
|
pages => "internal($page/$config{comments_pagename}*)",
|
||||||
|
template => 'comment',
|
||||||
|
show => 0,
|
||||||
|
reverse => 'yes',
|
||||||
|
page => $page,
|
||||||
|
destpage => $params{destpage},
|
||||||
|
feedfile => 'comments',
|
||||||
|
emptyfeeds => 'no',
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (defined $comments && length $comments) {
|
||||||
|
$template->param(comments => $comments);
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($shown && commentsopen($page)) {
|
||||||
|
my $addcommenturl = IkiWiki::cgiurl(do => 'comment',
|
||||||
|
page => $page);
|
||||||
|
$template->param(addcommenturl => $addcommenturl);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($template->query(name => 'commentsurl')) {
|
||||||
|
if ($shown) {
|
||||||
|
$template->param(commentsurl =>
|
||||||
|
urlto($page, undef, 1).'#comments');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($template->query(name => 'atomcommentsurl') && $config{usedirs}) {
|
||||||
|
if ($shown) {
|
||||||
|
# This will 404 until there are some comments, but I
|
||||||
|
# think that's probably OK...
|
||||||
|
$template->param(atomcommentsurl =>
|
||||||
|
urlto($page, undef, 1).'comments.atom');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($template->query(name => 'commentslink')) {
|
||||||
|
# XXX Would be nice to say how many comments there are in
|
||||||
|
# the link. But, to update the number, blog pages
|
||||||
|
# would have to update whenever comments of any inlines
|
||||||
|
# page are added, which is not currently done.
|
||||||
|
if ($shown) {
|
||||||
|
$template->param(commentslink =>
|
||||||
|
htmllink($page, $params{destpage}, $page,
|
||||||
|
linktext => gettext("Comments"),
|
||||||
|
anchor => "comments",
|
||||||
|
noimageinline => 1));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
# everything below this point is only relevant to the comments
|
||||||
|
# themselves
|
||||||
|
if (!exists $commentstate{$page}) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($template->query(name => 'commentid')) {
|
||||||
|
$template->param(commentid => page_to_id($page));
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($template->query(name => 'commentuser')) {
|
||||||
|
$template->param(commentuser =>
|
||||||
|
$commentstate{$page}{commentuser});
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($template->query(name => 'commentopenid')) {
|
||||||
|
$template->param(commentopenid =>
|
||||||
|
$commentstate{$page}{commentopenid});
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($template->query(name => 'commentip')) {
|
||||||
|
$template->param(commentip =>
|
||||||
|
$commentstate{$page}{commentip});
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($template->query(name => 'commentauthor')) {
|
||||||
|
$template->param(commentauthor =>
|
||||||
|
$commentstate{$page}{commentauthor});
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($template->query(name => 'commentauthorurl')) {
|
||||||
|
$template->param(commentauthorurl =>
|
||||||
|
$commentstate{$page}{commentauthorurl});
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($template->query(name => 'removeurl') &&
|
||||||
|
IkiWiki::Plugin::remove->can("check_canremove") &&
|
||||||
|
length $config{cgiurl}) {
|
||||||
|
$template->param(removeurl => IkiWiki::cgiurl(do => 'remove',
|
||||||
|
page => $page));
|
||||||
|
$template->param(have_actions => 1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
sub unique_comment_location ($) {
|
||||||
|
my $page=shift;
|
||||||
|
my $dir=shift;
|
||||||
|
|
||||||
|
my $location;
|
||||||
|
my $i = 0;
|
||||||
|
do {
|
||||||
|
$i++;
|
||||||
|
$location = "$page/$config{comments_pagename}$i";
|
||||||
|
} while (-e "$dir/$location._comment");
|
||||||
|
|
||||||
|
return $location;
|
||||||
|
}
|
||||||
|
|
||||||
|
sub page_to_id ($) {
|
||||||
|
# Converts a comment page name into a unique, legal html id
|
||||||
|
# addtibute value, that can be used as an anchor to link to the
|
||||||
|
# comment.
|
||||||
|
my $page=shift;
|
||||||
|
|
||||||
|
eval q{use Digest::MD5 'md5_hex'};
|
||||||
|
error($@) if $@;
|
||||||
|
|
||||||
|
return "comment-".md5_hex($page);
|
||||||
|
}
|
||||||
|
|
||||||
|
package IkiWiki::PageSpec;
|
||||||
|
|
||||||
|
sub match_postcomment ($$;@) {
|
||||||
|
my $page = shift;
|
||||||
|
my $glob = shift;
|
||||||
|
|
||||||
|
if (! $postcomment) {
|
||||||
|
return IkiWiki::FailReason->new("not posting a comment");
|
||||||
|
}
|
||||||
|
return match_glob($page, $glob);
|
||||||
|
}
|
||||||
|
|
||||||
|
1
|
|
@ -3,23 +3,23 @@ package IkiWiki::Plugin::conditional;
|
||||||
|
|
||||||
use warnings;
|
use warnings;
|
||||||
use strict;
|
use strict;
|
||||||
use IkiWiki 2.00;
|
use IkiWiki 3.00;
|
||||||
use UNIVERSAL;
|
use UNIVERSAL;
|
||||||
|
|
||||||
sub import { #{{{
|
sub import {
|
||||||
hook(type => "getsetup", id => "conditional", call => \&getsetup);
|
hook(type => "getsetup", id => "conditional", call => \&getsetup);
|
||||||
hook(type => "preprocess", id => "if", call => \&preprocess_if);
|
hook(type => "preprocess", id => "if", call => \&preprocess_if);
|
||||||
} # }}}
|
}
|
||||||
|
|
||||||
sub getsetup { #{{{
|
sub getsetup {
|
||||||
return
|
return
|
||||||
plugin => {
|
plugin => {
|
||||||
safe => 1,
|
safe => 1,
|
||||||
rebuild => undef,
|
rebuild => undef,
|
||||||
},
|
},
|
||||||
} #}}}
|
}
|
||||||
|
|
||||||
sub preprocess_if (@) { #{{{
|
sub preprocess_if (@) {
|
||||||
my %params=@_;
|
my %params=@_;
|
||||||
|
|
||||||
foreach my $param (qw{test then}) {
|
foreach my $param (qw{test then}) {
|
||||||
|
@ -66,11 +66,11 @@ sub preprocess_if (@) { #{{{
|
||||||
}
|
}
|
||||||
return IkiWiki::preprocess($params{page}, $params{destpage},
|
return IkiWiki::preprocess($params{page}, $params{destpage},
|
||||||
IkiWiki::filter($params{page}, $params{destpage}, $ret));
|
IkiWiki::filter($params{page}, $params{destpage}, $ret));
|
||||||
} # }}}
|
}
|
||||||
|
|
||||||
package IkiWiki::PageSpec;
|
package IkiWiki::PageSpec;
|
||||||
|
|
||||||
sub match_enabled ($$;@) { #{{{
|
sub match_enabled ($$;@) {
|
||||||
shift;
|
shift;
|
||||||
my $plugin=shift;
|
my $plugin=shift;
|
||||||
|
|
||||||
|
@ -81,12 +81,14 @@ sub match_enabled ($$;@) { #{{{
|
||||||
else {
|
else {
|
||||||
return IkiWiki::FailReason->new("$plugin is not enabled");
|
return IkiWiki::FailReason->new("$plugin is not enabled");
|
||||||
}
|
}
|
||||||
} #}}}
|
}
|
||||||
|
|
||||||
sub match_sourcepage ($$;@) { #{{{
|
sub match_sourcepage ($$;@) {
|
||||||
shift;
|
shift;
|
||||||
my $glob=shift;
|
my $glob=shift;
|
||||||
my %params=@_;
|
my %params=@_;
|
||||||
|
|
||||||
|
$glob=derel($glob, $params{location});
|
||||||
|
|
||||||
return IkiWiki::FailReason->new("cannot match sourcepage") unless exists $params{sourcepage};
|
return IkiWiki::FailReason->new("cannot match sourcepage") unless exists $params{sourcepage};
|
||||||
if (match_glob($params{sourcepage}, $glob, @_)) {
|
if (match_glob($params{sourcepage}, $glob, @_)) {
|
||||||
|
@ -95,13 +97,15 @@ sub match_sourcepage ($$;@) { #{{{
|
||||||
else {
|
else {
|
||||||
return IkiWiki::FailReason->new("sourcepage does not match $glob");
|
return IkiWiki::FailReason->new("sourcepage does not match $glob");
|
||||||
}
|
}
|
||||||
} #}}}
|
}
|
||||||
|
|
||||||
sub match_destpage ($$;@) { #{{{
|
sub match_destpage ($$;@) {
|
||||||
shift;
|
shift;
|
||||||
my $glob=shift;
|
my $glob=shift;
|
||||||
my %params=@_;
|
my %params=@_;
|
||||||
|
|
||||||
|
$glob=derel($glob, $params{location});
|
||||||
|
|
||||||
return IkiWiki::FailReason->new("cannot match destpage") unless exists $params{destpage};
|
return IkiWiki::FailReason->new("cannot match destpage") unless exists $params{destpage};
|
||||||
if (match_glob($params{destpage}, $glob, @_)) {
|
if (match_glob($params{destpage}, $glob, @_)) {
|
||||||
return IkiWiki::SuccessReason->new("destpage matches $glob");
|
return IkiWiki::SuccessReason->new("destpage matches $glob");
|
||||||
|
@ -109,9 +113,9 @@ sub match_destpage ($$;@) { #{{{
|
||||||
else {
|
else {
|
||||||
return IkiWiki::FailReason->new("destpage does not match $glob");
|
return IkiWiki::FailReason->new("destpage does not match $glob");
|
||||||
}
|
}
|
||||||
} #}}}
|
}
|
||||||
|
|
||||||
sub match_included ($$;@) { #{{{
|
sub match_included ($$;@) {
|
||||||
shift;
|
shift;
|
||||||
shift;
|
shift;
|
||||||
my %params=@_;
|
my %params=@_;
|
||||||
|
@ -123,6 +127,6 @@ sub match_included ($$;@) { #{{{
|
||||||
else {
|
else {
|
||||||
return IkiWiki::FailReason->new("page $params{sourcepage} is not included");
|
return IkiWiki::FailReason->new("page $params{sourcepage} is not included");
|
||||||
}
|
}
|
||||||
} #}}}
|
}
|
||||||
|
|
||||||
1
|
1
|
||||||
|
|
|
@ -5,22 +5,22 @@ package IkiWiki::Plugin::creole;
|
||||||
|
|
||||||
use warnings;
|
use warnings;
|
||||||
use strict;
|
use strict;
|
||||||
use IkiWiki 2.00;
|
use IkiWiki 3.00;
|
||||||
|
|
||||||
sub import { #{{{
|
sub import {
|
||||||
hook(type => "getsetup", id => "creole", call => \&getsetup);
|
hook(type => "getsetup", id => "creole", call => \&getsetup);
|
||||||
hook(type => "htmlize", id => "creole", call => \&htmlize);
|
hook(type => "htmlize", id => "creole", call => \&htmlize);
|
||||||
} # }}}
|
}
|
||||||
|
|
||||||
sub getsetup { #{{{
|
sub getsetup {
|
||||||
return
|
return
|
||||||
plugin => {
|
plugin => {
|
||||||
safe => 1,
|
safe => 1,
|
||||||
rebuild => 1, # format plugin
|
rebuild => 1, # format plugin
|
||||||
},
|
},
|
||||||
} #}}}
|
}
|
||||||
|
|
||||||
sub htmlize (@) { #{{{
|
sub htmlize (@) {
|
||||||
my %params=@_;
|
my %params=@_;
|
||||||
my $content = $params{content};
|
my $content = $params{content};
|
||||||
|
|
||||||
|
@ -32,6 +32,6 @@ sub htmlize (@) { #{{{
|
||||||
creole_custombarelinks();
|
creole_custombarelinks();
|
||||||
|
|
||||||
return creole_parse($content);
|
return creole_parse($content);
|
||||||
} # }}}
|
}
|
||||||
|
|
||||||
1
|
1
|
||||||
|
|
|
@ -3,26 +3,26 @@ package IkiWiki::Plugin::cutpaste;
|
||||||
|
|
||||||
use warnings;
|
use warnings;
|
||||||
use strict;
|
use strict;
|
||||||
use IkiWiki 2.00;
|
use IkiWiki 3.00;
|
||||||
|
|
||||||
my %savedtext;
|
my %savedtext;
|
||||||
|
|
||||||
sub import { #{{{
|
sub import {
|
||||||
hook(type => "getsetup", id => "cutpaste", call => \&getsetup);
|
hook(type => "getsetup", id => "cutpaste", call => \&getsetup);
|
||||||
hook(type => "preprocess", id => "cut", call => \&preprocess_cut, scan => 1);
|
hook(type => "preprocess", id => "cut", call => \&preprocess_cut, scan => 1);
|
||||||
hook(type => "preprocess", id => "copy", call => \&preprocess_copy, scan => 1);
|
hook(type => "preprocess", id => "copy", call => \&preprocess_copy, scan => 1);
|
||||||
hook(type => "preprocess", id => "paste", call => \&preprocess_paste);
|
hook(type => "preprocess", id => "paste", call => \&preprocess_paste);
|
||||||
} # }}}
|
}
|
||||||
|
|
||||||
sub getsetup () { #{{{
|
sub getsetup () {
|
||||||
return
|
return
|
||||||
plugin => {
|
plugin => {
|
||||||
safe => 1,
|
safe => 1,
|
||||||
rebuild => undef,
|
rebuild => undef,
|
||||||
},
|
},
|
||||||
} #}}}
|
}
|
||||||
|
|
||||||
sub preprocess_cut (@) { #{{{
|
sub preprocess_cut (@) {
|
||||||
my %params=@_;
|
my %params=@_;
|
||||||
|
|
||||||
foreach my $param (qw{id text}) {
|
foreach my $param (qw{id text}) {
|
||||||
|
@ -35,9 +35,9 @@ sub preprocess_cut (@) { #{{{
|
||||||
$savedtext{$params{page}}->{$params{id}} = $params{text};
|
$savedtext{$params{page}}->{$params{id}} = $params{text};
|
||||||
|
|
||||||
return "" if defined wantarray;
|
return "" if defined wantarray;
|
||||||
} # }}}
|
}
|
||||||
|
|
||||||
sub preprocess_copy (@) { #{{{
|
sub preprocess_copy (@) {
|
||||||
my %params=@_;
|
my %params=@_;
|
||||||
|
|
||||||
foreach my $param (qw{id text}) {
|
foreach my $param (qw{id text}) {
|
||||||
|
@ -51,9 +51,9 @@ sub preprocess_copy (@) { #{{{
|
||||||
|
|
||||||
return IkiWiki::preprocess($params{page}, $params{destpage},
|
return IkiWiki::preprocess($params{page}, $params{destpage},
|
||||||
IkiWiki::filter($params{page}, $params{destpage}, $params{text})) if defined wantarray;
|
IkiWiki::filter($params{page}, $params{destpage}, $params{text})) if defined wantarray;
|
||||||
} # }}}
|
}
|
||||||
|
|
||||||
sub preprocess_paste (@) { #{{{
|
sub preprocess_paste (@) {
|
||||||
my %params=@_;
|
my %params=@_;
|
||||||
|
|
||||||
foreach my $param (qw{id}) {
|
foreach my $param (qw{id}) {
|
||||||
|
@ -71,6 +71,6 @@ sub preprocess_paste (@) { #{{{
|
||||||
|
|
||||||
return IkiWiki::preprocess($params{page}, $params{destpage},
|
return IkiWiki::preprocess($params{page}, $params{destpage},
|
||||||
IkiWiki::filter($params{page}, $params{destpage}, $savedtext{$params{page}}->{$params{id}}));
|
IkiWiki::filter($params{page}, $params{destpage}, $savedtext{$params{page}}->{$params{id}}));
|
||||||
} # }}}
|
}
|
||||||
|
|
||||||
1;
|
1;
|
||||||
|
|
|
@ -2,22 +2,22 @@
|
||||||
# Discordian date support fnord ikiwiki.
|
# Discordian date support fnord ikiwiki.
|
||||||
package IkiWiki::Plugin::ddate;
|
package IkiWiki::Plugin::ddate;
|
||||||
|
|
||||||
use IkiWiki 2.00;
|
use IkiWiki 3.00;
|
||||||
no warnings;
|
no warnings;
|
||||||
|
|
||||||
sub import { #{{{
|
sub import {
|
||||||
hook(type => "getsetup", id => "ddate", call => \&getsetup);
|
hook(type => "getsetup", id => "ddate", call => \&getsetup);
|
||||||
} # }}}
|
}
|
||||||
|
|
||||||
sub getsetup { #{{{
|
sub getsetup {
|
||||||
return
|
return
|
||||||
plugin => {
|
plugin => {
|
||||||
safe => 1,
|
safe => 1,
|
||||||
rebuild => 1,
|
rebuild => 1,
|
||||||
},
|
},
|
||||||
} #}}}
|
}
|
||||||
|
|
||||||
sub IkiWiki::displaytime ($;$) { #{{{
|
sub IkiWiki::formattime ($;$) {
|
||||||
my $time=shift;
|
my $time=shift;
|
||||||
my $format=shift;
|
my $format=shift;
|
||||||
if (! defined $format) {
|
if (! defined $format) {
|
||||||
|
@ -36,6 +36,6 @@ sub IkiWiki::displaytime ($;$) { #{{{
|
||||||
my $dt = DateTime->from_epoch(epoch => $time);
|
my $dt = DateTime->from_epoch(epoch => $time);
|
||||||
my $dd = DateTime::Calendar::Discordian->from_object(object => $dt);
|
my $dd = DateTime::Calendar::Discordian->from_object(object => $dt);
|
||||||
return $dd->strftime($format);
|
return $dd->strftime($format);
|
||||||
} #}}}
|
}
|
||||||
|
|
||||||
5
|
5
|
||||||
|
|
|
@ -4,25 +4,25 @@ package IkiWiki::Plugin::editdiff;
|
||||||
|
|
||||||
use warnings;
|
use warnings;
|
||||||
use strict;
|
use strict;
|
||||||
use IkiWiki 2.00;
|
use IkiWiki 3.00;
|
||||||
use HTML::Entities;
|
use HTML::Entities;
|
||||||
use IPC::Open2;
|
use IPC::Open2;
|
||||||
|
|
||||||
sub import { #{{{
|
sub import {
|
||||||
hook(type => "getsetup", id => "editdiff", call => \&getsetup);
|
hook(type => "getsetup", id => "editdiff", call => \&getsetup);
|
||||||
hook(type => "formbuilder_setup", id => "editdiff",
|
hook(type => "formbuilder_setup", id => "editdiff",
|
||||||
call => \&formbuilder_setup);
|
call => \&formbuilder_setup);
|
||||||
} #}}}
|
}
|
||||||
|
|
||||||
sub getsetup () { #{{{
|
sub getsetup () {
|
||||||
return
|
return
|
||||||
plugin => {
|
plugin => {
|
||||||
safe => 1,
|
safe => 1,
|
||||||
rebuild => 0,
|
rebuild => 0,
|
||||||
},
|
},
|
||||||
} #}}}
|
}
|
||||||
|
|
||||||
sub diff ($$) { #{{{
|
sub diff ($$) {
|
||||||
my $orig=shift;
|
my $orig=shift;
|
||||||
my $content=shift;
|
my $content=shift;
|
||||||
|
|
||||||
|
@ -50,9 +50,9 @@ sub diff ($$) { #{{{
|
||||||
return "couldn't run diff\n" if $sigpipe;
|
return "couldn't run diff\n" if $sigpipe;
|
||||||
|
|
||||||
return "<pre>".encode_entities($ret)."</pre>";
|
return "<pre>".encode_entities($ret)."</pre>";
|
||||||
} #}}}
|
}
|
||||||
|
|
||||||
sub formbuilder_setup { #{{{
|
sub formbuilder_setup {
|
||||||
my %params=@_;
|
my %params=@_;
|
||||||
my $form=$params{form};
|
my $form=$params{form};
|
||||||
|
|
||||||
|
@ -72,6 +72,6 @@ sub formbuilder_setup { #{{{
|
||||||
my $diff = diff(srcfile($pagesources{$page}), $content);
|
my $diff = diff(srcfile($pagesources{$page}), $content);
|
||||||
$form->tmpl_param("page_preview", $diff);
|
$form->tmpl_param("page_preview", $diff);
|
||||||
}
|
}
|
||||||
} #}}}
|
}
|
||||||
|
|
||||||
1
|
1
|
||||||
|
|
|
@ -6,19 +6,19 @@ use strict;
|
||||||
use IkiWiki;
|
use IkiWiki;
|
||||||
use open qw{:utf8 :std};
|
use open qw{:utf8 :std};
|
||||||
|
|
||||||
sub import { #{{{
|
sub import {
|
||||||
hook(type => "getsetup", id => "editpage", call => \&getsetup);
|
hook(type => "getsetup", id => "editpage", call => \&getsetup);
|
||||||
hook(type => "refresh", id => "editpage", call => \&refresh);
|
hook(type => "refresh", id => "editpage", call => \&refresh);
|
||||||
hook(type => "sessioncgi", id => "editpage", call => \&IkiWiki::cgi_editpage);
|
hook(type => "sessioncgi", id => "editpage", call => \&IkiWiki::cgi_editpage);
|
||||||
} # }}}
|
}
|
||||||
|
|
||||||
sub getsetup () { #{{{
|
sub getsetup () {
|
||||||
return
|
return
|
||||||
plugin => {
|
plugin => {
|
||||||
safe => 1,
|
safe => 1,
|
||||||
rebuild => 1,
|
rebuild => 1,
|
||||||
},
|
},
|
||||||
} #}}}
|
}
|
||||||
|
|
||||||
sub refresh () {
|
sub refresh () {
|
||||||
if (exists $wikistate{editpage} && exists $wikistate{editpage}{previews}) {
|
if (exists $wikistate{editpage} && exists $wikistate{editpage}{previews}) {
|
||||||
|
@ -51,37 +51,10 @@ sub refresh () {
|
||||||
|
|
||||||
# Back to ikiwiki namespace for the rest, this code is very much
|
# Back to ikiwiki namespace for the rest, this code is very much
|
||||||
# internal to ikiwiki even though it's separated into a plugin,
|
# internal to ikiwiki even though it's separated into a plugin,
|
||||||
# and other plugins use the functions below.
|
# and other plugins use the function below.
|
||||||
package IkiWiki;
|
package IkiWiki;
|
||||||
|
|
||||||
sub check_canedit ($$$;$) { #{{{
|
sub cgi_editpage ($$) {
|
||||||
my $page=shift;
|
|
||||||
my $q=shift;
|
|
||||||
my $session=shift;
|
|
||||||
my $nonfatal=shift;
|
|
||||||
|
|
||||||
my $canedit;
|
|
||||||
run_hooks(canedit => sub {
|
|
||||||
return if defined $canedit;
|
|
||||||
my $ret=shift->($page, $q, $session);
|
|
||||||
if (defined $ret) {
|
|
||||||
if ($ret eq "") {
|
|
||||||
$canedit=1;
|
|
||||||
}
|
|
||||||
elsif (ref $ret eq 'CODE') {
|
|
||||||
$ret->() unless $nonfatal;
|
|
||||||
$canedit=0;
|
|
||||||
}
|
|
||||||
elsif (defined $ret) {
|
|
||||||
error($ret) unless $nonfatal;
|
|
||||||
$canedit=0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
|
||||||
return $canedit;
|
|
||||||
} #}}}
|
|
||||||
|
|
||||||
sub cgi_editpage ($$) { #{{{
|
|
||||||
my $q=shift;
|
my $q=shift;
|
||||||
my $session=shift;
|
my $session=shift;
|
||||||
|
|
||||||
|
@ -105,7 +78,6 @@ sub cgi_editpage ($$) { #{{{
|
||||||
header => 0,
|
header => 0,
|
||||||
table => 0,
|
table => 0,
|
||||||
template => scalar template_params("editpage.tmpl"),
|
template => scalar template_params("editpage.tmpl"),
|
||||||
wikiname => $config{wikiname},
|
|
||||||
);
|
);
|
||||||
|
|
||||||
decode_form_utf8($form);
|
decode_form_utf8($form);
|
||||||
|
@ -122,7 +94,7 @@ sub cgi_editpage ($$) { #{{{
|
||||||
my $absolute=($page =~ s#^/+##);
|
my $absolute=($page =~ s#^/+##);
|
||||||
if (! defined $page || ! length $page ||
|
if (! defined $page || ! length $page ||
|
||||||
file_pruned($page, $config{srcdir})) {
|
file_pruned($page, $config{srcdir})) {
|
||||||
error("bad page name");
|
error(gettext("bad page name"));
|
||||||
}
|
}
|
||||||
|
|
||||||
my $baseurl = urlto($page, undef, 1);
|
my $baseurl = urlto($page, undef, 1);
|
||||||
|
@ -340,16 +312,7 @@ sub cgi_editpage ($$) { #{{{
|
||||||
else {
|
else {
|
||||||
# save page
|
# save page
|
||||||
check_canedit($page, $q, $session);
|
check_canedit($page, $q, $session);
|
||||||
|
checksessionexpiry($q, $session, $q->param('sid'));
|
||||||
# The session id is stored on the form and checked to
|
|
||||||
# guard against CSRF. But only if the user is logged in,
|
|
||||||
# as anonok can allow anonymous edits.
|
|
||||||
if (defined $session->param("name")) {
|
|
||||||
my $sid=$q->param('sid');
|
|
||||||
if (! defined $sid || $sid ne $session->id) {
|
|
||||||
error(gettext("Your login session has expired."));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
my $exists=-e "$config{srcdir}/$file";
|
my $exists=-e "$config{srcdir}/$file";
|
||||||
|
|
||||||
|
@ -378,8 +341,17 @@ sub cgi_editpage ($$) { #{{{
|
||||||
showform($form, \@buttons, $session, $q, forcebaseurl => $baseurl);
|
showform($form, \@buttons, $session, $q, forcebaseurl => $baseurl);
|
||||||
exit;
|
exit;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
my $message="";
|
||||||
|
if (defined $form->field('comments') &&
|
||||||
|
length $form->field('comments')) {
|
||||||
|
$message=$form->field('comments');
|
||||||
|
}
|
||||||
|
|
||||||
my $content=$form->field('editcontent');
|
my $content=$form->field('editcontent');
|
||||||
|
check_content(content => $content, page => $page,
|
||||||
|
cgi => $q, session => $session,
|
||||||
|
subject => $message);
|
||||||
run_hooks(editcontent => sub {
|
run_hooks(editcontent => sub {
|
||||||
$content=shift->(
|
$content=shift->(
|
||||||
content => $content,
|
content => $content,
|
||||||
|
@ -413,12 +385,6 @@ sub cgi_editpage ($$) { #{{{
|
||||||
|
|
||||||
my $conflict;
|
my $conflict;
|
||||||
if ($config{rcs}) {
|
if ($config{rcs}) {
|
||||||
my $message="";
|
|
||||||
if (defined $form->field('comments') &&
|
|
||||||
length $form->field('comments')) {
|
|
||||||
$message=$form->field('comments');
|
|
||||||
}
|
|
||||||
|
|
||||||
if (! $exists) {
|
if (! $exists) {
|
||||||
rcs_add($file);
|
rcs_add($file);
|
||||||
}
|
}
|
||||||
|
@ -462,6 +428,6 @@ sub cgi_editpage ($$) { #{{{
|
||||||
}
|
}
|
||||||
|
|
||||||
exit;
|
exit;
|
||||||
} #}}}
|
}
|
||||||
|
|
||||||
1
|
1
|
||||||
|
|
|
@ -3,11 +3,11 @@ package IkiWiki::Plugin::edittemplate;
|
||||||
|
|
||||||
use warnings;
|
use warnings;
|
||||||
use strict;
|
use strict;
|
||||||
use IkiWiki 2.00;
|
use IkiWiki 3.00;
|
||||||
use HTML::Template;
|
use HTML::Template;
|
||||||
use Encode;
|
use Encode;
|
||||||
|
|
||||||
sub import { #{{{
|
sub import {
|
||||||
hook(type => "getsetup", id => "edittemplate",
|
hook(type => "getsetup", id => "edittemplate",
|
||||||
call => \&getsetup);
|
call => \&getsetup);
|
||||||
hook(type => "needsbuild", id => "edittemplate",
|
hook(type => "needsbuild", id => "edittemplate",
|
||||||
|
@ -16,17 +16,17 @@ sub import { #{{{
|
||||||
call => \&preprocess);
|
call => \&preprocess);
|
||||||
hook(type => "formbuilder", id => "edittemplate",
|
hook(type => "formbuilder", id => "edittemplate",
|
||||||
call => \&formbuilder);
|
call => \&formbuilder);
|
||||||
} #}}}
|
}
|
||||||
|
|
||||||
sub getsetup () { #{{{
|
sub getsetup () {
|
||||||
return
|
return
|
||||||
plugin => {
|
plugin => {
|
||||||
safe => 1,
|
safe => 1,
|
||||||
rebuild => undef,
|
rebuild => undef,
|
||||||
},
|
},
|
||||||
} #}}}
|
}
|
||||||
|
|
||||||
sub needsbuild (@) { #{{{
|
sub needsbuild (@) {
|
||||||
my $needsbuild=shift;
|
my $needsbuild=shift;
|
||||||
|
|
||||||
foreach my $page (keys %pagestate) {
|
foreach my $page (keys %pagestate) {
|
||||||
|
@ -40,9 +40,9 @@ sub needsbuild (@) { #{{{
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} #}}}
|
}
|
||||||
|
|
||||||
sub preprocess (@) { #{{{
|
sub preprocess (@) {
|
||||||
my %params=@_;
|
my %params=@_;
|
||||||
|
|
||||||
return "" if $params{page} ne $params{destpage};
|
return "" if $params{page} ne $params{destpage};
|
||||||
|
@ -62,9 +62,9 @@ sub preprocess (@) { #{{{
|
||||||
return sprintf(gettext("edittemplate %s registered for %s"),
|
return sprintf(gettext("edittemplate %s registered for %s"),
|
||||||
htmllink($params{page}, $params{destpage}, $link),
|
htmllink($params{page}, $params{destpage}, $link),
|
||||||
$params{match});
|
$params{match});
|
||||||
} # }}}
|
}
|
||||||
|
|
||||||
sub formbuilder (@) { #{{{
|
sub formbuilder (@) {
|
||||||
my %params=@_;
|
my %params=@_;
|
||||||
my $form=$params{form};
|
my $form=$params{form};
|
||||||
|
|
||||||
|
@ -103,9 +103,9 @@ sub formbuilder (@) { #{{{
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} #}}}
|
}
|
||||||
|
|
||||||
sub filltemplate ($$) { #{{{
|
sub filltemplate ($$) {
|
||||||
my $template_page=shift;
|
my $template_page=shift;
|
||||||
my $page=shift;
|
my $page=shift;
|
||||||
|
|
||||||
|
@ -136,6 +136,6 @@ sub filltemplate ($$) { #{{{
|
||||||
$template->param(name => $page);
|
$template->param(name => $page);
|
||||||
|
|
||||||
return $template->output;
|
return $template->output;
|
||||||
} #}}}
|
}
|
||||||
|
|
||||||
1
|
1
|
||||||
|
|
|
@ -3,7 +3,7 @@ package IkiWiki::Plugin::embed;
|
||||||
|
|
||||||
use warnings;
|
use warnings;
|
||||||
use strict;
|
use strict;
|
||||||
use IkiWiki 2.00;
|
use IkiWiki 3.00;
|
||||||
|
|
||||||
my $attribr=qr/[^<>"]+/;
|
my $attribr=qr/[^<>"]+/;
|
||||||
|
|
||||||
|
@ -43,35 +43,35 @@ my $safehtml=qr{(
|
||||||
|
|
||||||
my @embedded;
|
my @embedded;
|
||||||
|
|
||||||
sub import { #{{{
|
sub import {
|
||||||
hook(type => "getsetup", id => "embed", call => \&getsetup);
|
hook(type => "getsetup", id => "embed", call => \&getsetup);
|
||||||
hook(type => "filter", id => "embed", call => \&filter);
|
hook(type => "filter", id => "embed", call => \&filter);
|
||||||
} # }}}
|
}
|
||||||
|
|
||||||
sub getsetup () { #{{{
|
sub getsetup () {
|
||||||
return
|
return
|
||||||
plugin => {
|
plugin => {
|
||||||
safe => 1,
|
safe => 1,
|
||||||
rebuild => undef,
|
rebuild => undef,
|
||||||
},
|
},
|
||||||
} #}}}
|
}
|
||||||
|
|
||||||
sub embed ($) { #{{{
|
sub embed ($) {
|
||||||
hook(type => "format", id => "embed", call => \&format) unless @embedded;
|
hook(type => "format", id => "embed", call => \&format) unless @embedded;
|
||||||
push @embedded, shift;
|
push @embedded, shift;
|
||||||
return "<div class=\"embed$#embedded\"></div>";
|
return "<div class=\"embed$#embedded\"></div>";
|
||||||
} #}}}
|
}
|
||||||
|
|
||||||
sub filter (@) { #{{{
|
sub filter (@) {
|
||||||
my %params=@_;
|
my %params=@_;
|
||||||
$params{content} =~ s/$safehtml/embed($1)/eg;
|
$params{content} =~ s/$safehtml/embed($1)/eg;
|
||||||
return $params{content};
|
return $params{content};
|
||||||
} # }}}
|
}
|
||||||
|
|
||||||
sub format (@) { #{{{
|
sub format (@) {
|
||||||
my %params=@_;
|
my %params=@_;
|
||||||
$params{content} =~ s/<div class="embed(\d+)"><\/div>/$embedded[$1]/eg;
|
$params{content} =~ s/<div class="embed(\d+)"><\/div>/$embedded[$1]/eg;
|
||||||
return $params{content};
|
return $params{content};
|
||||||
} # }}}
|
}
|
||||||
|
|
||||||
1
|
1
|
||||||
|
|
|
@ -6,7 +6,7 @@ package IkiWiki::Plugin::external;
|
||||||
|
|
||||||
use warnings;
|
use warnings;
|
||||||
use strict;
|
use strict;
|
||||||
use IkiWiki 2.00;
|
use IkiWiki 3.00;
|
||||||
use RPC::XML;
|
use RPC::XML;
|
||||||
use RPC::XML::Parser;
|
use RPC::XML::Parser;
|
||||||
use IPC::Open2;
|
use IPC::Open2;
|
||||||
|
@ -14,7 +14,7 @@ use IO::Handle;
|
||||||
|
|
||||||
my %plugins;
|
my %plugins;
|
||||||
|
|
||||||
sub import { #{{{
|
sub import {
|
||||||
my $self=shift;
|
my $self=shift;
|
||||||
my $plugin=shift;
|
my $plugin=shift;
|
||||||
return unless defined $plugin;
|
return unless defined $plugin;
|
||||||
|
@ -32,17 +32,17 @@ sub import { #{{{
|
||||||
$RPC::XML::ENCODING="utf-8";
|
$RPC::XML::ENCODING="utf-8";
|
||||||
|
|
||||||
rpc_call($plugins{$plugin}, "import");
|
rpc_call($plugins{$plugin}, "import");
|
||||||
} #}}}
|
}
|
||||||
|
|
||||||
sub rpc_write ($$) { #{{{
|
sub rpc_write ($$) {
|
||||||
my $fh=shift;
|
my $fh=shift;
|
||||||
my $string=shift;
|
my $string=shift;
|
||||||
|
|
||||||
$fh->print($string."\n");
|
$fh->print($string."\n");
|
||||||
$fh->flush;
|
$fh->flush;
|
||||||
} #}}}
|
}
|
||||||
|
|
||||||
sub rpc_call ($$;@) { #{{{
|
sub rpc_call ($$;@) {
|
||||||
my $plugin=shift;
|
my $plugin=shift;
|
||||||
my $command=shift;
|
my $command=shift;
|
||||||
|
|
||||||
|
@ -131,12 +131,12 @@ sub rpc_call ($$;@) { #{{{
|
||||||
}
|
}
|
||||||
|
|
||||||
return undef;
|
return undef;
|
||||||
} #}}}
|
}
|
||||||
|
|
||||||
package IkiWiki::RPC::XML;
|
package IkiWiki::RPC::XML;
|
||||||
use Memoize;
|
use Memoize;
|
||||||
|
|
||||||
sub getvar ($$$) { #{{{
|
sub getvar ($$$) {
|
||||||
my $plugin=shift;
|
my $plugin=shift;
|
||||||
my $varname="IkiWiki::".shift;
|
my $varname="IkiWiki::".shift;
|
||||||
my $key=shift;
|
my $key=shift;
|
||||||
|
@ -145,9 +145,9 @@ sub getvar ($$$) { #{{{
|
||||||
my $ret=$varname->{$key};
|
my $ret=$varname->{$key};
|
||||||
use strict 'refs';
|
use strict 'refs';
|
||||||
return $ret;
|
return $ret;
|
||||||
} #}}}
|
}
|
||||||
|
|
||||||
sub setvar ($$$;@) { #{{{
|
sub setvar ($$$;@) {
|
||||||
my $plugin=shift;
|
my $plugin=shift;
|
||||||
my $varname="IkiWiki::".shift;
|
my $varname="IkiWiki::".shift;
|
||||||
my $key=shift;
|
my $key=shift;
|
||||||
|
@ -157,18 +157,18 @@ sub setvar ($$$;@) { #{{{
|
||||||
my $ret=$varname->{$key}=$value;
|
my $ret=$varname->{$key}=$value;
|
||||||
use strict 'refs';
|
use strict 'refs';
|
||||||
return $ret;
|
return $ret;
|
||||||
} #}}}
|
}
|
||||||
|
|
||||||
sub getstate ($$$$) { #{{{
|
sub getstate ($$$$) {
|
||||||
my $plugin=shift;
|
my $plugin=shift;
|
||||||
my $page=shift;
|
my $page=shift;
|
||||||
my $id=shift;
|
my $id=shift;
|
||||||
my $key=shift;
|
my $key=shift;
|
||||||
|
|
||||||
return $IkiWiki::pagestate{$page}{$id}{$key};
|
return $IkiWiki::pagestate{$page}{$id}{$key};
|
||||||
} #}}}
|
}
|
||||||
|
|
||||||
sub setstate ($$$$;@) { #{{{
|
sub setstate ($$$$;@) {
|
||||||
my $plugin=shift;
|
my $plugin=shift;
|
||||||
my $page=shift;
|
my $page=shift;
|
||||||
my $id=shift;
|
my $id=shift;
|
||||||
|
@ -176,22 +176,22 @@ sub setstate ($$$$;@) { #{{{
|
||||||
my $value=shift;
|
my $value=shift;
|
||||||
|
|
||||||
return $IkiWiki::pagestate{$page}{$id}{$key}=$value;
|
return $IkiWiki::pagestate{$page}{$id}{$key}=$value;
|
||||||
} #}}}
|
}
|
||||||
|
|
||||||
sub getargv ($) { #{{{
|
sub getargv ($) {
|
||||||
my $plugin=shift;
|
my $plugin=shift;
|
||||||
|
|
||||||
return \@ARGV;
|
return \@ARGV;
|
||||||
} #}}}
|
}
|
||||||
|
|
||||||
sub setargv ($@) { #{{{
|
sub setargv ($@) {
|
||||||
my $plugin=shift;
|
my $plugin=shift;
|
||||||
my $array=shift;
|
my $array=shift;
|
||||||
|
|
||||||
@ARGV=@$array;
|
@ARGV=@$array;
|
||||||
} #}}}
|
}
|
||||||
|
|
||||||
sub inject ($@) { #{{{
|
sub inject ($@) {
|
||||||
# Bind a given perl function name to a particular RPC request.
|
# Bind a given perl function name to a particular RPC request.
|
||||||
my $plugin=shift;
|
my $plugin=shift;
|
||||||
my %params=@_;
|
my %params=@_;
|
||||||
|
@ -202,12 +202,20 @@ sub inject ($@) { #{{{
|
||||||
my $sub = sub {
|
my $sub = sub {
|
||||||
IkiWiki::Plugin::external::rpc_call($plugin, $params{call}, @_)
|
IkiWiki::Plugin::external::rpc_call($plugin, $params{call}, @_)
|
||||||
};
|
};
|
||||||
eval qq{*$params{name}=\$sub};
|
$sub=memoize($sub) if $params{memoize};
|
||||||
memoize($params{name}) if $params{memoize};
|
|
||||||
return 1;
|
|
||||||
} #}}}
|
|
||||||
|
|
||||||
sub hook ($@) { #{{{
|
# This will add it to the symbol table even if not present.
|
||||||
|
no warnings;
|
||||||
|
eval qq{*$params{name}=\$sub};
|
||||||
|
use warnings;
|
||||||
|
|
||||||
|
# This will ensure that everywhere it was exported to sees
|
||||||
|
# the injected version.
|
||||||
|
IkiWiki::inject(name => $params{name}, call => $sub);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
sub hook ($@) {
|
||||||
# the call parameter is a function name to call, since XML RPC
|
# the call parameter is a function name to call, since XML RPC
|
||||||
# cannot pass a function reference
|
# cannot pass a function reference
|
||||||
my $plugin=shift;
|
my $plugin=shift;
|
||||||
|
@ -219,13 +227,13 @@ sub hook ($@) { #{{{
|
||||||
IkiWiki::hook(%params, call => sub {
|
IkiWiki::hook(%params, call => sub {
|
||||||
IkiWiki::Plugin::external::rpc_call($plugin, $callback, @_);
|
IkiWiki::Plugin::external::rpc_call($plugin, $callback, @_);
|
||||||
});
|
});
|
||||||
} #}}}
|
}
|
||||||
|
|
||||||
sub pagespec_match ($@) { #{{{
|
sub pagespec_match ($@) {
|
||||||
# convert pagespec_match's return object into a XML RPC boolean
|
# convert pagespec_match's return object into a XML RPC boolean
|
||||||
my $plugin=shift;
|
my $plugin=shift;
|
||||||
|
|
||||||
return RPC::XML::boolean->new(0 + IkiWiki::pagespec_march(@_));
|
return RPC::XML::boolean->new(0 + IkiWiki::pagespec_march(@_));
|
||||||
} #}}}
|
}
|
||||||
|
|
||||||
1
|
1
|
||||||
|
|
|
@ -5,22 +5,22 @@ package IkiWiki::Plugin::favicon;
|
||||||
|
|
||||||
use warnings;
|
use warnings;
|
||||||
use strict;
|
use strict;
|
||||||
use IkiWiki 2.00;
|
use IkiWiki 3.00;
|
||||||
|
|
||||||
sub import { #{{{
|
sub import {
|
||||||
hook(type => "getsetup", id => "favicon", call => \&getsetup);
|
hook(type => "getsetup", id => "favicon", call => \&getsetup);
|
||||||
hook(type => "pagetemplate", id => "favicon", call => \&pagetemplate);
|
hook(type => "pagetemplate", id => "favicon", call => \&pagetemplate);
|
||||||
} # }}}
|
}
|
||||||
|
|
||||||
sub getsetup () { #{{{
|
sub getsetup () {
|
||||||
return
|
return
|
||||||
plugin => {
|
plugin => {
|
||||||
safe => 1,
|
safe => 1,
|
||||||
rebuild => 1,
|
rebuild => 1,
|
||||||
},
|
},
|
||||||
} #}}}
|
}
|
||||||
|
|
||||||
sub pagetemplate (@) { #{{{
|
sub pagetemplate (@) {
|
||||||
my %params=@_;
|
my %params=@_;
|
||||||
|
|
||||||
my $template=$params{template};
|
my $template=$params{template};
|
||||||
|
@ -28,6 +28,6 @@ sub pagetemplate (@) { #{{{
|
||||||
if ($template->query(name => "favicon")) {
|
if ($template->query(name => "favicon")) {
|
||||||
$template->param(favicon => "favicon.ico");
|
$template->param(favicon => "favicon.ico");
|
||||||
}
|
}
|
||||||
} # }}}
|
}
|
||||||
|
|
||||||
1
|
1
|
||||||
|
|
|
@ -3,7 +3,7 @@ package IkiWiki::Plugin::filecheck;
|
||||||
|
|
||||||
use warnings;
|
use warnings;
|
||||||
use strict;
|
use strict;
|
||||||
use IkiWiki 2.00;
|
use IkiWiki 3.00;
|
||||||
|
|
||||||
my %units=( #{{{ # size in bytes
|
my %units=( #{{{ # size in bytes
|
||||||
B => 1,
|
B => 1,
|
||||||
|
@ -37,9 +37,9 @@ my %units=( #{{{ # size in bytes
|
||||||
# ikiwiki, if you find you need larger data quantities, either modify
|
# ikiwiki, if you find you need larger data quantities, either modify
|
||||||
# yourself to add them, or travel back in time to 2008 and kill me.
|
# yourself to add them, or travel back in time to 2008 and kill me.
|
||||||
# -- Joey
|
# -- Joey
|
||||||
); #}}}
|
);
|
||||||
|
|
||||||
sub parsesize ($) { #{{{
|
sub parsesize ($) {
|
||||||
my $size=shift;
|
my $size=shift;
|
||||||
|
|
||||||
no warnings;
|
no warnings;
|
||||||
|
@ -51,10 +51,10 @@ sub parsesize ($) { #{{{
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return $base;
|
return $base;
|
||||||
} #}}}
|
}
|
||||||
|
|
||||||
# This is provided for other plugins that want to convert back the other way.
|
# This is provided for other plugins that want to convert back the other way.
|
||||||
sub humansize ($) { #{{{
|
sub humansize ($) {
|
||||||
my $size=shift;
|
my $size=shift;
|
||||||
|
|
||||||
foreach my $unit (reverse sort { $units{$a} <=> $units{$b} || $b cmp $a } keys %units) {
|
foreach my $unit (reverse sort { $units{$a} <=> $units{$b} || $b cmp $a } keys %units) {
|
||||||
|
@ -63,11 +63,11 @@ sub humansize ($) { #{{{
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return $size; # near zero, or negative
|
return $size; # near zero, or negative
|
||||||
} #}}}
|
}
|
||||||
|
|
||||||
package IkiWiki::PageSpec;
|
package IkiWiki::PageSpec;
|
||||||
|
|
||||||
sub match_maxsize ($$;@) { #{{{
|
sub match_maxsize ($$;@) {
|
||||||
my $page=shift;
|
my $page=shift;
|
||||||
my $maxsize=eval{IkiWiki::Plugin::filecheck::parsesize(shift)};
|
my $maxsize=eval{IkiWiki::Plugin::filecheck::parsesize(shift)};
|
||||||
if ($@) {
|
if ($@) {
|
||||||
|
@ -86,9 +86,9 @@ sub match_maxsize ($$;@) { #{{{
|
||||||
else {
|
else {
|
||||||
return IkiWiki::SuccessReason->new("file not too large");
|
return IkiWiki::SuccessReason->new("file not too large");
|
||||||
}
|
}
|
||||||
} #}}}
|
}
|
||||||
|
|
||||||
sub match_minsize ($$;@) { #{{{
|
sub match_minsize ($$;@) {
|
||||||
my $page=shift;
|
my $page=shift;
|
||||||
my $minsize=eval{IkiWiki::Plugin::filecheck::parsesize(shift)};
|
my $minsize=eval{IkiWiki::Plugin::filecheck::parsesize(shift)};
|
||||||
if ($@) {
|
if ($@) {
|
||||||
|
@ -107,9 +107,9 @@ sub match_minsize ($$;@) { #{{{
|
||||||
else {
|
else {
|
||||||
return IkiWiki::SuccessReason->new("file not too small");
|
return IkiWiki::SuccessReason->new("file not too small");
|
||||||
}
|
}
|
||||||
} #}}}
|
}
|
||||||
|
|
||||||
sub match_mimetype ($$;@) { #{{{
|
sub match_mimetype ($$;@) {
|
||||||
my $page=shift;
|
my $page=shift;
|
||||||
my $wanted=shift;
|
my $wanted=shift;
|
||||||
|
|
||||||
|
@ -140,9 +140,9 @@ sub match_mimetype ($$;@) { #{{{
|
||||||
else {
|
else {
|
||||||
return IkiWiki::SuccessReason->new("file MIME type is $mimetype");
|
return IkiWiki::SuccessReason->new("file MIME type is $mimetype");
|
||||||
}
|
}
|
||||||
} #}}}
|
}
|
||||||
|
|
||||||
sub match_virusfree ($$;@) { #{{{
|
sub match_virusfree ($$;@) {
|
||||||
my $page=shift;
|
my $page=shift;
|
||||||
my $wanted=shift;
|
my $wanted=shift;
|
||||||
|
|
||||||
|
@ -182,9 +182,9 @@ sub match_virusfree ($$;@) { #{{{
|
||||||
else {
|
else {
|
||||||
return IkiWiki::SuccessReason->new("file seems virusfree ($reason)");
|
return IkiWiki::SuccessReason->new("file seems virusfree ($reason)");
|
||||||
}
|
}
|
||||||
} #}}}
|
}
|
||||||
|
|
||||||
sub match_ispage ($$;@) { #{{{
|
sub match_ispage ($$;@) {
|
||||||
my $filename=shift;
|
my $filename=shift;
|
||||||
|
|
||||||
if (defined IkiWiki::pagetype($filename)) {
|
if (defined IkiWiki::pagetype($filename)) {
|
||||||
|
@ -193,4 +193,4 @@ sub match_ispage ($$;@) { #{{{
|
||||||
else {
|
else {
|
||||||
return IkiWiki::FailReason->new("file is not a wiki page");
|
return IkiWiki::FailReason->new("file is not a wiki page");
|
||||||
}
|
}
|
||||||
} #}}}
|
}
|
||||||
|
|
|
@ -0,0 +1,30 @@
|
||||||
|
#!/usr/bin/perl
|
||||||
|
package IkiWiki::Plugin::format;
|
||||||
|
|
||||||
|
use warnings;
|
||||||
|
use strict;
|
||||||
|
use IkiWiki 3.00;
|
||||||
|
|
||||||
|
sub import {
|
||||||
|
hook(type => "preprocess", id => "format", call => \&preprocess);
|
||||||
|
}
|
||||||
|
|
||||||
|
sub preprocess (@) {
|
||||||
|
my $format=$_[0];
|
||||||
|
shift; shift;
|
||||||
|
my $text=$_[0];
|
||||||
|
shift; shift;
|
||||||
|
my %params=@_;
|
||||||
|
|
||||||
|
if (! defined $format || ! defined $text) {
|
||||||
|
error(gettext("must specify format and text"));
|
||||||
|
}
|
||||||
|
elsif (! exists $IkiWiki::hooks{htmlize}{$format}) {
|
||||||
|
error(sprintf(gettext("unsupported page format %s"), $format));
|
||||||
|
}
|
||||||
|
|
||||||
|
return IkiWiki::htmlize($params{page}, $params{destpage}, $format,
|
||||||
|
IkiWiki::preprocess($params{page}, $params{destpage}, $text));
|
||||||
|
}
|
||||||
|
|
||||||
|
1
|
|
@ -4,22 +4,22 @@ package IkiWiki::Plugin::fortune;
|
||||||
|
|
||||||
use warnings;
|
use warnings;
|
||||||
use strict;
|
use strict;
|
||||||
use IkiWiki 2.00;
|
use IkiWiki 3.00;
|
||||||
|
|
||||||
sub import { #{{{
|
sub import {
|
||||||
hook(type => "getsetup", id => "fortune", call => \&getsetup);
|
hook(type => "getsetup", id => "fortune", call => \&getsetup);
|
||||||
hook(type => "preprocess", id => "fortune", call => \&preprocess);
|
hook(type => "preprocess", id => "fortune", call => \&preprocess);
|
||||||
} # }}}
|
}
|
||||||
|
|
||||||
sub getsetup () { #{{{
|
sub getsetup () {
|
||||||
return
|
return
|
||||||
plugin => {
|
plugin => {
|
||||||
safe => 1,
|
safe => 1,
|
||||||
rebuild => undef,
|
rebuild => undef,
|
||||||
},
|
},
|
||||||
} #}}}
|
}
|
||||||
|
|
||||||
sub preprocess (@) { #{{{
|
sub preprocess (@) {
|
||||||
$ENV{PATH}="$ENV{PATH}:/usr/games:/usr/local/games";
|
$ENV{PATH}="$ENV{PATH}:/usr/games:/usr/local/games";
|
||||||
my $f = `fortune 2>/dev/null`;
|
my $f = `fortune 2>/dev/null`;
|
||||||
|
|
||||||
|
@ -29,6 +29,6 @@ sub preprocess (@) { #{{{
|
||||||
else {
|
else {
|
||||||
return "<pre>$f</pre>\n";
|
return "<pre>$f</pre>\n";
|
||||||
}
|
}
|
||||||
} # }}}
|
}
|
||||||
|
|
||||||
1
|
1
|
||||||
|
|
|
@ -9,8 +9,9 @@ use open qw{:utf8 :std};
|
||||||
|
|
||||||
my $sha1_pattern = qr/[0-9a-fA-F]{40}/; # pattern to validate Git sha1sums
|
my $sha1_pattern = qr/[0-9a-fA-F]{40}/; # pattern to validate Git sha1sums
|
||||||
my $dummy_commit_msg = 'dummy commit'; # message to skip in recent changes
|
my $dummy_commit_msg = 'dummy commit'; # message to skip in recent changes
|
||||||
|
my $no_chdir=0;
|
||||||
|
|
||||||
sub import { #{{{
|
sub import {
|
||||||
hook(type => "checkconfig", id => "git", call => \&checkconfig);
|
hook(type => "checkconfig", id => "git", call => \&checkconfig);
|
||||||
hook(type => "getsetup", id => "git", call => \&getsetup);
|
hook(type => "getsetup", id => "git", call => \&getsetup);
|
||||||
hook(type => "rcs", id => "rcs_update", call => \&rcs_update);
|
hook(type => "rcs", id => "rcs_update", call => \&rcs_update);
|
||||||
|
@ -23,24 +24,34 @@ sub import { #{{{
|
||||||
hook(type => "rcs", id => "rcs_recentchanges", call => \&rcs_recentchanges);
|
hook(type => "rcs", id => "rcs_recentchanges", call => \&rcs_recentchanges);
|
||||||
hook(type => "rcs", id => "rcs_diff", call => \&rcs_diff);
|
hook(type => "rcs", id => "rcs_diff", call => \&rcs_diff);
|
||||||
hook(type => "rcs", id => "rcs_getctime", call => \&rcs_getctime);
|
hook(type => "rcs", id => "rcs_getctime", call => \&rcs_getctime);
|
||||||
} #}}}
|
hook(type => "rcs", id => "rcs_receive", call => \&rcs_receive);
|
||||||
|
}
|
||||||
|
|
||||||
sub checkconfig () { #{{{
|
sub checkconfig () {
|
||||||
if (! defined $config{gitorigin_branch}) {
|
if (! defined $config{gitorigin_branch}) {
|
||||||
$config{gitorigin_branch}="origin";
|
$config{gitorigin_branch}="origin";
|
||||||
}
|
}
|
||||||
if (! defined $config{gitmaster_branch}) {
|
if (! defined $config{gitmaster_branch}) {
|
||||||
$config{gitmaster_branch}="master";
|
$config{gitmaster_branch}="master";
|
||||||
}
|
}
|
||||||
if (defined $config{git_wrapper} && length $config{git_wrapper}) {
|
if (defined $config{git_wrapper} &&
|
||||||
|
length $config{git_wrapper}) {
|
||||||
push @{$config{wrappers}}, {
|
push @{$config{wrappers}}, {
|
||||||
wrapper => $config{git_wrapper},
|
wrapper => $config{git_wrapper},
|
||||||
wrappermode => (defined $config{git_wrappermode} ? $config{git_wrappermode} : "06755"),
|
wrappermode => (defined $config{git_wrappermode} ? $config{git_wrappermode} : "06755"),
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
} #}}}
|
if (defined $config{git_test_receive_wrapper} &&
|
||||||
|
length $config{git_test_receive_wrapper}) {
|
||||||
|
push @{$config{wrappers}}, {
|
||||||
|
test_receive => 1,
|
||||||
|
wrapper => $config{git_test_receive_wrapper},
|
||||||
|
wrappermode => (defined $config{git_wrappermode} ? $config{git_wrappermode} : "06755"),
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
sub getsetup () { #{{{
|
sub getsetup () {
|
||||||
return
|
return
|
||||||
plugin => {
|
plugin => {
|
||||||
safe => 0, # rcs plugin
|
safe => 0, # rcs plugin
|
||||||
|
@ -60,6 +71,20 @@ sub getsetup () { #{{{
|
||||||
safe => 0,
|
safe => 0,
|
||||||
rebuild => 0,
|
rebuild => 0,
|
||||||
},
|
},
|
||||||
|
git_test_receive_wrapper => {
|
||||||
|
type => "string",
|
||||||
|
example => "/git/wiki.git/hooks/pre-receive",
|
||||||
|
description => "git pre-receive hook to generate",
|
||||||
|
safe => 0, # file
|
||||||
|
rebuild => 0,
|
||||||
|
},
|
||||||
|
untrusted_committers => {
|
||||||
|
type => "string",
|
||||||
|
example => [],
|
||||||
|
description => "unix users whose commits should be checked by the pre-receive hook",
|
||||||
|
safe => 0,
|
||||||
|
rebuild => 0,
|
||||||
|
},
|
||||||
historyurl => {
|
historyurl => {
|
||||||
type => "string",
|
type => "string",
|
||||||
example => "http://git.example.com/gitweb.cgi?p=wiki.git;a=history;f=[[file]]",
|
example => "http://git.example.com/gitweb.cgi?p=wiki.git;a=history;f=[[file]]",
|
||||||
|
@ -69,8 +94,8 @@ sub getsetup () { #{{{
|
||||||
},
|
},
|
||||||
diffurl => {
|
diffurl => {
|
||||||
type => "string",
|
type => "string",
|
||||||
example => "http://git.example.com/gitweb.cgi?p=wiki.git;a=blobdiff;h=[[sha1_to]];hp=[[sha1_from]];hb=[[sha1_parent]];f=[[file]]",
|
example => "http://git.example.com/gitweb.cgi?p=wiki.git;a=blobdiff;f=[[file]];h=[[sha1_to]];hp=[[sha1_from]];hb=[[sha1_commit]];hpb=[[sha1_parent]]",
|
||||||
description => "gitweb url to show a diff ([[sha1_to]], [[sha1_from]], [[sha1_parent]], and [[file]] substituted)",
|
description => "gitweb url to show a diff ([[file]], [[sha1_to]], [[sha1_from]], [[sha1_commit]], and [[sha1_parent]] substituted)",
|
||||||
safe => 1,
|
safe => 1,
|
||||||
rebuild => 1,
|
rebuild => 1,
|
||||||
},
|
},
|
||||||
|
@ -88,9 +113,9 @@ sub getsetup () { #{{{
|
||||||
safe => 0, # paranoia
|
safe => 0, # paranoia
|
||||||
rebuild => 0,
|
rebuild => 0,
|
||||||
},
|
},
|
||||||
} #}}}
|
}
|
||||||
|
|
||||||
sub safe_git (&@) { #{{{
|
sub safe_git (&@) {
|
||||||
# Start a child process safely without resorting /bin/sh.
|
# Start a child process safely without resorting /bin/sh.
|
||||||
# Return command output or success state (in scalar context).
|
# Return command output or success state (in scalar context).
|
||||||
|
|
||||||
|
@ -103,15 +128,25 @@ sub safe_git (&@) { #{{{
|
||||||
if (!$pid) {
|
if (!$pid) {
|
||||||
# In child.
|
# In child.
|
||||||
# Git commands want to be in wc.
|
# Git commands want to be in wc.
|
||||||
chdir $config{srcdir}
|
if (! $no_chdir) {
|
||||||
or error("Cannot chdir to $config{srcdir}: $!");
|
chdir $config{srcdir}
|
||||||
|
or error("Cannot chdir to $config{srcdir}: $!");
|
||||||
|
}
|
||||||
exec @cmdline or error("Cannot exec '@cmdline': $!");
|
exec @cmdline or error("Cannot exec '@cmdline': $!");
|
||||||
}
|
}
|
||||||
# In parent.
|
# In parent.
|
||||||
|
|
||||||
|
# git output is probably utf-8 encoded, but may contain
|
||||||
|
# other encodings or invalidly encoded stuff. So do not rely
|
||||||
|
# on the normal utf-8 IO layer, decode it by hand.
|
||||||
|
binmode($OUT);
|
||||||
|
|
||||||
my @lines;
|
my @lines;
|
||||||
while (<$OUT>) {
|
while (<$OUT>) {
|
||||||
|
$_=decode_utf8($_, 0);
|
||||||
|
|
||||||
chomp;
|
chomp;
|
||||||
|
|
||||||
push @lines, $_;
|
push @lines, $_;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -125,9 +160,9 @@ sub safe_git (&@) { #{{{
|
||||||
sub run_or_die ($@) { safe_git(\&error, @_) }
|
sub run_or_die ($@) { safe_git(\&error, @_) }
|
||||||
sub run_or_cry ($@) { safe_git(sub { warn @_ }, @_) }
|
sub run_or_cry ($@) { safe_git(sub { warn @_ }, @_) }
|
||||||
sub run_or_non ($@) { safe_git(undef, @_) }
|
sub run_or_non ($@) { safe_git(undef, @_) }
|
||||||
#}}}
|
|
||||||
|
|
||||||
sub merge_past ($$$) { #{{{
|
|
||||||
|
sub merge_past ($$$) {
|
||||||
# Unlike with Subversion, Git cannot make a 'svn merge -rN:M file'.
|
# Unlike with Subversion, Git cannot make a 'svn merge -rN:M file'.
|
||||||
# Git merge commands work with the committed changes, except in the
|
# Git merge commands work with the committed changes, except in the
|
||||||
# implicit case of '-m' of git checkout(1). So we should invent a
|
# implicit case of '-m' of git checkout(1). So we should invent a
|
||||||
|
@ -219,9 +254,9 @@ sub merge_past ($$$) { #{{{
|
||||||
error("Git merge failed!\n$failure\n") if $failure;
|
error("Git merge failed!\n$failure\n") if $failure;
|
||||||
|
|
||||||
return $conflict;
|
return $conflict;
|
||||||
} #}}}
|
}
|
||||||
|
|
||||||
sub parse_diff_tree ($@) { #{{{
|
sub parse_diff_tree ($@) {
|
||||||
# Parse the raw diff tree chunk and return the info hash.
|
# Parse the raw diff tree chunk and return the info hash.
|
||||||
# See git-diff-tree(1) for the syntax.
|
# See git-diff-tree(1) for the syntax.
|
||||||
|
|
||||||
|
@ -320,6 +355,9 @@ sub parse_diff_tree ($@) { #{{{
|
||||||
'file' => decode("utf8", $file),
|
'file' => decode("utf8", $file),
|
||||||
'sha1_from' => $sha1_from[0],
|
'sha1_from' => $sha1_from[0],
|
||||||
'sha1_to' => $sha1_to,
|
'sha1_to' => $sha1_to,
|
||||||
|
'mode_from' => $mode_from[0],
|
||||||
|
'mode_to' => $mode_to,
|
||||||
|
'status' => $status,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
next;
|
next;
|
||||||
|
@ -328,17 +366,17 @@ sub parse_diff_tree ($@) { #{{{
|
||||||
}
|
}
|
||||||
|
|
||||||
return \%ci;
|
return \%ci;
|
||||||
} #}}}
|
}
|
||||||
|
|
||||||
sub git_commit_info ($;$) { #{{{
|
sub git_commit_info ($;$) {
|
||||||
# Return an array of commit info hashes of num commits (default: 1)
|
# Return an array of commit info hashes of num commits
|
||||||
# starting from the given sha1sum.
|
# starting from the given sha1sum.
|
||||||
|
|
||||||
my ($sha1, $num) = @_;
|
my ($sha1, $num) = @_;
|
||||||
|
|
||||||
$num ||= 1;
|
my @opts;
|
||||||
|
push @opts, "--max-count=$num" if defined $num;
|
||||||
|
|
||||||
my @raw_lines = run_or_die('git', 'log', "--max-count=$num",
|
my @raw_lines = run_or_die('git', 'log', @opts,
|
||||||
'--pretty=raw', '--raw', '--abbrev=40', '--always', '-c',
|
'--pretty=raw', '--raw', '--abbrev=40', '--always', '-c',
|
||||||
'-r', $sha1, '--', '.');
|
'-r', $sha1, '--', '.');
|
||||||
my ($prefix) = run_or_die('git', 'rev-parse', '--show-prefix');
|
my ($prefix) = run_or_die('git', 'rev-parse', '--show-prefix');
|
||||||
|
@ -351,11 +389,10 @@ sub git_commit_info ($;$) { #{{{
|
||||||
warn "Cannot parse commit info for '$sha1' commit" if !@ci;
|
warn "Cannot parse commit info for '$sha1' commit" if !@ci;
|
||||||
|
|
||||||
return wantarray ? @ci : $ci[0];
|
return wantarray ? @ci : $ci[0];
|
||||||
} #}}}
|
}
|
||||||
|
|
||||||
sub git_sha1 (;$) { #{{{
|
sub git_sha1 (;$) {
|
||||||
# Return head sha1sum (of given file).
|
# Return head sha1sum (of given file).
|
||||||
|
|
||||||
my $file = shift || q{--};
|
my $file = shift || q{--};
|
||||||
|
|
||||||
# Ignore error since a non-existing file might be given.
|
# Ignore error since a non-existing file might be given.
|
||||||
|
@ -365,26 +402,25 @@ sub git_sha1 (;$) { #{{{
|
||||||
($sha1) = $sha1 =~ m/($sha1_pattern)/; # sha1 is untainted now
|
($sha1) = $sha1 =~ m/($sha1_pattern)/; # sha1 is untainted now
|
||||||
} else { debug("Empty sha1sum for '$file'.") }
|
} else { debug("Empty sha1sum for '$file'.") }
|
||||||
return defined $sha1 ? $sha1 : q{};
|
return defined $sha1 ? $sha1 : q{};
|
||||||
} #}}}
|
}
|
||||||
|
|
||||||
sub rcs_update () { #{{{
|
sub rcs_update () {
|
||||||
# Update working directory.
|
# Update working directory.
|
||||||
|
|
||||||
if (length $config{gitorigin_branch}) {
|
if (length $config{gitorigin_branch}) {
|
||||||
run_or_cry('git', 'pull', $config{gitorigin_branch});
|
run_or_cry('git', 'pull', $config{gitorigin_branch});
|
||||||
}
|
}
|
||||||
} #}}}
|
}
|
||||||
|
|
||||||
sub rcs_prepedit ($) { #{{{
|
sub rcs_prepedit ($) {
|
||||||
# Return the commit sha1sum of the file when editing begins.
|
# Return the commit sha1sum of the file when editing begins.
|
||||||
# This will be later used in rcs_commit if a merge is required.
|
# This will be later used in rcs_commit if a merge is required.
|
||||||
|
|
||||||
my ($file) = @_;
|
my ($file) = @_;
|
||||||
|
|
||||||
return git_sha1($file);
|
return git_sha1($file);
|
||||||
} #}}}
|
}
|
||||||
|
|
||||||
sub rcs_commit ($$$;$$) { #{{{
|
sub rcs_commit ($$$;$$) {
|
||||||
# Try to commit the page; returns undef on _success_ and
|
# Try to commit the page; returns undef on _success_ and
|
||||||
# a version of the page with the rcs's conflict markers on
|
# a version of the page with the rcs's conflict markers on
|
||||||
# failure.
|
# failure.
|
||||||
|
@ -403,7 +439,7 @@ sub rcs_commit ($$$;$$) { #{{{
|
||||||
|
|
||||||
rcs_add($file);
|
rcs_add($file);
|
||||||
return rcs_commit_staged($message, $user, $ipaddr);
|
return rcs_commit_staged($message, $user, $ipaddr);
|
||||||
} #}}}
|
}
|
||||||
|
|
||||||
sub rcs_commit_staged ($$$) {
|
sub rcs_commit_staged ($$$) {
|
||||||
# Commits all staged changes. Changes can be staged using rcs_add,
|
# Commits all staged changes. Changes can be staged using rcs_add,
|
||||||
|
@ -413,7 +449,7 @@ sub rcs_commit_staged ($$$) {
|
||||||
# Set the commit author and email to the web committer.
|
# Set the commit author and email to the web committer.
|
||||||
my %env=%ENV;
|
my %env=%ENV;
|
||||||
if (defined $user || defined $ipaddr) {
|
if (defined $user || defined $ipaddr) {
|
||||||
my $u=defined $user ? $user : $ipaddr;
|
my $u=encode_utf8(defined $user ? $user : $ipaddr);
|
||||||
$ENV{GIT_AUTHOR_NAME}=$u;
|
$ENV{GIT_AUTHOR_NAME}=$u;
|
||||||
$ENV{GIT_AUTHOR_EMAIL}="$u\@web";
|
$ENV{GIT_AUTHOR_EMAIL}="$u\@web";
|
||||||
}
|
}
|
||||||
|
@ -444,29 +480,29 @@ sub rcs_commit_staged ($$$) {
|
||||||
return undef; # success
|
return undef; # success
|
||||||
}
|
}
|
||||||
|
|
||||||
sub rcs_add ($) { # {{{
|
sub rcs_add ($) {
|
||||||
# Add file to archive.
|
# Add file to archive.
|
||||||
|
|
||||||
my ($file) = @_;
|
my ($file) = @_;
|
||||||
|
|
||||||
run_or_cry('git', 'add', $file);
|
run_or_cry('git', 'add', $file);
|
||||||
} #}}}
|
}
|
||||||
|
|
||||||
sub rcs_remove ($) { # {{{
|
sub rcs_remove ($) {
|
||||||
# Remove file from archive.
|
# Remove file from archive.
|
||||||
|
|
||||||
my ($file) = @_;
|
my ($file) = @_;
|
||||||
|
|
||||||
run_or_cry('git', 'rm', '-f', $file);
|
run_or_cry('git', 'rm', '-f', $file);
|
||||||
} #}}}
|
}
|
||||||
|
|
||||||
sub rcs_rename ($$) { # {{{
|
sub rcs_rename ($$) {
|
||||||
my ($src, $dest) = @_;
|
my ($src, $dest) = @_;
|
||||||
|
|
||||||
run_or_cry('git', 'mv', '-f', $src, $dest);
|
run_or_cry('git', 'mv', '-f', $src, $dest);
|
||||||
} #}}}
|
}
|
||||||
|
|
||||||
sub rcs_recentchanges ($) { #{{{
|
sub rcs_recentchanges ($) {
|
||||||
# List of recent changes.
|
# List of recent changes.
|
||||||
|
|
||||||
my ($num) = @_;
|
my ($num) = @_;
|
||||||
|
@ -475,7 +511,7 @@ sub rcs_recentchanges ($) { #{{{
|
||||||
error($@) if $@;
|
error($@) if $@;
|
||||||
|
|
||||||
my @rets;
|
my @rets;
|
||||||
foreach my $ci (git_commit_info('HEAD', $num)) {
|
foreach my $ci (git_commit_info('HEAD', $num || 1)) {
|
||||||
# Skip redundant commits.
|
# Skip redundant commits.
|
||||||
next if ($ci->{'comment'} && @{$ci->{'comment'}}[0] eq $dummy_commit_msg);
|
next if ($ci->{'comment'} && @{$ci->{'comment'}}[0] eq $dummy_commit_msg);
|
||||||
|
|
||||||
|
@ -493,6 +529,7 @@ sub rcs_recentchanges ($) { #{{{
|
||||||
$diffurl =~ s/\[\[sha1_parent\]\]/$ci->{'parent'}/go;
|
$diffurl =~ s/\[\[sha1_parent\]\]/$ci->{'parent'}/go;
|
||||||
$diffurl =~ s/\[\[sha1_from\]\]/$detail->{'sha1_from'}/go;
|
$diffurl =~ s/\[\[sha1_from\]\]/$detail->{'sha1_from'}/go;
|
||||||
$diffurl =~ s/\[\[sha1_to\]\]/$detail->{'sha1_to'}/go;
|
$diffurl =~ s/\[\[sha1_to\]\]/$detail->{'sha1_to'}/go;
|
||||||
|
$diffurl =~ s/\[\[sha1_commit\]\]/$sha1/go;
|
||||||
|
|
||||||
push @pages, {
|
push @pages, {
|
||||||
page => pagename($file),
|
page => pagename($file),
|
||||||
|
@ -533,9 +570,9 @@ sub rcs_recentchanges ($) { #{{{
|
||||||
}
|
}
|
||||||
|
|
||||||
return @rets;
|
return @rets;
|
||||||
} #}}}
|
}
|
||||||
|
|
||||||
sub rcs_diff ($) { #{{{
|
sub rcs_diff ($) {
|
||||||
my $rev=shift;
|
my $rev=shift;
|
||||||
my ($sha1) = $rev =~ /^($sha1_pattern)$/; # untaint
|
my ($sha1) = $rev =~ /^($sha1_pattern)$/; # untaint
|
||||||
my @lines;
|
my @lines;
|
||||||
|
@ -550,19 +587,112 @@ sub rcs_diff ($) { #{{{
|
||||||
else {
|
else {
|
||||||
return join("", @lines);
|
return join("", @lines);
|
||||||
}
|
}
|
||||||
} #}}}
|
}
|
||||||
|
|
||||||
sub rcs_getctime ($) { #{{{
|
sub rcs_getctime ($) {
|
||||||
my $file=shift;
|
my $file=shift;
|
||||||
# Remove srcdir prefix
|
# Remove srcdir prefix
|
||||||
$file =~ s/^\Q$config{srcdir}\E\/?//;
|
$file =~ s/^\Q$config{srcdir}\E\/?//;
|
||||||
|
|
||||||
my $sha1 = git_sha1($file);
|
my @sha1s = run_or_non('git', 'rev-list', 'HEAD', '--', $file);
|
||||||
my $ci = git_commit_info($sha1);
|
my $ci = git_commit_info($sha1s[$#sha1s], 1);
|
||||||
my $ctime = $ci->{'author_epoch'};
|
my $ctime = $ci->{'author_epoch'};
|
||||||
debug("ctime for '$file': ". localtime($ctime));
|
debug("ctime for '$file': ". localtime($ctime));
|
||||||
|
|
||||||
return $ctime;
|
return $ctime;
|
||||||
} #}}}
|
}
|
||||||
|
|
||||||
|
sub rcs_receive () {
|
||||||
|
# The wiki may not be the only thing in the git repo.
|
||||||
|
# Determine if it is in a subdirectory by examining the srcdir,
|
||||||
|
# and its parents, looking for the .git directory.
|
||||||
|
my $subdir="";
|
||||||
|
my $dir=$config{srcdir};
|
||||||
|
while (! -d "$dir/.git") {
|
||||||
|
$subdir=IkiWiki::basename($dir)."/".$subdir;
|
||||||
|
$dir=IkiWiki::dirname($dir);
|
||||||
|
if (! length $dir) {
|
||||||
|
error("cannot determine root of git repo");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
my @rets;
|
||||||
|
while (<>) {
|
||||||
|
chomp;
|
||||||
|
my ($oldrev, $newrev, $refname) = split(' ', $_, 3);
|
||||||
|
|
||||||
|
# only allow changes to gitmaster_branch
|
||||||
|
if ($refname !~ /^refs\/heads\/\Q$config{gitmaster_branch}\E$/) {
|
||||||
|
error sprintf(gettext("you are not allowed to change %s"), $refname);
|
||||||
|
}
|
||||||
|
|
||||||
|
# Avoid chdir when running git here, because the changes
|
||||||
|
# are in the master git repo, not the srcdir repo.
|
||||||
|
# The pre-recieve hook already puts us in the right place.
|
||||||
|
$no_chdir=1;
|
||||||
|
my @changes=git_commit_info($oldrev."..".$newrev);
|
||||||
|
$no_chdir=0;
|
||||||
|
|
||||||
|
foreach my $ci (@changes) {
|
||||||
|
foreach my $detail (@{ $ci->{'details'} }) {
|
||||||
|
my $file = $detail->{'file'};
|
||||||
|
|
||||||
|
# check that all changed files are in the
|
||||||
|
# subdir
|
||||||
|
if (length $subdir &&
|
||||||
|
! ($file =~ s/^\Q$subdir\E//)) {
|
||||||
|
error sprintf(gettext("you are not allowed to change %s"), $file);
|
||||||
|
}
|
||||||
|
|
||||||
|
my ($action, $mode, $path);
|
||||||
|
if ($detail->{'status'} =~ /^[M]+\d*$/) {
|
||||||
|
$action="change";
|
||||||
|
$mode=$detail->{'mode_to'};
|
||||||
|
}
|
||||||
|
elsif ($detail->{'status'} =~ /^[AM]+\d*$/) {
|
||||||
|
$action="add";
|
||||||
|
$mode=$detail->{'mode_to'};
|
||||||
|
}
|
||||||
|
elsif ($detail->{'status'} =~ /^[DAM]+\d*/) {
|
||||||
|
$action="remove";
|
||||||
|
$mode=$detail->{'mode_from'};
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
error "unknown status ".$detail->{'status'};
|
||||||
|
}
|
||||||
|
|
||||||
|
# test that the file mode is ok
|
||||||
|
if ($mode !~ /^100[64][64][64]$/) {
|
||||||
|
error sprintf(gettext("you cannot act on a file with mode %s"), $mode);
|
||||||
|
}
|
||||||
|
if ($action eq "change") {
|
||||||
|
if ($detail->{'mode_from'} ne $detail->{'mode_to'}) {
|
||||||
|
error gettext("you are not allowed to change file modes");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
# extract attachment to temp file
|
||||||
|
if (($action eq 'add' || $action eq 'change') &&
|
||||||
|
! pagetype($file)) {
|
||||||
|
eval q{use File::Temp};
|
||||||
|
die $@ if $@;
|
||||||
|
my $fh;
|
||||||
|
($fh, $path)=File::Temp::tempfile("XXXXXXXXXX", UNLINK => 1);
|
||||||
|
if (system("git show ".$detail->{sha1_to}." > '$path'") != 0) {
|
||||||
|
error("failed writing temp file");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
push @rets, {
|
||||||
|
file => $file,
|
||||||
|
action => $action,
|
||||||
|
path => $path,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return reverse @rets;
|
||||||
|
}
|
||||||
|
|
||||||
1
|
1
|
||||||
|
|
|
@ -4,13 +4,12 @@ package IkiWiki::Plugin::goodstuff;
|
||||||
|
|
||||||
use warnings;
|
use warnings;
|
||||||
use strict;
|
use strict;
|
||||||
use IkiWiki 2.00;
|
use IkiWiki 3.00;
|
||||||
|
|
||||||
my @bundle=qw{
|
my @bundle=qw{
|
||||||
brokenlinks
|
brokenlinks
|
||||||
img
|
img
|
||||||
map
|
map
|
||||||
meta
|
|
||||||
more
|
more
|
||||||
orphans
|
orphans
|
||||||
pagecount
|
pagecount
|
||||||
|
@ -23,21 +22,22 @@ my @bundle=qw{
|
||||||
template
|
template
|
||||||
toc
|
toc
|
||||||
toggle
|
toggle
|
||||||
|
repolist
|
||||||
};
|
};
|
||||||
|
|
||||||
sub import { #{{{
|
sub import {
|
||||||
hook(type => "getsetup", id => "goodstuff", call => \&getsetup);
|
hook(type => "getsetup", id => "goodstuff", call => \&getsetup);
|
||||||
foreach my $plugin (@bundle) {
|
foreach my $plugin (@bundle) {
|
||||||
IkiWiki::loadplugin($plugin);
|
IkiWiki::loadplugin($plugin);
|
||||||
}
|
}
|
||||||
} # }}}
|
}
|
||||||
|
|
||||||
sub getsetup { #{{{
|
sub getsetup {
|
||||||
return
|
return
|
||||||
plugin => {
|
plugin => {
|
||||||
safe => 1,
|
safe => 1,
|
||||||
rebuild => undef,
|
rebuild => undef,
|
||||||
},
|
},
|
||||||
} #}}}
|
}
|
||||||
|
|
||||||
1
|
1
|
||||||
|
|
|
@ -3,26 +3,26 @@ package IkiWiki::Plugin::google;
|
||||||
|
|
||||||
use warnings;
|
use warnings;
|
||||||
use strict;
|
use strict;
|
||||||
use IkiWiki 2.00;
|
use IkiWiki 3.00;
|
||||||
use URI;
|
use URI;
|
||||||
|
|
||||||
my $host;
|
my $host;
|
||||||
|
|
||||||
sub import { #{{{
|
sub import {
|
||||||
hook(type => "getsetup", id => "google", call => \&getsetup);
|
hook(type => "getsetup", id => "google", call => \&getsetup);
|
||||||
hook(type => "checkconfig", id => "google", call => \&checkconfig);
|
hook(type => "checkconfig", id => "google", call => \&checkconfig);
|
||||||
hook(type => "pagetemplate", id => "google", call => \&pagetemplate);
|
hook(type => "pagetemplate", id => "google", call => \&pagetemplate);
|
||||||
} # }}}
|
}
|
||||||
|
|
||||||
sub getsetup () { #{{{
|
sub getsetup () {
|
||||||
return
|
return
|
||||||
plugin => {
|
plugin => {
|
||||||
safe => 1,
|
safe => 1,
|
||||||
rebuild => 1,
|
rebuild => 1,
|
||||||
},
|
},
|
||||||
} #}}}
|
}
|
||||||
|
|
||||||
sub checkconfig () { #{{{
|
sub checkconfig () {
|
||||||
if (! length $config{url}) {
|
if (! length $config{url}) {
|
||||||
error(sprintf(gettext("Must specify %s when using the google search plugin"), "url"));
|
error(sprintf(gettext("Must specify %s when using the google search plugin"), "url"));
|
||||||
}
|
}
|
||||||
|
@ -31,10 +31,10 @@ sub checkconfig () { #{{{
|
||||||
error(gettext("Failed to parse url, cannot determine domain name"));
|
error(gettext("Failed to parse url, cannot determine domain name"));
|
||||||
}
|
}
|
||||||
$host=$uri->host;
|
$host=$uri->host;
|
||||||
} #}}}
|
}
|
||||||
|
|
||||||
my $form;
|
my $form;
|
||||||
sub pagetemplate (@) { #{{{
|
sub pagetemplate (@) {
|
||||||
my %params=@_;
|
my %params=@_;
|
||||||
my $page=$params{page};
|
my $page=$params{page};
|
||||||
my $template=$params{template};
|
my $template=$params{template};
|
||||||
|
@ -49,6 +49,6 @@ sub pagetemplate (@) { #{{{
|
||||||
|
|
||||||
$template->param(searchform => $form);
|
$template->param(searchform => $form);
|
||||||
}
|
}
|
||||||
} #}}}
|
}
|
||||||
|
|
||||||
1
|
1
|
||||||
|
|
|
@ -1,55 +0,0 @@
|
||||||
#!/usr/bin/perl
|
|
||||||
package IkiWiki::Plugin::googlecalendar;
|
|
||||||
|
|
||||||
use warnings;
|
|
||||||
use strict;
|
|
||||||
use IkiWiki 2.00;
|
|
||||||
|
|
||||||
sub import { #{{{
|
|
||||||
hook(type => "getsetup", id => "googlecalendar",
|
|
||||||
call => \&getsetup);
|
|
||||||
hook(type => "preprocess", id => "googlecalendar",
|
|
||||||
call => \&preprocess);
|
|
||||||
hook(type => "format", id => "googlecalendar",
|
|
||||||
call => \&format);
|
|
||||||
} # }}}
|
|
||||||
|
|
||||||
sub getsetup () { #{{{
|
|
||||||
return
|
|
||||||
plugin => {
|
|
||||||
safe => 1,
|
|
||||||
rebuild => undef,
|
|
||||||
},
|
|
||||||
} #}}}
|
|
||||||
|
|
||||||
sub preprocess (@) { #{{{
|
|
||||||
my %params=@_;
|
|
||||||
|
|
||||||
# Parse the html, looking for the url to embed for the calendar.
|
|
||||||
# Avoid XSS attacks..
|
|
||||||
my ($url)=$params{html}=~m#iframe\s+src="http://www\.google\.com/calendar/embed\?([^"<>]+)"#;
|
|
||||||
if (! defined $url || ! length $url) {
|
|
||||||
error gettext("failed to find url in html")
|
|
||||||
}
|
|
||||||
my ($height)=$params{html}=~m#height="(\d+)"#;
|
|
||||||
my ($width)=$params{html}=~m#width="(\d+)"#;
|
|
||||||
|
|
||||||
return "<div class=\"googlecalendar\" src=\"$url\" height=\"$height\" width=\"$width\"></div>";
|
|
||||||
} # }}}
|
|
||||||
|
|
||||||
sub format (@) { #{{{
|
|
||||||
my %params=@_;
|
|
||||||
|
|
||||||
$params{content}=~s/<div class=\"googlecalendar" src="([^"]+)" height="([^"]+)" width="([^"]+)"><\/div>/gencal($1,$2,$3)/eg;
|
|
||||||
|
|
||||||
return $params{content};
|
|
||||||
} # }}}
|
|
||||||
|
|
||||||
sub gencal ($$$) { #{{{
|
|
||||||
my $url=shift;
|
|
||||||
my $height=shift;
|
|
||||||
my $width=shift;
|
|
||||||
return qq{<iframe src="http://www.google.com/calendar/embed?$url" style=" border-width:0 " width="$width" frameborder="0" height="$height"></iframe>};
|
|
||||||
} #}}}
|
|
||||||
|
|
||||||
1
|
|
|
@ -0,0 +1,75 @@
|
||||||
|
#!/usr/bin/perl
|
||||||
|
package IkiWiki::Plugin::goto;
|
||||||
|
|
||||||
|
use warnings;
|
||||||
|
use strict;
|
||||||
|
use IkiWiki 3.00;
|
||||||
|
|
||||||
|
sub import {
|
||||||
|
hook(type => "cgi", id => 'goto', call => \&cgi);
|
||||||
|
}
|
||||||
|
|
||||||
|
sub getsetup () {
|
||||||
|
return
|
||||||
|
plugin => {
|
||||||
|
safe => 1,
|
||||||
|
rebuild => 0,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
# cgi_goto(CGI, [page])
|
||||||
|
# Redirect to a specified page, or display "not found". If not specified,
|
||||||
|
# the page param from the CGI object is used.
|
||||||
|
sub cgi_goto ($;$) {
|
||||||
|
my $q = shift;
|
||||||
|
my $page = shift;
|
||||||
|
|
||||||
|
if (!defined $page) {
|
||||||
|
$page = IkiWiki::decode_utf8($q->param("page"));
|
||||||
|
|
||||||
|
if (!defined $page) {
|
||||||
|
error("missing page parameter");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
IkiWiki::loadindex();
|
||||||
|
|
||||||
|
# If the page is internal (like a comment), see if it has a
|
||||||
|
# permalink. Comments do.
|
||||||
|
if (IkiWiki::isinternal($page) &&
|
||||||
|
defined $pagestate{$page}{meta}{permalink}) {
|
||||||
|
IkiWiki::redirect($q, $pagestate{$page}{meta}{permalink});
|
||||||
|
}
|
||||||
|
|
||||||
|
my $link = bestlink("", $page);
|
||||||
|
|
||||||
|
if (! length $link) {
|
||||||
|
IkiWiki::cgi_custom_failure(
|
||||||
|
$q->header(-status => "404 Not Found"),
|
||||||
|
IkiWiki::misctemplate(gettext("missing page"),
|
||||||
|
"<p>".
|
||||||
|
sprintf(gettext("The page %s does not exist."),
|
||||||
|
htmllink("", "", $page)).
|
||||||
|
"</p>")
|
||||||
|
)
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
IkiWiki::redirect($q, urlto($link, undef, 1));
|
||||||
|
}
|
||||||
|
|
||||||
|
exit;
|
||||||
|
}
|
||||||
|
|
||||||
|
sub cgi ($) {
|
||||||
|
my $cgi=shift;
|
||||||
|
my $do = $cgi->param('do');
|
||||||
|
|
||||||
|
if (defined $do && ($do eq 'goto' || $do eq 'commenter' ||
|
||||||
|
$do eq 'recentchanges_link')) {
|
||||||
|
# goto is the preferred name for this; recentchanges_link and
|
||||||
|
# commenter are for compatibility with any saved URLs
|
||||||
|
cgi_goto($cgi);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
1;
|
|
@ -5,27 +5,27 @@ package IkiWiki::Plugin::graphviz;
|
||||||
|
|
||||||
use warnings;
|
use warnings;
|
||||||
use strict;
|
use strict;
|
||||||
use IkiWiki 2.00;
|
use IkiWiki 3.00;
|
||||||
use IPC::Open2;
|
use IPC::Open2;
|
||||||
|
|
||||||
sub import { #{{{
|
sub import {
|
||||||
hook(type => "getsetup", id => "graphviz", call => \&getsetup);
|
hook(type => "getsetup", id => "graphviz", call => \&getsetup);
|
||||||
hook(type => "preprocess", id => "graph", call => \&graph);
|
hook(type => "preprocess", id => "graph", call => \&graph);
|
||||||
} # }}}
|
}
|
||||||
|
|
||||||
sub getsetup () { #{{{
|
sub getsetup () {
|
||||||
return
|
return
|
||||||
plugin => {
|
plugin => {
|
||||||
safe => 1,
|
safe => 1,
|
||||||
rebuild => undef,
|
rebuild => undef,
|
||||||
},
|
},
|
||||||
} #}}}
|
}
|
||||||
|
|
||||||
my %graphviz_programs = (
|
my %graphviz_programs = (
|
||||||
"dot" => 1, "neato" => 1, "fdp" => 1, "twopi" => 1, "circo" => 1
|
"dot" => 1, "neato" => 1, "fdp" => 1, "twopi" => 1, "circo" => 1
|
||||||
);
|
);
|
||||||
|
|
||||||
sub render_graph (\%) { #{{{
|
sub render_graph (\%) {
|
||||||
my %params = %{(shift)};
|
my %params = %{(shift)};
|
||||||
|
|
||||||
my $src = "$params{type} g {\n";
|
my $src = "$params{type} g {\n";
|
||||||
|
@ -45,7 +45,7 @@ sub render_graph (\%) { #{{{
|
||||||
|
|
||||||
if (! -e "$config{destdir}/$dest") {
|
if (! -e "$config{destdir}/$dest") {
|
||||||
my $pid;
|
my $pid;
|
||||||
my $sigpipe=0;;
|
my $sigpipe=0;
|
||||||
$SIG{PIPE}=sub { $sigpipe=1 };
|
$SIG{PIPE}=sub { $sigpipe=1 };
|
||||||
$pid=open2(*IN, *OUT, "$params{prog} -Tpng");
|
$pid=open2(*IN, *OUT, "$params{prog} -Tpng");
|
||||||
|
|
||||||
|
@ -84,9 +84,9 @@ sub render_graph (\%) { #{{{
|
||||||
else {
|
else {
|
||||||
return "<img src=\"".urlto($dest, $params{destpage})."\" />\n";
|
return "<img src=\"".urlto($dest, $params{destpage})."\" />\n";
|
||||||
}
|
}
|
||||||
} #}}}
|
}
|
||||||
|
|
||||||
sub graph (@) { #{{{
|
sub graph (@) {
|
||||||
my %params=@_;
|
my %params=@_;
|
||||||
$params{src} = "" unless defined $params{src};
|
$params{src} = "" unless defined $params{src};
|
||||||
$params{type} = "digraph" unless defined $params{type};
|
$params{type} = "digraph" unless defined $params{type};
|
||||||
|
@ -94,6 +94,6 @@ sub graph (@) { #{{{
|
||||||
error gettext("prog not a valid graphviz program") unless $graphviz_programs{$params{prog}};
|
error gettext("prog not a valid graphviz program") unless $graphviz_programs{$params{prog}};
|
||||||
|
|
||||||
return render_graph(%params);
|
return render_graph(%params);
|
||||||
} # }}}
|
}
|
||||||
|
|
||||||
1
|
1
|
||||||
|
|
|
@ -4,22 +4,22 @@ package IkiWiki::Plugin::haiku;
|
||||||
|
|
||||||
use warnings;
|
use warnings;
|
||||||
use strict;
|
use strict;
|
||||||
use IkiWiki 2.00;
|
use IkiWiki 3.00;
|
||||||
|
|
||||||
sub import { #{{{
|
sub import {
|
||||||
hook(type => "getsetup", id => "haiku", call => \&getsetup);
|
hook(type => "getsetup", id => "haiku", call => \&getsetup);
|
||||||
hook(type => "preprocess", id => "haiku", call => \&preprocess);
|
hook(type => "preprocess", id => "haiku", call => \&preprocess);
|
||||||
} # }}}
|
}
|
||||||
|
|
||||||
sub getsetup { #{{{
|
sub getsetup {
|
||||||
return
|
return
|
||||||
plugin => {
|
plugin => {
|
||||||
safe => 1,
|
safe => 1,
|
||||||
rebuild => undef,
|
rebuild => undef,
|
||||||
},
|
},
|
||||||
} #}}}
|
}
|
||||||
|
|
||||||
sub preprocess (@) { #{{{
|
sub preprocess (@) {
|
||||||
my %params=@_;
|
my %params=@_;
|
||||||
|
|
||||||
my $haiku;
|
my $haiku;
|
||||||
|
@ -54,6 +54,6 @@ sub preprocess (@) { #{{{
|
||||||
$haiku=~s/\n/<br \/>\n/mg;
|
$haiku=~s/\n/<br \/>\n/mg;
|
||||||
|
|
||||||
return "\n\n<blockquote><p>$haiku</p></blockquote>\n\n";
|
return "\n\n<blockquote><p>$haiku</p></blockquote>\n\n";
|
||||||
} # }}}
|
}
|
||||||
|
|
||||||
1
|
1
|
||||||
|
|
|
@ -10,23 +10,23 @@ package IkiWiki::Plugin::hnb;
|
||||||
|
|
||||||
use warnings;
|
use warnings;
|
||||||
use strict;
|
use strict;
|
||||||
use IkiWiki 2.00;
|
use IkiWiki 3.00;
|
||||||
use File::Temp qw(:mktemp);
|
use File::Temp qw(:mktemp);
|
||||||
|
|
||||||
sub import { #{{{
|
sub import {
|
||||||
hook(type => "getsetup", id => "hnb", call => \&getsetup);
|
hook(type => "getsetup", id => "hnb", call => \&getsetup);
|
||||||
hook(type => "htmlize", id => "hnb", call => \&htmlize);
|
hook(type => "htmlize", id => "hnb", call => \&htmlize);
|
||||||
} #}}}
|
}
|
||||||
|
|
||||||
sub getsetup () { #{{{
|
sub getsetup () {
|
||||||
return
|
return
|
||||||
plugin => {
|
plugin => {
|
||||||
safe => 1,
|
safe => 1,
|
||||||
rebuild => 1, # format plugin
|
rebuild => 1, # format plugin
|
||||||
},
|
},
|
||||||
} #}}}
|
}
|
||||||
|
|
||||||
sub htmlize (@) { #{{{
|
sub htmlize (@) {
|
||||||
my %params = @_;
|
my %params = @_;
|
||||||
|
|
||||||
# hnb outputs version number etc. every time to STDOUT, so
|
# hnb outputs version number etc. every time to STDOUT, so
|
||||||
|
@ -52,6 +52,6 @@ sub htmlize (@) { #{{{
|
||||||
$ret =~ s/<body>.*//si;
|
$ret =~ s/<body>.*//si;
|
||||||
|
|
||||||
return $ret;
|
return $ret;
|
||||||
} #}}}
|
}
|
||||||
|
|
||||||
1;
|
1;
|
||||||
|
|
|
@ -4,9 +4,9 @@ package IkiWiki::Plugin::html;
|
||||||
|
|
||||||
use warnings;
|
use warnings;
|
||||||
use strict;
|
use strict;
|
||||||
use IkiWiki 2.00;
|
use IkiWiki 3.00;
|
||||||
|
|
||||||
sub import { #{{{
|
sub import {
|
||||||
hook(type => "getsetup", id => "html", call => \&getsetup);
|
hook(type => "getsetup", id => "html", call => \&getsetup);
|
||||||
hook(type => "htmlize", id => "html", call => \&htmlize);
|
hook(type => "htmlize", id => "html", call => \&htmlize);
|
||||||
hook(type => "htmlize", id => "htm", call => \&htmlize);
|
hook(type => "htmlize", id => "htm", call => \&htmlize);
|
||||||
|
@ -14,19 +14,19 @@ sub import { #{{{
|
||||||
# ikiwiki defaults to skipping .html files as a security measure;
|
# ikiwiki defaults to skipping .html files as a security measure;
|
||||||
# make it process them so this plugin can take effect
|
# make it process them so this plugin can take effect
|
||||||
$config{wiki_file_prune_regexps} = [ grep { !m/\\\.x\?html\?\$/ } @{$config{wiki_file_prune_regexps}} ];
|
$config{wiki_file_prune_regexps} = [ grep { !m/\\\.x\?html\?\$/ } @{$config{wiki_file_prune_regexps}} ];
|
||||||
} # }}}
|
}
|
||||||
|
|
||||||
sub getsetup () { #{{{
|
sub getsetup () {
|
||||||
return
|
return
|
||||||
plugin => {
|
plugin => {
|
||||||
safe => 1,
|
safe => 1,
|
||||||
rebuild => 1, # format plugin
|
rebuild => 1, # format plugin
|
||||||
},
|
},
|
||||||
} #}}}
|
}
|
||||||
|
|
||||||
sub htmlize (@) { #{{{
|
sub htmlize (@) {
|
||||||
my %params=@_;
|
my %params=@_;
|
||||||
return $params{content};
|
return $params{content};
|
||||||
} #}}}
|
}
|
||||||
|
|
||||||
1
|
1
|
||||||
|
|
|
@ -0,0 +1,58 @@
|
||||||
|
#!/usr/bin/perl
|
||||||
|
package IkiWiki::Plugin::htmlbalance;
|
||||||
|
|
||||||
|
# htmlbalance: Parse and re-serialize HTML to ensure balanced tags
|
||||||
|
#
|
||||||
|
# Copyright 2008 Simon McVittie <http://smcv.pseudorandom.co.uk/>
|
||||||
|
# Licensed under the GNU GPL, version 2, or any later version published by the
|
||||||
|
# Free Software Foundation
|
||||||
|
|
||||||
|
use warnings;
|
||||||
|
use strict;
|
||||||
|
use IkiWiki 3.00;
|
||||||
|
use HTML::Entities;
|
||||||
|
|
||||||
|
sub import {
|
||||||
|
hook(type => "getsetup", id => "htmlbalance", call => \&getsetup);
|
||||||
|
hook(type => "sanitize", id => "htmlbalance", call => \&sanitize);
|
||||||
|
}
|
||||||
|
|
||||||
|
sub getsetup () {
|
||||||
|
return
|
||||||
|
plugin => {
|
||||||
|
safe => 1,
|
||||||
|
rebuild => undef,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
sub sanitize (@) {
|
||||||
|
my %params=@_;
|
||||||
|
my $ret = '';
|
||||||
|
|
||||||
|
eval q{use HTML::TreeBuilder};
|
||||||
|
error $@ if $@;
|
||||||
|
my $tree = HTML::TreeBuilder->new();
|
||||||
|
$tree->ignore_unknown(0);
|
||||||
|
$tree->ignore_ignorable_whitespace(0);
|
||||||
|
$tree->no_space_compacting(1);
|
||||||
|
$tree->p_strict(1);
|
||||||
|
$tree->store_comments(0);
|
||||||
|
$tree->store_declarations(0);
|
||||||
|
$tree->store_pis(0);
|
||||||
|
$tree->parse_content($params{content});
|
||||||
|
my @nodes = $tree->disembowel();
|
||||||
|
foreach my $node (@nodes) {
|
||||||
|
if (ref $node) {
|
||||||
|
$ret .= $node->as_XML();
|
||||||
|
chomp $ret;
|
||||||
|
$node->delete();
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
$ret .= encode_entities($node);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
$tree->delete();
|
||||||
|
return $ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
1
|
|
@ -3,13 +3,13 @@ package IkiWiki::Plugin::htmlscrubber;
|
||||||
|
|
||||||
use warnings;
|
use warnings;
|
||||||
use strict;
|
use strict;
|
||||||
use IkiWiki 2.00;
|
use IkiWiki 3.00;
|
||||||
|
|
||||||
# This regexp matches urls that are in a known safe scheme.
|
# This regexp matches urls that are in a known safe scheme.
|
||||||
# Feel free to use it from other plugins.
|
# Feel free to use it from other plugins.
|
||||||
our $safe_url_regexp;
|
our $safe_url_regexp;
|
||||||
|
|
||||||
sub import { #{{{
|
sub import {
|
||||||
hook(type => "getsetup", id => "htmlscrubber", call => \&getsetup);
|
hook(type => "getsetup", id => "htmlscrubber", call => \&getsetup);
|
||||||
hook(type => "sanitize", id => "htmlscrubber", call => \&sanitize);
|
hook(type => "sanitize", id => "htmlscrubber", call => \&sanitize);
|
||||||
|
|
||||||
|
@ -33,9 +33,9 @@ sub import { #{{{
|
||||||
# data is a special case. Allow data:image/*, but
|
# data is a special case. Allow data:image/*, but
|
||||||
# disallow data:text/javascript and everything else.
|
# disallow data:text/javascript and everything else.
|
||||||
$safe_url_regexp=qr/^(?:(?:$uri_schemes):|data:image\/|[^:]+(?:$|\/))/i;
|
$safe_url_regexp=qr/^(?:(?:$uri_schemes):|data:image\/|[^:]+(?:$|\/))/i;
|
||||||
} # }}}
|
}
|
||||||
|
|
||||||
sub getsetup () { #{{{
|
sub getsetup () {
|
||||||
return
|
return
|
||||||
plugin => {
|
plugin => {
|
||||||
safe => 1,
|
safe => 1,
|
||||||
|
@ -49,9 +49,9 @@ sub getsetup () { #{{{
|
||||||
safe => 1,
|
safe => 1,
|
||||||
rebuild => undef,
|
rebuild => undef,
|
||||||
},
|
},
|
||||||
} #}}}
|
}
|
||||||
|
|
||||||
sub sanitize (@) { #{{{
|
sub sanitize (@) {
|
||||||
my %params=@_;
|
my %params=@_;
|
||||||
|
|
||||||
if (exists $config{htmlscrubber_skip} &&
|
if (exists $config{htmlscrubber_skip} &&
|
||||||
|
@ -62,10 +62,10 @@ sub sanitize (@) { #{{{
|
||||||
}
|
}
|
||||||
|
|
||||||
return scrubber()->scrub($params{content});
|
return scrubber()->scrub($params{content});
|
||||||
} # }}}
|
}
|
||||||
|
|
||||||
my $_scrubber;
|
my $_scrubber;
|
||||||
sub scrubber { #{{{
|
sub scrubber {
|
||||||
return $_scrubber if defined $_scrubber;
|
return $_scrubber if defined $_scrubber;
|
||||||
|
|
||||||
eval q{use HTML::Scrubber};
|
eval q{use HTML::Scrubber};
|
||||||
|
@ -111,6 +111,6 @@ sub scrubber { #{{{
|
||||||
}],
|
}],
|
||||||
);
|
);
|
||||||
return $_scrubber;
|
return $_scrubber;
|
||||||
} # }}}
|
}
|
||||||
|
|
||||||
1
|
1
|
||||||
|
|
|
@ -9,23 +9,23 @@ package IkiWiki::Plugin::htmltidy;
|
||||||
|
|
||||||
use warnings;
|
use warnings;
|
||||||
use strict;
|
use strict;
|
||||||
use IkiWiki 2.00;
|
use IkiWiki 3.00;
|
||||||
use IPC::Open2;
|
use IPC::Open2;
|
||||||
|
|
||||||
sub import { #{{{
|
sub import {
|
||||||
hook(type => "getsetup", id => "tidy", call => \&getsetup);
|
hook(type => "getsetup", id => "tidy", call => \&getsetup);
|
||||||
hook(type => "sanitize", id => "tidy", call => \&sanitize);
|
hook(type => "sanitize", id => "tidy", call => \&sanitize);
|
||||||
} # }}}
|
}
|
||||||
|
|
||||||
sub getsetup () { #{{{
|
sub getsetup () {
|
||||||
return
|
return
|
||||||
plugin => {
|
plugin => {
|
||||||
safe => 1,
|
safe => 1,
|
||||||
rebuild => undef,
|
rebuild => undef,
|
||||||
},
|
},
|
||||||
} #}}}
|
}
|
||||||
|
|
||||||
sub sanitize (@) { #{{{
|
sub sanitize (@) {
|
||||||
my %params=@_;
|
my %params=@_;
|
||||||
|
|
||||||
my $pid;
|
my $pid;
|
||||||
|
@ -49,6 +49,6 @@ sub sanitize (@) { #{{{
|
||||||
return "" if $sigpipe || ! defined $ret;
|
return "" if $sigpipe || ! defined $ret;
|
||||||
|
|
||||||
return $ret;
|
return $ret;
|
||||||
} # }}}
|
}
|
||||||
|
|
||||||
1
|
1
|
||||||
|
|
|
@ -4,28 +4,28 @@ package IkiWiki::Plugin::httpauth;
|
||||||
|
|
||||||
use warnings;
|
use warnings;
|
||||||
use strict;
|
use strict;
|
||||||
use IkiWiki 2.00;
|
use IkiWiki 3.00;
|
||||||
|
|
||||||
sub import { #{{{
|
sub import {
|
||||||
hook(type => "getsetup", id => "httpauth", call => \&getsetup);
|
hook(type => "getsetup", id => "httpauth", call => \&getsetup);
|
||||||
hook(type => "auth", id => "httpauth", call => \&auth);
|
hook(type => "auth", id => "httpauth", call => \&auth);
|
||||||
} # }}}
|
}
|
||||||
|
|
||||||
sub getsetup () { #{{{
|
sub getsetup () {
|
||||||
return
|
return
|
||||||
plugin => {
|
plugin => {
|
||||||
safe => 1,
|
safe => 1,
|
||||||
rebuild => 0,
|
rebuild => 0,
|
||||||
},
|
},
|
||||||
} #}}}
|
}
|
||||||
|
|
||||||
sub auth ($$) { #{{{
|
sub auth ($$) {
|
||||||
my $cgi=shift;
|
my $cgi=shift;
|
||||||
my $session=shift;
|
my $session=shift;
|
||||||
|
|
||||||
if (defined $cgi->remote_user()) {
|
if (defined $cgi->remote_user()) {
|
||||||
$session->param("name", $cgi->remote_user());
|
$session->param("name", $cgi->remote_user());
|
||||||
}
|
}
|
||||||
} #}}}
|
}
|
||||||
|
|
||||||
1
|
1
|
||||||
|
|
|
@ -5,24 +5,24 @@ package IkiWiki::Plugin::img;
|
||||||
|
|
||||||
use warnings;
|
use warnings;
|
||||||
use strict;
|
use strict;
|
||||||
use IkiWiki 2.00;
|
use IkiWiki 3.00;
|
||||||
|
|
||||||
my %imgdefaults;
|
my %imgdefaults;
|
||||||
|
|
||||||
sub import { #{{{
|
sub import {
|
||||||
hook(type => "getsetup", id => "img", call => \&getsetup);
|
hook(type => "getsetup", id => "img", call => \&getsetup);
|
||||||
hook(type => "preprocess", id => "img", call => \&preprocess, scan => 1);
|
hook(type => "preprocess", id => "img", call => \&preprocess, scan => 1);
|
||||||
} #}}}
|
}
|
||||||
|
|
||||||
sub getsetup () { #{{{
|
sub getsetup () {
|
||||||
return
|
return
|
||||||
plugin => {
|
plugin => {
|
||||||
safe => 1,
|
safe => 1,
|
||||||
rebuild => undef,
|
rebuild => undef,
|
||||||
},
|
},
|
||||||
} #}}}
|
}
|
||||||
|
|
||||||
sub preprocess (@) { #{{{
|
sub preprocess (@) {
|
||||||
my ($image) = $_[0] =~ /$config{wiki_file_regexp}/; # untaint
|
my ($image) = $_[0] =~ /$config{wiki_file_regexp}/; # untaint
|
||||||
my %params=@_;
|
my %params=@_;
|
||||||
|
|
||||||
|
@ -119,9 +119,9 @@ sub preprocess (@) { #{{{
|
||||||
}
|
}
|
||||||
|
|
||||||
my $imgtag='<img src="'.$imgurl.
|
my $imgtag='<img src="'.$imgurl.
|
||||||
'" alt="'.(exists $params{alt} ? $params{alt} : '').
|
|
||||||
'" width="'.$im->Get("width").
|
'" width="'.$im->Get("width").
|
||||||
'" height="'.$im->Get("height").'"'.
|
'" height="'.$im->Get("height").'"'.
|
||||||
|
(exists $params{alt} ? '" alt="'.$params{alt}.'"' : '').
|
||||||
(exists $params{title} ? ' title="'.$params{title}.'"' : '').
|
(exists $params{title} ? ' title="'.$params{title}.'"' : '').
|
||||||
(exists $params{class} ? ' class="'.$params{class}.'"' : '').
|
(exists $params{class} ? ' class="'.$params{class}.'"' : '').
|
||||||
(exists $params{id} ? ' id="'.$params{id}.'"' : '').
|
(exists $params{id} ? ' id="'.$params{id}.'"' : '').
|
||||||
|
@ -149,6 +149,6 @@ sub preprocess (@) { #{{{
|
||||||
else {
|
else {
|
||||||
return $imgtag;
|
return $imgtag;
|
||||||
}
|
}
|
||||||
} #}}}
|
}
|
||||||
|
|
||||||
1
|
1
|
||||||
|
|
|
@ -5,7 +5,7 @@ package IkiWiki::Plugin::inline;
|
||||||
use warnings;
|
use warnings;
|
||||||
use strict;
|
use strict;
|
||||||
use Encode;
|
use Encode;
|
||||||
use IkiWiki 2.00;
|
use IkiWiki 3.00;
|
||||||
use URI;
|
use URI;
|
||||||
|
|
||||||
my %knownfeeds;
|
my %knownfeeds;
|
||||||
|
@ -13,7 +13,7 @@ my %page_numfeeds;
|
||||||
my @inline;
|
my @inline;
|
||||||
my $nested=0;
|
my $nested=0;
|
||||||
|
|
||||||
sub import { #{{{
|
sub import {
|
||||||
hook(type => "getopt", id => "inline", call => \&getopt);
|
hook(type => "getopt", id => "inline", call => \&getopt);
|
||||||
hook(type => "getsetup", id => "inline", call => \&getsetup);
|
hook(type => "getsetup", id => "inline", call => \&getsetup);
|
||||||
hook(type => "checkconfig", id => "inline", call => \&checkconfig);
|
hook(type => "checkconfig", id => "inline", call => \&checkconfig);
|
||||||
|
@ -22,15 +22,14 @@ sub import { #{{{
|
||||||
call => \&IkiWiki::preprocess_inline);
|
call => \&IkiWiki::preprocess_inline);
|
||||||
hook(type => "pagetemplate", id => "inline",
|
hook(type => "pagetemplate", id => "inline",
|
||||||
call => \&IkiWiki::pagetemplate_inline);
|
call => \&IkiWiki::pagetemplate_inline);
|
||||||
hook(type => "format", id => "inline", call => \&format);
|
hook(type => "format", id => "inline", call => \&format, first => 1);
|
||||||
# Hook to change to do pinging since it's called late.
|
# Hook to change to do pinging since it's called late.
|
||||||
# This ensures each page only pings once and prevents slow
|
# This ensures each page only pings once and prevents slow
|
||||||
# pings interrupting page builds.
|
# pings interrupting page builds.
|
||||||
hook(type => "change", id => "inline",
|
hook(type => "change", id => "inline", call => \&IkiWiki::pingurl);
|
||||||
call => \&IkiWiki::pingurl);
|
}
|
||||||
} # }}}
|
|
||||||
|
|
||||||
sub getopt () { #{{{
|
sub getopt () {
|
||||||
eval q{use Getopt::Long};
|
eval q{use Getopt::Long};
|
||||||
error($@) if $@;
|
error($@) if $@;
|
||||||
Getopt::Long::Configure('pass_through');
|
Getopt::Long::Configure('pass_through');
|
||||||
|
@ -43,9 +42,9 @@ sub getopt () { #{{{
|
||||||
push @{$config{pingurl}}, $_[1];
|
push @{$config{pingurl}}, $_[1];
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
} #}}}
|
}
|
||||||
|
|
||||||
sub getsetup () { #{{{
|
sub getsetup () {
|
||||||
return
|
return
|
||||||
plugin => {
|
plugin => {
|
||||||
safe => 1,
|
safe => 1,
|
||||||
|
@ -86,9 +85,9 @@ sub getsetup () { #{{{
|
||||||
safe => 1,
|
safe => 1,
|
||||||
rebuild => 0,
|
rebuild => 0,
|
||||||
},
|
},
|
||||||
} #}}}
|
}
|
||||||
|
|
||||||
sub checkconfig () { #{{{
|
sub checkconfig () {
|
||||||
if (($config{rss} || $config{atom}) && ! length $config{url}) {
|
if (($config{rss} || $config{atom}) && ! length $config{url}) {
|
||||||
error(gettext("Must specify url to wiki with --url when using --rss or --atom"));
|
error(gettext("Must specify url to wiki with --url when using --rss or --atom"));
|
||||||
}
|
}
|
||||||
|
@ -101,9 +100,9 @@ sub checkconfig () { #{{{
|
||||||
if (! exists $config{pingurl}) {
|
if (! exists $config{pingurl}) {
|
||||||
$config{pingurl}=[];
|
$config{pingurl}=[];
|
||||||
}
|
}
|
||||||
} #}}}
|
}
|
||||||
|
|
||||||
sub format (@) { #{{{
|
sub format (@) {
|
||||||
my %params=@_;
|
my %params=@_;
|
||||||
|
|
||||||
# Fill in the inline content generated earlier. This is actually an
|
# Fill in the inline content generated earlier. This is actually an
|
||||||
|
@ -112,9 +111,9 @@ sub format (@) { #{{{
|
||||||
delete @inline[$1,]
|
delete @inline[$1,]
|
||||||
}eg;
|
}eg;
|
||||||
return $params{content};
|
return $params{content};
|
||||||
} #}}}
|
}
|
||||||
|
|
||||||
sub sessioncgi ($$) { #{{{
|
sub sessioncgi ($$) {
|
||||||
my $q=shift;
|
my $q=shift;
|
||||||
my $session=shift;
|
my $session=shift;
|
||||||
|
|
||||||
|
@ -149,7 +148,7 @@ package IkiWiki;
|
||||||
my %toping;
|
my %toping;
|
||||||
my %feedlinks;
|
my %feedlinks;
|
||||||
|
|
||||||
sub preprocess_inline (@) { #{{{
|
sub preprocess_inline (@) {
|
||||||
my %params=@_;
|
my %params=@_;
|
||||||
|
|
||||||
if (! exists $params{pages}) {
|
if (! exists $params{pages}) {
|
||||||
|
@ -161,6 +160,7 @@ sub preprocess_inline (@) { #{{{
|
||||||
my $atom=(($config{atom} || $config{allowatom}) && exists $params{atom}) ? yesno($params{atom}) : $config{atom};
|
my $atom=(($config{atom} || $config{allowatom}) && exists $params{atom}) ? yesno($params{atom}) : $config{atom};
|
||||||
my $quick=exists $params{quick} ? yesno($params{quick}) : 0;
|
my $quick=exists $params{quick} ? yesno($params{quick}) : 0;
|
||||||
my $feeds=exists $params{feeds} ? yesno($params{feeds}) : !$quick;
|
my $feeds=exists $params{feeds} ? yesno($params{feeds}) : !$quick;
|
||||||
|
my $emptyfeeds=exists $params{emptyfeeds} ? yesno($params{emptyfeeds}) : 1;
|
||||||
my $feedonly=yesno($params{feedonly});
|
my $feedonly=yesno($params{feedonly});
|
||||||
if (! exists $params{show} && ! $archive) {
|
if (! exists $params{show} && ! $archive) {
|
||||||
$params{show}=10;
|
$params{show}=10;
|
||||||
|
@ -194,6 +194,13 @@ sub preprocess_inline (@) { #{{{
|
||||||
if (exists $params{sort} && $params{sort} eq 'title') {
|
if (exists $params{sort} && $params{sort} eq 'title') {
|
||||||
@list=sort { pagetitle(basename($a)) cmp pagetitle(basename($b)) } @list;
|
@list=sort { pagetitle(basename($a)) cmp pagetitle(basename($b)) } @list;
|
||||||
}
|
}
|
||||||
|
elsif (exists $params{sort} && $params{sort} eq 'title_natural') {
|
||||||
|
eval q{use Sort::Naturally};
|
||||||
|
if ($@) {
|
||||||
|
error(gettext("Sort::Naturally needed for title_natural sort"));
|
||||||
|
}
|
||||||
|
@list=sort { Sort::Naturally::ncmp(pagetitle(basename($a)), pagetitle(basename($b))) } @list;
|
||||||
|
}
|
||||||
elsif (exists $params{sort} && $params{sort} eq 'mtime') {
|
elsif (exists $params{sort} && $params{sort} eq 'mtime') {
|
||||||
@list=sort { $pagemtime{$b} <=> $pagemtime{$a} } @list;
|
@list=sort { $pagemtime{$b} <=> $pagemtime{$a} } @list;
|
||||||
}
|
}
|
||||||
|
@ -201,7 +208,7 @@ sub preprocess_inline (@) { #{{{
|
||||||
@list=sort { $pagectime{$b} <=> $pagectime{$a} } @list;
|
@list=sort { $pagectime{$b} <=> $pagectime{$a} } @list;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
return sprintf(gettext("unknown sort type %s"), $params{sort});
|
error sprintf(gettext("unknown sort type %s"), $params{sort});
|
||||||
}
|
}
|
||||||
|
|
||||||
if (yesno($params{reverse})) {
|
if (yesno($params{reverse})) {
|
||||||
|
@ -232,29 +239,51 @@ sub preprocess_inline (@) { #{{{
|
||||||
# that if they are removed or otherwise changed, the inline will be
|
# that if they are removed or otherwise changed, the inline will be
|
||||||
# sure to be updated.
|
# sure to be updated.
|
||||||
add_depends($params{page}, join(" or ", $#list >= $#feedlist ? @list : @feedlist));
|
add_depends($params{page}, join(" or ", $#list >= $#feedlist ? @list : @feedlist));
|
||||||
|
|
||||||
my $feednum="";
|
if ($feeds && exists $params{feedpages}) {
|
||||||
|
@feedlist=grep { pagespec_match($_, $params{feedpages}, location => $params{page}) } @feedlist;
|
||||||
my $feedid=join("\0", map { $_."\0".$params{$_} } sort keys %params);
|
|
||||||
if (exists $knownfeeds{$feedid}) {
|
|
||||||
$feednum=$knownfeeds{$feedid};
|
|
||||||
}
|
}
|
||||||
else {
|
|
||||||
if (exists $page_numfeeds{$params{destpage}}) {
|
my ($feedbase, $feednum);
|
||||||
if ($feeds) {
|
if ($feeds) {
|
||||||
$feednum=$knownfeeds{$feedid}=++$page_numfeeds{$params{destpage}};
|
# Ensure that multiple feeds on a page go to unique files.
|
||||||
|
|
||||||
|
# Feedfile can lead to conflicts if usedirs is not enabled,
|
||||||
|
# so avoid supporting it in that case.
|
||||||
|
delete $params{feedfile} if ! $config{usedirs};
|
||||||
|
# Tight limits on legal feedfiles, to avoid security issues
|
||||||
|
# and conflicts.
|
||||||
|
if (defined $params{feedfile}) {
|
||||||
|
if ($params{feedfile} =~ /\// ||
|
||||||
|
$params{feedfile} !~ /$config{wiki_file_regexp}/) {
|
||||||
|
error("illegal feedfile");
|
||||||
}
|
}
|
||||||
|
$params{feedfile}=possibly_foolish_untaint($params{feedfile});
|
||||||
|
}
|
||||||
|
$feedbase=targetpage($params{destpage}, "", $params{feedfile});
|
||||||
|
|
||||||
|
my $feedid=join("\0", $feedbase, map { $_."\0".$params{$_} } sort keys %params);
|
||||||
|
if (exists $knownfeeds{$feedid}) {
|
||||||
|
$feednum=$knownfeeds{$feedid};
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
$feednum=$knownfeeds{$feedid}="";
|
if (exists $page_numfeeds{$params{destpage}}{$feedbase}) {
|
||||||
if ($feeds) {
|
if ($feeds) {
|
||||||
$page_numfeeds{$params{destpage}}=1;
|
$feednum=$knownfeeds{$feedid}=++$page_numfeeds{$params{destpage}}{$feedbase};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
$feednum=$knownfeeds{$feedid}="";
|
||||||
|
if ($feeds) {
|
||||||
|
$page_numfeeds{$params{destpage}}{$feedbase}=1;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
my $rssurl=basename(rsspage($params{destpage}).$feednum) if $feeds && $rss;
|
my $rssurl=abs2rel($feedbase."rss".$feednum, dirname(htmlpage($params{destpage}))) if $feeds && $rss;
|
||||||
my $atomurl=basename(atompage($params{destpage}).$feednum) if $feeds && $atom;
|
my $atomurl=abs2rel($feedbase."atom".$feednum, dirname(htmlpage($params{destpage}))) if $feeds && $atom;
|
||||||
|
|
||||||
my $ret="";
|
my $ret="";
|
||||||
|
|
||||||
if (length $config{cgiurl} && ! $params{preview} && (exists $params{rootpage} ||
|
if (length $config{cgiurl} && ! $params{preview} && (exists $params{rootpage} ||
|
||||||
|
@ -285,8 +314,12 @@ sub preprocess_inline (@) { #{{{
|
||||||
gettext("Add a new post titled:"));
|
gettext("Add a new post titled:"));
|
||||||
}
|
}
|
||||||
$ret.=$formtemplate->output;
|
$ret.=$formtemplate->output;
|
||||||
|
|
||||||
|
# The post form includes the feed buttons, so
|
||||||
|
# emptyfeeds cannot be hidden.
|
||||||
|
$emptyfeeds=1;
|
||||||
}
|
}
|
||||||
elsif ($feeds && !$params{preview}) {
|
elsif ($feeds && !$params{preview} && ($emptyfeeds || @feedlist)) {
|
||||||
# Add feed buttons.
|
# Add feed buttons.
|
||||||
my $linktemplate=template("feedlink.tmpl", blind_cache => 1);
|
my $linktemplate=template("feedlink.tmpl", blind_cache => 1);
|
||||||
$linktemplate->param(rssurl => $rssurl) if $rss;
|
$linktemplate->param(rssurl => $rssurl) if $rss;
|
||||||
|
@ -298,7 +331,7 @@ sub preprocess_inline (@) { #{{{
|
||||||
require HTML::Template;
|
require HTML::Template;
|
||||||
my @params=IkiWiki::template_params($params{template}.".tmpl", blind_cache => 1);
|
my @params=IkiWiki::template_params($params{template}.".tmpl", blind_cache => 1);
|
||||||
if (! @params) {
|
if (! @params) {
|
||||||
return sprintf(gettext("nonexistant template %s"), $params{template});
|
error sprintf(gettext("nonexistant template %s"), $params{template});
|
||||||
}
|
}
|
||||||
my $template=HTML::Template->new(@params) unless $raw;
|
my $template=HTML::Template->new(@params) unless $raw;
|
||||||
|
|
||||||
|
@ -314,6 +347,7 @@ sub preprocess_inline (@) { #{{{
|
||||||
$template->param(content => $content);
|
$template->param(content => $content);
|
||||||
}
|
}
|
||||||
$template->param(pageurl => urlto(bestlink($params{page}, $page), $params{destpage}));
|
$template->param(pageurl => urlto(bestlink($params{page}, $page), $params{destpage}));
|
||||||
|
$template->param(inlinepage => $page);
|
||||||
$template->param(title => pagetitle(basename($page)));
|
$template->param(title => pagetitle(basename($page)));
|
||||||
$template->param(ctime => displaytime($pagectime{$page}, $params{timeformat}));
|
$template->param(ctime => displaytime($pagectime{$page}, $params{timeformat}));
|
||||||
$template->param(mtime => displaytime($pagemtime{$page}, $params{timeformat}));
|
$template->param(mtime => displaytime($pagemtime{$page}, $params{timeformat}));
|
||||||
|
@ -363,30 +397,26 @@ sub preprocess_inline (@) { #{{{
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if ($feeds) {
|
if ($feeds && ($emptyfeeds || @feedlist)) {
|
||||||
if (exists $params{feedpages}) {
|
|
||||||
@feedlist=grep { pagespec_match($_, $params{feedpages}, location => $params{page}) } @feedlist;
|
|
||||||
}
|
|
||||||
|
|
||||||
if ($rss) {
|
if ($rss) {
|
||||||
my $rssp=rsspage($params{destpage}).$feednum;
|
my $rssp=$feedbase."rss".$feednum;
|
||||||
will_render($params{destpage}, $rssp);
|
will_render($params{destpage}, $rssp);
|
||||||
if (! $params{preview}) {
|
if (! $params{preview}) {
|
||||||
writefile($rssp, $config{destdir},
|
writefile($rssp, $config{destdir},
|
||||||
genfeed("rss",
|
genfeed("rss",
|
||||||
$config{url}."/".$rssp, $desc, $params{guid}, $params{destpage}, @feedlist));
|
$config{url}."/".$rssp, $desc, $params{guid}, $params{destpage}, @feedlist));
|
||||||
$toping{$params{destpage}}=1 unless $config{rebuild};
|
$toping{$params{destpage}}=1 unless $config{rebuild};
|
||||||
$feedlinks{$params{destpage}}=qq{<link rel="alternate" type="application/rss+xml" title="$desc (RSS)" href="$rssurl" />};
|
$feedlinks{$params{destpage}}.=qq{<link rel="alternate" type="application/rss+xml" title="$desc (RSS)" href="$rssurl" />};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if ($atom) {
|
if ($atom) {
|
||||||
my $atomp=atompage($params{destpage}).$feednum;
|
my $atomp=$feedbase."atom".$feednum;
|
||||||
will_render($params{destpage}, $atomp);
|
will_render($params{destpage}, $atomp);
|
||||||
if (! $params{preview}) {
|
if (! $params{preview}) {
|
||||||
writefile($atomp, $config{destdir},
|
writefile($atomp, $config{destdir},
|
||||||
genfeed("atom", $config{url}."/".$atomp, $desc, $params{guid}, $params{destpage}, @feedlist));
|
genfeed("atom", $config{url}."/".$atomp, $desc, $params{guid}, $params{destpage}, @feedlist));
|
||||||
$toping{$params{destpage}}=1 unless $config{rebuild};
|
$toping{$params{destpage}}=1 unless $config{rebuild};
|
||||||
$feedlinks{$params{destpage}}=qq{<link rel="alternate" type="application/atom+xml" title="$desc (Atom)" href="$atomurl" />};
|
$feedlinks{$params{destpage}}.=qq{<link rel="alternate" type="application/atom+xml" title="$desc (Atom)" href="$atomurl" />};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -394,18 +424,18 @@ sub preprocess_inline (@) { #{{{
|
||||||
return $ret if $raw || $nested;
|
return $ret if $raw || $nested;
|
||||||
push @inline, $ret;
|
push @inline, $ret;
|
||||||
return "<div class=\"inline\" id=\"$#inline\"></div>\n\n";
|
return "<div class=\"inline\" id=\"$#inline\"></div>\n\n";
|
||||||
} #}}}
|
}
|
||||||
|
|
||||||
sub pagetemplate_inline (@) { #{{{
|
sub pagetemplate_inline (@) {
|
||||||
my %params=@_;
|
my %params=@_;
|
||||||
my $page=$params{page};
|
my $page=$params{page};
|
||||||
my $template=$params{template};
|
my $template=$params{template};
|
||||||
|
|
||||||
$template->param(feedlinks => $feedlinks{$page})
|
$template->param(feedlinks => $feedlinks{$page})
|
||||||
if exists $feedlinks{$page} && $template->query(name => "feedlinks");
|
if exists $feedlinks{$page} && $template->query(name => "feedlinks");
|
||||||
} #}}}
|
}
|
||||||
|
|
||||||
sub get_inline_content ($$) { #{{{
|
sub get_inline_content ($$) {
|
||||||
my $page=shift;
|
my $page=shift;
|
||||||
my $destpage=shift;
|
my $destpage=shift;
|
||||||
|
|
||||||
|
@ -424,9 +454,9 @@ sub get_inline_content ($$) { #{{{
|
||||||
else {
|
else {
|
||||||
return "";
|
return "";
|
||||||
}
|
}
|
||||||
} #}}}
|
}
|
||||||
|
|
||||||
sub date_822 ($) { #{{{
|
sub date_822 ($) {
|
||||||
my $time=shift;
|
my $time=shift;
|
||||||
|
|
||||||
my $lc_time=POSIX::setlocale(&POSIX::LC_TIME);
|
my $lc_time=POSIX::setlocale(&POSIX::LC_TIME);
|
||||||
|
@ -434,9 +464,9 @@ sub date_822 ($) { #{{{
|
||||||
my $ret=POSIX::strftime("%a, %d %b %Y %H:%M:%S %z", localtime($time));
|
my $ret=POSIX::strftime("%a, %d %b %Y %H:%M:%S %z", localtime($time));
|
||||||
POSIX::setlocale(&POSIX::LC_TIME, $lc_time);
|
POSIX::setlocale(&POSIX::LC_TIME, $lc_time);
|
||||||
return $ret;
|
return $ret;
|
||||||
} #}}}
|
}
|
||||||
|
|
||||||
sub date_3339 ($) { #{{{
|
sub date_3339 ($) {
|
||||||
my $time=shift;
|
my $time=shift;
|
||||||
|
|
||||||
my $lc_time=POSIX::setlocale(&POSIX::LC_TIME);
|
my $lc_time=POSIX::setlocale(&POSIX::LC_TIME);
|
||||||
|
@ -444,9 +474,9 @@ sub date_3339 ($) { #{{{
|
||||||
my $ret=POSIX::strftime("%Y-%m-%dT%H:%M:%SZ", gmtime($time));
|
my $ret=POSIX::strftime("%Y-%m-%dT%H:%M:%SZ", gmtime($time));
|
||||||
POSIX::setlocale(&POSIX::LC_TIME, $lc_time);
|
POSIX::setlocale(&POSIX::LC_TIME, $lc_time);
|
||||||
return $ret;
|
return $ret;
|
||||||
} #}}}
|
}
|
||||||
|
|
||||||
sub absolute_urls ($$) { #{{{
|
sub absolute_urls ($$) {
|
||||||
# sucky sub because rss sucks
|
# sucky sub because rss sucks
|
||||||
my $content=shift;
|
my $content=shift;
|
||||||
my $baseurl=shift;
|
my $baseurl=shift;
|
||||||
|
@ -467,17 +497,9 @@ sub absolute_urls ($$) { #{{{
|
||||||
$content=~s/(<a(?:\s+(?:class|id)\s*="?\w+"?)?)\s+href=\s*"(?!\w+:)(\/[^"]*)"/$1 href="$urltop$2"/mig;
|
$content=~s/(<a(?:\s+(?:class|id)\s*="?\w+"?)?)\s+href=\s*"(?!\w+:)(\/[^"]*)"/$1 href="$urltop$2"/mig;
|
||||||
$content=~s/(<img(?:\s+(?:class|id|width|height)\s*="?\w+"?)*)\s+src=\s*"(?!\w+:)(\/[^"]*)"/$1 src="$urltop$2"/mig;
|
$content=~s/(<img(?:\s+(?:class|id|width|height)\s*="?\w+"?)*)\s+src=\s*"(?!\w+:)(\/[^"]*)"/$1 src="$urltop$2"/mig;
|
||||||
return $content;
|
return $content;
|
||||||
} #}}}
|
}
|
||||||
|
|
||||||
sub rsspage ($) { #{{{
|
sub genfeed ($$$$$@) {
|
||||||
return targetpage(shift, "rss");
|
|
||||||
} #}}}
|
|
||||||
|
|
||||||
sub atompage ($) { #{{{
|
|
||||||
return targetpage(shift, "atom");
|
|
||||||
} #}}}
|
|
||||||
|
|
||||||
sub genfeed ($$$$$@) { #{{{
|
|
||||||
my $feedtype=shift;
|
my $feedtype=shift;
|
||||||
my $feedurl=shift;
|
my $feedurl=shift;
|
||||||
my $feeddesc=shift;
|
my $feeddesc=shift;
|
||||||
|
@ -504,9 +526,15 @@ sub genfeed ($$$$$@) { #{{{
|
||||||
mdate_3339 => date_3339($pagemtime{$p}),
|
mdate_3339 => date_3339($pagemtime{$p}),
|
||||||
);
|
);
|
||||||
|
|
||||||
if (exists $pagestate{$p} &&
|
if (exists $pagestate{$p}) {
|
||||||
exists $pagestate{$p}{meta}{guid}) {
|
if (exists $pagestate{$p}{meta}{guid}) {
|
||||||
$itemtemplate->param(guid => $pagestate{$p}{meta}{guid});
|
$itemtemplate->param(guid => $pagestate{$p}{meta}{guid});
|
||||||
|
}
|
||||||
|
|
||||||
|
if (exists $pagestate{$p}{meta}{updated}) {
|
||||||
|
$itemtemplate->param(mdate_822 => date_822($pagestate{$p}{meta}{updated}));
|
||||||
|
$itemtemplate->param(mdate_3339 => date_3339($pagestate{$p}{meta}{updated}));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if ($itemtemplate->query(name => "enclosure")) {
|
if ($itemtemplate->query(name => "enclosure")) {
|
||||||
|
@ -562,9 +590,9 @@ sub genfeed ($$$$$@) { #{{{
|
||||||
});
|
});
|
||||||
|
|
||||||
return $template->output;
|
return $template->output;
|
||||||
} #}}}
|
}
|
||||||
|
|
||||||
sub pingurl (@) { #{{{
|
sub pingurl (@) {
|
||||||
return unless @{$config{pingurl}} && %toping;
|
return unless @{$config{pingurl}} && %toping;
|
||||||
|
|
||||||
eval q{require RPC::XML::Client};
|
eval q{require RPC::XML::Client};
|
||||||
|
@ -610,6 +638,6 @@ sub pingurl (@) { #{{{
|
||||||
}
|
}
|
||||||
|
|
||||||
exit 0; # daemon done
|
exit 0; # daemon done
|
||||||
} #}}}
|
}
|
||||||
|
|
||||||
1
|
1
|
||||||
|
|
|
@ -3,27 +3,27 @@ package IkiWiki::Plugin::link;
|
||||||
|
|
||||||
use warnings;
|
use warnings;
|
||||||
use strict;
|
use strict;
|
||||||
use IkiWiki 2.00;
|
use IkiWiki 3.00;
|
||||||
|
|
||||||
my $link_regexp;
|
my $link_regexp;
|
||||||
|
|
||||||
sub import { #{{{
|
sub import {
|
||||||
hook(type => "getsetup", id => "link", call => \&getsetup);
|
hook(type => "getsetup", id => "link", call => \&getsetup);
|
||||||
hook(type => "checkconfig", id => "link", call => \&checkconfig);
|
hook(type => "checkconfig", id => "link", call => \&checkconfig);
|
||||||
hook(type => "linkify", id => "link", call => \&linkify);
|
hook(type => "linkify", id => "link", call => \&linkify);
|
||||||
hook(type => "scan", id => "link", call => \&scan);
|
hook(type => "scan", id => "link", call => \&scan);
|
||||||
hook(type => "renamepage", id => "link", call => \&renamepage);
|
hook(type => "renamepage", id => "link", call => \&renamepage);
|
||||||
} # }}}
|
}
|
||||||
|
|
||||||
sub getsetup () { #{{{
|
sub getsetup () {
|
||||||
return
|
return
|
||||||
plugin => {
|
plugin => {
|
||||||
safe => 1,
|
safe => 1,
|
||||||
rebuild => 1,
|
rebuild => 1,
|
||||||
},
|
},
|
||||||
} #}}}
|
}
|
||||||
|
|
||||||
sub checkconfig () { #{{{
|
sub checkconfig () {
|
||||||
if ($config{prefix_directives}) {
|
if ($config{prefix_directives}) {
|
||||||
$link_regexp = qr{
|
$link_regexp = qr{
|
||||||
\[\[(?=[^!]) # beginning of link
|
\[\[(?=[^!]) # beginning of link
|
||||||
|
@ -58,9 +58,9 @@ sub checkconfig () { #{{{
|
||||||
\]\] # end of link
|
\]\] # end of link
|
||||||
}x,
|
}x,
|
||||||
}
|
}
|
||||||
} #}}}
|
}
|
||||||
|
|
||||||
sub linkify (@) { #{{{
|
sub linkify (@) {
|
||||||
my %params=@_;
|
my %params=@_;
|
||||||
my $page=$params{page};
|
my $page=$params{page};
|
||||||
my $destpage=$params{destpage};
|
my $destpage=$params{destpage};
|
||||||
|
@ -78,9 +78,9 @@ sub linkify (@) { #{{{
|
||||||
}eg;
|
}eg;
|
||||||
|
|
||||||
return $params{content};
|
return $params{content};
|
||||||
} #}}}
|
}
|
||||||
|
|
||||||
sub scan (@) { #{{{
|
sub scan (@) {
|
||||||
my %params=@_;
|
my %params=@_;
|
||||||
my $page=$params{page};
|
my $page=$params{page};
|
||||||
my $content=$params{content};
|
my $content=$params{content};
|
||||||
|
@ -88,9 +88,9 @@ sub scan (@) { #{{{
|
||||||
while ($content =~ /(?<!\\)$link_regexp/g) {
|
while ($content =~ /(?<!\\)$link_regexp/g) {
|
||||||
push @{$links{$page}}, linkpage($2);
|
push @{$links{$page}}, linkpage($2);
|
||||||
}
|
}
|
||||||
} # }}}
|
}
|
||||||
|
|
||||||
sub renamepage (@) { #{{{
|
sub renamepage (@) {
|
||||||
my %params=@_;
|
my %params=@_;
|
||||||
my $page=$params{page};
|
my $page=$params{page};
|
||||||
my $old=$params{oldpage};
|
my $old=$params{oldpage};
|
||||||
|
@ -118,6 +118,6 @@ sub renamepage (@) { #{{{
|
||||||
}eg;
|
}eg;
|
||||||
|
|
||||||
return $params{content};
|
return $params{content};
|
||||||
} #}}}
|
}
|
||||||
|
|
||||||
1
|
1
|
||||||
|
|
|
@ -3,27 +3,27 @@ package IkiWiki::Plugin::linkmap;
|
||||||
|
|
||||||
use warnings;
|
use warnings;
|
||||||
use strict;
|
use strict;
|
||||||
use IkiWiki 2.00;
|
use IkiWiki 3.00;
|
||||||
use IPC::Open2;
|
use IPC::Open2;
|
||||||
|
|
||||||
sub import { #{{{
|
sub import {
|
||||||
hook(type => "getsetup", id => "linkmap", call => \&getsetup);
|
hook(type => "getsetup", id => "linkmap", call => \&getsetup);
|
||||||
hook(type => "preprocess", id => "linkmap", call => \&preprocess);
|
hook(type => "preprocess", id => "linkmap", call => \&preprocess);
|
||||||
hook(type => "format", id => "linkmap", call => \&format);
|
hook(type => "format", id => "linkmap", call => \&format);
|
||||||
} # }}}
|
}
|
||||||
|
|
||||||
sub getsetup () { #{{{
|
sub getsetup () {
|
||||||
return
|
return
|
||||||
plugin => {
|
plugin => {
|
||||||
safe => 1,
|
safe => 1,
|
||||||
rebuild => undef,
|
rebuild => undef,
|
||||||
},
|
},
|
||||||
} #}}}
|
}
|
||||||
|
|
||||||
my $mapnum=0;
|
my $mapnum=0;
|
||||||
my %maps;
|
my %maps;
|
||||||
|
|
||||||
sub preprocess (@) { #{{{
|
sub preprocess (@) {
|
||||||
my %params=@_;
|
my %params=@_;
|
||||||
|
|
||||||
$params{pages}="*" unless defined $params{pages};
|
$params{pages}="*" unless defined $params{pages};
|
||||||
|
@ -39,17 +39,17 @@ sub preprocess (@) { #{{{
|
||||||
$mapnum++;
|
$mapnum++;
|
||||||
$maps{$mapnum}=\%params;
|
$maps{$mapnum}=\%params;
|
||||||
return "<div class=\"linkmap$mapnum\"></div>";
|
return "<div class=\"linkmap$mapnum\"></div>";
|
||||||
} # }}}
|
}
|
||||||
|
|
||||||
sub format (@) { #{{{
|
sub format (@) {
|
||||||
my %params=@_;
|
my %params=@_;
|
||||||
|
|
||||||
$params{content}=~s/<div class=\"linkmap(\d+)"><\/div>/genmap($1)/eg;
|
$params{content}=~s/<div class=\"linkmap(\d+)"><\/div>/genmap($1)/eg;
|
||||||
|
|
||||||
return $params{content};
|
return $params{content};
|
||||||
} # }}}
|
}
|
||||||
|
|
||||||
sub genmap ($) { #{{{
|
sub genmap ($) {
|
||||||
my $mapnum=shift;
|
my $mapnum=shift;
|
||||||
return "" unless exists $maps{$mapnum};
|
return "" unless exists $maps{$mapnum};
|
||||||
my %params=%{$maps{$mapnum}};
|
my %params=%{$maps{$mapnum}};
|
||||||
|
@ -106,6 +106,6 @@ sub genmap ($) { #{{{
|
||||||
error gettext("failed to run dot") if $sigpipe;
|
error gettext("failed to run dot") if $sigpipe;
|
||||||
|
|
||||||
return $ret;
|
return $ret;
|
||||||
} #}}}
|
}
|
||||||
|
|
||||||
1
|
1
|
||||||
|
|
|
@ -4,17 +4,17 @@ package IkiWiki::Plugin::listdirectives;
|
||||||
|
|
||||||
use warnings;
|
use warnings;
|
||||||
use strict;
|
use strict;
|
||||||
use IkiWiki 2.00;
|
use IkiWiki 3.00;
|
||||||
|
|
||||||
sub import { #{{{
|
sub import {
|
||||||
add_underlay("directives");
|
add_underlay("directives");
|
||||||
hook(type => "getsetup", id => "listdirectives", call => \&getsetup);
|
hook(type => "getsetup", id => "listdirectives", call => \&getsetup);
|
||||||
hook(type => "checkconfig", id => "listdirectives", call => \&checkconfig);
|
hook(type => "checkconfig", id => "listdirectives", call => \&checkconfig);
|
||||||
hook(type => "needsbuild", id => "listdirectives", call => \&needsbuild);
|
hook(type => "needsbuild", id => "listdirectives", call => \&needsbuild);
|
||||||
hook(type => "preprocess", id => "listdirectives", call => \&preprocess);
|
hook(type => "preprocess", id => "listdirectives", call => \&preprocess);
|
||||||
} # }}}
|
}
|
||||||
|
|
||||||
sub getsetup () { #{{{
|
sub getsetup () {
|
||||||
return
|
return
|
||||||
plugin => {
|
plugin => {
|
||||||
safe => 1,
|
safe => 1,
|
||||||
|
@ -27,28 +27,27 @@ sub getsetup () { #{{{
|
||||||
safe => 1,
|
safe => 1,
|
||||||
rebuild => 1,
|
rebuild => 1,
|
||||||
},
|
},
|
||||||
} #}}}
|
}
|
||||||
|
|
||||||
my @fulllist;
|
my @fulllist;
|
||||||
my @earlylist;
|
my @shortlist;
|
||||||
my $pluginstring;
|
my $pluginstring;
|
||||||
|
|
||||||
sub checkconfig () { #{{{
|
sub checkconfig () {
|
||||||
if (! defined $config{directive_description_dir}) {
|
if (! defined $config{directive_description_dir}) {
|
||||||
$config{directive_description_dir} = "ikiwiki/directive";
|
$config{directive_description_dir} = "ikiwiki/directive";
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
$config{directive_description_dir} =~ s/\/+$//;
|
$config{directive_description_dir} =~ s/\/+$//;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@earlylist = sort keys %{$IkiWiki::hooks{preprocess}};
|
sub needsbuild (@) {
|
||||||
} #}}}
|
|
||||||
|
|
||||||
sub needsbuild (@) { #{{{
|
|
||||||
my $needsbuild=shift;
|
my $needsbuild=shift;
|
||||||
|
|
||||||
@fulllist = sort keys %{$IkiWiki::hooks{preprocess}};
|
@fulllist = sort keys %{$IkiWiki::hooks{preprocess}};
|
||||||
$pluginstring = join(' ', @earlylist) . " : " . join(' ', @fulllist);
|
@shortlist = grep { ! $IkiWiki::hooks{preprocess}{$_}{shortcut} } @fulllist;
|
||||||
|
$pluginstring = join(' ', @shortlist) . " : " . join(' ', @fulllist);
|
||||||
|
|
||||||
foreach my $page (keys %pagestate) {
|
foreach my $page (keys %pagestate) {
|
||||||
if (exists $pagestate{$page}{listdirectives}{shown}) {
|
if (exists $pagestate{$page}{listdirectives}{shown}) {
|
||||||
|
@ -64,9 +63,9 @@ sub needsbuild (@) { #{{{
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} # }}}
|
}
|
||||||
|
|
||||||
sub preprocess (@) { #{{{
|
sub preprocess (@) {
|
||||||
my %params=@_;
|
my %params=@_;
|
||||||
|
|
||||||
$pagestate{$params{destpage}}{listdirectives}{shown}=$pluginstring;
|
$pagestate{$params{destpage}}{listdirectives}{shown}=$pluginstring;
|
||||||
|
@ -77,7 +76,7 @@ sub preprocess (@) { #{{{
|
||||||
@pluginlist = @fulllist;
|
@pluginlist = @fulllist;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
@pluginlist = @earlylist;
|
@pluginlist = @shortlist;
|
||||||
}
|
}
|
||||||
|
|
||||||
my $result = '<ul class="listdirectives">';
|
my $result = '<ul class="listdirectives">';
|
||||||
|
@ -93,6 +92,6 @@ sub preprocess (@) { #{{{
|
||||||
$result .= "</ul>";
|
$result .= "</ul>";
|
||||||
|
|
||||||
return $result;
|
return $result;
|
||||||
} # }}}
|
}
|
||||||
|
|
||||||
1
|
1
|
||||||
|
|
|
@ -3,16 +3,14 @@ package IkiWiki::Plugin::lockedit;
|
||||||
|
|
||||||
use warnings;
|
use warnings;
|
||||||
use strict;
|
use strict;
|
||||||
use IkiWiki 2.00;
|
use IkiWiki 3.00;
|
||||||
|
|
||||||
sub import { #{{{
|
sub import {
|
||||||
hook(type => "getsetup", id => "lockedit", call => \&getsetup);
|
hook(type => "getsetup", id => "lockedit", call => \&getsetup);
|
||||||
hook(type => "canedit", id => "lockedit", call => \&canedit);
|
hook(type => "canedit", id => "lockedit", call => \&canedit);
|
||||||
hook(type => "formbuilder_setup", id => "lockedit",
|
}
|
||||||
call => \&formbuilder_setup);
|
|
||||||
} # }}}
|
|
||||||
|
|
||||||
sub getsetup () { #{{{
|
sub getsetup () {
|
||||||
return
|
return
|
||||||
plugin => {
|
plugin => {
|
||||||
safe => 1,
|
safe => 1,
|
||||||
|
@ -26,9 +24,9 @@ sub getsetup () { #{{{
|
||||||
safe => 1,
|
safe => 1,
|
||||||
rebuild => 0,
|
rebuild => 0,
|
||||||
},
|
},
|
||||||
} #}}}
|
}
|
||||||
|
|
||||||
sub canedit ($$) { #{{{
|
sub canedit ($$) {
|
||||||
my $page=shift;
|
my $page=shift;
|
||||||
my $cgi=shift;
|
my $cgi=shift;
|
||||||
my $session=shift;
|
my $session=shift;
|
||||||
|
@ -52,63 +50,7 @@ sub canedit ($$) { #{{{
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
# XXX deprecated, should be removed eventually
|
|
||||||
foreach my $admin (@{$config{adminuser}}) {
|
|
||||||
if (pagespec_match($page, IkiWiki::userinfo_get($admin, "locked_pages"),
|
|
||||||
user => $session->param("name"),
|
|
||||||
ip => $ENV{REMOTE_ADDR},
|
|
||||||
)) {
|
|
||||||
if (! defined $user ||
|
|
||||||
! IkiWiki::userinfo_get($session->param("name"), "regdate")) {
|
|
||||||
return sub { IkiWiki::needsignin($cgi, $session) };
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
return sprintf(gettext("%s is locked and cannot be edited"),
|
|
||||||
htmllink("", "", $page, noimageinline => 1));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return undef;
|
return undef;
|
||||||
} #}}}
|
}
|
||||||
|
|
||||||
sub formbuilder_setup (@) { #{{{
|
|
||||||
my %params=@_;
|
|
||||||
|
|
||||||
# XXX deprecated, should be removed eventually
|
|
||||||
my $form=$params{form};
|
|
||||||
if ($form->title eq "preferences") {
|
|
||||||
my $session=$params{session};
|
|
||||||
my $cgi=$params{cgi};
|
|
||||||
my $user_name=$session->param("name");
|
|
||||||
|
|
||||||
$form->field(name => "locked_pages", size => 50,
|
|
||||||
fieldset => "admin",
|
|
||||||
comment => "deprecated; please move to locked_pages in setup file"
|
|
||||||
);
|
|
||||||
if (! IkiWiki::is_admin($user_name)) {
|
|
||||||
$form->field(name => "locked_pages", type => "hidden");
|
|
||||||
}
|
|
||||||
if (! $form->submitted) {
|
|
||||||
my $value=IkiWiki::userinfo_get($user_name, "locked_pages");
|
|
||||||
if (length $value) {
|
|
||||||
$form->field(name => "locked_pages", force => 1, value => $value);
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
$form->field(name => "locked_pages", type => "hidden");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if ($form->submitted && $form->submitted eq 'Save Preferences') {
|
|
||||||
if (defined $form->field("locked_pages")) {
|
|
||||||
IkiWiki::userinfo_set($user_name, "locked_pages",
|
|
||||||
$form->field("locked_pages")) ||
|
|
||||||
error("failed to set locked_pages");
|
|
||||||
if (! length $form->field("locked_pages")) {
|
|
||||||
$form->field(name => "locked_pages", type => "hidden");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} #}}}
|
|
||||||
|
|
||||||
1
|
1
|
||||||
|
|
|
@ -9,22 +9,22 @@ package IkiWiki::Plugin::map;
|
||||||
|
|
||||||
use warnings;
|
use warnings;
|
||||||
use strict;
|
use strict;
|
||||||
use IkiWiki 2.00;
|
use IkiWiki 3.00;
|
||||||
|
|
||||||
sub import { #{{{
|
sub import {
|
||||||
hook(type => "getsetup", id => "map", call => \&getsetup);
|
hook(type => "getsetup", id => "map", call => \&getsetup);
|
||||||
hook(type => "preprocess", id => "map", call => \&preprocess);
|
hook(type => "preprocess", id => "map", call => \&preprocess);
|
||||||
} # }}}
|
}
|
||||||
|
|
||||||
sub getsetup () { #{{{
|
sub getsetup () {
|
||||||
return
|
return
|
||||||
plugin => {
|
plugin => {
|
||||||
safe => 1,
|
safe => 1,
|
||||||
rebuild => undef,
|
rebuild => undef,
|
||||||
},
|
},
|
||||||
} #}}}
|
}
|
||||||
|
|
||||||
sub preprocess (@) { #{{{
|
sub preprocess (@) {
|
||||||
my %params=@_;
|
my %params=@_;
|
||||||
$params{pages}="*" unless defined $params{pages};
|
$params{pages}="*" unless defined $params{pages};
|
||||||
|
|
||||||
|
@ -144,6 +144,6 @@ sub preprocess (@) { #{{{
|
||||||
}
|
}
|
||||||
$map .= "</div>\n";
|
$map .= "</div>\n";
|
||||||
return $map;
|
return $map;
|
||||||
} # }}}
|
}
|
||||||
|
|
||||||
1
|
1
|
||||||
|
|
|
@ -4,14 +4,14 @@ package IkiWiki::Plugin::mdwn;
|
||||||
|
|
||||||
use warnings;
|
use warnings;
|
||||||
use strict;
|
use strict;
|
||||||
use IkiWiki 2.00;
|
use IkiWiki 3.00;
|
||||||
|
|
||||||
sub import { #{{{
|
sub import {
|
||||||
hook(type => "getsetup", id => "mdwn", call => \&getsetup);
|
hook(type => "getsetup", id => "mdwn", call => \&getsetup);
|
||||||
hook(type => "htmlize", id => "mdwn", call => \&htmlize);
|
hook(type => "htmlize", id => "mdwn", call => \&htmlize);
|
||||||
} # }}}
|
}
|
||||||
|
|
||||||
sub getsetup () { #{{{
|
sub getsetup () {
|
||||||
return
|
return
|
||||||
plugin => {
|
plugin => {
|
||||||
safe => 1,
|
safe => 1,
|
||||||
|
@ -24,10 +24,10 @@ sub getsetup () { #{{{
|
||||||
safe => 1,
|
safe => 1,
|
||||||
rebuild => 1,
|
rebuild => 1,
|
||||||
},
|
},
|
||||||
} #}}}
|
}
|
||||||
|
|
||||||
my $markdown_sub;
|
my $markdown_sub;
|
||||||
sub htmlize (@) { #{{{
|
sub htmlize (@) {
|
||||||
my %params=@_;
|
my %params=@_;
|
||||||
my $content = $params{content};
|
my $content = $params{content};
|
||||||
|
|
||||||
|
@ -83,6 +83,6 @@ sub htmlize (@) { #{{{
|
||||||
$content=Encode::decode_utf8($content);
|
$content=Encode::decode_utf8($content);
|
||||||
|
|
||||||
return $content;
|
return $content;
|
||||||
} # }}}
|
}
|
||||||
|
|
||||||
1
|
1
|
||||||
|
|
|
@ -7,7 +7,7 @@ use IkiWiki;
|
||||||
use Encode;
|
use Encode;
|
||||||
use open qw{:utf8 :std};
|
use open qw{:utf8 :std};
|
||||||
|
|
||||||
sub import { #{{{
|
sub import {
|
||||||
hook(type => "checkconfig", id => "mercurial", call => \&checkconfig);
|
hook(type => "checkconfig", id => "mercurial", call => \&checkconfig);
|
||||||
hook(type => "getsetup", id => "mercurial", call => \&getsetup);
|
hook(type => "getsetup", id => "mercurial", call => \&getsetup);
|
||||||
hook(type => "rcs", id => "rcs_update", call => \&rcs_update);
|
hook(type => "rcs", id => "rcs_update", call => \&rcs_update);
|
||||||
|
@ -20,18 +20,18 @@ sub import { #{{{
|
||||||
hook(type => "rcs", id => "rcs_recentchanges", call => \&rcs_recentchanges);
|
hook(type => "rcs", id => "rcs_recentchanges", call => \&rcs_recentchanges);
|
||||||
hook(type => "rcs", id => "rcs_diff", call => \&rcs_diff);
|
hook(type => "rcs", id => "rcs_diff", call => \&rcs_diff);
|
||||||
hook(type => "rcs", id => "rcs_getctime", call => \&rcs_getctime);
|
hook(type => "rcs", id => "rcs_getctime", call => \&rcs_getctime);
|
||||||
} #}}}
|
}
|
||||||
|
|
||||||
sub checkconfig () { #{{{
|
sub checkconfig () {
|
||||||
if (exists $config{mercurial_wrapper} && length $config{mercurial_wrapper}) {
|
if (exists $config{mercurial_wrapper} && length $config{mercurial_wrapper}) {
|
||||||
push @{$config{wrappers}}, {
|
push @{$config{wrappers}}, {
|
||||||
wrapper => $config{mercurial_wrapper},
|
wrapper => $config{mercurial_wrapper},
|
||||||
wrappermode => (defined $config{mercurial_wrappermode} ? $config{mercurial_wrappermode} : "06755"),
|
wrappermode => (defined $config{mercurial_wrappermode} ? $config{mercurial_wrappermode} : "06755"),
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
} #}}}
|
}
|
||||||
|
|
||||||
sub getsetup () { #{{{
|
sub getsetup () {
|
||||||
return
|
return
|
||||||
plugin => {
|
plugin => {
|
||||||
safe => 0, # rcs plugin
|
safe => 0, # rcs plugin
|
||||||
|
@ -65,9 +65,9 @@ sub getsetup () { #{{{
|
||||||
safe => 1,
|
safe => 1,
|
||||||
rebuild => 1,
|
rebuild => 1,
|
||||||
},
|
},
|
||||||
} #}}}
|
}
|
||||||
|
|
||||||
sub mercurial_log ($) { #{{{
|
sub mercurial_log ($) {
|
||||||
my $out = shift;
|
my $out = shift;
|
||||||
my @infos;
|
my @infos;
|
||||||
|
|
||||||
|
@ -111,20 +111,20 @@ sub mercurial_log ($) { #{{{
|
||||||
close $out;
|
close $out;
|
||||||
|
|
||||||
return @infos;
|
return @infos;
|
||||||
} #}}}
|
}
|
||||||
|
|
||||||
sub rcs_update () { #{{{
|
sub rcs_update () {
|
||||||
my @cmdline = ("hg", "-q", "-R", "$config{srcdir}", "update");
|
my @cmdline = ("hg", "-q", "-R", "$config{srcdir}", "update");
|
||||||
if (system(@cmdline) != 0) {
|
if (system(@cmdline) != 0) {
|
||||||
warn "'@cmdline' failed: $!";
|
warn "'@cmdline' failed: $!";
|
||||||
}
|
}
|
||||||
} #}}}
|
}
|
||||||
|
|
||||||
sub rcs_prepedit ($) { #{{{
|
sub rcs_prepedit ($) {
|
||||||
return "";
|
return "";
|
||||||
} #}}}
|
}
|
||||||
|
|
||||||
sub rcs_commit ($$$;$$) { #{{{
|
sub rcs_commit ($$$;$$) {
|
||||||
my ($file, $message, $rcstoken, $user, $ipaddr) = @_;
|
my ($file, $message, $rcstoken, $user, $ipaddr) = @_;
|
||||||
|
|
||||||
if (defined $user) {
|
if (defined $user) {
|
||||||
|
@ -149,7 +149,7 @@ sub rcs_commit ($$$;$$) { #{{{
|
||||||
}
|
}
|
||||||
|
|
||||||
return undef; # success
|
return undef; # success
|
||||||
} #}}}
|
}
|
||||||
|
|
||||||
sub rcs_commit_staged ($$$) {
|
sub rcs_commit_staged ($$$) {
|
||||||
# Commits all staged changes. Changes can be staged using rcs_add,
|
# Commits all staged changes. Changes can be staged using rcs_add,
|
||||||
|
@ -159,28 +159,28 @@ sub rcs_commit_staged ($$$) {
|
||||||
error("rcs_commit_staged not implemented for mercurial"); # TODO
|
error("rcs_commit_staged not implemented for mercurial"); # TODO
|
||||||
}
|
}
|
||||||
|
|
||||||
sub rcs_add ($) { # {{{
|
sub rcs_add ($) {
|
||||||
my ($file) = @_;
|
my ($file) = @_;
|
||||||
|
|
||||||
my @cmdline = ("hg", "-q", "-R", "$config{srcdir}", "add", "$config{srcdir}/$file");
|
my @cmdline = ("hg", "-q", "-R", "$config{srcdir}", "add", "$config{srcdir}/$file");
|
||||||
if (system(@cmdline) != 0) {
|
if (system(@cmdline) != 0) {
|
||||||
warn "'@cmdline' failed: $!";
|
warn "'@cmdline' failed: $!";
|
||||||
}
|
}
|
||||||
} #}}}
|
}
|
||||||
|
|
||||||
sub rcs_remove ($) { # {{{
|
sub rcs_remove ($) {
|
||||||
my ($file) = @_;
|
my ($file) = @_;
|
||||||
|
|
||||||
error("rcs_remove not implemented for mercurial"); # TODO
|
error("rcs_remove not implemented for mercurial"); # TODO
|
||||||
} #}}}
|
}
|
||||||
|
|
||||||
sub rcs_rename ($$) { # {{{
|
sub rcs_rename ($$) {
|
||||||
my ($src, $dest) = @_;
|
my ($src, $dest) = @_;
|
||||||
|
|
||||||
error("rcs_rename not implemented for mercurial"); # TODO
|
error("rcs_rename not implemented for mercurial"); # TODO
|
||||||
} #}}}
|
}
|
||||||
|
|
||||||
sub rcs_recentchanges ($) { #{{{
|
sub rcs_recentchanges ($) {
|
||||||
my ($num) = @_;
|
my ($num) = @_;
|
||||||
|
|
||||||
my @cmdline = ("hg", "-R", $config{srcdir}, "log", "-v", "-l", $num,
|
my @cmdline = ("hg", "-R", $config{srcdir}, "log", "-v", "-l", $num,
|
||||||
|
@ -217,7 +217,7 @@ sub rcs_recentchanges ($) { #{{{
|
||||||
push @ret, {
|
push @ret, {
|
||||||
rev => $info->{"changeset"},
|
rev => $info->{"changeset"},
|
||||||
user => $user,
|
user => $user,
|
||||||
committype => "mercurial",
|
committype => "hg",
|
||||||
when => str2time($info->{"date"}),
|
when => str2time($info->{"date"}),
|
||||||
message => [@message],
|
message => [@message],
|
||||||
pages => [@pages],
|
pages => [@pages],
|
||||||
|
@ -225,18 +225,18 @@ sub rcs_recentchanges ($) { #{{{
|
||||||
}
|
}
|
||||||
|
|
||||||
return @ret;
|
return @ret;
|
||||||
} #}}}
|
}
|
||||||
|
|
||||||
sub rcs_diff ($) { #{{{
|
sub rcs_diff ($) {
|
||||||
# TODO
|
# TODO
|
||||||
} #}}}
|
}
|
||||||
|
|
||||||
sub rcs_getctime ($) { #{{{
|
sub rcs_getctime ($) {
|
||||||
my ($file) = @_;
|
my ($file) = @_;
|
||||||
|
|
||||||
# XXX filename passes through the shell here, should try to avoid
|
# XXX filename passes through the shell here, should try to avoid
|
||||||
# that just in case
|
# that just in case
|
||||||
my @cmdline = ("hg", "-R", $config{srcdir}, "log", "-v", "-l", '1',
|
my @cmdline = ("hg", "-R", $config{srcdir}, "log", "-v",
|
||||||
"--style", "default", "$config{srcdir}/$file");
|
"--style", "default", "$config{srcdir}/$file");
|
||||||
open (my $out, "@cmdline |");
|
open (my $out, "@cmdline |");
|
||||||
|
|
||||||
|
@ -249,8 +249,8 @@ sub rcs_getctime ($) { #{{{
|
||||||
eval q{use Date::Parse};
|
eval q{use Date::Parse};
|
||||||
error($@) if $@;
|
error($@) if $@;
|
||||||
|
|
||||||
my $ctime = str2time($log[0]->{"date"});
|
my $ctime = str2time($log[$#log]->{"date"});
|
||||||
return $ctime;
|
return $ctime;
|
||||||
} #}}}
|
}
|
||||||
|
|
||||||
1
|
1
|
||||||
|
|
|
@ -4,26 +4,26 @@ package IkiWiki::Plugin::meta;
|
||||||
|
|
||||||
use warnings;
|
use warnings;
|
||||||
use strict;
|
use strict;
|
||||||
use IkiWiki 2.00;
|
use IkiWiki 3.00;
|
||||||
|
|
||||||
my %metaheaders;
|
my %metaheaders;
|
||||||
|
|
||||||
sub import { #{{{
|
sub import {
|
||||||
hook(type => "getsetup", id => "meta", call => \&getsetup);
|
hook(type => "getsetup", id => "meta", call => \&getsetup);
|
||||||
hook(type => "needsbuild", id => "meta", call => \&needsbuild);
|
hook(type => "needsbuild", id => "meta", call => \&needsbuild);
|
||||||
hook(type => "preprocess", id => "meta", call => \&preprocess, scan => 1);
|
hook(type => "preprocess", id => "meta", call => \&preprocess, scan => 1);
|
||||||
hook(type => "pagetemplate", id => "meta", call => \&pagetemplate);
|
hook(type => "pagetemplate", id => "meta", call => \&pagetemplate);
|
||||||
} # }}}
|
}
|
||||||
|
|
||||||
sub getsetup () { #{{{
|
sub getsetup () {
|
||||||
return
|
return
|
||||||
plugin => {
|
plugin => {
|
||||||
safe => 1,
|
safe => 1,
|
||||||
rebuild => undef,
|
rebuild => undef,
|
||||||
},
|
},
|
||||||
} #}}}
|
}
|
||||||
|
|
||||||
sub needsbuild (@) { #{{{
|
sub needsbuild (@) {
|
||||||
my $needsbuild=shift;
|
my $needsbuild=shift;
|
||||||
foreach my $page (keys %pagestate) {
|
foreach my $page (keys %pagestate) {
|
||||||
if (exists $pagestate{$page}{meta}) {
|
if (exists $pagestate{$page}{meta}) {
|
||||||
|
@ -38,16 +38,17 @@ sub needsbuild (@) { #{{{
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
sub scrub ($) { #{{{
|
sub scrub ($$) {
|
||||||
if (IkiWiki::Plugin::htmlscrubber->can("sanitize")) {
|
if (IkiWiki::Plugin::htmlscrubber->can("sanitize")) {
|
||||||
return IkiWiki::Plugin::htmlscrubber::sanitize(content => shift);
|
return IkiWiki::Plugin::htmlscrubber::sanitize(
|
||||||
|
content => shift, destpage => shift);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
return shift;
|
return shift;
|
||||||
}
|
}
|
||||||
} #}}}
|
}
|
||||||
|
|
||||||
sub safeurl ($) { #{{{
|
sub safeurl ($) {
|
||||||
my $url=shift;
|
my $url=shift;
|
||||||
if (exists $IkiWiki::Plugin::htmlscrubber::{safe_url_regexp} &&
|
if (exists $IkiWiki::Plugin::htmlscrubber::{safe_url_regexp} &&
|
||||||
defined $IkiWiki::Plugin::htmlscrubber::safe_url_regexp) {
|
defined $IkiWiki::Plugin::htmlscrubber::safe_url_regexp) {
|
||||||
|
@ -56,9 +57,9 @@ sub safeurl ($) { #{{{
|
||||||
else {
|
else {
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
} #}}}
|
}
|
||||||
|
|
||||||
sub htmlize ($$$) { #{{{
|
sub htmlize ($$$) {
|
||||||
my $page = shift;
|
my $page = shift;
|
||||||
my $destpage = shift;
|
my $destpage = shift;
|
||||||
|
|
||||||
|
@ -67,7 +68,7 @@ sub htmlize ($$$) { #{{{
|
||||||
IkiWiki::preprocess($page, $destpage, shift)));
|
IkiWiki::preprocess($page, $destpage, shift)));
|
||||||
}
|
}
|
||||||
|
|
||||||
sub preprocess (@) { #{{{
|
sub preprocess (@) {
|
||||||
return "" unless @_;
|
return "" unless @_;
|
||||||
my %params=@_;
|
my %params=@_;
|
||||||
my $key=shift;
|
my $key=shift;
|
||||||
|
@ -120,6 +121,20 @@ sub preprocess (@) { #{{{
|
||||||
$pagestate{$page}{meta}{authorurl}=$value if safeurl($value);
|
$pagestate{$page}{meta}{authorurl}=$value if safeurl($value);
|
||||||
# fallthrough
|
# fallthrough
|
||||||
}
|
}
|
||||||
|
elsif ($key eq 'date') {
|
||||||
|
eval q{use Date::Parse};
|
||||||
|
if (! $@) {
|
||||||
|
my $time = str2time($value);
|
||||||
|
$IkiWiki::pagectime{$page}=$time if defined $time;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
elsif ($key eq 'updated') {
|
||||||
|
eval q{use Date::Parse};
|
||||||
|
if (! $@) {
|
||||||
|
my $time = str2time($value);
|
||||||
|
$pagestate{$page}{meta}{updated}=$time if defined $time;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (! defined wantarray) {
|
if (! defined wantarray) {
|
||||||
# avoid collecting duplicate data during scan pass
|
# avoid collecting duplicate data during scan pass
|
||||||
|
@ -127,17 +142,10 @@ sub preprocess (@) { #{{{
|
||||||
}
|
}
|
||||||
|
|
||||||
# Metadata collection that happens only during preprocessing pass.
|
# Metadata collection that happens only during preprocessing pass.
|
||||||
if ($key eq 'date') {
|
if ($key eq 'permalink') {
|
||||||
eval q{use Date::Parse};
|
|
||||||
if (! $@) {
|
|
||||||
my $time = str2time($value);
|
|
||||||
$IkiWiki::pagectime{$page}=$time if defined $time;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
elsif ($key eq 'permalink') {
|
|
||||||
if (safeurl($value)) {
|
if (safeurl($value)) {
|
||||||
$pagestate{$page}{meta}{permalink}=$value;
|
$pagestate{$page}{meta}{permalink}=$value;
|
||||||
push @{$metaheaders{$page}}, scrub('<link rel="bookmark" href="'.encode_entities($value).'" />');
|
push @{$metaheaders{$page}}, scrub('<link rel="bookmark" href="'.encode_entities($value).'" />', $destpage);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
elsif ($key eq 'stylesheet') {
|
elsif ($key eq 'stylesheet') {
|
||||||
|
@ -206,7 +214,7 @@ sub preprocess (@) { #{{{
|
||||||
my $delay=int(exists $params{delay} ? $params{delay} : 0);
|
my $delay=int(exists $params{delay} ? $params{delay} : 0);
|
||||||
my $redir="<meta http-equiv=\"refresh\" content=\"$delay; URL=$value\" />";
|
my $redir="<meta http-equiv=\"refresh\" content=\"$delay; URL=$value\" />";
|
||||||
if (! $safe) {
|
if (! $safe) {
|
||||||
$redir=scrub($redir);
|
$redir=scrub($redir, $destpage);
|
||||||
}
|
}
|
||||||
push @{$metaheaders{$page}}, $redir;
|
push @{$metaheaders{$page}}, $redir;
|
||||||
}
|
}
|
||||||
|
@ -216,7 +224,7 @@ sub preprocess (@) { #{{{
|
||||||
join(" ", map {
|
join(" ", map {
|
||||||
encode_entities($_)."=\"".encode_entities(decode_entities($params{$_}))."\""
|
encode_entities($_)."=\"".encode_entities(decode_entities($params{$_}))."\""
|
||||||
} keys %params).
|
} keys %params).
|
||||||
" />\n");
|
" />\n", $destpage);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
elsif ($key eq 'robots') {
|
elsif ($key eq 'robots') {
|
||||||
|
@ -225,13 +233,13 @@ sub preprocess (@) { #{{{
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
push @{$metaheaders{$page}}, scrub('<meta name="'.encode_entities($key).
|
push @{$metaheaders{$page}}, scrub('<meta name="'.encode_entities($key).
|
||||||
'" content="'.encode_entities($value).'" />');
|
'" content="'.encode_entities($value).'" />', $destpage);
|
||||||
}
|
}
|
||||||
|
|
||||||
return "";
|
return "";
|
||||||
} # }}}
|
}
|
||||||
|
|
||||||
sub pagetemplate (@) { #{{{
|
sub pagetemplate (@) {
|
||||||
my %params=@_;
|
my %params=@_;
|
||||||
my $page=$params{page};
|
my $page=$params{page};
|
||||||
my $destpage=$params{destpage};
|
my $destpage=$params{destpage};
|
||||||
|
@ -259,9 +267,9 @@ sub pagetemplate (@) { #{{{
|
||||||
$template->param($field => htmlize($page, $destpage, $pagestate{$page}{meta}{$field}));
|
$template->param($field => htmlize($page, $destpage, $pagestate{$page}{meta}{$field}));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} # }}}
|
}
|
||||||
|
|
||||||
sub match { #{{{
|
sub match {
|
||||||
my $field=shift;
|
my $field=shift;
|
||||||
my $page=shift;
|
my $page=shift;
|
||||||
|
|
||||||
|
@ -287,28 +295,28 @@ sub match { #{{{
|
||||||
else {
|
else {
|
||||||
return IkiWiki::FailReason->new("$page does not have a $field");
|
return IkiWiki::FailReason->new("$page does not have a $field");
|
||||||
}
|
}
|
||||||
} #}}}
|
}
|
||||||
|
|
||||||
package IkiWiki::PageSpec;
|
package IkiWiki::PageSpec;
|
||||||
|
|
||||||
sub match_title ($$;@) { #{{{
|
sub match_title ($$;@) {
|
||||||
IkiWiki::Plugin::meta::match("title", @_);
|
IkiWiki::Plugin::meta::match("title", @_);
|
||||||
} #}}}
|
}
|
||||||
|
|
||||||
sub match_author ($$;@) { #{{{
|
sub match_author ($$;@) {
|
||||||
IkiWiki::Plugin::meta::match("author", @_);
|
IkiWiki::Plugin::meta::match("author", @_);
|
||||||
} #}}}
|
}
|
||||||
|
|
||||||
sub match_authorurl ($$;@) { #{{{
|
sub match_authorurl ($$;@) {
|
||||||
IkiWiki::Plugin::meta::match("authorurl", @_);
|
IkiWiki::Plugin::meta::match("authorurl", @_);
|
||||||
} #}}}
|
}
|
||||||
|
|
||||||
sub match_license ($$;@) { #{{{
|
sub match_license ($$;@) {
|
||||||
IkiWiki::Plugin::meta::match("license", @_);
|
IkiWiki::Plugin::meta::match("license", @_);
|
||||||
} #}}}
|
}
|
||||||
|
|
||||||
sub match_copyright ($$;@) { #{{{
|
sub match_copyright ($$;@) {
|
||||||
IkiWiki::Plugin::meta::match("copyright", @_);
|
IkiWiki::Plugin::meta::match("copyright", @_);
|
||||||
} #}}}
|
}
|
||||||
|
|
||||||
1
|
1
|
||||||
|
|
|
@ -3,14 +3,14 @@ package IkiWiki::Plugin::mirrorlist;
|
||||||
|
|
||||||
use warnings;
|
use warnings;
|
||||||
use strict;
|
use strict;
|
||||||
use IkiWiki 2.00;
|
use IkiWiki 3.00;
|
||||||
|
|
||||||
sub import { #{{{
|
sub import {
|
||||||
hook(type => "getsetup", id => "mirrorlist", call => \&getsetup);
|
hook(type => "getsetup", id => "mirrorlist", call => \&getsetup);
|
||||||
hook(type => "pagetemplate", id => "mirrorlist", call => \&pagetemplate);
|
hook(type => "pagetemplate", id => "mirrorlist", call => \&pagetemplate);
|
||||||
} # }}}
|
}
|
||||||
|
|
||||||
sub getsetup () { #{{{
|
sub getsetup () {
|
||||||
return
|
return
|
||||||
plugin => {
|
plugin => {
|
||||||
safe => 1,
|
safe => 1,
|
||||||
|
@ -23,9 +23,9 @@ sub getsetup () { #{{{
|
||||||
safe => 1,
|
safe => 1,
|
||||||
rebuild => 1,
|
rebuild => 1,
|
||||||
},
|
},
|
||||||
} #}}}
|
}
|
||||||
|
|
||||||
sub pagetemplate (@) { #{{{
|
sub pagetemplate (@) {
|
||||||
my %params=@_;
|
my %params=@_;
|
||||||
my $template=$params{template};
|
my $template=$params{template};
|
||||||
|
|
||||||
|
@ -34,9 +34,9 @@ sub pagetemplate (@) { #{{{
|
||||||
$value.=mirrorlist($params{page});
|
$value.=mirrorlist($params{page});
|
||||||
$template->param(extrafooter => $value);
|
$template->param(extrafooter => $value);
|
||||||
}
|
}
|
||||||
} # }}}
|
}
|
||||||
|
|
||||||
sub mirrorlist ($) { #{{{
|
sub mirrorlist ($) {
|
||||||
my $page=shift;
|
my $page=shift;
|
||||||
return "<p>".
|
return "<p>".
|
||||||
(keys %{$config{mirrorlist}} > 1 ? gettext("Mirrors") : gettext("Mirror")).
|
(keys %{$config{mirrorlist}} > 1 ? gettext("Mirrors") : gettext("Mirror")).
|
||||||
|
@ -49,6 +49,6 @@ sub mirrorlist ($) { #{{{
|
||||||
} keys %{$config{mirrorlist}}
|
} keys %{$config{mirrorlist}}
|
||||||
).
|
).
|
||||||
"</p>";
|
"</p>";
|
||||||
} # }}}
|
}
|
||||||
|
|
||||||
1
|
1
|
||||||
|
|
|
@ -10,7 +10,7 @@ use Date::Format qw(time2str);
|
||||||
|
|
||||||
my $sha1_pattern = qr/[0-9a-fA-F]{40}/; # pattern to validate sha1sums
|
my $sha1_pattern = qr/[0-9a-fA-F]{40}/; # pattern to validate sha1sums
|
||||||
|
|
||||||
sub import { #{{{
|
sub import {
|
||||||
hook(type => "checkconfig", id => "monotone", call => \&checkconfig);
|
hook(type => "checkconfig", id => "monotone", call => \&checkconfig);
|
||||||
hook(type => "getsetup", id => "monotone", call => \&getsetup);
|
hook(type => "getsetup", id => "monotone", call => \&getsetup);
|
||||||
hook(type => "rcs", id => "rcs_update", call => \&rcs_update);
|
hook(type => "rcs", id => "rcs_update", call => \&rcs_update);
|
||||||
|
@ -23,9 +23,9 @@ sub import { #{{{
|
||||||
hook(type => "rcs", id => "rcs_recentchanges", call => \&rcs_recentchanges);
|
hook(type => "rcs", id => "rcs_recentchanges", call => \&rcs_recentchanges);
|
||||||
hook(type => "rcs", id => "rcs_diff", call => \&rcs_diff);
|
hook(type => "rcs", id => "rcs_diff", call => \&rcs_diff);
|
||||||
hook(type => "rcs", id => "rcs_getctime", call => \&rcs_getctime);
|
hook(type => "rcs", id => "rcs_getctime", call => \&rcs_getctime);
|
||||||
} #}}}
|
}
|
||||||
|
|
||||||
sub checkconfig () { #{{{
|
sub checkconfig () {
|
||||||
if (!defined($config{mtnrootdir})) {
|
if (!defined($config{mtnrootdir})) {
|
||||||
$config{mtnrootdir} = $config{srcdir};
|
$config{mtnrootdir} = $config{srcdir};
|
||||||
}
|
}
|
||||||
|
@ -61,9 +61,9 @@ sub checkconfig () { #{{{
|
||||||
wrappermode => (defined $config{mtn_wrappermode} ? $config{mtn_wrappermode} : "06755"),
|
wrappermode => (defined $config{mtn_wrappermode} ? $config{mtn_wrappermode} : "06755"),
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
} #}}}
|
}
|
||||||
|
|
||||||
sub getsetup () { #{{{
|
sub getsetup () {
|
||||||
return
|
return
|
||||||
plugin => {
|
plugin => {
|
||||||
safe => 0, # rcs plugin
|
safe => 0, # rcs plugin
|
||||||
|
@ -117,9 +117,9 @@ sub getsetup () { #{{{
|
||||||
safe => 0, # path
|
safe => 0, # path
|
||||||
rebuild => 0,
|
rebuild => 0,
|
||||||
},
|
},
|
||||||
} #}}}
|
}
|
||||||
|
|
||||||
sub get_rev () { #{{{
|
sub get_rev () {
|
||||||
my $sha1 = `mtn --root=$config{mtnrootdir} automate get_base_revision_id`;
|
my $sha1 = `mtn --root=$config{mtnrootdir} automate get_base_revision_id`;
|
||||||
|
|
||||||
($sha1) = $sha1 =~ m/($sha1_pattern)/; # sha1 is untainted now
|
($sha1) = $sha1 =~ m/($sha1_pattern)/; # sha1 is untainted now
|
||||||
|
@ -128,9 +128,9 @@ sub get_rev () { #{{{
|
||||||
}
|
}
|
||||||
|
|
||||||
return $sha1;
|
return $sha1;
|
||||||
} #}}}
|
}
|
||||||
|
|
||||||
sub get_rev_auto ($) { #{{{
|
sub get_rev_auto ($) {
|
||||||
my $automator=shift;
|
my $automator=shift;
|
||||||
|
|
||||||
my @results = $automator->call("get_base_revision_id");
|
my @results = $automator->call("get_base_revision_id");
|
||||||
|
@ -142,9 +142,9 @@ sub get_rev_auto ($) { #{{{
|
||||||
}
|
}
|
||||||
|
|
||||||
return $sha1;
|
return $sha1;
|
||||||
} #}}}
|
}
|
||||||
|
|
||||||
sub mtn_merge ($$$$) { #{{{
|
sub mtn_merge ($$$$) {
|
||||||
my $leftRev=shift;
|
my $leftRev=shift;
|
||||||
my $rightRev=shift;
|
my $rightRev=shift;
|
||||||
my $branch=shift;
|
my $branch=shift;
|
||||||
|
@ -172,9 +172,9 @@ sub mtn_merge ($$$$) { #{{{
|
||||||
debug("merged $leftRev, $rightRev to make $mergeRev");
|
debug("merged $leftRev, $rightRev to make $mergeRev");
|
||||||
|
|
||||||
return $mergeRev;
|
return $mergeRev;
|
||||||
} #}}}
|
}
|
||||||
|
|
||||||
sub commit_file_to_new_rev ($$$$$$$$) { #{{{
|
sub commit_file_to_new_rev ($$$$$$$$) {
|
||||||
my $automator=shift;
|
my $automator=shift;
|
||||||
my $wsfilename=shift;
|
my $wsfilename=shift;
|
||||||
my $oldFileID=shift;
|
my $oldFileID=shift;
|
||||||
|
@ -219,9 +219,9 @@ sub commit_file_to_new_rev ($$$$$$$$) { #{{{
|
||||||
|
|
||||||
debug("Added certs for rev: $newRevID");
|
debug("Added certs for rev: $newRevID");
|
||||||
return $newRevID;
|
return $newRevID;
|
||||||
} #}}}
|
}
|
||||||
|
|
||||||
sub read_certs ($$) { #{{{
|
sub read_certs ($$) {
|
||||||
my $automator=shift;
|
my $automator=shift;
|
||||||
my $rev=shift;
|
my $rev=shift;
|
||||||
my @results = $automator->call("certs", $rev);
|
my @results = $automator->call("certs", $rev);
|
||||||
|
@ -239,9 +239,9 @@ sub read_certs ($$) { #{{{
|
||||||
}
|
}
|
||||||
|
|
||||||
return @ret;
|
return @ret;
|
||||||
} #}}}
|
}
|
||||||
|
|
||||||
sub get_changed_files ($$) { #{{{
|
sub get_changed_files ($$) {
|
||||||
my $automator=shift;
|
my $automator=shift;
|
||||||
my $rev=shift;
|
my $rev=shift;
|
||||||
|
|
||||||
|
@ -261,9 +261,9 @@ sub get_changed_files ($$) { #{{{
|
||||||
}
|
}
|
||||||
|
|
||||||
return @ret;
|
return @ret;
|
||||||
} #}}}
|
}
|
||||||
|
|
||||||
sub rcs_update () { #{{{
|
sub rcs_update () {
|
||||||
chdir $config{srcdir}
|
chdir $config{srcdir}
|
||||||
or error("Cannot chdir to $config{srcdir}: $!");
|
or error("Cannot chdir to $config{srcdir}: $!");
|
||||||
|
|
||||||
|
@ -278,9 +278,9 @@ sub rcs_update () { #{{{
|
||||||
if (system("mtn", "--root=$config{mtnrootdir}", "update", "--quiet") != 0) {
|
if (system("mtn", "--root=$config{mtnrootdir}", "update", "--quiet") != 0) {
|
||||||
debug("monotone update failed");
|
debug("monotone update failed");
|
||||||
}
|
}
|
||||||
} #}}}
|
}
|
||||||
|
|
||||||
sub rcs_prepedit ($) { #{{{
|
sub rcs_prepedit ($) {
|
||||||
my $file=shift;
|
my $file=shift;
|
||||||
|
|
||||||
chdir $config{srcdir}
|
chdir $config{srcdir}
|
||||||
|
@ -289,9 +289,9 @@ sub rcs_prepedit ($) { #{{{
|
||||||
# For monotone, return the revision of the file when
|
# For monotone, return the revision of the file when
|
||||||
# editing begins.
|
# editing begins.
|
||||||
return get_rev();
|
return get_rev();
|
||||||
} #}}}
|
}
|
||||||
|
|
||||||
sub rcs_commit ($$$;$$) { #{{{
|
sub rcs_commit ($$$;$$) {
|
||||||
# Tries to commit the page; returns undef on _success_ and
|
# Tries to commit the page; returns undef on _success_ and
|
||||||
# a version of the page with the rcs's conflict markers on failure.
|
# a version of the page with the rcs's conflict markers on failure.
|
||||||
# The file is relative to the srcdir.
|
# The file is relative to the srcdir.
|
||||||
|
@ -434,7 +434,7 @@ sub rcs_commit ($$$;$$) { #{{{
|
||||||
}
|
}
|
||||||
|
|
||||||
return undef # success
|
return undef # success
|
||||||
} #}}}
|
}
|
||||||
|
|
||||||
sub rcs_commit_staged ($$$) {
|
sub rcs_commit_staged ($$$) {
|
||||||
# Commits all staged changes. Changes can be staged using rcs_add,
|
# Commits all staged changes. Changes can be staged using rcs_add,
|
||||||
|
@ -466,7 +466,7 @@ sub rcs_commit_staged ($$$) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
sub rcs_add ($) { #{{{
|
sub rcs_add ($) {
|
||||||
my $file=shift;
|
my $file=shift;
|
||||||
|
|
||||||
chdir $config{srcdir}
|
chdir $config{srcdir}
|
||||||
|
@ -476,9 +476,9 @@ sub rcs_add ($) { #{{{
|
||||||
$file) != 0) {
|
$file) != 0) {
|
||||||
error("Monotone add failed");
|
error("Monotone add failed");
|
||||||
}
|
}
|
||||||
} #}}}
|
}
|
||||||
|
|
||||||
sub rcs_remove ($) { # {{{
|
sub rcs_remove ($) {
|
||||||
my $file = shift;
|
my $file = shift;
|
||||||
|
|
||||||
chdir $config{srcdir}
|
chdir $config{srcdir}
|
||||||
|
@ -495,9 +495,9 @@ sub rcs_remove ($) { # {{{
|
||||||
$file) != 0) {
|
$file) != 0) {
|
||||||
error("Monotone remove failed");
|
error("Monotone remove failed");
|
||||||
}
|
}
|
||||||
} #}}}
|
}
|
||||||
|
|
||||||
sub rcs_rename ($$) { # {{{
|
sub rcs_rename ($$) {
|
||||||
my ($src, $dest) = @_;
|
my ($src, $dest) = @_;
|
||||||
|
|
||||||
chdir $config{srcdir}
|
chdir $config{srcdir}
|
||||||
|
@ -507,9 +507,9 @@ sub rcs_rename ($$) { # {{{
|
||||||
$src, $dest) != 0) {
|
$src, $dest) != 0) {
|
||||||
error("Monotone rename failed");
|
error("Monotone rename failed");
|
||||||
}
|
}
|
||||||
} #}}}
|
}
|
||||||
|
|
||||||
sub rcs_recentchanges ($) { #{{{
|
sub rcs_recentchanges ($) {
|
||||||
my $num=shift;
|
my $num=shift;
|
||||||
my @ret;
|
my @ret;
|
||||||
|
|
||||||
|
@ -525,13 +525,12 @@ sub rcs_recentchanges ($) { #{{{
|
||||||
my $child = open(MTNLOG, "-|");
|
my $child = open(MTNLOG, "-|");
|
||||||
if (! $child) {
|
if (! $child) {
|
||||||
exec("mtn", "log", "--root=$config{mtnrootdir}", "--no-graph",
|
exec("mtn", "log", "--root=$config{mtnrootdir}", "--no-graph",
|
||||||
"--brief") || error("mtn log failed to run");
|
"--brief", "--last=$num") || error("mtn log failed to run");
|
||||||
}
|
}
|
||||||
|
|
||||||
while (($num >= 0) and (my $line = <MTNLOG>)) {
|
while (my $line = <MTNLOG>) {
|
||||||
if ($line =~ m/^($sha1_pattern)/) {
|
if ($line =~ m/^($sha1_pattern)/) {
|
||||||
push @revs, $1;
|
push @revs, $1;
|
||||||
$num -= 1;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
close MTNLOG || debug("mtn log exited $?");
|
close MTNLOG || debug("mtn log exited $?");
|
||||||
|
@ -560,7 +559,7 @@ sub rcs_recentchanges ($) { #{{{
|
||||||
if ($cert->{key} eq $config{mtnkey}) {
|
if ($cert->{key} eq $config{mtnkey}) {
|
||||||
$committype = "web";
|
$committype = "web";
|
||||||
} else {
|
} else {
|
||||||
$committype = "monotone";
|
$committype = "mtn";
|
||||||
}
|
}
|
||||||
} elsif ($cert->{name} eq "date") {
|
} elsif ($cert->{name} eq "date") {
|
||||||
$when = str2time($cert->{value}, 'UTC');
|
$when = str2time($cert->{value}, 'UTC');
|
||||||
|
@ -615,9 +614,9 @@ sub rcs_recentchanges ($) { #{{{
|
||||||
$automator->close();
|
$automator->close();
|
||||||
|
|
||||||
return @ret;
|
return @ret;
|
||||||
} #}}}
|
}
|
||||||
|
|
||||||
sub rcs_diff ($) { #{{{
|
sub rcs_diff ($) {
|
||||||
my $rev=shift;
|
my $rev=shift;
|
||||||
my ($sha1) = $rev =~ /^($sha1_pattern)$/; # untaint
|
my ($sha1) = $rev =~ /^($sha1_pattern)$/; # untaint
|
||||||
|
|
||||||
|
@ -639,9 +638,9 @@ sub rcs_diff ($) { #{{{
|
||||||
else {
|
else {
|
||||||
return join("", @lines);
|
return join("", @lines);
|
||||||
}
|
}
|
||||||
} #}}}
|
}
|
||||||
|
|
||||||
sub rcs_getctime ($) { #{{{
|
sub rcs_getctime ($) {
|
||||||
my $file=shift;
|
my $file=shift;
|
||||||
|
|
||||||
chdir $config{srcdir}
|
chdir $config{srcdir}
|
||||||
|
@ -691,6 +690,6 @@ sub rcs_getctime ($) { #{{{
|
||||||
$date=str2time($date, 'UTC');
|
$date=str2time($date, 'UTC');
|
||||||
debug("found ctime ".localtime($date)." for $file");
|
debug("found ctime ".localtime($date)." for $file");
|
||||||
return $date;
|
return $date;
|
||||||
} #}}}
|
}
|
||||||
|
|
||||||
1
|
1
|
||||||
|
|
|
@ -3,24 +3,24 @@ package IkiWiki::Plugin::more;
|
||||||
|
|
||||||
use warnings;
|
use warnings;
|
||||||
use strict;
|
use strict;
|
||||||
use IkiWiki 2.00;
|
use IkiWiki 3.00;
|
||||||
|
|
||||||
my $linktext = gettext("more");
|
my $linktext = gettext("more");
|
||||||
|
|
||||||
sub import { #{{{
|
sub import {
|
||||||
hook(type => "getsetup", id => "more", call => \&getsetup);
|
hook(type => "getsetup", id => "more", call => \&getsetup);
|
||||||
hook(type => "preprocess", id => "more", call => \&preprocess);
|
hook(type => "preprocess", id => "more", call => \&preprocess);
|
||||||
} # }}}
|
}
|
||||||
|
|
||||||
sub getsetup () { #{{{
|
sub getsetup () {
|
||||||
return
|
return
|
||||||
plugin => {
|
plugin => {
|
||||||
safe => 1,
|
safe => 1,
|
||||||
rebuild => undef,
|
rebuild => undef,
|
||||||
},
|
},
|
||||||
} #}}}
|
}
|
||||||
|
|
||||||
sub preprocess (@) { #{{{
|
sub preprocess (@) {
|
||||||
my %params=@_;
|
my %params=@_;
|
||||||
|
|
||||||
$params{linktext} = $linktext unless defined $params{linktext};
|
$params{linktext} = $linktext unless defined $params{linktext};
|
||||||
|
|
|
@ -6,7 +6,7 @@ use warnings;
|
||||||
use strict;
|
use strict;
|
||||||
use IkiWiki;
|
use IkiWiki;
|
||||||
|
|
||||||
sub import { #{{{
|
sub import {
|
||||||
hook(type => "getsetup", id => "norcs", call => \&getsetup);
|
hook(type => "getsetup", id => "norcs", call => \&getsetup);
|
||||||
hook(type => "rcs", id => "rcs_update", call => \&rcs_update);
|
hook(type => "rcs", id => "rcs_update", call => \&rcs_update);
|
||||||
hook(type => "rcs", id => "rcs_prepedit", call => \&rcs_prepedit);
|
hook(type => "rcs", id => "rcs_prepedit", call => \&rcs_prepedit);
|
||||||
|
@ -18,51 +18,51 @@ sub import { #{{{
|
||||||
hook(type => "rcs", id => "rcs_recentchanges", call => \&rcs_recentchanges);
|
hook(type => "rcs", id => "rcs_recentchanges", call => \&rcs_recentchanges);
|
||||||
hook(type => "rcs", id => "rcs_diff", call => \&rcs_diff);
|
hook(type => "rcs", id => "rcs_diff", call => \&rcs_diff);
|
||||||
hook(type => "rcs", id => "rcs_getctime", call => \&rcs_getctime);
|
hook(type => "rcs", id => "rcs_getctime", call => \&rcs_getctime);
|
||||||
} #}}}
|
}
|
||||||
|
|
||||||
sub getsetup () { #{{{
|
sub getsetup () {
|
||||||
return
|
return
|
||||||
plugin => {
|
plugin => {
|
||||||
safe => 0, # rcs plugin
|
safe => 0, # rcs plugin
|
||||||
rebuild => 0,
|
rebuild => 0,
|
||||||
},
|
},
|
||||||
} #}}}
|
}
|
||||||
|
|
||||||
|
|
||||||
sub rcs_update () { #{{{
|
sub rcs_update () {
|
||||||
} #}}}
|
}
|
||||||
|
|
||||||
sub rcs_prepedit ($) { #{{{
|
sub rcs_prepedit ($) {
|
||||||
return ""
|
return ""
|
||||||
} #}}}
|
}
|
||||||
|
|
||||||
sub rcs_commit ($$$;$$) { #{{{
|
sub rcs_commit ($$$;$$) {
|
||||||
my ($file, $message, $rcstoken, $user, $ipaddr) = @_;
|
my ($file, $message, $rcstoken, $user, $ipaddr) = @_;
|
||||||
return undef # success
|
return undef # success
|
||||||
} #}}}
|
}
|
||||||
|
|
||||||
sub rcs_commit_staged ($$$) { #{{{
|
sub rcs_commit_staged ($$$) {
|
||||||
my ($message, $user, $ipaddr)=@_;
|
my ($message, $user, $ipaddr)=@_;
|
||||||
return undef # success
|
return undef # success
|
||||||
} #}}}
|
}
|
||||||
|
|
||||||
sub rcs_add ($) { #{{{
|
sub rcs_add ($) {
|
||||||
} #}}}
|
}
|
||||||
|
|
||||||
sub rcs_remove ($) { #{{{
|
sub rcs_remove ($) {
|
||||||
} #}}}
|
}
|
||||||
|
|
||||||
sub rcs_rename ($$) { #{{{
|
sub rcs_rename ($$) {
|
||||||
} #}}}
|
}
|
||||||
|
|
||||||
sub rcs_recentchanges ($) { #{{{
|
sub rcs_recentchanges ($) {
|
||||||
} #}}}
|
}
|
||||||
|
|
||||||
sub rcs_diff ($) { #{{{
|
sub rcs_diff ($) {
|
||||||
} #}}}
|
}
|
||||||
|
|
||||||
sub rcs_getctime ($) { #{{{
|
sub rcs_getctime ($) {
|
||||||
error gettext("getctime not implemented");
|
error gettext("getctime not implemented");
|
||||||
} #}}}
|
}
|
||||||
|
|
||||||
1
|
1
|
||||||
|
|
|
@ -3,22 +3,22 @@ package IkiWiki::Plugin::opendiscussion;
|
||||||
|
|
||||||
use warnings;
|
use warnings;
|
||||||
use strict;
|
use strict;
|
||||||
use IkiWiki 2.00;
|
use IkiWiki 3.00;
|
||||||
|
|
||||||
sub import { #{{{
|
sub import {
|
||||||
hook(type => "getsetup", id => "opendiscussion", call => \&getsetup);
|
hook(type => "getsetup", id => "opendiscussion", call => \&getsetup);
|
||||||
hook(type => "canedit", id => "opendiscussion", call => \&canedit);
|
hook(type => "canedit", id => "opendiscussion", call => \&canedit);
|
||||||
} # }}}
|
}
|
||||||
|
|
||||||
sub getsetup () { #{{{
|
sub getsetup () {
|
||||||
return
|
return
|
||||||
plugin => {
|
plugin => {
|
||||||
safe => 1,
|
safe => 1,
|
||||||
rebuild => 0,
|
rebuild => 0,
|
||||||
},
|
},
|
||||||
} #}}}
|
}
|
||||||
|
|
||||||
sub canedit ($$) { #{{{
|
sub canedit ($$) {
|
||||||
my $page=shift;
|
my $page=shift;
|
||||||
my $cgi=shift;
|
my $cgi=shift;
|
||||||
my $session=shift;
|
my $session=shift;
|
||||||
|
@ -26,6 +26,6 @@ sub canedit ($$) { #{{{
|
||||||
my $discussion=gettext("discussion");
|
my $discussion=gettext("discussion");
|
||||||
return "" if $page=~/(\/|^)\Q$discussion\E$/;
|
return "" if $page=~/(\/|^)\Q$discussion\E$/;
|
||||||
return undef;
|
return undef;
|
||||||
} #}}}
|
}
|
||||||
|
|
||||||
1
|
1
|
||||||
|
|
|
@ -4,24 +4,24 @@ package IkiWiki::Plugin::openid;
|
||||||
|
|
||||||
use warnings;
|
use warnings;
|
||||||
use strict;
|
use strict;
|
||||||
use IkiWiki 2.00;
|
use IkiWiki 3.00;
|
||||||
|
|
||||||
sub import { #{{{
|
sub import {
|
||||||
hook(type => "getopt", id => "openid", call => \&getopt);
|
hook(type => "getopt", id => "openid", call => \&getopt);
|
||||||
hook(type => "getsetup", id => "openid", call => \&getsetup);
|
hook(type => "getsetup", id => "openid", call => \&getsetup);
|
||||||
hook(type => "auth", id => "openid", call => \&auth);
|
hook(type => "auth", id => "openid", call => \&auth);
|
||||||
hook(type => "formbuilder_setup", id => "openid",
|
hook(type => "formbuilder_setup", id => "openid",
|
||||||
call => \&formbuilder_setup, last => 1);
|
call => \&formbuilder_setup, last => 1);
|
||||||
} # }}}
|
}
|
||||||
|
|
||||||
sub getopt () { #{{{
|
sub getopt () {
|
||||||
eval q{use Getopt::Long};
|
eval q{use Getopt::Long};
|
||||||
error($@) if $@;
|
error($@) if $@;
|
||||||
Getopt::Long::Configure('pass_through');
|
Getopt::Long::Configure('pass_through');
|
||||||
GetOptions("openidsignup=s" => \$config{openidsignup});
|
GetOptions("openidsignup=s" => \$config{openidsignup});
|
||||||
} #}}}
|
}
|
||||||
|
|
||||||
sub getsetup () { #{{{
|
sub getsetup () {
|
||||||
return
|
return
|
||||||
plugin => {
|
plugin => {
|
||||||
safe => 1,
|
safe => 1,
|
||||||
|
@ -34,9 +34,9 @@ sub getsetup () { #{{{
|
||||||
safe => 1,
|
safe => 1,
|
||||||
rebuild => 0,
|
rebuild => 0,
|
||||||
},
|
},
|
||||||
} #}}}
|
}
|
||||||
|
|
||||||
sub formbuilder_setup (@) { #{{{
|
sub formbuilder_setup (@) {
|
||||||
my %params=@_;
|
my %params=@_;
|
||||||
|
|
||||||
my $form=$params{form};
|
my $form=$params{form};
|
||||||
|
@ -92,7 +92,7 @@ sub formbuilder_setup (@) { #{{{
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
sub validate ($$$;$) { #{{{
|
sub validate ($$$;$) {
|
||||||
my $q=shift;
|
my $q=shift;
|
||||||
my $session=shift;
|
my $session=shift;
|
||||||
my $openid_url=shift;
|
my $openid_url=shift;
|
||||||
|
@ -121,9 +121,9 @@ sub validate ($$$;$) { #{{{
|
||||||
# eventually bounce them back to auth()
|
# eventually bounce them back to auth()
|
||||||
IkiWiki::redirect($q, $check_url);
|
IkiWiki::redirect($q, $check_url);
|
||||||
exit 0;
|
exit 0;
|
||||||
} #}}}
|
}
|
||||||
|
|
||||||
sub auth ($$) { #{{{
|
sub auth ($$) {
|
||||||
my $q=shift;
|
my $q=shift;
|
||||||
my $session=shift;
|
my $session=shift;
|
||||||
|
|
||||||
|
@ -147,9 +147,9 @@ sub auth ($$) { #{{{
|
||||||
# myopenid.com affiliate support
|
# myopenid.com affiliate support
|
||||||
validate($q, $session, $q->param('openid_identifier'));
|
validate($q, $session, $q->param('openid_identifier'));
|
||||||
}
|
}
|
||||||
} #}}}
|
}
|
||||||
|
|
||||||
sub getobj ($$) { #{{{
|
sub getobj ($$) {
|
||||||
my $q=shift;
|
my $q=shift;
|
||||||
my $session=shift;
|
my $session=shift;
|
||||||
|
|
||||||
|
@ -178,26 +178,28 @@ sub getobj ($$) { #{{{
|
||||||
consumer_secret => sub { return shift()+$secret },
|
consumer_secret => sub { return shift()+$secret },
|
||||||
required_root => $config{cgiurl},
|
required_root => $config{cgiurl},
|
||||||
);
|
);
|
||||||
} #}}}
|
}
|
||||||
|
|
||||||
package IkiWiki;
|
package IkiWiki;
|
||||||
|
|
||||||
# This is not used by this plugin, but this seems the best place to put it.
|
# This is not used by this plugin, but this seems the best place to put it.
|
||||||
# Used elsewhere to pretty-display the name of an openid user.
|
# Used elsewhere to pretty-display the name of an openid user.
|
||||||
sub openiduser ($) { #{{{
|
sub openiduser ($) {
|
||||||
my $user=shift;
|
my $user=shift;
|
||||||
|
|
||||||
if ($user =~ m!^https?://! &&
|
if ($user =~ m!^https?://! &&
|
||||||
eval q{use Net::OpenID::VerifiedIdentity; 1} && !$@) {
|
eval q{use Net::OpenID::VerifiedIdentity; 1} && !$@) {
|
||||||
my $oid=Net::OpenID::VerifiedIdentity->new(identity => $user);
|
my $oid=Net::OpenID::VerifiedIdentity->new(identity => $user);
|
||||||
my $display=$oid->display;
|
my $display=$oid->display;
|
||||||
# Convert "user.somehost.com" to "user [somehost.com]".
|
# Convert "user.somehost.com" to "user [somehost.com]"
|
||||||
|
# (also "user.somehost.co.uk")
|
||||||
if ($display !~ /\[/) {
|
if ($display !~ /\[/) {
|
||||||
$display=~s/^(.*?)\.([^.]+\.[a-z]+)$/$1 [$2]/;
|
$display=~s/^([-a-zA-Z0-9]+?)\.([-.a-zA-Z0-9]+\.[a-z]+)$/$1 [$2]/;
|
||||||
}
|
}
|
||||||
# Convert "http://somehost.com/user" to "user [somehost.com]".
|
# Convert "http://somehost.com/user" to "user [somehost.com]".
|
||||||
|
# (also "https://somehost.com/user/")
|
||||||
if ($display !~ /\[/) {
|
if ($display !~ /\[/) {
|
||||||
$display=~s/^https?:\/\/(.+)\/([^\/]+)$/$2 [$1]/;
|
$display=~s/^https?:\/\/(.+)\/([^\/]+)\/?$/$2 [$1]/;
|
||||||
}
|
}
|
||||||
$display=~s!^https?://!!; # make sure this is removed
|
$display=~s!^https?://!!; # make sure this is removed
|
||||||
eval q{use CGI 'escapeHTML'};
|
eval q{use CGI 'escapeHTML'};
|
||||||
|
|
|
@ -4,22 +4,22 @@ package IkiWiki::Plugin::orphans;
|
||||||
|
|
||||||
use warnings;
|
use warnings;
|
||||||
use strict;
|
use strict;
|
||||||
use IkiWiki 2.00;
|
use IkiWiki 3.00;
|
||||||
|
|
||||||
sub import { #{{{
|
sub import {
|
||||||
hook(type => "getsetup", id => "orphans", call => \&getsetup);
|
hook(type => "getsetup", id => "orphans", call => \&getsetup);
|
||||||
hook(type => "preprocess", id => "orphans", call => \&preprocess);
|
hook(type => "preprocess", id => "orphans", call => \&preprocess);
|
||||||
} # }}}
|
}
|
||||||
|
|
||||||
sub getsetup () { #{{{
|
sub getsetup () {
|
||||||
return
|
return
|
||||||
plugin => {
|
plugin => {
|
||||||
safe => 1,
|
safe => 1,
|
||||||
rebuild => undef,
|
rebuild => undef,
|
||||||
},
|
},
|
||||||
} #}}}
|
}
|
||||||
|
|
||||||
sub preprocess (@) { #{{{
|
sub preprocess (@) {
|
||||||
my %params=@_;
|
my %params=@_;
|
||||||
$params{pages}="*" unless defined $params{pages};
|
$params{pages}="*" unless defined $params{pages};
|
||||||
|
|
||||||
|
@ -58,6 +58,6 @@ sub preprocess (@) { #{{{
|
||||||
"</li>"
|
"</li>"
|
||||||
} sort @orphans).
|
} sort @orphans).
|
||||||
"</ul>\n";
|
"</ul>\n";
|
||||||
} # }}}
|
}
|
||||||
|
|
||||||
1
|
1
|
||||||
|
|
|
@ -4,25 +4,25 @@ package IkiWiki::Plugin::otl;
|
||||||
|
|
||||||
use warnings;
|
use warnings;
|
||||||
use strict;
|
use strict;
|
||||||
use IkiWiki 2.00;
|
use IkiWiki 3.00;
|
||||||
use open qw{:utf8 :std};
|
use open qw{:utf8 :std};
|
||||||
|
|
||||||
sub import { #{{{
|
sub import {
|
||||||
hook(type => "getsetup", id => "otl", call => \&getsetup);
|
hook(type => "getsetup", id => "otl", call => \&getsetup);
|
||||||
hook(type => "filter", id => "otl", call => \&filter);
|
hook(type => "filter", id => "otl", call => \&filter);
|
||||||
hook(type => "htmlize", id => "otl", call => \&htmlize);
|
hook(type => "htmlize", id => "otl", call => \&htmlize);
|
||||||
|
|
||||||
} # }}}
|
}
|
||||||
|
|
||||||
sub getsetup () { #{{{
|
sub getsetup () {
|
||||||
return
|
return
|
||||||
plugin => {
|
plugin => {
|
||||||
safe => 1,
|
safe => 1,
|
||||||
rebuild => 1, # format plugin
|
rebuild => 1, # format plugin
|
||||||
},
|
},
|
||||||
} #}}}
|
}
|
||||||
|
|
||||||
sub filter (@) { #{{{
|
sub filter (@) {
|
||||||
my %params=@_;
|
my %params=@_;
|
||||||
|
|
||||||
# Munge up check boxes to look a little bit better. This is a hack.
|
# Munge up check boxes to look a little bit better. This is a hack.
|
||||||
|
@ -34,9 +34,9 @@ sub filter (@) { #{{{
|
||||||
$params{content}=~s/^(\s*)\[_\]\s/${1}$unchecked /mg;
|
$params{content}=~s/^(\s*)\[_\]\s/${1}$unchecked /mg;
|
||||||
|
|
||||||
return $params{content};
|
return $params{content};
|
||||||
} # }}}
|
}
|
||||||
|
|
||||||
sub htmlize (@) { #{{{
|
sub htmlize (@) {
|
||||||
my %params=@_;
|
my %params=@_;
|
||||||
|
|
||||||
# Can't use open2 since otl2html doesn't play nice with buffering.
|
# Can't use open2 since otl2html doesn't play nice with buffering.
|
||||||
|
@ -95,6 +95,6 @@ sub htmlize (@) { #{{{
|
||||||
$ret=~s/<body>.*//s;
|
$ret=~s/<body>.*//s;
|
||||||
$ret=~s/<div class="Footer">.*//s;
|
$ret=~s/<div class="Footer">.*//s;
|
||||||
return $ret;
|
return $ret;
|
||||||
} # }}}
|
}
|
||||||
|
|
||||||
1
|
1
|
||||||
|
|
|
@ -3,22 +3,22 @@ package IkiWiki::Plugin::pagecount;
|
||||||
|
|
||||||
use warnings;
|
use warnings;
|
||||||
use strict;
|
use strict;
|
||||||
use IkiWiki 2.00;
|
use IkiWiki 3.00;
|
||||||
|
|
||||||
sub import { #{{{
|
sub import {
|
||||||
hook(type => "getsetup", id => "pagecount", call => \&getsetup);
|
hook(type => "getsetup", id => "pagecount", call => \&getsetup);
|
||||||
hook(type => "preprocess", id => "pagecount", call => \&preprocess);
|
hook(type => "preprocess", id => "pagecount", call => \&preprocess);
|
||||||
} # }}}
|
}
|
||||||
|
|
||||||
sub getsetup () { #{{{
|
sub getsetup () {
|
||||||
return
|
return
|
||||||
plugin => {
|
plugin => {
|
||||||
safe => 1,
|
safe => 1,
|
||||||
rebuild => undef,
|
rebuild => undef,
|
||||||
},
|
},
|
||||||
} #}}}
|
}
|
||||||
|
|
||||||
sub preprocess (@) { #{{{
|
sub preprocess (@) {
|
||||||
my %params=@_;
|
my %params=@_;
|
||||||
$params{pages}="*" unless defined $params{pages};
|
$params{pages}="*" unless defined $params{pages};
|
||||||
|
|
||||||
|
@ -33,6 +33,6 @@ sub preprocess (@) { #{{{
|
||||||
$count++ if pagespec_match($page, $params{pages}, location => $params{page});
|
$count++ if pagespec_match($page, $params{pages}, location => $params{page});
|
||||||
}
|
}
|
||||||
return $count;
|
return $count;
|
||||||
} # }}}
|
}
|
||||||
|
|
||||||
1
|
1
|
||||||
|
|
|
@ -12,25 +12,25 @@ package IkiWiki::Plugin::pagestats;
|
||||||
|
|
||||||
use warnings;
|
use warnings;
|
||||||
use strict;
|
use strict;
|
||||||
use IkiWiki 2.00;
|
use IkiWiki 3.00;
|
||||||
|
|
||||||
# Names of the HTML classes to use for the tag cloud
|
# Names of the HTML classes to use for the tag cloud
|
||||||
our @classes = ('smallestPC', 'smallPC', 'normalPC', 'bigPC', 'biggestPC' );
|
our @classes = ('smallestPC', 'smallPC', 'normalPC', 'bigPC', 'biggestPC' );
|
||||||
|
|
||||||
sub import { #{{{
|
sub import {
|
||||||
hook(type => "getsetup", id => "pagestats", call => \&getsetup);
|
hook(type => "getsetup", id => "pagestats", call => \&getsetup);
|
||||||
hook(type => "preprocess", id => "pagestats", call => \&preprocess);
|
hook(type => "preprocess", id => "pagestats", call => \&preprocess);
|
||||||
} # }}}
|
}
|
||||||
|
|
||||||
sub getsetup () { #{{{
|
sub getsetup () {
|
||||||
return
|
return
|
||||||
plugin => {
|
plugin => {
|
||||||
safe => 1,
|
safe => 1,
|
||||||
rebuild => undef,
|
rebuild => undef,
|
||||||
},
|
},
|
||||||
} #}}}
|
}
|
||||||
|
|
||||||
sub preprocess (@) { #{{{
|
sub preprocess (@) {
|
||||||
my %params=@_;
|
my %params=@_;
|
||||||
$params{pages}="*" unless defined $params{pages};
|
$params{pages}="*" unless defined $params{pages};
|
||||||
my $style = ($params{style} or 'cloud');
|
my $style = ($params{style} or 'cloud');
|
||||||
|
@ -73,6 +73,6 @@ sub preprocess (@) { #{{{
|
||||||
|
|
||||||
return $res;
|
return $res;
|
||||||
}
|
}
|
||||||
} # }}}
|
}
|
||||||
|
|
||||||
1
|
1
|
||||||
|
|
|
@ -3,25 +3,25 @@ package IkiWiki::Plugin::pagetemplate;
|
||||||
|
|
||||||
use warnings;
|
use warnings;
|
||||||
use strict;
|
use strict;
|
||||||
use IkiWiki 2.00;
|
use IkiWiki 3.00;
|
||||||
|
|
||||||
my %templates;
|
my %templates;
|
||||||
|
|
||||||
sub import { #{{{
|
sub import {
|
||||||
hook(type => "getsetup", id => "pagetemplate", call => \&getsetup);
|
hook(type => "getsetup", id => "pagetemplate", call => \&getsetup);
|
||||||
hook(type => "preprocess", id => "pagetemplate", call => \&preprocess);
|
hook(type => "preprocess", id => "pagetemplate", call => \&preprocess);
|
||||||
hook(type => "templatefile", id => "pagetemplate", call => \&templatefile);
|
hook(type => "templatefile", id => "pagetemplate", call => \&templatefile);
|
||||||
} # }}}
|
}
|
||||||
|
|
||||||
sub getsetup () { #{{{
|
sub getsetup () {
|
||||||
return
|
return
|
||||||
plugin => {
|
plugin => {
|
||||||
safe => 1,
|
safe => 1,
|
||||||
rebuild => undef,
|
rebuild => undef,
|
||||||
},
|
},
|
||||||
} #}}}
|
}
|
||||||
|
|
||||||
sub preprocess (@) { #{{{
|
sub preprocess (@) {
|
||||||
my %params=@_;
|
my %params=@_;
|
||||||
|
|
||||||
if (! exists $params{template} ||
|
if (! exists $params{template} ||
|
||||||
|
@ -35,9 +35,9 @@ sub preprocess (@) { #{{{
|
||||||
}
|
}
|
||||||
|
|
||||||
return "";
|
return "";
|
||||||
} # }}}
|
}
|
||||||
|
|
||||||
sub templatefile (@) { #{{{
|
sub templatefile (@) {
|
||||||
my %params=@_;
|
my %params=@_;
|
||||||
|
|
||||||
if (exists $templates{$params{page}}) {
|
if (exists $templates{$params{page}}) {
|
||||||
|
@ -45,6 +45,6 @@ sub templatefile (@) { #{{{
|
||||||
}
|
}
|
||||||
|
|
||||||
return undef;
|
return undef;
|
||||||
} # }}}
|
}
|
||||||
|
|
||||||
1
|
1
|
||||||
|
|
|
@ -4,22 +4,22 @@ package IkiWiki::Plugin::parentlinks;
|
||||||
|
|
||||||
use warnings;
|
use warnings;
|
||||||
use strict;
|
use strict;
|
||||||
use IkiWiki 2.00;
|
use IkiWiki 3.00;
|
||||||
|
|
||||||
sub import { #{{{
|
sub import {
|
||||||
hook(type => "parentlinks", id => "parentlinks", call => \&parentlinks);
|
hook(type => "parentlinks", id => "parentlinks", call => \&parentlinks);
|
||||||
hook(type => "pagetemplate", id => "parentlinks", call => \&pagetemplate);
|
hook(type => "pagetemplate", id => "parentlinks", call => \&pagetemplate);
|
||||||
} # }}}
|
}
|
||||||
|
|
||||||
sub getsetup () { #{{{
|
sub getsetup () {
|
||||||
return
|
return
|
||||||
plugin => {
|
plugin => {
|
||||||
safe => 1,
|
safe => 1,
|
||||||
rebuild => 1,
|
rebuild => 1,
|
||||||
},
|
},
|
||||||
} #}}}
|
}
|
||||||
|
|
||||||
sub parentlinks ($) { #{{{
|
sub parentlinks ($) {
|
||||||
my $page=shift;
|
my $page=shift;
|
||||||
|
|
||||||
my @ret;
|
my @ret;
|
||||||
|
@ -48,9 +48,9 @@ sub parentlinks ($) { #{{{
|
||||||
$i++;
|
$i++;
|
||||||
}
|
}
|
||||||
return @ret;
|
return @ret;
|
||||||
} #}}}
|
}
|
||||||
|
|
||||||
sub pagetemplate (@) { #{{{
|
sub pagetemplate (@) {
|
||||||
my %params=@_;
|
my %params=@_;
|
||||||
my $page=$params{page};
|
my $page=$params{page};
|
||||||
my $template=$params{template};
|
my $template=$params{template};
|
||||||
|
@ -58,6 +58,6 @@ sub pagetemplate (@) { #{{{
|
||||||
if ($template->query(name => "parentlinks")) {
|
if ($template->query(name => "parentlinks")) {
|
||||||
$template->param(parentlinks => [parentlinks($page)]);
|
$template->param(parentlinks => [parentlinks($page)]);
|
||||||
}
|
}
|
||||||
} # }}}
|
}
|
||||||
|
|
||||||
1
|
1
|
||||||
|
|
|
@ -4,16 +4,16 @@ package IkiWiki::Plugin::passwordauth;
|
||||||
|
|
||||||
use warnings;
|
use warnings;
|
||||||
use strict;
|
use strict;
|
||||||
use IkiWiki 2.00;
|
use IkiWiki 3.00;
|
||||||
|
|
||||||
sub import { #{{{
|
sub import {
|
||||||
hook(type => "getsetup", id => "passwordauth", "call" => \&getsetup);
|
hook(type => "getsetup", id => "passwordauth", "call" => \&getsetup);
|
||||||
hook(type => "formbuilder_setup", id => "passwordauth", call => \&formbuilder_setup);
|
hook(type => "formbuilder_setup", id => "passwordauth", call => \&formbuilder_setup);
|
||||||
hook(type => "formbuilder", id => "passwordauth", call => \&formbuilder);
|
hook(type => "formbuilder", id => "passwordauth", call => \&formbuilder);
|
||||||
hook(type => "sessioncgi", id => "passwordauth", call => \&sessioncgi);
|
hook(type => "sessioncgi", id => "passwordauth", call => \&sessioncgi);
|
||||||
} # }}}
|
}
|
||||||
|
|
||||||
sub getsetup () { #{{{
|
sub getsetup () {
|
||||||
return
|
return
|
||||||
plugin => {
|
plugin => {
|
||||||
safe => 1,
|
safe => 1,
|
||||||
|
@ -33,10 +33,10 @@ sub getsetup () { #{{{
|
||||||
safe => 1,
|
safe => 1,
|
||||||
rebuild => 0,
|
rebuild => 0,
|
||||||
},
|
},
|
||||||
} #}}}
|
}
|
||||||
|
|
||||||
# Checks if a string matches a user's password, and returns true or false.
|
# Checks if a string matches a user's password, and returns true or false.
|
||||||
sub checkpassword ($$;$) { #{{{
|
sub checkpassword ($$;$) {
|
||||||
my $user=shift;
|
my $user=shift;
|
||||||
my $password=shift;
|
my $password=shift;
|
||||||
my $field=shift || "password";
|
my $field=shift || "password";
|
||||||
|
@ -74,9 +74,9 @@ sub checkpassword ($$;$) { #{{{
|
||||||
}
|
}
|
||||||
|
|
||||||
return $ret;
|
return $ret;
|
||||||
} #}}}
|
}
|
||||||
|
|
||||||
sub setpassword ($$;$) { #{{{
|
sub setpassword ($$;$) {
|
||||||
my $user=shift;
|
my $user=shift;
|
||||||
my $password=shift;
|
my $password=shift;
|
||||||
my $field=shift || "password";
|
my $field=shift || "password";
|
||||||
|
@ -94,9 +94,9 @@ sub setpassword ($$;$) { #{{{
|
||||||
else {
|
else {
|
||||||
IkiWiki::userinfo_set($user, $field, $password);
|
IkiWiki::userinfo_set($user, $field, $password);
|
||||||
}
|
}
|
||||||
} #}}}
|
}
|
||||||
|
|
||||||
sub formbuilder_setup (@) { #{{{
|
sub formbuilder_setup (@) {
|
||||||
my %params=@_;
|
my %params=@_;
|
||||||
|
|
||||||
my $form=$params{form};
|
my $form=$params{form};
|
||||||
|
@ -222,7 +222,7 @@ sub formbuilder_setup (@) { #{{{
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
sub formbuilder (@) { #{{{
|
sub formbuilder (@) {
|
||||||
my %params=@_;
|
my %params=@_;
|
||||||
|
|
||||||
my $form=$params{form};
|
my $form=$params{form};
|
||||||
|
@ -313,9 +313,9 @@ sub formbuilder (@) { #{{{
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} #}}}
|
}
|
||||||
|
|
||||||
sub sessioncgi ($$) { #{{{
|
sub sessioncgi ($$) {
|
||||||
my $q=shift;
|
my $q=shift;
|
||||||
my $session=shift;
|
my $session=shift;
|
||||||
|
|
||||||
|
@ -335,6 +335,6 @@ sub sessioncgi ($$) { #{{{
|
||||||
IkiWiki::cgi_prefs($q, $session);
|
IkiWiki::cgi_prefs($q, $session);
|
||||||
exit;
|
exit;
|
||||||
}
|
}
|
||||||
} #}}}
|
}
|
||||||
|
|
||||||
1
|
1
|
||||||
|
|
|
@ -3,22 +3,22 @@ package IkiWiki::Plugin::pingee;
|
||||||
|
|
||||||
use warnings;
|
use warnings;
|
||||||
use strict;
|
use strict;
|
||||||
use IkiWiki 2.00;
|
use IkiWiki 3.00;
|
||||||
|
|
||||||
sub import { #{{{
|
sub import {
|
||||||
hook(type => "getsetup", id => "pingee", call => \&getsetup);
|
hook(type => "getsetup", id => "pingee", call => \&getsetup);
|
||||||
hook(type => "cgi", id => "pingee", call => \&cgi);
|
hook(type => "cgi", id => "pingee", call => \&cgi);
|
||||||
} # }}}
|
}
|
||||||
|
|
||||||
sub getsetup () { #{{{
|
sub getsetup () {
|
||||||
return
|
return
|
||||||
plugin => {
|
plugin => {
|
||||||
safe => 1,
|
safe => 1,
|
||||||
rebuild => undef,
|
rebuild => undef,
|
||||||
},
|
},
|
||||||
} #}}}
|
}
|
||||||
|
|
||||||
sub cgi ($) { #{{{
|
sub cgi ($) {
|
||||||
my $cgi=shift;
|
my $cgi=shift;
|
||||||
|
|
||||||
if (defined $cgi->param('do') && $cgi->param("do") eq "ping") {
|
if (defined $cgi->param('do') && $cgi->param("do") eq "ping") {
|
||||||
|
@ -37,6 +37,6 @@ sub cgi ($) { #{{{
|
||||||
IkiWiki::saveindex();
|
IkiWiki::saveindex();
|
||||||
exit 0;
|
exit 0;
|
||||||
}
|
}
|
||||||
} #}}}
|
}
|
||||||
|
|
||||||
1
|
1
|
||||||
|
|
|
@ -3,20 +3,20 @@ package IkiWiki::Plugin::pinger;
|
||||||
|
|
||||||
use warnings;
|
use warnings;
|
||||||
use strict;
|
use strict;
|
||||||
use IkiWiki 2.00;
|
use IkiWiki 3.00;
|
||||||
|
|
||||||
my %pages;
|
my %pages;
|
||||||
my $pinged=0;
|
my $pinged=0;
|
||||||
|
|
||||||
sub import { #{{{
|
sub import {
|
||||||
hook(type => "getsetup", id => "pinger", call => \&getsetup);
|
hook(type => "getsetup", id => "pinger", call => \&getsetup);
|
||||||
hook(type => "needsbuild", id => "pinger", call => \&needsbuild);
|
hook(type => "needsbuild", id => "pinger", call => \&needsbuild);
|
||||||
hook(type => "preprocess", id => "ping", call => \&preprocess);
|
hook(type => "preprocess", id => "ping", call => \&preprocess);
|
||||||
hook(type => "delete", id => "pinger", call => \&ping);
|
hook(type => "delete", id => "pinger", call => \&ping);
|
||||||
hook(type => "change", id => "pinger", call => \&ping);
|
hook(type => "change", id => "pinger", call => \&ping);
|
||||||
} # }}}
|
}
|
||||||
|
|
||||||
sub getsetup () { #{{{
|
sub getsetup () {
|
||||||
return
|
return
|
||||||
plugin => {
|
plugin => {
|
||||||
safe => 1,
|
safe => 1,
|
||||||
|
@ -29,9 +29,9 @@ sub getsetup () { #{{{
|
||||||
safe => 1,
|
safe => 1,
|
||||||
rebuild => 0,
|
rebuild => 0,
|
||||||
},
|
},
|
||||||
} #}}}
|
}
|
||||||
|
|
||||||
sub needsbuild (@) { #{{{
|
sub needsbuild (@) {
|
||||||
my $needsbuild=shift;
|
my $needsbuild=shift;
|
||||||
foreach my $page (keys %pagestate) {
|
foreach my $page (keys %pagestate) {
|
||||||
if (exists $pagestate{$page}{pinger}) {
|
if (exists $pagestate{$page}{pinger}) {
|
||||||
|
@ -45,9 +45,9 @@ sub needsbuild (@) { #{{{
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} # }}}
|
}
|
||||||
|
|
||||||
sub preprocess (@) { #{{{
|
sub preprocess (@) {
|
||||||
my %params=@_;
|
my %params=@_;
|
||||||
if (! exists $params{from} || ! exists $params{to}) {
|
if (! exists $params{from} || ! exists $params{to}) {
|
||||||
error gettext("requires 'from' and 'to' parameters");
|
error gettext("requires 'from' and 'to' parameters");
|
||||||
|
@ -60,7 +60,7 @@ sub preprocess (@) { #{{{
|
||||||
else {
|
else {
|
||||||
return sprintf(gettext("Ignoring ping directive for wiki %s (this wiki is %s)"), $params{from}, $config{url});
|
return sprintf(gettext("Ignoring ping directive for wiki %s (this wiki is %s)"), $params{from}, $config{url});
|
||||||
}
|
}
|
||||||
} # }}}
|
}
|
||||||
|
|
||||||
sub ping {
|
sub ping {
|
||||||
if (! $pinged && %pages) {
|
if (! $pinged && %pages) {
|
||||||
|
@ -106,7 +106,7 @@ sub ping {
|
||||||
# will still be avoided.
|
# will still be avoided.
|
||||||
next if $url=~/^\Q$config{cgiurl}\E/;
|
next if $url=~/^\Q$config{cgiurl}\E/;
|
||||||
|
|
||||||
$ua->head($url);
|
$ua->get($url);
|
||||||
}
|
}
|
||||||
|
|
||||||
exit 0;
|
exit 0;
|
||||||
|
|
|
@ -3,25 +3,25 @@ package IkiWiki::Plugin::poll;
|
||||||
|
|
||||||
use warnings;
|
use warnings;
|
||||||
use strict;
|
use strict;
|
||||||
use IkiWiki 2.00;
|
use IkiWiki 3.00;
|
||||||
use Encode;
|
use Encode;
|
||||||
|
|
||||||
sub import { #{{{
|
sub import {
|
||||||
hook(type => "getsetup", id => "poll", call => \&getsetup);
|
hook(type => "getsetup", id => "poll", call => \&getsetup);
|
||||||
hook(type => "preprocess", id => "poll", call => \&preprocess);
|
hook(type => "preprocess", id => "poll", call => \&preprocess);
|
||||||
hook(type => "sessioncgi", id => "poll", call => \&sessioncgi);
|
hook(type => "sessioncgi", id => "poll", call => \&sessioncgi);
|
||||||
} # }}}
|
}
|
||||||
|
|
||||||
sub getsetup () { #{{{
|
sub getsetup () {
|
||||||
return
|
return
|
||||||
plugin => {
|
plugin => {
|
||||||
safe => 1,
|
safe => 1,
|
||||||
rebuild => undef,
|
rebuild => undef,
|
||||||
},
|
},
|
||||||
} #}}}
|
}
|
||||||
|
|
||||||
my %pagenum;
|
my %pagenum;
|
||||||
sub preprocess (@) { #{{{
|
sub preprocess (@) {
|
||||||
my %params=(open => "yes", total => "yes", percent => "yes", @_);
|
my %params=(open => "yes", total => "yes", percent => "yes", @_);
|
||||||
|
|
||||||
my $open=IkiWiki::yesno($params{open});
|
my $open=IkiWiki::yesno($params{open});
|
||||||
|
@ -77,9 +77,9 @@ sub preprocess (@) { #{{{
|
||||||
$ret.="<span>".gettext("Total votes:")." $total</span>\n";
|
$ret.="<span>".gettext("Total votes:")." $total</span>\n";
|
||||||
}
|
}
|
||||||
return "<div class=poll>$ret</div>";
|
return "<div class=poll>$ret</div>";
|
||||||
} # }}}
|
}
|
||||||
|
|
||||||
sub sessioncgi ($$) { #{{{
|
sub sessioncgi ($$) {
|
||||||
my $cgi=shift;
|
my $cgi=shift;
|
||||||
my $session=shift;
|
my $session=shift;
|
||||||
if (defined $cgi->param('do') && $cgi->param('do') eq "poll") {
|
if (defined $cgi->param('do') && $cgi->param('do') eq "poll") {
|
||||||
|
@ -152,6 +152,6 @@ sub sessioncgi ($$) { #{{{
|
||||||
-url => urlto($page, undef, 1));
|
-url => urlto($page, undef, 1));
|
||||||
exit;
|
exit;
|
||||||
}
|
}
|
||||||
} #}}}
|
}
|
||||||
|
|
||||||
1
|
1
|
||||||
|
|
|
@ -7,23 +7,23 @@ package IkiWiki::Plugin::polygen;
|
||||||
|
|
||||||
use warnings;
|
use warnings;
|
||||||
use strict;
|
use strict;
|
||||||
use IkiWiki 2.00;
|
use IkiWiki 3.00;
|
||||||
use File::Find;
|
use File::Find;
|
||||||
|
|
||||||
sub import { #{{{
|
sub import {
|
||||||
hook(type => "getsetup", id => "polygen", call => \&getsetup);
|
hook(type => "getsetup", id => "polygen", call => \&getsetup);
|
||||||
hook(type => "preprocess", id => "polygen", call => \&preprocess);
|
hook(type => "preprocess", id => "polygen", call => \&preprocess);
|
||||||
} # }}}
|
}
|
||||||
|
|
||||||
sub getsetup () { #{{{
|
sub getsetup () {
|
||||||
return
|
return
|
||||||
plugin => {
|
plugin => {
|
||||||
safe => 1,
|
safe => 1,
|
||||||
rebuild => undef,
|
rebuild => undef,
|
||||||
},
|
},
|
||||||
} #}}}
|
}
|
||||||
|
|
||||||
sub preprocess (@) { #{{{
|
sub preprocess (@) {
|
||||||
my %params=@_;
|
my %params=@_;
|
||||||
my $grammar = ($params{grammar} or 'polygen');
|
my $grammar = ($params{grammar} or 'polygen');
|
||||||
my $symbol = ($params{symbol} or undef);
|
my $symbol = ($params{symbol} or undef);
|
||||||
|
@ -64,6 +64,6 @@ sub preprocess (@) { #{{{
|
||||||
# markdown text
|
# markdown text
|
||||||
$res =~ s/\s*$//;
|
$res =~ s/\s*$//;
|
||||||
return $res;
|
return $res;
|
||||||
} # }}}
|
}
|
||||||
|
|
||||||
1
|
1
|
||||||
|
|
|
@ -3,23 +3,23 @@ package IkiWiki::Plugin::postsparkline;
|
||||||
|
|
||||||
use warnings;
|
use warnings;
|
||||||
use strict;
|
use strict;
|
||||||
use IkiWiki 2.00;
|
use IkiWiki 3.00;
|
||||||
|
|
||||||
sub import { #{{{
|
sub import {
|
||||||
IkiWiki::loadplugin('sparkline');
|
IkiWiki::loadplugin('sparkline');
|
||||||
hook(type => "getsetup", id => "postsparkline", call => \&getsetup);
|
hook(type => "getsetup", id => "postsparkline", call => \&getsetup);
|
||||||
hook(type => "preprocess", id => "postsparkline", call => \&preprocess);
|
hook(type => "preprocess", id => "postsparkline", call => \&preprocess);
|
||||||
} # }}}
|
}
|
||||||
|
|
||||||
sub getsetup () { #{{{
|
sub getsetup () {
|
||||||
return
|
return
|
||||||
plugin => {
|
plugin => {
|
||||||
safe => 1,
|
safe => 1,
|
||||||
rebuild => undef,
|
rebuild => undef,
|
||||||
},
|
},
|
||||||
} #}}}
|
}
|
||||||
|
|
||||||
sub preprocess (@) { #{{{
|
sub preprocess (@) {
|
||||||
my %params=@_;
|
my %params=@_;
|
||||||
|
|
||||||
if (! exists $params{max}) {
|
if (! exists $params{max}) {
|
||||||
|
@ -78,7 +78,7 @@ sub preprocess (@) { #{{{
|
||||||
delete $params{color};
|
delete $params{color};
|
||||||
return IkiWiki::Plugin::sparkline::preprocess(%params,
|
return IkiWiki::Plugin::sparkline::preprocess(%params,
|
||||||
map { $_.$color => "" } reverse @data);
|
map { $_.$color => "" } reverse @data);
|
||||||
} # }}}
|
}
|
||||||
|
|
||||||
sub perfoo ($@) {
|
sub perfoo ($@) {
|
||||||
my $sub=shift;
|
my $sub=shift;
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
#!/usr/bin/perl
|
#!/usr/bin/perl
|
||||||
package IkiWiki::Plugin::prettydate;
|
package IkiWiki::Plugin::prettydate;
|
||||||
use IkiWiki 2.00;
|
use IkiWiki 3.00;
|
||||||
use warnings;
|
use warnings;
|
||||||
no warnings 'redefine';
|
no warnings 'redefine';
|
||||||
use strict;
|
use strict;
|
||||||
|
@ -39,12 +39,12 @@ sub default_timetable {
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
|
||||||
sub import { #{{{
|
sub import {
|
||||||
hook(type => "getsetup", id => "prettydate", call => \&getsetup);
|
hook(type => "getsetup", id => "prettydate", call => \&getsetup);
|
||||||
hook(type => "checkconfig", id => "prettydate", call => \&checkconfig);
|
hook(type => "checkconfig", id => "prettydate", call => \&checkconfig);
|
||||||
} # }}}
|
}
|
||||||
|
|
||||||
sub getsetup () { #{{{
|
sub getsetup () {
|
||||||
return
|
return
|
||||||
plugin => {
|
plugin => {
|
||||||
safe => 1,
|
safe => 1,
|
||||||
|
@ -64,9 +64,9 @@ sub getsetup () { #{{{
|
||||||
safe => 1,
|
safe => 1,
|
||||||
rebuild => 1,
|
rebuild => 1,
|
||||||
},
|
},
|
||||||
} #}}}
|
}
|
||||||
|
|
||||||
sub checkconfig () { #{{{
|
sub checkconfig () {
|
||||||
if (! defined $config{prettydateformat} ||
|
if (! defined $config{prettydateformat} ||
|
||||||
$config{prettydateformat} eq '%c') {
|
$config{prettydateformat} eq '%c') {
|
||||||
$config{prettydateformat}='%X, %B %o, %Y';
|
$config{prettydateformat}='%X, %B %o, %Y';
|
||||||
|
@ -82,9 +82,9 @@ sub checkconfig () { #{{{
|
||||||
$config{timetable}[$h] = $config{timetable}[$h - 1];
|
$config{timetable}[$h] = $config{timetable}[$h - 1];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} #}}}
|
}
|
||||||
|
|
||||||
sub IkiWiki::displaytime ($;$) { #{{{
|
sub IkiWiki::formattime ($;$) {
|
||||||
my $time=shift;
|
my $time=shift;
|
||||||
my $format=shift;
|
my $format=shift;
|
||||||
if (! defined $format) {
|
if (! defined $format) {
|
||||||
|
@ -122,6 +122,6 @@ sub IkiWiki::displaytime ($;$) { #{{{
|
||||||
|
|
||||||
$format=~s/\%X/$t/g;
|
$format=~s/\%X/$t/g;
|
||||||
return strftime($format, \@t);
|
return strftime($format, \@t);
|
||||||
} #}}}
|
}
|
||||||
|
|
||||||
1
|
1
|
||||||
|
|
|
@ -3,25 +3,25 @@ package IkiWiki::Plugin::progress;
|
||||||
|
|
||||||
use warnings;
|
use warnings;
|
||||||
use strict;
|
use strict;
|
||||||
use IkiWiki 2.00;
|
use IkiWiki 3.00;
|
||||||
|
|
||||||
my $percentage_pattern = qr/[0-9]+\%?/; # pattern to validate percentages
|
my $percentage_pattern = qr/[0-9]+\%?/; # pattern to validate percentages
|
||||||
|
|
||||||
sub import { #{{{
|
sub import {
|
||||||
hook(type => "getsetup", id => "progress", call => \&getsetup);
|
hook(type => "getsetup", id => "progress", call => \&getsetup);
|
||||||
hook(type => "preprocess", id => "progress", call => \&preprocess);
|
hook(type => "preprocess", id => "progress", call => \&preprocess);
|
||||||
hook(type => "format", id => "progress", call => \&format);
|
hook(type => "format", id => "progress", call => \&format);
|
||||||
} # }}}
|
}
|
||||||
|
|
||||||
sub getsetup () { #{{{
|
sub getsetup () {
|
||||||
return
|
return
|
||||||
plugin => {
|
plugin => {
|
||||||
safe => 1,
|
safe => 1,
|
||||||
rebuild => undef,
|
rebuild => undef,
|
||||||
},
|
},
|
||||||
} #}}}
|
}
|
||||||
|
|
||||||
sub preprocess (@) { #{{{
|
sub preprocess (@) {
|
||||||
my %params=@_;
|
my %params=@_;
|
||||||
|
|
||||||
my $fill;
|
my $fill;
|
||||||
|
@ -64,9 +64,9 @@ sub preprocess (@) { #{{{
|
||||||
<div class="progress-done" style="width: $fill">$fill</div>
|
<div class="progress-done" style="width: $fill">$fill</div>
|
||||||
</div>
|
</div>
|
||||||
EODIV
|
EODIV
|
||||||
} # }}}
|
}
|
||||||
|
|
||||||
sub format(@) { #{{{
|
sub format(@) {
|
||||||
my %params = @_;
|
my %params = @_;
|
||||||
|
|
||||||
# If HTMLScrubber has removed the style attribute, then bring it back
|
# If HTMLScrubber has removed the style attribute, then bring it back
|
||||||
|
@ -74,6 +74,6 @@ sub format(@) { #{{{
|
||||||
$params{content} =~ s!<div class="progress-done">($percentage_pattern)</div>!<div class="progress-done" style="width: $1">$1</div>!g;
|
$params{content} =~ s!<div class="progress-done">($percentage_pattern)</div>!<div class="progress-done" style="width: $1">$1</div>!g;
|
||||||
|
|
||||||
return $params{content};
|
return $params{content};
|
||||||
} #}}}
|
}
|
||||||
|
|
||||||
1
|
1
|
||||||
|
|
|
@ -4,19 +4,19 @@ package IkiWiki::Plugin::rawhtml;
|
||||||
|
|
||||||
use warnings;
|
use warnings;
|
||||||
use strict;
|
use strict;
|
||||||
use IkiWiki 2.00;
|
use IkiWiki 3.00;
|
||||||
|
|
||||||
sub import { #{{{
|
sub import {
|
||||||
hook(type => "getsetup", id => "rawhtml", call => \&getsetup);
|
hook(type => "getsetup", id => "rawhtml", call => \&getsetup);
|
||||||
$config{wiki_file_prune_regexps} = [ grep { !m/\\\.x\?html\?\$/ } @{$config{wiki_file_prune_regexps}} ];
|
$config{wiki_file_prune_regexps} = [ grep { !m/\\\.x\?html\?\$/ } @{$config{wiki_file_prune_regexps}} ];
|
||||||
} # }}}
|
}
|
||||||
|
|
||||||
sub getsetup () { #{{{
|
sub getsetup () {
|
||||||
return
|
return
|
||||||
plugin => {
|
plugin => {
|
||||||
safe => 1,
|
safe => 1,
|
||||||
rebuild => 1, # changes file types
|
rebuild => 1, # changes file types
|
||||||
},
|
},
|
||||||
} #}}}
|
}
|
||||||
|
|
||||||
1
|
1
|
||||||
|
|
|
@ -3,19 +3,21 @@ package IkiWiki::Plugin::recentchanges;
|
||||||
|
|
||||||
use warnings;
|
use warnings;
|
||||||
use strict;
|
use strict;
|
||||||
use IkiWiki 2.00;
|
use IkiWiki 3.00;
|
||||||
use Encode;
|
use Encode;
|
||||||
|
use HTML::Entities;
|
||||||
|
|
||||||
sub import { #{{{
|
sub import {
|
||||||
hook(type => "getsetup", id => "recentchanges", call => \&getsetup);
|
hook(type => "getsetup", id => "recentchanges", call => \&getsetup);
|
||||||
hook(type => "checkconfig", id => "recentchanges", call => \&checkconfig);
|
hook(type => "checkconfig", id => "recentchanges", call => \&checkconfig);
|
||||||
hook(type => "refresh", id => "recentchanges", call => \&refresh);
|
hook(type => "refresh", id => "recentchanges", call => \&refresh);
|
||||||
hook(type => "pagetemplate", id => "recentchanges", call => \&pagetemplate);
|
hook(type => "pagetemplate", id => "recentchanges", call => \&pagetemplate);
|
||||||
hook(type => "htmlize", id => "_change", call => \&htmlize);
|
hook(type => "htmlize", id => "_change", call => \&htmlize);
|
||||||
hook(type => "cgi", id => "recentchanges", call => \&cgi);
|
# Load goto to fix up links from recentchanges
|
||||||
} #}}}
|
IkiWiki::loadplugin("goto");
|
||||||
|
}
|
||||||
|
|
||||||
sub getsetup () { #{{{
|
sub getsetup () {
|
||||||
return
|
return
|
||||||
plugin => {
|
plugin => {
|
||||||
safe => 1,
|
safe => 1,
|
||||||
|
@ -35,14 +37,14 @@ sub getsetup () { #{{{
|
||||||
safe => 1,
|
safe => 1,
|
||||||
rebuild => 0,
|
rebuild => 0,
|
||||||
},
|
},
|
||||||
} #}}}
|
}
|
||||||
|
|
||||||
sub checkconfig () { #{{{
|
sub checkconfig () {
|
||||||
$config{recentchangespage}='recentchanges' unless defined $config{recentchangespage};
|
$config{recentchangespage}='recentchanges' unless defined $config{recentchangespage};
|
||||||
$config{recentchangesnum}=100 unless defined $config{recentchangesnum};
|
$config{recentchangesnum}=100 unless defined $config{recentchangesnum};
|
||||||
} #}}}
|
}
|
||||||
|
|
||||||
sub refresh ($) { #{{{
|
sub refresh ($) {
|
||||||
my %seen;
|
my %seen;
|
||||||
|
|
||||||
# add new changes
|
# add new changes
|
||||||
|
@ -56,10 +58,10 @@ sub refresh ($) { #{{{
|
||||||
unlink($config{srcdir}.'/'.$pagesources{$page});
|
unlink($config{srcdir}.'/'.$pagesources{$page});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} #}}}
|
}
|
||||||
|
|
||||||
# Enable the recentchanges link on wiki pages.
|
# Enable the recentchanges link on wiki pages.
|
||||||
sub pagetemplate (@) { #{{{
|
sub pagetemplate (@) {
|
||||||
my %params=@_;
|
my %params=@_;
|
||||||
my $template=$params{template};
|
my $template=$params{template};
|
||||||
my $page=$params{page};
|
my $page=$params{page};
|
||||||
|
@ -70,48 +72,15 @@ sub pagetemplate (@) { #{{{
|
||||||
$template->param(recentchangesurl => urlto($config{recentchangespage}, $page));
|
$template->param(recentchangesurl => urlto($config{recentchangespage}, $page));
|
||||||
$template->param(have_actions => 1);
|
$template->param(have_actions => 1);
|
||||||
}
|
}
|
||||||
} #}}}
|
|
||||||
|
|
||||||
# Pages with extension _change have plain html markup, pass through.
|
|
||||||
sub htmlize (@) { #{{{
|
|
||||||
my %params=@_;
|
|
||||||
return $params{content};
|
|
||||||
} #}}}
|
|
||||||
|
|
||||||
sub cgi ($) { #{{{
|
|
||||||
my $cgi=shift;
|
|
||||||
if (defined $cgi->param('do') && $cgi->param('do') eq "recentchanges_link") {
|
|
||||||
# This is a link from a change page to some
|
|
||||||
# other page. Since the change pages are only generated
|
|
||||||
# once, statically, links on them won't be updated if the
|
|
||||||
# page they link to is deleted, or newly created, or
|
|
||||||
# changes for whatever reason. So this CGI handles that
|
|
||||||
# dynamic linking stuff.
|
|
||||||
my $page=decode_utf8($cgi->param("page"));
|
|
||||||
if (!defined $page) {
|
|
||||||
error("missing page parameter");
|
|
||||||
}
|
|
||||||
|
|
||||||
IkiWiki::loadindex();
|
|
||||||
|
|
||||||
my $link=bestlink("", $page);
|
|
||||||
if (! length $link) {
|
|
||||||
print "Content-type: text/html\n\n";
|
|
||||||
print IkiWiki::misctemplate(gettext(gettext("missing page")),
|
|
||||||
"<p>".
|
|
||||||
sprintf(gettext("The page %s does not exist."),
|
|
||||||
htmllink("", "", $page)).
|
|
||||||
"</p>");
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
IkiWiki::redirect($cgi, urlto($link, undef, 1));
|
|
||||||
}
|
|
||||||
|
|
||||||
exit;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
sub store ($$$) { #{{{
|
# Pages with extension _change have plain html markup, pass through.
|
||||||
|
sub htmlize (@) {
|
||||||
|
my %params=@_;
|
||||||
|
return $params{content};
|
||||||
|
}
|
||||||
|
|
||||||
|
sub store ($$$) {
|
||||||
my $change=shift;
|
my $change=shift;
|
||||||
|
|
||||||
my $page="$config{recentchangespage}/change_".titlepage($change->{rev});
|
my $page="$config{recentchangespage}/change_".titlepage($change->{rev});
|
||||||
|
@ -128,10 +97,10 @@ sub store ($$$) { #{{{
|
||||||
if (length $config{cgiurl}) {
|
if (length $config{cgiurl}) {
|
||||||
$_->{link} = "<a href=\"".
|
$_->{link} = "<a href=\"".
|
||||||
IkiWiki::cgiurl(
|
IkiWiki::cgiurl(
|
||||||
do => "recentchanges_link",
|
do => "goto",
|
||||||
page => $_->{page}
|
page => $_->{page}
|
||||||
).
|
).
|
||||||
"\">".
|
"\" rel=\"nofollow\">".
|
||||||
pagetitle($_->{page}).
|
pagetitle($_->{page}).
|
||||||
"</a>"
|
"</a>"
|
||||||
}
|
}
|
||||||
|
@ -154,16 +123,18 @@ sub store ($$$) { #{{{
|
||||||
}
|
}
|
||||||
elsif (length $config{cgiurl}) {
|
elsif (length $config{cgiurl}) {
|
||||||
$change->{authorurl} = IkiWiki::cgiurl(
|
$change->{authorurl} = IkiWiki::cgiurl(
|
||||||
do => "recentchanges_link",
|
do => "goto",
|
||||||
page => (length $config{userdir} ? "$config{userdir}/" : "").$change->{author},
|
page => (length $config{userdir} ? "$config{userdir}/" : "").$change->{author},
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
# escape wikilinks and preprocessor stuff in commit messages
|
|
||||||
if (ref $change->{message}) {
|
if (ref $change->{message}) {
|
||||||
foreach my $field (@{$change->{message}}) {
|
foreach my $field (@{$change->{message}}) {
|
||||||
if (exists $field->{line}) {
|
if (exists $field->{line}) {
|
||||||
$field->{line} =~ s/(?<!\\)\[\[/\\\[\[/g;
|
# escape html
|
||||||
|
$field->{line} = encode_entities($field->{line});
|
||||||
|
# escape links and preprocessor stuff
|
||||||
|
$field->{line} = encode_entities($field->{line}, '\[\]');
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -175,6 +146,10 @@ sub store ($$$) { #{{{
|
||||||
commitdate => displaytime($change->{when}, "%X %x"),
|
commitdate => displaytime($change->{when}, "%X %x"),
|
||||||
wikiname => $config{wikiname},
|
wikiname => $config{wikiname},
|
||||||
);
|
);
|
||||||
|
|
||||||
|
$template->param(permalink => "$config{url}/$config{recentchangespage}/#change-".titlepage($change->{rev}))
|
||||||
|
if exists $config{url};
|
||||||
|
|
||||||
IkiWiki::run_hooks(pagetemplate => sub {
|
IkiWiki::run_hooks(pagetemplate => sub {
|
||||||
shift->(page => $page, destpage => $page,
|
shift->(page => $page, destpage => $page,
|
||||||
template => $template, rev => $change->{rev});
|
template => $template, rev => $change->{rev});
|
||||||
|
@ -185,6 +160,6 @@ sub store ($$$) { #{{{
|
||||||
utime $change->{when}, $change->{when}, "$config{srcdir}/$file";
|
utime $change->{when}, $change->{when}, "$config{srcdir}/$file";
|
||||||
|
|
||||||
return $page;
|
return $page;
|
||||||
} #}}}
|
}
|
||||||
|
|
||||||
1
|
1
|
||||||
|
|
|
@ -3,26 +3,27 @@ package IkiWiki::Plugin::recentchangesdiff;
|
||||||
|
|
||||||
use warnings;
|
use warnings;
|
||||||
use strict;
|
use strict;
|
||||||
use IkiWiki 2.00;
|
use IkiWiki 3.00;
|
||||||
|
use HTML::Entities;
|
||||||
|
|
||||||
my $maxlines=200;
|
my $maxlines=200;
|
||||||
|
|
||||||
sub import { #{{{
|
sub import {
|
||||||
hook(type => "getsetup", id => "recentchangesdiff",
|
hook(type => "getsetup", id => "recentchangesdiff",
|
||||||
call => \&getsetup);
|
call => \&getsetup);
|
||||||
hook(type => "pagetemplate", id => "recentchangesdiff",
|
hook(type => "pagetemplate", id => "recentchangesdiff",
|
||||||
call => \&pagetemplate);
|
call => \&pagetemplate);
|
||||||
} #}}}
|
}
|
||||||
|
|
||||||
sub getsetup () { #{{{
|
sub getsetup () {
|
||||||
return
|
return
|
||||||
plugin => {
|
plugin => {
|
||||||
safe => 1,
|
safe => 1,
|
||||||
rebuild => 1,
|
rebuild => 1,
|
||||||
},
|
},
|
||||||
} #}}}
|
}
|
||||||
|
|
||||||
sub pagetemplate (@) { #{{{
|
sub pagetemplate (@) {
|
||||||
my %params=@_;
|
my %params=@_;
|
||||||
my $template=$params{template};
|
my $template=$params{template};
|
||||||
if ($config{rcs} && exists $params{rev} && length $params{rev} &&
|
if ($config{rcs} && exists $params{rev} && length $params{rev} &&
|
||||||
|
@ -38,11 +39,13 @@ sub pagetemplate (@) { #{{{
|
||||||
else {
|
else {
|
||||||
$diff=join("", @lines);
|
$diff=join("", @lines);
|
||||||
}
|
}
|
||||||
|
# escape html
|
||||||
|
$diff = encode_entities($diff);
|
||||||
# escape links and preprocessor stuff
|
# escape links and preprocessor stuff
|
||||||
$diff =~ s/(?<!\\)\[\[/\\\[\[/g;
|
$diff = encode_entities($diff, '\[\]');
|
||||||
$template->param(diff => $diff);
|
$template->param(diff => $diff);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} #}}}
|
}
|
||||||
|
|
||||||
1
|
1
|
||||||
|
|
|
@ -0,0 +1,60 @@
|
||||||
|
#!/usr/bin/perl
|
||||||
|
package IkiWiki::Plugin::relativedate;
|
||||||
|
|
||||||
|
use warnings;
|
||||||
|
no warnings 'redefine';
|
||||||
|
use strict;
|
||||||
|
use IkiWiki 3.00;
|
||||||
|
use POSIX;
|
||||||
|
use Encode;
|
||||||
|
|
||||||
|
sub import {
|
||||||
|
add_underlay("javascript");
|
||||||
|
hook(type => "getsetup", id => "relativedate", call => \&getsetup);
|
||||||
|
hook(type => "format", id => "relativedate", call => \&format);
|
||||||
|
inject(name => "IkiWiki::displaytime", call => \&mydisplaytime);
|
||||||
|
}
|
||||||
|
|
||||||
|
sub getsetup () {
|
||||||
|
return
|
||||||
|
plugin => {
|
||||||
|
safe => 1,
|
||||||
|
rebuild => 1,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
sub format (@) {
|
||||||
|
my %params=@_;
|
||||||
|
|
||||||
|
if (! ($params{content}=~s!^(<body>)!$1.include_javascript($params{page})!em)) {
|
||||||
|
# no </body> tag, probably in preview mode
|
||||||
|
$params{content}=include_javascript($params{page}, 1).$params{content};
|
||||||
|
}
|
||||||
|
return $params{content};
|
||||||
|
}
|
||||||
|
|
||||||
|
sub include_javascript ($;$) {
|
||||||
|
my $page=shift;
|
||||||
|
my $absolute=shift;
|
||||||
|
|
||||||
|
return '<script src="'.urlto("ikiwiki.js", $page, $absolute).
|
||||||
|
'" type="text/javascript" charset="utf-8"></script>'."\n".
|
||||||
|
'<script src="'.urlto("relativedate.js", $page, $absolute).
|
||||||
|
'" type="text/javascript" charset="utf-8"></script>';
|
||||||
|
}
|
||||||
|
|
||||||
|
sub mydisplaytime ($;$) {
|
||||||
|
my $time=shift;
|
||||||
|
my $format=shift;
|
||||||
|
|
||||||
|
# This needs to be in a form that can be parsed by javascript.
|
||||||
|
# Being fairly human readable is also nice, as it will be exposed
|
||||||
|
# as the title if javascript is not available.
|
||||||
|
my $gmtime=decode_utf8(POSIX::strftime("%a, %d %b %Y %H:%M:%S %z",
|
||||||
|
localtime($time)));
|
||||||
|
|
||||||
|
return '<span class="relativedate" title="'.$gmtime.'">'.
|
||||||
|
IkiWiki::formattime($time, $format).'</span>';
|
||||||
|
}
|
||||||
|
|
||||||
|
1
|
|
@ -3,25 +3,25 @@ package IkiWiki::Plugin::remove;
|
||||||
|
|
||||||
use warnings;
|
use warnings;
|
||||||
use strict;
|
use strict;
|
||||||
use IkiWiki 2.00;
|
use IkiWiki 3.00;
|
||||||
|
|
||||||
sub import { #{{{
|
sub import {
|
||||||
hook(type => "getsetup", id => "remove", call => \&getsetup);
|
hook(type => "getsetup", id => "remove", call => \&getsetup);
|
||||||
hook(type => "formbuilder_setup", id => "remove", call => \&formbuilder_setup);
|
hook(type => "formbuilder_setup", id => "remove", call => \&formbuilder_setup);
|
||||||
hook(type => "formbuilder", id => "remove", call => \&formbuilder);
|
hook(type => "formbuilder", id => "remove", call => \&formbuilder);
|
||||||
hook(type => "sessioncgi", id => "remove", call => \&sessioncgi);
|
hook(type => "sessioncgi", id => "remove", call => \&sessioncgi);
|
||||||
|
|
||||||
} # }}}
|
}
|
||||||
|
|
||||||
sub getsetup () { #{{{
|
sub getsetup () {
|
||||||
return
|
return
|
||||||
plugin => {
|
plugin => {
|
||||||
safe => 1,
|
safe => 1,
|
||||||
rebuild => 0,
|
rebuild => 0,
|
||||||
},
|
},
|
||||||
} #}}}
|
}
|
||||||
|
|
||||||
sub check_canremove ($$$) { #{{{
|
sub check_canremove ($$$) {
|
||||||
my $page=shift;
|
my $page=shift;
|
||||||
my $q=shift;
|
my $q=shift;
|
||||||
my $session=shift;
|
my $session=shift;
|
||||||
|
@ -41,7 +41,7 @@ sub check_canremove ($$$) { #{{{
|
||||||
error(sprintf(gettext("%s is not a file"), $file));
|
error(sprintf(gettext("%s is not a file"), $file));
|
||||||
}
|
}
|
||||||
|
|
||||||
# Must be editiable.
|
# Must be editable.
|
||||||
IkiWiki::check_canedit($page, $q, $session);
|
IkiWiki::check_canedit($page, $q, $session);
|
||||||
|
|
||||||
# If a user can't upload an attachment, don't let them delete it.
|
# If a user can't upload an attachment, don't let them delete it.
|
||||||
|
@ -54,9 +54,9 @@ sub check_canremove ($$$) { #{{{
|
||||||
error("renaming of attachments is not allowed");
|
error("renaming of attachments is not allowed");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} #}}}
|
}
|
||||||
|
|
||||||
sub formbuilder_setup (@) { #{{{
|
sub formbuilder_setup (@) {
|
||||||
my %params=@_;
|
my %params=@_;
|
||||||
my $form=$params{form};
|
my $form=$params{form};
|
||||||
my $q=$params{cgi};
|
my $q=$params{cgi};
|
||||||
|
@ -67,9 +67,9 @@ sub formbuilder_setup (@) { #{{{
|
||||||
push @{$params{buttons}}, "Remove" if $form->field("do") eq "edit";
|
push @{$params{buttons}}, "Remove" if $form->field("do") eq "edit";
|
||||||
$form->tmpl_param("field-remove" => '<input name="_submit" type="submit" value="Remove Attachments" />');
|
$form->tmpl_param("field-remove" => '<input name="_submit" type="submit" value="Remove Attachments" />');
|
||||||
}
|
}
|
||||||
} #}}}
|
}
|
||||||
|
|
||||||
sub confirmation_form ($$) { #{{{
|
sub confirmation_form ($$) {
|
||||||
my $q=shift;
|
my $q=shift;
|
||||||
my $session=shift;
|
my $session=shift;
|
||||||
|
|
||||||
|
@ -90,9 +90,9 @@ sub confirmation_form ($$) { #{{{
|
||||||
$f->field(name => "do", type => "hidden", value => "remove", force => 1);
|
$f->field(name => "do", type => "hidden", value => "remove", force => 1);
|
||||||
|
|
||||||
return $f, ["Remove", "Cancel"];
|
return $f, ["Remove", "Cancel"];
|
||||||
} #}}}
|
}
|
||||||
|
|
||||||
sub removal_confirm ($$@) { #{{{
|
sub removal_confirm ($$@) {
|
||||||
my $q=shift;
|
my $q=shift;
|
||||||
my $session=shift;
|
my $session=shift;
|
||||||
my $attachment=shift;
|
my $attachment=shift;
|
||||||
|
@ -122,9 +122,9 @@ sub removal_confirm ($$@) { #{{{
|
||||||
|
|
||||||
IkiWiki::showform($f, $buttons, $session, $q);
|
IkiWiki::showform($f, $buttons, $session, $q);
|
||||||
exit 0;
|
exit 0;
|
||||||
} #}}}
|
}
|
||||||
|
|
||||||
sub postremove ($) { #{{{
|
sub postremove ($) {
|
||||||
my $session=shift;
|
my $session=shift;
|
||||||
|
|
||||||
# Load saved form state and return to edit form.
|
# Load saved form state and return to edit form.
|
||||||
|
@ -132,9 +132,9 @@ sub postremove ($) { #{{{
|
||||||
$session->clear("postremove");
|
$session->clear("postremove");
|
||||||
IkiWiki::cgi_savesession($session);
|
IkiWiki::cgi_savesession($session);
|
||||||
IkiWiki::cgi($postremove, $session);
|
IkiWiki::cgi($postremove, $session);
|
||||||
} #}}}
|
}
|
||||||
|
|
||||||
sub formbuilder (@) { #{{{
|
sub formbuilder (@) {
|
||||||
my %params=@_;
|
my %params=@_;
|
||||||
my $form=$params{form};
|
my $form=$params{form};
|
||||||
|
|
||||||
|
@ -154,9 +154,9 @@ sub formbuilder (@) { #{{{
|
||||||
removal_confirm($q, $session, 1, @selected);
|
removal_confirm($q, $session, 1, @selected);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} #}}}
|
}
|
||||||
|
|
||||||
sub sessioncgi ($$) { #{{{
|
sub sessioncgi ($$) {
|
||||||
my $q=shift;
|
my $q=shift;
|
||||||
|
|
||||||
if ($q->param("do") eq 'remove') {
|
if ($q->param("do") eq 'remove') {
|
||||||
|
@ -218,7 +218,7 @@ sub sessioncgi ($$) { #{{{
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
IkiWiki::showform($form, $buttons, $session, $q);
|
removal_confirm($q, $session, 0, $q->param("page"));
|
||||||
}
|
}
|
||||||
|
|
||||||
exit 0;
|
exit 0;
|
||||||
|
|
|
@ -3,25 +3,25 @@ package IkiWiki::Plugin::rename;
|
||||||
|
|
||||||
use warnings;
|
use warnings;
|
||||||
use strict;
|
use strict;
|
||||||
use IkiWiki 2.00;
|
use IkiWiki 3.00;
|
||||||
|
|
||||||
sub import { #{{{
|
sub import {
|
||||||
hook(type => "getsetup", id => "rename", call => \&getsetup);
|
hook(type => "getsetup", id => "rename", call => \&getsetup);
|
||||||
hook(type => "formbuilder_setup", id => "rename", call => \&formbuilder_setup);
|
hook(type => "formbuilder_setup", id => "rename", call => \&formbuilder_setup);
|
||||||
hook(type => "formbuilder", id => "rename", call => \&formbuilder);
|
hook(type => "formbuilder", id => "rename", call => \&formbuilder);
|
||||||
hook(type => "sessioncgi", id => "rename", call => \&sessioncgi);
|
hook(type => "sessioncgi", id => "rename", call => \&sessioncgi);
|
||||||
|
|
||||||
} # }}}
|
}
|
||||||
|
|
||||||
sub getsetup () { #{{{
|
sub getsetup () {
|
||||||
return
|
return
|
||||||
plugin => {
|
plugin => {
|
||||||
safe => 1,
|
safe => 1,
|
||||||
rebuild => 0,
|
rebuild => 0,
|
||||||
},
|
},
|
||||||
} #}}}
|
}
|
||||||
|
|
||||||
sub check_canrename ($$$$$$) { #{{{
|
sub check_canrename ($$$$$$) {
|
||||||
my $src=shift;
|
my $src=shift;
|
||||||
my $srcfile=shift;
|
my $srcfile=shift;
|
||||||
my $dest=shift;
|
my $dest=shift;
|
||||||
|
@ -87,9 +87,9 @@ sub check_canrename ($$$$$$) { #{{{
|
||||||
IkiWiki::Plugin::attachment::check_canattach($session, $dest, $srcfile);
|
IkiWiki::Plugin::attachment::check_canattach($session, $dest, $srcfile);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} #}}}
|
}
|
||||||
|
|
||||||
sub rename_form ($$$) { #{{{
|
sub rename_form ($$$) {
|
||||||
my $q=shift;
|
my $q=shift;
|
||||||
my $session=shift;
|
my $session=shift;
|
||||||
my $page=shift;
|
my $page=shift;
|
||||||
|
@ -111,7 +111,7 @@ sub rename_form ($$$) { #{{{
|
||||||
|
|
||||||
$f->field(name => "do", type => "hidden", value => "rename", force => 1);
|
$f->field(name => "do", type => "hidden", value => "rename", force => 1);
|
||||||
$f->field(name => "page", type => "hidden", value => $page, force => 1);
|
$f->field(name => "page", type => "hidden", value => $page, force => 1);
|
||||||
$f->field(name => "new_name", value => pagetitle($page), size => 60);
|
$f->field(name => "new_name", value => pagetitle($page, 1), size => 60);
|
||||||
if (!$q->param("attachment")) {
|
if (!$q->param("attachment")) {
|
||||||
# insert the standard extensions
|
# insert the standard extensions
|
||||||
my @page_types;
|
my @page_types;
|
||||||
|
@ -145,9 +145,9 @@ sub rename_form ($$$) { #{{{
|
||||||
$f->field(name => "attachment", type => "hidden");
|
$f->field(name => "attachment", type => "hidden");
|
||||||
|
|
||||||
return $f, ["Rename", "Cancel"];
|
return $f, ["Rename", "Cancel"];
|
||||||
} #}}}
|
}
|
||||||
|
|
||||||
sub rename_start ($$$$) { #{{{
|
sub rename_start ($$$$) {
|
||||||
my $q=shift;
|
my $q=shift;
|
||||||
my $session=shift;
|
my $session=shift;
|
||||||
my $attachment=shift;
|
my $attachment=shift;
|
||||||
|
@ -171,9 +171,9 @@ sub rename_start ($$$$) { #{{{
|
||||||
my ($f, $buttons)=rename_form($q, $session, $page);
|
my ($f, $buttons)=rename_form($q, $session, $page);
|
||||||
IkiWiki::showform($f, $buttons, $session, $q);
|
IkiWiki::showform($f, $buttons, $session, $q);
|
||||||
exit 0;
|
exit 0;
|
||||||
} #}}}
|
}
|
||||||
|
|
||||||
sub postrename ($;$$$) { #{{{
|
sub postrename ($;$$$) {
|
||||||
my $session=shift;
|
my $session=shift;
|
||||||
my $src=shift;
|
my $src=shift;
|
||||||
my $dest=shift;
|
my $dest=shift;
|
||||||
|
@ -204,9 +204,9 @@ sub postrename ($;$$$) { #{{{
|
||||||
}
|
}
|
||||||
|
|
||||||
IkiWiki::cgi_editpage($postrename, $session);
|
IkiWiki::cgi_editpage($postrename, $session);
|
||||||
} #}}}
|
}
|
||||||
|
|
||||||
sub formbuilder (@) { #{{{
|
sub formbuilder (@) {
|
||||||
my %params=@_;
|
my %params=@_;
|
||||||
my $form=$params{form};
|
my $form=$params{form};
|
||||||
|
|
||||||
|
@ -229,11 +229,11 @@ sub formbuilder (@) { #{{{
|
||||||
rename_start($q, $session, 1, $selected[0]);
|
rename_start($q, $session, 1, $selected[0]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} #}}}
|
}
|
||||||
|
|
||||||
my $renamesummary;
|
my $renamesummary;
|
||||||
|
|
||||||
sub formbuilder_setup (@) { #{{{
|
sub formbuilder_setup (@) {
|
||||||
my %params=@_;
|
my %params=@_;
|
||||||
my $form=$params{form};
|
my $form=$params{form};
|
||||||
my $q=$params{cgi};
|
my $q=$params{cgi};
|
||||||
|
@ -248,9 +248,9 @@ sub formbuilder_setup (@) { #{{{
|
||||||
$form->tmpl_param(message => $renamesummary);
|
$form->tmpl_param(message => $renamesummary);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} #}}}
|
}
|
||||||
|
|
||||||
sub sessioncgi ($$) { #{{{
|
sub sessioncgi ($$) {
|
||||||
my $q=shift;
|
my $q=shift;
|
||||||
|
|
||||||
if ($q->param("do") eq 'rename') {
|
if ($q->param("do") eq 'rename') {
|
||||||
|
@ -390,22 +390,8 @@ sub sessioncgi ($$) { #{{{
|
||||||
$template->param(error => $rename->{error});
|
$template->param(error => $rename->{error});
|
||||||
if ($rename->{src} ne $rename->{dest}) {
|
if ($rename->{src} ne $rename->{dest}) {
|
||||||
$template->param(brokenlinks_checked => 1);
|
$template->param(brokenlinks_checked => 1);
|
||||||
$template->param(brokenlinks => [
|
$template->param(brokenlinks => linklist($rename->{dest}, $rename->{brokenlinks}));
|
||||||
map {
|
$template->param(fixedlinks => linklist($rename->{dest}, $rename->{fixedlinks}));
|
||||||
{
|
|
||||||
page => htmllink($rename->{dest}, $rename->{dest}, $_,
|
|
||||||
noimageinline => 1)
|
|
||||||
}
|
|
||||||
} @{$rename->{brokenlinks}}
|
|
||||||
]);
|
|
||||||
$template->param(fixedlinks => [
|
|
||||||
map {
|
|
||||||
{
|
|
||||||
page => htmllink($rename->{dest}, $rename->{dest}, $_,
|
|
||||||
noimageinline => 1)
|
|
||||||
}
|
|
||||||
} @{$rename->{fixedlinks}}
|
|
||||||
]);
|
|
||||||
}
|
}
|
||||||
$renamesummary.=$template->output;
|
$renamesummary.=$template->output;
|
||||||
}
|
}
|
||||||
|
@ -418,9 +404,26 @@ sub sessioncgi ($$) { #{{{
|
||||||
|
|
||||||
exit 0;
|
exit 0;
|
||||||
}
|
}
|
||||||
} #}}}
|
}
|
||||||
|
|
||||||
|
sub linklist {
|
||||||
|
# generates a list of links in a form suitable for FormBuilder
|
||||||
|
my $dest=shift;
|
||||||
|
my $list=shift;
|
||||||
|
# converts a list of pages into a list of links
|
||||||
|
# in a form suitable for FormBuilder.
|
||||||
|
|
||||||
sub renamepage_hook ($$$$) { #{{{
|
[map {
|
||||||
|
{
|
||||||
|
page => htmllink($dest, $dest, $_,
|
||||||
|
noimageinline => 1,
|
||||||
|
linktext => pagetitle($_),
|
||||||
|
)
|
||||||
|
}
|
||||||
|
} @{$list}]
|
||||||
|
}
|
||||||
|
|
||||||
|
sub renamepage_hook ($$$$) {
|
||||||
my ($page, $src, $dest, $content)=@_;
|
my ($page, $src, $dest, $content)=@_;
|
||||||
|
|
||||||
IkiWiki::run_hooks(renamepage => sub {
|
IkiWiki::run_hooks(renamepage => sub {
|
||||||
|
@ -433,9 +436,9 @@ sub renamepage_hook ($$$$) { #{{{
|
||||||
});
|
});
|
||||||
|
|
||||||
return $content;
|
return $content;
|
||||||
}# }}}
|
}
|
||||||
|
|
||||||
sub do_rename ($$$) { #{{{
|
sub do_rename ($$$) {
|
||||||
my $rename=shift;
|
my $rename=shift;
|
||||||
my $q=shift;
|
my $q=shift;
|
||||||
my $session=shift;
|
my $session=shift;
|
||||||
|
@ -460,9 +463,9 @@ sub do_rename ($$$) { #{{{
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
} # }}}
|
}
|
||||||
|
|
||||||
sub fixlinks ($$$) { #{{{
|
sub fixlinks ($$$) {
|
||||||
my $rename=shift;
|
my $rename=shift;
|
||||||
my $session=shift;
|
my $session=shift;
|
||||||
|
|
||||||
|
@ -498,6 +501,6 @@ sub fixlinks ($$$) { #{{{
|
||||||
}
|
}
|
||||||
|
|
||||||
return @fixedlinks;
|
return @fixedlinks;
|
||||||
} #}}}
|
}
|
||||||
|
|
||||||
1
|
1
|
||||||
|
|
|
@ -0,0 +1,51 @@
|
||||||
|
#!/usr/bin/perl
|
||||||
|
package IkiWiki::Plugin::repolist;
|
||||||
|
|
||||||
|
use warnings;
|
||||||
|
use strict;
|
||||||
|
use IkiWiki 3.00;
|
||||||
|
|
||||||
|
sub import {
|
||||||
|
hook(type => "getsetup", id => "repolist", call => \&getsetup);
|
||||||
|
hook(type => "checkconfig", id => "repolist", call => \&checkconfig);
|
||||||
|
}
|
||||||
|
|
||||||
|
sub getsetup () {
|
||||||
|
return
|
||||||
|
plugin => {
|
||||||
|
safe => 1,
|
||||||
|
rebuild => undef,
|
||||||
|
},
|
||||||
|
repositories => {
|
||||||
|
type => "string",
|
||||||
|
example => ["svn://svn.example.org/wiki/trunk"],
|
||||||
|
description => "URIs of repositories containing the wiki's source",
|
||||||
|
safe => 1,
|
||||||
|
rebuild => undef,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
my $relvcs;
|
||||||
|
|
||||||
|
sub checkconfig () {
|
||||||
|
if (defined $config{rcs} && $config{repositories}) {
|
||||||
|
$relvcs=join("\n", map {
|
||||||
|
s/"//g; # avoid quotes just in case
|
||||||
|
qq{<link rel="vcs-$config{rcs}" href="$_" title="wiki $config{rcs} repository" />}
|
||||||
|
} @{$config{repositories}});
|
||||||
|
|
||||||
|
hook(type => "pagetemplate", id => "repolist", call => \&pagetemplate);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
sub pagetemplate (@) {
|
||||||
|
my %params=@_;
|
||||||
|
my $page=$params{page};
|
||||||
|
my $template=$params{template};
|
||||||
|
|
||||||
|
if (defined $relvcs && $template->query(name => "relvcs")) {
|
||||||
|
$template->param(relvcs => $relvcs);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
1
|
|
@ -4,18 +4,18 @@ package IkiWiki::Plugin::search;
|
||||||
|
|
||||||
use warnings;
|
use warnings;
|
||||||
use strict;
|
use strict;
|
||||||
use IkiWiki 2.00;
|
use IkiWiki 3.00;
|
||||||
|
|
||||||
sub import { #{{{
|
sub import {
|
||||||
hook(type => "getsetup", id => "search", call => \&getsetup);
|
hook(type => "getsetup", id => "search", call => \&getsetup);
|
||||||
hook(type => "checkconfig", id => "search", call => \&checkconfig);
|
hook(type => "checkconfig", id => "search", call => \&checkconfig);
|
||||||
hook(type => "pagetemplate", id => "search", call => \&pagetemplate);
|
hook(type => "pagetemplate", id => "search", call => \&pagetemplate);
|
||||||
hook(type => "postscan", id => "search", call => \&index);
|
hook(type => "postscan", id => "search", call => \&index);
|
||||||
hook(type => "delete", id => "search", call => \&delete);
|
hook(type => "delete", id => "search", call => \&delete);
|
||||||
hook(type => "cgi", id => "search", call => \&cgi);
|
hook(type => "cgi", id => "search", call => \&cgi);
|
||||||
} # }}}
|
}
|
||||||
|
|
||||||
sub getsetup () { #{{{
|
sub getsetup () {
|
||||||
return
|
return
|
||||||
plugin => {
|
plugin => {
|
||||||
safe => 1,
|
safe => 1,
|
||||||
|
@ -28,9 +28,9 @@ sub getsetup () { #{{{
|
||||||
safe => 0, # external program
|
safe => 0, # external program
|
||||||
rebuild => 0,
|
rebuild => 0,
|
||||||
},
|
},
|
||||||
} #}}}
|
}
|
||||||
|
|
||||||
sub checkconfig () { #{{{
|
sub checkconfig () {
|
||||||
foreach my $required (qw(url cgiurl)) {
|
foreach my $required (qw(url cgiurl)) {
|
||||||
if (! length $config{$required}) {
|
if (! length $config{$required}) {
|
||||||
error(sprintf(gettext("Must specify %s when using the search plugin"), $required));
|
error(sprintf(gettext("Must specify %s when using the search plugin"), $required));
|
||||||
|
@ -40,10 +40,10 @@ sub checkconfig () { #{{{
|
||||||
if (! defined $config{omega_cgi}) {
|
if (! defined $config{omega_cgi}) {
|
||||||
$config{omega_cgi}="/usr/lib/cgi-bin/omega/omega";
|
$config{omega_cgi}="/usr/lib/cgi-bin/omega/omega";
|
||||||
}
|
}
|
||||||
} #}}}
|
}
|
||||||
|
|
||||||
my $form;
|
my $form;
|
||||||
sub pagetemplate (@) { #{{{
|
sub pagetemplate (@) {
|
||||||
my %params=@_;
|
my %params=@_;
|
||||||
my $page=$params{page};
|
my $page=$params{page};
|
||||||
my $template=$params{template};
|
my $template=$params{template};
|
||||||
|
@ -58,11 +58,11 @@ sub pagetemplate (@) { #{{{
|
||||||
|
|
||||||
$template->param(searchform => $form);
|
$template->param(searchform => $form);
|
||||||
}
|
}
|
||||||
} #}}}
|
}
|
||||||
|
|
||||||
my $scrubber;
|
my $scrubber;
|
||||||
my $stemmer;
|
my $stemmer;
|
||||||
sub index (@) { #{{{
|
sub index (@) {
|
||||||
my %params=@_;
|
my %params=@_;
|
||||||
|
|
||||||
setupfiles();
|
setupfiles();
|
||||||
|
@ -146,17 +146,17 @@ sub index (@) { #{{{
|
||||||
|
|
||||||
$doc->add_term($pageterm);
|
$doc->add_term($pageterm);
|
||||||
$db->replace_document_by_term($pageterm, $doc);
|
$db->replace_document_by_term($pageterm, $doc);
|
||||||
} #}}}
|
}
|
||||||
|
|
||||||
sub delete (@) { #{{{
|
sub delete (@) {
|
||||||
my $db=xapiandb();
|
my $db=xapiandb();
|
||||||
foreach my $page (@_) {
|
foreach my $page (@_) {
|
||||||
my $pageterm=pageterm(pagename($page));
|
my $pageterm=pageterm(pagename($page));
|
||||||
$db->delete_document_by_term($pageterm) if defined $pageterm;
|
$db->delete_document_by_term($pageterm) if defined $pageterm;
|
||||||
}
|
}
|
||||||
} #}}}
|
}
|
||||||
|
|
||||||
sub cgi ($) { #{{{
|
sub cgi ($) {
|
||||||
my $cgi=shift;
|
my $cgi=shift;
|
||||||
|
|
||||||
if (defined $cgi->param('P')) {
|
if (defined $cgi->param('P')) {
|
||||||
|
@ -169,9 +169,9 @@ sub cgi ($) { #{{{
|
||||||
noimageinline => 1, linktext => "Help");
|
noimageinline => 1, linktext => "Help");
|
||||||
exec($config{omega_cgi}) || error("$config{omega_cgi} failed: $!");
|
exec($config{omega_cgi}) || error("$config{omega_cgi} failed: $!");
|
||||||
}
|
}
|
||||||
} #}}}
|
}
|
||||||
|
|
||||||
sub pageterm ($) { #{{{
|
sub pageterm ($) {
|
||||||
my $page=shift;
|
my $page=shift;
|
||||||
|
|
||||||
# 240 is the number used by omindex to decide when to hash an
|
# 240 is the number used by omindex to decide when to hash an
|
||||||
|
@ -190,10 +190,10 @@ sub pageterm ($) { #{{{
|
||||||
else {
|
else {
|
||||||
return "U:".$page;
|
return "U:".$page;
|
||||||
}
|
}
|
||||||
} #}}}
|
}
|
||||||
|
|
||||||
my $db;
|
my $db;
|
||||||
sub xapiandb () { #{{{
|
sub xapiandb () {
|
||||||
if (! defined $db) {
|
if (! defined $db) {
|
||||||
eval q{
|
eval q{
|
||||||
use Search::Xapian;
|
use Search::Xapian;
|
||||||
|
@ -204,11 +204,11 @@ sub xapiandb () { #{{{
|
||||||
Search::Xapian::DB_CREATE_OR_OPEN());
|
Search::Xapian::DB_CREATE_OR_OPEN());
|
||||||
}
|
}
|
||||||
return $db;
|
return $db;
|
||||||
} #}}}
|
}
|
||||||
|
|
||||||
{
|
{
|
||||||
my $setup=0;
|
my $setup=0;
|
||||||
sub setupfiles () { #{{{
|
sub setupfiles () {
|
||||||
if (! $setup and (! -e $config{wikistatedir}."/xapian" || $config{rebuild})) {
|
if (! $setup and (! -e $config{wikistatedir}."/xapian" || $config{rebuild})) {
|
||||||
writefile("omega.conf", $config{wikistatedir}."/xapian",
|
writefile("omega.conf", $config{wikistatedir}."/xapian",
|
||||||
"database_dir .\n".
|
"database_dir .\n".
|
||||||
|
@ -218,7 +218,7 @@ sub setupfiles () { #{{{
|
||||||
readfile(IkiWiki::template_file("searchquery.tmpl"))));
|
readfile(IkiWiki::template_file("searchquery.tmpl"))));
|
||||||
$setup=1;
|
$setup=1;
|
||||||
}
|
}
|
||||||
} #}}}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
1
|
1
|
||||||
|
|
|
@ -3,33 +3,41 @@ package IkiWiki::Plugin::shortcut;
|
||||||
|
|
||||||
use warnings;
|
use warnings;
|
||||||
use strict;
|
use strict;
|
||||||
use IkiWiki 2.00;
|
use IkiWiki 3.00;
|
||||||
|
|
||||||
sub import { #{{{
|
sub import {
|
||||||
hook(type => "getsetup", id => "shortcut", call => \&getsetup);
|
hook(type => "getsetup", id => "shortcut", call => \&getsetup);
|
||||||
hook(type => "refresh", id => "shortcut", call => \&refresh);
|
hook(type => "checkconfig", id => "shortcut", call => \&checkconfig);
|
||||||
hook(type => "preprocess", id => "shortcut", call => \&preprocess_shortcut);
|
hook(type => "preprocess", id => "shortcut", call => \&preprocess_shortcut);
|
||||||
} #}}}
|
}
|
||||||
|
|
||||||
sub getsetup () { #{{{
|
sub getsetup () {
|
||||||
return
|
return
|
||||||
plugin => {
|
plugin => {
|
||||||
safe => 1,
|
safe => 1,
|
||||||
rebuild => undef,
|
rebuild => undef,
|
||||||
},
|
},
|
||||||
} #}}}
|
}
|
||||||
|
|
||||||
sub refresh () { #{{{
|
sub checkconfig () {
|
||||||
# Preprocess the shortcuts page to get all the available shortcuts
|
if (defined $config{srcdir} && length $config{srcdir}) {
|
||||||
# defined before other pages are rendered.
|
# Preprocess the shortcuts page to get all the available shortcuts
|
||||||
my $srcfile=srcfile("shortcuts.mdwn", 1);
|
# defined before other pages are rendered.
|
||||||
if (! defined $srcfile) {
|
my $srcfile=srcfile("shortcuts.".$config{default_pageext}, 1);
|
||||||
error(gettext("shortcut plugin will not work without a shortcuts.mdwn"));
|
if (! defined $srcfile) {
|
||||||
|
$srcfile=srcfile("shortcuts.mdwn", 1);
|
||||||
|
}
|
||||||
|
if (! defined $srcfile) {
|
||||||
|
print STDERR sprintf(gettext("shortcut plugin will not work without %s"),
|
||||||
|
"shortcuts.".$config{default_pageext})."\n";
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
IkiWiki::preprocess("shortcuts", "shortcuts", readfile($srcfile));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
IkiWiki::preprocess("shortcuts", "shortcuts", readfile($srcfile));
|
}
|
||||||
} # }}}
|
|
||||||
|
|
||||||
sub preprocess_shortcut (@) { #{{{
|
sub preprocess_shortcut (@) {
|
||||||
my %params=@_;
|
my %params=@_;
|
||||||
|
|
||||||
if (! defined $params{name} || ! defined $params{url}) {
|
if (! defined $params{name} || ! defined $params{url}) {
|
||||||
|
@ -37,15 +45,16 @@ sub preprocess_shortcut (@) { #{{{
|
||||||
}
|
}
|
||||||
|
|
||||||
hook(type => "preprocess", no_override => 1, id => $params{name},
|
hook(type => "preprocess", no_override => 1, id => $params{name},
|
||||||
|
shortcut => 1,
|
||||||
call => sub { shortcut_expand($params{url}, $params{desc}, @_) });
|
call => sub { shortcut_expand($params{url}, $params{desc}, @_) });
|
||||||
|
|
||||||
#translators: This is used to display what shortcuts are defined.
|
#translators: This is used to display what shortcuts are defined.
|
||||||
#translators: First parameter is the name of the shortcut, the second
|
#translators: First parameter is the name of the shortcut, the second
|
||||||
#translators: is an URL.
|
#translators: is an URL.
|
||||||
return sprintf(gettext("shortcut %s points to <i>%s</i>"), $params{name}, $params{url});
|
return sprintf(gettext("shortcut %s points to <i>%s</i>"), $params{name}, $params{url});
|
||||||
} # }}}
|
}
|
||||||
|
|
||||||
sub shortcut_expand ($$@) { #{{{
|
sub shortcut_expand ($$@) {
|
||||||
my $url=shift;
|
my $url=shift;
|
||||||
my $desc=shift;
|
my $desc=shift;
|
||||||
my %params=@_;
|
my %params=@_;
|
||||||
|
@ -82,6 +91,6 @@ sub shortcut_expand ($$@) { #{{{
|
||||||
}
|
}
|
||||||
|
|
||||||
return "<a href=\"$url\">$desc</a>";
|
return "<a href=\"$url\">$desc</a>";
|
||||||
} #}}}
|
}
|
||||||
|
|
||||||
1
|
1
|
||||||
|
|
|
@ -6,22 +6,22 @@ package IkiWiki::Plugin::sidebar;
|
||||||
|
|
||||||
use warnings;
|
use warnings;
|
||||||
use strict;
|
use strict;
|
||||||
use IkiWiki 2.00;
|
use IkiWiki 3.00;
|
||||||
|
|
||||||
sub import { #{{{
|
sub import {
|
||||||
hook(type => "getsetup", id => "sidebar", call => \&getsetup);
|
hook(type => "getsetup", id => "sidebar", call => \&getsetup);
|
||||||
hook(type => "pagetemplate", id => "sidebar", call => \&pagetemplate);
|
hook(type => "pagetemplate", id => "sidebar", call => \&pagetemplate);
|
||||||
} # }}}
|
}
|
||||||
|
|
||||||
sub getsetup () { #{{{
|
sub getsetup () {
|
||||||
return
|
return
|
||||||
plugin => {
|
plugin => {
|
||||||
safe => 1,
|
safe => 1,
|
||||||
rebuild => 1,
|
rebuild => 1,
|
||||||
},
|
},
|
||||||
} #}}}
|
}
|
||||||
|
|
||||||
sub sidebar_content ($) { #{{{
|
sub sidebar_content ($) {
|
||||||
my $page=shift;
|
my $page=shift;
|
||||||
|
|
||||||
my $sidebar_page=bestlink($page, "sidebar") || return;
|
my $sidebar_page=bestlink($page, "sidebar") || return;
|
||||||
|
@ -42,9 +42,9 @@ sub sidebar_content ($) { #{{{
|
||||||
IkiWiki::filter($sidebar_page, $page, $content))));
|
IkiWiki::filter($sidebar_page, $page, $content))));
|
||||||
}
|
}
|
||||||
|
|
||||||
} # }}}
|
}
|
||||||
|
|
||||||
sub pagetemplate (@) { #{{{
|
sub pagetemplate (@) {
|
||||||
my %params=@_;
|
my %params=@_;
|
||||||
|
|
||||||
my $page=$params{page};
|
my $page=$params{page};
|
||||||
|
@ -56,6 +56,6 @@ sub pagetemplate (@) { #{{{
|
||||||
$template->param(sidebar => $content);
|
$template->param(sidebar => $content);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} # }}}
|
}
|
||||||
|
|
||||||
1
|
1
|
||||||
|
|
|
@ -3,23 +3,23 @@ package IkiWiki::Plugin::signinedit;
|
||||||
|
|
||||||
use warnings;
|
use warnings;
|
||||||
use strict;
|
use strict;
|
||||||
use IkiWiki 2.00;
|
use IkiWiki 3.00;
|
||||||
|
|
||||||
sub import { #{{{
|
sub import {
|
||||||
hook(type => "getsetup", id => "signinedit", call => \&getsetup);
|
hook(type => "getsetup", id => "signinedit", call => \&getsetup);
|
||||||
hook(type => "canedit", id => "signinedit", call => \&canedit,
|
hook(type => "canedit", id => "signinedit", call => \&canedit,
|
||||||
last => 1);
|
last => 1);
|
||||||
} # }}}
|
}
|
||||||
|
|
||||||
sub getsetup () { #{{{
|
sub getsetup () {
|
||||||
return
|
return
|
||||||
plugin => {
|
plugin => {
|
||||||
safe => 1,
|
safe => 1,
|
||||||
rebuild => 0,
|
rebuild => 0,
|
||||||
},
|
},
|
||||||
} #}}}
|
}
|
||||||
|
|
||||||
sub canedit ($$$) { #{{{
|
sub canedit ($$$) {
|
||||||
my $page=shift;
|
my $page=shift;
|
||||||
my $cgi=shift;
|
my $cgi=shift;
|
||||||
my $session=shift;
|
my $session=shift;
|
||||||
|
@ -34,6 +34,6 @@ sub canedit ($$$) { #{{{
|
||||||
else {
|
else {
|
||||||
return "";
|
return "";
|
||||||
}
|
}
|
||||||
} #}}}
|
}
|
||||||
|
|
||||||
1
|
1
|
||||||
|
|
|
@ -6,9 +6,9 @@ package IkiWiki::Plugin::skeleton;
|
||||||
|
|
||||||
use warnings;
|
use warnings;
|
||||||
use strict;
|
use strict;
|
||||||
use IkiWiki 2.00;
|
use IkiWiki 3.00;
|
||||||
|
|
||||||
sub import { #{{{
|
sub import {
|
||||||
hook(type => "getopt", id => "skeleton", call => \&getopt);
|
hook(type => "getopt", id => "skeleton", call => \&getopt);
|
||||||
hook(type => "getsetup", id => "skeleton", call => \&getsetup);
|
hook(type => "getsetup", id => "skeleton", call => \&getsetup);
|
||||||
hook(type => "checkconfig", id => "skeleton", call => \&checkconfig);
|
hook(type => "checkconfig", id => "skeleton", call => \&checkconfig);
|
||||||
|
@ -30,17 +30,18 @@ sub import { #{{{
|
||||||
hook(type => "auth", id => "skeleton", call => \&auth);
|
hook(type => "auth", id => "skeleton", call => \&auth);
|
||||||
hook(type => "sessioncgi", id => "skeleton", call => \&sessioncgi);
|
hook(type => "sessioncgi", id => "skeleton", call => \&sessioncgi);
|
||||||
hook(type => "canedit", id => "skeleton", call => \&canedit);
|
hook(type => "canedit", id => "skeleton", call => \&canedit);
|
||||||
|
hook(type => "checkcontent", id => "skeleton", call => \&checkcontent);
|
||||||
hook(type => "editcontent", id => "skeleton", call => \&editcontent);
|
hook(type => "editcontent", id => "skeleton", call => \&editcontent);
|
||||||
hook(type => "formbuilder_setup", id => "skeleton", call => \&formbuilder_setup);
|
hook(type => "formbuilder_setup", id => "skeleton", call => \&formbuilder_setup);
|
||||||
hook(type => "formbuilder", id => "skeleton", call => \&formbuilder);
|
hook(type => "formbuilder", id => "skeleton", call => \&formbuilder);
|
||||||
hook(type => "savestate", id => "skeleton", call => \&savestate);
|
hook(type => "savestate", id => "skeleton", call => \&savestate);
|
||||||
} # }}}
|
}
|
||||||
|
|
||||||
sub getopt () { #{{{
|
sub getopt () {
|
||||||
debug("skeleton plugin getopt");
|
debug("skeleton plugin getopt");
|
||||||
} #}}}
|
}
|
||||||
|
|
||||||
sub getsetup () { #{{{
|
sub getsetup () {
|
||||||
return
|
return
|
||||||
plugin => {
|
plugin => {
|
||||||
safe => 1,
|
safe => 1,
|
||||||
|
@ -53,155 +54,161 @@ sub getsetup () { #{{{
|
||||||
safe => 0,
|
safe => 0,
|
||||||
rebuild => 0,
|
rebuild => 0,
|
||||||
},
|
},
|
||||||
} #}}}
|
}
|
||||||
|
|
||||||
sub checkconfig () { #{{{
|
sub checkconfig () {
|
||||||
debug("skeleton plugin checkconfig");
|
debug("skeleton plugin checkconfig");
|
||||||
} #}}}
|
}
|
||||||
|
|
||||||
sub refresh () { #{{{
|
sub refresh () {
|
||||||
debug("skeleton plugin refresh");
|
debug("skeleton plugin refresh");
|
||||||
} #}}}
|
}
|
||||||
|
|
||||||
sub needsbuild () { #{{{
|
sub needsbuild () {
|
||||||
debug("skeleton plugin needsbuild");
|
debug("skeleton plugin needsbuild");
|
||||||
} #}}}
|
}
|
||||||
|
|
||||||
sub preprocess (@) { #{{{
|
sub preprocess (@) {
|
||||||
my %params=@_;
|
my %params=@_;
|
||||||
|
|
||||||
return "skeleton plugin result";
|
return "skeleton plugin result";
|
||||||
} # }}}
|
}
|
||||||
|
|
||||||
sub filter (@) { #{{{
|
sub filter (@) {
|
||||||
my %params=@_;
|
my %params=@_;
|
||||||
|
|
||||||
debug("skeleton plugin running as filter");
|
debug("skeleton plugin running as filter");
|
||||||
|
|
||||||
return $params{content};
|
return $params{content};
|
||||||
} # }}}
|
}
|
||||||
|
|
||||||
sub linkify (@) { #{{{
|
sub linkify (@) {
|
||||||
my %params=@_;
|
my %params=@_;
|
||||||
|
|
||||||
debug("skeleton plugin running as linkify");
|
debug("skeleton plugin running as linkify");
|
||||||
|
|
||||||
return $params{content};
|
return $params{content};
|
||||||
} # }}}
|
}
|
||||||
|
|
||||||
sub scan (@) { #{{{a
|
sub scan (@) {
|
||||||
my %params=@_;
|
my %params=@_;
|
||||||
|
|
||||||
debug("skeleton plugin running as scan");
|
debug("skeleton plugin running as scan");
|
||||||
} # }}}
|
}
|
||||||
|
|
||||||
sub htmlize (@) { #{{{
|
sub htmlize (@) {
|
||||||
my %params=@_;
|
my %params=@_;
|
||||||
|
|
||||||
debug("skeleton plugin running as htmlize");
|
debug("skeleton plugin running as htmlize");
|
||||||
|
|
||||||
return $params{content};
|
return $params{content};
|
||||||
} # }}}
|
}
|
||||||
|
|
||||||
sub sanitize (@) { #{{{
|
sub sanitize (@) {
|
||||||
my %params=@_;
|
my %params=@_;
|
||||||
|
|
||||||
debug("skeleton plugin running as a sanitizer");
|
debug("skeleton plugin running as a sanitizer");
|
||||||
|
|
||||||
return $params{content};
|
return $params{content};
|
||||||
} # }}}
|
}
|
||||||
|
|
||||||
sub postscan (@) { #{{{
|
sub postscan (@) {
|
||||||
my %params=@_;
|
my %params=@_;
|
||||||
|
|
||||||
debug("skeleton plugin running as postscan");
|
debug("skeleton plugin running as postscan");
|
||||||
} # }}}
|
}
|
||||||
|
|
||||||
sub format (@) { #{{{
|
sub format (@) {
|
||||||
my %params=@_;
|
my %params=@_;
|
||||||
|
|
||||||
debug("skeleton plugin running as a formatter");
|
debug("skeleton plugin running as a formatter");
|
||||||
|
|
||||||
return $params{content};
|
return $params{content};
|
||||||
} # }}}
|
}
|
||||||
|
|
||||||
sub pagetemplate (@) { #{{{
|
sub pagetemplate (@) {
|
||||||
my %params=@_;
|
my %params=@_;
|
||||||
my $page=$params{page};
|
my $page=$params{page};
|
||||||
my $template=$params{template};
|
my $template=$params{template};
|
||||||
|
|
||||||
debug("skeleton plugin running as a pagetemplate hook");
|
debug("skeleton plugin running as a pagetemplate hook");
|
||||||
} # }}}
|
}
|
||||||
|
|
||||||
sub templatefile (@) { #{{{
|
sub templatefile (@) {
|
||||||
my %params=@_;
|
my %params=@_;
|
||||||
my $page=$params{page};
|
my $page=$params{page};
|
||||||
|
|
||||||
debug("skeleton plugin running as a templatefile hook");
|
debug("skeleton plugin running as a templatefile hook");
|
||||||
} # }}}
|
}
|
||||||
|
|
||||||
sub delete (@) { #{{{
|
sub delete (@) {
|
||||||
my @files=@_;
|
my @files=@_;
|
||||||
|
|
||||||
debug("skeleton plugin told that files were deleted: @files");
|
debug("skeleton plugin told that files were deleted: @files");
|
||||||
} #}}}
|
}
|
||||||
|
|
||||||
sub change (@) { #{{{
|
sub change (@) {
|
||||||
my @files=@_;
|
my @files=@_;
|
||||||
|
|
||||||
debug("skeleton plugin told that changed files were rendered: @files");
|
debug("skeleton plugin told that changed files were rendered: @files");
|
||||||
} #}}}
|
}
|
||||||
|
|
||||||
sub cgi ($) { #{{{
|
sub cgi ($) {
|
||||||
my $cgi=shift;
|
my $cgi=shift;
|
||||||
|
|
||||||
debug("skeleton plugin running in cgi");
|
debug("skeleton plugin running in cgi");
|
||||||
} #}}}
|
}
|
||||||
|
|
||||||
sub auth ($$) { #{{{
|
sub auth ($$) {
|
||||||
my $cgi=shift;
|
my $cgi=shift;
|
||||||
my $session=shift;
|
my $session=shift;
|
||||||
|
|
||||||
debug("skeleton plugin running in auth");
|
debug("skeleton plugin running in auth");
|
||||||
} #}}}
|
}
|
||||||
|
|
||||||
sub sessioncgi ($$) { #{{{
|
sub sessioncgi ($$) {
|
||||||
my $cgi=shift;
|
my $cgi=shift;
|
||||||
my $session=shift;
|
my $session=shift;
|
||||||
|
|
||||||
debug("skeleton plugin running in sessioncgi");
|
debug("skeleton plugin running in sessioncgi");
|
||||||
} #}}}
|
}
|
||||||
|
|
||||||
sub canedit ($$$) { #{{{
|
sub canedit ($$$) {
|
||||||
my $page=shift;
|
my $page=shift;
|
||||||
my $cgi=shift;
|
my $cgi=shift;
|
||||||
my $session=shift;
|
my $session=shift;
|
||||||
|
|
||||||
debug("skeleton plugin running in canedit");
|
debug("skeleton plugin running in canedit");
|
||||||
} #}}}
|
}
|
||||||
|
|
||||||
sub editcontent ($$$) { #{{{
|
sub checkcontent (@) {
|
||||||
|
my %params=@_;
|
||||||
|
|
||||||
|
debug("skeleton plugin running in checkcontent");
|
||||||
|
}
|
||||||
|
|
||||||
|
sub editcontent ($$$) {
|
||||||
my %params=@_;
|
my %params=@_;
|
||||||
|
|
||||||
debug("skeleton plugin running in editcontent");
|
debug("skeleton plugin running in editcontent");
|
||||||
|
|
||||||
return $params{content};
|
return $params{content};
|
||||||
} #}}}
|
}
|
||||||
|
|
||||||
sub formbuilder_setup (@) { #{{{
|
sub formbuilder_setup (@) {
|
||||||
my %params=@_;
|
my %params=@_;
|
||||||
|
|
||||||
debug("skeleton plugin running in formbuilder_setup");
|
debug("skeleton plugin running in formbuilder_setup");
|
||||||
} # }}}
|
}
|
||||||
|
|
||||||
sub formbuilder (@) { #{{{
|
sub formbuilder (@) {
|
||||||
my %params=@_;
|
my %params=@_;
|
||||||
|
|
||||||
debug("skeleton plugin running in formbuilder");
|
debug("skeleton plugin running in formbuilder");
|
||||||
} # }}}
|
}
|
||||||
|
|
||||||
sub savestate () { #{{{
|
sub savestate () {
|
||||||
debug("skeleton plugin running in savestate");
|
debug("skeleton plugin running in savestate");
|
||||||
} #}}}
|
}
|
||||||
|
|
||||||
1
|
1
|
||||||
|
|
|
@ -3,18 +3,18 @@ package IkiWiki::Plugin::smiley;
|
||||||
|
|
||||||
use warnings;
|
use warnings;
|
||||||
use strict;
|
use strict;
|
||||||
use IkiWiki 2.00;
|
use IkiWiki 3.00;
|
||||||
|
|
||||||
my %smileys;
|
my %smileys;
|
||||||
my $smiley_regexp;
|
my $smiley_regexp;
|
||||||
|
|
||||||
sub import { #{{{
|
sub import {
|
||||||
add_underlay("smiley");
|
add_underlay("smiley");
|
||||||
hook(type => "getsetup", id => "smiley", call => \&getsetup);
|
hook(type => "getsetup", id => "smiley", call => \&getsetup);
|
||||||
hook(type => "sanitize", id => "smiley", call => \&sanitize);
|
hook(type => "sanitize", id => "smiley", call => \&sanitize);
|
||||||
} # }}}
|
}
|
||||||
|
|
||||||
sub getsetup () { #{{{
|
sub getsetup () {
|
||||||
return
|
return
|
||||||
plugin => {
|
plugin => {
|
||||||
safe => 1,
|
safe => 1,
|
||||||
|
@ -22,9 +22,9 @@ sub getsetup () { #{{{
|
||||||
# removes the smileys, which would break links
|
# removes the smileys, which would break links
|
||||||
rebuild => 1,
|
rebuild => 1,
|
||||||
},
|
},
|
||||||
} #}}}
|
}
|
||||||
|
|
||||||
sub build_regexp () { #{{{
|
sub build_regexp () {
|
||||||
my $list=readfile(srcfile("smileys.mdwn"));
|
my $list=readfile(srcfile("smileys.mdwn"));
|
||||||
while ($list =~ m/^\s*\*\s+\\\\([^\s]+)\s+\[\[([^]]+)\]\]/mg) {
|
while ($list =~ m/^\s*\*\s+\\\\([^\s]+)\s+\[\[([^]]+)\]\]/mg) {
|
||||||
my $smiley=$1;
|
my $smiley=$1;
|
||||||
|
@ -50,9 +50,9 @@ sub build_regexp () { #{{{
|
||||||
$smiley_regexp='('.join('|', map { quotemeta }
|
$smiley_regexp='('.join('|', map { quotemeta }
|
||||||
reverse sort keys %smileys).')';
|
reverse sort keys %smileys).')';
|
||||||
#debug($smiley_regexp);
|
#debug($smiley_regexp);
|
||||||
} #}}}
|
}
|
||||||
|
|
||||||
sub sanitize (@) { #{{{
|
sub sanitize (@) {
|
||||||
my %params=@_;
|
my %params=@_;
|
||||||
|
|
||||||
build_regexp() unless defined $smiley_regexp;
|
build_regexp() unless defined $smiley_regexp;
|
||||||
|
@ -87,14 +87,14 @@ MATCH: while (m{(?:^|(?<=\s|>))(\\?)$smiley_regexp(?:(?=\s|<)|$)}g) {
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
# Replace the smiley with its expanded value.
|
# Replace the smiley with its expanded value.
|
||||||
substr($_, $spos, length($smiley))=
|
my $link=htmllink($params{page}, $params{destpage},
|
||||||
htmllink($params{page}, $params{destpage},
|
|
||||||
$smileys{$smiley}, linktext => $smiley);
|
$smileys{$smiley}, linktext => $smiley);
|
||||||
pos=$epos+1;
|
substr($_, $spos, length($smiley))=$link;
|
||||||
|
pos=$epos+length($link);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return $_;
|
return $_;
|
||||||
} # }}}
|
}
|
||||||
|
|
||||||
1
|
1
|
||||||
|
|
|
@ -3,7 +3,7 @@ package IkiWiki::Plugin::sparkline;
|
||||||
|
|
||||||
use warnings;
|
use warnings;
|
||||||
use strict;
|
use strict;
|
||||||
use IkiWiki 2.00;
|
use IkiWiki 3.00;
|
||||||
use IPC::Open2;
|
use IPC::Open2;
|
||||||
|
|
||||||
my $match_num=qr/[-+]?[0-9]+(?:\.[0-9]+)?/;
|
my $match_num=qr/[-+]?[0-9]+(?:\.[0-9]+)?/;
|
||||||
|
@ -14,20 +14,20 @@ my %locmap=(
|
||||||
left => 'TEXT_LEFT',
|
left => 'TEXT_LEFT',
|
||||||
);
|
);
|
||||||
|
|
||||||
sub import { #{{{
|
sub import {
|
||||||
hook(type => "getsetup", id => "sparkline", call => \&getsetup);
|
hook(type => "getsetup", id => "sparkline", call => \&getsetup);
|
||||||
hook(type => "preprocess", id => "sparkline", call => \&preprocess);
|
hook(type => "preprocess", id => "sparkline", call => \&preprocess);
|
||||||
} # }}}
|
}
|
||||||
|
|
||||||
sub getsetup () { #{{{
|
sub getsetup () {
|
||||||
return
|
return
|
||||||
plugin => {
|
plugin => {
|
||||||
safe => 1,
|
safe => 1,
|
||||||
rebuild => undef,
|
rebuild => undef,
|
||||||
},
|
},
|
||||||
} #}}}
|
}
|
||||||
|
|
||||||
sub preprocess (@) { #{{{
|
sub preprocess (@) {
|
||||||
my %params=@_;
|
my %params=@_;
|
||||||
|
|
||||||
my $php;
|
my $php;
|
||||||
|
@ -130,7 +130,7 @@ sub preprocess (@) { #{{{
|
||||||
|
|
||||||
if (! -e "$config{destdir}/$fn") {
|
if (! -e "$config{destdir}/$fn") {
|
||||||
my $pid;
|
my $pid;
|
||||||
my $sigpipe=0;;
|
my $sigpipe=0;
|
||||||
$SIG{PIPE}=sub { $sigpipe=1 };
|
$SIG{PIPE}=sub { $sigpipe=1 };
|
||||||
$pid=open2(*IN, *OUT, "php");
|
$pid=open2(*IN, *OUT, "php");
|
||||||
|
|
||||||
|
@ -166,6 +166,6 @@ sub preprocess (@) { #{{{
|
||||||
}
|
}
|
||||||
|
|
||||||
return '<img src="'.urlto($fn, $params{destpage}).'" alt="graph" />';
|
return '<img src="'.urlto($fn, $params{destpage}).'" alt="graph" />';
|
||||||
} # }}}
|
}
|
||||||
|
|
||||||
1
|
1
|
||||||
|
|
|
@ -6,7 +6,7 @@ use strict;
|
||||||
use IkiWiki;
|
use IkiWiki;
|
||||||
use POSIX qw(setlocale LC_CTYPE);
|
use POSIX qw(setlocale LC_CTYPE);
|
||||||
|
|
||||||
sub import { #{{{
|
sub import {
|
||||||
hook(type => "checkconfig", id => "svn", call => \&checkconfig);
|
hook(type => "checkconfig", id => "svn", call => \&checkconfig);
|
||||||
hook(type => "getsetup", id => "svn", call => \&getsetup);
|
hook(type => "getsetup", id => "svn", call => \&getsetup);
|
||||||
hook(type => "rcs", id => "rcs_update", call => \&rcs_update);
|
hook(type => "rcs", id => "rcs_update", call => \&rcs_update);
|
||||||
|
@ -19,9 +19,9 @@ sub import { #{{{
|
||||||
hook(type => "rcs", id => "rcs_recentchanges", call => \&rcs_recentchanges);
|
hook(type => "rcs", id => "rcs_recentchanges", call => \&rcs_recentchanges);
|
||||||
hook(type => "rcs", id => "rcs_diff", call => \&rcs_diff);
|
hook(type => "rcs", id => "rcs_diff", call => \&rcs_diff);
|
||||||
hook(type => "rcs", id => "rcs_getctime", call => \&rcs_getctime);
|
hook(type => "rcs", id => "rcs_getctime", call => \&rcs_getctime);
|
||||||
} #}}}
|
}
|
||||||
|
|
||||||
sub checkconfig () { #{{{
|
sub checkconfig () {
|
||||||
if (! defined $config{svnpath}) {
|
if (! defined $config{svnpath}) {
|
||||||
$config{svnpath}="trunk";
|
$config{svnpath}="trunk";
|
||||||
}
|
}
|
||||||
|
@ -37,9 +37,9 @@ sub checkconfig () { #{{{
|
||||||
wrappermode => (defined $config{svn_wrappermode} ? $config{svn_wrappermode} : "04755"),
|
wrappermode => (defined $config{svn_wrappermode} ? $config{svn_wrappermode} : "04755"),
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
} #}}}
|
}
|
||||||
|
|
||||||
sub getsetup () { #{{{
|
sub getsetup () {
|
||||||
return
|
return
|
||||||
plugin => {
|
plugin => {
|
||||||
safe => 0, # rcs plugin
|
safe => 0, # rcs plugin
|
||||||
|
@ -87,7 +87,7 @@ sub getsetup () { #{{{
|
||||||
safe => 1,
|
safe => 1,
|
||||||
rebuild => 1,
|
rebuild => 1,
|
||||||
},
|
},
|
||||||
} #}}}
|
}
|
||||||
|
|
||||||
# svn needs LC_CTYPE set to a UTF-8 locale, so try to find one. Any will do.
|
# svn needs LC_CTYPE set to a UTF-8 locale, so try to find one. Any will do.
|
||||||
sub find_lc_ctype() {
|
sub find_lc_ctype() {
|
||||||
|
@ -107,27 +107,27 @@ sub find_lc_ctype() {
|
||||||
|
|
||||||
# fallback to the current locale
|
# fallback to the current locale
|
||||||
return $current;
|
return $current;
|
||||||
} # }}}
|
}
|
||||||
$ENV{LC_CTYPE} = $ENV{LC_CTYPE} || find_lc_ctype();
|
$ENV{LC_CTYPE} = $ENV{LC_CTYPE} || find_lc_ctype();
|
||||||
|
|
||||||
sub svn_info ($$) { #{{{
|
sub svn_info ($$) {
|
||||||
my $field=shift;
|
my $field=shift;
|
||||||
my $file=shift;
|
my $file=shift;
|
||||||
|
|
||||||
my $info=`LANG=C svn info $file`;
|
my $info=`LANG=C svn info $file`;
|
||||||
my ($ret)=$info=~/^$field: (.*)$/m;
|
my ($ret)=$info=~/^$field: (.*)$/m;
|
||||||
return $ret;
|
return $ret;
|
||||||
} #}}}
|
}
|
||||||
|
|
||||||
sub rcs_update () { #{{{
|
sub rcs_update () {
|
||||||
if (-d "$config{srcdir}/.svn") {
|
if (-d "$config{srcdir}/.svn") {
|
||||||
if (system("svn", "update", "--quiet", $config{srcdir}) != 0) {
|
if (system("svn", "update", "--quiet", $config{srcdir}) != 0) {
|
||||||
warn("svn update failed\n");
|
warn("svn update failed\n");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} #}}}
|
}
|
||||||
|
|
||||||
sub rcs_prepedit ($) { #{{{
|
sub rcs_prepedit ($) {
|
||||||
# Prepares to edit a file under revision control. Returns a token
|
# Prepares to edit a file under revision control. Returns a token
|
||||||
# that must be passed into rcs_commit when the file is ready
|
# that must be passed into rcs_commit when the file is ready
|
||||||
# for committing.
|
# for committing.
|
||||||
|
@ -140,9 +140,9 @@ sub rcs_prepedit ($) { #{{{
|
||||||
my $rev=svn_info("Revision", "$config{srcdir}/$file");
|
my $rev=svn_info("Revision", "$config{srcdir}/$file");
|
||||||
return defined $rev ? $rev : "";
|
return defined $rev ? $rev : "";
|
||||||
}
|
}
|
||||||
} #}}}
|
}
|
||||||
|
|
||||||
sub rcs_commit ($$$;$$) { #{{{
|
sub rcs_commit ($$$;$$) {
|
||||||
# Tries to commit the page; returns undef on _success_ and
|
# Tries to commit the page; returns undef on _success_ and
|
||||||
# a version of the page with the rcs's conflict markers on failure.
|
# a version of the page with the rcs's conflict markers on failure.
|
||||||
# The file is relative to the srcdir.
|
# The file is relative to the srcdir.
|
||||||
|
@ -185,7 +185,7 @@ sub rcs_commit ($$$;$$) { #{{{
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return undef # success
|
return undef # success
|
||||||
} #}}}
|
}
|
||||||
|
|
||||||
sub rcs_commit_staged ($$$) {
|
sub rcs_commit_staged ($$$) {
|
||||||
# Commits all staged changes. Changes can be staged using rcs_add,
|
# Commits all staged changes. Changes can be staged using rcs_add,
|
||||||
|
@ -209,7 +209,7 @@ sub rcs_commit_staged ($$$) {
|
||||||
return undef # success
|
return undef # success
|
||||||
}
|
}
|
||||||
|
|
||||||
sub rcs_add ($) { #{{{
|
sub rcs_add ($) {
|
||||||
# filename is relative to the root of the srcdir
|
# filename is relative to the root of the srcdir
|
||||||
my $file=shift;
|
my $file=shift;
|
||||||
|
|
||||||
|
@ -224,9 +224,9 @@ sub rcs_add ($) { #{{{
|
||||||
warn("svn add failed\n");
|
warn("svn add failed\n");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} #}}}
|
}
|
||||||
|
|
||||||
sub rcs_remove ($) { #{{{
|
sub rcs_remove ($) {
|
||||||
# filename is relative to the root of the srcdir
|
# filename is relative to the root of the srcdir
|
||||||
my $file=shift;
|
my $file=shift;
|
||||||
|
|
||||||
|
@ -235,9 +235,9 @@ sub rcs_remove ($) { #{{{
|
||||||
warn("svn rm failed\n");
|
warn("svn rm failed\n");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} #}}}
|
}
|
||||||
|
|
||||||
sub rcs_rename ($$) { #{{{
|
sub rcs_rename ($$) {
|
||||||
# filenames relative to the root of the srcdir
|
# filenames relative to the root of the srcdir
|
||||||
my ($src, $dest)=@_;
|
my ($src, $dest)=@_;
|
||||||
|
|
||||||
|
@ -258,9 +258,9 @@ sub rcs_rename ($$) { #{{{
|
||||||
warn("svn rename failed\n");
|
warn("svn rename failed\n");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} #}}}
|
}
|
||||||
|
|
||||||
sub rcs_recentchanges ($) { #{{{
|
sub rcs_recentchanges ($) {
|
||||||
my $num=shift;
|
my $num=shift;
|
||||||
my @ret;
|
my @ret;
|
||||||
|
|
||||||
|
@ -341,14 +341,14 @@ sub rcs_recentchanges ($) { #{{{
|
||||||
}
|
}
|
||||||
|
|
||||||
return @ret;
|
return @ret;
|
||||||
} #}}}
|
}
|
||||||
|
|
||||||
sub rcs_diff ($) { #{{{
|
sub rcs_diff ($) {
|
||||||
my $rev=IkiWiki::possibly_foolish_untaint(int(shift));
|
my $rev=IkiWiki::possibly_foolish_untaint(int(shift));
|
||||||
return `svnlook diff $config{svnrepo} -r$rev --no-diff-deleted`;
|
return `svnlook diff $config{svnrepo} -r$rev --no-diff-deleted`;
|
||||||
} #}}}
|
}
|
||||||
|
|
||||||
sub rcs_getctime ($) { #{{{
|
sub rcs_getctime ($) {
|
||||||
my $file=shift;
|
my $file=shift;
|
||||||
|
|
||||||
my $svn_log_infoline=qr/^r\d+\s+\|\s+[^\s]+\s+\|\s+(\d+-\d+-\d+\s+\d+:\d+:\d+\s+[-+]?\d+).*/;
|
my $svn_log_infoline=qr/^r\d+\s+\|\s+[^\s]+\s+\|\s+(\d+-\d+-\d+\s+\d+:\d+:\d+\s+[-+]?\d+).*/;
|
||||||
|
@ -376,6 +376,6 @@ sub rcs_getctime ($) { #{{{
|
||||||
$date=str2time($date);
|
$date=str2time($date);
|
||||||
debug("found ctime ".localtime($date)." for $file");
|
debug("found ctime ".localtime($date)." for $file");
|
||||||
return $date;
|
return $date;
|
||||||
} #}}}
|
}
|
||||||
|
|
||||||
1
|
1
|
||||||
|
|
|
@ -4,22 +4,22 @@ package IkiWiki::Plugin::table;
|
||||||
use warnings;
|
use warnings;
|
||||||
use strict;
|
use strict;
|
||||||
use Encode;
|
use Encode;
|
||||||
use IkiWiki 2.00;
|
use IkiWiki 3.00;
|
||||||
|
|
||||||
sub import { #{{{
|
sub import {
|
||||||
hook(type => "getsetup", id => "table", call => \&getsetup);
|
hook(type => "getsetup", id => "table", call => \&getsetup);
|
||||||
hook(type => "preprocess", id => "table", call => \&preprocess);
|
hook(type => "preprocess", id => "table", call => \&preprocess, scan => 1);
|
||||||
} # }}}
|
}
|
||||||
|
|
||||||
sub getsetup () { #{{{
|
sub getsetup () {
|
||||||
return
|
return
|
||||||
plugin => {
|
plugin => {
|
||||||
safe => 1,
|
safe => 1,
|
||||||
rebuild => undef,
|
rebuild => undef,
|
||||||
},
|
},
|
||||||
} #}}}
|
}
|
||||||
|
|
||||||
sub preprocess (@) { #{{{
|
sub preprocess (@) {
|
||||||
my %params =(
|
my %params =(
|
||||||
format => 'auto',
|
format => 'auto',
|
||||||
header => 'row',
|
header => 'row',
|
||||||
|
@ -27,13 +27,31 @@ sub preprocess (@) { #{{{
|
||||||
);
|
);
|
||||||
|
|
||||||
if (exists $params{file}) {
|
if (exists $params{file}) {
|
||||||
if (! $pagesources{$params{file}}) {
|
if (! exists $pagesources{$params{file}}) {
|
||||||
error gettext("cannot find file");
|
error gettext("cannot find file");
|
||||||
}
|
}
|
||||||
$params{data} = readfile(srcfile($params{file}));
|
$params{data} = readfile(srcfile($params{file}));
|
||||||
add_depends($params{page}, $params{file});
|
add_depends($params{page}, $params{file});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (! defined wantarray) {
|
||||||
|
# scan mode -- if the table uses an external file, need to
|
||||||
|
# scan that file too.
|
||||||
|
return unless exists $params{file};
|
||||||
|
|
||||||
|
IkiWiki::run_hooks(scan => sub {
|
||||||
|
shift->(
|
||||||
|
page => $params{page},
|
||||||
|
content => $params{data},
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
|
# Preprocess in scan-only mode.
|
||||||
|
IkiWiki::preprocess($params{page}, $params{page}, $params{data}, 1);
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
if (lc $params{format} eq 'auto') {
|
if (lc $params{format} eq 'auto') {
|
||||||
# first try the more simple format
|
# first try the more simple format
|
||||||
if (is_dsv_data($params{data})) {
|
if (is_dsv_data($params{data})) {
|
||||||
|
@ -50,22 +68,18 @@ sub preprocess (@) { #{{{
|
||||||
defined $params{delimiter} ? $params{delimiter} : ",",);
|
defined $params{delimiter} ? $params{delimiter} : ",",);
|
||||||
# linkify after parsing since html link quoting can
|
# linkify after parsing since html link quoting can
|
||||||
# confuse CSV parsing
|
# confuse CSV parsing
|
||||||
if (! exists $params{file}) {
|
@data=map {
|
||||||
@data=map {
|
[ map {
|
||||||
[ map {
|
IkiWiki::linkify($params{page},
|
||||||
IkiWiki::linkify($params{page},
|
$params{destpage}, $_);
|
||||||
$params{destpage}, $_);
|
} @$_ ]
|
||||||
} @$_ ]
|
} @data;
|
||||||
} @data;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
elsif (lc $params{format} eq 'dsv') {
|
elsif (lc $params{format} eq 'dsv') {
|
||||||
# linkify before parsing since wikilinks can contain the
|
# linkify before parsing since wikilinks can contain the
|
||||||
# delimiter
|
# delimiter
|
||||||
if (! exists $params{file}) {
|
$params{data} = IkiWiki::linkify($params{page},
|
||||||
$params{data} = IkiWiki::linkify($params{page},
|
$params{destpage}, $params{data});
|
||||||
$params{destpage}, $params{data});
|
|
||||||
}
|
|
||||||
@data=split_dsv($params{data},
|
@data=split_dsv($params{data},
|
||||||
defined $params{delimiter} ? $params{delimiter} : "|",);
|
defined $params{delimiter} ? $params{delimiter} : "|",);
|
||||||
}
|
}
|
||||||
|
@ -102,16 +116,16 @@ sub preprocess (@) { #{{{
|
||||||
else {
|
else {
|
||||||
return $html;
|
return $html;
|
||||||
}
|
}
|
||||||
} #}}}
|
}
|
||||||
|
|
||||||
sub is_dsv_data ($) { #{{{
|
sub is_dsv_data ($) {
|
||||||
my $text = shift;
|
my $text = shift;
|
||||||
|
|
||||||
my ($line) = split(/\n/, $text);
|
my ($line) = split(/\n/, $text);
|
||||||
return $line =~ m{.+\|};
|
return $line =~ m{.+\|};
|
||||||
}
|
}
|
||||||
|
|
||||||
sub split_csv ($$) { #{{{
|
sub split_csv ($$) {
|
||||||
my @text_lines = split(/\n/, shift);
|
my @text_lines = split(/\n/, shift);
|
||||||
my $delimiter = shift;
|
my $delimiter = shift;
|
||||||
|
|
||||||
|
@ -137,9 +151,9 @@ sub split_csv ($$) { #{{{
|
||||||
}
|
}
|
||||||
|
|
||||||
return @data;
|
return @data;
|
||||||
} #}}}
|
}
|
||||||
|
|
||||||
sub split_dsv ($$) { #{{{
|
sub split_dsv ($$) {
|
||||||
my @text_lines = split(/\n/, shift);
|
my @text_lines = split(/\n/, shift);
|
||||||
my $delimiter = shift;
|
my $delimiter = shift;
|
||||||
$delimiter="|" unless defined $delimiter;
|
$delimiter="|" unless defined $delimiter;
|
||||||
|
@ -150,9 +164,9 @@ sub split_dsv ($$) { #{{{
|
||||||
}
|
}
|
||||||
|
|
||||||
return @data;
|
return @data;
|
||||||
} #}}}
|
}
|
||||||
|
|
||||||
sub genrow ($@) { #{{{
|
sub genrow ($@) {
|
||||||
my %params=%{shift()};
|
my %params=%{shift()};
|
||||||
my $elt = shift;
|
my $elt = shift;
|
||||||
my @data = @_;
|
my @data = @_;
|
||||||
|
@ -190,6 +204,6 @@ sub genrow ($@) { #{{{
|
||||||
push @ret, "\t\t</tr>";
|
push @ret, "\t\t</tr>";
|
||||||
|
|
||||||
return @ret;
|
return @ret;
|
||||||
} #}}}
|
}
|
||||||
|
|
||||||
1
|
1
|
||||||
|
|
|
@ -4,26 +4,26 @@ package IkiWiki::Plugin::tag;
|
||||||
|
|
||||||
use warnings;
|
use warnings;
|
||||||
use strict;
|
use strict;
|
||||||
use IkiWiki 2.00;
|
use IkiWiki 3.00;
|
||||||
|
|
||||||
my %tags;
|
my %tags;
|
||||||
|
|
||||||
sub import { #{{{
|
sub import {
|
||||||
hook(type => "getopt", id => "tag", call => \&getopt);
|
hook(type => "getopt", id => "tag", call => \&getopt);
|
||||||
hook(type => "getsetup", id => "tag", call => \&getsetup);
|
hook(type => "getsetup", id => "tag", call => \&getsetup);
|
||||||
hook(type => "preprocess", id => "tag", call => \&preprocess_tag, scan => 1);
|
hook(type => "preprocess", id => "tag", call => \&preprocess_tag, scan => 1);
|
||||||
hook(type => "preprocess", id => "taglink", call => \&preprocess_taglink, scan => 1);
|
hook(type => "preprocess", id => "taglink", call => \&preprocess_taglink, scan => 1);
|
||||||
hook(type => "pagetemplate", id => "tag", call => \&pagetemplate);
|
hook(type => "pagetemplate", id => "tag", call => \&pagetemplate);
|
||||||
} # }}}
|
}
|
||||||
|
|
||||||
sub getopt () { #{{{
|
sub getopt () {
|
||||||
eval q{use Getopt::Long};
|
eval q{use Getopt::Long};
|
||||||
error($@) if $@;
|
error($@) if $@;
|
||||||
Getopt::Long::Configure('pass_through');
|
Getopt::Long::Configure('pass_through');
|
||||||
GetOptions("tagbase=s" => \$config{tagbase});
|
GetOptions("tagbase=s" => \$config{tagbase});
|
||||||
} #}}}
|
}
|
||||||
|
|
||||||
sub getsetup () { #{{{
|
sub getsetup () {
|
||||||
return
|
return
|
||||||
plugin => {
|
plugin => {
|
||||||
safe => 1,
|
safe => 1,
|
||||||
|
@ -36,35 +36,30 @@ sub getsetup () { #{{{
|
||||||
safe => 1,
|
safe => 1,
|
||||||
rebuild => 1,
|
rebuild => 1,
|
||||||
},
|
},
|
||||||
} #}}}
|
}
|
||||||
|
|
||||||
sub tagpage ($) { #{{{
|
sub tagpage ($) {
|
||||||
my $tag=shift;
|
my $tag=shift;
|
||||||
|
|
||||||
if ($tag !~ m{^\.?/} &&
|
if ($tag !~ m{^\.?/} &&
|
||||||
defined $config{tagbase}) {
|
defined $config{tagbase}) {
|
||||||
$tag=$config{tagbase}."/".$tag;
|
$tag="/".$config{tagbase}."/".$tag;
|
||||||
|
$tag=~y#/#/#s; # squash dups
|
||||||
}
|
}
|
||||||
|
|
||||||
return $tag;
|
return $tag;
|
||||||
} #}}}
|
}
|
||||||
|
|
||||||
sub taglink ($$$;@) { #{{{
|
sub taglink ($$$;@) {
|
||||||
my $page=shift;
|
my $page=shift;
|
||||||
my $destpage=shift;
|
my $destpage=shift;
|
||||||
my $tag=shift;
|
my $tag=shift;
|
||||||
my %opts=@_;
|
my %opts=@_;
|
||||||
|
|
||||||
my $link=tagpage($tag);
|
return htmllink($page, $destpage, tagpage($tag), %opts);
|
||||||
|
}
|
||||||
|
|
||||||
# Force tag creation links to create the tag under /tagbase,
|
sub preprocess_tag (@) {
|
||||||
# if there is a tagbase and this tag used it.
|
|
||||||
$link="/".$link if $tag ne $link;
|
|
||||||
|
|
||||||
return htmllink($page, $destpage, $link, %opts);
|
|
||||||
} #}}}
|
|
||||||
|
|
||||||
sub preprocess_tag (@) { #{{{
|
|
||||||
if (! @_) {
|
if (! @_) {
|
||||||
return "";
|
return "";
|
||||||
}
|
}
|
||||||
|
@ -82,9 +77,9 @@ sub preprocess_tag (@) { #{{{
|
||||||
}
|
}
|
||||||
|
|
||||||
return "";
|
return "";
|
||||||
} # }}}
|
}
|
||||||
|
|
||||||
sub preprocess_taglink (@) { #{{{
|
sub preprocess_taglink (@) {
|
||||||
if (! @_) {
|
if (! @_) {
|
||||||
return "";
|
return "";
|
||||||
}
|
}
|
||||||
|
@ -107,9 +102,9 @@ sub preprocess_taglink (@) { #{{{
|
||||||
grep {
|
grep {
|
||||||
$_ ne 'page' && $_ ne 'destpage' && $_ ne 'preview'
|
$_ ne 'page' && $_ ne 'destpage' && $_ ne 'preview'
|
||||||
} keys %params);
|
} keys %params);
|
||||||
} # }}}
|
}
|
||||||
|
|
||||||
sub pagetemplate (@) { #{{{
|
sub pagetemplate (@) {
|
||||||
my %params=@_;
|
my %params=@_;
|
||||||
my $page=$params{page};
|
my $page=$params{page};
|
||||||
my $destpage=$params{destpage};
|
my $destpage=$params{destpage};
|
||||||
|
@ -128,6 +123,14 @@ sub pagetemplate (@) { #{{{
|
||||||
sort keys %{$tags{$page}}]);
|
sort keys %{$tags{$page}}]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} # }}}
|
}
|
||||||
|
|
||||||
|
package IkiWiki::PageSpec;
|
||||||
|
|
||||||
|
sub match_tagged ($$;@) {
|
||||||
|
my $page = shift;
|
||||||
|
my $glob = shift;
|
||||||
|
return match_link($page, IkiWiki::Plugin::tag::tagpage($glob));
|
||||||
|
}
|
||||||
|
|
||||||
1
|
1
|
||||||
|
|
|
@ -4,24 +4,25 @@ package IkiWiki::Plugin::template;
|
||||||
|
|
||||||
use warnings;
|
use warnings;
|
||||||
use strict;
|
use strict;
|
||||||
use IkiWiki 2.00;
|
use IkiWiki 3.00;
|
||||||
use HTML::Template;
|
use HTML::Template;
|
||||||
use Encode;
|
use Encode;
|
||||||
|
|
||||||
sub import { #{{{
|
sub import {
|
||||||
hook(type => "getsetup", id => "template", call => \&getsetup);
|
hook(type => "getsetup", id => "template", call => \&getsetup);
|
||||||
hook(type => "preprocess", id => "template", call => \&preprocess);
|
hook(type => "preprocess", id => "template", call => \&preprocess,
|
||||||
} # }}}
|
scan => 1);
|
||||||
|
}
|
||||||
|
|
||||||
sub getsetup () { #{{{
|
sub getsetup () {
|
||||||
return
|
return
|
||||||
plugin => {
|
plugin => {
|
||||||
safe => 1,
|
safe => 1,
|
||||||
rebuild => undef,
|
rebuild => undef,
|
||||||
},
|
},
|
||||||
} #}}}
|
}
|
||||||
|
|
||||||
sub preprocess (@) { #{{{
|
sub preprocess (@) {
|
||||||
my %params=@_;
|
my %params=@_;
|
||||||
|
|
||||||
if (! exists $params{id}) {
|
if (! exists $params{id}) {
|
||||||
|
@ -68,9 +69,13 @@ sub preprocess (@) { #{{{
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
# This needs to run even in scan mode, in order to process
|
||||||
|
# links and other metadata includes via the template.
|
||||||
|
my $scan=! defined wantarray;
|
||||||
|
|
||||||
return IkiWiki::preprocess($params{page}, $params{destpage},
|
return IkiWiki::preprocess($params{page}, $params{destpage},
|
||||||
IkiWiki::filter($params{page}, $params{destpage},
|
IkiWiki::filter($params{page}, $params{destpage},
|
||||||
$template->output));
|
$template->output), $scan);
|
||||||
} # }}}
|
}
|
||||||
|
|
||||||
1
|
1
|
||||||
|
|
|
@ -3,22 +3,22 @@ package IkiWiki::Plugin::testpagespec;
|
||||||
|
|
||||||
use warnings;
|
use warnings;
|
||||||
use strict;
|
use strict;
|
||||||
use IkiWiki 2.00;
|
use IkiWiki 3.00;
|
||||||
|
|
||||||
sub import { #{{{
|
sub import {
|
||||||
hook(type => "getsetup", id => "testpagespec", call => \&getsetup);
|
hook(type => "getsetup", id => "testpagespec", call => \&getsetup);
|
||||||
hook(type => "preprocess", id => "testpagespec", call => \&preprocess);
|
hook(type => "preprocess", id => "testpagespec", call => \&preprocess);
|
||||||
} # }}}
|
}
|
||||||
|
|
||||||
sub getsetup () { #{{{
|
sub getsetup () {
|
||||||
return
|
return
|
||||||
plugin => {
|
plugin => {
|
||||||
safe => 1,
|
safe => 1,
|
||||||
rebuild => undef,
|
rebuild => undef,
|
||||||
},
|
},
|
||||||
} #}}}
|
}
|
||||||
|
|
||||||
sub preprocess (@) { #{{{
|
sub preprocess (@) {
|
||||||
my %params=@_;
|
my %params=@_;
|
||||||
|
|
||||||
foreach my $param (qw{match pagespec}) {
|
foreach my $param (qw{match pagespec}) {
|
||||||
|
@ -37,6 +37,6 @@ sub preprocess (@) { #{{{
|
||||||
else {
|
else {
|
||||||
return "no match: $ret";
|
return "no match: $ret";
|
||||||
}
|
}
|
||||||
} # }}}
|
}
|
||||||
|
|
||||||
1
|
1
|
||||||
|
|
|
@ -8,7 +8,7 @@ use strict;
|
||||||
use Digest::MD5 qw(md5_hex);
|
use Digest::MD5 qw(md5_hex);
|
||||||
use File::Temp qw(tempdir);
|
use File::Temp qw(tempdir);
|
||||||
use HTML::Entities;
|
use HTML::Entities;
|
||||||
use IkiWiki 2.00;
|
use IkiWiki 3.00;
|
||||||
|
|
||||||
my $default_prefix = <<EOPREFIX;
|
my $default_prefix = <<EOPREFIX;
|
||||||
\\documentclass{article}
|
\\documentclass{article}
|
||||||
|
@ -21,12 +21,12 @@ EOPREFIX
|
||||||
|
|
||||||
my $default_postfix = '\\end{document}';
|
my $default_postfix = '\\end{document}';
|
||||||
|
|
||||||
sub import { #{{{
|
sub import {
|
||||||
hook(type => "getsetup", id => "teximg", call => \&getsetup);
|
hook(type => "getsetup", id => "teximg", call => \&getsetup);
|
||||||
hook(type => "preprocess", id => "teximg", call => \&preprocess);
|
hook(type => "preprocess", id => "teximg", call => \&preprocess);
|
||||||
} #}}}
|
}
|
||||||
|
|
||||||
sub getsetup () { #{{{
|
sub getsetup () {
|
||||||
return
|
return
|
||||||
plugin => {
|
plugin => {
|
||||||
safe => 1,
|
safe => 1,
|
||||||
|
@ -52,9 +52,9 @@ sub getsetup () { #{{{
|
||||||
safe => 0, # Not sure how secure LaTeX is...
|
safe => 0, # Not sure how secure LaTeX is...
|
||||||
rebuild => 1,
|
rebuild => 1,
|
||||||
},
|
},
|
||||||
} #}}}
|
}
|
||||||
|
|
||||||
sub preprocess (@) { #{{{
|
sub preprocess (@) {
|
||||||
my %params = @_;
|
my %params = @_;
|
||||||
|
|
||||||
my $height = $params{height};
|
my $height = $params{height};
|
||||||
|
@ -76,9 +76,9 @@ sub preprocess (@) { #{{{
|
||||||
else {
|
else {
|
||||||
error gettext("code includes disallowed latex commands")
|
error gettext("code includes disallowed latex commands")
|
||||||
}
|
}
|
||||||
} #}}}
|
}
|
||||||
|
|
||||||
sub check_height ($) { #{{{
|
sub check_height ($) {
|
||||||
# Since latex doesn't support unlimited scaling this function
|
# Since latex doesn't support unlimited scaling this function
|
||||||
# returns the closest supported size.
|
# returns the closest supported size.
|
||||||
my $height =shift;
|
my $height =shift;
|
||||||
|
@ -95,9 +95,9 @@ sub check_height ($) { #{{{
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return $ret;
|
return $ret;
|
||||||
} #}}}
|
}
|
||||||
|
|
||||||
sub create ($$$) { #{{{
|
sub create ($$$) {
|
||||||
# This function calls the image generating function and returns
|
# This function calls the image generating function and returns
|
||||||
# the <img .. /> for the generated image.
|
# the <img .. /> for the generated image.
|
||||||
my $code = shift;
|
my $code = shift;
|
||||||
|
@ -127,9 +127,9 @@ sub create ($$$) { #{{{
|
||||||
else {
|
else {
|
||||||
error qq{<a href="$logurl">}.gettext("failed to generate image from code")."</a>";
|
error qq{<a href="$logurl">}.gettext("failed to generate image from code")."</a>";
|
||||||
}
|
}
|
||||||
} #}}}
|
}
|
||||||
|
|
||||||
sub gen_image ($$$$) { #{{{
|
sub gen_image ($$$$) {
|
||||||
# Actually creates the image.
|
# Actually creates the image.
|
||||||
my $code = shift;
|
my $code = shift;
|
||||||
my $height = shift;
|
my $height = shift;
|
||||||
|
@ -180,18 +180,18 @@ sub gen_image ($$$$) { #{{{
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
} #}}}
|
}
|
||||||
|
|
||||||
sub create_tmp_dir ($) { #{{{
|
sub create_tmp_dir ($) {
|
||||||
# Create a temp directory, it will be removed when ikiwiki exits.
|
# Create a temp directory, it will be removed when ikiwiki exits.
|
||||||
my $base = shift;
|
my $base = shift;
|
||||||
|
|
||||||
my $template = $base.".XXXXXXXXXX";
|
my $template = $base.".XXXXXXXXXX";
|
||||||
my $tmpdir = tempdir($template, TMPDIR => 1, CLEANUP => 1);
|
my $tmpdir = tempdir($template, TMPDIR => 1, CLEANUP => 1);
|
||||||
return $tmpdir;
|
return $tmpdir;
|
||||||
} #}}}
|
}
|
||||||
|
|
||||||
sub check ($) { #{{{
|
sub check ($) {
|
||||||
# Check if the code is ok
|
# Check if the code is ok
|
||||||
my $code = shift;
|
my $code = shift;
|
||||||
|
|
||||||
|
@ -219,6 +219,6 @@ sub check ($) { #{{{
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return 1;
|
return 1;
|
||||||
} #}}}
|
}
|
||||||
|
|
||||||
1
|
1
|
||||||
|
|
|
@ -6,29 +6,29 @@ package IkiWiki::Plugin::textile;
|
||||||
|
|
||||||
use warnings;
|
use warnings;
|
||||||
use strict;
|
use strict;
|
||||||
use IkiWiki 2.00;
|
use IkiWiki 3.00;
|
||||||
use Encode;
|
use Encode;
|
||||||
|
|
||||||
sub import { #{{{
|
sub import {
|
||||||
hook(type => "getsetup", id => "textile", call => \&getsetup);
|
hook(type => "getsetup", id => "textile", call => \&getsetup);
|
||||||
hook(type => "htmlize", id => "txtl", call => \&htmlize);
|
hook(type => "htmlize", id => "txtl", call => \&htmlize);
|
||||||
} # }}}
|
}
|
||||||
|
|
||||||
sub getsetup () { #{{{
|
sub getsetup () {
|
||||||
return
|
return
|
||||||
plugin => {
|
plugin => {
|
||||||
safe => 1,
|
safe => 1,
|
||||||
rebuild => 1, # format plugin
|
rebuild => 1, # format plugin
|
||||||
},
|
},
|
||||||
} #}}}
|
}
|
||||||
|
|
||||||
sub htmlize (@) { #{{{
|
sub htmlize (@) {
|
||||||
my %params=@_;
|
my %params=@_;
|
||||||
my $content = decode_utf8(encode_utf8($params{content}));
|
my $content = decode_utf8(encode_utf8($params{content}));
|
||||||
|
|
||||||
eval q{use Text::Textile};
|
eval q{use Text::Textile};
|
||||||
return $content if $@;
|
return $content if $@;
|
||||||
return Text::Textile::textile($content);
|
return Text::Textile::textile($content);
|
||||||
} # }}}
|
}
|
||||||
|
|
||||||
1
|
1
|
||||||
|
|
|
@ -5,7 +5,7 @@ use warnings;
|
||||||
use strict;
|
use strict;
|
||||||
use IkiWiki;
|
use IkiWiki;
|
||||||
|
|
||||||
sub import { #{{{
|
sub import {
|
||||||
hook(type => "checkconfig", id => "tla", call => \&checkconfig);
|
hook(type => "checkconfig", id => "tla", call => \&checkconfig);
|
||||||
hook(type => "getsetup", id => "tla", call => \&getsetup);
|
hook(type => "getsetup", id => "tla", call => \&getsetup);
|
||||||
hook(type => "rcs", id => "rcs_update", call => \&rcs_update);
|
hook(type => "rcs", id => "rcs_update", call => \&rcs_update);
|
||||||
|
@ -18,18 +18,18 @@ sub import { #{{{
|
||||||
hook(type => "rcs", id => "rcs_recentchanges", call => \&rcs_recentchanges);
|
hook(type => "rcs", id => "rcs_recentchanges", call => \&rcs_recentchanges);
|
||||||
hook(type => "rcs", id => "rcs_diff", call => \&rcs_diff);
|
hook(type => "rcs", id => "rcs_diff", call => \&rcs_diff);
|
||||||
hook(type => "rcs", id => "rcs_getctime", call => \&rcs_getctime);
|
hook(type => "rcs", id => "rcs_getctime", call => \&rcs_getctime);
|
||||||
} #}}}
|
}
|
||||||
|
|
||||||
sub checkconfig () { #{{{
|
sub checkconfig () {
|
||||||
if (defined $config{tla_wrapper} && length $config{tla_wrapper}) {
|
if (defined $config{tla_wrapper} && length $config{tla_wrapper}) {
|
||||||
push @{$config{wrappers}}, {
|
push @{$config{wrappers}}, {
|
||||||
wrapper => $config{tla_wrapper},
|
wrapper => $config{tla_wrapper},
|
||||||
wrappermode => (defined $config{tla_wrappermode} ? $config{tla_wrappermode} : "06755"),
|
wrappermode => (defined $config{tla_wrappermode} ? $config{tla_wrappermode} : "06755"),
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
} #}}}
|
}
|
||||||
|
|
||||||
sub getsetup () { #{{{
|
sub getsetup () {
|
||||||
return
|
return
|
||||||
plugin => {
|
plugin => {
|
||||||
safe => 0, # rcs plugin
|
safe => 0, # rcs plugin
|
||||||
|
@ -63,9 +63,9 @@ sub getsetup () { #{{{
|
||||||
safe => 1,
|
safe => 1,
|
||||||
rebuild => 1,
|
rebuild => 1,
|
||||||
},
|
},
|
||||||
} #}}}
|
}
|
||||||
|
|
||||||
sub quiet_system (@) { #{{{
|
sub quiet_system (@) {
|
||||||
# See Debian bug #385939.
|
# See Debian bug #385939.
|
||||||
open (SAVEOUT, ">&STDOUT");
|
open (SAVEOUT, ">&STDOUT");
|
||||||
close STDOUT;
|
close STDOUT;
|
||||||
|
@ -75,17 +75,17 @@ sub quiet_system (@) { #{{{
|
||||||
open (STDOUT, ">&SAVEOUT");
|
open (STDOUT, ">&SAVEOUT");
|
||||||
close SAVEOUT;
|
close SAVEOUT;
|
||||||
return $ret;
|
return $ret;
|
||||||
} #}}}
|
}
|
||||||
|
|
||||||
sub rcs_update () { #{{{
|
sub rcs_update () {
|
||||||
if (-d "$config{srcdir}/{arch}") {
|
if (-d "$config{srcdir}/{arch}") {
|
||||||
if (quiet_system("tla", "replay", "-d", $config{srcdir}) != 0) {
|
if (quiet_system("tla", "replay", "-d", $config{srcdir}) != 0) {
|
||||||
warn("tla replay failed\n");
|
warn("tla replay failed\n");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} #}}}
|
}
|
||||||
|
|
||||||
sub rcs_prepedit ($) { #{{{
|
sub rcs_prepedit ($) {
|
||||||
my $file=shift;
|
my $file=shift;
|
||||||
|
|
||||||
if (-d "$config{srcdir}/{arch}") {
|
if (-d "$config{srcdir}/{arch}") {
|
||||||
|
@ -94,9 +94,9 @@ sub rcs_prepedit ($) { #{{{
|
||||||
my $rev=`tla tree-id $config{srcdir}`;
|
my $rev=`tla tree-id $config{srcdir}`;
|
||||||
return defined $rev ? $rev : "";
|
return defined $rev ? $rev : "";
|
||||||
}
|
}
|
||||||
} #}}}
|
}
|
||||||
|
|
||||||
sub rcs_commit ($$$;$$) { #{{{
|
sub rcs_commit ($$$;$$) {
|
||||||
my $file=shift;
|
my $file=shift;
|
||||||
my $message=shift;
|
my $message=shift;
|
||||||
my $rcstoken=shift;
|
my $rcstoken=shift;
|
||||||
|
@ -135,7 +135,7 @@ sub rcs_commit ($$$;$$) { #{{{
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return undef # success
|
return undef # success
|
||||||
} #}}}
|
}
|
||||||
|
|
||||||
sub rcs_commit_staged ($$$) {
|
sub rcs_commit_staged ($$$) {
|
||||||
# Commits all staged changes. Changes can be staged using rcs_add,
|
# Commits all staged changes. Changes can be staged using rcs_add,
|
||||||
|
@ -145,7 +145,7 @@ sub rcs_commit_staged ($$$) {
|
||||||
error("rcs_commit_staged not implemented for tla"); # TODO
|
error("rcs_commit_staged not implemented for tla"); # TODO
|
||||||
}
|
}
|
||||||
|
|
||||||
sub rcs_add ($) { #{{{
|
sub rcs_add ($) {
|
||||||
my $file=shift;
|
my $file=shift;
|
||||||
|
|
||||||
if (-d "$config{srcdir}/{arch}") {
|
if (-d "$config{srcdir}/{arch}") {
|
||||||
|
@ -153,19 +153,19 @@ sub rcs_add ($) { #{{{
|
||||||
warn("tla add failed\n");
|
warn("tla add failed\n");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} #}}}
|
}
|
||||||
|
|
||||||
sub rcs_remove ($) { # {{{
|
sub rcs_remove ($) {
|
||||||
my $file = shift;
|
my $file = shift;
|
||||||
|
|
||||||
error("rcs_remove not implemented for tla"); # TODO
|
error("rcs_remove not implemented for tla"); # TODO
|
||||||
} #}}}
|
}
|
||||||
|
|
||||||
sub rcs_rename ($$) { # {{{a
|
sub rcs_rename ($$) { # {{{a
|
||||||
my ($src, $dest) = @_;
|
my ($src, $dest) = @_;
|
||||||
|
|
||||||
error("rcs_rename not implemented for tla"); # TODO
|
error("rcs_rename not implemented for tla"); # TODO
|
||||||
} #}}}
|
}
|
||||||
|
|
||||||
sub rcs_recentchanges ($) {
|
sub rcs_recentchanges ($) {
|
||||||
my $num=shift;
|
my $num=shift;
|
||||||
|
@ -239,7 +239,7 @@ sub rcs_recentchanges ($) {
|
||||||
return @ret;
|
return @ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
sub rcs_diff ($) { #{{{
|
sub rcs_diff ($) {
|
||||||
my $rev=shift;
|
my $rev=shift;
|
||||||
my $logs = `tla logs -d $config{srcdir}`;
|
my $logs = `tla logs -d $config{srcdir}`;
|
||||||
my @changesets = reverse split(/\n/, $logs);
|
my @changesets = reverse split(/\n/, $logs);
|
||||||
|
@ -251,9 +251,9 @@ sub rcs_diff ($) { #{{{
|
||||||
|
|
||||||
my $revminusone = $changesets[$i+1];
|
my $revminusone = $changesets[$i+1];
|
||||||
return `tla diff -d $config{srcdir} $revminusone`;
|
return `tla diff -d $config{srcdir} $revminusone`;
|
||||||
} #}}}
|
}
|
||||||
|
|
||||||
sub rcs_getctime ($) { #{{{
|
sub rcs_getctime ($) {
|
||||||
my $file=shift;
|
my $file=shift;
|
||||||
eval q{use Date::Parse};
|
eval q{use Date::Parse};
|
||||||
error($@) if $@;
|
error($@) if $@;
|
||||||
|
@ -281,6 +281,6 @@ sub rcs_getctime ($) { #{{{
|
||||||
my $date=str2time($sdate, 'UTC');
|
my $date=str2time($sdate, 'UTC');
|
||||||
debug("found ctime ".localtime($date)." for $file");
|
debug("found ctime ".localtime($date)." for $file");
|
||||||
return $date;
|
return $date;
|
||||||
} #}}}
|
}
|
||||||
|
|
||||||
1
|
1
|
||||||
|
|
|
@ -4,26 +4,26 @@ package IkiWiki::Plugin::toc;
|
||||||
|
|
||||||
use warnings;
|
use warnings;
|
||||||
use strict;
|
use strict;
|
||||||
use IkiWiki 2.00;
|
use IkiWiki 3.00;
|
||||||
use HTML::Parser;
|
use HTML::Parser;
|
||||||
|
|
||||||
sub import { #{{{
|
sub import {
|
||||||
hook(type => "getsetup", id => "toc", call => \&getsetup);
|
hook(type => "getsetup", id => "toc", call => \&getsetup);
|
||||||
hook(type => "preprocess", id => "toc", call => \&preprocess);
|
hook(type => "preprocess", id => "toc", call => \&preprocess);
|
||||||
hook(type => "format", id => "toc", call => \&format);
|
hook(type => "format", id => "toc", call => \&format);
|
||||||
} # }}}
|
}
|
||||||
|
|
||||||
sub getsetup () { #{{{
|
sub getsetup () {
|
||||||
return
|
return
|
||||||
plugin => {
|
plugin => {
|
||||||
safe => 1,
|
safe => 1,
|
||||||
rebuild => undef,
|
rebuild => undef,
|
||||||
},
|
},
|
||||||
} #}}}
|
}
|
||||||
|
|
||||||
my %tocpages;
|
my %tocpages;
|
||||||
|
|
||||||
sub preprocess (@) { #{{{
|
sub preprocess (@) {
|
||||||
my %params=@_;
|
my %params=@_;
|
||||||
|
|
||||||
if ($params{page} eq $params{destpage}) {
|
if ($params{page} eq $params{destpage}) {
|
||||||
|
@ -40,9 +40,9 @@ sub preprocess (@) { #{{{
|
||||||
# right.
|
# right.
|
||||||
return "";
|
return "";
|
||||||
}
|
}
|
||||||
} # }}}
|
}
|
||||||
|
|
||||||
sub format (@) { #{{{
|
sub format (@) {
|
||||||
my %params=@_;
|
my %params=@_;
|
||||||
my $content=$params{content};
|
my $content=$params{content};
|
||||||
|
|
||||||
|
|
|
@ -3,80 +3,27 @@ package IkiWiki::Plugin::toggle;
|
||||||
|
|
||||||
use warnings;
|
use warnings;
|
||||||
use strict;
|
use strict;
|
||||||
use IkiWiki 2.00;
|
use IkiWiki 3.00;
|
||||||
|
|
||||||
# Here's the javascript that makes this possible. A key feature is the use
|
sub import {
|
||||||
# of css to hide toggleables, to avoid any flashing on page load. The css
|
add_underlay("javascript");
|
||||||
# is only emitted after the javascript tests that it's going to be able to
|
|
||||||
# show the toggleables.
|
|
||||||
our $javascript=<<'EOF';
|
|
||||||
<script type="text/javascript">
|
|
||||||
<!--
|
|
||||||
if (document.getElementById && document.getElementsByTagName && document.createTextNode) {
|
|
||||||
document.write('<style type="text/css">div.toggleable { display: none; }</style>');
|
|
||||||
window.onload = inittoggle;
|
|
||||||
}
|
|
||||||
|
|
||||||
function inittoggle() {
|
|
||||||
var as = getElementsByClass('toggle');
|
|
||||||
for (var i = 0; i < as.length; i++) {
|
|
||||||
var id = as[i].href.match(/#(\w.+)/)[1];
|
|
||||||
if (document.getElementById(id).className == "toggleable")
|
|
||||||
document.getElementById(id).style.display="none";
|
|
||||||
as[i].onclick = function() {
|
|
||||||
toggle(this);
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
function toggle(s) {
|
|
||||||
var id = s.href.match(/#(\w.+)/)[1];
|
|
||||||
style = document.getElementById(id).style;
|
|
||||||
if (style.display == "none")
|
|
||||||
style.display = "block";
|
|
||||||
else
|
|
||||||
style.display = "none";
|
|
||||||
}
|
|
||||||
|
|
||||||
function getElementsByClass(cls, node, tag) {
|
|
||||||
if (document.getElementsByClass)
|
|
||||||
return document.getElementsByClass(cls, node, tag);
|
|
||||||
if (! node) node = document;
|
|
||||||
if (! tag) tag = '*';
|
|
||||||
var ret = new Array();
|
|
||||||
var pattern = new RegExp("(^|\\s)"+cls+"(\\s|$)");
|
|
||||||
var els = node.getElementsByTagName(tag);
|
|
||||||
for (i = 0; i < els.length; i++) {
|
|
||||||
if ( pattern.test(els[i].className) ) {
|
|
||||||
ret.push(els[i]);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
//-->
|
|
||||||
</script>
|
|
||||||
EOF
|
|
||||||
|
|
||||||
sub import { #{{{
|
|
||||||
hook(type => "getsetup", id => "toggle", call => \&getsetup);
|
hook(type => "getsetup", id => "toggle", call => \&getsetup);
|
||||||
hook(type => "preprocess", id => "toggle",
|
hook(type => "preprocess", id => "toggle",
|
||||||
call => \&preprocess_toggle);
|
call => \&preprocess_toggle);
|
||||||
hook(type => "preprocess", id => "toggleable",
|
hook(type => "preprocess", id => "toggleable",
|
||||||
call => \&preprocess_toggleable);
|
call => \&preprocess_toggleable);
|
||||||
hook(type => "format", id => "toggle", call => \&format);
|
hook(type => "format", id => "toggle", call => \&format);
|
||||||
} # }}}
|
}
|
||||||
|
|
||||||
sub getsetup () { #{{{
|
sub getsetup () {
|
||||||
return
|
return
|
||||||
plugin => {
|
plugin => {
|
||||||
safe => 1,
|
safe => 1,
|
||||||
rebuild => undef,
|
rebuild => undef,
|
||||||
},
|
},
|
||||||
} #}}}
|
}
|
||||||
|
|
||||||
sub genid ($$) { #{{{
|
sub genid ($$) {
|
||||||
my $page=shift;
|
my $page=shift;
|
||||||
my $id=shift;
|
my $id=shift;
|
||||||
|
|
||||||
|
@ -88,16 +35,16 @@ sub genid ($$) { #{{{
|
||||||
$id="id$id";
|
$id="id$id";
|
||||||
}
|
}
|
||||||
return $id;
|
return $id;
|
||||||
} #}}}
|
}
|
||||||
|
|
||||||
sub preprocess_toggle (@) { #{{{
|
sub preprocess_toggle (@) {
|
||||||
my %params=(id => "default", text => "more", @_);
|
my %params=(id => "default", text => "more", @_);
|
||||||
|
|
||||||
my $id=genid($params{page}, $params{id});
|
my $id=genid($params{page}, $params{id});
|
||||||
return "<a class=\"toggle\" href=\"#$id\">$params{text}</a>";
|
return "<a class=\"toggle\" href=\"#$id\">$params{text}</a>";
|
||||||
} # }}}
|
}
|
||||||
|
|
||||||
sub preprocess_toggleable (@) { #{{{
|
sub preprocess_toggleable (@) {
|
||||||
my %params=(id => "default", text => "", open => "no", @_);
|
my %params=(id => "default", text => "", open => "no", @_);
|
||||||
|
|
||||||
# Preprocess the text to expand any preprocessor directives
|
# Preprocess the text to expand any preprocessor directives
|
||||||
|
@ -114,19 +61,29 @@ sub preprocess_toggleable (@) { #{{{
|
||||||
my ($indent)=$params{text}=~/( +)$/;
|
my ($indent)=$params{text}=~/( +)$/;
|
||||||
$indent="" unless defined $indent;
|
$indent="" unless defined $indent;
|
||||||
return "<div class=\"$class\" id=\"$id\"></div>\n\n$params{text}\n$indent<div class=\"toggleableend\"></div>";
|
return "<div class=\"$class\" id=\"$id\"></div>\n\n$params{text}\n$indent<div class=\"toggleableend\"></div>";
|
||||||
} # }}}
|
}
|
||||||
|
|
||||||
sub format (@) { #{{{
|
sub format (@) {
|
||||||
my %params=@_;
|
my %params=@_;
|
||||||
|
|
||||||
if ($params{content}=~s!(<div class="toggleable(?:-open)?" id="[^"]+">\s*)</div>!$1!g) {
|
if ($params{content}=~s!(<div class="toggleable(?:-open)?" id="[^"]+">\s*)</div>!$1!g) {
|
||||||
$params{content}=~s/<div class="toggleableend">//g;
|
$params{content}=~s/<div class="toggleableend">//g;
|
||||||
if (! ($params{content}=~s!^<body>!<body>$javascript!m)) {
|
if (! ($params{content}=~s!^(<body>)!$1.include_javascript($params{page})!em)) {
|
||||||
# no </body> tag, probably in preview mode
|
# no </body> tag, probably in preview mode
|
||||||
$params{content}=$javascript.$params{content};
|
$params{content}=include_javascript($params{page}, 1).$params{content};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return $params{content};
|
return $params{content};
|
||||||
} # }}}
|
}
|
||||||
|
|
||||||
|
sub include_javascript ($;$) {
|
||||||
|
my $page=shift;
|
||||||
|
my $absolute=shift;
|
||||||
|
|
||||||
|
return '<script src="'.urlto("ikiwiki.js", $page, $absolute).
|
||||||
|
'" type="text/javascript" charset="utf-8"></script>'."\n".
|
||||||
|
'<script src="'.urlto("toggle.js", $page, $absolute).
|
||||||
|
'" type="text/javascript" charset="utf-8"></script>';
|
||||||
|
}
|
||||||
|
|
||||||
1
|
1
|
||||||
|
|
|
@ -8,7 +8,7 @@ package IkiWiki::Plugin::txt;
|
||||||
|
|
||||||
use warnings;
|
use warnings;
|
||||||
use strict;
|
use strict;
|
||||||
use IkiWiki 2.00;
|
use IkiWiki 3.00;
|
||||||
use HTML::Entities;
|
use HTML::Entities;
|
||||||
|
|
||||||
my $findurl=0;
|
my $findurl=0;
|
||||||
|
@ -24,13 +24,13 @@ sub import {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
sub getsetup () { #{{{
|
sub getsetup () {
|
||||||
return
|
return
|
||||||
plugin => {
|
plugin => {
|
||||||
safe => 1,
|
safe => 1,
|
||||||
rebuild => 1, # format plugin
|
rebuild => 1, # format plugin
|
||||||
},
|
},
|
||||||
} #}}}
|
}
|
||||||
|
|
||||||
# We use filter to convert raw text to HTML
|
# We use filter to convert raw text to HTML
|
||||||
# (htmlize is called after other plugins insert HTML)
|
# (htmlize is called after other plugins insert HTML)
|
||||||
|
@ -39,7 +39,7 @@ sub filter (@) {
|
||||||
my $content = $params{content};
|
my $content = $params{content};
|
||||||
|
|
||||||
if (defined $pagesources{$params{page}} && $pagesources{$params{page}} =~ /\.txt$/) {
|
if (defined $pagesources{$params{page}} && $pagesources{$params{page}} =~ /\.txt$/) {
|
||||||
encode_entities($content);
|
encode_entities($content, "<>&");
|
||||||
if ($findurl) {
|
if ($findurl) {
|
||||||
my $finder = URI::Find->new(sub {
|
my $finder = URI::Find->new(sub {
|
||||||
my ($uri, $orig_uri) = @_;
|
my ($uri, $orig_uri) = @_;
|
||||||
|
|
|
@ -4,22 +4,22 @@ package IkiWiki::Plugin::typography;
|
||||||
|
|
||||||
use warnings;
|
use warnings;
|
||||||
use strict;
|
use strict;
|
||||||
use IkiWiki 2.00;
|
use IkiWiki 3.00;
|
||||||
|
|
||||||
sub import { #{{{
|
sub import {
|
||||||
hook(type => "getopt", id => "typography", call => \&getopt);
|
hook(type => "getopt", id => "typography", call => \&getopt);
|
||||||
hook(type => "getsetup", id => "typography", call => \&getsetup);
|
hook(type => "getsetup", id => "typography", call => \&getsetup);
|
||||||
IkiWiki::hook(type => "sanitize", id => "typography", call => \&sanitize);
|
IkiWiki::hook(type => "sanitize", id => "typography", call => \&sanitize);
|
||||||
} # }}}
|
}
|
||||||
|
|
||||||
sub getopt () { #{{{
|
sub getopt () {
|
||||||
eval q{use Getopt::Long};
|
eval q{use Getopt::Long};
|
||||||
error($@) if $@;
|
error($@) if $@;
|
||||||
Getopt::Long::Configure('pass_through');
|
Getopt::Long::Configure('pass_through');
|
||||||
GetOptions("typographyattributes=s" => \$config{typographyattributes});
|
GetOptions("typographyattributes=s" => \$config{typographyattributes});
|
||||||
} #}}}
|
}
|
||||||
|
|
||||||
sub getsetup () { #{{{
|
sub getsetup () {
|
||||||
eval q{use Text::Typography};
|
eval q{use Text::Typography};
|
||||||
error($@) if $@;
|
error($@) if $@;
|
||||||
|
|
||||||
|
@ -36,9 +36,9 @@ sub getsetup () { #{{{
|
||||||
safe => 1,
|
safe => 1,
|
||||||
rebuild => 1,
|
rebuild => 1,
|
||||||
},
|
},
|
||||||
} #}}}
|
}
|
||||||
|
|
||||||
sub sanitize (@) { #{{{
|
sub sanitize (@) {
|
||||||
my %params=@_;
|
my %params=@_;
|
||||||
|
|
||||||
eval q{use Text::Typography};
|
eval q{use Text::Typography};
|
||||||
|
@ -46,6 +46,6 @@ sub sanitize (@) { #{{{
|
||||||
|
|
||||||
my $attributes=defined $config{typographyattributes} ? $config{typographyattributes} : '3';
|
my $attributes=defined $config{typographyattributes} ? $config{typographyattributes} : '3';
|
||||||
return Text::Typography::typography($params{content}, $attributes);
|
return Text::Typography::typography($params{content}, $attributes);
|
||||||
} # }}}
|
}
|
||||||
|
|
||||||
1
|
1
|
||||||
|
|
|
@ -0,0 +1,40 @@
|
||||||
|
#!/usr/bin/perl
|
||||||
|
package IkiWiki::Plugin::underlay;
|
||||||
|
# Copyright © 2008 Simon McVittie <http://smcv.pseudorandom.co.uk/>
|
||||||
|
# Licensed under the GNU GPL, version 2, or any later version published by the
|
||||||
|
# Free Software Foundation
|
||||||
|
|
||||||
|
use warnings;
|
||||||
|
use strict;
|
||||||
|
use IkiWiki 3.00;
|
||||||
|
|
||||||
|
sub import {
|
||||||
|
hook(type => "getsetup", id => "underlay", call => \&getsetup);
|
||||||
|
hook(type => "checkconfig", id => "underlay", call => \&checkconfig);
|
||||||
|
}
|
||||||
|
|
||||||
|
sub getsetup () {
|
||||||
|
return
|
||||||
|
plugin => {
|
||||||
|
safe => 0,
|
||||||
|
rebuild => undef,
|
||||||
|
},
|
||||||
|
add_underlays => {
|
||||||
|
type => "string",
|
||||||
|
default => [],
|
||||||
|
description => "extra underlay directories to add",
|
||||||
|
advanced => 1,
|
||||||
|
safe => 0,
|
||||||
|
rebuild => 1,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
sub checkconfig () {
|
||||||
|
return unless exists $config{add_underlays};
|
||||||
|
|
||||||
|
foreach my $dir (@{$config{add_underlays}}) {
|
||||||
|
add_underlay($dir);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
1;
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue