Compare commits

..

2 Commits

Author SHA1 Message Date
Alex Schroeder
3626593fad lock-expiration.t: test fake time 2015-07-22 09:51:54 +02:00
Alex Schroeder
4a1e1a5529 Fake time to speed up tests
Fake time requires changes to wiki.pl. We created a test-wiki.pl with a
preamble that changes how the time and sleep builtins work. This is used
in lock-expiration.t as a proof of concept.
2015-07-22 09:33:09 +02:00
482 changed files with 12523 additions and 18722 deletions

1
.gitattributes vendored
View File

@@ -1 +0,0 @@
*.pl linguist-language=Perl

5
.gitignore vendored
View File

@@ -1,11 +1,8 @@
*~
/build/
\#*\#
/test-data*
/test-data
/Mac/pkg/
*.dmg
*.pkg
.DS_Store
wiki.log
.prove
TAGS

View File

@@ -3,7 +3,7 @@
# subdirectory.
VERSION_NO=$(shell git describe --tags)
TRANSLATIONS=$(wildcard modules/translations/[a-z]*-utf8.pl$)
TRANSLATIONS=$(wildcard modules/translations/[a-z]*.pl$)
MODULES=$(wildcard modules/*.pl)
BUILD=build/wiki.pl $(foreach file, $(notdir $(MODULES)) $(notdir $(TRANSLATIONS)), build/$(file))
@@ -19,13 +19,9 @@ build:
clean:
rm -rf build
prove t/setup.pl
release:
perl stuff/release ~/oddmuse.org/releases 2.3.3
build/wiki.pl: wiki.pl
perl -lne "s/(\\\$$q->a\(\{-href=>'https:\/\/www.oddmuse.org\/'\}, 'Oddmuse'\))/\\\$$q->a({-href=>'https:\/\/git.savannah.gnu.org\/cgit\/oddmuse.git\/tag\/?id=$(VERSION_NO)'}, 'wiki.pl') . ' ($(VERSION_NO)), see ' . \$$1/; print" < $< > $@
perl -lne "s/(\\\$$q->a\({-href=>'http:\/\/www.oddmuse.org\/'}, 'Oddmuse'\))/\\\$$q->a({-href=>'http:\/\/git.savannah.gnu.org\/cgit\/oddmuse.git\/tag\/?id=$(VERSION_NO)'}, 'wiki.pl') . ' ($(VERSION_NO)), see ' . \$$1/; print" < $< > $@
build/%-utf8.pl: modules/translations/%-utf8.pl
perl -lne "s/(AddModuleDescription\('[^']+', '[^']+')\)/\$$1, 'translations\/', '$(VERSION_NO)')/; print" < $< > $@
@@ -36,27 +32,17 @@ build/national-%.pl: modules/translations/national-%.pl
build/month-names-%.pl: modules/translations/month-names-%.pl
perl -lne "s/(AddModuleDescription\('[^']+', '[^']+')\)/\$$1, 'translations\/', '$(VERSION_NO)')/; print" < $< > $@
# from: https://git.savannah.gnu.org/cgit/oddmuse.git/tree/modules/namespaces.pl
# to: https://git.savannah.gnu.org/cgit/oddmuse.git/tree/modules/namespaces.pl?id=2.1-11-gd4f1e27
# from: http://git.savannah.gnu.org/cgit/oddmuse.git/tree/modules/namespaces.pl
# to: http://git.savannah.gnu.org/cgit/oddmuse.git/tree/modules/namespaces.pl?id=2.1-11-gd4f1e27
build/%.pl: modules/%.pl
perl -lne "s/(AddModuleDescription\('[^']+', '[^']+')\)/\$$1, undef, '$(VERSION_NO)')/; print" < $< > $@
modules/translations/new-utf8.pl: wiki.pl $(MODULES)
cp $@ $@-old
perl stuff/oddtrans -l $@-old wiki.pl $(MODULES) > $@
rm -f $@-old
translations: $(TRANSLATIONS)
for f in $^; do \
echo updating $$f...; \
perl stuff/oddtrans -l $$f wiki.pl $(MODULES) > $$f-new && mv $$f-new $$f; \
perl oddtrans -l $$f wiki.pl $(MODULES) > $$f-new && mv $$f-new $$f; \
done
# Running four jobs in parallel, but clean up data directories without
# race conditions!
jobs ?= 4
test:
prove t/setup.pl
prove --jobs=$(jobs) --state=slow,save t
prove t

View File

@@ -1,5 +1,5 @@
This is the README file distributed together with the
[[https://oddmuse.org/|Oddmuse]] script.
[[http://oddmuse.org/|Oddmuse]] script.
== Installing Oddmuse on a Debian System running Apache
@@ -23,21 +23,12 @@ usermod -a -G sudo alex
Now you can login as {{{alex}}} and do everything else using {{{sudo}}}.
You need to copy wiki.pl into your cgi-bin directory, and you need to
make the script executable. You might also have to change its owner to
an appropriate user on your system.
make the script executable.
{{{
sudo wget -O /usr/lib/cgi-bin/wiki.pl \
http://git.savannah.gnu.org/cgit/oddmuse.git/plain/wiki.pl
sudo chmod +x /usr/lib/cgi-bin/wiki.pl
sudo chown www-data.www-data /usr/lib/cgi-bin/wiki.pl
}}}
If you're on SUSE, the user might not be {{{www-data}}} but
{{{wwwrun}}} without appropriate group:
{{{
sudo chown wwwrun.root /usr/lib/cgi-bin/wiki.pl
}}}
You should be able to test it right now! Visit
@@ -91,10 +82,10 @@ putting their names in {{{[[double square brackets]]}}}.
Enjoy your wiki experience.
Visit https://www.oddmuse.org/ to learn more about the translation
Visit http://www.oddmuse.org/ to learn more about the translation
files and modules that are part of this package.
== Checking the Apache Setup
== Apache
If you think this information doesn't work for you, here are some things
to check.
@@ -128,7 +119,7 @@ The default site is configured in
sudo a2ensite default
}}}
This file also lists the directories we've used in our instructions
This file also lists the directories we've used in out instructions
above.
{{{
@@ -145,33 +136,7 @@ simply restart it all:
sudo service apache2 graceful
}}}
== Using just Perl
You can use Mojolicious as your web server. There is a simple
##server.pl## which you can use. Here's how you might start it:
{{{
mkdir ~/oddmuse
WikiDataDir=$HOME/oddmuse perl server.pl daemon
}}}
This makes the server available on {{{http://localhost:3000/wiki}}}.
If it works for you, feel free to upgrade to Hypnotoad.
{{{
WikiDataDir=$HOME/oddmuse hypnotoad server.pl
}}}
Note: Hypnotoad uses a different default port. The above makes the
server available on {{{http://localhost:8080/wiki}}}. Hypnotoad will
keep forking new processes. To stop it, use the {{{-s}}} flag.
{{{
hypnotoad -s server.pl
}}}
== License
----------------------------------------------------------------------
Permission is granted to copy, distribute and/or modify this document
under the terms of the GNU Free Documentation License, Version 1.1 or
@@ -188,7 +153,5 @@ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
General Public License for more details.
Both the GNU Free Documentation License, and the GNU General Public
License are distributed together with this script. See the files
[[https://github.com/kensanata/oddmuse/blob/master/FDL|FDL]] and
[[https://github.com/kensanata/oddmuse/blob/master/GPL|GPL]],
respectively.
License are distributed together with this script. See the files FDL
and GPL, respectively.

View File

@@ -1,4 +1,4 @@
The files in this directory are used to run https://campaignwiki.org/
The files in this directory are used to run http://campaignwiki.org/
add-link.pl
===========
@@ -8,7 +8,7 @@ bookmark site: A few pages make up a big unordered list of links in
wiki format. add-link is a tool to help users contribute new links to
the list.
https://campaignwiki.org/wiki/LinksToWisdom/HomePage
http://campaignwiki.org/wiki/LinksToWisdom/HomePage
copy.pl
=======
@@ -17,7 +17,7 @@ This is used to copy the text from a web page to a wiki page. The idea
was to keep archive copies of cool pages somewhere. The Blog Archive
never got used, though.
https://campaignwiki.org/wiki/BlogArchive/HomePage
http://campaignwiki.org/wiki/BlogArchive/HomePage
monster-tag.pl
==============
@@ -25,7 +25,7 @@ monster-tag.pl
This is used to quickly tag many pages in the Monsters wiki. The
Monsters wiki hasn't been used in a long time, though.
https://campaignwiki.org/wiki/Monsters/HomePage
http://campaignwiki.org/wiki/Monsters/HomePage
submit.pl
=========
@@ -34,4 +34,4 @@ This used to be used to add sites to the Old School RPG Planet. The
aggregator was configured via a wiki page on the Planet wiki. It's now
abandoned.
https://campaignwiki.org/wiki/Planet/HomePage
http://campaignwiki.org/wiki/Planet/HomePage

View File

@@ -292,7 +292,6 @@ sub main {
Init(); # read config file (no modules!)
$ScriptName = $site; # undo setting in the config file
$FullUrl = $site; #
InitPageVariables(); # call again: $ScriptName was wrong
binmode(STDOUT,':utf8');
$q->charset('utf8');
if ($q->path_info eq '/source') {

View File

@@ -1,14 +0,0 @@
#!/bin/bash
if test -z "$2" -o ! -z "$3"; then
echo "Usage: delete.sh USERNAME WIKI"
exit 1
fi
username=$1
wiki=$2
for p in $(curl --silent "https://campaignwiki.org/wiki/$wiki?action=index;raw=1"); do
echo "Deleting: $p"
curl -F frodo=1 -F "title=$p" -F text=DeletedPage -F summary=Deleted -F username="$username" "https://campaignwiki.org/wiki/$wiki"
sleep 5
done

View File

@@ -3,7 +3,7 @@
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 3 of the License, or
# the Free Software Foundation; either version 2 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
@@ -12,7 +12,10 @@
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
# along with this program; if not, write to the
# Free Software Foundation, Inc.
# 59 Temple Place, Suite 330
# Boston, MA 02111-1307 USA
use CGI;
use CGI::Carp qw(fatalsToBrowser);

View File

@@ -1,131 +0,0 @@
#! /usr/bin/perl -w
# Copyright (C) 2005-2016 Alex Schroeder <alex@gnu.org>
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
use Modern::Perl;
use LWP::UserAgent;
use utf8;
binmode(STDOUT, ":utf8");
my $ua = LWP::UserAgent->new;
sub url_encode {
my $str = shift;
return '' unless $str;
utf8::encode($str); # turn to byte string
my @letters = split(//, $str);
my %safe = map {$_ => 1} ('a' .. 'z', 'A' .. 'Z', '0' .. '9', '-', '_', '.', '!', '~', '*', "'", '(', ')', '#');
foreach my $letter (@letters) {
$letter = sprintf("%%%02x", ord($letter)) unless $safe{$letter};
}
return join('', @letters);
}
sub get_raw {
my $uri = shift;
my $response = $ua->get($uri);
return $response->content if $response->is_success;
}
sub get_wiki_page {
my ($wiki, $id, $password) = @_;
my $parameters = [
pwd => $password,
action => 'browse',
id => $id,
raw => 1,
];
my $response = $ua->post($wiki, $parameters);
return $response->decoded_content if $response->is_success;
die "Getting $id returned " . $response->status_line;
}
sub get_wiki_index {
my $wiki = shift;
my $parameters = [
search => "flickr.com",
context => 0,
raw => 1,
];
my $response = $ua->post($wiki, $parameters);
return $response->decoded_content if $response->is_success;
die "Getting the index returned " . $response->status_line;
}
sub post_wiki_page {
my ($wiki, $id, $username, $password, $text) = @_;
my $parameters = [
username => $username,
pwd => $password,
recent_edit => 'on',
text => $text,
title => $id,
];
my $response = $ua->post($wiki, $parameters);
die "Posting to $id returned " . $response->status_line unless $response->code == 302;
}
my %seen = ();
sub write_flickr {
my ($id, $flickr, $dir, $file) = @_;
say "Found $flickr";
warn "$file was seen before: " . $seen{$file} if $seen{$file};
die "$file contains unknown characters" if $file =~ /[^a-z0-9_.]/;
$seen{$file} = "$id used $flickr";
my $bytes = get_raw($flickr) or die("No data for $id");
open(my $fh, '>', "$dir/$file") or die "Cannot write $dir/$file";
binmode($fh);
print $fh $bytes;
close($fh);
}
sub convert_page {
my ($wiki, $pics, $dir, $username, $password, $id) = @_;
say $id;
my $text = get_wiki_page($wiki, $id, $password);
my $is_changed = 0;
while ($text =~ m!(https://[a-z0-9.]+.flickr.com/(?:[a-z0-9.]+/)?([a-z0-9_]+\.(?:jpg|png)))!) {
my $flickr = $1;
my $file = $2;
write_flickr($id, $flickr, $dir, $file);
$is_changed = 1;
my $re = quotemeta($flickr);
$text =~ s!$flickr!$pics/$file!g;
}
if ($is_changed) {
post_wiki_page($wiki, $id, $username, $password, $text);
} else {
# die "$id has no flickr matches?\n$text";
}
sleep(5);
}
sub convert_site {
my ($wiki, $pics, $dir, $username, $password) = @_;
my @ids = split(/\n/, get_wiki_index($wiki));
for my $id (@ids) {
convert_page($wiki, $pics, $dir, $username, $password, $id);
}
}
our $AdminPass;
do "/home/alex/password.pl";
convert_site('https://alexschroeder.ch/wiki',
'https://alexschroeder.ch/pics',
'/home/alex/alexschroeder.ch/pics',
'Alex Schroeder',
$AdminPass);

1109
contrib/oddmuse-curl.el Normal file

File diff suppressed because it is too large Load Diff

View File

@@ -1,114 +0,0 @@
#! /usr/bin/perl -w
# Copyright (C) 2015 Alex Schroeder <alex@gnu.org>
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
use utf8;
use strict;
use warnings;
undef $/; # slurp
my %index = ();
my $verbose = '';
sub write_file {
my ($file, $data) = @_;
return unless $data;
open(my $fh, '>:utf8', $file) or die "Cannot write $file: $!";
print $fh $data;
close($fh);
}
sub replacement_block {
my ($block, $pos, @no_go) = @_;
while (@no_go) {
my $first = shift @no_go;
print "Is $pos between " . $first->[0] . " and " . $first->[1] . "?\n" if $verbose;
return $block if $pos >= $first->[0] and $pos <= $first->[1];
}
return "";
}
sub translate_file {
my ($data) = @_;
my @no_go = ();
while ($data =~ /( <nowiki>.*?<\/nowiki>
| <code>.*?<\/code>
| ^ <pre> (.*\n)+ <\/pre>
| ^ {{{ (.*\n)+ }}} )/gmx) {
push @no_go, [pos($data) - length $1, pos($data)];
print "no go from " . $no_go[-1]->[0] . ".." . $no_go[-1]->[1] . " for $1\n" if $verbose;
}
# The problem is that these replacements don't adjust @no_go! Perhaps it is good enough?
my $subs = '';
$subs = $subs || $data =~ s/ ( \[\/quote\] \n \n \[quote\] ) /replacement_block($1, pos($data), @no_go)/gex;
return $data if $subs;
}
sub read_file {
my $file = shift;
open(my $fh, '<:utf8', $file) or die "Cannot read $file: $!";
my $data = <$fh>;
close($fh);
return $data;
}
sub main {
my ($dir) = @_;
mkdir($dir . '-new') or die "Cannot create $dir-new: $!";
print "Indexing files\n";
foreach my $file (glob("$dir/.* $dir/*")) {
next unless $file =~ /$dir\/(.+)/;
my $id = $1;
next if $id eq ".";
next if $id eq "..";
$index{$id} = 1;
}
print "Converting files\n";
foreach my $id (sort keys %index) {
# this is where you debug a particular page
# $verbose = $id eq '2014-12-18_Emacs_Wiki_Migration';
write_file("$dir-new/$id", translate_file(read_file("$dir/$id")));
}
}
use Getopt::Long;
my $dir = 'raw';
my $help = '';
GetOptions ("dir=s" => \$dir,
"help" => \$help);
if ($help) {
print qq{
Usage: $0 [--dir=DIR]
You need to use the raw.pl script to create a directory full of raw
wiki text files.
--dir=DIR is where the raw wiki text files are. Default: raw. The
converted files will be stored in DIR-new, ie. in raw-new by
default.
Example: $0 --dir=~/alexschroeder/raw
}
} else {
main ($dir);
}

View File

@@ -1,170 +0,0 @@
#! /usr/bin/perl -w
# Copyright (C) 2015 Alex Schroeder <alex@gnu.org>
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
use utf8;
use strict;
use warnings;
undef $/; # slurp
my %index = ();
my $verbose = '';
my $LinkPattern = '(\p{Uppercase}+\p{Lowercase}+\p{Uppercase}\p{Alphabetic}*)';
my $FreeLinkPattern = "([-,.()'%&?;<> _1-9A-Za-z\x{0080}-\x{fffd}]|[-,.()'%&?;<> _0-9A-Za-z\x{0080}-\x{fffd}][-,.()'%&?;<> _0-9A-Za-z\x{0080}-\x{fffd}]+)";
my $UrlProtocols = 'http|https|ftp|afs|news|nntp|mid|cid|mailto|wais|prospero|telnet|gopher|irc|feed';
my $UrlChars = '[-a-zA-Z0-9/@=+$_~*.,;:?!\'"()&#%]'; # see RFC 2396
my $FullUrlPattern="((?:$UrlProtocols):$UrlChars+)"; # when used in square brackets
# either a single letter, or a string that begins with a single letter and ends with a non-space
my $words = '([A-Za-z\x{0080}-\x{fffd}](?:[-%.,:;\'"!?0-9 A-Za-z\x{0080}-\x{fffd}]*?[-%.,:;\'"!?0-9A-Za-z\x{0080}-\x{fffd}])?)';
# zero-width assertion to prevent km/h from counting
my $nowordstart = '(?:(?<=[^-0-9A-Za-z\x{0080}-\x{fffd}])|^)';
# zero-width look-ahead assertion to prevent km/h from counting
my $nowordend = '(?=[^-0-9A-Za-z\x{0080}-\x{fffd}]|$)';
my $IrcNickRegexp = qr{[]a-zA-Z^[;\\`_{}|][]^[;\\`_{}|a-zA-Z0-9-]*};
sub FreeToNormal { # trim all spaces and convert them to underlines
my $id = shift;
return '' unless $id;
$id =~ s/ /_/g;
$id =~ s/__+/_/g;
$id =~ s/^_//;
$id =~ s/_$//;
return $id;
}
sub parse_local_names {
my $filename = shift;
print "Reading $filename\n";
open(my $fh, '<:utf8', $filename) or die "Cannot read $filename: $!";
my $data = <$fh>;
close($fh);
print "Parsing $filename\n";
my %names = ();
while ($data =~ m/\[$FullUrlPattern\s+([^\]]+?)\]/g) {
my ($page, $url) = ($2, $1);
my $id = FreeToNormal($page);
$names{$id} = $url;
}
return \%names;
}
sub write_file {
my ($file, $data) = @_;
return unless $data;
open(my $fh, '>:utf8', $file) or die "Cannot write $file: $!";
print $fh $data;
close($fh);
}
sub replacement {
my ($names, $id, $pos, @no_go) = @_;
while (@no_go) {
my $first = shift @no_go;
print "Is $pos between " . $first->[0] . " and " . $first->[1] . "?\n" if $verbose;
return $id if $pos >= $first->[0] and $pos <= $first->[1];
}
return "[[$id]]" if exists $index{$id}; # local page exists
return $id unless $names->{$id};
return '[' . $names->{$id} . ' ' . $id . ']';
}
sub translate_file {
my ($names, $data) = @_;
my @no_go = ();
while ($data =~ /( <nowiki>.*?<\/nowiki>
| <code>.*?<\/code>
| ^ <pre> (.*\n)+ <\/pre>
| ^ {{{ (.*\n)+ }}}
| ${nowordstart} \* ${words} \* ${nowordend}
| ${nowordstart} \/ ${words} \/ ${nowordend}
| ${nowordstart} \_ ${words} \_ ${nowordend}
| ${nowordstart} \! ${words} \! ${nowordend}
| \[\[ $FreeLinkPattern .*? \]\]
| \[ $FullUrlPattern \s+ [^\]]+? \]
| ^( \h+.+\n )+
| ^(?: \[? \d\d?:\d\d (?:am|pm)? \]? )? \s* < $IrcNickRegexp > )/gmx) {
push @no_go, [pos($data) - length $1, pos($data)];
print "no go from " . $no_go[-1]->[0] . ".." . $no_go[-1]->[1] . " for $1\n" if $verbose;
}
my $subs = $data =~ s/(?<![:![])\b$LinkPattern(?![:])/replacement($names, $1, pos($data), @no_go)/ge;
return $data if $subs;
}
sub read_file {
my $file = shift;
open(my $fh, '<:utf8', $file) or die "Cannot read $file: $!";
my $data = <$fh>;
close($fh);
return $data;
}
sub main {
my ($dir, $local_names) = @_;
mkdir($dir . '-new') or die "Cannot create $dir-new: $!";
my $names = parse_local_names("$dir/$local_names");
print "Indexing files\n";
foreach my $file (glob("$dir/.* $dir/*")) {
next unless $file =~ /$dir\/(.+)/;
my $id = $1;
next if $id eq ".";
next if $id eq "..";
next if $id eq "$local_names";
$index{$id} = 1;
}
print "Converting files\n";
foreach my $id (sort keys %index) {
# this is where you debug a particular page
# $verbose = $id eq '2014-12-18_Emacs_Wiki_Migration';
write_file("$dir-new/$id", translate_file($names, read_file("$dir/$id")));
}
}
use Getopt::Long;
my $names = 'LocalNames';
my $dir = 'raw';
my $help = '';
GetOptions ("names=s" => \$names,
"dir=s" => \$dir,
"help" => \$help);
if ($help) {
print qq{
Usage: $0 [--dir=DIR] [--names=LocalNames]
You need to use the raw.pl script to create a directory full of raw
wiki text files.
--dir=DIR is where the raw wiki text files are. Default: raw. The
converted files will be stored in DIR-new, ie. in raw-new by
default.
--names=LocalNames is the page name with all the local names on
it. Default: LocalNames
Example: $0 --dir=~/alexschroeder/raw --names=Names
}
} else {
main ($dir, $names);
}

View File

@@ -1,128 +0,0 @@
#! /usr/bin/perl -w
# Copyright (C) 2015 Alex Schroeder <alex@gnu.org>
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
use utf8;
use strict;
use warnings;
undef $/; # slurp
my %index = ();
my $verbose = '';
sub write_file {
my ($file, $data) = @_;
return unless $data;
open(my $fh, '>:utf8', $file) or die "Cannot write $file: $!";
print $fh $data;
close($fh);
}
sub replacement_block {
my ($block, $pos, @no_go) = @_;
while (@no_go) {
my $first = shift @no_go;
print "Is $pos between " . $first->[0] . " and " . $first->[1] . "?\n" if $verbose;
return $block if $pos >= $first->[0] and $pos <= $first->[1];
}
return "[quote]\n" . join("\n", split(/ \n :+ \h? /x, $block)) . "[/quote]\n";
}
sub replacement {
my ($block, $tag, $pos, @no_go) = @_;
while (@no_go) {
my $first = shift @no_go;
print "Is $pos between " . $first->[0] . " and " . $first->[1] . "?\n" if $verbose;
return $block if $pos >= $first->[0] and $pos <= $first->[1];
}
return $tag . $block . $tag;
}
sub translate_file {
my ($data) = @_;
my @no_go = ();
while ($data =~ /( <nowiki>.*?<\/nowiki>
| <code>.*?<\/code>
| ^ <pre> (.*\n)+ <\/pre>
| ^ {{{ (.*\n)+ }}} )/gmx) {
push @no_go, [pos($data) - length $1, pos($data)];
print "no go from " . $no_go[-1]->[0] . ".." . $no_go[-1]->[1] . " for $1\n" if $verbose;
}
# The problem is that these replacements don't adjust @no_go! Perhaps it is good enough?
my $subs = '';
$subs = $subs || $data =~ s/ ''' (.*?) ''' /replacement($1, '**', pos($data), @no_go)/gxe;
$subs = $subs || $data =~ s/ '' (.*?) '' /replacement($1, '\/\/', pos($data), @no_go)/gxe;
$subs = $data =~ s/ ^ :+ \h? ( .* \n (?: .+ \n ) * ) /replacement_block($1, pos($data), @no_go)/gmxe;
return $data if $subs;
}
sub read_file {
my $file = shift;
open(my $fh, '<:utf8', $file) or die "Cannot read $file: $!";
my $data = <$fh>;
close($fh);
return $data;
}
sub main {
my ($dir) = @_;
mkdir($dir . '-new') or die "Cannot create $dir-new: $!";
print "Indexing files\n";
foreach my $file (glob("$dir/.* $dir/*")) {
next unless $file =~ /$dir\/(.+)/;
my $id = $1;
next if $id eq ".";
next if $id eq "..";
$index{$id} = 1;
}
print "Converting files\n";
foreach my $id (sort keys %index) {
# this is where you debug a particular page
# $verbose = $id eq '2014-12-18_Emacs_Wiki_Migration';
write_file("$dir-new/$id", translate_file(read_file("$dir/$id")));
}
}
use Getopt::Long;
my $dir = 'raw';
my $help = '';
GetOptions ("dir=s" => \$dir,
"help" => \$help);
if ($help) {
print qq{
Usage: $0 [--dir=DIR]
You need to use the raw.pl script to create a directory full of raw
wiki text files.
--dir=DIR is where the raw wiki text files are. Default: raw. The
converted files will be stored in DIR-new, ie. in raw-new by
default.
Example: $0 --dir=~/alexschroeder/raw
}
} else {
main ($dir);
}

168
contrib/vc-oddmuse.el Normal file
View File

@@ -0,0 +1,168 @@
;;; vc-oddmuse.el -- add VC support to oddmuse-curl
;;
;; Copyright (C) 2014 Alex Schroeder <alex@gnu.org>
;;
;; Latest version:
;; http://git.savannah.gnu.org/cgit/oddmuse.git/plain/contrib/vc-oddmuse.el
;; Discussion, feedback:
;; http://www.emacswiki.org/cgi-bin/wiki/OddmuseCurl
;;
;; This program is free software: you can redistribute it and/or modify it
;; under the terms of the GNU General Public License as published by the Free
;; Software Foundation, either version 3 of the License, or (at your option)
;; any later version.
;;
;; This program is distributed in the hope that it will be useful, but WITHOUT
;; ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
;; FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
;; more details.
;;
;; You should have received a copy of the GNU General Public License along
;; with GNU Emacs. If not, see <http://www.gnu.org/licenses/>.
;;; Commentary:
;;
;; Add the following to your init file:
;;
;; (add-to-list 'vc-handled-backends 'oddmuse)
(add-to-list 'vc-handled-backends 'oddmuse)
(require 'oddmuse-curl)
(require 'diff)
(defun vc-oddmuse-revision-granularity () 'file)
(defun vc-oddmuse-registered (file)
"Handle files in `oddmuse-directory'."
(string-match (concat "^" (expand-file-name oddmuse-directory))
(file-name-directory file)))
(defun vc-oddmuse-state (file)
"Return the current version control state of FILE.
For a list of possible values, see `vc-state'."
;; Avoid downloading the current version from the wiki and comparing
;; the text: Too much traffic!
'edited)
(defun vc-oddmuse-working-revision (file)
"The current revision based on `oddmuse-revisions'."
(oddmuse-revision-get oddmuse-wiki oddmuse-page-name))
(defun vc-oddmuse-checkout-model (files)
"No locking."
'implicit)
(defun vc-oddmuse-create-repo (file)
(error "You cannot create Oddmuse wikis using Emacs."))
(defun vc-oddmuse-register (files &optional rev comment)
"This always works.")
(defun vc-oddmuse-revert (file &optional contents-done)
"No idea"
nil)
(defvar vc-oddmuse-log-command
(concat "curl --silent %w"
" --form action=rc"
" --form showedit=1"
" --form all=1"
" --form from=1"
" --form raw=1"
" --form match='%r'")
"Command to use for publishing index pages.
It must print the page to stdout.
See `oddmuse-format-command' for the formatting options.")
(defun vc-oddmuse-print-log (files buffer &optional shortlog start-revision limit)
"Load complete recent changes for the files."
;; Derive `oddmuse-wiki' from the first file
(with-oddmuse-file (car files)
;; The wiki expects a Perl regular expression!
(let ((regexp (concat "^(" (mapconcat 'file-name-nondirectory files "|") ")$")))
(oddmuse-run "Getting recent changes" vc-oddmuse-log-command nil nil buffer)))
(with-current-buffer buffer
(oddmuse-render-rss3))
'limit-unsupported)
(defun vc-oddmuse-log-outgoing ()
(error "This is not supported."))
(defun vc-oddmuse-log-incoming ()
(error "This is not supported."))
(defvar vc-oddmuse-get-revision-command
(concat "curl --silent"
" --form action=browse"
" --form id=%t"
" --form revision=%v"
" --form raw=1"
" '%w'")
"Command to use to get older revisions of a page.
It must print the page to stdout.
%? '?' character
%w URL of the wiki as provided by `oddmuse-wikis'
%t Page title as provided by `oddmuse-page-name'
%v Revision to retrieve as provided by `oddmuse-revision'")
(defun oddmuse-revision-filename (rev)
"Return filename for revision REV.
This uses `oddmuse-directory', `wiki' and `pagename' as bound by
`with-oddmuse-file'."
(concat oddmuse-directory
"/" wiki
"/" pagename
".~" rev "~"))
(defun vc-oddmuse-diff (files &optional rev1 rev2 buffer)
"Report the differences for FILES."
(setq buffer (or buffer (get-buffer-create "*vc-diff*")))
(dolist (file files)
(with-oddmuse-file file
(setq rev1 (or rev1 (oddmuse-get-latest-revision wiki pagename)))
(dolist (rev (list rev1 rev2))
(when (and rev (not (file-readable-p (oddmuse-revision-filename rev))))
(let* ((oddmuse-revision rev)
(command vc-oddmuse-get-revision-command)
(filename (oddmuse-revision-filename rev)))
(with-temp-buffer
(oddmuse-run
(concat "Downloading revision " rev)
command wiki pagename)
(write-file filename)))))
(diff-no-select
(if rev1 (oddmuse-revision-filename rev1) file)
(if rev2 (oddmuse-revision-filename rev2) file)
nil
(vc-switches 'oddmuse 'diff)
buffer))))
(defun vc-oddmuse-revert (file &optional contents-done)
"Revert FILE back to the wiki revision.
If optional arg CONTENTS-DONE is non-nil, then nothing needs to
be done, as the contents of FILE have already been reverted from
a version backup."
(unless contents-done
(with-oddmuse-file file
(let ((command (oddmuse-format-command vc-oddmuse-get-revision-command)))
(with-temp-buffer
(oddmuse-run "Loading" command)
(write-file file))))))
(defun vc-oddmuse-checkin (files rev comment)
"Commit changes in FILES to this backend.
REV is a historical artifact and should be ignored. COMMENT is
used as a check-in comment."
(dolist (file files)
(with-oddmuse-file file
(let* ((summary comment)
(command (oddmuse-format-command oddmuse-post-command))
(buf (get-buffer-create " *oddmuse-response*")))
(with-temp-buffer
(insert-file-contents file)
(oddmuse-run "Posting" command wiki pagename buf t 302))))))
(provide 'vc-oddmuse)

View File

@@ -1,7 +1,110 @@
/* This file is in the public domain. */
/* @import url(https://fonts.googleapis.com/css?family=Noticia+Text:400,400italic,700italic,700&subset=latin,latin-ext); */
/* vietnamese */
@font-face {
font-family: 'Noticia Text';
font-style: normal;
font-weight: 400;
src: local('Noticia Text'), local('NoticiaText-Regular)'), url('/fonts/NoticiaText-Regular.woff') format('woff');
unicode-range: U+0102-0103, U+1EA0-1EF1, U+20AB;
}
/* latin-ext */
@font-face {
font-family: 'Noticia Text';
font-style: normal;
font-weight: 400;
src: local('Noticia Text'), local('NoticiaText-Regular)'), url('/fonts/NoticiaText-Regular.woff') format('woff');
unicode-range: U+0100-024F, U+1E00-1EFF, U+20A0-20AB, U+20AD-20CF, U+2C60-2C7F, U+A720-A7FF;
}
/* latin */
@font-face {
font-family: 'Noticia Text';
font-style: normal;
font-weight: 400;
src: local('Noticia Text'), local('NoticiaText-Regular)'), url('/fonts/NoticiaText-Regular.woff') format('woff');
unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02C6, U+02DA, U+02DC, U+2000-206F, U+2074, U+20AC, U+2212, U+2215, U+E0FF, U+EFFD, U+F000;
}
/* vietnamese */
@font-face {
font-family: 'Noticia Text';
font-style: normal;
font-weight: 700;
src: local('Noticia Text Bold'), local('NoticiaText-Bold)'), url('/fonts/NoticiaText-Bold.woff') format('woff');
unicode-range: U+0102-0103, U+1EA0-1EF1, U+20AB;
}
/* latin-ext */
@font-face {
font-family: 'Noticia Text';
font-style: normal;
font-weight: 700;
src: local('Noticia Text Bold'), local('NoticiaText-Bold)'), url('/fonts/NoticiaText-Bold.woff') format('woff');
unicode-range: U+0100-024F, U+1E00-1EFF, U+20A0-20AB, U+20AD-20CF, U+2C60-2C7F, U+A720-A7FF;
}
/* latin */
@font-face {
font-family: 'Noticia Text';
font-style: normal;
font-weight: 700;
src: local('Noticia Text Bold'), local('NoticiaText-Bold)'), url('/fonts/NoticiaText-Bold.woff') format('woff');
unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02C6, U+02DA, U+02DC, U+2000-206F, U+2074, U+20AC, U+2212, U+2215, U+E0FF, U+EFFD, U+F000;
}
/* vietnamese */
@font-face {
font-family: 'Noticia Text';
font-style: italic;
font-weight: 400;
src: local('Noticia Text Italic'), local('NoticiaText-Italic)'), url('/fonts/NoticiaText-Italic.woff') format('woff');
unicode-range: U+0102-0103, U+1EA0-1EF1, U+20AB;
}
/* latin-ext */
@font-face {
font-family: 'Noticia Text';
font-style: italic;
font-weight: 400;
src: local('Noticia Text Italic'), local('NoticiaText-Italic)'), url('/fonts/NoticiaText-Italic.woff') format('woff');
unicode-range: U+0100-024F, U+1E00-1EFF, U+20A0-20AB, U+20AD-20CF, U+2C60-2C7F, U+A720-A7FF;
}
/* latin */
@font-face {
font-family: 'Noticia Text';
font-style: italic;
font-weight: 400;
src: local('Noticia Text Italic'), local('NoticiaText-Italic)'), url('/fonts/NoticiaText-Italic.woff') format('woff');
unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02C6, U+02DA, U+02DC, U+2000-206F, U+2074, U+20AC, U+2212, U+2215, U+E0FF, U+EFFD, U+F000;
}
/* vietnamese */
@font-face {
font-family: 'Noticia Text';
font-style: italic;
font-weight: 700;
src: local('Noticia Text Bold Italic'), local('NoticiaText-BoldItalic)'), url('/fonts/NoticiaText-BoldItalic.woff') format('woff');
unicode-range: U+0102-0103, U+1EA0-1EF1, U+20AB;
}
/* latin-ext */
@font-face {
font-family: 'Noticia Text';
font-style: italic;
font-weight: 700;
src: local('Noticia Text Bold Italic'), local('NoticiaText-BoldItalic)'), url('/fonts/NoticiaText-BoldItalic.woff') format('woff');
unicode-range: U+0100-024F, U+1E00-1EFF, U+20A0-20AB, U+20AD-20CF, U+2C60-2C7F, U+A720-A7FF;
}
/* latin */
@font-face {
font-family: 'Noticia Text';
font-style: italic;
font-weight: 700;
src: local('Noticia Text Bold Italic'), local('NoticiaText-BoldItalic)'), url('/fonts/NoticiaText-BoldItalic.woff') format('woff');
unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02C6, U+02DA, U+02DC, U+2000-206F, U+2074, U+20AC, U+2212, U+2215, U+E0FF, U+EFFD, U+F000;
}
@font-face {
font-family: 'Symbola';
src: local('Symbola'), url('/fonts/Symbola.woff') format('woff') url('/fonts/Symbola.ttf') format('truetype');
}
body, rss {
font-family: "Palatino Linotype", "Book Antiqua", Palatino, serif;
font-family: "Noticia Text", Symbola, serif;
font-style: normal;
font-size: 14pt;
margin: 1em 3em;
@@ -168,7 +271,7 @@ label[for="searchlang"], #searchlang, .header input[type="submit"] {
visibility: hidden; position: absolute;
}
/* wrap on the iphone */
@media only screen and (max-device-width: 480px) {
@media media only screen and (max-device-width: 480px) {
}
.header input {

View File

@@ -1,536 +0,0 @@
/* This file is in the public domain. */
html{ text-align: center; }
body, rss {
font-family: "Palatino Linotype", "Book Antiqua", Palatino, serif;
font-style: normal;
font-size: 14pt;
padding: 1em 3em;
max-width: 72ex;
display: inline-block;
text-align: left;
color: #000;
background-color: #fff;
}
@media print {
body {
font-size: 12pt;
}
/* hide all the crap */
div.diff, div.diff+hr, div.refer, div.near, div.definition, div.sister,
div.cal, div.footer, span.specialdays, span.gotobar, a.edit, a.number span,
div.rc form, form.tiny, p.comment, p#plus1, div.g-plusone, div.content a.feed {
display:none;
}
div.content a.book,
div.content a.movie {
text-decoration: none;
}
a cite {
font-style: italic;
}
img[alt="RSS"] { display: none }
a.rss { font-size: 8pt }
}
/* headings: we can use larger sizes if we use a lighter color.
we cannot inherit the font-family because header and footer use a narrow font. */
h1, h2, h3, title {
font-family: inherit;
font-weight: normal;
}
h1, channel title {
font-size: 32pt;
margin: 1em 0 0.5em 0;
padding: 0.4em 0;
}
h2 {
font-size: 18pt;
margin: 2em 0 0 0;
padding: 0;
}
h3 {
font-size: inherit;
font-weight: bold;
padding: 0;
margin: 1em 0 0 0;
clear: both;
}
/* headers in the journal are smaller */
div.journal h1, item title {
font-size: inherit;
padding: 0;
clear: both;
border-bottom: 1px solid #000;
}
div.journal h2 {
font-family: inherit;
font-size: inherit;
}
div.journal h3 {
font-family: inherit;
font-size: inherit;
font-weight: inherit;
font-style: italic;
}
div.journal hr {
visibility: hidden;
}
p.more {
margin-top: 3em;
}
/* Links in headings appear on journal pages. */
h1 a, h2 a, h3 a {
color:inherit;
text-decoration:none;
font-weight: normal;
}
h1 a:visited, h2 a:visited, h3 a:visited {
color: inherit;
}
/* for download buttons and the like */
.button {
display: inline-block;
font-size: 120%;
cursor: pointer;
padding: 0.4em 0.6em;
text-shadow: 0px -1px 0px #ccc;
background-color: #cfa;
border: 1px solid #9d8;
border-radius: 5px;
box-shadow: 0px 1px 3px white inset, 0px 1px 3px black;
}
.button .icon {
color: #363;
text-shadow: 0px -1px 1px white, 0px 1px 3px #666;
}
.button a {
text-decoration: none;
font-weight: normal;
}
/* links */
a.pencil {
padding-left: 1ex;
text-decoration: none;
color: inherit;
visibility: hidden;
transition: visibility 0s 1s, opacity 1s linear;
opacity: 0;
}
*:hover > a.pencil {
visibility: visible;
transition: opacity .5s linear;
opacity: 1;
}
@media print {
a.pencil {
display: none;
}
}
a.number {
text-decoration: none;
}
/* stop floating content from flowing over the footer */
hr {
clear: both;
}
/* the distance between links in the navigation bars */
span.bar a {
margin-right: 1ex;
}
a img {
border: none;
}
/* search box in the top bar */
.header form, .header p {
display: inline;
white-space: nowrap;
}
label[for="searchlang"], #searchlang, .header input[type="submit"] {
/* don't use display: none! http://stackoverflow.com/questions/5665203/getting-iphone-go-button-to-submit-form */
visibility: hidden; position: absolute;
}
/* wrap on the iphone */
@media only screen and (max-device-width: 480px) {
}
.header input {
width: 10ex;
}
/* other form fields */
input[type="text"] {
padding: 0;
font-size: 80%;
line-height: 125%;
}
/* code */
textarea, pre, code, tt {
font-family: "Andale Mono", Monaco, "Courier New", Courier, monospace, "Symbola";
font-size: 80%;
}
pre {
overflow:hidden;
white-space: pre-wrap; /* CSS 3 */
white-space: -moz-pre-wrap; /* Mozilla, since 1999 */
white-space: -pre-wrap; /* Opera 4-6 */
white-space: -o-pre-wrap; /* Opera 7 */
word-wrap: break-word; /* Internet Explorer 5.5+ */
}
/* styling for divs that will be invisible when printing
when printing. */
div.header, div.footer, div.near, div.definition, p.comment, a.tag {
font-size: 14pt;
}
@media print {
div.header, div.footer, div.near, div.definition, p.comment, a.tag {
font-size: 8pt;
}
}
div.footer form.search {
display: none;
}
div.rc li + li {
margin-top: 1em;
}
div.rc li strong, table.history strong, strong.description {
font-family: inherit;
font-weight: inherit;
}
div.diff {
padding-left: 5%;
padding-right: 5%;
font-size: 12pt;
color: #000;
}
div.old {
background-color: #ffffaf;
}
div.new {
background-color: #cfffcf;
}
div.refer {
padding-left: 5%;
padding-right: 5%;
font-size: 12pt;
}
div.message {
background-color:#fee;
color:#000;
}
img.xml {
border:none;
padding:1px;
}
a.small img {
max-width:300px;
}
a.large img {
max-width:600px;
}
div.sister {
margin-right:1ex;
background-color:inherit;
}
div.sister p {
margin-top:0;
}
div.sister hr {
display:none;
}
div.sister img {
border:none;
}
div.near, div.definition {
background-color:#efe;
}
div.sidebar {
float:right;
border:1px dotted #000;
padding:0 1em;
}
div.sidebar ul {
padding-left:1em;
}
/* replacements, features */
ins {
font-style: italic;
text-decoration: none;
}
acronym, abbr {
letter-spacing:0.1em;
font-variant:small-caps;
}
/* Interlink prefix not shown */
a .site, a .separator {
display: none;
}
a cite { font:inherit; }
/* browser borkage */
textarea[name="text"] { width:97%; height:80%; }
textarea[name="summary"] { width:97%; height:3em; }
/* comments */
textarea[name="aftertext"] { width:97%; height:10em; }
div.commentshown {
font-size: 12pt;
padding: 2em 0;
}
div.commenthidden {
display:none;
}
div.commentshown {
display:block;
}
p.comment {
margin-bottom: 0;
}
div.comment {
font-size: 14pt;
}
div.comment h2 {
margin-top: 5em;
}
/* comment pages with username, homepage, and email subscription */
.comment form span { display: block; }
.comment form span label { display: inline-block; width: 10em; }
/* IE sucks */
.comment input#username,
.comment input#homepage,
.comment input#mail { width: 20em; }
/* cal */
div.month { padding:0; margin:0 2ex; }
body > div.month {
float:right;
background-color: inherit;
border:solid thin;
padding:0 1ex;
}
.year > .month {
float:left;
}
.footer {
clear:both;
}
.month .title a.local {
background-color: inherit;
}
.month a.local {
background-color: #ddf;
}
.month a.today {
background-color: #fdd;
}
.month a {
color:inherit;
font-weight:inherit;
text-decoration: none;
background-color: #eee;
}
/* history tables and other tables */
table.history {
border: none;
}
td.history {
border: none;
}
table.user {
border: none;
border-top: 1px solid #ccc;
border-bottom: 1px solid #ccc;
padding: 1em;
margin: 1em 2em;
}
table.user tr td, table.user tr th {
border: none;
padding: 0.2em 0.5em;
vertical-align: top;
}
table.arab tr th {
font-weight:normal;
text-align:left;
vertical-align:top;
}
table.arab, table.arab tr th, table.arab tr td {
border:none;
}
th.nobreak {
white-space:nowrap;
}
table.full { width:99%; margin-left:1px; }
table.j td, table.j th, table tr td.j, table tr th.j, .j { text-align:justify; }
table.l td, table.l th, table tr td.l, table tr th.l, .l { text-align:left; }
table.r td, table.r th, table tr td.r, table tr th.r, .r { text-align:right; }
table.c td, table.c th, table tr td.c, table tr th.c, .c { text-align:center; }
table.t td { vertical-align: top; }
td.half { width:50%; }
td.third { width:33%; }
form table td { padding:5px; }
/* lists */
dd { padding-bottom:0.5ex; }
dl.inside dt { float:left; }
/* search */
div.search span.result { font-size:larger; }
div.search span.info { font-size:smaller; font-style:italic; }
div.search p.result { display:none; }
img.logo {
float: right;
margin: 0 0 0 1ex;
padding: 0;
border: 1px solid #000;
opacity: 0.3;
background-color:#ffe;
}
/* images */
div.content a.feed img, div.journal a.feed img,
div.content a img.smiley, div.journal a img.smiley, img.smiley,
div.content a.inline img, div.journal a.inline img,
div.content li a.image img, div.journal li a.image img {
margin: 0; padding: 0; border: none;
}
div.image a img {
margin-bottom: 0;
}
div.image span.caption {
margin: 0 1em;
}
img {
max-width: 100%;
}
.left { float:left; margin-right: 1em; }
.right { float:right; margin-left: 1em; }
.half img { height: 50%; width: 50%; }
.face img { width: 200px; }
div.left .left, div.right .right {
float:none;
}
.center { text-align:center; }
table.aside {
float:right;
width:40%;
margin-left: 1em;
padding: 1ex;
border: 1px dotted #666;
}
table.aside td {
text-align:left;
}
div.sidebar {
float:right; width: 250px;
text-align: right;
border: none;
margin: 1ex;
}
.bigsidebar {
float:right;
width: 500px;
border: none;
margin-left: 1ex;
font-size: 80%;
}
dl.irc dt { width:20ex; float:left; text-align:right; clear:left; }
dl.irc dt span.time { float:left; }
dl.irc dd { margin-left:22ex; }
/* portrait */
div.footer, div.comment, hr { clear: both; }
.portrait { float: left; font-size: small; margin-right: 1em; }
.portrait a { color: #999; }
div.left { float:left; margin:1em; padding: 0.5em; }
div.left p { display:table-cell; }
div.left p + p { display:table-caption; caption-side:bottom; }
p.table a { float:left; width:20ex; }
p.table + p { clear:both; }
/* rss */
channel * { display: block; }
channel title {
margin-top: 30pt;
}
copyright {
font-size: 14pt;
margin-top: 1em;
}
channel > link:before {
font-size: 18pt;
display: block;
margin: 1em;
padding: 0.5em;
content: "This is an RSS feed, designed to be read in a feed reader.";
color: red;
border: 1px solid red;
}
link, license {
font-size: 11pt;
margin-bottom: 9pt;
}
username:before { content: "Last edited by "; }
username:after { content: "."; }
generator:before { content: "Feed generated by "; }
generator:after { content: "."; }
channel description {
font-weight: bold;
}
item description {
font-style: italic;
font-weight: normal;
margin-bottom: 1em;
}
docs, language,
pubDate, lastBuildDate, ttl, guid, category, comments,
docs, image title, image link,
status, version, diff, history, importance {
display: none;
}

View File

@@ -321,6 +321,7 @@ div.sister {
float:left;
margin-right:1ex;
padding-right:1ex;
border-right:1px dashed;
}
div.sister p { padding:1ex; margin:0; }
div.sister hr { display:none; }

View File

@@ -8,8 +8,110 @@
@import url(https://fonts.googleapis.com/css?family=Noticia+Text:400,400italic,700italic,700&subset=latin,latin-ext); */
/* vietnamese */
@font-face {
font-family: 'Noticia Text';
font-style: normal;
font-weight: 400;
src: local('Noticia Text'), local('NoticiaText-Regular)'), url('/fonts/NoticiaText-Regular.woff') format('woff');
unicode-range: U+0102-0103, U+1EA0-1EF1, U+20AB;
}
/* latin-ext */
@font-face {
font-family: 'Noticia Text';
font-style: normal;
font-weight: 400;
src: local('Noticia Text'), local('NoticiaText-Regular)'), url('/fonts/NoticiaText-Regular.woff') format('woff');
unicode-range: U+0100-024F, U+1E00-1EFF, U+20A0-20AB, U+20AD-20CF, U+2C60-2C7F, U+A720-A7FF;
}
/* latin */
@font-face {
font-family: 'Noticia Text';
font-style: normal;
font-weight: 400;
src: local('Noticia Text'), local('NoticiaText-Regular)'), url('/fonts/NoticiaText-Regular.woff') format('woff');
unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02C6, U+02DA, U+02DC, U+2000-206F, U+2074, U+20AC, U+2212, U+2215, U+E0FF, U+EFFD, U+F000;
}
/* vietnamese */
@font-face {
font-family: 'Noticia Text';
font-style: normal;
font-weight: 700;
src: local('Noticia Text Bold'), local('NoticiaText-Bold)'), url('/fonts/NoticiaText-Bold.woff') format('woff');
unicode-range: U+0102-0103, U+1EA0-1EF1, U+20AB;
}
/* latin-ext */
@font-face {
font-family: 'Noticia Text';
font-style: normal;
font-weight: 700;
src: local('Noticia Text Bold'), local('NoticiaText-Bold)'), url('/fonts/NoticiaText-Bold.woff') format('woff');
unicode-range: U+0100-024F, U+1E00-1EFF, U+20A0-20AB, U+20AD-20CF, U+2C60-2C7F, U+A720-A7FF;
}
/* latin */
@font-face {
font-family: 'Noticia Text';
font-style: normal;
font-weight: 700;
src: local('Noticia Text Bold'), local('NoticiaText-Bold)'), url('/fonts/NoticiaText-Bold.woff') format('woff');
unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02C6, U+02DA, U+02DC, U+2000-206F, U+2074, U+20AC, U+2212, U+2215, U+E0FF, U+EFFD, U+F000;
}
/* vietnamese */
@font-face {
font-family: 'Noticia Text';
font-style: italic;
font-weight: 400;
src: local('Noticia Text Italic'), local('NoticiaText-Italic)'), url('/fonts/NoticiaText-Italic.woff') format('woff');
unicode-range: U+0102-0103, U+1EA0-1EF1, U+20AB;
}
/* latin-ext */
@font-face {
font-family: 'Noticia Text';
font-style: italic;
font-weight: 400;
src: local('Noticia Text Italic'), local('NoticiaText-Italic)'), url('/fonts/NoticiaText-Italic.woff') format('woff');
unicode-range: U+0100-024F, U+1E00-1EFF, U+20A0-20AB, U+20AD-20CF, U+2C60-2C7F, U+A720-A7FF;
}
/* latin */
@font-face {
font-family: 'Noticia Text';
font-style: italic;
font-weight: 400;
src: local('Noticia Text Italic'), local('NoticiaText-Italic)'), url('/fonts/NoticiaText-Italic.woff') format('woff');
unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02C6, U+02DA, U+02DC, U+2000-206F, U+2074, U+20AC, U+2212, U+2215, U+E0FF, U+EFFD, U+F000;
}
/* vietnamese */
@font-face {
font-family: 'Noticia Text';
font-style: italic;
font-weight: 700;
src: local('Noticia Text Bold Italic'), local('NoticiaText-BoldItalic)'), url('/fonts/NoticiaText-BoldItalic.woff') format('woff');
unicode-range: U+0102-0103, U+1EA0-1EF1, U+20AB;
}
/* latin-ext */
@font-face {
font-family: 'Noticia Text';
font-style: italic;
font-weight: 700;
src: local('Noticia Text Bold Italic'), local('NoticiaText-BoldItalic)'), url('/fonts/NoticiaText-BoldItalic.woff') format('woff');
unicode-range: U+0100-024F, U+1E00-1EFF, U+20A0-20AB, U+20AD-20CF, U+2C60-2C7F, U+A720-A7FF;
}
/* latin */
@font-face {
font-family: 'Noticia Text';
font-style: italic;
font-weight: 700;
src: local('Noticia Text Bold Italic'), local('NoticiaText-BoldItalic)'), url('/fonts/NoticiaText-BoldItalic.woff') format('woff');
unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02C6, U+02DA, U+02DC, U+2000-206F, U+2074, U+20AC, U+2212, U+2215, U+E0FF, U+EFFD, U+F000;
}
@font-face {
font-family: 'Symbola';
src: local('Symbola'), url('/fonts/Symbola.woff') format('woff');
}
body {
font-family: "Palatino Linotype", "Book Antiqua", Palatino, serif;
font-family: "Noticia Text", Symbola, serif;
font-size: 14pt;
color: #000;
background-color: #eed;
@@ -17,20 +119,16 @@ body {
}
textarea, pre, code, tt {
font-family: "Andale Mono", Monaco, "Courier New", Courier, monospace, Symbola;
font-size: 80%;
font-family: "Andale Mono", Monaco, "Courier New", Courier, monospace, Symbola;
font-size: 80%;
}
@media print {
body {
background-color: white;
background-color: white;
font-family: Times, serif;
font-size:10pt;
}
/* Printing from Firefox */
svg {
transform: translate(-1.5cm, -1cm);
}
}
/* iPhone */
@@ -51,10 +149,9 @@ textarea, pre, code, tt {
.browse { min-height: 3em; }
.header form, .header p { margin: 0; }
/* hide the buttons but don't use display:none because of
http://stackoverflow.com/questions/5665203/getting-iphone-go-button-to-submit-form
.header input[type="submit"] { position: absolute; visibility: hidden; } */
.header input { width: 6em; font-size: 80%; }
.header input[type="checkbox"] { width: 1em; }
http://stackoverflow.com/questions/5665203/getting-iphone-go-button-to-submit-form */
.header input[type="submit"] { position: absolute; visibility: hidden; }
.header input { width: 5em; font-size: 80%; }
.footer { clear:both; font-size: 90%; }
.content input { font-size: 80%; line-height: 125%; }
@@ -78,9 +175,9 @@ input#mail, input#homepage, input#username {
/* titles */
h1 {
font-weight: bold;
font-size: 150%;
padding: 1em 0;
font-weight: bold;
font-size: 150%;
padding: 1em 0;
}
h1 a:link, h1 a:visited {
color: inherit;
@@ -120,7 +217,7 @@ a:active {
border: 1px solid #9d8;
border-radius: 5px;
box-shadow: 0px 1px 3px white inset,
0px 1px 3px black;
0px 1px 3px black;
}
.button a {
text-decoration: none;
@@ -134,6 +231,10 @@ a:active {
font-weight: normal;
}
a.edit, div.footer, form, span.gotobar, a.number span { display:none; }
a[class="url number"]:after, a[class="inter number"]:after {
content:"[" attr(href) "]";
}
a[class="local number"]:after { content:"[" attr(title) "]"; }
img[smiley] { line-height: inherit; }
}
@@ -142,15 +243,15 @@ a.pencil { display: none; }
/* table of contents */
.toc {
font-size: smaller;
border-left: 1em solid #886;
font-size: smaller;
border-left: 1em solid #886;
}
.toc ol {
list-style-type: none;
padding-left: 1em;
list-style-type: none;
padding-left: 1em;
}
.toc a {
font-weight: normal;
font-weight: normal;
}
/* images with links, captions, etc */
@@ -206,28 +307,26 @@ div.message {
}
table.history { border-style:none; }
td.history { border-style:none; }
div.history span.dash + strong { font-weight: normal; }
span.result { font-size:larger; }
span.info { font-size:smaller; font-style:italic; }
div.rc hr { display: none; }
div.rc li { padding-bottom: 0.5em; }
div.rc li strong { font-weight: normal; }
/* Tables */
table.user {
margin: 1em 0;
padding: 0 1em;
border-top: 1px solid black;
border-bottom: 1px solid black;
margin: 1em 0;
padding: 0 1em;
border-top: 1px solid black;
border-bottom: 1px solid black;
}
div.aside table.user {
margin: 1em 0;
padding: 0;
margin: 1em 0;
padding: 0;
}
table.user td, table.user th {
border-style: none;
padding:5px 10px;
vertical-align: top;
border-style: none;
padding:5px 10px;
vertical-align: top;
}
table.user th { font-weight:bold; }
table.user td.r { text-align:right; }
@@ -238,7 +337,7 @@ table.user td.mark { background-color:yellow; }
tr:empty { display: block; height: 0.5em; }
@media print {
table {
font-size: 9pt;
font-size: 9pt;
margin: 0;
}
table.user td, table.user th {

View File

@@ -51,13 +51,13 @@ a.image:hover img {
}
/* a.definition soll aussehen wie h2 */
h2, p > a.definition {
h2, p a.definition {
display: block;
clear: both;
}
/* Such Link im h1 soll nicht auffallen. */
h1, h2, h3, h4, h1 a, h1 a:visited, p > a.definition {
h1, h2, h3, h4, h1 a, h1 a:visited, p a.definition {
color: #666;
font-size: 30pt;
font-weight: normal;
@@ -188,7 +188,7 @@ div.footer hr {
div.content > div.comment {
border-top: none;
padding-top: 0;
padding-top: none;
border-left: 1ex solid #bbb;
padding-left: 1ex;
}
@@ -213,9 +213,51 @@ pre {
tt, pre, code {
font-size: 80%;
};
@font-face {
font-family: 'Gentium Basic';
font-style: normal;
font-weight: 700;
src: local('Gentium Basic Bold'), local('GentiumBasic-Bold'), url(/fonts/GenBasB.woff) format('woff');
}
code {
background: #eee;
white-space: pre-wrap;
@font-face {
font-family: 'Gentium Basic';
font-style: italic;
font-weight: 400;
src: local('Gentium Basic Italic'), local('GentiumBasic-Italic'), url(/fonts/GenBasI.woff) format('woff');
}
@font-face {
font-family: 'Gentium Basic';
font-style: italic;
font-weight: 700;
src: local('Gentium Basic Bold Italic'), local('GentiumBasic-BoldItalic'), url(/fonts/GenBasBI.woff) format('woff');
}
@font-face {
font-family: 'Gentium Basic';
font-style: normal;
font-weight: 400;
src: local('Gentium Basic'), local('GentiumBasic'), url(/fonts/GenBasR.woff) format('woff');
}
@font-face {
font-family: 'Gentium Plus';
font-style: normal;
font-weight: 400;
src: local('Gentium Plus'), local('GentiumPlus'), url(/fonts/GentiumPlus-R.woff) format('woff');
}
@font-face {
font-family: 'Gentium Plus';
font-style: italic;
font-weight: 400;
src: local('Gentium Plus Italic'), local('GentiumPlus-Italic'), url(/fonts/GentiumPlus-I.woff) format('woff');
}
@font-face {
font-family: 'Symbola';
src: local('Symbola'), url('/fonts/Symbola.woff') format('woff') url('/fonts/Symbola.ttf') format('truetype');
}

View File

Before

Width:  |  Height:  |  Size: 424 B

After

Width:  |  Height:  |  Size: 424 B

View File

Before

Width:  |  Height:  |  Size: 347 B

After

Width:  |  Height:  |  Size: 347 B

View File

Before

Width:  |  Height:  |  Size: 978 B

After

Width:  |  Height:  |  Size: 978 B

View File

Before

Width:  |  Height:  |  Size: 319 B

After

Width:  |  Height:  |  Size: 319 B

View File

Before

Width:  |  Height:  |  Size: 1.1 KiB

After

Width:  |  Height:  |  Size: 1.1 KiB

View File

Before

Width:  |  Height:  |  Size: 1.0 KiB

After

Width:  |  Height:  |  Size: 1.0 KiB

View File

Before

Width:  |  Height:  |  Size: 497 B

After

Width:  |  Height:  |  Size: 497 B

View File

Before

Width:  |  Height:  |  Size: 1.1 KiB

After

Width:  |  Height:  |  Size: 1.1 KiB

View File

Before

Width:  |  Height:  |  Size: 372 B

After

Width:  |  Height:  |  Size: 372 B

View File

Before

Width:  |  Height:  |  Size: 1.1 KiB

After

Width:  |  Height:  |  Size: 1.1 KiB

View File

Before

Width:  |  Height:  |  Size: 975 B

After

Width:  |  Height:  |  Size: 975 B

View File

Before

Width:  |  Height:  |  Size: 434 B

After

Width:  |  Height:  |  Size: 434 B

View File

Before

Width:  |  Height:  |  Size: 316 B

After

Width:  |  Height:  |  Size: 316 B

View File

Before

Width:  |  Height:  |  Size: 730 B

After

Width:  |  Height:  |  Size: 730 B

View File

Before

Width:  |  Height:  |  Size: 1.1 KiB

After

Width:  |  Height:  |  Size: 1.1 KiB

View File

Before

Width:  |  Height:  |  Size: 375 B

After

Width:  |  Height:  |  Size: 375 B

View File

Before

Width:  |  Height:  |  Size: 3.9 KiB

After

Width:  |  Height:  |  Size: 3.9 KiB

View File

Before

Width:  |  Height:  |  Size: 1.2 KiB

After

Width:  |  Height:  |  Size: 1.2 KiB

View File

Before

Width:  |  Height:  |  Size: 335 B

After

Width:  |  Height:  |  Size: 335 B

View File

Before

Width:  |  Height:  |  Size: 1010 B

After

Width:  |  Height:  |  Size: 1010 B

View File

Before

Width:  |  Height:  |  Size: 311 B

After

Width:  |  Height:  |  Size: 311 B

View File

@@ -3,7 +3,7 @@
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 3 of the License, or
# the Free Software Foundation; either version 2 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
@@ -12,7 +12,10 @@
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
# along with this program; if not, write to the
# Free Software Foundation, Inc.
# 59 Temple Place, Suite 330
# Boston, MA 02111-1307 USA
package OddMuse;
@@ -24,7 +27,7 @@ my @path = split(/\//, $ENV{REDIRECT_URL});
my $file = $path[$#path];
# for dynamic pages
our ($NotFoundHandlerExceptionsPage);
use vars qw($NotFoundHandlerExceptionsPage);
$NotFoundHandlerExceptionsPage = 'NoCachePages';
$RunCGI = 0;
do $script;

42
modules/aawrapperdiv.pl Normal file
View File

@@ -0,0 +1,42 @@
# Copyright (C) 2004, 2005 Fletcher T. Penney <fletcher@freeshell.org>
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the
# Free Software Foundation, Inc.
# 59 Temple Place, Suite 330
# Boston, MA 02111-1307 USA
use strict;
AddModuleDescription('aawrapperdiv.pl', 'WrapperDiv Module');
our ($q);
*OldGetHeader = \&GetHeader;
*GetHeader = \&WrapperGetHeader;
sub WrapperGetHeader {
my ($id, $title, $oldId, $nocache, $status) = @_;
my $result = OldGetHeader ($id, $title, $oldId, $nocache, $status);
$result .= $q->start_div({-class=>'wrapper'});
}
*OldPrintFooter = \&PrintFooter;
*PrintFooter = \&WrapperPrintFooter;
sub WrapperPrintFooter {
my ($id, $rev, $comment) = @_;
print $q->start_div({-class=>'wrapper close'});
print $q->end_div(), $q->end_div();
OldPrintFooter($id, $rev, $comment);
}

View File

@@ -14,7 +14,6 @@
# this program. If not, see <http://www.gnu.org/licenses/>.
use strict;
use v5.10;
AddModuleDescription('accesskeys.pl', 'Links With AccessKeys Extension');
@@ -22,7 +21,7 @@ our (@MyRules, $FreeLinkPattern);
push(@MyRules, \&LinksWithAccessKeys);
sub LinksWithAccessKeys {
if (m/\G(\[\[$FreeLinkPattern\{(.)\}\]\])/cg) {
if (m/\G(\[\[$FreeLinkPattern\{(.)\}\]\])/cog) {
my ($id, $key) = ($2, $3);
Dirty($1);
$id = FreeToNormal($id);

View File

@@ -2,7 +2,7 @@
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 3 of the License, or
# the Free Software Foundation; either version 2 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
@@ -11,10 +11,12 @@
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
# along with this program; if not, write to the
# Free Software Foundation, Inc.
# 59 Temple Place, Suite 330
# Boston, MA 02111-1307 USA
use strict;
use v5.10;
our ($q, %Page, %Action, $IndexFile, $PageDir, $KeepDir, @MyAdminCode, $RefererDir);
@@ -33,15 +35,15 @@ sub AdminPowerDelete {
OpenPage($id);
my $status = DeletePage($id);
if ($status) {
print $q->p(GetPageLink($id) . ' ' . T('not deleted:') . ' ' . $status);
print $q->p(GetPageLink($id) . ' ' . T('not deleted: ')) . $status;
} else {
print $q->p(GetPageLink($id) . ' ' . T('deleted'));
WriteRcLog($id, Ts('Deleted %s', $id), 0, $Page{revision},
GetParam('username', ''), $q->remote_addr(), $Page{languages},
GetParam('username', ''), GetRemoteHost(), $Page{languages},
GetCluster($Page{text}));
}
# Regenerate index on next request
Unlink($IndexFile);
unlink($IndexFile);
ReleaseLock();
print $q->p(T('Main lock released.'));
PrintFooter();
@@ -58,38 +60,38 @@ sub AdminPowerRename {
print $q->p(T('Main lock obtained.'));
# page file -- only check for existing or missing pages here
my $fname = GetPageFile($id);
ReportError(Ts('The page %s does not exist', $id), '400 BAD REQUEST') unless IsFile($fname);
ReportError(Ts('The page %s does not exist', $id), '400 BAD REQUEST') unless -f $fname;
my $newfname = GetPageFile($new);
ReportError(Ts('The page %s already exists', $new), '400 BAD REQUEST') if IsFile($newfname);
ReportError(Ts('The page %s already exists', $new), '400 BAD REQUEST') if -f $newfname;
# Regenerate index on next request -- remove this before errors can occur!
Unlink($IndexFile);
unlink($IndexFile);
# page file
CreateDir($PageDir); # It might not exist yet
Rename($fname, $newfname)
rename($fname, $newfname)
or ReportError(Tss('Cannot rename %1 to %2', $fname, $newfname) . ": $!", '500 INTERNAL SERVER ERROR');
# keep directory
my $kdir = GetKeepDir($id);
my $newkdir = GetKeepDir($new);
CreateDir($KeepDir); # It might not exist yet (only the parent directory!)
Rename($kdir, $newkdir)
rename($kdir, $newkdir)
or ReportError(Tss('Cannot rename %1 to %2', $kdir, $newkdir) . ": $!", '500 INTERNAL SERVER ERROR')
if IsDir($kdir);
if -d $kdir;
# refer file
if (defined(&GetRefererFile)) {
my $rdir = GetRefererFile($id);
my $newrdir = GetRefererFile($new);
CreateDir($RefererDir); # It might not exist yet
Rename($rdir, $newrdir)
rename($rdir, $newrdir)
or ReportError(Tss('Cannot rename %1 to %2', $rdir, $newrdir) . ": $!", '500 INTERNAL SERVER ERROR')
if IsDir($rdir);
if -d $rdir;
}
# RecentChanges
OpenPage($new);
WriteRcLog($id, Ts('Renamed to %s', $new), 0, $Page{revision},
GetParam('username', ''), $q->remote_addr(), $Page{languages},
GetParam('username', ''), GetRemoteHost(), $Page{languages},
GetCluster($Page{text}));
WriteRcLog($new, Ts('Renamed from %s', $id), 0, $Page{revision},
GetParam('username', ''), $q->remote_addr(), $Page{languages},
GetParam('username', ''), GetRemoteHost(), $Page{languages},
GetCluster($Page{text}));
print $q->p(Tss('Renamed %1 to %2.', GetPageLink($id), GetPageLink($new)));
ReleaseLock();

View File

@@ -15,7 +15,6 @@
# along with this program. If not, see <http://www.gnu.org/licenses/>.
use strict;
use v5.10;
AddModuleDescription('adsense.pl', 'AdSense Module');

View File

@@ -13,7 +13,6 @@
# this program. If not, see <http://www.gnu.org/licenses/>.
use strict;
use v5.10;
AddModuleDescription('advanced-uploads.pl', 'Advanced File Upload Extension');

View File

@@ -2,7 +2,7 @@
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 3 of the License, or
# the Free Software Foundation; either version 2 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
@@ -11,10 +11,12 @@
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
# along with this program; if not, write to the
# Free Software Foundation, Inc.
# 59 Temple Place, Suite 330
# Boston, MA 02111-1307 USA
use strict;
use v5.10;
AddModuleDescription('age.pl', 'Age Indication Extension');

View File

@@ -2,7 +2,7 @@
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 3 of the License, or
# the Free Software Foundation; either version 2 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
@@ -11,10 +11,12 @@
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
# along with this program; if not, write to the
# Free Software Foundation, Inc.
# 59 Temple Place, Suite 330
# Boston, MA 02111-1307 USA
use strict;
use v5.10;
AddModuleDescription('aggregate.pl', 'Front Page Extension');
@@ -23,7 +25,7 @@ our ($q, $bol, %Action, %Page, $OpenPageName, $UseDiff, $UsePathInfo, $RssStyleS
push(@MyRules, \&AggregateRule);
sub AggregateRule {
if ($bol && m/\G(&lt;aggregate\s+((("[^\"&]+",?\s*)+)|(sort\s+)?search\s+(.+?))&gt;)/cg) {
if ($bol && m/\G(&lt;aggregate\s+((("[^\"&]+",?\s*)+)|(sort\s+)?search\s+(.+?))&gt;)/gc) {
Clean(CloseHtmlEnvironments());
Dirty($1);
my ($oldpos, $old_, $str, $sort, $search) = ((pos), $_, $3, $5, $6);
@@ -123,8 +125,8 @@ sub DoAggregate {
}
}
foreach my $id (@pages) {
my $data = ParseData(ReadFileOrDie(GetPageFile(FreeToNormal($id))));
my $page = $data->{text};
my %data = ParseData(ReadFileOrDie(GetPageFile(FreeToNormal($id))));
my $page = $data{text};
my $size = length($page);
my $i = index($page, "\n=");
my $j = index($page, "\n----");
@@ -133,13 +135,13 @@ sub DoAggregate {
$page =~ s/^=.*\n//; # if it starts with a header
my $name = $id;
$name =~ s/_/ /g;
my $date = TimeToRFC822($data->{ts});
my $host = $data->{host};
my $username = $data->{username};
my $date = TimeToRFC822($data{ts});
my $host = $data{host};
my $username = $data{username};
$username = QuoteHtml($username);
$username = $host unless $username;
my $minor = $data->{minor};
my $revision = $data->{revision};
my $minor = $data{minor};
my $revision = $data{revision};
my $cluster = GetCluster($page);
my $description = ToString(sub { ApplyRules(QuoteHtml($page), 1, 0, undef, 'p') });
$description .= $q->p(GetPageLink($id, T('Learn more...')))

View File

@@ -1,116 +0,0 @@
# Copyright (C) 2005 Bayle Shanks http://purl.net/net/bshanks
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
use strict;
use v5.10;
our ($Now, @MyMacros, @MyRules, $DefaultStyleSheet, $q, $bol);
AddModuleDescription('agree-disagree.pl', 'AgreeDisagreePlugin');
push(@MyRules, \&AgreeDisagreeSupportRule);
push(@MyMacros, sub{ s/\[\+\]/"[+:" . GetParam('username', T('Anonymous'))
. ':' . TimeToText($Now) . "]"/eg });
push(@MyMacros, sub{ s/\[\+(:[^]:]+)\]/"[+$1:" . TimeToText($Now) . "]"/eg });
push(@MyMacros, sub{ s/\[\-\]/"[-:" . GetParam('username', T('Anonymous'))
. ':' . TimeToText($Now) . "]"/eg });
push(@MyMacros, sub{ s/\[\-(:[^]:]+)\]/"[-$1:" . TimeToText($Now) . "]"/eg });
$DefaultStyleSheet .= <<'EOT' unless $DefaultStyleSheet =~ /div\.agree/; # mod_perl?
div.agreeCount {
float: left;
clear: left;
background-color: Green;
padding-left: .5em;
padding-right: .5em;
padding-top: .5em;
padding-bottom: .5em;
}
div.disagreeCount {
float: left;
clear: right;
background-color: Red;
padding-left: .5em;
padding-right: .5em;
padding-top: .5em;
padding-bottom: .5em;
}
div.agreeNames {
float: left;
background-color: Green;
font-size: xx-small;
display: none;
}
div.disagreeNames {
float: left;
background-color: Red;
font-size: xx-small;
display: none;
}
EOT
my %AgreePortraits = ();
sub AgreeDisagreeSupportRule {
if ($bol) {
if ($bol && m/(\G(\s*\[\+(.*?)\]|\s*\[-(.*?)\])+)/cgs) {
my $votes = $1;
my @ayes = ();
my @nayes = ();
while ($votes =~ m/\G.*?\[\+(.*?)\]/cgs) {
my ($ignore, $name, $time) = split(/:/, $1, 3);
push(@ayes, $name);
}
my $votes2 = $votes;
while ($votes2 =~ m/\G.*?\[-(.*?)\]/cgs) {
my ($ignore, $name, $time) = split(/:/, $1, 3);
push(@nayes, $name);
}
my $html = CloseHtmlEnvironments() ;
$html .= $q->div({-class=>'agreeCount'}) . ($#ayes+1) . ' ' . '</div>' ;
$html .= $q->div({-class=>'agreeNames'}) . printNames(@ayes) . '</div>' ;
$html .= $q->div({-class=>'disagreeCount'}) . ' ' . ($#nayes+1) . '</div>' ;
$html .= $q->div({-class=>'disagreeNames'}) . printNames(@nayes) . '</div>' ;
return $html;
}
}
return undef;
}
sub printNames {
my @names = @_;
my $html = '';
foreach my $name (@names) {
$html .= "$name<br>";
}
return $html;
}

View File

@@ -2,7 +2,7 @@
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 3 of the License, or
# the Free Software Foundation; either version 2 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
@@ -11,10 +11,12 @@
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
# along with this program; if not, write to the
# Free Software Foundation, Inc.
# 59 Temple Place, Suite 330
# Boston, MA 02111-1307 USA
use strict;
use v5.10;
AddModuleDescription('all.pl', 'All Action');

View File

@@ -13,7 +13,6 @@
# this program. If not, see <http://www.gnu.org/licenses/>.
use strict;
use v5.10;
AddModuleDescription('anchors.pl', 'Local Anchor Extension');
@@ -21,13 +20,13 @@ our ($q, %Page, $FootnoteNumber, $FreeLinkPattern, @MyRules, $BracketWiki);
push(@MyRules, \&AnchorsRule);
sub AnchorsRule {
if (m/\G\[\[\#$FreeLinkPattern\]\]/cg) {
if (m/\G\[\[\#$FreeLinkPattern\]\]/gc) {
return $q->a({-href=>'#' . FreeToNormal($1), -class=>'local anchor'}, $1);
} elsif ($BracketWiki && m/\G\[\[\#$FreeLinkPattern\|([^\]]+)\]\]/cg) {
} elsif ($BracketWiki && m/\G\[\[\#$FreeLinkPattern\|([^\]]+)\]\]/gc) {
return $q->a({-href=>'#' . FreeToNormal($1), -class=>'local anchor'}, $2);
} elsif ($BracketWiki && m/\G(\[\[$FreeLinkPattern\#$FreeLinkPattern\|([^\]]+)\]\])/cg
or m/\G(\[\[\[$FreeLinkPattern\#$FreeLinkPattern\]\]\])/cg
or m/\G(\[\[$FreeLinkPattern\#$FreeLinkPattern\]\])/cg) {
} elsif ($BracketWiki && m/\G(\[\[$FreeLinkPattern\#$FreeLinkPattern\|([^\]]+)\]\])/cog
or m/\G(\[\[\[$FreeLinkPattern\#$FreeLinkPattern\]\]\])/cog
or m/\G(\[\[$FreeLinkPattern\#$FreeLinkPattern\]\])/cog) {
# This one is not a dirty rule because the output is always a page
# link, never an edit link (unlike normal free links).
my $bracket = (substr($1, 0, 3) eq '[[[');
@@ -47,7 +46,7 @@ sub AnchorsRule {
$text = $id unless $text;
$text =~ s/_/ /g;
return ScriptLink(UrlEncode($id), $text, $class, undef, $title);
} elsif (m/\G\[\:$FreeLinkPattern\]/cg) {
} elsif (m/\G\[\:$FreeLinkPattern\]/gc) {
return $q->a({-name=>FreeToNormal($1), -class=>'anchor'}, '');
}
return;

View File

@@ -2,7 +2,7 @@
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 3 of the License, or
# the Free Software Foundation; either version 2 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
@@ -11,10 +11,12 @@
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
# along with this program; if not, write to the
# Free Software Foundation, Inc.
# 59 Temple Place, Suite 330
# Boston, MA 02111-1307 USA
use strict;
use v5.10;
AddModuleDescription('antispam.pl', 'Antispam Module');
@@ -31,7 +33,7 @@ push(@MyRules, \&MaskEmailRule);
sub MaskEmailRule {
# Allow [email@foo.bar Email Me] links
if (m/\G\[($EmailRegExp(\s\w+)*\s*)\]/cgi) {
if (m/\G\[($EmailRegExp(\s\w+)*\s*)\]/igc) {
my $chunk = $1;
$chunk =~ s/($EmailRegExp)//i;
my $email = $1;
@@ -48,7 +50,7 @@ sub MaskEmailRule {
return "<a href=\"mailto:$email\">$chunk</a>";
}
if (m/\G($EmailRegExp)/cgi) {
if (m/\G($EmailRegExp)/igc) {
my $email = $1;
if ($DoMaskEmail) {
my $masked="";

View File

@@ -2,7 +2,7 @@
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 3 of the License, or
# the Free Software Foundation; either version 2 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
@@ -11,10 +11,12 @@
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
# along with this program; if not, write to the
# Free Software Foundation, Inc.
# 59 Temple Place, Suite 330
# Boston, MA 02111-1307 USA
use strict;
use v5.10;
AddModuleDescription('archive.pl', 'Archive Extension');

View File

@@ -14,13 +14,12 @@
# along with this program. If not, see <http://www.gnu.org/licenses/>.
use strict;
use v5.10;
AddModuleDescription('askpage.pl', 'Ask Page Extension');
use Fcntl qw(:DEFAULT :flock);
our ($DataDir, %Translate, @MyFooters);
our ($DataDir);
our ($AskPage, $QuestionPage, $NewQuestion);
# Don't forget to set your $CommentsPattern to include both $AskPage and $QuestionPage
$AskPage = 'Ask';
@@ -29,7 +28,7 @@ $NewQuestion = 'Write your question here:';
sub IncrementInFile {
my $filename = shift;
sysopen my $fh, encode_utf8($filename), O_RDWR|O_CREAT or die "can't open $filename: $!";
sysopen my $fh, $filename, O_RDWR|O_CREAT or die "can't open $filename: $!";
flock $fh, LOCK_EX or die "can't flock $filename: $!";
my $num = <$fh> || 1;
seek $fh, 0, 0 or die "can't rewind $filename: $!";
@@ -39,8 +38,8 @@ sub IncrementInFile {
return $num;
}
*OldAskPageDoPost = \&DoPost;
*DoPost = \&NewAskPageDoPost;
*OldAskPageDoPost=\&DoPost;
*DoPost=\&NewAskPageDoPost;
sub NewAskPageDoPost {
my $id = FreeToNormal(shift);
if ($id eq $AskPage and not GetParam('text', undef)) { # comment, not a regular edit
@@ -51,18 +50,16 @@ sub NewAskPageDoPost {
OldAskPageDoPost($id, @_); # keep original functionality for regular edits
}
*OldAskPageGetCommentForm = \&GetCommentForm;
*GetCommentForm = \&NewAskPageGetCommentForm;
@MyFooters = map { $_ == \&OldAskPageGetCommentForm ? \&NewAskPageGetCommentForm : $_ } @MyFooters;
*OldAskPageGetCommentForm=\&GetCommentForm;
*GetCommentForm=\&NewAskPageGetCommentForm;
sub NewAskPageGetCommentForm {
my ($id) = @_;
$Translate{'Add your comment here:'} = $NewQuestion if $id eq $AskPage;
my ($id, $rev, $comment) = @_;
$comment = $NewQuestion if not $comment and $id eq $AskPage;
OldAskPageGetCommentForm(@_);
}
*OldAskPageJournalSort = \&JournalSort;
*JournalSort = \&NewAskPageJournalSort;
*OldAskPageJournalSort=\&JournalSort;
*JournalSort=\&NewAskPageJournalSort;
sub NewAskPageJournalSort {
return OldAskPageJournalSort() unless $a =~ m/^$QuestionPage\d+$/ and $b =~ m/^$QuestionPage\d+$/;
($b =~ m/$QuestionPage(\d+)/)[0] <=> ($a =~ m/$QuestionPage(\d+)/)[0];

View File

@@ -14,9 +14,7 @@
# along with this program. If not, see <http://www.gnu.org/licenses/>.
use strict;
use v5.10;
use XML::Atom;
use XML::Atom::Entry;
use XML::Atom::Link;
use XML::Atom::Person;
@@ -150,7 +148,7 @@ sub GetRcAtom {
# Based on DoPost
sub DoAtomSave {
my ($type, $oldid) = @_;
my $entry = AtomEntry($type);
my $entry = AtomEntry();
my $title = $entry->title();
my $author = $entry->author();
SetParam('username', $author->name) if $author; # Used in Save()
@@ -231,8 +229,15 @@ sub DoAtomGet {
}
sub AtomEntry {
my $type = shift || 'POST';
my $data = $q->param($type . 'DATA'); # PUTDATA or POSTDATA
my $data = $q->param('POSTDATA');
if (not $data) {
# CGI provides POSTDATA for POST requests, not for PUT requests.
# The following code is based on the CGI->init code.
my $content_length = defined($ENV{'CONTENT_LENGTH'}) ? $ENV{'CONTENT_LENGTH'} : 0;
if ($content_length > 0 and $content_length < $MaxPost) {
$q->read_from_client(\$data, $content_length, 0);
}
}
my $entry = XML::Atom::Entry->new(\$data);
return $entry;
}

View File

@@ -1,6 +1,5 @@
#!/usr/bin/env perl
use strict;
use v5.10;
# ====================[ autolock.pl ]====================
@@ -171,11 +170,11 @@ sub UserCanEditAutoLockFix {
return 0 if $id eq 'SampleUndefinedPage' or $id eq T('SampleUndefinedPage')
or $id eq 'Sample_Undefined_Page' or $id eq T('Sample_Undefined_Page');
return 1 if UserIsAdmin() || UserIsEditor();
return 0 if $id ne '' and IsFile(GetLockedPageFile($id));
return 0 if $LockOnCreation{$id} and not IsFile(GetPageFile($id)); # new page
return 0 if !$EditAllowed or IsFile($NoEditFile);
return 0 if $id ne '' and -f GetLockedPageFile($id);
return 0 if $LockOnCreation{$id} and not -f GetPageFile($id); # new page
return 0 if !$EditAllowed or -f $NoEditFile;
return 0 if $editing and UserIsBanned(); # this call is more expensive
return 0 if $EditAllowed >= 2 and (not $CommentsPrefix or $id !~ /^$CommentsPrefix/);
return 0 if $EditAllowed >= 2 and (not $CommentsPrefix or $id !~ /^$CommentsPrefix/o);
return 1 if $EditAllowed >= 3 and ($comment or (GetParam('aftertext', '') and not GetParam('text', '')));
return 0 if $EditAllowed >= 3;
return 1;
@@ -206,17 +205,18 @@ except where noted.
Copyleft 2008 by B.w.Curry <http://www.raiazome.com>.
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 3 of the License, or
(at your option) any later version.
This file is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License
as published by the Free Software Foundation; either version 2
of the License, or (at your option) any later version.
This program is distributed in the hope that it will be useful,
This file is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
along with this file; if not, write to the Free Software
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
=cut

View File

@@ -2,7 +2,7 @@
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 3 of the License, or
# the Free Software Foundation; either version 2 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
@@ -11,13 +11,15 @@
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
# along with this program; if not, write to the
# Free Software Foundation, Inc.
# 59 Temple Place, Suite 330
# Boston, MA 02111-1307 USA
# Grab MLDBM at http://search.cpan.org/dist/MLDBM/lib/MLDBM.pm
# ie: http://search.cpan.org/CPAN/authors/id/C/CH/CHAMAS/MLDBM-2.01.tar.gz
use strict;
use v5.10;
use Fcntl;
use MLDBM qw( DB_File Storable );
@@ -41,8 +43,8 @@ sub BacklinksMenu {
$Action{buildback} = \&BuildBacklinkDatabase;
sub BuildBacklinkDatabase {
print GetHttpHeader('text/plain');
Unlink($backfile); # Remove old database
tie my %backhash, 'MLDBM', encode_utf8($backfile) or die "Cannot open file $backfile $!\n";
unlink $backfile; # Remove old database
tie my %backhash, 'MLDBM', $backfile or die "Cannot open file $backfile $!\n";
log1("Starting Database Store Process ... please wait\n\n");
foreach my $name (AllPagesList()) {
@@ -98,7 +100,7 @@ sub GetBackLink {
our ($BacklinkBanned);
$BacklinkBanned = "HomePage|ScratchPad" if !$BacklinkBanned;
tie my %backhash, 'MLDBM', encode_utf8($backfile), O_CREAT|O_RDWR, oct(644) or die "Cannot open file $backfile $!\n";
tie my %backhash, 'MLDBM', $backfile, O_CREAT|O_RDWR, oct(644) or die "Cannot open file $backfile $!\n";
# Search database for matches
while ( my ($source, $hashes) = each %backhash ) {
@@ -114,7 +116,7 @@ sub GetBackLink {
foreach my $backlink (@backlinks) {
my ($class, $resolved, $title, $exists) = ResolveId($backlink);
if (($resolved ne $id) && ($resolved !~ /^($BacklinkBanned)$/)) {
push(@unpopped, ScriptLink(UrlEncode($resolved), $resolved, $class . ' backlink', undef, Ts('Internal Page: %s', $resolved)));
push(@unpopped, ScriptLink(UrlEncode($resolved), $resolved, $class . ' backlink', undef, T('Internal Page: ' . $resolved)));
}
}

View File

@@ -11,7 +11,6 @@
# http://www.oddmuse.org/cgi-bin/oddmuse/Backlinks_Extension
use strict;
use v5.10;
AddModuleDescription('backlinks.pl', 'Backlinks Extension');

View File

@@ -1,4 +1,4 @@
# Copyright (C) 2013-2016 Alex Schroeder <alex@gnu.org>
# Copyright (C) 2013 Alex Schroeder <alex@gnu.org>
# This program is free software: you can redistribute it and/or modify it under
# the terms of the GNU General Public License as published by the Free Software
@@ -21,12 +21,10 @@ compared to the list of regular expressions on the C<BannedHosts> page
(see C<$BannedHosts>). If the contributor is already banned, this is
mentioned. If the contributor is not banned, you'll see a button
allowing you to ban him or her immediately. If you click the button,
the IP will be added to the C<BannedHosts> page for you.
the IP or hostname will be added to the C<BannedHosts> page for you.
=cut
use strict;
use v5.10;
our ($q, $Now, %Page, $OpenPageName, %Action, $UrlPattern, $BannedContent, $BannedHosts, @MyAdminCode);
AddModuleDescription('ban-contributors.pl', 'Ban Contributors Extension');
@@ -57,18 +55,17 @@ sub IsItBanned {
sub DoBanHosts {
my $id = shift;
my $content = GetParam('content', '');
my $range = GetParam('range', '');
my $regexp = GetParam('regexp', '');
my $host = GetParam('host', '');
if ($content) {
SetParam('text', GetPageContent($BannedContent)
. $content . " # " . CalcDay($Now) . " "
. NormalToFree($id) . "\n");
SetParam('summary', NormalToFree($id));
DoPost($BannedContent);
} elsif ($regexp) {
} elsif ($host) {
$host =~ s/\./\\./g;
SetParam('text', GetPageContent($BannedHosts)
. $regexp . " # " . CalcDay($Now)
. " $range "
. "^" . $host . " # " . CalcDay($Now) . " "
. NormalToFree($id) . "\n");
SetParam('summary', NormalToFree($id));
DoPost($BannedHosts);
@@ -96,14 +93,10 @@ sub DoBanHosts {
if (IsItBanned($_, \@regexps)) {
print $q->p(Ts("%s is banned", $name));
} else {
my ($start, $end) = BanContributors::get_range($_);
$range = "[$start - $end]";
$name .= " " . $range;
print GetFormStart(undef, 'get', 'ban'),
GetHiddenValue('action', 'ban'),
GetHiddenValue('id', $id),
GetHiddenValue('range', $range),
GetHiddenValue('regexp', BanContributors::get_regexp_ip($start, $end)),
GetHiddenValue('host', $_),
GetHiddenValue('recent_edit', 'on'),
$q->p($name, $q->submit(T('Ban!'))), $q->end_form();
}
@@ -130,10 +123,10 @@ sub NewBanContributorsWriteRcLog {
and $OpenPageName eq $id and UserIsAdmin()) {
# we currently have the clean page loaded, so we need to reload
# the spammed revision (there is a possible race condition here)
my $old = GetTextRevision($Page{revision} - 1, 1)->{text};
my %urls = map {$_ => 1 } $old =~ /$UrlPattern/g;
my ($old) = GetTextRevision($Page{revision}-1, 1);
my %urls = map {$_ => 1 } $old =~ /$UrlPattern/og;
# we open the file again to force a load of the despammed page
foreach my $url ($Page{text} =~ /$UrlPattern/g) {
foreach my $url ($Page{text} =~ /$UrlPattern/og) {
delete($urls{$url});
}
# we also remove any candidates that are already banned
@@ -159,100 +152,8 @@ sub NewBanContributorsWriteRcLog {
$q->submit(T('Ban!'))),
$q->end_form();
};
print $q->p(T("Consider banning the IP number as well:"), ' ',
print $q->p(T("Consider banning the IP number as well: "),
ScriptLink('action=ban;id=' . UrlEncode($id), T('Ban contributors')));
};
return OldBanContributorsWriteRcLog(@_);
}
package BanContributors;
use Net::Whois::Parser qw/parse_whois/;
sub get_range {
my $ip = shift;
my $response = parse_whois(domain => $ip);
my ($start, $end);
my $re = '(?:[0-9]{1,3}\.){3}[0-9]{1,3}';
my ($start, $end) = $response->{inetnum} =~ /($re) *- *($re)/;
return $start, $end;
}
sub get_groups {
my ($from, $to) = @_;
my @groups;
if ($from < 10) {
my $to = $to >= 10 ? 9 : $to;
push(@groups, [$from, $to]);
$from = $to + 1;
}
while ($from < $to) {
my $to = int($from/100) < int($to/100) ? $from + 99 - $from % 100 : $to;
if ($from % 10) {
push(@groups, [$from, $from + 9 - $from % 10]);
$from += 10 - $from % 10;
}
if (int($from/10) < int($to/10)) {
if ($to % 10 == 9) {
push(@groups, [$from, $to]);
$from = 1 + $to;
} else {
push(@groups, [$from, $to - 1 - $to % 10]);
$from = $to - $to % 10;
}
} else {
push(@groups, [$from - $from % 10, $to]);
last;
}
if ($to % 10 != 9) {
push(@groups, [$from, $to]);
$from = 1 + $to; # jump from 99 to 100
}
}
return \@groups;
}
sub get_regexp_range {
my @chars;
for my $group (@{get_groups(@_)}) {
my ($from, $to) = @$group;
my $char;
for (my $i = length($from); $i >= 1; $i--) {
if (substr($from, - $i, 1) eq substr($to, - $i, 1)) {
$char .= substr($from, - $i, 1);
} else {
$char .= '[' . substr($from, - $i, 1) . '-' . substr($to, - $i, 1). ']';
}
}
push(@chars, $char);
}
return join('|', @chars);
}
sub get_regexp_ip {
my ($from, $to) = @_;
my @start = split(/\./, $from);
my @end = split(/\./, $to);
my $regexp = "^";
for my $i (0 .. 3) {
if ($start[$i] eq $end[$i]) {
$regexp .= $start[$i];
} elsif ($start[$i] eq '0' and $end[$i] eq '255') {
last;
} elsif ($start[$i + 1] > 0) {
$regexp .= '(' . $start[$i] . '\.('
. get_regexp_range($start[$i + 1], '255') . ')|'
. get_regexp_range($start[$i] + 1, $end[$i + 1]) . ')';
$regexp .= '\.';
last;
} else {
$regexp .= '(' . get_regexp_range($start[$i], $end[$i]) . ')$';
last;
}
$regexp .= '\.' if $i < 3;
}
return $regexp;
}
# this is required in case we concatenate other modules to this one
package OddMuse;

View File

@@ -1,4 +1,4 @@
# Copyright (C) 20132015 Alex Schroeder <alex@gnu.org>
# Copyright (C) 2013 Alex Schroeder <alex@gnu.org>
#
# This program is free software: you can redistribute it and/or modify it under
# the terms of the GNU General Public License as published by the Free Software
@@ -16,11 +16,10 @@
# editors will be logged.
use strict;
use v5.10;
AddModuleDescription('ban-quick-editors.pl', 'Banning Quick Editors');
our ($q, $Now, %RecentVisitors, $SurgeProtection);
our ($Now, %RecentVisitors, $SurgeProtection);
*BanQuickOldUserIsBanned = \&UserIsBanned;
*UserIsBanned = \&BanQuickNewUserIsBanned;
@@ -30,7 +29,7 @@ sub BanQuickNewUserIsBanned {
if (not $rule
and $SurgeProtection # need surge protection
and GetParam('title')) {
my $name = GetParam('username', $q->remote_addr());
my $name = GetParam('username', GetRemoteHost());
my @entries = @{$RecentVisitors{$name}};
# $entry[0] is $Now after AddRecentVisitor
my $ts = $entries[1];

View File

@@ -13,17 +13,14 @@
# this program. If not, see <http://www.gnu.org/licenses/>.
use strict;
use v5.10;
AddModuleDescription('banned-regexps.pl', 'Banning Regular Expressions');
=encoding utf8
=head1 Compatibility
=h1 Compatibility
This extension works with logbannedcontent.pl.
=head1 Example content for the BannedRegexps page:
=h1 Example content for the BannedRegexps page:
# This page lists regular expressions that prevent the saving of a page.
# The regexps are matched against any page or comment submitted.
@@ -45,8 +42,7 @@ This extension works with logbannedcontent.pl.
=cut
our (%AdminPages, %LockOnCreation, @MyInitVariables, %PlainTextPages, $BannedContent, $BannedFile,
$FullUrlPattern);
our (%AdminPages, %LockOnCreation, @MyInitVariables, %PlainTextPages, $BannedContent, $BannedFile);
our ($BannedRegexps);
$BannedRegexps = 'BannedRegexps';
@@ -62,8 +58,6 @@ push(@MyInitVariables, sub {
sub RegexpNewBannedContent {
my $str = shift;
# remove URLs as they are controlled by $BannedContent
$str =~ s/$FullUrlPattern//g;
my $rule = RegexpOldBannedContent($str, @_);
if (not $rule) {
foreach (split(/\n/, GetPageContent($BannedRegexps))) {

View File

@@ -13,13 +13,12 @@
# this program. If not, see <http://www.gnu.org/licenses/>.
use strict;
use v5.10;
AddModuleDescription('bbcode.pl', 'bbCode Extension');
our ($q, @HtmlStack, @MyRules, %RuleOrder, $UrlProtocols, $FullUrlPattern);
push(@MyRules, \&bbCodeRule);
$RuleOrder{\&bbCodeRule} = 300; # must come after PortraitSupportRule, MarkdownRule
$RuleOrder{\&bbCodeRule} = 100; # must come after PortraitSupportRule
our ($bbBlock);
my %bbTitle = qw(h1 1 h2 1 h3 1 h4 1 h5 1 h6 1);
@@ -61,12 +60,12 @@ sub bbCodeRule {
return AddHtmlEnvironment('strong', qq{class="highlight"}); }
elsif ($tag eq 'url') {
if ($option) {
$option =~ /^($UrlProtocols)/;
$option =~ /^($UrlProtocols)/o;
my $class = "url $1";
return AddHtmlEnvironment('a', qq{href="$option" class="$class"}); }
elsif (/\G$FullUrlPattern\s*\[\/url\]/cgi) {
elsif (/\G$FullUrlPattern\s*\[\/url\]/cogi) {
return GetUrl($1); }}
elsif ($tag eq 'img' and /\G$FullUrlPattern\s*\[\/img\]/cgi) {
elsif ($tag eq 'img' and /\G$FullUrlPattern\s*\[\/img\]/cogi) {
return GetUrl($1, undef, undef, 1); } # force image
elsif ($tag eq 'quote') {
my $html = CloseHtmlEnvironments();

View File

@@ -14,7 +14,6 @@
# along with this program. If not, see <http://www.gnu.org/licenses/>.
use strict;
use v5.10;
AddModuleDescription('big-brother.pl', 'Big Brother Extension');
@@ -60,6 +59,7 @@ sub AddRecentVisitor {
my $url = ScriptUrl(join(';', "action=$action;id=" . UrlEncode($id),
map { $_ . '=' . UrlEncode(GetParam($_)) }
keys %params));
my $url = $q->url(-path_info=>1,-query=>1);
my $download = GetParam('action', 'browse') eq 'download'
|| GetParam('download', 0)
|| $q->path_info() =~ m/\/download\//;

View File

@@ -2,7 +2,7 @@
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 3 of the License, or
# the Free Software Foundation; either version 2 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
@@ -11,10 +11,12 @@
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
# along with this program; if not, write to the
# Free Software Foundation, Inc.
# 59 Temple Place, Suite 330
# Boston, MA 02111-1307 USA
use strict;
use v5.10;
AddModuleDescription('blockquote.pl', 'Comments on Text Formatting Rules');
@@ -25,10 +27,10 @@ push(@MyRules, \&BlockQuoteRule);
sub BlockQuoteRule {
# indented text using : with the option of spanning multiple text
# paragraphs (but not lists etc).
if (InElement('blockquote') && m/\G(\s*\n)+:[ \t]*/cg) {
if (InElement('blockquote') && m/\G(\s*\n)+:[ \t]*/cog) {
return CloseHtmlEnvironmentUntil('blockquote')
. AddHtmlEnvironment('p');
} elsif ($bol && m/\G(\s*\n)*:[ \t]*/cg) {
} elsif ($bol && m/\G(\s*\n)*:[ \t]*/cog) {
return CloseHtmlEnvironments()
. AddHtmlEnvironment('blockquote')
. AddHtmlEnvironment('p');

View File

@@ -3,7 +3,7 @@
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 3 of the License, or
# the Free Software Foundation; either version 2 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
@@ -12,10 +12,12 @@
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
# along with this program; if not, write to the
# Free Software Foundation, Inc.
# 59 Temple Place, Suite 330
# Boston, MA 02111-1307 USA
use strict;
use v5.10;
AddModuleDescription('calendar.pl', 'Calendar Extension');
@@ -23,7 +25,6 @@ our ($q, %Page, %Action, $Now, $OpenPageName, $CollectingJournal, $FreeLinkPatte
our ($CalendarOnEveryPage, $CalAsTable, $CalStartMonday);
$CalendarOnEveryPage = 0; # 1=on every page is a month-div situated in the header, use css to control
# 2=this month and the previous month; 3=this, previous and next month
$CalAsTable = 0; # 0=every month-div is "free", 1=every month-div is caught in a table, use css to control
$CalStartMonday = 0; # 0=week starts with Su, 1=week starts with Mo
@@ -35,22 +36,8 @@ sub NewCalendarGetHeader {
return $header unless $CalendarOnEveryPage;
my $action = GetParam('action', 'browse');
return $header if grep(/^$action$/, ('calendar', 'edit'));
my $cal;
my ($sec, $min, $hour, $mday, $mon, $year) = localtime($Now);
$year += 1900;
# $mon is 0 based and thus good for previous month
if ($mon < 1) { $year -= 1; $mon += 12; };
$cal .= Cal($year, $mon) if $CalendarOnEveryPage > 1;
# the current month
$mon += 1;
if ($mon > 12) { $year += 1; $mon -= 12; };
$cal .= Cal($year, $mon) if $CalendarOnEveryPage;
# the next month
$mon += 1;
if ($mon > 12) { $year += 1; $mon -= 12; };
$cal .= Cal($year, $mon) if $CalendarOnEveryPage > 2;
# insert calendars before header div
$header =~ s!<div class="header">!<div class="cal">$cal</div><div class="header">!;
my $cal = Cal();
$header =~ s/<div class="header">/$cal<div class="header">/;
return $header;
}
@@ -86,7 +73,7 @@ sub Cal {
$link .= ScriptLink('action=collect;match=' . UrlEncode($re), $day, 'local collection' . $class);
}
$link;
}}eg;
}}ge;
$cal =~ s{(\S+) (\d\d\d\d)}{{
my ($month_text, $year_text) = ($1, $2);
my $date = sprintf("%d-%02d", $year, $mon);
@@ -100,7 +87,7 @@ sub Cal {
$year_text, 'local collection year'));
}
}}e;
return "<div class=\"month\"><pre>$cal</pre></div>";
return "<div class=\"cal month\"><pre>$cal</pre></div>";
}
$Action{collect} = \&DoCollect;
@@ -130,22 +117,22 @@ sub DoCollect {
push(@MyRules, \&CalendarRule);
sub CalendarRule {
if (/\G(calendar:(\d\d\d\d))/cg) {
if (/\G(calendar:(\d\d\d\d))/gc) {
my $oldpos = pos;
Clean(CloseHtmlEnvironments());
Dirty($1);
PrintYearCalendar($2);
pos = $oldpos;
return AddHtmlEnvironment('p');
} elsif (/\G(month:(\d\d\d\d)-(\d\d))/cg) {
} elsif (/\G(month:(\d\d\d\d)-(\d\d))/gc) {
my $oldpos = pos;
Clean(CloseHtmlEnvironments());
Dirty($1);
print $q->div({-class => 'cal'}, Cal($2, $3));
print Cal($2, $3);
pos = $oldpos;
return AddHtmlEnvironment('p');
} elsif (/\G(month:([+-]\d\d?))/cg
or /\G(\[\[month:([+-]\d\d?) $FreeLinkPattern\]\])/cg) {
} elsif (/\G(month:([+-]\d\d?))/gc
or /\G(\[\[month:([+-]\d\d?) $FreeLinkPattern\]\])/gc) {
my $oldpos = pos;
Clean(CloseHtmlEnvironments());
Dirty($1);
@@ -156,7 +143,7 @@ sub CalendarRule {
$mon += 1 + $delta;
while ($mon < 1) { $year -= 1; $mon += 12; };
while ($mon > 12) { $year += 1; $mon -= 12; };
print $q->div({-class => 'cal'}, Cal($year, $mon, undef, $id));
print Cal($year, $mon, undef, $id);
pos = $oldpos;
return AddHtmlEnvironment('p');
}

View File

@@ -2,7 +2,7 @@
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 3 of the License, or
# the Free Software Foundation; either version 2 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
@@ -11,10 +11,12 @@
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
# along with this program; if not, write to the
# Free Software Foundation, Inc.
# 59 Temple Place, Suite 330
# Boston, MA 02111-1307 USA
use strict;
use v5.10;
AddModuleDescription('canonical.pl', 'Canonical Names');

View File

@@ -1,178 +0,0 @@
# Copyright (C) 2008 Eric Hsu <apricotan@gmail.com>
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
use strict;
use v5.10;
use utf8;
AddModuleDescription('cart.pl', 'Cart Extension');
our ($q, %Action, $UserGotoBar, $CookieName);
our ($CartPic, $CartName, %Cart, $ShowCart, @CartOrdered);
my $LOADED_CART_JS;
# ============
# = cart-bfc =
# ============
# This is a simple shopping cart for pages!
# Requires searchpaged-bfc.pl.
# We make a checkbox that onChange, uses Yahoo! UI Cookie 2.6 (note we need 2.6!) routines to set a subcookie.
# We have the cookie "$CartName" (by default $Cookiename . "Cart")
# which holds the actual cart and is managed almost entirely
# in client-side javascript. That means the checkboxes directly control the cookie.
# If you want a little picture of a cart, you can set the URL at $CartPic.
# InitCart loads the cookie values into %Cart. $Cart->{$pagename}=1 if it's in the cart.
# In theory cookies are capped at 4K. Our page names are capped around 90ish chars. That leaves room for 40 maximal names in the cart. Probably enough.
# We'll need the cookie values for
# action=cart;subaction=show; along with other future subactions (download in latex, bibtex)
# we'll feed this display to a variant of search display.
# I'll have to check oddmuse.pl.
# load Yahoo UI code bit to manage subcookies.
$Action{cart} = \&DoCart;
sub DoCart {
# foreach $key (keys %Cart) {
# push @cart, $key if ($Cart{"$key"});
# }
DoSearch(\@CartOrdered);
}
$UserGotoBar .= '<a href="?action=cart;cache=0">View Cart</a>';
# Manage Cart Routines
#push @MyPrintSearchResultsPrefix, \&PrintCheckboxTableStart;
#push @MyPrintSearchResultsSuffix, \&PrintCheckboxTableEnd;
# I can't hack into Init, so let's tap into InitCookie.
# We also tap into Cookie() to arrange writing out our cleaned up Cart.
*OldInitCookie = *InitCookie;
*InitCookie = *InitCookieAndCart;
# To get a checkbox in the titles of pages, we patch GetHeader.
*OldGetHeader = *GetHeader;
*GetHeader = *GetHeaderAndCart;
sub InitCookieAndCart {
OldInitCookie();
InitCart();
}
sub GetHeaderAndCart {
my ($id, $title, $oldId, $nocache, $status) = @_;
my $result = OldGetHeader(@_);
return ($result) unless ($id);
my $checkbox = MakeCheckbox($id);
$checkbox = qq(<span class="cart-checkbox" style="float:right">$checkbox</span>);
$result =~ s/(<\/h1>)/$checkbox$1/;
return ($result);
}
# We load the contents of our Cart cookie into the global %Cart and @CartOrdered
sub InitCart {
$CartName = $CookieName . "Cart" unless (defined ($CartName) );
my @pairs;
%Cart = ();
@CartOrdered = ();
if ($q->cookie($CartName)) {
# @pairs = split(/&/, $q->cookie($CartName));
@pairs = $q->cookie($CartName);
foreach my $pair (@pairs) {
# my $encodedequals = UrlEncode("=");
my ($name, $val)= split(/\=/, $pair);
$Cart{"$name"}=$val;
push @CartOrdered, $name;
}
}
}
sub PrintCheckboxTableStart {
my ($name, $regex, $text, $type) = @_;
my $html;
$html .= "<table><tr>";
my $checkbox = MakeCheckbox(@_);
$html .= qq(<td valign=top>$checkbox</td>);
$html .= "<td valign=top>";
print $html;
}
sub PrintCheckboxTableEnd {
my ($name, $regex, $text, $type) = @_;
my $html;
$html .= "</td>";
$html .= "</tr></table>";
print $html;
}
sub MakeCheckbox {
my ($name, $regex, $text, $type) = @_;
my $html;
return unless ($ShowCart);
unless ($LOADED_CART_JS) {
$html .= '<script type="text/javascript" src="http://yui.yahooapis.com/combo?2.7.0/build/yahoo/yahoo-min.js&2.7.0/build/cookie/cookie-min.js&2.7.0/build/event/event-min.js"></script>';
$LOADED_CART_JS=1;
}
my $selected = qq(checked="yes") if ($Cart{"$name"});
$html .=<<HTMLEND;
$CartPic<input type="checkbox" value="cart" id="$name-set" title="Add To Cart" $selected/> <br>
<script type="text/javascript">
(function(){
YAHOO.util.Event.on("$name-set", "change", function(){
var value = YAHOO.util.Cookie.getSub("$CartName", "$name");
if (value == 1 ) { YAHOO.util.Cookie.removeSub("$CartName", "$name"); }
else { YAHOO.util.Cookie.setSub("$CartName", "$name", 1 ); }
});
})();
</script>
HTMLEND
return $html unless ($q->param('action') eq 'edit' || $q->param('Preview'));
# no checkboxes for edit pages.
return;
}
__END__
=
(0.7) Load JS libraries on first checkbox (so won't load if we are editing).
(0.6) Changed the JS source to be Yahoo's CDN.
(0.51) Use CSS class cart-checkbox for the cart checkbox! That way, we can remove them for printouts, for instance.
(0.5) Our hack of cookies was not working cross-platform. We have a mismatch because our attempts to send out a cookie from oddmuse were getting the contents encoded and unreadable for the YUI routines. Instead,we will use removeSub to avoid ever having to send the cookie back from our server!
(0.4) Now every page title has a checkbox floated to the right, which controls the cart status.
(0.3) Allow cart editing from cart display. Currently, doesn't seem to affect the cart.
(0.2) Cart now displays.
(0.1) Cart is now persistent and is edited by the checkboxes.

View File

@@ -2,7 +2,7 @@
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 3 of the License, or
# the Free Software Foundation; either version 2 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
@@ -11,10 +11,12 @@
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
# along with this program; if not, write to the
# Free Software Foundation, Inc.
# 59 Temple Place, Suite 330
# Boston, MA 02111-1307 USA
use strict;
use v5.10;
AddModuleDescription('checkbox.pl', 'Checklist Extension');
@@ -74,7 +76,7 @@ sub DoCheckBox{
$summary{$3} = 0 if $2 eq 'x' or $2 eq 'X';
"${1}[[ :${3}]]";
}
}egi;
}eig;
SetParam('text', $text);
SetParam('summary', join(', ', map {
if ($summary{$_}) {

View File

@@ -2,7 +2,7 @@
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 3 of the License, or
# the Free Software Foundation; either version 2 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
@@ -11,10 +11,12 @@
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
# along with this program; if not, write to the
# Free Software Foundation, Inc.
# 59 Temple Place, Suite 330
# Boston, MA 02111-1307 USA
use strict;
use v5.10;
AddModuleDescription('clustermap.pl', 'ClusterMap Module');
@@ -59,7 +61,7 @@ foreach (@ClusterMapAdminPages){
}
sub ClusterMapRule {
if (/\G^([\n\r]*\<\s*clustermap\s*\>\s*)$/cgm) {
if (/\G^([\n\r]*\<\s*clustermap\s*\>\s*)$/mgc) {
Dirty($1);
my $oldpos = pos;
my $oldstr = $_;

View File

@@ -14,7 +14,6 @@
# this program. If not, see <http://www.gnu.org/licenses/>.
use strict;
use v5.10;
AddModuleDescription('comment-div-wrapper.pl', 'Comment Div Wrapper Extension');
@@ -30,7 +29,7 @@ sub CommentDivWrapper {
return $q->start_div({-class=>'userComment'});
}
}
if ($OpenPageName =~ /$CommentsPattern/) {
if ($OpenPageName =~ /$CommentsPattern/o) {
if ($bol and m/\G(\s*\n)*----+[ \t]*\n?/cg) {
my $html = CloseHtmlEnvironments()
. ($CommentDiv++ > 0 ? $q->end_div() : $q->h2({-class=>'commentsHeading'}, T('Comments:'))) . $q->start_div({-class=>'userComment'})

View File

@@ -2,7 +2,7 @@
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 3 of the License, or
# the Free Software Foundation; either version 2 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
@@ -11,10 +11,12 @@
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
# along with this program; if not, write to the
# Free Software Foundation, Inc.
# 59 Temple Place, Suite 330
# Boston, MA 02111-1307 USA
use strict;
use v5.10;
AddModuleDescription('commentcount.pl', 'Comment Count Extension');
@@ -49,15 +51,15 @@ sub NewCommentcountScriptLink {
if ($CommentsPrefix && $action =~ /^$CommentsPrefix(.*)/) { # TODO use $CommentsPattern ?
# Add the number of comments here
my $id = $action;
$id =~ s/%([0-9a-f][0-9a-f])/chr(hex($1))/eg; # undo urlencode
$id =~ s/%([0-9a-f][0-9a-f])/chr(hex($1))/ge; # undo urlencode
my $comments = GetPageContent($id);
my $num = 0;
if($comments =~ /=== (\d+) Comments?\. ===/) {
$num = $1;
}
# Fix plurals
my $plural = T('Comments on');
my $singular = T('Comment on');
my $plural = T('Comments on ');
my $singular = T('Comment on ');
$text =~ s/$plural/$singular/ if($num == 1);
$text = $num . ' ' . $text;
}

View File

@@ -2,7 +2,7 @@
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 3 of the License, or
# the Free Software Foundation; either version 2 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
@@ -11,10 +11,12 @@
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
# along with this program; if not, write to the
# Free Software Foundation, Inc.
# 59 Temple Place, Suite 330
# Boston, MA 02111-1307 USA
use strict;
use v5.10;
AddModuleDescription('compilation.pl', 'Compilation Extension');

View File

@@ -2,7 +2,7 @@
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 3 of the License, or
# the Free Software Foundation; either version 2 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
@@ -14,7 +14,6 @@
# along with this program. If not, see <http://www.gnu.org/licenses/>.
use strict;
use v5.10;
AddModuleDescription('context.pl', 'Calendar Extension');

View File

@@ -1,35 +1,33 @@
# Copyright (C) 2005 Fletcher T. Penney <fletcher@freeshell.org>
# Copyright (C) 2016 Alex Schroeder <alex@gnu.org>
#
# This program is free software; you can redistribute it and/or modify it under
# the terms of the GNU General Public License as published by the Free Software
# Foundation; either version 3 of the License, or (at your option) any later
# version.
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful, but WITHOUT
# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
# FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License along with
# this program. If not, see <http://www.gnu.org/licenses/>.
=head1 Creation Date Extension
This module stores additional information about a page when it is first created:
=over
=item C<created> is the date the page is first saved
=item C<originalAuthor> is the username that first created a page
=back
=cut
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the
# Free Software Foundation, Inc.
# 59 Temple Place, Suite 330
# Boston, MA 02111-1307 USA
#
# This module stores additional information about a page when it is
# first created:
# created = the date the page is FIRST saved
# originalAuthor = the username that first created a page
#
# Of course, you can customize this to store more information
use strict;
use v5.10;
AddModuleDescription('creationdate.pl', 'CreationDate Module');
our (%Page, $Now, @MyAdminCode, %Action, $q, $FS, $RcOldFile, $RcFile);
our (%Page, $Now);
*CreationDateOldOpenPage = \&OpenPage;
*OpenPage = \&CreationDateOpenPage;
@@ -40,45 +38,3 @@ sub CreationDateOpenPage{
$Page{originalAuthor} = GetParam('username','') unless $Page{originalAuthor}
or $Page{revision};
}
# Allow administrators to add the 'created' item to page files, based on rc log
# files.
push(@MyAdminCode, \&CreationDateMenu);
sub CreationDateMenu {
my ($id, $menuref, $restref) = @_;
push(@$menuref,
ScriptLink('action=add-creation-date',
T('Add creation date to page files'),
'creationdate')) if UserIsAdmin();
}
$Action{'add-creation-date'} = \&AddCreationDate;
sub AddCreationDate {
print GetHeader('', T('Add creation date to page files'));
print $q->start_div({-class=>'creationdate'});
print '<ul>';
RequestLockOrError();
for my $file ($RcOldFile, $RcFile) {
open(my $F, '<:encoding(UTF-8)', encode_utf8($file)) or next;
while (my $line = <$F>) {
chomp($line);
my ($ts, $id, $minor, $summary, $host, $username, $revision)
= split(/$FS/, $line);
next unless $revision == 1;
print $q->li(NormalToFree($id));
OpenPage($id);
next unless $Page{revision}; # skip if page no longer exists
next if $Page{created} and $Page{originalAuthor};
$Page{created} = $ts unless $Page{created};
$Page{originalAuthor} = $username unless $Page{originalAuthor};
SavePage();
}
}
ReleaseLock();
print '</ul>';
print $q->end_div();
PrintFooter();
}

View File

@@ -1,6 +1,5 @@
#!/usr/bin/env perl
use strict;
use v5.10;
# ====================[ creole.pl ]====================
@@ -218,7 +217,7 @@ sub CreoleRule {
}
# escape next char (and prevent // in URLs from enabling italics)
# ~
elsif (m/\G(~($FullUrlPattern|\S))/cg) {
elsif (m/\G(~($FullUrlPattern|\S))/cgo) {
return
($CreoleTildeAlternative and
index( 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'
@@ -234,12 +233,12 @@ sub CreoleRule {
# {{{preformatted code}}}
elsif (m/\G\{\{\{(.*?}*)\}\}\}/cg) { return $q->code($1); }
# download: {{pic}} and {{pic|text}}
elsif (m/\G(\{\{$FreeLinkPattern$CreoleLinkTextPattern\}\})/cgs) {
elsif (m/\G(\{\{$FreeLinkPattern$CreoleLinkTextPattern\}\})/cgos) {
my $text = $4 || $2;
return GetCreoleLinkHtml($1, GetDownloadLink(FreeToNormal($2), 1, undef, $text), $text);
}
# image link: {{url}} and {{url|text}}
elsif (m/\G\{\{$FullUrlPattern$CreoleLinkTextPattern\}\}/cgs) {
elsif (m/\G\{\{$FullUrlPattern$CreoleLinkTextPattern\}\}/cgos) {
return GetCreoleImageHtml(
$q->a({-href=> UnquoteHtml($1),
-class=> 'image outside'},
@@ -250,7 +249,7 @@ sub CreoleRule {
}
# image link: [[link|{{pic}}]] and [[link|{{pic|text}}]]
elsif (m/\G(\[\[$FreeLinkPattern$CreoleLinkPipePattern
\{\{$FreeLinkPattern$CreoleLinkTextPattern\}\}\]\])/cgsx) {
\{\{$FreeLinkPattern$CreoleLinkTextPattern\}\}\]\])/cgosx) {
my $text = $5 || $2;
return GetCreoleLinkHtml($1, GetCreoleImageHtml(
ScriptLink(UrlEncode(FreeToNormal($2)),
@@ -261,7 +260,7 @@ sub CreoleRule {
}
# image link: [[link|{{url}}]] and [[link|{{url|text}}]]
elsif (m/\G(\[\[$FreeLinkPattern$CreoleLinkPipePattern
\{\{$FullUrlPattern$CreoleLinkTextPattern\}\}\]\])/cgsx) {
\{\{$FullUrlPattern$CreoleLinkTextPattern\}\}\]\])/cgosx) {
my $text = $5 || $2;
return GetCreoleLinkHtml($1, GetCreoleImageHtml(
ScriptLink(UrlEncode(FreeToNormal($2)),
@@ -272,7 +271,7 @@ sub CreoleRule {
}
# image link: [[url|{{pic}}]] and [[url|{{pic|text}}]]
elsif (m/\G(\[\[$FullUrlPattern$CreoleLinkPipePattern
\{\{$FreeLinkPattern$CreoleLinkTextPattern\}\}\]\])/cgsx) {
\{\{$FreeLinkPattern$CreoleLinkTextPattern\}\}\]\])/cgosx) {
my $text = $5 || $2;
return GetCreoleLinkHtml($1, GetCreoleImageHtml(
$q->a({-href=> UnquoteHtml($2), -class=> 'image outside'},
@@ -283,7 +282,7 @@ sub CreoleRule {
}
# image link: [[url|{{url}}]] and [[url|{{url|text}}]]
elsif (m/\G\[\[$FullUrlPattern$CreoleLinkPipePattern
\{\{$FullUrlPattern$CreoleLinkTextPattern\}\}\]\]/cgsx) {
\{\{$FullUrlPattern$CreoleLinkTextPattern\}\}\]\]/cgosx) {
return GetCreoleImageHtml(
$q->a({-href=> UnquoteHtml($1), -class=> 'image outside'},
$q->img({-src=> UnquoteHtml($2),
@@ -292,7 +291,7 @@ sub CreoleRule {
-class=> 'url outside'})));
}
# link: [[url]] and [[url|text]]
elsif (m/\G\[\[$FullUrlPattern$CreoleLinkTextPattern\]\]/cgs) {
elsif (m/\G\[\[$FullUrlPattern$CreoleLinkTextPattern\]\]/cgos) {
# Permit embedding of Creole syntax within link text. (Rather complicated,
# but it does the job remarkably.)
my $link_url = $1;
@@ -305,7 +304,7 @@ sub CreoleRule {
return GetUrl($link_url, $link_text, 1);
}
# link: [[page]] and [[page|text]]
elsif (m/\G(\[\[$FreeLinkPattern$CreoleLinkTextPattern\]\])/cgs) {
elsif (m/\G(\[\[$FreeLinkPattern$CreoleLinkTextPattern\]\])/cgos) {
my $markup = $1;
my $page_name = $2;
my $link_text = $4 ? CreoleRuleRecursive($4, @_) : $page_name;
@@ -315,7 +314,7 @@ sub CreoleRule {
}
# interlink: [[Wiki:page]] and [[Wiki:page|text]]
elsif ($is_interlinking and
m/\G(\[\[$FreeInterLinkPattern$CreoleLinkTextPattern\]\])/cgs) {
m/\G(\[\[$FreeInterLinkPattern$CreoleLinkTextPattern\]\])/cgos) {
my $markup = $1;
my $interlink = $2;
my $interlink_text = $4;
@@ -405,7 +404,8 @@ sub CreoleRule {
if ($is_left_justified and
$is_right_justified) { $attributes .= 'align="center"' }
elsif ($is_right_justified) { $attributes .= 'align="right"' }
elsif ($is_left_justified) { $attributes .= 'align="left"' }
# this is the default:
# elsif ($is_left_justified) { $attributes .= 'align="left"' }
return
(InElement('td') || InElement('th') ? CloseHtmlEnvironmentUntil('tr') : '')

View File

@@ -1,6 +1,5 @@
#!/usr/bin/env perl
use strict;
use v5.10;
# ====================[ creoleaddition.pl ]====================

View File

@@ -1,6 +1,5 @@
#!/usr/bin/env perl
use strict;
use v5.10;
# ====================[ crossbar.pl ]====================

View File

@@ -2,7 +2,7 @@
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 3 of the License, or
# the Free Software Foundation; either version 2 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
@@ -11,10 +11,12 @@
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
# along with this program; if not, write to the
# Free Software Foundation, Inc.
# 59 Temple Place, Suite 330
# Boston, MA 02111-1307 USA
use strict;
use v5.10;
AddModuleDescription('crumbs.pl', 'List Parent Pages Extension');
@@ -25,8 +27,8 @@ $RuleOrder{\&CrumbsRule} = -10; # run before default rules!
sub CrumbsRule {
if (not (pos) # first!
and (($WikiLinks && /\G($LinkPattern\n)/cg)
or ($FreeLinks && /\G(\[\[$FreeLinkPattern\]\]\n)/cg))) {
and (($WikiLinks && /\G($LinkPattern\n)/cgo)
or ($FreeLinks && /\G(\[\[$FreeLinkPattern\]\]\n)/cgo))) {
my $oldpos = pos; # will be trashed below
my $cluster = FreeToNormal($2);
my %seen = ($cluster => 1);

View File

@@ -1,5 +1,4 @@
use strict;
use v5.10;
=head1 NAME

View File

@@ -2,7 +2,7 @@
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 3 of the License, or
# the Free Software Foundation; either version 2 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
@@ -11,10 +11,12 @@
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
# along with this program; if not, write to the
# Free Software Foundation, Inc.
# 59 Temple Place, Suite 330
# Boston, MA 02111-1307 USA
use strict;
use v5.10;
AddModuleDescription('csv.pl', 'Comments on Long Table Markup Extension');

View File

@@ -14,7 +14,6 @@
# along with this program. If not, see <http://www.gnu.org/licenses/>.
use strict;
use v5.10;
AddModuleDescription('dates.pl', 'Dates Extension');

View File

@@ -13,7 +13,6 @@
# this program. If not, see <http://www.gnu.org/licenses/>.
use strict;
use v5.10;
AddModuleDescription('delete-all.pl');

View File

@@ -2,7 +2,7 @@
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 3 of the License, or
# the Free Software Foundation; either version 2 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
@@ -11,10 +11,12 @@
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
# along with this program; if not, write to the
# Free Software Foundation, Inc.
# 59 Temple Place, Suite 330
# Boston, MA 02111-1307 USA
use strict;
use v5.10;
our ($q, $Now, %IndexHash, %Action, %Page, $OpenPageName, $FS, $BannedContent, $RcFile, $RcDefault, @MyAdminCode, $FullUrlPattern, $DeletedPage, $StrangeBannedContent);
@@ -130,14 +132,14 @@ sub DespamPage {
# from DoHistory()
my @revisions = sort {$b <=> $a} map { m|/([0-9]+).kp$|; $1; } GetKeepFiles($OpenPageName);
foreach my $revision (@revisions) {
my ($revisionPage, $rev) = GetTextRevision($revision, 1); # quiet
my ($text, $rev) = GetTextRevision($revision, 1); # quiet
if (not $rev) {
print ': ' . Ts('Cannot find revision %s.', $revision);
return;
} elsif (not DespamBannedContent($revisionPage->{text})) {
} elsif (not DespamBannedContent($text)) {
my $summary = Tss('Revert to revision %1: %2', $revision, $rule);
print ': ' . $summary;
Save($OpenPageName, $revisionPage->{text}, $summary) unless GetParam('debug', 0);
Save($OpenPageName, $text, $summary) unless GetParam('debug', 0);
return;
}
}

View File

@@ -14,7 +14,6 @@
# this program. If not, see <http://www.gnu.org/licenses/>.
use strict;
use v5.10;
AddModuleDescription('diff.pl', 'Diff Action Extension');
@@ -77,7 +76,8 @@ sub DoUnifiedDiff { # copied from DoDiff
RequestLockDir('diff') or return '';
WriteStringToFile($oldName, $_[0]);
WriteStringToFile($newName, $_[1]);
my $diff_out = decode_utf8(`diff -U 99999 -- \Q$oldName\E \Q$newName\E | tail -n +7`); # should be +4, but we always add extra line # TODO that workaround is ugly, fix it!
my $diff_out = `diff -U 99999 -- \Q$oldName\E \Q$newName\E | tail -n +7`; # should be +4, but we always add extra line # TODO that workaround is ugly, fix it!
utf8::decode($diff_out); # needs decoding
$diff_out =~ s/\n\K\\ No newline.*\n//g; # Get rid of common complaint.
ReleaseLockDir('diff');
# No need to unlink temp files--next diff will just overwrite.

View File

@@ -1,49 +0,0 @@
#! /usr/bin/perl
# Copyright (C) 20152017 Alex Schroeder <alex@gnu.org>
# This program is free software: you can redistribute it and/or modify it under
# the terms of the GNU General Public License as published by the Free Software
# Foundation, either version 3 of the License, or (at your option) any later
# version.
#
# This program is distributed in the hope that it will be useful, but WITHOUT
# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
# FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License along with
# this program. If not, see <http://www.gnu.org/licenses/>.
use strict;
use v5.10;
AddModuleDescription('ditaa.pl', 'Ditaa for Diagrams');
our ($q, $bol, @MyRules, @KnownLocks, $TempDir);
push (@MyRules, \&DitaaRule);
push(@KnownLocks, 'diagram');
sub DitaaRule {
if ($bol && m/\G&lt;diagram(\s+style=".*")?&gt;\n((.*\n)+)&lt;\/diagram&gt;/cg) {
return "MIME::Base64 not installed" unless eval { require MIME::Base64; };
my $style = $1;
my $map = UnquoteHtml($2);
RequestLockDir('diagram', undef, undef, 1);
WriteStringToFile("$TempDir/diagram.txt", $map);
$ENV{LANG}='en_US.UTF-8'; # Java needs Locale to match as well!
my $output = `ditaa "$TempDir/diagram.txt" "$TempDir/diagram.png"`;
my $image = '';
# not UTF-8 layer!
if (open(IN, '<', "$TempDir/diagram.png")) {
local $/ = undef; # Read complete files
$image = <IN>;
close IN;
}
ReleaseLockDir('diagram');
my $data = MIME::Base64::encode_base64($image);
my $url = "data:image/png;base64,$data";
return CloseHtmlEnvironments()
. "<div$style>" . $q->img({-src=>$url, -alt=>$map}) . "</div>";
}
return undef;
}

View File

@@ -13,7 +13,6 @@
# this program. If not, see <http://www.gnu.org/licenses/>.
use strict;
use v5.10;
AddModuleDescription('div-foo.pl', 'Div Foo Extension');

View File

@@ -14,7 +14,6 @@
# along with this program. If not, see <http://www.gnu.org/licenses/>.
use strict;
use v5.10;
AddModuleDescription('dojo.pl', 'Using Dojo Instead Of Wiki Markup');
@@ -30,7 +29,7 @@ $DojoTheme = 'tundra';
push (@MyRules, \&WysiwygRule);
sub WysiwygRule {
if (m/\G(&lt;.*?&gt;)/cg) {
if (m/\G(&lt;.*?&gt;)/gc) {
return $1 if substr($1,5,6) eq 'script'
or substr($1,4,6) eq 'script';
return UnquoteHtml($1);

View File

@@ -3,7 +3,7 @@
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 3 of the License, or
# the Free Software Foundation; either version 2 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
@@ -12,14 +12,16 @@
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
# along with this program; if not, write to the
# Free Software Foundation, Inc.
# 59 Temple Place, Suite 330
# Boston, MA 02111-1307 USA
# This module offers the user the additional possibility to
# edit a page by double-clicking on it. The user must have
# JavaScript enabled for this to work.
use strict;
use v5.10;
AddModuleDescription('doubleclick.pl', 'Doubleclick Extension');

View File

@@ -2,7 +2,7 @@
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 3 of the License, or
# the Free Software Foundation; either version 2 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
@@ -11,10 +11,12 @@
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
# along with this program; if not, write to the
# Free Software Foundation, Inc.
# 59 Temple Place, Suite 330
# Boston, MA 02111-1307 USA
use strict;
use v5.10;
AddModuleDescription('download.pl', 'Download Extension');
@@ -25,8 +27,8 @@ push( @MyRules, \&DownloadSupportRule );
# [[download:page name|alternate title]]
sub DownloadSupportRule {
if (m/\G(\[\[download:$FreeLinkPattern\|([^\]]+)\]\])/cg
or m!\G(\[\[download:$FreeLinkPattern\]\])!cg) {
if (m/\G(\[\[download:$FreeLinkPattern\|([^\]]+)\]\])/cog
or m!\G(\[\[download:$FreeLinkPattern\]\])!cog) {
Dirty($1);
print GetDownloadLink($2, undef, undef, $3);
return '';

View File

@@ -13,7 +13,6 @@
# this program. If not, see <http://www.gnu.org/licenses/>.
use strict;
use v5.10;
use File::Glob ':glob';
our ($DraftDir);
@@ -29,7 +28,7 @@ push(@MyInitVariables, \&DraftInit);
sub DraftInit {
if (GetParam('Draft', '')) {
SetParam('action', 'draft') ; # Draft button used
} elsif (IsFile("$DraftDir/" . GetParam('username', $q->remote_addr())) # draft exists
} elsif (-f "$DraftDir/" . GetParam('username', GetRemoteHost()) # draft exists
and $FooterNote !~ /action=draft/) { # take care of mod_perl persistence
$FooterNote = $q->p(ScriptLink('action=draft', T('Recover Draft'))) . $FooterNote;
}
@@ -39,7 +38,7 @@ $Action{draft} = \&DoDraft;
sub DoDraft {
my $id = shift;
my $draft = $DraftDir . '/' . GetParam('username', $q->remote_addr());
my $draft = $DraftDir . '/' . GetParam('username', GetRemoteHost());
if ($id) {
my $text = GetParam('text', '');
ReportError(T('No text to save'), '400 BAD REQUEST') unless $text;
@@ -47,11 +46,11 @@ sub DoDraft {
WriteStringToFile($draft, EncodePage(text=>$text, id=>$id));
SetParam('msg', T('Draft saved')); # invalidate cache
print GetHttpHeader('', T('Draft saved'), '204 NO CONTENT');
} elsif (IsFile($draft)) {
my $data = ParseData(ReadFileOrDie($draft));
Unlink($draft);
} elsif (-f $draft) {
my %data = ParseData(ReadFileOrDie($draft));
unlink ($draft);
$Message .= $q->p(T('Draft recovered'));
DoEdit($data->{id}, $data->{text}, 1);
DoEdit($data{id}, $data{text}, 1);
} else {
ReportError(T('No draft available to recover'), '404 NOT FOUND');
}
@@ -76,19 +75,22 @@ push(@MyMaintenance, \&DraftCleanup);
sub DraftFiles {
return map {
substr($_, length($DraftDir) + 1);
} Glob("$DraftDir/*"), Glob("$DraftDir/.*");
my $x = $_;
$x = substr($x, length($DraftDir) + 1);
utf8::decode($x);
$x;
} bsd_glob("$DraftDir/*"), bsd_glob("$DraftDir/.*");
}
sub DraftCleanup {
print '<p>' . T('Draft Cleanup');
foreach my $draft (DraftFiles()) {
next if $draft eq '.' or $draft eq '..';
my $ts = Modified("$DraftDir/$draft");
my $ts = (stat("$DraftDir/$draft"))[9];
if ($Now - $ts < 1209600) { # 14*24*60*60
print $q->br(), Tss("%1 was last modified %2 and was kept",
$draft, CalcTimeSince($Now - $ts));
} elsif (Unlink("$DraftDir/$draft")) {
} elsif (unlink("$DraftDir/$draft")) {
print $q->br(), Tss("%1 was last modified %2 and was deleted",
$draft, CalcTimeSince($Now - $ts));
} else {

View File

@@ -13,7 +13,6 @@
# this program. If not, see <http://www.gnu.org/licenses/>.
use strict;
use v5.10;
AddModuleDescription('duckduckgo-search.pl', 'Use DuckDuckGo For Searches');

View File

@@ -13,7 +13,6 @@
# this program. If not, see <http://www.gnu.org/licenses/>.
use strict;
use v5.10;
AddModuleDescription('dynamic-comments.pl', 'Dynamic Comments Extension');

View File

@@ -2,7 +2,7 @@
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 3 of the License, or
# the Free Software Foundation; either version 2 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
@@ -11,7 +11,10 @@
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
# along with this program; if not, write to the
# Free Software Foundation, Inc.
# 59 Temple Place, Suite 330
# Boston, MA 02111-1307 USA
# Makes the wiki logo depend on the current date.
#
@@ -25,7 +28,6 @@
#
use strict;
use v5.10;
AddModuleDescription('dynlogo.pl', 'Dynamic Logo');

View File

@@ -1,6 +1,6 @@
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 3 of the License, or
# the Free Software Foundation; either version 2 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
@@ -9,10 +9,12 @@
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
# along with this program; if not, write to the
# Free Software Foundation, Inc.
# 59 Temple Place, Suite 330
# Boston, MA 02111-1307 USA
use strict;
use v5.10;
AddModuleDescription('edit-assist.pl', 'Edit Assist Extension');

View File

@@ -14,11 +14,10 @@
# this program. If not, see <http://www.gnu.org/licenses/>.
use strict;
use v5.10;
AddModuleDescription('edit-cluster.pl', 'Edit Cluster Extension');
our ($q, $FS, $RcDefault, @RcDays, $RecentTop, $LastUpdate, $ShowAll);
our ($q, $FS, $RcDefault, @RcDays, $RecentTop, $LastUpdate);
our $EditCluster = 'EditCluster';
@@ -34,7 +33,7 @@ sub GetRc {
$changetime{$pagename} = $ts;
}
my $date = '';
my $all = GetParam('all', $ShowAll);
my $all = GetParam('all', 0);
my ($idOnly, $userOnly, $hostOnly, $clusterOnly, $filterOnly, $match, $lang) =
map { GetParam($_, ''); }
('rcidonly', 'rcuseronly', 'rchostonly', 'rcclusteronly',
@@ -128,7 +127,7 @@ sub EditClusterNewRcHeader {
$action = "action=rc$action";
}
my $days = GetParam('days', $RcDefault);
my $all = GetParam('all', $ShowAll);
my $all = GetParam('all', 0);
my @menu;
if ($all) {
push(@menu, ScriptLink("$action;days=$days;all=0",

Some files were not shown because too many files have changed in this diff Show More