forked from github/kensanata.oddmuse
Compare commits
88 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
f10dde33c8 | ||
|
|
a046436a50 | ||
|
|
bcb9721499 | ||
|
|
609f037345 | ||
|
|
4ed8c4fb25 | ||
|
|
45ebd07cf4 | ||
|
|
51223c6297 | ||
|
|
08b7674ab4 | ||
|
|
a8780e75f5 | ||
|
|
dc43759ebd | ||
|
|
e8ba28bffe | ||
|
|
f3266288e1 | ||
|
|
8482c47383 | ||
|
|
1e4268597d | ||
|
|
dd05f824a8 | ||
|
|
6b2d119481 | ||
|
|
37bdb62db8 | ||
|
|
30c5c3798f | ||
|
|
0f55e3d59e | ||
|
|
60a5a8fcee | ||
|
|
598b5e06f6 | ||
|
|
f451e62d30 | ||
|
|
a41920a5fd | ||
|
|
e8683fdb02 | ||
|
|
f08a404bde | ||
|
|
e1f0d909c1 | ||
|
|
3ab606d96a | ||
|
|
93dc6b415f | ||
|
|
6d8314cb39 | ||
|
|
ce18377109 | ||
|
|
d4edb159ae | ||
|
|
16198f8784 | ||
|
|
03e08464bb | ||
|
|
7ca0f6172b | ||
|
|
276c1c2076 | ||
|
|
9c996cee04 | ||
|
|
6c813b8297 | ||
|
|
ec4cba6fb3 | ||
|
|
76c50674f5 | ||
|
|
a73a9e4a96 | ||
|
|
f27ec6c142 | ||
|
|
37c32783f3 | ||
|
|
f922c0ae9a | ||
|
|
b46fcb3c90 | ||
|
|
b885287ea2 | ||
|
|
67d68a370a | ||
|
|
ccef879ac1 | ||
|
|
e8b9708f40 | ||
|
|
d4f1e27cae | ||
|
|
b0a8e49975 | ||
|
|
9383adcba5 | ||
|
|
cde2d41dd1 | ||
|
|
6e5766f431 | ||
|
|
a2fe639a57 | ||
|
|
f452d99e2f | ||
|
|
49f0c6d200 | ||
|
|
f9efba3976 | ||
|
|
36ef964d0d | ||
|
|
eb4a4653a2 | ||
|
|
741601489f | ||
|
|
217055fab2 | ||
|
|
8f68442db1 | ||
|
|
b9d0c60080 | ||
|
|
2b2e45b952 | ||
|
|
dfc3555184 | ||
|
|
474798c5cd | ||
|
|
0a54f14a6f | ||
|
|
04cdf0be24 | ||
|
|
e531f9d569 | ||
|
|
4f6407fd38 | ||
|
|
3174e184f9 | ||
|
|
8d94a0a50f | ||
|
|
67650e3dc8 | ||
|
|
700d412a01 | ||
|
|
cd2b4d624e | ||
|
|
fdde88c98f | ||
|
|
f6c18b2ccd | ||
|
|
a7d9995db9 | ||
|
|
8d39c095ff | ||
|
|
cdecbef49a | ||
|
|
8fa4eed63d | ||
|
|
41ef3cb386 | ||
|
|
c11a196f8f | ||
|
|
de4ef6451f | ||
|
|
8ed24a11f8 | ||
|
|
17dbca2353 | ||
|
|
f73c8f66ce | ||
|
|
348f4bcf3b |
@@ -1,8 +0,0 @@
|
||||
.DS_Store
|
||||
oddmuse-1.*
|
||||
oddmuse-inkscape-1.*
|
||||
*.patch
|
||||
*.patch.gz
|
||||
*.diff
|
||||
*.diff.gz
|
||||
test-data
|
||||
7
.gitignore
vendored
Normal file
7
.gitignore
vendored
Normal file
@@ -0,0 +1,7 @@
|
||||
*~
|
||||
/build/
|
||||
\#*\#
|
||||
/test-data
|
||||
/Mac/pkg/
|
||||
*.dmg
|
||||
*.pkg
|
||||
@@ -1 +0,0 @@
|
||||
pkg
|
||||
55
Makefile
55
Makefile
@@ -1,23 +1,53 @@
|
||||
# The Makefile is only for developpers wanting to prepare the tarball.
|
||||
# Make sure the CVS keywords for the sed command on the next line are not expanded.
|
||||
|
||||
VERSION_NO=$(shell sed -n -e 's/^.*\$$Id: wiki\.pl,v \(1\.[0-9]*\).*$$/\1/p' wiki.pl | head -n 1)
|
||||
VERSION=oddmuse-$(VERSION_NO)
|
||||
UPLOADVERSION=oddmuse-inkscape-$(shell sed -n -e 's/^.*\$$Id: wikiupload,v \([0-9.]*\).*$$/\1/p' wikiupload)
|
||||
VERSION_NO=$(shell git describe --tags)
|
||||
TRANSLATIONS=$(wildcard modules/translations/[a-z]*-utf8.pl$)
|
||||
MODULES=$(wildcard modules/*.pl)
|
||||
BUILD=build/wiki.pl $(foreach file, $(notdir $(MODULES)) $(notdir $(TRANSLATIONS)), build/$(file))
|
||||
|
||||
# PREPARE/BUILD: this creates copies of wiki.pl and all the modules
|
||||
# and translations in the build subdirectory. These copies all contain
|
||||
# a reference to the revision they were created from (git describe
|
||||
# --tags).
|
||||
|
||||
prepare: build $(BUILD)
|
||||
|
||||
build:
|
||||
mkdir -p build
|
||||
|
||||
build/wiki.pl: wiki.pl
|
||||
sed "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 ' . &/" < $< > $@
|
||||
|
||||
build/%-utf8.pl: modules/translations/%-utf8.pl
|
||||
sed "s/<a href=\"http:\/\/git.savannah.gnu.org\/cgit\/oddmuse.git\/tree\/modules\/translations\/\\(.*\\).pl\">\\(.*\\).pl<\/a>/<a href=\"http:\/\/git.savannah.gnu.org\/cgit\/oddmuse.git\/tree\/modules\/translations\/\\1.pl?id=$(VERSION_NO)\">\\1.pl<\/a> (for $(VERSION_NO))/" < $< > $@
|
||||
|
||||
# Currently oddtrans introduces encoding errors!
|
||||
|
||||
%-utf8.pl: wiki.pl $(MODULES)
|
||||
perl oddtrans -l $@ $^ > $@-new && mv $@-new $@
|
||||
|
||||
# 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
|
||||
sed "s/<a href=\"http:\/\/git.savannah.gnu.org\/cgit\/oddmuse.git\/tree\/modules\/\\(.*\\).pl\">\\(.*\\).pl<\/a>/<a href=\"http:\/\/git.savannah.gnu.org\/cgit\/oddmuse.git\/tree\/modules\/\\1.pl?id=$(VERSION_NO)\">\\1.pl<\/a> (for $(VERSION_NO))/" < $< > $@
|
||||
|
||||
|
||||
|
||||
|
||||
# UNTESTED/OBSOLETE: these targets have not been tested in a long time
|
||||
# and are potentially obsolete.
|
||||
VERSION=oddmuse-$(VERSION_NO)
|
||||
UPLOADVERSION=oddmuse-inkscape-$(VERSION_NO)
|
||||
INKSCAPE=GPL $(wildcard inkscape/*.py inkscape/*.inx inkscape/*.sh)
|
||||
PACKAGEMAKER=/Developer/Applications/Utilities/PackageMaker.app/Contents/MacOS/PackageMaker
|
||||
PWD=$(shell pwd)
|
||||
DIST=$(VERSION).tar.gz $(VERSION).tar.gz.sig \
|
||||
contrib/simple-install/$(VERSION)-simple.tar.gz \
|
||||
contrib/simple-install/$(VERSION)-simple.tar.gz.sig
|
||||
|
||||
# These targets no longer work are have not been verified in a long time.
|
||||
OLDDIST=$(VERSION).dmg $(VERSION).dmg.sig \
|
||||
$(VERSION).tar.gz $(VERSION).tar.gz.sig \
|
||||
$(VERSION).tgz $(VERSION).tgz.sig \
|
||||
$(UPLOADVERSION).tar.gz $(UPLOADVERSION).tar.gz.sig
|
||||
$(VERSION).tgz $(VERSION).tgz.sig
|
||||
PWD=$(shell pwd)
|
||||
|
||||
dist: $(DIST)
|
||||
|
||||
@@ -32,7 +62,7 @@ upload-text: new-utf8.pl
|
||||
contrib/simple-install/$(VERSION)-simple.tar.gz:
|
||||
cd contrib/simple-install && make $(VERSION)-simple.tar.gz
|
||||
|
||||
$(VERSION).tar.gz: README FDL GPL ChangeLog wiki.pl $(TRANSLATIONS) $(MODULES)
|
||||
$(VERSION).tar.gz: README FDL GPL ChangeLog wiki.pl $(TRANSLATIONS) $(MODULES) current.pl
|
||||
rm -rf $(VERSION)
|
||||
mkdir $(VERSION)
|
||||
cp $^ $(VERSION)
|
||||
@@ -104,9 +134,6 @@ $(VERSION).tgz: wiki.pl modules/creole.pl Mac/config Mac/wiki
|
||||
sudo chmod 775 Slack/var/www/cgi-bin/wiki
|
||||
cd Slack && tar czf ../$@ var install
|
||||
|
||||
%-utf8.pl: wiki.pl $(MODULES)
|
||||
perl oddtrans -l $@ $^ > $@-new && mv $@-new $@
|
||||
|
||||
update-translations: $(TRANSLATIONS)
|
||||
|
||||
upload-translations: always
|
||||
@@ -116,8 +143,6 @@ upload-translations: always
|
||||
"http://www.oddmuse.org/cgi-bin/oddmuse/raw/$$f" < $$f; \
|
||||
done
|
||||
|
||||
.PHONY: always
|
||||
|
||||
deb:
|
||||
equivs-build control
|
||||
|
||||
|
||||
@@ -1,2 +0,0 @@
|
||||
install
|
||||
var
|
||||
@@ -1,6 +1,6 @@
|
||||
#!/usr/bin/perl
|
||||
|
||||
# Copyright (C) 2010 Alex Schroeder <alex@gnu.org>
|
||||
# Copyright (C) 2010, 2012 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
|
||||
@@ -17,6 +17,7 @@
|
||||
package OddMuse;
|
||||
use URI;
|
||||
use LWP::UserAgent;
|
||||
use utf8;
|
||||
|
||||
# load Oddmuse core
|
||||
$RunCGI = 0;
|
||||
@@ -61,16 +62,16 @@ sub parse_blogs {
|
||||
return %cached_blogs if %cached_blogs;
|
||||
my @data = split(/\n/, GetRaw($src));
|
||||
my $url;
|
||||
my $name;
|
||||
my $paramref;
|
||||
foreach $_ (@data) {
|
||||
if (/^\[(.+)\]/) {
|
||||
$url = $1;
|
||||
$name = undef;
|
||||
} elsif (/^name *= *(.+)/) {
|
||||
$name = $1;
|
||||
$paramref = {};
|
||||
} elsif (/^([a-z_]+) *= *(.+)/) {
|
||||
$paramref->{$1} = $2;
|
||||
}
|
||||
if ($url && $name) {
|
||||
$cached_blogs{$url} = $name;
|
||||
if ($url && $paramref->{name}) {
|
||||
$cached_blogs{$url} = $paramref;
|
||||
}
|
||||
}
|
||||
return %cached_blogs;
|
||||
@@ -84,8 +85,16 @@ sub host_exists {
|
||||
}
|
||||
}
|
||||
|
||||
sub debug_url {
|
||||
my $url = $q->url(-path_info=>1) . "?debug=1;";
|
||||
$url .= join(";", map { $_ . "=" . GetParam($_) }
|
||||
qw(username confirmed candidate url));
|
||||
return $url;
|
||||
}
|
||||
|
||||
sub check_url {
|
||||
my $url = shift;
|
||||
print $q->p("Debug: url=$url") if GetParam("debug");
|
||||
my $frown = $q->img({-src=>"http://emacswiki.org/pics/smiles/sad.png",
|
||||
-alt=>":("});
|
||||
my $smile = $q->img({-src=>"http://emacswiki.org/pics/smiles/smile.png",
|
||||
@@ -97,26 +106,24 @@ sub check_url {
|
||||
$u = URI->new($url);
|
||||
eval {$u->host };
|
||||
}
|
||||
|
||||
# - not an url
|
||||
# - it's campaign wiki site
|
||||
# - no username
|
||||
# or read Feeds page and
|
||||
# - it's a duplicate
|
||||
# - it's a partial match: continue with confirmed=1
|
||||
# or read the list of alternatives from the url
|
||||
# - one of the feeds listed is known: continue with confirmed=2
|
||||
# - no feeds were listed: url is a feed or report it
|
||||
# - one feed was listed: try it
|
||||
# - some feeds were listed: pick one
|
||||
|
||||
if ($@) {
|
||||
# the prefixing of http:// above should make it really hard to reach this code
|
||||
print $q->p($q->a({-href=>$url}, $url) . qq{
|
||||
seems to be <strong>invalid</strong>. $frown Make sure you use something
|
||||
like the following: <tt>http://grognardia.blogspot.com/</tt>});
|
||||
} elsif (not GetParam('username', '')) {
|
||||
print $q->p(qq{As an anti-spam measure I'd really like you to <strong>provide a name</strong> for the log file. Sorry about that. $frown});
|
||||
} else {
|
||||
my %blogs = parse_blogs();
|
||||
my $duplicate = host_exists($u->host, %blogs);
|
||||
if ($duplicate
|
||||
&& !$blogs{$url}
|
||||
&& !GetParam('confirmed')) {
|
||||
print $q->p("We have a partial match: ",
|
||||
$q->a({-href=>$duplicate}, $duplicate));
|
||||
print GetFormStart();
|
||||
print $q->hidden('confirmed', 1);
|
||||
print $q->hidden('url', $url);
|
||||
print $q->submit('go', 'Proceed anyway!');
|
||||
print $q->end_form();
|
||||
} elsif ($url =~ /campaignwiki\.org/i) {
|
||||
print $q->p(qq{
|
||||
This looks <strong>familiar</strong>!
|
||||
@@ -124,17 +131,35 @@ I do not think that adding any of the wikis on this site is the right
|
||||
thing to do, though.});
|
||||
print $q->p(qq{Thanks for testing it. }
|
||||
. $q->img({-src=>"http://www.emacswiki.org/pics/grin.png"}));
|
||||
} elsif (not GetParam('username', '')) {
|
||||
print $q->p(qq{As an anti-spam measure I'd really like you to
|
||||
<strong>provide a name</strong> for the log file. Sorry about that. $frown});
|
||||
} else {
|
||||
my %blogs = parse_blogs();
|
||||
my $duplicate = host_exists($u->host, %blogs);
|
||||
if ($blogs{$url}) {
|
||||
print $q->p("We already list ",
|
||||
$q->a({-href=>$duplicate}, $duplicate));
|
||||
} elsif ($duplicate && !GetParam('confirmed')) {
|
||||
print $q->p("We have a partial match: ",
|
||||
$q->a({-href=>$duplicate}, $duplicate));
|
||||
print GetFormStart();
|
||||
print $q->hidden('confirmed', 1);
|
||||
print $q->hidden('url', $url);
|
||||
print $q->submit('go', 'Proceed anyway!');
|
||||
print $q->end_form();
|
||||
} else {
|
||||
my @alternatives = get_feeds($url, keys %blogs);
|
||||
if ($#alternatives > 0 && !GetParam('candidate')) {
|
||||
my ($status, @alternatives) = get_feeds($url, %blogs);
|
||||
if ($status eq 'known' && GetParam('confirmed') < 2) {
|
||||
print $q->p($q->a({-href=>$url},
|
||||
"The page you submitted")
|
||||
. " lists "
|
||||
. $q->a({-href=>$alternatives[0]},
|
||||
"a known feed") . ".");
|
||||
print GetFormStart();
|
||||
print $q->hidden('confirmed', 1);
|
||||
print $q->hidden('confirmed', 2);
|
||||
print $q->hidden('url', $url);
|
||||
print $q->p("You need to pick one of the candidates:");
|
||||
print $q->p(join($q->br(), map {
|
||||
$q->input({-type=>"radio", -name=>"candidate", -value=>$_},
|
||||
$q->a({-href=>$_}, QuoteHtml($_))) } @alternatives));
|
||||
print $q->submit('go', 'Submit');
|
||||
print $q->submit('go', 'Proceed anyway!');
|
||||
print $q->end_form();
|
||||
} elsif ($#alternatives < 0) {
|
||||
if (is_feed($url)) {
|
||||
@@ -143,20 +168,31 @@ thing to do, though.});
|
||||
print $q->p("Apparently " . $q->a({-href=>$url}, QuoteHtml($url))
|
||||
. " is not a feed and doesn't link to any feed. "
|
||||
. "There is nothing for me to add. " . $frown);
|
||||
print $q->p("If you feel like it, you could try to "
|
||||
. $q->a({-href=>debug_url()}, "debug")
|
||||
. " this.");
|
||||
}
|
||||
} elsif ($#alternatives == 0) {
|
||||
print $q->p($q->a({-href=>$url}, "The page you submitted")
|
||||
. " lists "
|
||||
. $q->a({-href=>$alternatives[0]},
|
||||
"one new feed")
|
||||
. ".");
|
||||
print GetFormStart();
|
||||
print $q->hidden('url', $alternatives[0]);
|
||||
print $q->submit('go', 'Take it!');
|
||||
print $q->end_form();
|
||||
print $q->p("If you feel like it, you could try to "
|
||||
. $q->a({-href=>debug_url()}, "debug")
|
||||
. " this.");
|
||||
} else {
|
||||
my $candidate = GetParam('candidate');
|
||||
$candidate = $alternatives[0] unless $candidate;
|
||||
if (is_feed($candidate)) {
|
||||
post_addition($candidate);
|
||||
} else {
|
||||
print $q->p($q->a({-href=>$candidate}, "The page you submitted")
|
||||
. " listed "
|
||||
. $q->a({-href=>$candidate}, QuoteHtml($candidate))
|
||||
. " as one of its feeds. "
|
||||
. "But it turns out that this is not a valid feed! "
|
||||
. "I can't add an invalid feed. " . $frown);
|
||||
}
|
||||
print GetFormStart();
|
||||
print $q->p("You need to pick one of the candidates:");
|
||||
print $q->p(join($q->br(), map {
|
||||
$q->input({-type=>"radio", -name=>"url", -value=>$_},
|
||||
$q->a({-href=>$_}, QuoteHtml($_))) } @alternatives));
|
||||
print $q->submit('go', 'Submit');
|
||||
print $q->end_form();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -172,23 +208,73 @@ sub is_feed {
|
||||
|
||||
sub get_feeds {
|
||||
my $url = shift;
|
||||
my %others = map { $_ => 1 } @_;
|
||||
my @links = GetRaw($url) =~ /<link\b *(.*?)>/g;
|
||||
my %others = @_;
|
||||
my $html = GetRaw($url);
|
||||
my @links = $html =~ /<link\b *(.*?)>/g;
|
||||
print $q->p("Debug: " . scalar(@links) . " links found") if GetParam("debug");
|
||||
print $q->pre($html) unless scalar(@links);
|
||||
print $q->p("Debug: no content returned") if GetParam("debug") and not $html;
|
||||
my @feeds;
|
||||
foreach my $link (@links) {
|
||||
my %link;
|
||||
foreach (split(/ /, lc($link))) {
|
||||
my ($attr, $val) = split(/=/, $_, 2);
|
||||
# strip quotes and garbage: "foo"/ -> foo
|
||||
my $to = index($val, substr($val, 0, 1), 1);
|
||||
$val = substr($val, 1, $to -1) if $to >= 0;
|
||||
$link{$attr} = $val;
|
||||
|
||||
print $q->p("Debug: $link")
|
||||
if GetParam("debug");
|
||||
|
||||
if ($link !~ /\brel=(['"])alternate\1/i) {
|
||||
print $q->p("Debug: missing rel='alternate'")
|
||||
if GetParam("debug");
|
||||
next;
|
||||
}
|
||||
next unless $link{rel} eq 'alternate';
|
||||
next unless $valid_content_type{$link{type}};
|
||||
push(@feeds, $link{href}) unless $others{$link{href}};
|
||||
|
||||
$link =~ /\btype=(['"])(.*?)\1/i;
|
||||
my $type = $2;
|
||||
if (not $valid_content_type{$type}) {
|
||||
print $q->p("Debug: type parameter is invalid ($type)")
|
||||
if GetParam("debug");
|
||||
next;
|
||||
}
|
||||
|
||||
$link =~ /\bhref=(['"])(.*?)\1/i;
|
||||
my $href = $2;
|
||||
# clean up blogspot urls and prefer atom format
|
||||
$href =~ s/\?alt=rss$//i if $href =~ /blogspot/i;
|
||||
if (not $href) {
|
||||
print $q->p("Debug: href missing")
|
||||
if GetParam("debug");
|
||||
next;
|
||||
}
|
||||
if ($others{$href}) {
|
||||
print $q->p("Debug: feed already known ($href)")
|
||||
if GetParam("debug");
|
||||
if ($q->param('confirmed') >= 2) {
|
||||
next;
|
||||
} else {
|
||||
# don't look for other alternatives!
|
||||
return 'known', $href;
|
||||
}
|
||||
}
|
||||
|
||||
push(@feeds, $href);
|
||||
}
|
||||
return @feeds;
|
||||
print $q->p("Debug: returning " . scalar(@feeds) . " links found")
|
||||
if GetParam("debug");
|
||||
return 'ok', @feeds;
|
||||
}
|
||||
|
||||
sub config {
|
||||
my %blogs = @_;
|
||||
my $result = qq{#! config file for the RPG Planet
|
||||
# format:
|
||||
# Feed URL in square brackets, followed by name = and the name of the feed
|
||||
};
|
||||
foreach my $url (sort {lc($blogs{$a}->{name}) cmp lc($blogs{$b}->{name})} keys %blogs) {
|
||||
$result .= "[$url]\n";
|
||||
$paramref = $blogs{$url};
|
||||
foreach my $key (sort keys %{$paramref}) {
|
||||
$result .= $key . " = " . $paramref->{$key} . "\n";
|
||||
}
|
||||
}
|
||||
return $result;
|
||||
}
|
||||
|
||||
sub post_addition {
|
||||
@@ -206,14 +292,9 @@ sub post_addition {
|
||||
$title = $final_url unless $title;
|
||||
print $q->p("Adding ",
|
||||
$q->a({-href=>$final_url}, $title));
|
||||
$blogs{$url} = $title;
|
||||
my $result = qq{#! config file for the RPG Planet
|
||||
# format:
|
||||
# Feed URL in square brackets, followed by name = and the name of the feed
|
||||
};
|
||||
foreach $url (sort {lc($blogs{$a}) cmp lc($blogs{$b})} keys %blogs) {
|
||||
$result .= "[$url]\nname = " . $blogs{$url} . "\n";
|
||||
}
|
||||
my %param = (name => $title);
|
||||
$blogs{$url} = \%param;
|
||||
my $result = config(%blogs);
|
||||
my $ua = LWP::UserAgent->new;
|
||||
my %params = (text => $result,
|
||||
title => $page,
|
||||
@@ -250,16 +331,18 @@ sub main {
|
||||
if ($q->path_info eq '/source') {
|
||||
seek DATA, 0, 0;
|
||||
print "Content-type: text/plain; charset=UTF-8\r\n\r\n", <DATA>;
|
||||
} elsif ($q->path_info eq '/test') {
|
||||
print "Content-type: text/plain; charset=UTF-8\r\n\r\n";
|
||||
print config(parse_blogs());
|
||||
} else {
|
||||
$UserGotoBar .= $q->a({-href=>$q->url . '/source'}, 'Source');
|
||||
print GetHeader('', 'Submit a new blog');
|
||||
print $q->start_div({-class=>'content index'});
|
||||
if (not GetParam('url')
|
||||
or not GetParam($HoneyPotOk)) {
|
||||
if (not GetParam('url')) {
|
||||
print $q->p("Debug: no url parameter provided.") if GetParam("debug");
|
||||
default();
|
||||
} else {
|
||||
SetParam('title', 'Feeds'); # required to trigger HoneyPotInspection()
|
||||
HoneyPotInspection();
|
||||
check_url(GetParam('url'));
|
||||
}
|
||||
print $q->p('Questions? Send mail to Alex Schröder <'
|
||||
|
||||
@@ -1,5 +0,0 @@
|
||||
current.pl
|
||||
FDL
|
||||
GPL
|
||||
*.tar.gz
|
||||
*.tar.gz.sig
|
||||
@@ -83,6 +83,10 @@ span.bar a {
|
||||
margin-right: 1ex;
|
||||
}
|
||||
|
||||
a img {
|
||||
border: none;
|
||||
}
|
||||
|
||||
/* search box in the top bar */
|
||||
|
||||
form.tiny, form.tiny p {
|
||||
@@ -145,9 +149,6 @@ div.refer {
|
||||
line-height: 13pt;
|
||||
}
|
||||
|
||||
div.refer a:first-child:before { content: "" }
|
||||
div.refer a:before { content: "• " }
|
||||
|
||||
div.message {
|
||||
background-color:#fee;
|
||||
color:#000;
|
||||
@@ -332,6 +333,7 @@ div.image span.caption {
|
||||
|
||||
.left { float:left; margin-right: 1em; }
|
||||
.right { float:right; margin-left: 1em; }
|
||||
.half a img { height: 50%; width: 50%; }
|
||||
div.left .left, div.right .right {
|
||||
float:none;
|
||||
}
|
||||
|
||||
@@ -16,6 +16,23 @@ body {
|
||||
font-size:12pt;
|
||||
}
|
||||
}
|
||||
|
||||
/* iPhone */
|
||||
|
||||
@media only screen and (max-device-width: 480px) {
|
||||
body { font-size: 200%; }
|
||||
}
|
||||
|
||||
/* iPad */
|
||||
|
||||
@media only screen and (min-device-width: 481px) and (max-device-width: 900px) {
|
||||
body { font-size: 150%; }
|
||||
textarea,input { font-size: 100%; }
|
||||
img { max-width: 550px !important; }
|
||||
}
|
||||
|
||||
|
||||
|
||||
div.browse {
|
||||
min-height: 3em;
|
||||
}
|
||||
@@ -41,6 +58,14 @@ div.commentshown {
|
||||
}
|
||||
div.commenthidden { display:none; }
|
||||
div.commentshown { display:block; }
|
||||
/* comment pages with username, homepage, and email subscription */
|
||||
.comment span { display: block; }
|
||||
.comment span label {
|
||||
display: inline-block; width: 10em;
|
||||
}
|
||||
input#mail, input#homepage, input#username {
|
||||
display: inline-block; width: 20em;
|
||||
}
|
||||
|
||||
h1 {
|
||||
font-weight: bold;
|
||||
@@ -63,9 +88,10 @@ h2 {
|
||||
font-weight: bold;
|
||||
color: white;
|
||||
background-color: #000;
|
||||
width: 98%;
|
||||
/* width: 98%; */
|
||||
font-size: 110%;
|
||||
padding: 0.2em;
|
||||
clear: both;
|
||||
}
|
||||
a:link {
|
||||
font-weight: bold;
|
||||
@@ -89,21 +115,47 @@ div.image { display: inline; margin: 1em; font-size: 90%; text-align: center; }
|
||||
.right { float: right; margin-left: 1em; }
|
||||
div.right .right { float: none; }
|
||||
div.left .left { float: none; }
|
||||
.caption { padding: 0 1em; }
|
||||
.license { font-size: small; }
|
||||
.aside {
|
||||
font-size: small;
|
||||
width: 30%;
|
||||
float: right;
|
||||
margin-left: 1em;
|
||||
margin-bottom: 1em;
|
||||
padding-left: 1em;
|
||||
}
|
||||
.aside img.smiley { height: 1em; }
|
||||
.narrow {
|
||||
width: 70%;
|
||||
}
|
||||
|
||||
a img { border: 1px solid #333; }
|
||||
.fit img { width: 80%; text-align: center; margin: 2em 8%; }
|
||||
.half img { width: 50%; height: 50%; text-align: center; margin: 2em 8%; }
|
||||
.noborder img { border: none; }
|
||||
.twenty img { max-width: 20em; }
|
||||
|
||||
em.underline { font-weight: bold; }
|
||||
.bar a { padding-right: 1em; }
|
||||
textarea { width:100%; }
|
||||
div.edit { padding-right: 1em; }
|
||||
img.logo { float: right; clear: right; border-style:none; }
|
||||
img.logo {
|
||||
float: right;
|
||||
clear: right;
|
||||
border-style:none;
|
||||
margin-left: 1em;
|
||||
margin-bottom: 1ex;
|
||||
border: 1px solid black;
|
||||
}
|
||||
div.diff { padding-left:5%; padding-right:5%; }
|
||||
div.old { background-color:#FFFFAF; }
|
||||
div.new { background-color:#CFFFCF; }
|
||||
div.message { background-color:#FEE; }
|
||||
/* div.message { background-color:#FEE; } */
|
||||
div.message {
|
||||
background-color: inherit;
|
||||
font-size: smaller;
|
||||
}
|
||||
table.history { border-style:none; }
|
||||
td.history { border-style:none; }
|
||||
span.result { font-size:larger; }
|
||||
@@ -127,11 +179,15 @@ div.rc hr { display: none; }
|
||||
|
||||
/* Tables */
|
||||
table.user {
|
||||
margin: 1em 4em;
|
||||
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;
|
||||
}
|
||||
table.user td, table.user th {
|
||||
border-style: none;
|
||||
padding:5px 10px;
|
||||
@@ -153,6 +209,12 @@ table.user td.mark { background-color:yellow; }
|
||||
}
|
||||
}
|
||||
|
||||
/* Help */
|
||||
|
||||
.edit table {
|
||||
font-size: small;
|
||||
}
|
||||
|
||||
/* Calendar */
|
||||
div.month { margin:0; padding:0; font-size:x-small; float:right; }
|
||||
div.content div.month { float:none; }
|
||||
@@ -164,7 +226,7 @@ div.month span.title a { font: inherit; }
|
||||
div.month a.local { font-weight: bold; }
|
||||
div.month a.local:link { color: #562; }
|
||||
div.month a.local:visited { color: #542; }
|
||||
div.month a.today { font-weight: bold; color: #fff; }
|
||||
div.month a.today { background-color: #faa; }
|
||||
div.month span.title a.local { font-weight: normal; color: #842; }
|
||||
@media print {
|
||||
div.month { display: none; }
|
||||
|
||||
@@ -38,6 +38,13 @@ li img, img.smiley, .noborder img {
|
||||
background:#fff;
|
||||
color:#000;
|
||||
}
|
||||
/* Google +1 */
|
||||
a#plus1 img {
|
||||
background-color: #fff;
|
||||
padding: 0;
|
||||
margin: 0;
|
||||
border: none;
|
||||
}
|
||||
|
||||
div.header img, div.footer img { border:0; padding:0; margin:0; }
|
||||
|
||||
|
||||
152
imap2wiki
Executable file
152
imap2wiki
Executable file
@@ -0,0 +1,152 @@
|
||||
#!/usr/bin/perl -w
|
||||
#
|
||||
# Copyright (C) 2012 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 Getopt::Std;
|
||||
use LWP::UserAgent;
|
||||
use Net::IMAP::Simple;
|
||||
use Email::Simple;
|
||||
use Email::MIME;
|
||||
use IO::Socket::SSL; # fail unless this is available
|
||||
|
||||
my $usage = "Usage:\n"
|
||||
. " imap2wiki TARGET SERVER PORT FROM TO MAIL_USER MAIL_PASSWORD \\\n"
|
||||
. " MAIL_USER MAIL_PASSWORD WIKI_USER [WIKI_PASSWORD]\n\n"
|
||||
. "TARGET is the base URL for the wiki.\n"
|
||||
. "SERVER is the IMAP server you are checking.\n"
|
||||
. "PORT is the port you are using.\n"
|
||||
. " (We assume that you must use SSL.)\n"
|
||||
. "FROM is sender you are looking for.\n"
|
||||
. "TO is recipient you are looking for.\n"
|
||||
. "MAIL_USER is the username to connect to the mail server.\n"
|
||||
. "MAIL_PASSWORD is the password to use for the mail server.\n"
|
||||
. "WIKI_USER is the username to use for the edit.\n"
|
||||
. "WIKI_PASSWORD is the password to use if required.\n"
|
||||
. "Example:\n"
|
||||
. " imap2wiki http://www.emacswiki.org/cgi-bin/test imap.gmail.com 993 \\\n"
|
||||
. " kensanata\@gmail.com kensanata+post\@gmail.com \\\n"
|
||||
. " kensanata\@gmail.com '*secret*' \\\n"
|
||||
. " Alex test\n\n";
|
||||
|
||||
sub UrlEncode {
|
||||
my $str = shift;
|
||||
return '' unless $str;
|
||||
my @letters = split(//, $str);
|
||||
my @safe = ('a' .. 'z', 'A' .. 'Z', '0' .. '9', '-', '_', '.', '!',
|
||||
'~', '*', "'", '(', ')', '#');
|
||||
foreach my $letter (@letters) {
|
||||
my $pattern = quotemeta($letter);
|
||||
if (not grep(/$pattern/, @safe)) {
|
||||
$letter = sprintf("%%%02x", ord($letter));
|
||||
}
|
||||
}
|
||||
return join('', @letters);
|
||||
}
|
||||
|
||||
sub GetRaw {
|
||||
my ($uri) = @_;
|
||||
my $ua = LWP::UserAgent->new;
|
||||
my $response = $ua->get($uri);
|
||||
return $response->content if $response->is_success;
|
||||
}
|
||||
|
||||
sub PostRaw {
|
||||
my ($uri, $id, $data, $user, $pwd) = @_;
|
||||
my $ua = LWP::UserAgent->new;
|
||||
my $summary;
|
||||
if ($data =~ /^#FILE (\S+) ?(\S+)?\n/) {
|
||||
$summary = 'file upload';
|
||||
}
|
||||
my $response = $ua->post($uri, {title=>$id, text=>$data, raw=>1,
|
||||
summary=>$summary,
|
||||
username=>$user, pwd=>$pwd});
|
||||
warn "POST $id failed: " . $response->status_line . "\n"
|
||||
unless $response->is_success;
|
||||
return $response->is_success;
|
||||
}
|
||||
|
||||
sub post {
|
||||
my ($target, $page, $data, $user, $pwd) = @_;
|
||||
$page =~ s/ /_/g;
|
||||
$page = UrlEncode ($page);
|
||||
return PostRaw($target, $page, $data, $user, $pwd);
|
||||
}
|
||||
|
||||
sub main {
|
||||
my ($target, $server, $port, $from, $to,
|
||||
$mail_user, $mail_pwd, $wiki_user, $wiki_pwd) = @ARGV;
|
||||
# all parameters except the wiki password are mandatory
|
||||
for my $arg ($target, $server, $port, $from, $to,
|
||||
$mail_user, $mail_pwd, $wiki_user) {
|
||||
die $usage unless $arg;
|
||||
}
|
||||
|
||||
my $imap = Net::IMAP::Simple->new($server, port=>$port, use_ssl=>1 )
|
||||
or die "Unable to connect to IMAP: $Net::IMAP::Simple::errstr\n";
|
||||
|
||||
if (not $imap->login($mail_user, $mail_pwd)) {
|
||||
print STDERR "Login failed: " . $imap->errstr . "\n";
|
||||
exit(64);
|
||||
}
|
||||
|
||||
my %result;
|
||||
my $rfrom = quotemeta($from);
|
||||
my $rto = quotemeta($to);
|
||||
|
||||
# go through the inbox and look for appropriate mails
|
||||
my $num = $imap->select('INBOX');
|
||||
for (my $i = 1; $i <= $num; $i++) {
|
||||
# looking at headers only
|
||||
my $email = Email::Simple->new(join '', @{ $imap->top($i) } );
|
||||
if ($email->header("From") =~ /$rfrom/io
|
||||
and $email->header("To") =~ /$rto/io) {
|
||||
my $subject = $email->header('Subject');
|
||||
my $n = 1;
|
||||
# fetch the body and parse the MIME stuff
|
||||
$email = Email::MIME->new(join '', @{ $imap->get($i) } );
|
||||
|
||||
$email->walk_parts(sub {
|
||||
my ($part) = @_;
|
||||
return if $part->subparts; # multipart
|
||||
|
||||
my ($pagename, $data);
|
||||
|
||||
warn $part->content_type;
|
||||
|
||||
if ($part->content_type =~ m[text/plain]i) {
|
||||
($pagename, $data) = ($subject, $part->body);
|
||||
} elsif ($part->content_type =~ m!(image/[a-z]+)!i) {
|
||||
($pagename, $data) = ($subject . " " . $n++,
|
||||
"#FILE " . $1 . "\n" . $part->body_raw);
|
||||
}
|
||||
|
||||
if ($pagename and $data) {
|
||||
warn "Posting $pagename\n";
|
||||
post($target, $pagename, $data, $wiki_user, $wiki_pwd)
|
||||
|| die "Posting aborted, INBOX not expunged\n";
|
||||
}
|
||||
} );
|
||||
|
||||
# mark as deleted
|
||||
$imap->delete($i);
|
||||
}
|
||||
}
|
||||
|
||||
# expunge messages that are marked for deletion
|
||||
$imap->quit;
|
||||
}
|
||||
|
||||
main();
|
||||
@@ -1 +0,0 @@
|
||||
.DS_Store
|
||||
@@ -55,7 +55,7 @@ sub DoAtomIntrospection {
|
||||
push(@types, @UploadTypes) if $UploadAllowed;
|
||||
my $upload = '<accept>' . join(', ', @types) . '</accept>';
|
||||
print <<EOT;
|
||||
<?xml version="1.0" encoding='$HttpCharset'?>
|
||||
<?xml version="1.0" encoding='UTF-8'?>
|
||||
<service xmlns="http://purl.org/atom/app#">
|
||||
<workspace title="Wiki" >
|
||||
<collection title="$SiteName" href="$ScriptName/atom/wiki">
|
||||
@@ -79,7 +79,7 @@ sub GetRcAtom {
|
||||
my $historyPrefix = QuoteHtml($ScriptName) . "?action=history;id=";
|
||||
my $limit = GetParam("rsslimit", 15); # Only take the first 15 entries
|
||||
my $count = 0;
|
||||
my $feed = qq{<?xml version="1.0" encoding="$HttpCharset"?>\n};
|
||||
my $feed = qq{<?xml version="1.0" encoding="UTF-8"?>\n};
|
||||
if ($RssStyleSheet =~ /\.(xslt?|xml)$/) {
|
||||
$feed .= qq{<?xml-stylesheet type="text/xml" href="$RssStyleSheet" ?>\n};
|
||||
} elsif ($RssStyleSheet) {
|
||||
|
||||
@@ -18,6 +18,8 @@
|
||||
|
||||
$ModulesDescription .= '<p><a href="http://git.savannah.gnu.org/cgit/oddmuse.git/tree/modules/canonical.pl">canonical.pl</a>, see <a href="http://www.oddmuse.org/cgi-bin/oddmuse/Canonical_Names">Canonical Names</a></p>';
|
||||
|
||||
use utf8;
|
||||
|
||||
*OldCanonicalResolveId = *ResolveId;
|
||||
*ResolveId = *NewCanonicalResolveId;
|
||||
|
||||
@@ -39,14 +41,9 @@ sub NewCanonicalResolveId {
|
||||
|
||||
# If the page AlexSchröder exists, [[alexschroder]] will link to it.
|
||||
|
||||
use utf8;
|
||||
use Encode;
|
||||
sub CanonicalName {
|
||||
my $str = shift;
|
||||
$DebugInfo .= ' ' . $str;
|
||||
$str = decode('utf-8', $str);
|
||||
$str =~ tr/äáàâëéèêïíìîöóòôüúùû/aaaaeeeeiiiioooouuuu/;
|
||||
$str = lc($str);
|
||||
$DebugInfo .= '->' . $str;
|
||||
return $str;
|
||||
}
|
||||
|
||||
@@ -29,25 +29,21 @@ sub DoConfig {
|
||||
\$EditPass = "";
|
||||
};
|
||||
my $source = GetRaw('http://www.emacswiki.org/scripts/current');
|
||||
foreach my $var qw($HomePage $MaxPost $HttpCharset $StyleSheet
|
||||
$StyleSheetPage $NotFoundPg $NewText $NewComment
|
||||
$EditAllowed $BannedHosts $BannedCanRead
|
||||
$BannedContent $WikiLinks $FreeLinks $BracketText
|
||||
$BracketWiki $NetworkFile $AllNetworkFiles
|
||||
$PermanentAnchors $InterMap $NearMap
|
||||
$RssInterwikiTranslate $SurgeProtection
|
||||
$SurgeProtectionTime $SurgeProtectionViews
|
||||
foreach my $var qw($HomePage $MaxPost $StyleSheet $StyleSheetPage $NotFoundPg
|
||||
$NewText $NewComment $EditAllowed $BannedHosts
|
||||
$BannedCanRead $BannedContent $WikiLinks $FreeLinks
|
||||
$BracketText $BracketWiki $NetworkFile $AllNetworkFiles
|
||||
$PermanentAnchors $InterMap $NearMap $RssInterwikiTranslate
|
||||
$SurgeProtection $SurgeProtectionTime $SurgeProtectionViews
|
||||
$DeletedPage $RCName @RcDays $RcDefault $KeepDays
|
||||
$KeepMajor $SummaryHours $SummaryDefaultLength
|
||||
$ShowEdits $UseLookup $RecentTop $RecentLink
|
||||
$PageCluster $InterWikiMoniker $SiteDescription
|
||||
$RssImageUrl $RssRights $RssExclude
|
||||
$RssCacheHours $RssStyleSheet $UploadAllowed
|
||||
@UploadTypes $EmbedWiki $FooterNote $EditNote
|
||||
$TopLinkBar @UserGotoBarPages $UserGotoBar
|
||||
$ValidatorLink $CommentsPrefix $HtmlHeaders
|
||||
$IndentLimit $LanguageLimit $JournalLimit
|
||||
$SisterSiteLogoUrl %SpecialDays %Smilies
|
||||
$KeepMajor $SummaryHours $SummaryDefaultLength $ShowEdits
|
||||
$UseLookup $RecentTop $RecentLink $PageCluster
|
||||
$InterWikiMoniker $SiteDescription $RssImageUrl $RssRights
|
||||
$RssExclude $RssCacheHours $RssStyleSheet $UploadAllowed
|
||||
@UploadTypes $EmbedWiki $FooterNote $EditNote $TopLinkBar
|
||||
@UserGotoBarPages $UserGotoBar $ValidatorLink
|
||||
$CommentsPrefix $HtmlHeaders $IndentLimit $LanguageLimit
|
||||
$JournalLimit $SisterSiteLogoUrl %SpecialDays %Smilies
|
||||
%Languages) {
|
||||
my $default = undef;
|
||||
my $re = quotemeta($var);
|
||||
|
||||
@@ -156,7 +156,7 @@ sub CreoleInit {
|
||||
# $FullUrlPattern = "((?:$UrlProtocols:|/)$UrlChars+)";
|
||||
|
||||
# Permit page authors to link to other pages having semicolons in their names.
|
||||
# my $LinkCharsSansZero = "-;,.()' _1-9A-Za-z\x80-\xff";
|
||||
# my $LinkCharsSansZero = "-;,.()' _1-9A-Za-z\x{0080}-\x{fffd}";
|
||||
# my $LinkChars = $LinkCharsSansZero.'0';
|
||||
# $FreeLinkPattern = "([$LinkCharsSansZero]|[$LinkChars][$LinkChars]+)";
|
||||
}
|
||||
@@ -623,8 +623,8 @@ sub CreoleRuleRecursive {
|
||||
elsif (m/\G\s+/cg) {
|
||||
$html .= ' ';
|
||||
}
|
||||
elsif ( m/\G([A-Za-z\x80-\xff]+([ \t]+[a-z\x80-\xff]+)*[ \t]+)/cg
|
||||
or m/\G([A-Za-z\x80-\xff]+)/cg
|
||||
elsif ( m/\G([A-Za-z\x{0080}-\x{fffd}]+([ \t]+[a-z\x{0080}-\x{fffd}]+)*[ \t]+)/cg
|
||||
or m/\G([A-Za-z\x{0080}-\x{fffd}]+)/cg
|
||||
or m/\G(\S)/cg) {
|
||||
$html .= $1; # multiple words but do not match http://foo
|
||||
}
|
||||
|
||||
@@ -1,21 +1,18 @@
|
||||
# Copyright (C) 2006 Alex Schroeder <alex@emacswiki.org>
|
||||
# Copyright (C) 2006, 2012 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 2 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 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.
|
||||
# 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
|
||||
# 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 File::Glob ':glob';
|
||||
use vars qw($DraftDir);
|
||||
|
||||
$DraftDir = $DataDir."/draft"; # directory for drafts
|
||||
@@ -70,15 +67,23 @@ sub DraftNewGetEditForm {
|
||||
|
||||
push(@MyMaintenance, \&DraftCleanup);
|
||||
|
||||
sub DraftFiles {
|
||||
return map {
|
||||
$_ = substr($_, length($DraftDir) + 1);
|
||||
utf8::decode($_);
|
||||
$_;
|
||||
} bsd_glob("$DraftDir/*"), bsd_glob("$DraftDir/.*");
|
||||
}
|
||||
|
||||
sub DraftCleanup {
|
||||
print '<p>' . T('Draft Cleanup');
|
||||
foreach my $draft (glob("$DraftDir/* $DraftDir/.*")) {
|
||||
next if $draft =~ m!/\.\.?$!;
|
||||
my $ts = (stat($draft))[9];
|
||||
foreach my $draft (DraftFiles()) {
|
||||
next if $draft eq '.' or $draft eq '..';
|
||||
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($draft)) {
|
||||
} elsif (unlink("$DraftDir/$draft")) {
|
||||
print $q->br(), Tss("%1 was last modified %2 and was deleted",
|
||||
$draft, CalcTimeSince($Now - $ts));
|
||||
} else {
|
||||
|
||||
@@ -36,29 +36,7 @@ function togglecomments (id) {
|
||||
} unless $HtmlHeaders =~ /commenthidden/; # mod_perl?
|
||||
}
|
||||
|
||||
sub SafeId {
|
||||
my $id = shift;
|
||||
my $regexp = "";
|
||||
$regexp = "|\xc3[\x80-\x96\x98-\xb6\xb8-\xff]|[\xc4-\xca].|\xcb[\x00-\xbf]"
|
||||
. "|\xcd[\xb0-\xbd\xbf-\xff]|[\xce-\xDF].|\xe0..|\xe1[\x00-\xbe]."
|
||||
. "|\xe1\xbf[\x00-\xbf]|\xe2\x80[\x8c\x8d]"
|
||||
if $HttpCharset eq 'UTF-8';
|
||||
# Unicode Codepoint UTF-8 encoding
|
||||
# [#xC0-#xD6] c3 80 - c3 96
|
||||
# [#xD8-#xF6] c3 98 - c3 b6
|
||||
# [#xF8-#x2FF] c3 b8 - cb bf
|
||||
# [#x370-#x37D] cd b0 - cd bd
|
||||
# [#x37F-#x1FFF] cd bf - e1 bf bf
|
||||
# [#x200C-#x200D] e2 80 8c - e2 80 8d
|
||||
# [#x2070-#x218F] e2 81 b0 - e2 86 8f -- FIXME \
|
||||
# [#x2C00-#x2FEF] e2 b0 80 - e2 bf af -- FIXME |
|
||||
# [#x3001-#xD7FF] e3 80 81 - ed 9f bf -- FIXME | these are missing
|
||||
# [#xF900-#xFDCF] ef a4 80 - ef b7 8f -- FIXME | in the regexp above
|
||||
# [#xFDF0-#xFFFD] ef b7 b0 - ef bf bd -- FIXME |
|
||||
# [#x10000-#xEFFFF] f0 90 80 80 - f3 af bf bf -- FIXME /
|
||||
$id = ":$id" unless $id =~ /^[:_A-Za-z]$regexp/;
|
||||
return join('', $id =~ m/([-.:_A-Za-z0-9]$regexp)/g);
|
||||
}
|
||||
my $num = 0;
|
||||
|
||||
*DynamicCommentsOldGetPageLink = *GetPageLink;
|
||||
*GetPageLink = *DynamicCommentsNewGetPageLink;
|
||||
@@ -70,10 +48,10 @@ sub DynamicCommentsNewGetPageLink {
|
||||
$title =~ s/_/ /g;
|
||||
my $page = PageHtml($id);
|
||||
if ($page) {
|
||||
my $safe = SafeId($id);
|
||||
return qq{<a href="javascript:togglecomments('$safe')">$title</a>}
|
||||
my $anchor = "id" . $num++;
|
||||
return qq{<a href="javascript:togglecomments('$anchor')">$title</a>}
|
||||
. '</p>' # close p before opening div
|
||||
. $q->div({-class=>commenthidden, -id=>$safe},
|
||||
. $q->div({-class=>commenthidden, -id=>$anchor},
|
||||
$page,
|
||||
$q->p(DynamicCommentsOldGetPageLink($id, T('Add Comment'))))
|
||||
. '<p>'; # open an empty p that will be closed in PrintAllPages
|
||||
|
||||
40
modules/fix-encoding.pl
Normal file
40
modules/fix-encoding.pl
Normal file
@@ -0,0 +1,40 @@
|
||||
# Copyright (C) 2012 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/>.
|
||||
|
||||
$ModulesDescription .= '<p><a href="http://git.savannah.gnu.org/cgit/oddmuse.git/tree/modules/fix-encoding.pl">fix-encoding.pl</a></p>';
|
||||
|
||||
$Action{'fix-encoding'} = \&FixEncoding;
|
||||
|
||||
sub FixEncoding {
|
||||
my $id = shift;
|
||||
ValidIdOrDie($id);
|
||||
RequestLockOrError();
|
||||
OpenPage($id);
|
||||
my $text = $Page{text};
|
||||
utf8::decode($text);
|
||||
Save($id, $text, 'fix encoding', 1);
|
||||
ReleaseLock();
|
||||
ReBrowsePage($id);
|
||||
}
|
||||
|
||||
push(@MyAdminCode, \&FixEncodingMenu);
|
||||
|
||||
sub FixEncodingMenu {
|
||||
my ($id, $menuref, $restref) = @_;
|
||||
if ($id) {
|
||||
push(@$menuref,
|
||||
ScriptLink('action=fix-encoding;id=' . UrlEncode($id), T('Fix page encoding')));
|
||||
}
|
||||
}
|
||||
@@ -147,8 +147,11 @@ sub GitCleanup {
|
||||
OpenPage($id);
|
||||
WriteStringToFile("$GitRepo/$id", $Page{text});
|
||||
}
|
||||
# commit the new state
|
||||
# run git!
|
||||
chdir($GitRepo); # important for all the git commands that follow!
|
||||
# add any new files
|
||||
GitRun('add', '.');
|
||||
# commit the new state
|
||||
GitRun('commit', '--quiet', '-a', '-m', 'maintenance job',
|
||||
"--author=Oddmuse <$GitMail>");
|
||||
}
|
||||
|
||||
@@ -32,6 +32,7 @@
|
||||
# img.InlineMath
|
||||
# img.DisplayMath
|
||||
|
||||
use File::Glob ':glob';
|
||||
use vars qw($LatexDir $LatexLinkDir $LatexExtendPath $LatexSingleDollars);
|
||||
|
||||
# One of the following options must be set correctly to the full path of
|
||||
@@ -172,7 +173,7 @@ sub MakeLaTeX {
|
||||
#setup rendering directory
|
||||
my $dir = "$LatexDir/$hash";
|
||||
if (-d $dir) {
|
||||
unlink (glob('$dir/*'));
|
||||
unlink (bsd_glob('$dir/*'));
|
||||
} else {
|
||||
mkdir($dir) or return "[Unable to create $dir]";
|
||||
}
|
||||
@@ -220,5 +221,3 @@ sub MakeLaTeX {
|
||||
rmdir ($dir);
|
||||
return $result;
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -22,7 +22,7 @@ push(@MyRules, \&LinkAllRule);
|
||||
$RuleOrder{\&LinkAllRule} = 1000;
|
||||
|
||||
sub LinkAllRule {
|
||||
if (/\G([A-Za-z\x80-\xff]+)/gc) {
|
||||
if (/\G([A-Za-z\x{0080}-\x{fffd}]+)/gc) {
|
||||
my $oldpos = pos;
|
||||
Dirty($1);
|
||||
# print the word, or the link to the word
|
||||
|
||||
@@ -18,24 +18,79 @@
|
||||
|
||||
$ModulesDescription .= '<p><a href="http://git.savannah.gnu.org/cgit/oddmuse.git/tree/modules/mac.pl">mac.pl</a>, see <a href="http://www.oddmuse.org/cgi-bin/oddmuse/Mac">Mac</a></p>';
|
||||
|
||||
use Encode;
|
||||
use Unicode::Normalize;
|
||||
|
||||
*OldAllPagesList = *AllPagesList;
|
||||
*AllPagesList = *NewAllPagesList;
|
||||
*OldMacAllPagesList = *AllPagesList;
|
||||
*AllPagesList = *NewMacAllPagesList;
|
||||
|
||||
sub NewAllPagesList {
|
||||
sub NewMacAllPagesList {
|
||||
$refresh = GetParam('refresh', 0);
|
||||
if ($IndexInit && !$refresh) {
|
||||
return @IndexList;
|
||||
}
|
||||
OldAllPagesList(@_);
|
||||
OldMacAllPagesList(@_);
|
||||
my @new = ();
|
||||
%IndexHash = ();
|
||||
foreach my $id (@IndexList) {
|
||||
$id = encode_utf8(NFC(decode_utf8($id)));
|
||||
$id = NFC($id);
|
||||
push(@new, $id);
|
||||
$IndexHash{$id} = 1;
|
||||
}
|
||||
@IndexList = @new;
|
||||
return @new;
|
||||
}
|
||||
|
||||
*OldMacGrepFiltered = *GrepFiltered;
|
||||
*GrepFiltered = *NewMacGrepFiltered;
|
||||
|
||||
sub NewMacGrepFiltered {
|
||||
my @pages = OldMacGrepFiltered(@_);
|
||||
foreach my $id (@pages) {
|
||||
$id = NFC($id);
|
||||
}
|
||||
return @pages;
|
||||
}
|
||||
|
||||
push(@MyInitVariables, \&MacFixEncoding);
|
||||
|
||||
sub MacFixEncoding {
|
||||
# disable grep if searching for non-ascii stuff:
|
||||
|
||||
# $ mkdir /tmp/dir
|
||||
# $ echo schroeder > /tmp/dir/schroeder
|
||||
# $ echo schröder > /tmp/dir/schröder
|
||||
# $ echo SCHRÖDER > /tmp/dir/SCHRÖDER-UP # don't use SCHRÖDER because of HFS
|
||||
# $ grep -rli schröder /tmp/dir
|
||||
# /tmp/dir/schröder
|
||||
# $ grep -rli SCHRÖDER /tmp/dir
|
||||
# /tmp/dir/schröder
|
||||
#
|
||||
# Why is grep not finding the upper case variant in the SCHRÖDER-UP
|
||||
# file?
|
||||
|
||||
$UseGrep = 0 if GetParam('search', '') =~ /[x{0080}-\x{fffd}]/;
|
||||
|
||||
# the rest is only necessary if using namespaces.pl
|
||||
return unless defined %Namespaces;
|
||||
while (my ($key, $value) = each %Namespaces) {
|
||||
delete $Namespaces{$key};
|
||||
utf8::decode($key);
|
||||
$key = NFC($key);
|
||||
$Namespaces{$key} = $NamespaceRoot . '/' . $key . '/';
|
||||
}
|
||||
while (my ($key, $value) = each %InterSite) {
|
||||
delete $InterSite{$key};
|
||||
utf8::decode($key);
|
||||
$key = NFC($key);
|
||||
$InterSite{$key} = $Namespaces{$key} if $Namespaces{$key};
|
||||
}
|
||||
}
|
||||
|
||||
# for drafts.pl
|
||||
|
||||
*OldMacDraftFiles = *DraftFiles;
|
||||
*DraftFiles = *NewMacDraftFiles;
|
||||
|
||||
sub NewMacDraftFiles {
|
||||
return map { NFC($_) } OldMacDraftFiles(@_);
|
||||
}
|
||||
|
||||
@@ -152,7 +152,7 @@ sub MarkdownQuoteHtml {
|
||||
$html =~ s/&/&/g;
|
||||
$html =~ s/</</g;
|
||||
# $html =~ s/>/>/g;
|
||||
$html =~ s/[\x00-\x08\x0b\x0c\x0e-\x1f]/ /g; # legal xml: #x9 | #xA | #xD | [#x20-#xD7FF] | [#xE000-#xFFFD] | [#x10000-#x10FFFF]
|
||||
$html =~ s/[\x00-\x08\x0b\x0c\x0e-\x1f]/ /g; # legal xml: #x9 | #xA | #xD | [#x20-#xD7FF] | [#xE000-#xFFFD] | [#x10000-#x10FFFD]
|
||||
|
||||
return $html;
|
||||
}
|
||||
@@ -198,8 +198,8 @@ sub MarkdownNearInit {
|
||||
sub DoWikiWords {
|
||||
|
||||
my $text = shift;
|
||||
my $WikiWord = '[A-Z]+[a-z\x80-\xff]+[A-Z][A-Za-z\x80-\xff]*';
|
||||
my $FreeLinkPattern = "([-,.()' _0-9A-Za-z\x80-\xff]+)";
|
||||
my $WikiWord = '[A-Z]+[a-z\x{0080}-\x{fffd}]+[A-Z][A-Za-z\x{0080}-\x{fffd}]*';
|
||||
my $FreeLinkPattern = "([-,.()' _0-9A-Za-z\x{0080}-\x{fffd}]+)";
|
||||
|
||||
if ($FreeLinks) {
|
||||
# FreeLinks
|
||||
@@ -299,7 +299,7 @@ sub CreateWikiLink {
|
||||
|
||||
sub UnescapeWikiWords {
|
||||
my $text = shift;
|
||||
my $WikiWord = '[A-Z]+[a-z\x80-\xff]+[A-Z][A-Za-z\x80-\xff]*';
|
||||
my $WikiWord = '[A-Z]+[a-z\x{0080}-\x{fffd}]+[A-Z][A-Za-z\x{0080}-\x{fffd}]*';
|
||||
|
||||
# Unescape escaped WikiWords
|
||||
$text =~ s/\\($WikiWord)/$1/g;
|
||||
@@ -379,7 +379,7 @@ sub NewEncodeCode {
|
||||
$text = OldEncodeCode($text);
|
||||
|
||||
# Protect Wiki Words
|
||||
my $WikiWord = '[A-Z]+[a-z\x80-\xff]+[A-Z][A-Za-z\x80-\xff]*';
|
||||
my $WikiWord = '[A-Z]+[a-z\x{0080}-\x{fffd}]+[A-Z][A-Za-z\x{0080}-\x{fffd}]*';
|
||||
$text =~ s!($WikiWord)!\\$1!gx;
|
||||
|
||||
return $text;
|
||||
@@ -471,7 +471,7 @@ sub MarkdownAddComment {
|
||||
|
||||
sub NewDoAnchors {
|
||||
my $text = shift;
|
||||
my $WikiWord = '[A-Z]+[a-z\x80-\xff]+[A-Z][A-Za-z\x80-\xff]*';
|
||||
my $WikiWord = '[A-Z]+[a-z\x{0080}-\x{fffd}]+[A-Z][A-Za-z\x{0080}-\x{fffd}]*';
|
||||
|
||||
return Markdown::_DoAnchors($text);
|
||||
}
|
||||
|
||||
@@ -80,9 +80,9 @@ $RuleOrder{\&MarkupRule} = 150;
|
||||
%MarkupLines = ('>' => 'pre',
|
||||
);
|
||||
|
||||
my $words = '([A-Za-z\x80-\xff][-%.,:;\'"!?0-9 A-Za-z\x80-\xff]*?)';
|
||||
my $words = '([A-Za-z\x{0080}-\x{fffd}][-%.,:;\'"!?0-9 A-Za-z\x{0080}-\x{fffd}]*?)';
|
||||
# zero-width look-ahead assertion to prevent km/h from counting
|
||||
my $noword = '(?=[^-0-9A-Za-z\x80-\xff]|$)';
|
||||
my $noword = '(?=[^-0-9A-Za-z\x{0080}-\x{fffd}]|$)';
|
||||
|
||||
my $markup_pairs_re = '';
|
||||
my $markup_forced_pairs_re = '';
|
||||
@@ -174,7 +174,7 @@ sub MarkupRule {
|
||||
return $MarkupSingles{UnquoteHtml($1)};
|
||||
} elsif ($MarkupPairs{'/'} and m|\G~/|gc) {
|
||||
return '~/'; # fix ~/elisp/ example
|
||||
} elsif ($MarkupPairs{'/'} and m|\G(/[-A-Za-z0-9\x80-\xff/]+/$words/)|gc) {
|
||||
} elsif ($MarkupPairs{'/'} and m|\G(/[-A-Za-z0-9\x{0080}-\x{fffd}/]+/$words/)|gc) {
|
||||
return $1; # fix /usr/share/lib/! example
|
||||
}
|
||||
# "foo
|
||||
|
||||
@@ -1,17 +1,16 @@
|
||||
# Copyright (C) 2004, 2005, 2006, 2007, 2008, 2009 Alex Schroeder <alex@gnu.org>
|
||||
# Copyright (C) 2004, 2005, 2006, 2007, 2008, 2009, 2012 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 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.
|
||||
# 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/>.
|
||||
# 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 Namespaces Extension
|
||||
|
||||
@@ -38,6 +37,7 @@ be changed using the C<$NamespacesSelf> option.
|
||||
|
||||
$ModulesDescription .= '<p><a href="http://git.savannah.gnu.org/cgit/oddmuse.git/tree/modules/namespaces.pl">namespaces.pl</a>, see <a href="http://www.oddmuse.org/cgi-bin/oddmuse/Namespaces_Extension">Namespaces Extension</a></p>';
|
||||
|
||||
use File::Glob ':glob';
|
||||
use vars qw($NamespacesMain $NamespacesSelf $NamespaceCurrent
|
||||
$NamespaceRoot $NamespaceSlashing @NamespaceParameters
|
||||
%Namespaces);
|
||||
@@ -80,7 +80,8 @@ sub NamespacesInitVariables {
|
||||
# Do this before changing the $DataDir and $ScriptName
|
||||
if (!$Monolithic and $UsePathInfo) {
|
||||
$Namespaces{$NamespacesMain} = $ScriptName . '/';
|
||||
foreach my $name (glob("$DataDir/*")) {
|
||||
foreach my $name (bsd_glob("$DataDir/*")) {
|
||||
utf8::decode($name);
|
||||
if (-d $name
|
||||
and $name =~ m|/($InterSitePattern)$|
|
||||
and $name ne $NamespacesMain
|
||||
@@ -92,19 +93,21 @@ sub NamespacesInitVariables {
|
||||
$NamespaceRoot = $ScriptName; # $ScriptName may be changed below
|
||||
$NamespaceCurrent = '';
|
||||
my $ns = GetParam('ns', '');
|
||||
if (not $ns and $UsePathInfo) {
|
||||
my $path_info = $q->path_info();
|
||||
utf8::decode($path_info);
|
||||
# make sure ordinary page names are not matched!
|
||||
if ($path_info =~ m|^/($InterSitePattern)(/.*)?|
|
||||
and ($2 or $q->keywords or NamespaceRequiredByParameter())) {
|
||||
$ns = $1;
|
||||
}
|
||||
}
|
||||
ReportError(Ts('%s is not a legal name for a namespace', $ns))
|
||||
if $ns and $ns !~ m/^($InterSitePattern)$/;
|
||||
if (($UsePathInfo
|
||||
# make sure ordinary page names are not matched!
|
||||
and $q->path_info() =~ m|^/($InterSitePattern)(/.*)?|
|
||||
and ($1 ne $NamespacesMain)
|
||||
and ($1 ne $NamespacesSelf)
|
||||
and ($2 or $q->keywords or NamespaceRequiredByParameter()))
|
||||
or
|
||||
($ns =~ m/^($InterSitePattern)$/
|
||||
and ($1 ne $NamespacesMain)
|
||||
and ($1 ne $NamespacesSelf))) {
|
||||
$NamespaceCurrent = $1;
|
||||
if ($ns
|
||||
and $ns ne $NamespacesMain
|
||||
and $ns ne $NamespacesSelf) {
|
||||
$NamespaceCurrent = $ns;
|
||||
# Change some stuff from the original InitVariables call:
|
||||
$SiteName .= ' ' . $NamespaceCurrent;
|
||||
$InterWikiMoniker = $NamespaceCurrent;
|
||||
@@ -115,7 +118,7 @@ sub NamespacesInitVariables {
|
||||
$TempDir = "$DataDir/temp";
|
||||
$LockDir = "$TempDir/lock";
|
||||
$NoEditFile = "$DataDir/noedit";
|
||||
$RcFile = "$DataDir/rc.log";
|
||||
$RcFile = "$DataDir/rc.log";
|
||||
$RcOldFile = "$DataDir/oldrc.log";
|
||||
$IndexFile = "$DataDir/pageidx";
|
||||
$VisitorFile = "$DataDir/visitors.log";
|
||||
@@ -133,8 +136,8 @@ sub NamespacesInitVariables {
|
||||
my ($dev,$ino,$mode,$nlink,$uid,$gid,$rdev,$size, $atime,$mtime,$ctime,$blksize,$blocks)
|
||||
= stat($IndexFile);
|
||||
$LastUpdate = $mtime;
|
||||
CreateDir($DataDir); # Create directory if it doesn't exist
|
||||
ReportError(Ts('Could not create %s', $DataDir) . ": $!", '500 INTERNAL SERVER ERROR')
|
||||
CreateDir($DataDir); # Create directory if it doesn't exist
|
||||
ReportError(Ts('Cannot create %s', $DataDir) . ": $!", '500 INTERNAL SERVER ERROR')
|
||||
unless -d $DataDir;
|
||||
}
|
||||
$Namespaces{$NamespacesSelf} = $ScriptName . '?';
|
||||
@@ -203,8 +206,8 @@ sub NewNamespaceGetRcLines { # starttime, hash of seen pages to use as a second
|
||||
# directory. This reduces the chances of getting different
|
||||
# results.
|
||||
foreach my $site (keys %InterSite) {
|
||||
if ($InterSite{$site} =~ m|^$ScriptName/([^/]*)|) {
|
||||
my $ns = $1 or next;
|
||||
if (substr($InterSite{$site}, 0, length($ScriptName)) eq $ScriptName) {
|
||||
my $ns = $site;
|
||||
my $file = "$DataDir/$ns/rc.log";
|
||||
push(@rcfiles, $file);
|
||||
$namespaces{$file} = $ns;
|
||||
@@ -217,7 +220,7 @@ sub NewNamespaceGetRcLines { # starttime, hash of seen pages to use as a second
|
||||
# starttime. If any rcfile exists with no timestamp before the
|
||||
# starttime, we need to open its rcoldfile.
|
||||
foreach my $file (@rcfiles) {
|
||||
open(F, $file);
|
||||
open(F, '<:encoding(UTF-8)', $file);
|
||||
my $line = <F>;
|
||||
my ($ts) = split(/$FS/o, $line); # the first timestamp in the regular rc file
|
||||
my @new;
|
||||
@@ -249,7 +252,7 @@ sub NewNamespaceGetRcLines { # starttime, hash of seen pages to use as a second
|
||||
return LatestChanges(@result);
|
||||
}
|
||||
|
||||
=head RSS feed
|
||||
=head2 RSS feed
|
||||
|
||||
When retrieving the RSS feed with the parameter full=1, one would
|
||||
expect the various items to contain the fully rendered HTML.
|
||||
|
||||
@@ -24,6 +24,8 @@
|
||||
# If you are running a multilingual site, then you should explicitly
|
||||
# load this file from your language-specific config file.
|
||||
|
||||
use utf8;
|
||||
|
||||
$ModulesDescription .= '<p><a href="http://git.savannah.gnu.org/cgit/oddmuse.git/tree/modules/national-days-de.pl">national-days-de.pl</a>, see <a href="http://www.oddmuse.org/cgi-bin/oddmuse/Special_Days">Special Days</a></p>';
|
||||
|
||||
%SpecialDays = (
|
||||
|
||||
@@ -16,6 +16,8 @@
|
||||
# 59 Temple Place, Suite 330
|
||||
# Boston, MA 02111-1307 USA
|
||||
|
||||
use utf8;
|
||||
|
||||
$ModulesDescription .= '<p><a href="http://git.savannah.gnu.org/cgit/oddmuse.git/tree/modules/national-days.pl">national-days.pl</a>, see <a href="http://www.oddmuse.org/cgi-bin/oddmuse/Special_Days">Special Days</a></p>';
|
||||
|
||||
%SpecialDays = (
|
||||
|
||||
@@ -18,6 +18,7 @@
|
||||
|
||||
$ModulesDescription .= '<p><a href="http://git.savannah.gnu.org/cgit/oddmuse.git/tree/modules/not-found-handler.pl">not-found-handler.pl</a>, see <a href="http://www.oddmuse.org/cgi-bin/oddmuse/404_Handler_Extension">404 Handler Extension</a></p>';
|
||||
|
||||
use File::Glob ':glob';
|
||||
use vars qw($NotFoundHandlerDir, $LinkFile, %LinkDb, $LinkDbInit);
|
||||
|
||||
$NotFoundHandlerDir = '/tmp/oddmuse/cache';
|
||||
@@ -29,7 +30,7 @@ $Action{clearcache} = \&DoClearCache;
|
||||
|
||||
sub DoClearCache {
|
||||
print GetHeader('', QuoteHtml(T('Clearing Cache')), '');
|
||||
unlink(glob("$NotFoundHandlerDir/*"));
|
||||
unlink(bsd_glob("$NotFoundHandlerDir/*"));
|
||||
print $q->p(T('Done.'));
|
||||
PrintFooter();
|
||||
}
|
||||
@@ -103,7 +104,7 @@ sub NewNotFoundHandlerSave {
|
||||
NotFoundHandlerCacheUpdate($id);
|
||||
} else {
|
||||
# unlink PageName, PageName.en, PageName.de, etc.
|
||||
unlink("$NotFoundHandlerDir/$id", glob("$NotFoundHandlerDir/$id.[a-z][a-z]"));
|
||||
unlink("$NotFoundHandlerDir/$id", bsd_glob("$NotFoundHandlerDir/$id.[a-z][a-z]"));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -128,7 +129,7 @@ sub NotFoundHandlerCacheUpdate {
|
||||
foreach my $source (keys %LinkDb) {
|
||||
warn "Examining $source\n";
|
||||
if (grep(/$target/, @{$LinkDb{$source}})) {
|
||||
unlink("$NotFoundHandlerDir/$source", glob("$NotFoundHandlerDir/$source.[a-z][a-z]"));
|
||||
unlink("$NotFoundHandlerDir/$source", bsd_glob("$NotFoundHandlerDir/$source.[a-z][a-z]"));
|
||||
warn "Unlinking $source\n";
|
||||
}
|
||||
}
|
||||
|
||||
@@ -77,7 +77,7 @@ sub NewQuestionaskerDoPost {
|
||||
or QuestionaskerException($id)) {
|
||||
print GetHeader('', T('Edit Denied'), undef, undef, '403 FORBIDDEN');
|
||||
print $q->p(T('You did not answer correctly.'));
|
||||
print $q->start_form, QuestionaskerGetQuestion(1),
|
||||
print GetFormStart(), QuestionaskerGetQuestion(1),
|
||||
(map { $q->hidden($_, '') }
|
||||
qw(title text oldtime summary recent_edit aftertext)), $q->end_form;
|
||||
PrintFooter();
|
||||
|
||||
@@ -230,7 +230,7 @@ sub NewReCaptchaDoPost {
|
||||
print GetHeader('', T('Edit Denied'), undef, undef, '403 FORBIDDEN');
|
||||
print $q->start_div({-class=>'error'});
|
||||
print $q->p(T('You did not answer correctly.'));
|
||||
print $q->start_form, ReCaptchaGetQuestion(1),
|
||||
print GetFormStart(), ReCaptchaGetQuestion(1),
|
||||
(map { $q->hidden($_, '') }
|
||||
qw(title text oldtime summary recent_edit aftertext)), $q->end_form;
|
||||
print $q->end_div();
|
||||
|
||||
@@ -178,8 +178,8 @@ sub UpdateReferers {
|
||||
}
|
||||
my $ua = LWP::UserAgent->new;
|
||||
my $response = $ua->get($referer);
|
||||
return unless $response->is_success and $response->content =~ /$self/;
|
||||
my $title = PageContentToTitle($response->content);
|
||||
return unless $response->is_success and $response->decoded_content =~ /$self/;
|
||||
my $title = PageContentToTitle($response->decoded_content);
|
||||
# starting with a timestamp makes sure that numerical comparisons still work!
|
||||
$Referers{$referer} = "$Now $title";
|
||||
return 1;
|
||||
|
||||
@@ -33,7 +33,7 @@ package OddMuse::Tokenize;
|
||||
|
||||
use vars qw($regexp);
|
||||
|
||||
$regexp = qr'[A-Za-z0-9_\x80-\xff]+';
|
||||
$regexp = qr'[A-Za-z0-9_\x{0080}-\x{fffd}]+';
|
||||
|
||||
sub new {
|
||||
my ($classname, @args) = @_;
|
||||
|
||||
@@ -33,7 +33,7 @@ push(@MyRules, \&SeTextRule);
|
||||
# If the length does not match, pos is reset and zero is returned so
|
||||
# that the remaining rules will be tested instead.
|
||||
|
||||
my $word = '([-A-Za-z\x80-\xff]+)';
|
||||
my $word = '([-A-Za-z\x{0080}-\x{fffd}]+)';
|
||||
sub SeTextRule {
|
||||
my $oldpos = pos;
|
||||
if ($bol && ((m/\G((.+?)[ \t]*\n(-+|=+)[ \t]*\n)/gc
|
||||
|
||||
@@ -5,7 +5,7 @@ use vars qw($FS $FreeLinkPattern $UrlProtocols $UrlChars $EndChars
|
||||
$UrlPattern $q);
|
||||
|
||||
$FS = "\x1e";
|
||||
$FreeLinkPattern = "([-,.()' _0-9A-Za-z\x80-\xff]+)";
|
||||
$FreeLinkPattern = "([-,.()' _0-9A-Za-z\x{0080}-\x{fffd}]+)";
|
||||
$UrlProtocols = 'http|https|ftp|afs|news|nntp|mid|cid|mailto|wais|prospero|telnet|gopher|irc';
|
||||
$UrlChars = '[-a-zA-Z0-9/@=+$_~*.,;:?!\'"()&#%]'; # see RFC 2396
|
||||
$EndChars = '[-a-zA-Z0-9/@=+$_~*]'; # no punctuation at the end of the url.
|
||||
|
||||
@@ -16,7 +16,7 @@
|
||||
# 59 Temple Place, Suite 330
|
||||
# Boston, MA 02111-1307 USA
|
||||
|
||||
$ModulesDescription .= '<p><a href="http://git.savannah.gnu.org/cgit/oddmuse.git/tree/modules/smiles.pl">smiles.pl</a></p>';
|
||||
$ModulesDescription .= '<p><a href="http://git.savannah.gnu.org/cgit/oddmuse.git/tree/modules/smiles.pl">smiles.pl</a>, see <a href="http://www.oddmuse.org/cgi-bin/oddmuse/Logo_And_Icons#Smilies">Logo And Icons</a></p>';
|
||||
|
||||
%Smilies = (
|
||||
':-?D' => 'http://www.emacswiki.org/pics/grin.png',
|
||||
|
||||
@@ -158,7 +158,7 @@ sub StaticHtml {
|
||||
<title>$SiteName: $id</title>
|
||||
<link type="text/css" rel="stylesheet" href="static.css" />
|
||||
<meta http-equiv="refresh" content="0; url=$target">
|
||||
<meta http-equiv="content-type" content="text/html; charset=$HttpCharset">
|
||||
<meta http-equiv="content-type" content="text/html; charset=UTF-8">
|
||||
</head>
|
||||
<body>
|
||||
<p>Redirected to <a href="$target">$1</a>.</p>
|
||||
@@ -173,7 +173,7 @@ EOT
|
||||
<head>
|
||||
<title>$SiteName: $id</title>
|
||||
<link type="text/css" rel="stylesheet" href="static.css" />
|
||||
<meta http-equiv="content-type" content="text/html; charset=$HttpCharset">
|
||||
<meta http-equiv="content-type" content="text/html; charset=UTF-8">
|
||||
</head>
|
||||
<body>
|
||||
EOT
|
||||
|
||||
@@ -173,7 +173,7 @@ sub StaticHtml {
|
||||
# Process the page
|
||||
local $Message = "";
|
||||
# encoding is left off, so fix it:
|
||||
print qq!<?xml version="1.0" encoding="$HttpCharset" ?>!;
|
||||
print qq!<?xml version="1.0" encoding="UTF-8" ?>!;
|
||||
print GetHeader($id, QuoteHtml($id), undef, "");
|
||||
print $q->start_div({-class=> 'content browse'});
|
||||
print PageHtml($id);
|
||||
|
||||
@@ -33,7 +33,7 @@ sub TablesLongRule {
|
||||
# a new row is started when a cell is repeated
|
||||
# if cells are missing, column spans are created (the first row
|
||||
# could use row spans...)
|
||||
if ($bol && m|\G\s*\n*\<table(/[A-Za-z\x80-\xff/]+)? +([A-Za-z\x80-\xff,;\/ ]+)\> *\n|cg) {
|
||||
if ($bol && m|\G\s*\n*\<table(/[A-Za-z\x{0080}-\x{fffd}/]+)? +([A-Za-z\x{0080}-\x{fffd},;\/ ]+)\> *\n|cg) {
|
||||
my $class = join(' ', split(m|/|, $1)); # leading / in $1 will make sure we have leading space
|
||||
Clean(CloseHtmlEnvironments() . "<table class=\"user long$class\">");
|
||||
# labels and their default class
|
||||
@@ -60,7 +60,7 @@ sub TablesLongRule {
|
||||
my $rowspan = '';
|
||||
my $first = 1;
|
||||
for my $line (@lines) {
|
||||
if ($line =~ m|^($regexp)/?([0-9]+)?/?([A-Za-z\x80-\xff/]+)?[:=] *(.*)|) { # regexp changes for other tables
|
||||
if ($line =~ m|^($regexp)/?([0-9]+)?/?([A-Za-z\x{0080}-\x{fffd}/]+)?[:=] *(.*)|) { # regexp changes for other tables
|
||||
$label = $1;
|
||||
$rowspan = $2;
|
||||
$class = join(' ', split(m|/|, $3)); # no leading / therefore no leading space
|
||||
|
||||
@@ -218,6 +218,7 @@ sub TagFind {
|
||||
my %page;
|
||||
foreach my $tag (@tags) {
|
||||
foreach my $id (split(/$FS/, $h{lc($tag)})) {
|
||||
utf8::decode($id);
|
||||
$page{$id} = 1;
|
||||
}
|
||||
}
|
||||
@@ -248,9 +249,7 @@ sub NewTagGrepFiltered { # called within a lock!
|
||||
}
|
||||
# filter out the tags from the search string
|
||||
$string = join(' ', grep(!/^-?tag:/, $string =~ /\"([^\"]+)\"|(\S+)/g));
|
||||
# if no query terms remain, just return the pages we found
|
||||
# return sort keys %page if $string eq '';
|
||||
# otherwise run grep
|
||||
# run the old code for any remaining search terms
|
||||
return OldTagGrepFiltered($string, sort keys %page);
|
||||
}
|
||||
|
||||
@@ -353,6 +352,12 @@ sub DoTagsReindex {
|
||||
$Page{text} =~ m/\[\[tag:$FreeLinkPattern\|([^]|]+)\]\]/g);
|
||||
next unless %tag;
|
||||
|
||||
# utf8::encode($id);
|
||||
# back to bytes for the following installation:
|
||||
# This is perl, v5.10.1 (*) built for i486-linux-gnu-thread-multi
|
||||
# (with 56 registered patches, see perl -V for more detail)
|
||||
# (FIXME: get rid of this call, or explain why no UTF-8 can be stored in %h)
|
||||
|
||||
# For each tag we list the files tagged. Add the current file for
|
||||
# all tags.
|
||||
foreach my $tag (keys %tag) {
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
# Copyright (C) 2006 Alex Schroeder <alex@emacswiki.org>
|
||||
# Copyright (C) 2006, 2012 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 2 of the License, or
|
||||
# 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,
|
||||
@@ -11,16 +11,14 @@
|
||||
# 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
|
||||
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
$ModulesDescription .= '<p><a href="http://git.savannah.gnu.org/cgit/oddmuse.git/tree/modules/tex.pl">tex.pl</a></p>';
|
||||
$ModulesDescription .= '<p><a href="http://git.savannah.gnu.org/cgit/oddmuse.git/tree/modules/tex.pl">tex.pl</a>, see <a href="http://www.oddmuse.org/cgi-bin/oddmuse/TeX_Extension">TeX Extension</a></p>';
|
||||
|
||||
use vars qw($TeXInit);
|
||||
use vars qw($TeXInit %Tex);
|
||||
use utf8;
|
||||
|
||||
my %h = qw( !` ¡ {\pounds} £ \pounds £ {\S} § \S § \"{} ¨ {\copyright} ©
|
||||
%Tex = qw( !` ¡ {\pounds} £ \pounds £ {\S} § \S § \"{} ¨ {\copyright} ©
|
||||
\copyright © $^a$ ª \={} ¯ $\pm$ ± \pm ± $^2$ ² $^3$ ³ \'{} ´ {\P} ¶
|
||||
\P ¶ $\cdot$ · \cdot · \c{} ¸ $^1$ ¹ $^o$ º ?` ¿ \`{A} À \`A À \'{A} Á
|
||||
\'A Á \^{A} Â \^A Â \~{A} Ã \~A Ã \"{A} Ä \"A Ä \k{A} Ą {\AA} Å \AA Å
|
||||
@@ -154,17 +152,27 @@ _0 ₀ _1 ₁ _2 ₂ _3 ₃ _4 ₄ _5 ₅ _6 ₆ _7 ₇ _8 ₈ _9 ₉ _= ₌ \~
|
||||
′ \varpropto ∝ \varrho ϱ \varsigma ς \vartheta ϑ \vartriangleleft ⊲
|
||||
\vartriangleright ⊳ \vdash ⊢ \vdots ⋮ \vee ∨ \veebar ⊻ \vert | \wedge
|
||||
∧ \wp ℘ \wr ≀ \xi ξ \zeta ζ \Bbb{N} ℕ \Bbb{P} ℙ \Bbb{R} ℝ \Bbb{Z} ℤ --
|
||||
– --- — ~ \mu μ \rho ρ \mathscr{I} ℐ \Smiley ☺ \blacksmiley ☻
|
||||
– --- — \mu μ \rho ρ \mathscr{I} ℐ \Smiley ☺ \blacksmiley ☻
|
||||
\Frowny ☹ \Letter ✉ \permil ‰ \registered ® \currency ¤ \dh ð \DH Ð
|
||||
\th þ \TH Þ \micro µ \lnot ¬ \ordfeminine ª \ordmasculine º \lambdabar
|
||||
ƛ \celsius ℃ \ldq “ \rdq ” \minus − \defs ≙ \llbracket 〚 \rrbracket 〛
|
||||
\ldata 《\rdata 》\glq ‚ \grq ‘ \glqq „ \"` „ \grqq “ \"' “ \flq ‹
|
||||
\ldata 《 \rdata 》 \glq ‚ \grq ‘ \glqq „ \"` „ \grqq “ \"' “ \flq ‹
|
||||
\frq › \flqq « \"< « \frqq » \"> » \- \textmu µ \textfractionsolidus
|
||||
⁄ \textbigcircle ⃝ \textmusicalnote ♪ \textdied ✝ \textcolonmonetary ₡
|
||||
\textwon ₩ \textnaira ₦ \textpeso ₱ \textlira ₤ \textrecipe ℞
|
||||
\textinterrobang ‽ \textpertenthousand ‱ \textbaht ฿ \textnumero №
|
||||
\textdiscount ⁒ \textestimated ℮ \textopenbullet ◦ \textlquill ⁅
|
||||
\textrquill ⁆ \textcircledP ℗ \textreferencemark ※ );
|
||||
$Tex{'~'} = ' ';
|
||||
|
||||
my $re = '(' . join('|', map {quotemeta} keys %h) . ')(\s|\b)';
|
||||
push(@MyMacros, sub {s/$re/$h{$1}/go});
|
||||
my $TexRe = '(' . join('|', map {quotemeta} sort { $b cmp $a } keys %Tex) . ')';
|
||||
$TexRe = qr{$TexRe};
|
||||
|
||||
push(@MyRules, \&TexRule);
|
||||
|
||||
sub TexRule {
|
||||
if (m/\G$TexRe/goc) {
|
||||
return $Tex{$1};
|
||||
}
|
||||
return undef;
|
||||
}
|
||||
|
||||
@@ -23,6 +23,7 @@
|
||||
|
||||
$ModulesDescription .= '<p><a href="http://git.savannah.gnu.org/cgit/oddmuse.git/tree/modules/throttle.pl">throttle.pl</a>, see <a href="http://www.oddmuse.org/cgi-bin/oddmuse/Limit_Number_Of_Instances_Running">Limit Number Of Instances Running</a></p>';
|
||||
|
||||
use File::Glob ':glob';
|
||||
use vars qw($InstanceThrottleDir $InstanceThrottleLimit);
|
||||
|
||||
$InstanceThrottleDir = $DataDir."/pids"; # directory for pid files
|
||||
@@ -47,7 +48,7 @@ sub NewDoBrowseRequest {
|
||||
|
||||
# limit the script to a maximum of $InstanceThrottleLimit instances
|
||||
sub DoInstanceThrottle {
|
||||
my @pids = glob($InstanceThrottleDir."/*");
|
||||
my @pids = bsd_glob($InstanceThrottleDir."/*");
|
||||
# Go over all pids: validate each pid by sending signal 0, unlink
|
||||
# pidfile if pid does not exist and return 0. Count the number of
|
||||
# zeros (= removed files = zombies) with grep.
|
||||
|
||||
256
modules/thumbs.pl
Normal file
256
modules/thumbs.pl
Normal file
@@ -0,0 +1,256 @@
|
||||
# Copyright (C) 2004, 2012 Alex Schroeder <alex@gnu.org>
|
||||
# Copyright (C) 2005 Rob Neild
|
||||
#
|
||||
# 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/>.
|
||||
|
||||
# Thumbnail (and improved image handling) module for OddMuse wiki
|
||||
# Conflicts with the "Image extension module"
|
||||
|
||||
require MIME::Base64;
|
||||
|
||||
use File::Path;
|
||||
|
||||
$ModulesDescription .= '<p><a href="http://git.savannah.gnu.org/cgit/oddmuse.git/tree/modules/thumbs.pl">thumbs.pl</a>, see <a href="http://www.oddmuse.org/cgi-bin/oddmuse/Image_Thumbnails">Image Thumbnails</a></p>';
|
||||
|
||||
# Tempoary directory to create thumbnails in
|
||||
$ThumbnailTempDir = '/tmp';
|
||||
|
||||
# Path and name of external program to use to create thumbnails. Only
|
||||
# ImageMagick 'convert' can be used. You may have to set the MAGICK_HOME
|
||||
# environment variable in your config file if you set it to
|
||||
# /usr/local/bin/convert and get the following error:
|
||||
# convert: no decode delegate for this image format
|
||||
# For your config file:
|
||||
# $ENV{MAGICK_HOME} = '/usr/local';
|
||||
$ThumbnailConvert = '/usr/bin/convert';
|
||||
|
||||
# Max size for a thumbnail. If larger size is specified just shows
|
||||
# regular image
|
||||
$ThumbnailMaxSize = 500;
|
||||
|
||||
# Default thumbnail size if non is specified
|
||||
$ThumbnailDefaultSize = 100;
|
||||
|
||||
# MIME types to create thumbnail for, all allowed if empty list
|
||||
@ThumbnailTypes = @UploadTypes;
|
||||
|
||||
# As well as using ALT, use TITLE. This enables comments to popup when
|
||||
# hovering mouse over thumbnail
|
||||
$ThumbnailImageUseTitle = 0;
|
||||
|
||||
$ThumbnailCacheDir = "oddmuse_thumbnail_cache";
|
||||
$ThumbnailCacheUrl = "/oddmuse_thumbnail_cache";
|
||||
|
||||
# Define new formatting rule "thumb" that inserts an auto generated thumbnail
|
||||
# Syntax is [[thumb:page name | etc. ]]
|
||||
|
||||
push(@MyRules, \&ThumbNailSupportRule);
|
||||
|
||||
sub ThumbNailSupportRule {
|
||||
my $result;
|
||||
my $RawMatch;
|
||||
|
||||
if (m!\G(\[\[thumb:$FreeLinkPattern(\|.*?)?\]\])!gc)
|
||||
{
|
||||
|
||||
$RawMatch = $1;
|
||||
|
||||
# Try and extract out all the options. They can be in any order, apart from comment at end
|
||||
|
||||
my $name = $2;
|
||||
|
||||
my $size="$ThumbnailDefaultSize"; # default size for thumbnail
|
||||
my $frame;
|
||||
my $comment; # default alignment for a non framed picture
|
||||
my $alignment_framed = 'tright'; # default alignment for a framed picture
|
||||
my $alignment;
|
||||
|
||||
my $params = $3 . '|';
|
||||
|
||||
if($params =~ s/\|([0-9]+)px\|/\|/) { $size = $1; }
|
||||
|
||||
if($params =~ s/\|thumb\|/\|/) { $frame = 'yes' ;}
|
||||
if($params =~ s/\|frame\|/\|/) { $frame = 'yes'; }
|
||||
|
||||
if ($params =~ s/\|none\|/\|/) { $alignment_framed= 'tnone'; }
|
||||
if ($params =~ s/\|right\|/\|/) { $alignment_framed= 'tright'; $alignment='floatright';}
|
||||
if ($params =~ s/\|left\|/\|/) { $alignment_framed= 'tleft'; $alignment='floatleft'; }
|
||||
|
||||
if ($params =~ m/\|(.+)\|$/) { $comment = $1; }
|
||||
|
||||
my $id = FreeToNormal($name);
|
||||
AllPagesList();
|
||||
|
||||
# if the page does exists
|
||||
|
||||
if ($IndexHash{$id})
|
||||
{
|
||||
|
||||
|
||||
if (! -e "$ThumbnailCacheDir/$id/$size")
|
||||
{
|
||||
GenerateThumbNail ($id, $size);
|
||||
}
|
||||
|
||||
|
||||
my %img_attribs;
|
||||
|
||||
my $action = "$ThumbnailCacheUrl/" . UrlEncode($id) . "/$size";
|
||||
|
||||
$img_attribs{'-src'} = $action;
|
||||
|
||||
if (defined $comment) {
|
||||
$img_attribs{'-alt'} ="$comment";
|
||||
$img_attribs{'-title'} = "$comment" if $ThumbnailImageUseTitle==1;
|
||||
}
|
||||
else { $img_attribs{'-alt'} = "$name"; }
|
||||
|
||||
|
||||
$img_attribs{'-class'} = 'upload';
|
||||
|
||||
$result = $q->img(\%img_attribs);
|
||||
$result = ScriptLink(UrlEncode($id) , $result, 'image');
|
||||
|
||||
if (defined $frame) {
|
||||
if (defined $comment) { $result = $result . $q->div({-class=>'thumbcaption'}, "$comment"); }
|
||||
|
||||
if ($size>0) {
|
||||
$result = $q->div({-style=>"width:" . ($size+2) . "px"}, $result);
|
||||
$result = $q->div({-class=>"thumb " . $alignment_framed}, $result);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (defined $alignment) { $result = $q->div({-class=>"$alignment" }, $result); }
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
# if the image does not exist
|
||||
$result = '[' . T('thumb') . ':' . $name . GetEditLink($id, '?', 1) . ']';
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
if (defined $result)
|
||||
{
|
||||
Dirty($RawMatch);
|
||||
print $result;
|
||||
|
||||
$result = '';
|
||||
}
|
||||
|
||||
return $result;
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
# define new action "thumbnail" that actually does the on fly generation of the image
|
||||
# thumbnails are put into the file so they only need be generated once
|
||||
# we also store the size of thumbnail so that can be used in the markup
|
||||
|
||||
# if we get passed a size of zero then all we need to do is check whether we have the image size stored in thumbnail_0
|
||||
# this enbles markup for non-thumbnail images better
|
||||
|
||||
|
||||
sub GenerateThumbNail {
|
||||
my ($id, $size) = (@_);
|
||||
|
||||
ValidIdOrDie($id);
|
||||
|
||||
AllPagesList();
|
||||
|
||||
if (not $IndexHash{$id}) { ReportError(Ts('Error creating thumbnail from non existant page %s.' , $id), '500 INTERNAL SERVER ERROR'); } # Page Doesn't exist,
|
||||
|
||||
|
||||
my $openpage = $OpenPageName; # remember the current page we are on
|
||||
|
||||
|
||||
RequestLockOrError();
|
||||
OpenPage($id);
|
||||
|
||||
# Parse out some data
|
||||
# Check MIME type supported
|
||||
# Check is a file
|
||||
|
||||
my ($text, $revision) = GetTextRevision(GetParam('revision', '')); # maybe revision reset!
|
||||
my ($type) = TextIsFile($text); # MIME type if an uploaded file
|
||||
my $data = substr($text, index($text, "\n") + 1);
|
||||
|
||||
if ($type)
|
||||
{
|
||||
my $regexp = quotemeta($type);
|
||||
|
||||
if (@ThumbnailTypes and not grep(/^$regexp$/, @ThumbnailTypes)) {
|
||||
ReportError(Ts('Can not create thumbnail for file type %s.' , $type), '415 UNSUPPORTED MEDIA TYPE');
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
ReportError(T('Can not create thumbnail for a text document'), '500 INTERNAL SERVER ERROR');
|
||||
}
|
||||
|
||||
|
||||
my $filename = $ThumbnailTempDir . "/odd" . $id . "_" . $size;
|
||||
|
||||
# Decode the original image to a temp file
|
||||
|
||||
open(FD, "> $filename") or ReportError(Ts("Could not open %s for writing whilst trying to save image before creating thumbnail. Check write permissions.",$filename), '500 INTERNAL SERVER ERROR');
|
||||
binmode(FD);
|
||||
print FD MIME::Base64::decode($data);
|
||||
close(FD);
|
||||
|
||||
eval { mkpath("$ThumbnailCacheDir/$id") };
|
||||
if ($@) {
|
||||
ReportError(Ts('Can not create path for thumbnail - %s', $@), '500 INTERNAL SERVER ERROR');
|
||||
}
|
||||
|
||||
# create the thumbnail
|
||||
|
||||
my $command = "$ThumbnailConvert '$filename' -verbose -resize ${size}x '$ThumbnailCacheDir/$id/$size' 2>&1";
|
||||
open (MESSAGE, '-|', $command)
|
||||
or ReportError(Tss("Failed to run %1 to create thumbnail: %2", $ThumbnailConvert, $!),
|
||||
'500 INTERNAL SERVER ERROR');
|
||||
|
||||
my $convert = <MESSAGE>;
|
||||
close(MESSAGE);
|
||||
|
||||
my $scaled_size_x;
|
||||
my $scaled_size_y;
|
||||
|
||||
my $thumbnail_data= '';
|
||||
|
||||
if($?) {
|
||||
ReportError(Ts("%s ran into an error", $ThumbnailConvert), '500 INTERNAL SERVER ERROR', undef,
|
||||
$q->pre($command . "\n" . $convert));
|
||||
} elsif($convert =~ m/=>(\d+)x(\d+)/) {
|
||||
$scaled_size_x = $1;
|
||||
$scaled_size_y = $2;
|
||||
} elsif (!$convert) {
|
||||
ReportError(Ts("%s produced no output", $ThumbnailConvert), '500 INTERNAL SERVER ERROR');
|
||||
} else {
|
||||
ReportError(Ts("Failed to parse %s.", $convert), '500 INTERNAL SERVER ERROR');
|
||||
}
|
||||
|
||||
unlink($filename);
|
||||
|
||||
# save tag to page
|
||||
#$Page{'thumbnail_' . $size} = '#FILE ' . $type . ' created=' . $Now . ' revision=' . $Page{'revision'} . ' size=' . $scaled_size_x . 'x' . $scaled_size_y . "\n" . $thumbnail_data;
|
||||
#SavePage();
|
||||
|
||||
ReleaseLock();
|
||||
|
||||
OpenPage($openpage); # restore original open page
|
||||
}
|
||||
@@ -25,7 +25,6 @@ use vars qw($TocHeaderText
|
||||
$TocClass
|
||||
$TocAutomatic
|
||||
$TocAnchorPrefix
|
||||
|
||||
$TocIsApplyingAutomaticRules);
|
||||
|
||||
=head2 $TocHeaderText
|
||||
@@ -140,7 +139,7 @@ that table. This is optional. If not specified, it defaults to "toc".
|
||||
sub TocRule {
|
||||
# <toc...> markup. This explicitly displays a table of contents at this point.
|
||||
if ($bol and
|
||||
m~\G<toc(/([A-Za-z\x80-\xff/]+))? # $1
|
||||
m~\G<toc(/([A-Za-z\x{0080}-\x{fffd}/]+))? # $1
|
||||
(\s+(?:header_text\s*=\s*)?"(.+?)")? # $3
|
||||
(\s+(?:class\s*=\s*)?"(.+?)")? # $5
|
||||
>[ \t]*(\n|$)~cgx) { # $7
|
||||
@@ -229,8 +228,11 @@ sub NewTocApplyRules {
|
||||
{
|
||||
local *STDOUT;
|
||||
open( STDOUT, '>', \$html) or die "Can't open memory file: $!";
|
||||
binmode STDOUT, ":utf8";
|
||||
($blocks, $flags) = OldTocApplyRules(@_);
|
||||
close STDOUT;
|
||||
utf8::decode($blocks);
|
||||
utf8::decode($html);
|
||||
}
|
||||
# If there are at least two HTML headers on this page, insert a table of
|
||||
# contents.
|
||||
|
||||
@@ -1,17 +1,19 @@
|
||||
# Copyright (C) 2008 Alex Schroeder <alex@gnu.org>
|
||||
# Copyright (C) 2008, 2012 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 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.
|
||||
# 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/>.
|
||||
# You should have received a copy of the GNU General Public License along with
|
||||
# this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
$ModulesDescription .= '<p><a href="http://git.savannah.gnu.org/cgit/oddmuse.git/tree/modules/translation-links.pl">translation-links.pl</a>, see <a href="http://www.oddmuse.org/cgi-bin/oddmuse/Translation_Links">Translation Links</a></p>';
|
||||
|
||||
=head1 Translation Links
|
||||
|
||||
@@ -76,7 +78,6 @@ sub TranslationLinkInit {
|
||||
$TranslationLinkPattern .= '|' if $FreeLinks or $WikiLinks;
|
||||
$TranslationLinkPattern .= $LinkPattern if $WikiLinks;
|
||||
$TranslationLinkPattern .= ')\]\]';
|
||||
my $text = GetPageContent(FreeToNormal(GetId()));
|
||||
%TranslationLinkData = ();
|
||||
}
|
||||
|
||||
|
||||
@@ -1 +0,0 @@
|
||||
*.wiki
|
||||
@@ -1,24 +1,3 @@
|
||||
# UTF-8 encoded Brazilian Portuguese language file for use with Oddmuse
|
||||
#
|
||||
# Copyright (c) 2003 Marcelo Toledo <rw@locked.org>.
|
||||
# Copyright (c) 2006, 2007 Hélio Nunes <dedalu@dedalu.art.br>.
|
||||
#
|
||||
# Permission is granted to copy, distribute and/or modify this
|
||||
# document under the terms of the GNU Free Documentation License,
|
||||
# Version 1.2 or any later version published by the Free Software
|
||||
# Foundation; with no Invariant Sections, no Front-Cover Texts, and no
|
||||
# Back-Cover Texts. A copy of the license could be found at:
|
||||
# http://www.gnu.org/licenses/fdl.txt.
|
||||
#
|
||||
# Installation:
|
||||
# =============
|
||||
#
|
||||
# Create a modules subdirectory in your data directory, and put the
|
||||
# file in there. It will be loaded automatically.
|
||||
#
|
||||
# This translation was last checked for Oddmuse version 1.753.
|
||||
#
|
||||
$ModulesDescription .= '<p>$Id: brazilian-portuguese-utf8.pl,v 1.14 2009/06/07 19:30:37 as Exp $</p>';
|
||||
%Translate = split(/\n/,<<END_OF_TRANSLATION);
|
||||
Include normal pages
|
||||
Incluir páginas normais
|
||||
@@ -92,6 +71,8 @@ Please go on to %s.
|
||||
Por favor, vá para %s.
|
||||
Updates since %s
|
||||
Atualizações desde %s
|
||||
up to %s
|
||||
|
||||
Updates in the last %s days
|
||||
Atualizações nos últimos %s dias
|
||||
Updates in the last %s day
|
||||
@@ -176,6 +157,8 @@ The two revisions are the same.
|
||||
As duas versões são idênticas.
|
||||
Editing not allowed for %s.
|
||||
Edição não permitida para %s.
|
||||
Rollback of %s would restore banned content.
|
||||
|
||||
Rollback to %s
|
||||
Desfazer para %s
|
||||
%s rolled back
|
||||
@@ -196,8 +179,6 @@ Unlock site
|
||||
Desbloquear site
|
||||
Lock site
|
||||
Bloquear site
|
||||
Install CSS
|
||||
Instalar CSS
|
||||
Unlock %s
|
||||
Desbloquear %s
|
||||
Lock %s
|
||||
@@ -320,6 +301,8 @@ Could not get %s lock
|
||||
Não foi possível conseguir o bloqueio %s
|
||||
The lock was created %s.
|
||||
O bloqueio foi criado %s.
|
||||
Maybe the user running this script is no longer allowed to remove the lock directory?
|
||||
|
||||
This operation may take several seconds...
|
||||
Essa operação pode demorar vários segundos...
|
||||
Forced unlock of %s lock.
|
||||
@@ -410,6 +393,8 @@ Filtro:
|
||||
(para %s)
|
||||
%s pages found.
|
||||
%s páginas encontradas.
|
||||
Malformed regular expression in %s
|
||||
|
||||
Replaced: %s
|
||||
Substituído: %s
|
||||
Search for: %s
|
||||
@@ -492,16 +477,12 @@ Displaying Wiki Version
|
||||
Mostrando a versão do Wiki
|
||||
Debugging Information
|
||||
|
||||
Inter links:
|
||||
Links inter-:
|
||||
Too many connections by %s
|
||||
Muitas conexões de %s
|
||||
Please do not fetch more than %1 pages in %2 seconds.
|
||||
Por favor, abra mais do que %1 páginas em %2 segundos.
|
||||
Check whether the web server can create the directory %s and whether it can create files in it.
|
||||
Verifique se o servidor web pode criar o diretório %s e se pode criar arquivos nele.
|
||||
Copy one of the following stylesheets to %s:
|
||||
Copie uma das seguintes folhas de estilo para %s:
|
||||
Deleting %s
|
||||
Excluindo %s
|
||||
Deleted %s
|
||||
@@ -618,6 +599,20 @@ Compilation for %s
|
||||
Compilação para %s
|
||||
Compilation tag is missing a regular expression.
|
||||
Falta expressão regular na etiqueta de compilação.
|
||||
Install CSS
|
||||
Instalar CSS
|
||||
Copy one of the following stylesheets to %s:
|
||||
Copie uma das seguintes folhas de estilo para %s:
|
||||
Reset
|
||||
|
||||
Extract all dates from the database
|
||||
|
||||
Dates
|
||||
|
||||
No dates found.
|
||||
|
||||
Inter links:
|
||||
Links inter-:
|
||||
List spammed pages
|
||||
Listar páginas com spam
|
||||
Despamming pages
|
||||
@@ -658,6 +653,14 @@ ordinary changes
|
||||
alterações normais
|
||||
Matching page names:
|
||||
Coincidindo com os nomes de página:
|
||||
no summary available
|
||||
|
||||
page was marked for deletion
|
||||
|
||||
Oddmuse
|
||||
|
||||
Email:
|
||||
|
||||
Could not find %1.html template in %2
|
||||
Não foi possível encontrar o modelo %1.html em %2
|
||||
Only Editors are allowed to see this hidden page.
|
||||
@@ -686,6 +689,14 @@ O modelo %s ou está vazio ou não existe.
|
||||
-- definido em %s
|
||||
Local names defined on %1: %2
|
||||
Nomes locais definidos em %1: %2
|
||||
Name:
|
||||
|
||||
URL:
|
||||
|
||||
Define Local Names
|
||||
|
||||
Define external redirect:
|
||||
|
||||
Locked Pages
|
||||
|
||||
Register for %s
|
||||
@@ -788,8 +799,6 @@ unsubscribe
|
||||
|
||||
subscribe
|
||||
|
||||
Email:
|
||||
|
||||
%s appears to be an invalid mail address
|
||||
|
||||
Your mail subscriptions
|
||||
@@ -826,6 +835,8 @@ You linked more than %s times to the same domain. It would seem that only a spam
|
||||
%s não é um nome legal para um espaço de nomes
|
||||
Namespaces
|
||||
|
||||
(create locally)
|
||||
(criar localmente)
|
||||
Getting page index file for %s.
|
||||
Obtendo arquivo de índice de página para %s.
|
||||
Near links:
|
||||
@@ -842,8 +853,6 @@ EditNearLinks
|
||||
EditarLinksPróximos
|
||||
The same page on other sites:
|
||||
A mesma página em outros sites:
|
||||
(create locally)
|
||||
(criar localmente)
|
||||
image
|
||||
imagem
|
||||
download
|
||||
@@ -858,6 +867,12 @@ Generating Link Database
|
||||
Gerando Banco de Dados de Link
|
||||
The 404 handler extension requires the link data extension (links.pl).
|
||||
A extensão 404 handler requer a extensão link data (links.pl)
|
||||
Make available offline
|
||||
|
||||
Offline
|
||||
|
||||
You are currently offline and what you requested is not part of the offline application. You need to be online to do this.
|
||||
|
||||
LocalMap
|
||||
MapaLocal
|
||||
No page id for action localmap
|
||||
@@ -872,20 +887,6 @@ Self-ban by %s
|
||||
Auto-banimento por %s
|
||||
You have banned your own IP.
|
||||
Você baniu seu próprio IP.
|
||||
OpenID Login
|
||||
|
||||
Your identity is saved in a cookie, if you have cookies enabled. Cookies may get lost if you connect from another machine, from another account, or using another software.
|
||||
|
||||
Your homepage is set to %s.
|
||||
|
||||
You have no homepage set.
|
||||
|
||||
Homepage:
|
||||
|
||||
Homepage is missing
|
||||
|
||||
OpenID error %s
|
||||
|
||||
Orphan List
|
||||
Lista de Órfãs
|
||||
Trail:
|
||||
@@ -918,6 +919,8 @@ No target wiki was specified in the config file.
|
||||
Não foi especificado um wiki alvo no arquivo de configuração.
|
||||
The target wiki was misconfigured.
|
||||
O wiki alvo está mal configurado.
|
||||
Upload is limited to %s bytes
|
||||
|
||||
You did not answer correctly.
|
||||
Você não respondeu corretamente à pergunta.
|
||||
To save this page you must answer this question:
|
||||
@@ -970,6 +973,10 @@ Static Copy
|
||||
Cópia Estática
|
||||
Back to %s
|
||||
Voltar para %s
|
||||
Edit image in the browser
|
||||
|
||||
Summary of your changes:
|
||||
|
||||
Copy to %1 succeeded: %2.
|
||||
Sucesso na cópia de %1: %2.
|
||||
Copy to %1 failed: %2.
|
||||
@@ -1008,12 +1015,40 @@ Too many instances. Only %s allowed.
|
||||
Muitas instâncias. Apenas %s permitidas.
|
||||
Please try again later. Perhaps somebody is running maintenance or doing a long search. Unfortunately the site has limited resources, and so we must ask you for a bit of patience.
|
||||
Por favor, tente novamente mais tarde. Talvez alguém esteja executando manutenção ou uma longa busca. Infelizmente o site tem recursos limitados e, por isso, pedimos um pouco de paciência.
|
||||
thumb
|
||||
|
||||
Error creating thumbnail from non existant page %s.
|
||||
|
||||
Can not create thumbnail for file type %s.
|
||||
|
||||
Can not create thumbnail for a text document
|
||||
|
||||
Could not open %s for writing whilst trying to save image before creating thumbnail. Check write permissions.
|
||||
|
||||
Can not create path for thumbnail - %s
|
||||
|
||||
Failed to run %1 to create thumbnail: %2
|
||||
|
||||
%s ran into an error
|
||||
|
||||
%s produced no output
|
||||
|
||||
Failed to parse %s.
|
||||
|
||||
Timezone
|
||||
|
||||
Pick your timezone:
|
||||
|
||||
Set
|
||||
|
||||
Contents
|
||||
Conteúdo
|
||||
Create a new page for today
|
||||
|
||||
Add Translation
|
||||
|
||||
Please provide a different page name for the translation.
|
||||
|
||||
Added translation: %1 (%2)
|
||||
|
||||
Translate %s
|
||||
@@ -1056,6 +1091,8 @@ Páginas Procuradas
|
||||
%s páginas
|
||||
%s, referenced from:
|
||||
%s, referenciada por:
|
||||
Web application for offline browsing
|
||||
|
||||
Upload of %s file
|
||||
Envio de arquivos %s
|
||||
Blog
|
||||
|
||||
@@ -1,24 +1,3 @@
|
||||
# UTF-8 encoded Bulgarian translation file for use with Oddmuse
|
||||
#
|
||||
# Copyright (c) 2004 Stanislav Traykov <stanislav@tortoises.org>
|
||||
# Copyright (c) 2003, 2004 Alex Schröder <alex@emacswiki.org>
|
||||
#
|
||||
# Permission is granted to copy, distribute and/or modify this
|
||||
# document under the terms of the GNU Free Documentation License,
|
||||
# Version 1.2 or any later version published by the Free Software
|
||||
# Foundation; with no Invariant Sections, no Front-Cover Texts, and no
|
||||
# Back-Cover Texts. A copy of the license could be found at:
|
||||
# http://www.gnu.org/licenses/fdl.txt .
|
||||
#
|
||||
# Installation:
|
||||
# =============
|
||||
#
|
||||
# Create a modules subdirectory in your data directory, and put the
|
||||
# file in there. It will be loaded automatically.
|
||||
#
|
||||
# This translation was updated for Oddmuse 1.354.
|
||||
#
|
||||
$ModulesDescription .= '<p>$Id: bulgarian-utf8.pl,v 1.11 2009/06/07 19:30:37 as Exp $</p>';
|
||||
%Translate = split(/\n/,<<END_OF_TRANSLATION);
|
||||
Include normal pages
|
||||
|
||||
@@ -92,6 +71,8 @@ Please go on to %s.
|
||||
Моля продължи на %s.
|
||||
Updates since %s
|
||||
Промени от %s насам
|
||||
up to %s
|
||||
|
||||
Updates in the last %s days
|
||||
Промени през последните %s дни
|
||||
Updates in the last %s day
|
||||
@@ -176,6 +157,8 @@ The two revisions are the same.
|
||||
|
||||
Editing not allowed for %s.
|
||||
Редакция на %s не е разрешена.
|
||||
Rollback of %s would restore banned content.
|
||||
|
||||
Rollback to %s
|
||||
Връщане до %s
|
||||
%s rolled back
|
||||
@@ -196,8 +179,6 @@ Unlock site
|
||||
|
||||
Lock site
|
||||
|
||||
Install CSS
|
||||
|
||||
Unlock %s
|
||||
|
||||
Lock %s
|
||||
@@ -320,6 +301,8 @@ Could not get %s lock
|
||||
Не може да се резервират изключителни права върху %s.
|
||||
The lock was created %s.
|
||||
|
||||
Maybe the user running this script is no longer allowed to remove the lock directory?
|
||||
|
||||
This operation may take several seconds...
|
||||
Тази операция може да потрае малко...
|
||||
Forced unlock of %s lock.
|
||||
@@ -410,6 +393,8 @@ Filter:
|
||||
(за %s)
|
||||
%s pages found.
|
||||
%s намерени страници.
|
||||
Malformed regular expression in %s
|
||||
|
||||
Replaced: %s
|
||||
Заместено: %s
|
||||
Search for: %s
|
||||
@@ -492,16 +477,12 @@ Displaying Wiki Version
|
||||
|
||||
Debugging Information
|
||||
|
||||
Inter links:
|
||||
Интер-линкове:
|
||||
Too many connections by %s
|
||||
Прекалено много връзки с %s
|
||||
Please do not fetch more than %1 pages in %2 seconds.
|
||||
|
||||
Check whether the web server can create the directory %s and whether it can create files in it.
|
||||
|
||||
Copy one of the following stylesheets to %s:
|
||||
|
||||
Deleting %s
|
||||
|
||||
Deleted %s
|
||||
@@ -618,6 +599,20 @@ Compilation for %s
|
||||
|
||||
Compilation tag is missing a regular expression.
|
||||
|
||||
Install CSS
|
||||
|
||||
Copy one of the following stylesheets to %s:
|
||||
|
||||
Reset
|
||||
|
||||
Extract all dates from the database
|
||||
|
||||
Dates
|
||||
|
||||
No dates found.
|
||||
|
||||
Inter links:
|
||||
Интер-линкове:
|
||||
List spammed pages
|
||||
|
||||
Despamming pages
|
||||
@@ -658,6 +653,14 @@ ordinary changes
|
||||
|
||||
Matching page names:
|
||||
|
||||
no summary available
|
||||
|
||||
page was marked for deletion
|
||||
|
||||
Oddmuse
|
||||
|
||||
Email:
|
||||
|
||||
Could not find %1.html template in %2
|
||||
|
||||
Only Editors are allowed to see this hidden page.
|
||||
@@ -686,6 +689,14 @@ The template %s is either empty or does not exist.
|
||||
|
||||
Local names defined on %1: %2
|
||||
|
||||
Name:
|
||||
|
||||
URL:
|
||||
|
||||
Define Local Names
|
||||
|
||||
Define external redirect:
|
||||
|
||||
Locked Pages
|
||||
|
||||
Register for %s
|
||||
@@ -788,8 +799,6 @@ unsubscribe
|
||||
|
||||
subscribe
|
||||
|
||||
Email:
|
||||
|
||||
%s appears to be an invalid mail address
|
||||
|
||||
Your mail subscriptions
|
||||
@@ -826,6 +835,8 @@ You linked more than %s times to the same domain. It would seem that only a spam
|
||||
|
||||
Namespaces
|
||||
|
||||
(create locally)
|
||||
|
||||
Getting page index file for %s.
|
||||
Получаване на индекс за %s.
|
||||
Near links:
|
||||
@@ -842,8 +853,6 @@ EditNearLinks
|
||||
Редакция на близки линкове
|
||||
The same page on other sites:
|
||||
Същата страница на други места:
|
||||
(create locally)
|
||||
|
||||
image
|
||||
|
||||
download
|
||||
@@ -858,6 +867,12 @@ Generating Link Database
|
||||
|
||||
The 404 handler extension requires the link data extension (links.pl).
|
||||
|
||||
Make available offline
|
||||
|
||||
Offline
|
||||
|
||||
You are currently offline and what you requested is not part of the offline application. You need to be online to do this.
|
||||
|
||||
LocalMap
|
||||
|
||||
No page id for action localmap
|
||||
@@ -872,20 +887,6 @@ Self-ban by %s
|
||||
|
||||
You have banned your own IP.
|
||||
|
||||
OpenID Login
|
||||
|
||||
Your identity is saved in a cookie, if you have cookies enabled. Cookies may get lost if you connect from another machine, from another account, or using another software.
|
||||
|
||||
Your homepage is set to %s.
|
||||
|
||||
You have no homepage set.
|
||||
|
||||
Homepage:
|
||||
|
||||
Homepage is missing
|
||||
|
||||
OpenID error %s
|
||||
|
||||
Orphan List
|
||||
|
||||
Trail:
|
||||
@@ -918,6 +919,8 @@ No target wiki was specified in the config file.
|
||||
|
||||
The target wiki was misconfigured.
|
||||
|
||||
Upload is limited to %s bytes
|
||||
|
||||
You did not answer correctly.
|
||||
|
||||
To save this page you must answer this question:
|
||||
@@ -970,6 +973,10 @@ Static Copy
|
||||
|
||||
Back to %s
|
||||
Обратно към %s
|
||||
Edit image in the browser
|
||||
|
||||
Summary of your changes:
|
||||
|
||||
Copy to %1 succeeded: %2.
|
||||
|
||||
Copy to %1 failed: %2.
|
||||
@@ -1008,12 +1015,40 @@ Too many instances. Only %s allowed.
|
||||
|
||||
Please try again later. Perhaps somebody is running maintenance or doing a long search. Unfortunately the site has limited resources, and so we must ask you for a bit of patience.
|
||||
|
||||
thumb
|
||||
|
||||
Error creating thumbnail from non existant page %s.
|
||||
|
||||
Can not create thumbnail for file type %s.
|
||||
|
||||
Can not create thumbnail for a text document
|
||||
|
||||
Could not open %s for writing whilst trying to save image before creating thumbnail. Check write permissions.
|
||||
|
||||
Can not create path for thumbnail - %s
|
||||
|
||||
Failed to run %1 to create thumbnail: %2
|
||||
|
||||
%s ran into an error
|
||||
|
||||
%s produced no output
|
||||
|
||||
Failed to parse %s.
|
||||
|
||||
Timezone
|
||||
|
||||
Pick your timezone:
|
||||
|
||||
Set
|
||||
|
||||
Contents
|
||||
|
||||
Create a new page for today
|
||||
|
||||
Add Translation
|
||||
|
||||
Please provide a different page name for the translation.
|
||||
|
||||
Added translation: %1 (%2)
|
||||
|
||||
Translate %s
|
||||
@@ -1056,6 +1091,8 @@ Wanted Pages
|
||||
|
||||
%s, referenced from:
|
||||
|
||||
Web application for offline browsing
|
||||
|
||||
Upload of %s file
|
||||
|
||||
Blog
|
||||
|
||||
@@ -1,24 +1,3 @@
|
||||
# UTF-8 encoded Traditional Chinese language file for use with Oddmuse
|
||||
#
|
||||
# Copyright (c) 2003, 2004 wctang <wctang@csie.nctu.edu.tw>
|
||||
# Copyright (c) 2007 Wei Ren Wang <weithenn@gmail.com>
|
||||
#
|
||||
# Permission is granted to copy, distribute and/or modify this
|
||||
# document under the terms of the GNU Free Documentation License,
|
||||
# Version 1.2 or any later version published by the Free Software
|
||||
# Foundation; with no Invariant Sections, no Front-Cover Texts, and no
|
||||
# Back-Cover Texts. A copy of the license could be found at:
|
||||
# http://www.gnu.org/licenses/fdl.txt.
|
||||
#
|
||||
# Installation:
|
||||
# =============
|
||||
#
|
||||
# Create a modules subdirectory in your data directory, and put the
|
||||
# file in there. It will be loaded automatically.
|
||||
#
|
||||
# This translation was last checked for Oddmuse version 1.504.
|
||||
#
|
||||
$ModulesDescription .= '<p>$Id: chinese-utf8.pl,v 1.12 2009/06/07 19:30:37 as Exp $</p>';
|
||||
%Translate = split(/\n/,<<END_OF_TRANSLATION);
|
||||
Include normal pages
|
||||
包含正常頁面
|
||||
@@ -92,6 +71,8 @@ Please go on to %s.
|
||||
請繼續前住 %s 。
|
||||
Updates since %s
|
||||
自 %s 以來的修改
|
||||
up to %s
|
||||
|
||||
Updates in the last %s days
|
||||
在 %s 天之內的更動
|
||||
Updates in the last %s day
|
||||
@@ -176,6 +157,8 @@ The two revisions are the same.
|
||||
二個版本相同
|
||||
Editing not allowed for %s.
|
||||
不允許編輯 %s 。
|
||||
Rollback of %s would restore banned content.
|
||||
|
||||
Rollback to %s
|
||||
回復至 %s
|
||||
%s rolled back
|
||||
@@ -196,8 +179,6 @@ Unlock site
|
||||
網站解鎖
|
||||
Lock site
|
||||
網站鎖定
|
||||
Install CSS
|
||||
安裝 CSS
|
||||
Unlock %s
|
||||
解鎖 %s
|
||||
Lock %s
|
||||
@@ -320,6 +301,8 @@ Could not get %s lock
|
||||
無法取得 %s 鎖定
|
||||
The lock was created %s.
|
||||
建立鎖定 %s
|
||||
Maybe the user running this script is no longer allowed to remove the lock directory?
|
||||
|
||||
This operation may take several seconds...
|
||||
這個動作可能要花幾秒…
|
||||
Forced unlock of %s lock.
|
||||
@@ -410,6 +393,8 @@ Filter:
|
||||
(列出 %s )
|
||||
%s pages found.
|
||||
找到 %s 個頁面。
|
||||
Malformed regular expression in %s
|
||||
|
||||
Replaced: %s
|
||||
取代:%s
|
||||
Search for: %s
|
||||
@@ -492,16 +477,12 @@ Displaying Wiki Version
|
||||
顯示 Wiki 主機相關套件版本
|
||||
Debugging Information
|
||||
|
||||
Inter links:
|
||||
內部連結:
|
||||
Too many connections by %s
|
||||
太多來自 %s 的連線
|
||||
Please do not fetch more than %1 pages in %2 seconds.
|
||||
請不要在 %2 秒內抓取超過 %1 頁的資料。
|
||||
Check whether the web server can create the directory %s and whether it can create files in it.
|
||||
請確認網站伺服器是否可建立 %s 目錄,並且在其中建立檔案。
|
||||
Copy one of the following stylesheets to %s:
|
||||
複製以下 CSS 模版至 %s
|
||||
Deleting %s
|
||||
正在刪除 %s
|
||||
Deleted %s
|
||||
@@ -618,6 +599,20 @@ Compilation for %s
|
||||
%s 的彙整
|
||||
Compilation tag is missing a regular expression.
|
||||
匯編的標記缺少一個正規表示式
|
||||
Install CSS
|
||||
安裝 CSS
|
||||
Copy one of the following stylesheets to %s:
|
||||
複製以下 CSS 模版至 %s
|
||||
Reset
|
||||
|
||||
Extract all dates from the database
|
||||
|
||||
Dates
|
||||
|
||||
No dates found.
|
||||
|
||||
Inter links:
|
||||
內部連結:
|
||||
List spammed pages
|
||||
列出 SPAM 頁面
|
||||
Despamming pages
|
||||
@@ -658,6 +653,14 @@ ordinary changes
|
||||
普通變更
|
||||
Matching page names:
|
||||
匹配頁面的名稱:
|
||||
no summary available
|
||||
|
||||
page was marked for deletion
|
||||
|
||||
Oddmuse
|
||||
|
||||
Email:
|
||||
|
||||
Could not find %1.html template in %2
|
||||
無法在 %2 找到 %1.html 的範本
|
||||
Only Editors are allowed to see this hidden page.
|
||||
@@ -686,6 +689,14 @@ The template %s is either empty or does not exist.
|
||||
-- 在 %s 中定義
|
||||
Local names defined on %1: %2
|
||||
定義本地名稱在 %1: %2
|
||||
Name:
|
||||
|
||||
URL:
|
||||
|
||||
Define Local Names
|
||||
|
||||
Define external redirect:
|
||||
|
||||
Locked Pages
|
||||
|
||||
Register for %s
|
||||
@@ -788,8 +799,6 @@ unsubscribe
|
||||
|
||||
subscribe
|
||||
|
||||
Email:
|
||||
|
||||
%s appears to be an invalid mail address
|
||||
|
||||
Your mail subscriptions
|
||||
@@ -826,6 +835,8 @@ You linked more than %s times to the same domain. It would seem that only a spam
|
||||
%s 不是一個正常的命名空間
|
||||
Namespaces
|
||||
|
||||
(create locally)
|
||||
(本地建立)
|
||||
Getting page index file for %s.
|
||||
自 %s 取得頁面索引資料。
|
||||
Near links:
|
||||
@@ -842,8 +853,6 @@ EditNearLinks
|
||||
編輯接近連結
|
||||
The same page on other sites:
|
||||
其他網站的相同頁面
|
||||
(create locally)
|
||||
(本地建立)
|
||||
image
|
||||
圖像
|
||||
download
|
||||
@@ -858,6 +867,12 @@ Generating Link Database
|
||||
產生連結資料庫
|
||||
The 404 handler extension requires the link data extension (links.pl).
|
||||
404 訊息,您需要安裝 (links.pl) 擴充模組
|
||||
Make available offline
|
||||
|
||||
Offline
|
||||
|
||||
You are currently offline and what you requested is not part of the offline application. You need to be online to do this.
|
||||
|
||||
LocalMap
|
||||
本地地圖
|
||||
No page id for action localmap
|
||||
@@ -872,20 +887,6 @@ Self-ban by %s
|
||||
被 %s 禁止
|
||||
You have banned your own IP.
|
||||
您禁止了自已的 IP Address
|
||||
OpenID Login
|
||||
|
||||
Your identity is saved in a cookie, if you have cookies enabled. Cookies may get lost if you connect from another machine, from another account, or using another software.
|
||||
|
||||
Your homepage is set to %s.
|
||||
|
||||
You have no homepage set.
|
||||
|
||||
Homepage:
|
||||
|
||||
Homepage is missing
|
||||
|
||||
OpenID error %s
|
||||
|
||||
Orphan List
|
||||
孤立頁面列表
|
||||
Trail:
|
||||
@@ -918,6 +919,8 @@ No target wiki was specified in the config file.
|
||||
設定檔案中沒有設定目標(Target) Wiki
|
||||
The target wiki was misconfigured.
|
||||
目標(Target) Wiki 設定錯誤
|
||||
Upload is limited to %s bytes
|
||||
|
||||
You did not answer correctly.
|
||||
您沒有回答正確的答案
|
||||
To save this page you must answer this question:
|
||||
@@ -970,6 +973,10 @@ Static Copy
|
||||
靜態頁面備份
|
||||
Back to %s
|
||||
返回 %s
|
||||
Edit image in the browser
|
||||
|
||||
Summary of your changes:
|
||||
|
||||
Copy to %1 succeeded: %2.
|
||||
從 %2 複製到 %1 成功
|
||||
Copy to %1 failed: %2.
|
||||
@@ -1008,12 +1015,40 @@ Too many instances. Only %s allowed.
|
||||
太多請求,只允許 %s
|
||||
Please try again later. Perhaps somebody is running maintenance or doing a long search. Unfortunately the site has limited resources, and so we must ask you for a bit of patience.
|
||||
系統忙碌中請稍後在試一次,可能有人正在執行維護動作或長期搜尋
|
||||
thumb
|
||||
|
||||
Error creating thumbnail from non existant page %s.
|
||||
|
||||
Can not create thumbnail for file type %s.
|
||||
|
||||
Can not create thumbnail for a text document
|
||||
|
||||
Could not open %s for writing whilst trying to save image before creating thumbnail. Check write permissions.
|
||||
|
||||
Can not create path for thumbnail - %s
|
||||
|
||||
Failed to run %1 to create thumbnail: %2
|
||||
|
||||
%s ran into an error
|
||||
|
||||
%s produced no output
|
||||
|
||||
Failed to parse %s.
|
||||
|
||||
Timezone
|
||||
|
||||
Pick your timezone:
|
||||
|
||||
Set
|
||||
|
||||
Contents
|
||||
內容
|
||||
Create a new page for today
|
||||
建立今日頁面
|
||||
Add Translation
|
||||
|
||||
Please provide a different page name for the translation.
|
||||
|
||||
Added translation: %1 (%2)
|
||||
|
||||
Translate %s
|
||||
@@ -1056,6 +1091,8 @@ Wanted Pages
|
||||
%s 頁面
|
||||
%s, referenced from:
|
||||
%s 引用自:
|
||||
Web application for offline browsing
|
||||
|
||||
Upload of %s file
|
||||
上傳 %s 檔案
|
||||
Blog
|
||||
|
||||
@@ -24,7 +24,8 @@
|
||||
#by wctang <wctang@csie.nctu.edu.tw> and using the tool cnmap
|
||||
#(http://search.cpan.org/~qjzhou/Encode-CNMap-0.32/bin/cnmap) by Qing-Jie Zhou <qjzhou@hotmail.com>.
|
||||
#
|
||||
$ModulesDescription .= '<p>$Id: chinese_cn-utf8.pl,v 1.11 2009/06/07 19:30:37 as Exp $</p>';
|
||||
use utf8;
|
||||
$ModulesDescription .= '<p><a href="http://git.savannah.gnu.org/cgit/oddmuse.git/tree/modules/translations/chinese_cn-utf8.pl">chinese_cn-utf8.pl</a>, see <a href="http://www.oddmuse.org/cgi-bin/oddmuse/Chinese">Chinese</a></p>';
|
||||
##############################################################
|
||||
# for those who want to use Chinese even for special pages
|
||||
# please uncomment the corresponding lines to use translated
|
||||
|
||||
@@ -24,7 +24,8 @@
|
||||
#
|
||||
# This translation was last checked for Oddmuse version 1.215.
|
||||
#
|
||||
$ModulesDescription .= '<p>$Id: dutch-utf8.pl,v 1.12 2011/05/17 13:24:13 as Exp $</p>';
|
||||
use utf8;
|
||||
$ModulesDescription .= '<p><a href="http://git.savannah.gnu.org/cgit/oddmuse.git/tree/modules/translations/dutch-utf8.pl">dutch-utf8.pl</a>, see <a href="http://www.oddmuse.org/cgi-bin/oddmuse/Dutch">Dutch</a></p>';
|
||||
%Translate = split(/\n/,<<END_OF_TRANSLATION);
|
||||
Include normal pages
|
||||
|
||||
|
||||
@@ -16,7 +16,8 @@
|
||||
# Create a modules subdirectory in your data directory, and put the
|
||||
# file in there. It will be loaded automatically.
|
||||
#
|
||||
$ModulesDescription .= '<p>$Id: finnish-utf8.pl,v 1.11 2009/06/07 19:30:37 as Exp $</p>';
|
||||
use utf8;
|
||||
$ModulesDescription .= '<p><a href="http://git.savannah.gnu.org/cgit/oddmuse.git/tree/modules/translations/finnish-utf8.pl">finnish-utf8.pl</a>, see <a href="http://www.oddmuse.org/cgi-bin/oddmuse/Finnish">Finnish</a></p>';
|
||||
%Translate = split(/\n/,<<END_OF_TRANSLATION);
|
||||
Include normal pages
|
||||
|
||||
|
||||
@@ -3,6 +3,7 @@
|
||||
# Copyright (c) 2003, 2005 Pierre Gaston
|
||||
# Copyright (c) 2004, 2005 Christophe Ducamp
|
||||
# Copyright (c) 2010 Alex Schroeder
|
||||
# Copyright (c) 2012 Aurélien Desbrières
|
||||
#
|
||||
# Permission is granted to copy, distribute and/or modify this
|
||||
# document under the terms of the GNU Free Documentation License,
|
||||
@@ -17,9 +18,12 @@
|
||||
# Create a modules subdirectory in your data directory, and put the
|
||||
# file in there. It will be loaded automatically.
|
||||
#
|
||||
# This translation was last checked for Oddmuse version 1.296.
|
||||
#
|
||||
$ModulesDescription .= '<p>$Id: french-utf8.pl,v 1.20 2011/02/05 12:29:07 as Exp $</p>';
|
||||
# This translation was last checked for Oddmuse 2.2.
|
||||
|
||||
use utf8;
|
||||
|
||||
$ModulesDescription .= '<p><a href="http://git.savannah.gnu.org/cgit/oddmuse.git/tree/modules/translations/french-utf8.pl">french-utf8.pl</a>, see <a href="http://www.oddmuse.org/cgi-bin/oddmuse/French">French</a></p>';
|
||||
|
||||
%Translate = split(/\n/,<<END_OF_TRANSLATION);
|
||||
Include normal pages
|
||||
Comprend les pages normales
|
||||
@@ -30,9 +34,9 @@ Se connecter
|
||||
Error
|
||||
Erreur
|
||||
%s calls
|
||||
|
||||
%s appel
|
||||
Could not create %s
|
||||
Création impossible de %s
|
||||
Création de %s impossible
|
||||
Invalid UserName %s: not saved.
|
||||
Nom d’utilisateur non valide %s : non sauvegardé.
|
||||
UserName must be 50 characters or less: not saved
|
||||
@@ -86,13 +90,13 @@ Page non valide %s
|
||||
Too many redirections
|
||||
Trop de redirections
|
||||
No redirection for old revisions
|
||||
Pas de redirection pour les versions ancienne
|
||||
Pas de redirection pour les versions anciennes
|
||||
Invalid link pattern for #REDIRECT
|
||||
Mise en forme invalide pour le lien de redirection (#REDIRECT)
|
||||
Syntaxe invalide pour le lien de redirection (#REDIRECT)
|
||||
Please go on to %s.
|
||||
SVP aller a %s.
|
||||
SVP aller à %s.
|
||||
Updates since %s
|
||||
Mises à hour depuis %s
|
||||
Mises à jour depuis %s
|
||||
up to %s
|
||||
jusqu’à
|
||||
Updates in the last %s days
|
||||
@@ -108,7 +112,7 @@ Lister toutes les modifications
|
||||
Skip rollbacks
|
||||
Sans les retours en arrière
|
||||
Include rollbacks
|
||||
Incluant les retours en arrière
|
||||
Inclure les retours en arrière
|
||||
List only major changes
|
||||
Lister seulement les modifications majeures
|
||||
Include minor changes
|
||||
@@ -116,7 +120,7 @@ Inclure les modifications mineures
|
||||
%s days
|
||||
%s jours
|
||||
List later changes
|
||||
Lister les modifications les plus récentes
|
||||
Lister les modifications plus récentes
|
||||
RSS
|
||||
RSS
|
||||
RSS with pages
|
||||
@@ -150,15 +154,15 @@ Tous les changements pour %s
|
||||
from %s
|
||||
depuis %s
|
||||
This page is too big to send over RSS.
|
||||
Cette page est trop grosse pour être envoyée sur RSS
|
||||
Cette page est trop grande pour être envoyée sur RSS
|
||||
History of %s
|
||||
Historique de %s
|
||||
Compare
|
||||
Comparer
|
||||
Deleted
|
||||
Suprimé
|
||||
Suprimée
|
||||
Mark this page for deletion
|
||||
Marquer cette page à suprimer
|
||||
Marquer cette page comme étant à supprimer
|
||||
No other revisions available
|
||||
Il n’y a pas d’autre version
|
||||
current
|
||||
@@ -172,15 +176,15 @@ Cible manquante pour le retour en arrière.
|
||||
Target for rollback is too far back.
|
||||
La cible du retour en arrière est trop ancienne.
|
||||
A username is required for ordinary users.
|
||||
Un nom d’utilisateur est nécessaire pour les utilisateurs communs
|
||||
Un nom d’utilisateur est nécessaire pour les utilisateurs normaux
|
||||
Rolling back changes
|
||||
Réinitialisation en cours
|
||||
The two revisions are the same.
|
||||
Les deux révisions sont les mêmes.
|
||||
Les deux versions sont indentiques.
|
||||
Editing not allowed for %s.
|
||||
Edition non autorisée pour %s.
|
||||
Modification non autorisée pour %s.
|
||||
Rollback of %s would restore banned content.
|
||||
Un retour à %s restaurara du texte interdit.
|
||||
Un retour à %s restaurera du texte interdit.
|
||||
Rollback to %s
|
||||
Retour à %s
|
||||
%s rolled back
|
||||
@@ -214,7 +218,7 @@ Actions :
|
||||
Important pages:
|
||||
Pages importantes :
|
||||
To mark a page for deletion, put <strong>%s</strong> on the first line.
|
||||
Pour marquer une page devant être supprimée, ajoutez <strong>%s</strong> à la première ligne
|
||||
Pour marquer une page comme étant à supprimée, ajoutez <strong>%s</strong> à la première ligne
|
||||
[Home]
|
||||
[Accueil]
|
||||
redirected from %s
|
||||
@@ -258,7 +262,7 @@ Voir la version actuelle
|
||||
View all changes
|
||||
Voir toutes les modifications
|
||||
View contributors
|
||||
Vour les contributeurs
|
||||
Voir les contributeurs
|
||||
Homepage URL:
|
||||
Adresse(URL) du site perso
|
||||
s
|
||||
@@ -276,7 +280,7 @@ f
|
||||
Replace:
|
||||
Remplacer :
|
||||
Delete
|
||||
Suprimer
|
||||
Supprimer
|
||||
Validate HTML
|
||||
Valider HTML
|
||||
Validate CSS
|
||||
@@ -284,11 +288,11 @@ Valider CSS
|
||||
Last edit
|
||||
Dernière modification
|
||||
Difference between revision %1 and %2
|
||||
Différence (de la révision %1 à %2)
|
||||
Différence entre les versions %1 et %2
|
||||
revision %s
|
||||
révision %s
|
||||
version %s
|
||||
current revision
|
||||
révision actuelle
|
||||
version actuelle
|
||||
Last major edit (%s)
|
||||
Dernière modification majeure (%s)
|
||||
later minor edits
|
||||
@@ -392,7 +396,7 @@ Vous êtes actuellement éditeur de ce site.
|
||||
You are a normal user on this site.
|
||||
Vous êtes un utilisateur normal de ce site.
|
||||
Your password does not match any of the administrator or editor passwords.
|
||||
Vote mot de passe ne corespond à aucun de ceux des mots de passe administrateurs ou éditeurs.
|
||||
Vote mot de passe ne corespond ni au mot de passe administrateur ni au mot de passe éditeur.
|
||||
Password:
|
||||
Mot de passe :
|
||||
This site does not use admin or editor passwords.
|
||||
@@ -418,7 +422,7 @@ Filtre :
|
||||
%s pages found.
|
||||
%s pages trouvées.
|
||||
Malformed regular expression in %s
|
||||
Expression régulière malformé dans %s
|
||||
Expression régulière malformée dans %s
|
||||
Replaced: %s
|
||||
Remplacé : %s
|
||||
Search for: %s
|
||||
@@ -432,9 +436,9 @@ par
|
||||
Transfer Error: %s
|
||||
Erreur de Transfert : %s
|
||||
Browser reports no file info.
|
||||
Le navigateur signale pas d’information sur le fichier.
|
||||
Le navigateur ne signale pas d’information sur le fichier.
|
||||
Browser reports no file type.
|
||||
Le navigateur signale pas de format de fichier.
|
||||
Le navigateur ne signale pas de type de fichier.
|
||||
The page contains banned text.
|
||||
Cette page contient un texte interdit.
|
||||
No changes to be saved.
|
||||
@@ -530,7 +534,7 @@ Renamed %1 to %2.
|
||||
Immediately delete %s
|
||||
Supprimer immédiatement %s
|
||||
Rename %s to:
|
||||
Renommer %s en :
|
||||
Renommer %s en :
|
||||
Learn more...
|
||||
En savoir plus...
|
||||
Complete Content
|
||||
@@ -538,17 +542,17 @@ Contenu Complet
|
||||
The main page is %s.
|
||||
La page principale est %s.
|
||||
Archive:
|
||||
|
||||
Archive:
|
||||
Rebuild BackLink database
|
||||
|
||||
Rebâtir les liens de la base de donnée
|
||||
Internal Page:
|
||||
|
||||
Page Interne :
|
||||
Pages that link to this page
|
||||
|
||||
Pages liées à cette page
|
||||
The search parameter is missing.
|
||||
|
||||
Le paramètre de recherche est manquant
|
||||
Pages link to %s
|
||||
|
||||
Pages liées à %s
|
||||
Cannot highlight the language %s.
|
||||
Impossible de surligner la langue %s.
|
||||
Recent Visitors
|
||||
@@ -610,9 +614,9 @@ Novembre
|
||||
December
|
||||
Décembre
|
||||
set %s
|
||||
|
||||
paramétrer %s
|
||||
unset %s
|
||||
|
||||
dé-paramétrer %s
|
||||
Clustermap
|
||||
Carte du Faisceau
|
||||
Pages without a Cluster
|
||||
@@ -626,53 +630,53 @@ Compilation pour %s
|
||||
Compilation tag is missing a regular expression.
|
||||
Une expression régulière manque au tag de compilation.
|
||||
Extract all dates from the database
|
||||
|
||||
Extraire toutes les dates depuis la base de données
|
||||
Dates
|
||||
Dates
|
||||
|
||||
No dates found.
|
||||
|
||||
Aucune dates trouvées
|
||||
Inter links:
|
||||
InterLiens :
|
||||
InterLiens :
|
||||
List spammed pages
|
||||
|
||||
Lister les pages spammer
|
||||
Despamming pages
|
||||
Suppression des textes indésirables sur les pages.
|
||||
Spammed pages
|
||||
|
||||
Pages spammées
|
||||
Cannot find revision %s.
|
||||
Impossible de trouver la version %s.
|
||||
Revert to revision %1: %2
|
||||
Retour à la version %1 : %2
|
||||
Retour à la version %1 : %2
|
||||
Marked as %s.
|
||||
Marqué comme %s.
|
||||
Cannot find unspammed revision.
|
||||
Impossible de trouver une version sans texte indésirable.
|
||||
Recover Draft
|
||||
|
||||
Récupérer le brouillon
|
||||
No text to save
|
||||
|
||||
Pas de texte à sauvegarder
|
||||
Draft saved
|
||||
|
||||
Brouillon sauvegardé
|
||||
Draft recovered
|
||||
|
||||
Brouillon récupéré
|
||||
No draft available to recover
|
||||
|
||||
Pas de brouillon à récupérer
|
||||
Save Draft
|
||||
|
||||
Sauvegarder le Brouillon
|
||||
Draft Cleanup
|
||||
|
||||
Brouillon Nettoyer
|
||||
%1 was last modified %2 and was kept
|
||||
|
||||
%1 ont été les dernier modifier et %2 ont été gardé
|
||||
%1 was last modified %2 and was deleted
|
||||
|
||||
%1 ont été modifié et %2 on été effacés
|
||||
Unable to delete draft %s
|
||||
|
||||
Impossible d'effacer le brouillon %s
|
||||
Add Comment
|
||||
Ajouter Commentaire
|
||||
Ajouter un commentaire
|
||||
ordinary changes
|
||||
modifications ordinaires
|
||||
Matching page names:
|
||||
|
||||
Pages correspondant aux noms :
|
||||
Email:
|
||||
Email :
|
||||
Could not find %1.html template in %2
|
||||
@@ -684,27 +688,27 @@ Seuls les Administrateurs ont l'autorisation de voir cette page cachée.
|
||||
Index
|
||||
Index
|
||||
Languages:
|
||||
Langues :
|
||||
Langues :
|
||||
Show!
|
||||
Voir !
|
||||
Voir !
|
||||
Define
|
||||
Définir
|
||||
Full Link List
|
||||
Liste Complète des Liens
|
||||
List of locked pages
|
||||
|
||||
Liste des pages vérrouillés
|
||||
Pages tagged with %s
|
||||
|
||||
Pages taguées avec %s
|
||||
Template without parameters
|
||||
Gabarit sans paramètres
|
||||
Modèle sans paramètres
|
||||
The template %s is either empty or does not exist.
|
||||
Le gabarit %s est soit vide soit n'existe pas.
|
||||
Le modèle %s est soit vide soit n'existe pas.
|
||||
-- defined on %s
|
||||
-- défini sur %s
|
||||
Local names defined on %1: %2
|
||||
Noms locaux définis sur %1 : %2
|
||||
Locked Pages
|
||||
|
||||
Pages Vérouillées
|
||||
Register for %s
|
||||
Enregistrer pour %s
|
||||
Please choose a username of the form "FirstLast" using your real name.
|
||||
@@ -736,7 +740,7 @@ Connecté sous %s.
|
||||
Logout of %s
|
||||
Déconnexion de %s
|
||||
Logout of %s?
|
||||
Déconnexion de %s ?
|
||||
Déconnexion de %s ?
|
||||
Logged out of %s
|
||||
Déconnecté de %s
|
||||
You are now logged out.
|
||||
@@ -746,9 +750,9 @@ Enregistrer un nouveau compte.
|
||||
Logout
|
||||
Se déconnecter
|
||||
Who am I?
|
||||
Qui suis-je ?
|
||||
Qui suis-je ?
|
||||
Forgot your password?
|
||||
Mot de passe oublié ?
|
||||
Mot de passe oublié ?
|
||||
Change your password
|
||||
Changer votre mot de passe
|
||||
Approve pending registrations
|
||||
@@ -760,7 +764,7 @@ Confirmation d'Enregistrement pour %s
|
||||
Confirmation failed. Please email %s for help.
|
||||
Echec sur la confirmation. SVP envoyez un email à %s pour de l'aide.
|
||||
Who Am I?
|
||||
Qui suis-je ?
|
||||
Qui suis-je ?
|
||||
You are logged in as %s.
|
||||
Vous êtes connecté en tant que %s.
|
||||
You are not logged in.
|
||||
@@ -776,11 +780,11 @@ Le nom d'utilisateur "%s" n'existe pas.
|
||||
Reset Password for %s
|
||||
Réinitialiser le mot de passe pour %s
|
||||
Reset Password?
|
||||
Réinitialisation Mot de Passe ?
|
||||
Réinitialisation Mot de Passe ?
|
||||
Change Password for %s
|
||||
Modification Mot de Passe pour %s
|
||||
Change Password?
|
||||
Modification Mot de Passe ?
|
||||
Modification Mot de Passe ?
|
||||
Your current password is incorrect.
|
||||
Votre Mot de Passe est incorrect.
|
||||
Your password has been changed.
|
||||
@@ -836,7 +840,7 @@ Les pages restantes n’existent pas (ou plus).
|
||||
Unsubscribed %s from the following pages:
|
||||
%s a désabonné les pages suivantes :
|
||||
You linked more than %s times to the same domain. It would seem that only a spammer would do this. Your edit is refused.
|
||||
|
||||
Vous avez liés plus de %s le même domaine. Il semble que seul les spammeurs font cela. Votre édition est donc refusée.
|
||||
%s is not a legal name for a namespace
|
||||
%s n’est pas un nom valide pour un espace de noms
|
||||
Namespaces
|
||||
@@ -844,27 +848,27 @@ Espace de noms
|
||||
Getting page index file for %s.
|
||||
Récupération du fichier d'index de %s.
|
||||
Near links:
|
||||
Liens de proximité :
|
||||
Liens de proximité :
|
||||
Search sites on the %s as well
|
||||
Rechercher aussi les sites présents sur %s
|
||||
Fetching results from %s:
|
||||
Récupération des résultats à partir de %s :
|
||||
Récupération des résultats à partir de %s :
|
||||
Near pages:
|
||||
Pages à proximité :
|
||||
Pages à proximité :
|
||||
Include near pages
|
||||
Inclure les pages de proximité
|
||||
EditNearLinks
|
||||
EditerLiensDeProximité
|
||||
The same page on other sites:
|
||||
La même page sur d'autres sites :
|
||||
La même page sur d'autres sites :
|
||||
(create locally)
|
||||
|
||||
(créée locallement)
|
||||
image
|
||||
image
|
||||
download
|
||||
télécharger
|
||||
Backlinks
|
||||
|
||||
Liens en retour
|
||||
Clearing Cache
|
||||
Nettoyage du cache.
|
||||
Done.
|
||||
@@ -888,23 +892,23 @@ Auto-bannissement par %s
|
||||
You have banned your own IP.
|
||||
Vous avez banni votre propre IP.
|
||||
OpenID Login
|
||||
|
||||
Identification OpenID
|
||||
Your identity is saved in a cookie, if you have cookies enabled. Cookies may get lost if you connect from another machine, from another account, or using another software.
|
||||
|
||||
Votre identité est sauvegardée dans un cookie, si vous avez activé les cookies. Vos cookies seront perdue si vous vous connecté depuis une autre machine, sur un autre compte ou si vous utiliser un autre navigateur.
|
||||
Your homepage is set to %s.
|
||||
|
||||
Votre page d'accueil est ajusté sur %s.
|
||||
You have no homepage set.
|
||||
|
||||
Votre page d'acceuil n'est pas ajustée.
|
||||
Homepage:
|
||||
|
||||
Page d'accueil :
|
||||
Homepage is missing
|
||||
|
||||
La page d'accueil est manquante
|
||||
OpenID error %s
|
||||
|
||||
Erreur OpenID %s
|
||||
Orphan List
|
||||
Liste Orpheline
|
||||
Trail:
|
||||
Trace :
|
||||
Trace :
|
||||
None
|
||||
Aucune
|
||||
Type
|
||||
@@ -930,19 +934,19 @@ Portrait
|
||||
Publish %s
|
||||
Publier %s
|
||||
No target wiki was specified in the config file.
|
||||
|
||||
La cible du wiki n'est pas spécifiée dans le fichier de configuration.
|
||||
The target wiki was misconfigured.
|
||||
|
||||
La cible du wiki à été mal configurée.
|
||||
Upload is limited to %s bytes
|
||||
|
||||
Le téléversement est limité à %s bytes
|
||||
You did not answer correctly.
|
||||
Vous n’avez pas répondu correctement.
|
||||
To save this page you must answer this question:
|
||||
Il faut réponder a cette question pour sauvegarder la page :
|
||||
Vous devez répondre a cette question pour sauvegarder la page :
|
||||
Please type the following two words:
|
||||
|
||||
Taper s'il vous plait les deux mots suivant :
|
||||
Please answer this captcha:
|
||||
|
||||
Répondez à ce captcha s'il vous plais :
|
||||
Referrers
|
||||
Introducteurs
|
||||
All Referrers
|
||||
@@ -960,7 +964,7 @@ Reconstruction index non effectuée.
|
||||
(Rebuilding the index can only be done once every 12 hours.)
|
||||
(La reconstruction de l'index ne peut être faite qu'une fois toutes les 12 heures.)
|
||||
New Pages for Indexed Search
|
||||
|
||||
Nouvelle pages pour indexer la recherche
|
||||
List changes since %s
|
||||
Changement depuis %s
|
||||
...
|
||||
@@ -968,43 +972,43 @@ Changement depuis %s
|
||||
Search term missing.
|
||||
Terme de la recherche manquant.
|
||||
Result pages:
|
||||
Pages de résultats :
|
||||
Pages de résultats :
|
||||
(%s results)
|
||||
(%s résultats)
|
||||
Tags:
|
||||
|
||||
Tags :
|
||||
Tags: %s.
|
||||
|
||||
Tags : %s
|
||||
No tags
|
||||
|
||||
Pas de tags
|
||||
Page list for %s
|
||||
|
||||
Liste des pages pour %s
|
||||
Slideshow:%s
|
||||
Diaporama : %s
|
||||
Diaporama : %s
|
||||
Index of all small pages
|
||||
|
||||
Indexe de toutes les petites pages
|
||||
Static Copy
|
||||
Copie Statique
|
||||
Back to %s
|
||||
Retour à %s
|
||||
Edit image in the browser
|
||||
|
||||
Éditer l'image du navigateur
|
||||
Summary of your changes:
|
||||
|
||||
Sommaire des changements :
|
||||
Copy to %1 succeeded: %2.
|
||||
Copie vers %1 réussie : %2.
|
||||
Copie vers %1 réussie : %2.
|
||||
Copy to %1 failed: %2.
|
||||
Copie vers %1 échouée : %2.
|
||||
Copie vers %1 échouée : %2.
|
||||
Feed for this tag
|
||||
|
||||
Graines pour ce tag
|
||||
Rebuild tag index
|
||||
|
||||
Rebâtir votre index de tag
|
||||
list tags
|
||||
|
||||
liste de tags
|
||||
tag cloud
|
||||
|
||||
tag du nuage
|
||||
Alternatively, use one of the following templates:
|
||||
Alternativement, utilisez un des modèles suivants :
|
||||
Alternativement, utilisez un des modèles suivants :
|
||||
Thread: %s
|
||||
Fil: %s
|
||||
ID parameter is missing.
|
||||
@@ -1020,47 +1024,47 @@ Le paramètre URL est manquant.
|
||||
Add to %s thread
|
||||
Ajouter %s au fil
|
||||
Below:
|
||||
En-dessous :
|
||||
En-dessous :
|
||||
URL:
|
||||
URL :
|
||||
URL :
|
||||
Name:
|
||||
Nom :
|
||||
Nom :
|
||||
Too many instances. Only %s allowed.
|
||||
|
||||
Trop d'instances. %s seulement est autorisée
|
||||
Please try again later. Perhaps somebody is running maintenance or doing a long search. Unfortunately the site has limited resources, and so we must ask you for a bit of patience.
|
||||
|
||||
ressources, nous vous demandons de faire preuve d'un peu de patience.
|
||||
Timezone
|
||||
|
||||
Fuseau horaire
|
||||
Pick your timezone:
|
||||
|
||||
Sélectionner votre fuseau horaire
|
||||
Set
|
||||
|
||||
Ajusté
|
||||
Contents
|
||||
Contenus
|
||||
Create a new page for today
|
||||
Ajouter une page nouvelle pour aujourd’hui
|
||||
Add Translation
|
||||
Àjouter une traduction
|
||||
Ajouter une traduction
|
||||
Please provide a different page name for the translation.
|
||||
|
||||
Donné s'il vous plait un nom différent à votre traduction
|
||||
Added translation: %1 (%2)
|
||||
|
||||
Traduction ajoutée: %1 (%2)
|
||||
Translate %s
|
||||
Traduire %s
|
||||
Thank you for writing a translation of %s.
|
||||
Merci pour traduir %s.
|
||||
Merci pour la traduction de %s.
|
||||
Please indicate what language you will be using.
|
||||
|
||||
Merci d'indiquer quel langage vous allez utiliser.
|
||||
Language is missing
|
||||
|
||||
Le langage est manquant
|
||||
Suggested languages:
|
||||
|
||||
Langages suggérés
|
||||
Please indicate a page name for the translation of %s.
|
||||
|
||||
Indiqué s'il vous plait votre traduction pour %s.
|
||||
More help may be available here: %s.
|
||||
|
||||
Plus d'aide disponible ici: %s.
|
||||
Translated page:
|
||||
|
||||
Page traduite :
|
||||
This page is a translation of %s.
|
||||
Cette page est une traduction de %s.
|
||||
The translation is up to date.
|
||||
@@ -1080,23 +1084,23 @@ http://www.pricescan.com/books/BookDetail.asp?isbn=%s
|
||||
search
|
||||
chercher
|
||||
Wanted Pages
|
||||
|
||||
Pages recherchées
|
||||
%s pages
|
||||
%s pages
|
||||
|
||||
%s, referenced from:
|
||||
|
||||
%s, référencé depuis :
|
||||
Upload of %s file
|
||||
Téléversement du fichier %s
|
||||
Blog
|
||||
Blog
|
||||
Matching pages:
|
||||
Pages correspondantes :
|
||||
Pages correspondantes :
|
||||
New
|
||||
Nouveau
|
||||
Edit %s.
|
||||
Editer %s.
|
||||
Title:
|
||||
|
||||
Titre :
|
||||
Tags:
|
||||
|
||||
Tags :
|
||||
END_OF_TRANSLATION
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
# UTF-8 encoded German translation file for use with Oddmuse
|
||||
#
|
||||
# Copyright (c) 2003 Karl Loncarek <karl@loncarek.de>
|
||||
# Copyright (c) 2003, 2004, 2005, 2006, 2007, 2009, 2010 Alex Schröder <alex@gnu.org>
|
||||
# Copyright (c) 2003-2012 Alex Schröder <alex@gnu.org>
|
||||
#
|
||||
# Permission is granted to copy, distribute and/or modify this document under
|
||||
# the terms of the GNU Free Documentation License, Version 1.2 or any later
|
||||
@@ -15,7 +15,10 @@
|
||||
# Create a modules subdirectory in your data directory, and put the file in
|
||||
# there. It will be loaded automatically.
|
||||
#
|
||||
$ModulesDescription .= '<p>$Id: german-utf8.pl,v 1.30 2011/02/05 12:40:38 as Exp $</p>';
|
||||
use utf8;
|
||||
|
||||
$ModulesDescription .= '<p><a href="http://git.savannah.gnu.org/cgit/oddmuse.git/tree/modules/translations/german-utf8.pl">german-utf8.pl</a>, see <a href="http://www.oddmuse.org/cgi-bin/oddmuse/German">German</a></p>';
|
||||
|
||||
%Translate = split(/\n/,<<END_OF_TRANSLATION);
|
||||
Include normal pages
|
||||
Mit normalen Seiten
|
||||
@@ -27,8 +30,8 @@ Error
|
||||
Fehler
|
||||
%s calls
|
||||
%s Aufrufe
|
||||
Could not create %s
|
||||
Konnte %s nicht erzeugen
|
||||
Cannot create %s
|
||||
%s kann nicht erstellt werden
|
||||
Invalid UserName %s: not saved.
|
||||
Ungültiger Benutzername %s: nicht gespeichert.
|
||||
UserName must be 50 characters or less: not saved
|
||||
@@ -197,8 +200,6 @@ Unlock site
|
||||
Wiki entsperren
|
||||
Lock site
|
||||
Wiki sperren
|
||||
Install CSS
|
||||
CSS installieren
|
||||
Unlock %s
|
||||
%s entsperren
|
||||
Lock %s
|
||||
@@ -315,8 +316,6 @@ Cannot open %s
|
||||
%s kann nicht geöffnet werden
|
||||
Cannot write %s
|
||||
%s kann nicht geschrieben werden
|
||||
Cannot create %s
|
||||
%s kann nicht erstellt werden
|
||||
Could not get %s lock
|
||||
Die %s Sperre konnte nicht gesetzt werden
|
||||
The lock was created %s.
|
||||
@@ -503,8 +502,6 @@ Please do not fetch more than %1 pages in %2 seconds.
|
||||
Bitte rufen sie nicht mehr als %1 Seiten in %2 Sekunden auf.
|
||||
Check whether the web server can create the directory %s and whether it can create files in it.
|
||||
Vielleicht kann der Webserver das Verzeichnis %s nicht anlegen oder es wurde schon angelegt, aber der Webserver kann darin keine neuen Dateien anlegen.
|
||||
Copy one of the following stylesheets to %s:
|
||||
Eines der folgenden Style Sheets kann auf die %s Seite kopiert werden:
|
||||
Deleting %s
|
||||
%s löschen
|
||||
Deleted %s
|
||||
@@ -621,6 +618,12 @@ Compilation for %s
|
||||
Zusammenstellung für %s
|
||||
Compilation tag is missing a regular expression.
|
||||
Der tag für die Zusammenstellung benötigt noch ein Suchmuster.
|
||||
Install CSS
|
||||
CSS installieren
|
||||
Copy one of the following stylesheets to %s:
|
||||
Eines der folgenden Style Sheets kann auf die %s Seite kopiert werden:
|
||||
Reset
|
||||
Zurück setzen
|
||||
Extract all dates from the database
|
||||
Alle Daten aus der Datenbank extrahieren
|
||||
Dates
|
||||
@@ -669,6 +672,14 @@ ordinary changes
|
||||
normale Änderungen
|
||||
Matching page names:
|
||||
Übereinstimmende Seitennamen:
|
||||
Fix page encoding
|
||||
Zeichenkodierung korrigieren
|
||||
no summary available
|
||||
keine Zusammenfassug vorhanden
|
||||
page was marked for deletion
|
||||
die Seite war zum Löschen freigegeben
|
||||
Oddmuse
|
||||
Oddmuse
|
||||
Email:
|
||||
Email:
|
||||
Could not find %1.html template in %2
|
||||
@@ -683,6 +694,22 @@ Languages:
|
||||
Sprachen:
|
||||
Show!
|
||||
Zeigen!
|
||||
LaTeX export
|
||||
LaTeX Export
|
||||
An uploaded file cannot be rendered as LaTeX.
|
||||
Ein hochgeladene Datei kann nicht mit LaTeX dargestellt werden.
|
||||
Exporting of journal pages to LaTeX is not supported.
|
||||
Journalseiten können nicht für LaTeX exportiert werden.
|
||||
Exporting of RSS feeds to LaTeX is not supported.
|
||||
RSS Feeds können nicht für LaTeX exportiert werden.
|
||||
Exporting of search results to LaTeX is not supported.
|
||||
Suchresultate können nicht für LaTeX exportiert werden.
|
||||
Exporting of redirections to LaTeX is not supported.
|
||||
Umleitungen können nicht für LaTeX exportiert werden.
|
||||
Exporting of named entity reference to LaTeX is not supported.
|
||||
Benannte Zeichen können nicht für LaTeX exportiert werden.
|
||||
Exporting of images to LaTeX is not supported.
|
||||
Bilder können nicht für LaTeX exportiert werden.
|
||||
Define
|
||||
Definieren
|
||||
Full Link List
|
||||
@@ -699,6 +726,14 @@ Die %s Vorlage ist entweder leer oder existiert gar nicht.
|
||||
-- definiert auf der Seite %s
|
||||
Local names defined on %1: %2
|
||||
Der lokale Namen %2 wurde auf der Seite %1 definiert
|
||||
Name:
|
||||
Name:
|
||||
URL:
|
||||
URL:
|
||||
Define Local Names
|
||||
Lokalen Namen definieren
|
||||
Define external redirect:
|
||||
Umleitung auf eine externe Seite definieren:
|
||||
Locked Pages
|
||||
Gesperrte Seiten
|
||||
Register for %s
|
||||
@@ -869,6 +904,12 @@ Generating Link Database
|
||||
Verweis Datenbank wird angelegt
|
||||
The 404 handler extension requires the link data extension (links.pl).
|
||||
Die 404 handler Erweiterung benötigt die Link Data Erweiterung (links.pl).
|
||||
Make available offline
|
||||
Offline zur Verfügung stellen
|
||||
Offline
|
||||
Offline
|
||||
You are currently offline and what you requested is not part of the offline application. You need to be online to do this.
|
||||
Sie sind im Moment offline und was sie verlangt haben, ist nicht Teil der Offline Applikation. Hierfür müssen sie online sein.
|
||||
LocalMap
|
||||
LocalMap
|
||||
No page id for action localmap
|
||||
@@ -883,20 +924,6 @@ Self-ban by %s
|
||||
%s hat sich selber verbannt.
|
||||
You have banned your own IP.
|
||||
Sie haben ihre eigene IP Nummer verbannt.
|
||||
OpenID Login
|
||||
OpenID Login
|
||||
Your identity is saved in a cookie, if you have cookies enabled. Cookies may get lost if you connect from another machine, from another account, or using another software.
|
||||
Die Identität wird in einem Cookie gespeichert, falls diese erlaubt sind. Cookies gehen verloren, wenn ein anderer Rechner, eine anderes Konto, oder ein anderer Browser verwendet wird.
|
||||
Your homepage is set to %s.
|
||||
Homepage wurde auf %s gesetzt.
|
||||
You have no homepage set.
|
||||
Keine Homepage gesetzt.
|
||||
Homepage:
|
||||
Homepage:
|
||||
Homepage is missing
|
||||
Homepage fehlt
|
||||
OpenID error %s
|
||||
OpenID Fehler %s
|
||||
Orphan List
|
||||
Liste der Waisen
|
||||
Trail:
|
||||
@@ -1025,6 +1052,26 @@ Too many instances. Only %s allowed.
|
||||
Es laufen schon %s Wiki Prozesse gleichzeitig auf diesem Server. Mehr sind leider nicht erlaubt.
|
||||
Please try again later. Perhaps somebody is running maintenance or doing a long search. Unfortunately the site has limited resources, and so we must ask you for a bit of patience.
|
||||
Versuchen Sie es später nocheinmal. Vielleicht werden gerade Wartungsarbeiten durchgeführt, oder ein Suchbefehl nimmt gerade viel Zeit in Anspruch. Leider sind die Resourcen des Rechners limitiert; wir bitten Sie deshalb um etwas Geduld.
|
||||
thumb
|
||||
|
||||
Error creating thumbnail from non existant page %s.
|
||||
|
||||
Can not create thumbnail for file type %s.
|
||||
|
||||
Can not create thumbnail for a text document
|
||||
|
||||
Could not open %s for writing whilst trying to save image before creating thumbnail. Check write permissions.
|
||||
|
||||
Can not create path for thumbnail - %s
|
||||
|
||||
Failed to run %1 to create thumbnail: %2
|
||||
|
||||
%s ran into an error
|
||||
%s hat einen Fehler festgestellt
|
||||
%s produced no output
|
||||
%s hat nichts ausgegeben
|
||||
Failed to parse %s.
|
||||
Die Ausgabe von %s wurde nicht verstanden
|
||||
Timezone
|
||||
Zeitzone
|
||||
Pick your timezone:
|
||||
@@ -1081,6 +1128,8 @@ Gewünschte Seiten
|
||||
%s Seiten
|
||||
%s, referenced from:
|
||||
%s, referenziert von:
|
||||
Web application for offline browsing
|
||||
Offline Webapplikation
|
||||
Upload of %s file
|
||||
Hochladen der %s Datei
|
||||
Blog
|
||||
|
||||
@@ -15,7 +15,8 @@
|
||||
# Create a modules subdirectory in your data directory, and put the
|
||||
# file in there. It will be loaded automatically.
|
||||
#
|
||||
$ModulesDescription .= '<p>$Id: greek-utf8.pl,v 1.2 2009/06/07 19:30:37 as Exp $</p>';
|
||||
use utf8;
|
||||
$ModulesDescription .= '<p><a href="http://git.savannah.gnu.org/cgit/oddmuse.git/tree/modules/translations/greek-utf8.pl">greek-utf8.pl</a>, see <a href="http://www.oddmuse.org/cgi-bin/oddmuse/Greek">Greek</a></p>';
|
||||
%Translate = split(/\n/,<<END_OF_TRANSLATION);
|
||||
Include normal pages
|
||||
Με τις κανονικές σελίδες.
|
||||
|
||||
@@ -17,7 +17,8 @@
|
||||
#
|
||||
# This translation was last checked for Oddmuse version 1.195.
|
||||
#
|
||||
$ModulesDescription .= '<p>$Id: hebrew-utf8.pl,v 1.11 2009/06/07 19:30:37 as Exp $</p>';
|
||||
use utf8;
|
||||
$ModulesDescription .= '<p><a href="http://git.savannah.gnu.org/cgit/oddmuse.git/tree/modules/translations/hebrew-utf8.pl">hebrew-utf8.pl</a>, see <a href="http://www.oddmuse.org/cgi-bin/oddmuse/Hebrew">Hebrew</a></p>';
|
||||
%Translate = split(/\n/,<<END_OF_TRANSLATION);
|
||||
Include normal pages
|
||||
|
||||
|
||||
@@ -15,7 +15,8 @@
|
||||
# Create a modules subdirectory in your data directory, and put the
|
||||
# file in there. It will be loaded automatically.
|
||||
#
|
||||
$ModulesDescription .= '<p>$Id: italian-utf8.pl,v 1.11 2009/06/07 19:30:37 as Exp $</p>';
|
||||
use utf8;
|
||||
$ModulesDescription .= '<p><a href="http://git.savannah.gnu.org/cgit/oddmuse.git/tree/modules/translations/italian-utf8.pl">italian-utf8.pl</a>, see <a href="http://www.oddmuse.org/cgi-bin/oddmuse/Italian">Italian</a></p>';
|
||||
%Translate = split(/\n/,<<END_OF_TRANSLATION);
|
||||
Include normal pages
|
||||
Includi le pagine normali
|
||||
|
||||
@@ -17,7 +17,8 @@
|
||||
#
|
||||
# This translation was last checked for Oddmuse version 1.215.
|
||||
#
|
||||
$ModulesDescription .= '<p>$Id: japanese-utf8.pl,v 1.11 2009/06/07 19:30:37 as Exp $</p>';
|
||||
use utf8;
|
||||
$ModulesDescription .= '<p><a href="http://git.savannah.gnu.org/cgit/oddmuse.git/tree/modules/translations/japanese-utf8.pl">japanese-utf8.pl</a>, see <a href="http://www.oddmuse.org/cgi-bin/oddmuse/Japanese">Japanese</a></p>';
|
||||
%Translate = split(/\n/,<<END_OF_TRANSLATION);
|
||||
Include normal pages
|
||||
|
||||
|
||||
@@ -15,7 +15,8 @@
|
||||
# Create a modules subdirectory in your data directory, and put the
|
||||
# file in there. It will be loaded automatically.
|
||||
#
|
||||
$ModulesDescription .= '<p>$Id: korean-utf8.pl,v 1.5 2009/06/07 19:30:37 as Exp $</p>';
|
||||
use utf8;
|
||||
$ModulesDescription .= '<p><a href="http://git.savannah.gnu.org/cgit/oddmuse.git/tree/modules/translations/korean-utf8.pl">korean-utf8.pl</a>, see <a href="http://www.oddmuse.org/cgi-bin/oddmuse/Korean">Korean</a></p>';
|
||||
%Translate = split(/\n/,<<END_OF_TRANSLATION);
|
||||
Include normal pages
|
||||
정상 페이지를 포함하여
|
||||
|
||||
@@ -15,7 +15,8 @@
|
||||
# Create a modules subdirectory in your data directory, and put the
|
||||
# file in there. It will be loaded automatically.
|
||||
#
|
||||
$ModulesDescription .= '<p>$Id: new-utf8.pl,v 1.12 2009/06/07 19:30:37 as Exp $</p>';
|
||||
use utf8;
|
||||
$ModulesDescription .= '<p><a href="http://git.savannah.gnu.org/cgit/oddmuse.git/tree/modules/translations/fixme-utf8.pl">fixme-utf8.pl</a>, see <a href="http://www.oddmuse.org/cgi-bin/oddmuse/Fixme">Fixme</a></p>';
|
||||
%Translate = split(/\n/,<<END_OF_TRANSLATION);
|
||||
Include normal pages
|
||||
|
||||
|
||||
@@ -17,7 +17,8 @@
|
||||
# Create a modules subdirectory in your data directory, and put the
|
||||
# file in there. It will be loaded automatically.
|
||||
#
|
||||
$ModulesDescription .= '<p>$Id: polish-utf8.pl,v 1.7 2009/06/07 19:30:37 as Exp $</p>';
|
||||
use utf8;
|
||||
$ModulesDescription .= '<p><a href="http://git.savannah.gnu.org/cgit/oddmuse.git/tree/modules/translations/polish-utf8.pl">polish-utf8.pl</a>, see <a href="http://www.oddmuse.org/cgi-bin/oddmuse/Polish">Polish</a></p>';
|
||||
%Translate = split(/\n/,<<END_OF_TRANSLATION);
|
||||
Include normal pages
|
||||
Ze zwykłymi stronami
|
||||
|
||||
@@ -20,7 +20,8 @@
|
||||
#
|
||||
# This translation was last checked for Oddmuse version 1.195.
|
||||
#
|
||||
$ModulesDescription .= '<p>$Id: portuguese-utf8.pl,v 1.15 2009/06/07 19:30:37 as Exp $</p>';
|
||||
use utf8;
|
||||
$ModulesDescription .= '<p><a href="http://git.savannah.gnu.org/cgit/oddmuse.git/tree/modules/translations/portuguese-utf8.pl">portuguese-utf8.pl</a>, see <a href="http://www.oddmuse.org/cgi-bin/oddmuse/Portuguese">Portuguese</a></p>';
|
||||
%Translate = split(/\n/,<<END_OF_TRANSLATION);
|
||||
Include normal pages
|
||||
Incluir páginas normais
|
||||
|
||||
@@ -15,7 +15,8 @@
|
||||
# Create a modules subdirectory in your data directory, and put the
|
||||
# file in there. It will be loaded automatically.
|
||||
#
|
||||
$ModulesDescription .= '<p>$Id: romanian-utf8.pl,v 1.9 2009/06/07 19:30:37 as Exp $</p>';
|
||||
use utf8;
|
||||
$ModulesDescription .= '<p><a href="http://git.savannah.gnu.org/cgit/oddmuse.git/tree/modules/translations/romanian-utf8.pl">romanian-utf8.pl</a>, see <a href="http://www.oddmuse.org/cgi-bin/oddmuse/Romanian">Romanian</a></p>';
|
||||
%Translate = split(/\n/,<<END_OF_TRANSLATION);
|
||||
Include normal pages
|
||||
|
||||
|
||||
@@ -20,7 +20,8 @@
|
||||
#
|
||||
# This script was last checked for Oddmuse version 1.658.
|
||||
#
|
||||
$ModulesDescription .= '<p>$Id: russian-utf8.pl,v 1.13 2007/08/19 11:42:08 as Exp $</p>';
|
||||
use utf8;
|
||||
$ModulesDescription .= '<p><a href="http://git.savannah.gnu.org/cgit/oddmuse.git/tree/modules/translations/russian-utf8.pl">russian-utf8.pl</a>, see <a href="http://www.oddmuse.org/cgi-bin/oddmuse/Russian">Russian</a></p>';
|
||||
%Translate = split(/\n/,<<END_OF_TRANSLATION);
|
||||
Reading not allowed: user, ip, or network is blocked.
|
||||
Просмотр недоступен: имя пользователя, IP-адрес или сеть заблокированы.
|
||||
|
||||
@@ -17,7 +17,8 @@
|
||||
#
|
||||
# This translation was last checked for Oddmuse version 1.195.
|
||||
#
|
||||
$ModulesDescription .= '<p>$Id: serbian-utf8.pl,v 1.11 2009/06/07 19:30:37 as Exp $</p>';
|
||||
use utf8;
|
||||
$ModulesDescription .= '<p><a href="http://git.savannah.gnu.org/cgit/oddmuse.git/tree/modules/translations/serbian-utf8.pl">serbian-utf8.pl</a>, see <a href="http://www.oddmuse.org/cgi-bin/oddmuse/Serbian">Serbian</a></p>';
|
||||
%Translate = split(/\n/,<<END_OF_TRANSLATION);
|
||||
Include normal pages
|
||||
|
||||
|
||||
@@ -18,7 +18,8 @@
|
||||
#
|
||||
# This translation was last checked for Oddmuse version 1.195.
|
||||
#
|
||||
$ModulesDescription .= '<p>$Id: spanish-utf8.pl,v 1.13 2011/07/05 00:30:18 as Exp $</p>';
|
||||
use utf8;
|
||||
$ModulesDescription .= '<p><a href="http://git.savannah.gnu.org/cgit/oddmuse.git/tree/modules/translations/spanish-utf8.pl">spanish-utf8.pl</a>, see <a href="http://www.oddmuse.org/cgi-bin/oddmuse/Spanish">Spanish</a></p>';
|
||||
%Translate = split(/\n/,<<END_OF_TRANSLATION);
|
||||
Include normal pages
|
||||
Incluir páginas normales
|
||||
|
||||
@@ -20,7 +20,8 @@
|
||||
# Create a modules subdirectory in your data directory, and put the
|
||||
# file in there. It will be loaded automatically.
|
||||
#
|
||||
$ModulesDescription .= '<p>$Id: swedish-utf8.pl,v 1.18 2009/06/07 19:30:38 as Exp $</p>';
|
||||
use utf8;
|
||||
$ModulesDescription .= '<p><a href="http://git.savannah.gnu.org/cgit/oddmuse.git/tree/modules/translations/swedish-utf8.pl">swedish-utf8.pl</a>, see <a href="http://www.oddmuse.org/cgi-bin/oddmuse/Swedish">Swedish</a></p><p>';
|
||||
%Translate = split(/\n/,<<END_OF_TRANSLATION);
|
||||
Include normal pages
|
||||
Med vanliga sidor
|
||||
|
||||
@@ -15,7 +15,8 @@
|
||||
# Create a modules subdirectory in your data directory, and put the
|
||||
# file in there. It will be loaded automatically.
|
||||
#
|
||||
$ModulesDescription .= '<p>$Id: ukrainian-utf8.pl,v 1.6 2009/06/07 19:30:38 as Exp $</p>';
|
||||
use utf8;
|
||||
$ModulesDescription .= '<p><a href="http://git.savannah.gnu.org/cgit/oddmuse.git/tree/modules/translations/ukrainian-utf8.pl">ukrainian-utf8.pl</a>, see <a href="http://www.oddmuse.org/cgi-bin/oddmuse/Ukrainian">Ukrainian</a></p>';
|
||||
%Translate = split(/\n/,<<END_OF_TRANSLATION);
|
||||
Include normal pages
|
||||
Включати звичайні сторінки
|
||||
|
||||
@@ -109,7 +109,7 @@ sub get {
|
||||
} else {
|
||||
print $q->header( -cache_control => 'max-age=10',
|
||||
-etag => $OddMuse::Page{ts},
|
||||
-type => "text/plain; charset=$OddMuse::HttpCharset",
|
||||
-type => "text/plain; charset=UTF-8",
|
||||
-status => "200 OK",);
|
||||
print $OddMuse::Page{text} unless $head;
|
||||
}
|
||||
@@ -373,11 +373,6 @@ sub propfind {
|
||||
$resp->addChild($propstat);
|
||||
}
|
||||
}
|
||||
# The XML Parser handles UTF-8 correctly, but Perl will
|
||||
# automatically convert it to Latin-1 upon printing to STDOUT unless
|
||||
# we use binmode.
|
||||
eval { local $SIG{__DIE__}; binmode(STDOUT, ":utf8"); }
|
||||
if $OddMuse::HttpCharset eq 'UTF-8';
|
||||
warn "RESPONSE: 207\n" . $doc->toString(1) . "\n" if $verbose;
|
||||
print $doc->toString(1);
|
||||
}
|
||||
|
||||
3
oddtrans
3
oddtrans
@@ -2,6 +2,9 @@
|
||||
# Based on umtrans.pl version 1.0 (April 8, 2001) by Clifford Adams.
|
||||
# Extracts translation strings from wiki script and extensions.
|
||||
|
||||
binmode(STDIN, ':utf8');
|
||||
binmode(STDOUT, ':utf8');
|
||||
|
||||
$help = q{
|
||||
NAME
|
||||
oddtrans - complement translation tables for Oddmuse
|
||||
|
||||
@@ -119,7 +119,6 @@ sub get_rss {
|
||||
my $rss = new XML::RSS;
|
||||
$rss->parse($response->content);
|
||||
print "Found " . @{$rss->{items}} . " items.\n" if $debug;
|
||||
update_timestamp();
|
||||
return $rss;
|
||||
}
|
||||
|
||||
@@ -145,6 +144,7 @@ sub send_file {
|
||||
my ($id, $title, $item, @subscribers) = @_;
|
||||
return unless @subscribers;
|
||||
my $fh = File::Temp->new(SUFFIX => '.html');
|
||||
binmode($fh, ":utf8");
|
||||
warn "No content for $title\n" unless $item->{description};
|
||||
my $link = $item->{link};
|
||||
my $sub = "$root?action=subscriptions";
|
||||
@@ -207,6 +207,7 @@ sub main {
|
||||
my $subscribers = get_subscribers();
|
||||
return unless %{$subscribers};
|
||||
send_files($rss, $subscribers);
|
||||
update_timestamp();
|
||||
}
|
||||
|
||||
main ();
|
||||
|
||||
@@ -15,6 +15,7 @@
|
||||
require 't/test.pl';
|
||||
package OddMuse;
|
||||
use Test::More tests => 39;
|
||||
use utf8; # tests contain UTF-8 characters and it matters
|
||||
|
||||
clear_pages();
|
||||
|
||||
|
||||
18
t/conflict.t
18
t/conflict.t
@@ -18,7 +18,7 @@
|
||||
|
||||
require 't/test.pl';
|
||||
package OddMuse;
|
||||
use Test::More tests => 16;
|
||||
use Test::More tests => 19;
|
||||
|
||||
clear_pages();
|
||||
|
||||
@@ -49,6 +49,7 @@ The two are the same,
|
||||
But after they are produced,
|
||||
they have different names.
|
||||
};
|
||||
|
||||
my $lao_file_2 = q{The Way that can be told of is not the eternal Way;
|
||||
The name that can be named is not the eternal name.
|
||||
The Nameless is the origin of Heaven and Earth;
|
||||
@@ -118,9 +119,8 @@ sleep(2);
|
||||
|
||||
update_page('ConflictTest', $lao_file);
|
||||
|
||||
$_ = `perl wiki.pl action=edit id=ConflictTest`;
|
||||
/name="oldtime" value="([0-9]+)"/;
|
||||
my $oldtime = $1;
|
||||
my $oldtime = xpath_test(get_page('action=edit id=ConflictTest'),
|
||||
'//input[@name="oldtime"]/attribute::value');
|
||||
|
||||
sleep(2);
|
||||
|
||||
@@ -143,9 +143,8 @@ sleep(2);
|
||||
|
||||
update_page('ConflictTest', $tzu_file);
|
||||
|
||||
$_ = `perl wiki.pl action=edit id=ConflictTest`;
|
||||
/name="oldtime" value="([0-9]+)"/;
|
||||
$oldtime = $1;
|
||||
$oldtime = xpath_test(get_page('action=edit id=ConflictTest'),
|
||||
'//input[@name="oldtime"]/attribute::value');
|
||||
|
||||
sleep(2);
|
||||
|
||||
@@ -192,9 +191,8 @@ sleep(2);
|
||||
|
||||
update_page('ConflictTest', $lao_file);
|
||||
|
||||
$_ = `perl wiki.pl action=edit id=ConflictTest`;
|
||||
/name="oldtime" value="([0-9]+)"/;
|
||||
$oldtime = $1;
|
||||
$oldtime = xpath_test(get_page('action=edit id=ConflictTest'),
|
||||
'//input[@name="oldtime"]/attribute::value');
|
||||
|
||||
sleep(2);
|
||||
|
||||
|
||||
11
t/cookie.t
11
t/cookie.t
@@ -1,4 +1,4 @@
|
||||
# Copyright (C) 2009 Alex Schroeder <alex@gnu.org>
|
||||
# Copyright (C) 2009, 2012 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
|
||||
@@ -15,7 +15,8 @@
|
||||
|
||||
require 't/test.pl';
|
||||
package OddMuse;
|
||||
use Test::More tests => 16;
|
||||
use Test::More tests => 18;
|
||||
use utf8;
|
||||
|
||||
clear_pages();
|
||||
|
||||
@@ -78,4 +79,10 @@ SKIP: {
|
||||
$response = $ua->get("$wiki?action=debug;pwd=");
|
||||
test_page($ua->cookie_jar->as_string, 'Set-Cookie.*: Wiki=""');
|
||||
|
||||
# Encoding issues
|
||||
$response = $ua->get("$wiki?action=rc;username=Alex\%20Schr\%C3\%B6der");
|
||||
test_page($ua->cookie_jar->as_string,
|
||||
'Set-Cookie.*: Wiki=username%251eAlex%20Schr%C3%B6der');
|
||||
test_page($response->decoded_content,
|
||||
'Cookie: Wiki, username=Alex Schröder');
|
||||
};
|
||||
|
||||
@@ -29,7 +29,10 @@ test_page_negative($page, 'mu');
|
||||
AppendStringToFile($ConfigFile, "\$UploadAllowed = 1;\n");
|
||||
test_page(update_page('Alex', "#FILE image/png\niVBORw0KGgoAAAA"),
|
||||
'This page contains an uploaded file:');
|
||||
$page = get_page('action=download id=Alex');
|
||||
{
|
||||
local $raw = 1;
|
||||
$page = get_page('action=download id=Alex');
|
||||
}
|
||||
$page =~ s/^.*\r\n\r\n//s; # strip headers
|
||||
require MIME::Base64;
|
||||
test_page(MIME::Base64::encode($page), '^iVBORw0KGgoAAAA');
|
||||
|
||||
24
t/dotfiles.t
Normal file
24
t/dotfiles.t
Normal file
@@ -0,0 +1,24 @@
|
||||
# Copyright (C) 2012 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/>.
|
||||
|
||||
require 't/test.pl';
|
||||
package OddMuse;
|
||||
use Test::More tests => 4;
|
||||
|
||||
clear_pages();
|
||||
|
||||
test_page(update_page('Test', 'some text'), 'some text');
|
||||
test_page(update_page('.emacs', 'some code'), 'some code');
|
||||
unlink $IndexFile;
|
||||
test_page(get_page('action=index raw=1'), 'Test', '\.emacs');
|
||||
15
t/download.t
15
t/download.t
@@ -14,7 +14,7 @@
|
||||
|
||||
require 't/test.pl';
|
||||
package OddMuse;
|
||||
use Test::More tests => 12;
|
||||
use Test::More tests => 13;
|
||||
|
||||
clear_pages();
|
||||
|
||||
@@ -25,7 +25,15 @@ AppendStringToFile($ConfigFile, "\$LogoUrl = '/pic/logo.png';\n");
|
||||
xpath_test(get_page('HomePage'), '//a[@class="logo"]/img[@class="logo"][@src="/pic/logo.png"][@alt="[Home]"]');
|
||||
AppendStringToFile($ConfigFile, "\$LogoUrl = 'Logo';\n");
|
||||
xpath_test(get_page('HomePage'), '//a[@class="logo"]/img[@class="logo"][@src="Logo"][@alt="[Home]"]');
|
||||
|
||||
update_page('Logo', "#FILE image/png\niVBORw0KGgoAAAA");
|
||||
|
||||
# make sure we don't supply "content-type: image/png; charset=utf-8"
|
||||
{
|
||||
local $raw = 1;
|
||||
test_page_negative(get_page('action=download id=Logo'), 'charset');
|
||||
}
|
||||
|
||||
xpath_test(get_page('HomePage'), '//a[@class="logo"]/img[@class="logo"][@src="http://localhost/wiki.pl/download/Logo"][@alt="[Home]"]');
|
||||
AppendStringToFile($ConfigFile, "\$UsePathInfo = 0;\n");
|
||||
xpath_test(get_page('HomePage'), '//a[@class="logo"]/img[@class="logo"][@src="http://localhost/wiki.pl?action=download;id=Logo"][@alt="[Home]"]');
|
||||
@@ -46,7 +54,10 @@ test_page(update_page('Trogs', $page), 'contains an uploaded file');
|
||||
|
||||
xpath_test(get_page('Trogs'),
|
||||
'//p/img[@class="upload"][@src="http://localhost/wiki.pl?action=download;id=Trogs"][@alt="Trogs"]');
|
||||
$page = get_page('action=download id=Trogs');
|
||||
{
|
||||
local $raw = 1;
|
||||
$page = get_page('action=download id=Trogs');
|
||||
}
|
||||
test_page($page,
|
||||
'Content-Type: image/svg\+xml',
|
||||
'Content-encoding: gzip');
|
||||
|
||||
34
t/drafts.t
34
t/drafts.t
@@ -1,24 +1,21 @@
|
||||
# Copyright (C) 2006 Alex Schroeder <alex@emacswiki.org>
|
||||
# Copyright (C) 2006, 2012 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 2 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 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.
|
||||
# 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
|
||||
# You should have received a copy of the GNU General Public License along with
|
||||
# this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
require 't/test.pl';
|
||||
package OddMuse;
|
||||
use Test::More tests => 23;
|
||||
use Test::More tests => 26;
|
||||
use utf8;
|
||||
|
||||
clear_pages();
|
||||
|
||||
@@ -77,3 +74,10 @@ utime($Now-1300000, $Now-1300000, "$DraftDir/Alex");
|
||||
# Second maintenance requires admin password and deletes one draft
|
||||
test_page(get_page('action=maintain pwd=foo'), 'Alex was last modified [^<>]* ago and was deleted');
|
||||
ok(! -f "$DraftDir/.berta", "$DraftDir/Alex is gone");
|
||||
|
||||
# Testing UTF-8
|
||||
# Saving draft uses 204 No Content status
|
||||
test_page(get_page('title=HomePage text=foo username=Schröder Draft=1'),
|
||||
'Status: 204', 'username%251eSchr%C3%B6der');
|
||||
test_page(get_page('action=maintain pwd=foo'),
|
||||
'Schröder was last modified [^<>]* and was kept');
|
||||
|
||||
@@ -14,7 +14,8 @@
|
||||
|
||||
require 't/test.pl';
|
||||
package OddMuse;
|
||||
use Test::More tests => 9;
|
||||
use Test::More tests => 11;
|
||||
use utf8; # tests contain UTF-8 characters and it matters
|
||||
|
||||
clear_pages();
|
||||
|
||||
@@ -35,12 +36,16 @@ test_page(update_page('Comments_on_2011-07-06', 'Yo'),
|
||||
'Yo');
|
||||
|
||||
xpath_test(get_page('Hi'),
|
||||
'//div[@class="journal"]/div[@class="page"]/p[@class="comment"]/a[@href="javascript:togglecomments(\'Comments_on_2011-07-06\')"][text()="Comments on 2011-07-06"]');
|
||||
'//div[@class="journal"]/div[@class="page"]/p[@class="comment"]/a[@href="javascript:togglecomments(\'id0\')"][text()="Comments on 2011-07-06"]');
|
||||
|
||||
# encoding basics
|
||||
$page = update_page('2011-07-06_(…)_Dü', 'Hallo Dü');
|
||||
test_page($page, 'Hallo Dü');
|
||||
xpath_test($page, '//p[contains(text(), "Dü")]');
|
||||
|
||||
update_page('2011-07-06_(…)_Dü', 'Hallo');
|
||||
update_page('Comments_on_2011-07-06_(…)_Dü', 'Yo');
|
||||
|
||||
xpath_test(update_page('Hi', '<journal>'),
|
||||
'//h1/a[text()="2011-07-06 (…) Dü"]',
|
||||
'//div[@class="journal"]/div[@class="page"]/p[@class="comment"]/a[text()="Comments on 2011-07-06 (…) Dü"]',
|
||||
'//div[@class="journal"]/div[@class="page"]/p[@class="comment"]/a[@href="javascript:togglecomments(\'Comments_on_2011-07-06__Dü\')"]');
|
||||
'//div[@class="journal"]/div[@class="page"]/p[@class="comment"]/a[@href="javascript:togglecomments(\'id0\')"]');
|
||||
|
||||
116
t/encoding.t
Normal file
116
t/encoding.t
Normal file
@@ -0,0 +1,116 @@
|
||||
# Copyright (C) 2012 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/>.
|
||||
|
||||
require 't/test.pl';
|
||||
package OddMuse;
|
||||
use Test::More tests => 41;
|
||||
use utf8; # tests contain UTF-8 characters and it matters
|
||||
|
||||
clear_pages();
|
||||
|
||||
# ASCII basics
|
||||
|
||||
$page = update_page('Aal', 'aal');
|
||||
test_page($page, '<h1><a .*>Aal</a></h1>', '<p>aal</p>');
|
||||
xpath_test($page, '//h1/a[text()="Aal"]', '//p[text()="aal"]');
|
||||
|
||||
$page = get_page('Aal');
|
||||
test_page($page, '<h1><a .*>Aal</a></h1>', '<p>aal</p>');
|
||||
xpath_test($page, '//h1/a[text()="Aal"]', '//p[text()="aal"]');
|
||||
|
||||
# non-ASCII
|
||||
|
||||
$page = update_page('Öl', 'öl');
|
||||
test_page($page, '<h1><a .*>Öl</a></h1>', '<p>öl</p>');
|
||||
xpath_test($page, '//h1/a[text()="Öl"]', '//p[text()="öl"]');
|
||||
|
||||
$page = get_page('Öl');
|
||||
test_page($page, '<h1><a .*>Öl</a></h1>', '<p>öl</p>');
|
||||
xpath_test($page, '//h1/a[text()="Öl"]', '//p[text()="öl"]');
|
||||
|
||||
$page = get_page('action=index raw=1');
|
||||
test_page($page, 'Aal', 'Öl');
|
||||
|
||||
test_page(get_page('Aal'), 'aal');
|
||||
test_page(get_page('Öl'), 'öl');
|
||||
|
||||
# rc
|
||||
|
||||
test_page(get_page('action=rc raw=1'),
|
||||
'title: Öl', 'description: öl');
|
||||
|
||||
# diff
|
||||
|
||||
update_page('Öl', 'Ähren');
|
||||
xpath_test(get_page('action=browse id=Öl diff=1'),
|
||||
'//div[@class="old"]/p/strong[@class="changes"][text()="öl"]',
|
||||
'//div[@class="new"]/p/strong[@class="changes"][text()="Ähren"]');
|
||||
|
||||
# search
|
||||
|
||||
# testing with non-ASCII is important on a Mac
|
||||
|
||||
# ASCII
|
||||
$page = get_page('search=aal raw=1');
|
||||
test_page($page, 'title: Search for: aal', 'title: Aal');
|
||||
|
||||
# matching page name does not involve grep working
|
||||
$page = get_page('search=öl raw=1');
|
||||
test_page($page, 'title: Search for: öl', 'title: Öl');
|
||||
|
||||
# this fails with grep on a Mac, thus testing if mac.pl
|
||||
# managed to switch of the use of grep
|
||||
test_page(get_page('search=ähren raw=1'),
|
||||
'title: Search for: ähren', 'title: Öl');
|
||||
|
||||
# the username keeps getting reported as changed
|
||||
test_page(get_page('action=browse id=Möglich username=Schr%C3%B6der'),
|
||||
'Set-Cookie: Wiki=username%251eSchr%C3%B6der',
|
||||
'username=Schröder');
|
||||
|
||||
# verify that non-ASCII parameters work as intended
|
||||
AppendStringToFile($ConfigFile, "use utf8;\n\$CookieParameters{ärger} = 1;\n");
|
||||
test_page(get_page('action=browse id=Test %C3%A4rger=hallo'),
|
||||
'Set-Cookie: Wiki=%C3%A4rger%251ehallo');
|
||||
|
||||
# this causes wide character in print somehow? otherwise harmless
|
||||
test_page(update_page("Russian", "Русский Hello"),
|
||||
"Русский");
|
||||
|
||||
# checking for errors in the rss feed
|
||||
test_page(get_page("action=rss match=Russian full=1"),
|
||||
"Русский");
|
||||
|
||||
# with toc.pl, however, a problem: Русский is corrupted
|
||||
add_module('toc.pl');
|
||||
test_page(update_page("Russian", "Русский Hello again"),
|
||||
"Русский");
|
||||
|
||||
# and with inclusion, too:
|
||||
test_page(update_page("All", qq{<include "Russian">}),
|
||||
"Русский");
|
||||
|
||||
# and checking the cache
|
||||
test_page(get_page("All"), "Русский");
|
||||
|
||||
# and checking without the cache
|
||||
test_page(get_page("action=browse id=All cache=0"), "Русский");
|
||||
|
||||
# testing search
|
||||
test_page(get_page('search=Русский raw=1'),
|
||||
qw(Russian));
|
||||
|
||||
# testing page editing
|
||||
test_page(update_page("Русский", "друзья"),
|
||||
"друзья");
|
||||
33
t/fix-encoding.t
Normal file
33
t/fix-encoding.t
Normal file
@@ -0,0 +1,33 @@
|
||||
# Copyright (C) 2012 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/>.
|
||||
|
||||
require 't/test.pl';
|
||||
package OddMuse;
|
||||
use Test::More tests => 5;
|
||||
use utf8; # tests contain UTF-8 characters and it matters
|
||||
|
||||
clear_pages();
|
||||
add_module('fix-encoding.pl');
|
||||
|
||||
test_page_negative(get_page('action=admin'), 'action=fix-encoding');
|
||||
test_page(get_page('action=admin id=foo'), 'action=fix-encoding;id=foo');
|
||||
|
||||
test_page(update_page('Example', 'Pilgerstätte für die Göttin'),
|
||||
'Pilgerstätte für die Göttin');
|
||||
|
||||
test_page(get_page('action=fix-encoding id=Example'),
|
||||
'Location: http://localhost/wiki.pl/Example');
|
||||
|
||||
test_page(get_page('Example'),
|
||||
'Pilgerstätte für die Göttin');
|
||||
@@ -15,6 +15,7 @@
|
||||
require 't/test.pl';
|
||||
package OddMuse;
|
||||
use Test::More tests => 33;
|
||||
use utf8; # tests contain UTF-8 characters and it matters
|
||||
|
||||
clear_pages();
|
||||
|
||||
|
||||
@@ -16,6 +16,7 @@
|
||||
require 't/test.pl';
|
||||
package OddMuse;
|
||||
use Test::More tests => 61;
|
||||
use utf8; # tests contain UTF-8 characters and it matters
|
||||
|
||||
SKIP: {
|
||||
eval { require Search::FreeText };
|
||||
|
||||
@@ -19,6 +19,7 @@
|
||||
require 't/test.pl';
|
||||
package OddMuse;
|
||||
use Test::More tests => 5;
|
||||
use utf8; # tests contain UTF-8 characters and it matters
|
||||
|
||||
%Languages = ('de' => '\b(der|die|das|und|oder)\b',
|
||||
'fr' => '\b(et|le|la|pas)\b', );
|
||||
|
||||
@@ -122,12 +122,10 @@ i"m tired
|
||||
i"m tired
|
||||
He said, "[w]hen I voice complaints..."
|
||||
He said, “[w]hen I voice complaints…”
|
||||
[foo]'s problem
|
||||
[foo]’s problem
|
||||
EOT
|
||||
|
||||
xpath_run_tests("[http://foo.org/ foo]'s problem",
|
||||
'//a[@class="url http outside"][@href="http://foo.org/"][text()="foo"]'
|
||||
. '/following-sibling::text()[string()="’s problem"]');
|
||||
|
||||
$MarkupQuotes = 0;
|
||||
run_tests(q{"Get lost!", they say, and I answer: "I'm not 'lost'!"},
|
||||
q{"Get lost!", they say, and I answer: "I'm not 'lost'!"});
|
||||
|
||||
@@ -1,21 +1,22 @@
|
||||
# Copyright (C) 2006, 2007, 2008, 2009 Alex Schroeder <alex@gnu.org>
|
||||
# Copyright (C) 2006, 2007, 2008, 2009, 2012 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 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.
|
||||
# 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/>.
|
||||
# You should have received a copy of the GNU General Public License along with
|
||||
# this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
require 't/test.pl';
|
||||
package OddMuse;
|
||||
use Test::More tests => 71;
|
||||
use Test::More tests => 73;
|
||||
use utf8; # tests contain UTF-8 characters and it matters
|
||||
|
||||
clear_pages();
|
||||
|
||||
add_module('namespaces.pl');
|
||||
@@ -112,15 +113,20 @@ test_page(get_page('action=rss'),
|
||||
'<link>http://localhost/wiki.pl/Muu/Mu</link>',
|
||||
'<wiki:history>http://localhost/wiki.pl/Muu\?action=history;id=Mu</wiki:history>',
|
||||
'<wiki:diff>http://localhost/wiki.pl/Muu\?action=browse;diff=1;id=Mu</wiki:diff>');
|
||||
# Test non-ASCII characters in namespaces
|
||||
# Test Unicode characters in namespaces (BLACK HEART SUIT)
|
||||
test_page(update_page('Umlaute', 'namespace mit herz',
|
||||
'wo steckt das ü', undef, undef,
|
||||
'ns=Zürich♥'), 'namespace mit herz');
|
||||
xpath_test(get_page('action=rc'),
|
||||
# the exact result depends on filesystem encoding!
|
||||
'//a[@class="local"][@href="http://localhost/wiki.pl/Z%c3%bcrich%e2%99%a5/Umlaute"]');
|
||||
# Test potential Latin-1 characters in namespaces (LATIN SMALL LETTER U DIAERESIS)
|
||||
test_page(update_page('Umlaute', 'namespace mit umlaut',
|
||||
'wo steckt das ü', undef, undef,
|
||||
'ns=Zürich'), 'namespace mit umlaut');
|
||||
xpath_test(get_page('action=rc'),
|
||||
# the exact result depends on filesystem encoding!
|
||||
'//a[@class="local"][@href="http://localhost/wiki.pl/Zu%cc%88rich/Umlaute"'
|
||||
. ' or @href="http://localhost/wiki.pl/Zu%fcrich/Umlaute"'
|
||||
. ' or @href="http://localhost/wiki.pl/Z%c3%bcrich/Umlaute"]');
|
||||
'//a[@class="local"][@href="http://localhost/wiki.pl/Z%c3%bcrich/Umlaute"]');
|
||||
|
||||
# Test rollbacks
|
||||
test_page(get_page('action=browse ns=Muu id=Test'),
|
||||
|
||||
@@ -16,6 +16,8 @@
|
||||
require 't/test.pl';
|
||||
package OddMuse;
|
||||
use Test::More tests => 25;
|
||||
use utf8; # tests contain UTF-8 characters and it matters
|
||||
|
||||
clear_pages();
|
||||
|
||||
add_module('permanent-anchors.pl');
|
||||
@@ -57,7 +59,7 @@ $page = update_page('Keith_Jarret', 'plays unlike [::Thelonius Mönk]');
|
||||
like($page, qr(the page (.*?) also exists), 'the page ... also exists');
|
||||
$page =~ qr(the page (.*?) also exists);
|
||||
$link = $1;
|
||||
xpath_test($link, Encode::encode_utf8('//a[@class="local"][@href="http://localhost/wiki.pl?action=browse;anchor=0;id=Thelonius_M%c3%b6nk"][text()="Thelonius Mönk"]'));
|
||||
xpath_test($link, '//a[@class="local"][@href="http://localhost/wiki.pl?action=browse;anchor=0;id=Thelonius_M%c3%b6nk"][text()="Thelonius Mönk"]');
|
||||
# verify that the redirection works
|
||||
test_page(get_page('action=browse id=Thelonius_Mönk'),
|
||||
'Status: 302',
|
||||
|
||||
@@ -16,6 +16,7 @@
|
||||
require 't/test.pl';
|
||||
package OddMuse;
|
||||
use Test::More tests => 9;
|
||||
use utf8; # tests contain UTF-8 characters and it matters
|
||||
|
||||
clear_pages();
|
||||
|
||||
|
||||
@@ -19,6 +19,7 @@ require 't/test.pl';
|
||||
package OddMuse;
|
||||
|
||||
use Test::More tests => 10; # update two numbers below!
|
||||
use utf8; # tests contain UTF-8 characters and it matters
|
||||
|
||||
SKIP: {
|
||||
|
||||
|
||||
@@ -16,6 +16,7 @@
|
||||
require 't/test.pl';
|
||||
package OddMuse;
|
||||
use Test::More tests => 63;
|
||||
use utf8; # tests contain UTF-8 characters and it matters
|
||||
|
||||
clear_pages();
|
||||
WriteStringToFile($RcFile, "1FirstPage1\n");
|
||||
|
||||
1
t/rss.t
1
t/rss.t
@@ -16,6 +16,7 @@
|
||||
require 't/test.pl';
|
||||
package OddMuse;
|
||||
use Test::More tests => 100;
|
||||
use utf8; # tests contain UTF-8 characters and it matters
|
||||
|
||||
clear_pages();
|
||||
AppendStringToFile($ConfigFile, "\$CommentsPrefix = 'Comments on ';\n");
|
||||
|
||||
@@ -16,6 +16,7 @@
|
||||
require 't/test.pl';
|
||||
package OddMuse;
|
||||
use Test::More tests => 38;
|
||||
use utf8; # tests contain UTF-8 characters and it matters
|
||||
|
||||
clear_pages();
|
||||
|
||||
|
||||
34
t/tags.t
34
t/tags.t
@@ -16,6 +16,8 @@
|
||||
require 't/test.pl';
|
||||
package OddMuse;
|
||||
use Test::More tests => 70;
|
||||
use utf8;
|
||||
|
||||
clear_pages();
|
||||
|
||||
add_module('tags.pl');
|
||||
@@ -43,7 +45,7 @@ xpath_run_tests(split('\n',<<'EOT'));
|
||||
EOT
|
||||
|
||||
update_page('Brilliant', 'Gameologists [[tag:podcast]] [[tag:mag]]');
|
||||
update_page('Podgecast', 'Another [[tag:podcast]]');
|
||||
update_page('Pödgecäst', 'Another [[tag:podcast]]');
|
||||
update_page('Alex', 'Me! [[tag:Old School]]');
|
||||
|
||||
# open the DB file
|
||||
@@ -53,11 +55,11 @@ tie %h, "DB_File", $TagFile;
|
||||
%tag = map {$_=>1} split($FS, $h{"_Brilliant"});
|
||||
ok($tag{podcast}, 'Brilliant page tagged podcast');
|
||||
ok($tag{mag}, 'Brilliant page tagged mag');
|
||||
%tag = map {$_=>1} split($FS, $h{"_Podgecast"});
|
||||
ok($tag{podcast}, 'Podgecast page tagged podcast');
|
||||
%tag = map {$_=>1} split($FS, $h{"_Pödgecäst"});
|
||||
ok($tag{podcast}, 'Pödgecäst page tagged podcast');
|
||||
%file = map {$_=>1} split($FS, $h{"podcast"});
|
||||
ok($file{Brilliant}, 'Tag podcast applies to page Brilliant');
|
||||
ok($file{Podgecast}, 'Tag podcast applies to page Podgecast');
|
||||
ok($file{Pödgecäst}, 'Tag podcast applies to page Pödgecäst');
|
||||
%file = map {$_=>1} split($FS, $h{"mag"});
|
||||
ok($file{Brilliant}, 'Tag mag applies to page Brilliant');
|
||||
%file = map {$_=>1} split($FS, $h{"old_school"});
|
||||
@@ -76,7 +78,7 @@ ok(!$tag{podcast}, 'Brilliant page no longer tagged podcast');
|
||||
ok($tag{mag}, 'Brilliant page still tagged mag');
|
||||
%file = map {$_=>1} split($FS, $h{"podcast"});
|
||||
ok(!$file{Brilliant}, 'Tag podcast no longer applies to page Brilliant');
|
||||
ok($file{Podgecast}, 'Tag podcast still applies to page Podgecast');
|
||||
ok($file{Pödgecäst}, 'Tag podcast still applies to page Pödgecäst');
|
||||
|
||||
# close the DB file before making changes via the wiki!
|
||||
untie %h;
|
||||
@@ -99,46 +101,46 @@ update_page('Jeff', 'a blog [[tag:Old School]]');
|
||||
|
||||
# ordinary search finds Alex
|
||||
$page = get_page('search=podcast raw=1');
|
||||
test_page($page, qw(Podgecast Brilliant Sons Alex));
|
||||
test_page($page, qw(Pödgecäst Brilliant Sons Alex));
|
||||
|
||||
# tag search skips Alex
|
||||
$page = get_page('search=tag:podcast raw=1');
|
||||
test_page($page, qw(Podgecast Brilliant Sons));
|
||||
test_page($page, qw(Pödgecäst Brilliant Sons));
|
||||
test_page_negative($page, qw(Alex));
|
||||
|
||||
# tag search is case insensitive
|
||||
$page = get_page('search=tag:PODCAST raw=1');
|
||||
test_page($page, qw(Podgecast Brilliant Sons));
|
||||
test_page($page, qw(Pödgecäst Brilliant Sons));
|
||||
test_page_negative($page, qw(Alex));
|
||||
|
||||
# exclude tag search skips Brilliant
|
||||
$page = get_page('search=-tag:mag raw=1');
|
||||
test_page($page, qw(Podgecast Sons Alex));
|
||||
test_page($page, qw(Pödgecäst Sons Alex));
|
||||
test_page_negative($page, qw(Brilliant));
|
||||
|
||||
# combine include and exclude tag search to exclude both Alex and
|
||||
# Brilliant
|
||||
$page = get_page('search=tag:podcast%20-tag:mag raw=1');
|
||||
test_page($page, qw(Podgecast Sons));
|
||||
test_page($page, qw(Pödgecäst Sons));
|
||||
test_page_negative($page, qw(Brilliant Alex));
|
||||
|
||||
# combine ordinary search with include and exclude tag search to
|
||||
# exclude both Alex and Brilliant
|
||||
$page = get_page('search=kryos%20tag:podcast%20-tag:mag raw=1');
|
||||
test_page($page, qw(Sons));
|
||||
test_page_negative($page, qw(Podgecast Brilliant Alex));
|
||||
test_page_negative($page, qw(Pödgecäst Brilliant Alex));
|
||||
|
||||
# search for a tag containing spaces
|
||||
$page = get_page('search=tag:old_school raw=1');
|
||||
test_page($page, qw(Jeff));
|
||||
test_page_negative($page, qw(Sons Podgecast Brilliant Alex));
|
||||
test_page_negative($page, qw(Sons Pödgecäst Brilliant Alex));
|
||||
|
||||
test_page(get_page('action=reindex pwd=foo'),
|
||||
qw(Podgecast Brilliant Sons Alex));
|
||||
qw(Pödgecäst Brilliant Sons Alex));
|
||||
|
||||
# tag search skips Alex -- repeat test after reindexing
|
||||
$page = get_page('search=tag:podcast raw=1');
|
||||
test_page($page, qw(Podgecast Brilliant Sons));
|
||||
test_page($page, qw(Pödgecäst Brilliant Sons));
|
||||
test_page_negative($page, qw(Alex));
|
||||
|
||||
add_module('near-links.pl');
|
||||
@@ -158,7 +160,7 @@ test_page_negative($page, qw(AlexSchroeder Foo));
|
||||
|
||||
# check journal pages
|
||||
$page = update_page('Podcasts', '<journal "." search tag:podcast>');
|
||||
test_page($page, qw(Podgecast Brilliant Sons));
|
||||
test_page($page, qw(Pödgecäst Brilliant Sons));
|
||||
test_page_negative($page, qw(Alex Foo));
|
||||
|
||||
# check the tag cloud
|
||||
@@ -175,4 +177,4 @@ AppendStringToFile($ConfigFile, "\$LocalNamesCollect = 1;\n");
|
||||
update_page('LocalNames', 'test');
|
||||
update_page('Alex', 'is a [[tag:podcast]] after all');
|
||||
$page = get_page('search=tag:podcast raw=1');
|
||||
test_page($page, qw(Podgecast Brilliant Sons Alex));
|
||||
test_page($page, qw(Pödgecäst Brilliant Sons Alex));
|
||||
|
||||
86
t/test.pl
86
t/test.pl
@@ -1,32 +1,33 @@
|
||||
# Copyright (C) 2004, 2005, 2006, 2008 Alex Schroeder <alex@gnu.org>
|
||||
# Copyright (C) 2004, 2005, 2006, 2008, 2012 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 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.
|
||||
# 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/>.
|
||||
# You should have received a copy of the GNU General Public License along with
|
||||
# this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
package OddMuse;
|
||||
use lib '.';
|
||||
use XML::LibXML;
|
||||
use Encode;
|
||||
use utf8;
|
||||
use vars qw($raw);
|
||||
|
||||
# Import the functions
|
||||
|
||||
$raw = 0; # capture utf8 is the default
|
||||
$RunCGI = 0; # don't print HTML on stdout
|
||||
$UseConfig = 0; # don't read module files
|
||||
$DataDir = 'test-data';
|
||||
$ENV{WikiDataDir} = $DataDir;
|
||||
require 'wiki.pl';
|
||||
$ENV{PATH} = '/usr/local/bin:' . $ENV{PATH}; # location of perl?
|
||||
Init();
|
||||
|
||||
use vars qw($redirect);
|
||||
|
||||
undef $/;
|
||||
@@ -35,6 +36,7 @@ $| = 1; # no output buffering
|
||||
sub url_encode {
|
||||
my $str = shift;
|
||||
return '' unless $str;
|
||||
utf8::encode($str); # turn to byte string
|
||||
my @letters = split(//, $str);
|
||||
my @safe = ('a' .. 'z', 'A' .. 'Z', '0' .. '9', '-', '_', '.'); # shell metachars are unsafe
|
||||
foreach my $letter (@letters) {
|
||||
@@ -46,6 +48,25 @@ sub url_encode {
|
||||
return join('', @letters);
|
||||
}
|
||||
|
||||
# Run perl in a subprocess and make sure it prints UTF-8 and not Latin-1
|
||||
# If you use the download action, the output will be raw bytes. Use
|
||||
# something like the following:
|
||||
# {
|
||||
# local $raw = 1;
|
||||
# $page = get_page('action=download id=Trogs');
|
||||
# }
|
||||
sub capture {
|
||||
my $command = shift;
|
||||
if ($raw) {
|
||||
open (CL, '-|', $command) or die "Can't run $command: $!";
|
||||
} else {
|
||||
open (CL, '-|:encoding(utf-8)', $command) or die "Can't run $command: $!";
|
||||
}
|
||||
my $result = <CL>;
|
||||
close CL;
|
||||
return $result;
|
||||
}
|
||||
|
||||
sub update_page {
|
||||
my ($id, $text, $summary, $minor, $admin, @rest) = @_;
|
||||
my $pwd = $admin ? 'foo' : 'wrong';
|
||||
@@ -54,8 +75,8 @@ sub update_page {
|
||||
$summary = url_encode($summary);
|
||||
$minor = $minor ? 'on' : 'off';
|
||||
my $rest = join(' ', @rest);
|
||||
$redirect = `perl wiki.pl 'Save=1' 'title=$page' 'summary=$summary' 'recent_edit=$minor' 'text=$text' 'pwd=$pwd' $rest`;
|
||||
$output = `perl wiki.pl action=browse id=$page $rest`;
|
||||
$redirect = capture("perl wiki.pl 'Save=1' 'title=$page' 'summary=$summary' 'recent_edit=$minor' 'text=$text' 'pwd=$pwd' $rest");
|
||||
$output = capture("perl wiki.pl action=browse id=$page $rest");
|
||||
if ($redirect =~ /^Status: 302 /) {
|
||||
# just in case a new page got created or NearMap or InterMap
|
||||
$IndexHash{$id} = 1;
|
||||
@@ -66,16 +87,14 @@ sub update_page {
|
||||
}
|
||||
|
||||
sub get_page {
|
||||
open(F, "perl wiki.pl @_ |");
|
||||
my $output = <F>;
|
||||
close F;
|
||||
return $output;
|
||||
return capture("perl wiki.pl @_");
|
||||
}
|
||||
|
||||
sub name {
|
||||
$_ = shift;
|
||||
s/\n/\\n/g;
|
||||
$_ = '...' . substr($_, -60) if length > 63;
|
||||
utf8::encode($_);
|
||||
return $_;
|
||||
}
|
||||
|
||||
@@ -120,8 +139,8 @@ sub run_macro_tests {
|
||||
# one string, many tests
|
||||
sub test_page {
|
||||
my $page = shift;
|
||||
foreach my $str (@_) {
|
||||
like($page, qr($str), name($str));
|
||||
foreach my $test (@_) {
|
||||
like($page, qr($test), name($test));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -147,10 +166,19 @@ sub xpath_do {
|
||||
skip("Cannot parse ".name($page).": $@", $#tests + 1) if $@;
|
||||
foreach my $test (@tests) {
|
||||
my $nodelist;
|
||||
eval { $nodelist = $doc->findnodes($test) };
|
||||
my $bytes = $test;
|
||||
# utf8::encode: Converts in-place the character sequence to the
|
||||
# corresponding octet sequence in *UTF-X*. The UTF8 flag is
|
||||
# turned off, so that after this operation, the string is a byte
|
||||
# string. (I have no idea why this is necessary, but there you
|
||||
# go. See encoding.t tests and make sure the page file is
|
||||
# encoded correctly.)
|
||||
utf8::encode($bytes);
|
||||
eval { $nodelist = $doc->findnodes($bytes) };
|
||||
if ($@) {
|
||||
fail(&$check(1) ? "$test: $@" : "not $test: $@");
|
||||
} elsif (ok(&$check($nodelist->size()), name(&$check(1) ? $test : "not $test"))) {
|
||||
} elsif (ok(&$check($nodelist->size()),
|
||||
name(&$check(1) ? $test : "not $test"))) {
|
||||
$result .= $nodelist->string_value();
|
||||
} else {
|
||||
$page =~ s/^.*?<html/<html/s;
|
||||
@@ -201,16 +229,18 @@ sub remove_rule {
|
||||
}
|
||||
|
||||
sub add_module {
|
||||
my $mod = shift;
|
||||
my ($mod, $subdir) = @_;
|
||||
$subdir .= '/' if $subdir and substr($subdir, -1) ne '/';
|
||||
my $filename =
|
||||
mkdir $ModuleDir unless -d $ModuleDir;
|
||||
my $dir = `/bin/pwd`;
|
||||
chop($dir);
|
||||
if (-l "$ModuleDir/$mod") {
|
||||
# do nothing
|
||||
} elsif (eval{ symlink("$dir/modules/$mod", "$ModuleDir/$mod"); 1; }) {
|
||||
} elsif (eval{ symlink("$dir/modules/$subdir$mod", "$ModuleDir/$mod"); 1; }) {
|
||||
# do nothing
|
||||
} else {
|
||||
system("copy '$dir/modules/$mod' '$ModuleDir/$mod'");
|
||||
system("copy '$dir/modules/$subdir$mod' '$ModuleDir/$mod'");
|
||||
}
|
||||
die "Cannot symlink $mod: $!" unless -e "$ModuleDir/$mod";
|
||||
do "$ModuleDir/$mod";
|
||||
@@ -231,7 +261,8 @@ sub clear_pages {
|
||||
}
|
||||
die "Cannot remove $DataDir!\n" if -e $DataDir;
|
||||
mkdir $DataDir;
|
||||
open(F,">$DataDir/config");
|
||||
add_module('mac.pl') if $^O eq 'darwin'; # guessing HFS filesystem
|
||||
open(F, '>:encoding(utf-8)', "$DataDir/config");
|
||||
print F "\$AdminPass = 'foo';\n";
|
||||
# this used to be the default in earlier CGI.pm versions
|
||||
print F "\$ScriptName = 'http://localhost/wiki.pl';\n";
|
||||
@@ -240,6 +271,7 @@ sub clear_pages {
|
||||
$ScriptName = 'http://localhost/test.pl'; # different!
|
||||
$IndexInit = 0;
|
||||
%IndexHash = ();
|
||||
@IndexList = ();
|
||||
$InterSiteInit = 0;
|
||||
%InterSite = ();
|
||||
$NearSiteInit = 0;
|
||||
|
||||
36
t/tex.t
36
t/tex.t
@@ -1,8 +1,8 @@
|
||||
# Copyright (C) 2006 Alex Schroeder <alex@emacswiki.org>
|
||||
# Copyright (C) 2012 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 2 of the License, or
|
||||
# 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,
|
||||
@@ -11,22 +11,28 @@
|
||||
# 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
|
||||
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
require 't/test.pl';
|
||||
package OddMuse;
|
||||
use Test::More tests => 3;
|
||||
use Test::More tests => 4;
|
||||
use utf8; # tests contain UTF-8 characters and it matters
|
||||
|
||||
clear_pages();
|
||||
add_module('tex.pl');
|
||||
|
||||
run_macro_tests(split('\n',<<'EOT'));
|
||||
4\times 7
|
||||
4×7
|
||||
right\copyright
|
||||
right©
|
||||
a\infty b
|
||||
a∞b
|
||||
EOT
|
||||
test_page(update_page('Example', '4\times7 right\copyright a\inftyb'),
|
||||
qw(4×7 right© a∞b));
|
||||
|
||||
ok($Tex{'\textreferencemark'}, "TeX patterns ok");
|
||||
|
||||
# Create the table of documentation:
|
||||
# binmode(STDOUT, ':utf8');
|
||||
# my $i = 1;
|
||||
# foreach (sort keys %Tex) {
|
||||
# printf "||%s || %s ", $_, $Tex{$_};
|
||||
# if ($i % 5 == 0) {
|
||||
# print "||\n";
|
||||
# }
|
||||
# $i++;
|
||||
# }
|
||||
|
||||
@@ -16,11 +16,14 @@
|
||||
require 't/test.pl';
|
||||
package OddMuse;
|
||||
use Test::More tests => 20;
|
||||
use utf8; # tests contain UTF-8 characters and it matters
|
||||
|
||||
clear_pages();
|
||||
|
||||
add_module('translation-links.pl');
|
||||
|
||||
AppendStringToFile($ConfigFile, q{
|
||||
use utf8;
|
||||
%Languages = ('de' => '\b(der|die|das|und|oder)\b',
|
||||
'en' => '\b(the|he|she|that|this)\b');
|
||||
$Translate{de} = 'Deutsch';
|
||||
|
||||
28
t/translations.t
Normal file
28
t/translations.t
Normal file
@@ -0,0 +1,28 @@
|
||||
# Copyright (C) 2012 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/>.
|
||||
|
||||
require 't/test.pl';
|
||||
package OddMuse;
|
||||
use Test::More tests => 6;
|
||||
use utf8; # tests contain UTF-8 characters and it matters
|
||||
|
||||
clear_pages();
|
||||
|
||||
test_page(update_page('HomePage', 'tätärätää!'),
|
||||
'Edit this page', 'Last edited', 'tätärätää!');
|
||||
|
||||
add_module('german-utf8.pl', 'translations');
|
||||
|
||||
test_page(get_page('HomePage'),
|
||||
'Diese Seite bearbeiten', 'Zuletzt geändert', 'tätärätää!');
|
||||
227
wiki.pl
227
wiki.pl
@@ -1,8 +1,7 @@
|
||||
#! /usr/bin/perl
|
||||
# Version $Id: wiki.pl,v 1.960 2012/03/08 15:28:18 as Exp $
|
||||
# Copyleft 2008 Brian Curry <http://www.raiazome.com>
|
||||
# Copyright (C) 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010
|
||||
# Copyright (C) 2001-2012
|
||||
# Alex Schroeder <alex@gnu.org>
|
||||
# Copyleft 2008 Brian Curry <http://www.raiazome.com>
|
||||
# ... including lots of patches from the UseModWiki site
|
||||
# Copyright (C) 2001, 2002 various authors
|
||||
# ... which was based on UseModWiki version 0.92 (April 21, 2001)
|
||||
@@ -29,15 +28,12 @@
|
||||
# this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
package OddMuse;
|
||||
|
||||
use strict;
|
||||
use CGI;
|
||||
use CGI::Carp qw(fatalsToBrowser);
|
||||
use vars qw($VERSION);
|
||||
use File::Glob ':glob';
|
||||
local $| = 1; # Do not buffer output (localized for mod_perl)
|
||||
|
||||
$VERSION=(split(/ +/, q{$Revision: 1.960 $}))[1]; # for MakeMaker
|
||||
|
||||
# Options:
|
||||
use vars qw($RssLicense $RssCacheHours @RcDays $TempDir $LockDir $DataDir
|
||||
$KeepDir $PageDir $RcOldFile $IndexFile $BannedContent $NoEditFile $BannedHosts
|
||||
@@ -47,20 +43,19 @@ $EmbedWiki $BracketText $UseConfig $UseLookup $AdminPass $EditPass $NetworkFile
|
||||
$BracketWiki $FreeLinks $WikiLinks $SummaryHours $FreeLinkPattern $RCName
|
||||
$RunCGI $ShowEdits $LinkPattern $RssExclude $InterLinkPattern $MaxPost $UseGrep
|
||||
$UrlPattern $UrlProtocols $ImageExtensions $InterSitePattern $FS $CookieName
|
||||
$SiteBase $StyleSheet $NotFoundPg $FooterNote $NewText $EditNote $HttpCharset
|
||||
$UserGotoBar $VisitorFile $RcFile %Smilies %SpecialDays $InterWikiMoniker
|
||||
$SiteDescription $RssImageUrl $ReadMe $RssRights $BannedCanRead $SurgeProtection
|
||||
$TopLinkBar $LanguageLimit $SurgeProtectionTime $SurgeProtectionViews
|
||||
$DeletedPage %Languages $InterMap $ValidatorLink %LockOnCreation
|
||||
$RssStyleSheet %CookieParameters @UserGotoBarPages $NewComment $HtmlHeaders
|
||||
$StyleSheetPage $ConfigPage $ScriptName $CommentsPrefix @UploadTypes
|
||||
$AllNetworkFiles $UsePathInfo $UploadAllowed $LastUpdate $PageCluster
|
||||
%PlainTextPages $RssInterwikiTranslate $UseCache $Counter $ModuleDir
|
||||
$FullUrlPattern $SummaryDefaultLength $FreeInterLinkPattern
|
||||
%InvisibleCookieParameters %AdminPages $UseQuestionmark $JournalLimit
|
||||
$LockExpiration $RssStrip %LockExpires @IndexOptions @Debugging $DocumentHeader
|
||||
%HtmlEnvironmentContainers @MyAdminCode @MyFooters @MyInitVariables @MyMacros
|
||||
@MyMaintenance @MyRules);
|
||||
$SiteBase $StyleSheet $NotFoundPg $FooterNote $NewText $EditNote $UserGotoBar
|
||||
$VisitorFile $RcFile %Smilies %SpecialDays $InterWikiMoniker $SiteDescription
|
||||
$RssImageUrl $ReadMe $RssRights $BannedCanRead $SurgeProtection $TopLinkBar
|
||||
$LanguageLimit $SurgeProtectionTime $SurgeProtectionViews $DeletedPage
|
||||
%Languages $InterMap $ValidatorLink %LockOnCreation $RssStyleSheet
|
||||
%CookieParameters @UserGotoBarPages $NewComment $HtmlHeaders $StyleSheetPage
|
||||
$ConfigPage $ScriptName $CommentsPrefix @UploadTypes $AllNetworkFiles
|
||||
$UsePathInfo $UploadAllowed $LastUpdate $PageCluster %PlainTextPages
|
||||
$RssInterwikiTranslate $UseCache $Counter $ModuleDir $FullUrlPattern
|
||||
$SummaryDefaultLength $FreeInterLinkPattern %InvisibleCookieParameters
|
||||
%AdminPages $UseQuestionmark $JournalLimit $LockExpiration $RssStrip
|
||||
%LockExpires @IndexOptions @Debugging $DocumentHeader %HtmlEnvironmentContainers
|
||||
@MyAdminCode @MyFooters @MyInitVariables @MyMacros @MyMaintenance @MyRules);
|
||||
|
||||
# Internal variables:
|
||||
use vars qw(%Page %InterSite %IndexHash %Translate %OldCookie $FootnoteNumber
|
||||
@@ -95,7 +90,6 @@ $CookieName = 'Wiki'; # Name for this wiki (for multi-wiki sites)
|
||||
|
||||
$SiteBase = ''; # Full URL for <BASE> header
|
||||
$MaxPost = 1024 * 210; # Maximum 210K posts (about 200K for pages)
|
||||
$HttpCharset = 'UTF-8'; # You are on your own if you change this!
|
||||
$StyleSheet = ''; # URL for CSS stylesheet (like '/wiki.css')
|
||||
$StyleSheetPage = 'css'; # Page for CSS sheet
|
||||
$LogoUrl = ''; # URL for site logo ('' for no logo)
|
||||
@@ -207,7 +201,7 @@ sub DoWikiRequest {
|
||||
|
||||
sub ReportError { # fatal!
|
||||
my ($errmsg, $status, $log, @html) = @_;
|
||||
$q = new CGI unless $q; # make sure we can report errors before InitRequest
|
||||
InitRequest(); # make sure we can report errors before InitRequest
|
||||
print GetHttpHeader('text/html', 'nocache', $status), GetHtmlHeader(T('Error')),
|
||||
$q->start_div({class=>"error"}), $q->h1(QuoteHtml($errmsg)), @html, $q->end_div,
|
||||
$q->end_html, "\n\n"; # newlines for FCGI because of exit()
|
||||
@@ -217,22 +211,21 @@ sub ReportError { # fatal!
|
||||
}
|
||||
|
||||
sub Init {
|
||||
binmode(STDOUT, ':utf8');
|
||||
InitDirConfig();
|
||||
$FS = "\x1e"; # The FS character is the RECORD SEPARATOR control char in ASCII
|
||||
$Message = ''; # Warnings and non-fatal errors.
|
||||
InitLinkPatterns(); # Link pattern can be changed in config files
|
||||
InitModules(); # Modules come first so that users can change module variables in config
|
||||
InitConfig(); # Config comes as early as possible; remember $q is not available here
|
||||
InitRequest(); # get $q with $MaxPost and $HttpCharset; set these in the config file
|
||||
InitRequest(); # get $q with $MaxPost; set these in the config file
|
||||
InitCookie(); # After InitRequest, because $q is used
|
||||
InitVariables(); # After config, to change variables, after InitCookie for GetParam
|
||||
}
|
||||
|
||||
sub InitModules {
|
||||
if ($UseConfig and $ModuleDir and -d $ModuleDir) {
|
||||
foreach my $lib (glob("$ModuleDir/*.pm $ModuleDir/*.pl")) {
|
||||
next unless ($lib =~ /^($ModuleDir\/[-\w.]+\.p[lm])$/o);
|
||||
$lib = $1; # untaint
|
||||
foreach my $lib (bsd_glob("$ModuleDir/*.p[ml]")) {
|
||||
do $lib unless $MyInc{$lib};
|
||||
$MyInc{$lib} = 1; # Cannot use %INC in mod_perl settings
|
||||
$Message .= CGI::p("$lib: $@") if $@; # no $q exists, yet
|
||||
@@ -245,7 +238,7 @@ sub InitConfig {
|
||||
do $ConfigFile; # these options must be set in a wrapper script or via the environment
|
||||
$Message .= CGI::p("$ConfigFile: $@") if $@; # remember, no $q exists, yet
|
||||
}
|
||||
if ($ConfigPage) { # $FS, $HttpCharset, $MaxPost must be set in config file!
|
||||
if ($ConfigPage) { # $FS and $MaxPost must be set in config file!
|
||||
my ($status, $data) = ReadFile(GetPageFile(FreeToNormal($ConfigPage)));
|
||||
my %data = ParseData($data); # before InitVariables so GetPageContent won't work
|
||||
eval $data{text} if $data{text};
|
||||
@@ -254,6 +247,7 @@ sub InitConfig {
|
||||
}
|
||||
|
||||
sub InitDirConfig {
|
||||
utf8::decode($DataDir); # just in case, eg. "WikiDataDir=/tmp/Zürich♥ perl wiki.pl"
|
||||
$PageDir = "$DataDir/page"; # Stores page data
|
||||
$KeepDir = "$DataDir/keep"; # Stores kept (old) page data
|
||||
$TempDir = "$DataDir/temp"; # Temporary files and locks
|
||||
@@ -271,11 +265,9 @@ sub InitDirConfig {
|
||||
$ModuleDir = "$DataDir/modules" unless $ModuleDir;
|
||||
}
|
||||
|
||||
sub InitRequest {
|
||||
sub InitRequest { # set up $q
|
||||
$CGI::POST_MAX = $MaxPost;
|
||||
$q = new CGI unless $q;
|
||||
$q->charset($HttpCharset) if $HttpCharset;
|
||||
eval { local $SIG{__DIE__}; binmode(STDOUT, ":raw"); }; # we treat input and output as bytes
|
||||
}
|
||||
|
||||
sub InitVariables { # Init global session variables for mod_perl!
|
||||
@@ -312,7 +304,7 @@ sub InitVariables { # Init global session variables for mod_perl!
|
||||
$LastUpdate = $ts;
|
||||
unshift(@MyRules, \&MyRules) if defined(&MyRules) && (not @MyRules or $MyRules[0] != \&MyRules);
|
||||
@MyRules = sort {$RuleOrder{$a} <=> $RuleOrder{$b}} @MyRules; # default is 0
|
||||
ReportError(Ts('Could not create %s', $DataDir) . ": $!", '500 INTERNAL SERVER ERROR')
|
||||
ReportError(Ts('Cannot create %s', $DataDir) . ": $!", '500 INTERNAL SERVER ERROR')
|
||||
unless -d $DataDir;
|
||||
foreach my $sub (@MyInitVariables) {
|
||||
my $result = &$sub;
|
||||
@@ -329,12 +321,10 @@ sub ReInit { # init everything we need if we want to link to stuff
|
||||
|
||||
sub InitCookie {
|
||||
undef $q->{'.cookies'}; # Clear cache if it exists (for SpeedyCGI)
|
||||
if ($q->cookie($CookieName)) {
|
||||
%OldCookie = split(/$FS/o, UrlDecode($q->cookie($CookieName)));
|
||||
} else {
|
||||
%OldCookie = ();
|
||||
}
|
||||
my %provided = map { $_ => 1 } $q->param;
|
||||
my $cookie = $q->cookie($CookieName);
|
||||
utf8::decode($cookie); # make sure it's decoded as UTF-8
|
||||
%OldCookie = split(/$FS/o, UrlDecode($cookie));
|
||||
my %provided = map { utf8::decode($_); $_ => 1 } $q->param;
|
||||
for my $key (keys %OldCookie) {
|
||||
SetParam($key, $OldCookie{$key}) unless $provided{$key};
|
||||
}
|
||||
@@ -370,8 +360,10 @@ sub CookieRollbackFix {
|
||||
|
||||
sub GetParam {
|
||||
my ($name, $default) = @_;
|
||||
utf8::encode($name); # may fail
|
||||
my $result = $q->param($name);
|
||||
$result = $default unless defined($result);
|
||||
utf8::decode($result); # may fail
|
||||
return QuoteHtml($result); # you need to unquote anything that can have <tags>
|
||||
}
|
||||
|
||||
@@ -381,22 +373,22 @@ sub SetParam {
|
||||
}
|
||||
|
||||
sub InitLinkPatterns {
|
||||
my ($UpperLetter, $LowerLetter, $AnyLetter, $WikiWord, $QDelim);
|
||||
my ($WikiWord, $QDelim);
|
||||
$QDelim = '(?:"")?'; # Optional quote delimiter (removed from the output)
|
||||
$WikiWord = '[A-Z]+[a-z\x80-\xff]+[A-Z][A-Za-z\x80-\xff]*';
|
||||
$WikiWord = '[A-Z]+[a-z\x{0080}-\x{fffd}]+[A-Z][A-Za-z\x{0080}-\x{fffd}]*'; # exclude noncharacters FFFE and FFFF
|
||||
$LinkPattern = "($WikiWord)$QDelim";
|
||||
$FreeLinkPattern = "([-,.()'%&?;<> _1-9A-Za-z\x80-\xff]|[-,.()'%&?;<> _0-9A-Za-z\x80-\xff][-,.()'%&?;<> _0-9A-Za-z\x80-\xff]+)"; # disallow "0" and must match HTML and plain text (ie. > and >)
|
||||
$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}]+)"; # disallow "0" and must match HTML and plain text (ie. > and >)
|
||||
# Intersites must start with uppercase letter to avoid confusion with URLs.
|
||||
$InterSitePattern = '[A-Z\x80-\xff]+[A-Za-z\x80-\xff]+';
|
||||
$InterLinkPattern = "($InterSitePattern:[-a-zA-Z0-9\x80-\xff_=!?#\$\@~`\%&*+\\/:;.,]*[-a-zA-Z0-9\x80-\xff_=#\$\@~`\%&*+\\/])$QDelim";
|
||||
$FreeInterLinkPattern = "($InterSitePattern:[-a-zA-Z0-9\x80-\xff_=!?#\$\@~`\%&*+\\/:;.,()' ]+)"; # plus space and other characters, and no restrictions on the end of the pattern
|
||||
$InterSitePattern = '[A-Z\x{0080}-\x{fffd}]+[A-Za-z\x{0080}-\x{fffd}]+';
|
||||
$InterLinkPattern = "($InterSitePattern:[-a-zA-Z0-9\x{0080}-\x{fffd}_=!?#\$\@~`\%&*+\\/:;.,]*[-a-zA-Z0-9\x{0080}-\x{fffd}_=#\$\@~`\%&*+\\/])$QDelim";
|
||||
$FreeInterLinkPattern = "($InterSitePattern:[-a-zA-Z0-9\x{0080}-\x{fffd}_=!?#\$\@~`\%&*+\\/:;.,()' ]+)"; # plus space and other characters, and no restrictions on the end of the pattern
|
||||
$UrlProtocols = 'http|https|ftp|afs|news|nntp|mid|cid|mailto|wais|prospero|telnet|gopher|irc|feed';
|
||||
$UrlProtocols .= '|file' if $NetworkFile;
|
||||
my $UrlChars = '[-a-zA-Z0-9/@=+$_~*.,;:?!\'"()&#%]'; # see RFC 2396
|
||||
my $EndChars = '[-a-zA-Z0-9/@=+$_~*]'; # no punctuation at the end of the url.
|
||||
$UrlPattern = "((?:$UrlProtocols):$UrlChars+$EndChars)";
|
||||
$FullUrlPattern="((?:$UrlProtocols):$UrlChars+)"; # when used in square brackets
|
||||
$ImageExtensions = '(gif|jpg|png|bmp|jpeg)';
|
||||
$ImageExtensions = '(gif|jpg|png|bmp|jpeg|svg)';
|
||||
}
|
||||
|
||||
sub Clean {
|
||||
@@ -485,9 +477,7 @@ sub ApplyRules {
|
||||
Clean(CloseHtmlEnvironments());
|
||||
Dirty($1);
|
||||
my ($oldpos, $old_) = (pos, $_); # remember these because of the call to RSS()
|
||||
eval { local $SIG{__DIE__}; binmode(STDOUT, ":utf8"); } if $HttpCharset eq 'UTF-8';
|
||||
print RSS($3 ? $3 : 15, split(/\s+/, UnquoteHtml($4)));
|
||||
eval { local $SIG{__DIE__}; binmode(STDOUT, ":raw"); };
|
||||
Clean(AddHtmlEnvironment('p')); # if dirty block is looked at later, this will disappear
|
||||
($_, pos) = ($old_, $oldpos); # restore \G (assignment order matters!)
|
||||
} elsif (/\G(<search (.*?)>)/cgis) {
|
||||
@@ -522,8 +512,8 @@ sub ApplyRules {
|
||||
Clean("&$1;");
|
||||
} elsif (m/\G\s+/cg) {
|
||||
Clean(' ');
|
||||
} elsif (m/\G([A-Za-z\x80-\xff]+([ \t]+[a-z\x80-\xff]+)*[ \t]+)/cg
|
||||
or m/\G([A-Za-z\x80-\xff]+)/cg or m/\G(\S)/cg) {
|
||||
} elsif (m/\G([A-Za-z\x{0080}-\x{fffd}]+([ \t]+[a-z\x{0080}-\x{fffd}]+)*[ \t]+)/cg
|
||||
or m/\G([A-Za-z\x{0080}-\x{fffd}]+)/cg or m/\G(\S)/cg) {
|
||||
Clean($1); # multiple words but do not match http://foo
|
||||
} else {
|
||||
last;
|
||||
@@ -670,13 +660,14 @@ sub OpenHtmlEnvironment { # close the previous $html_tag and open a new one
|
||||
@HtmlStack = @stack if $found; # if not starting a new list
|
||||
$depth = $IndentLimit if $depth > $IndentLimit; # requested depth 0 makes no sense
|
||||
$html_tag_attr = qq/class="$html_tag_attr"/ # backwards-compatibility hack: classically, the third argument to this function was a single CSS class, rather than string of HTML tag attributes as in the second argument to the "AddHtmlEnvironment" function. To allow both sorts, we conditionally change this string to 'class="$html_tag_attr"' when this string is a single CSS class.
|
||||
if $html_tag_attr && $html_tag_attr !~ m/^\s*[:alpha:]+\s*=\s*('|").+\1/;
|
||||
if $html_tag_attr && $html_tag_attr !~ m/^\s*[[:alpha:]]@@+\s*=\s*('|").+\1/;
|
||||
splice(@HtmlAttrStack, 0, @HtmlAttrStack - @HtmlStack); # truncate to size of @HtmlStack
|
||||
foreach ($found..$depth-1) {
|
||||
unshift(@HtmlStack, $html_tag);
|
||||
unshift(@HtmlAttrStack, $html_tag_attr);
|
||||
$html .= $html_tag_attr ? "<$html_tag $html_tag_attr>" : "<$html_tag>";
|
||||
} return $html;
|
||||
}
|
||||
return $html;
|
||||
}
|
||||
|
||||
sub CloseHtmlEnvironments { # close all -- remember to use AddHtmlEnvironment('p') if required!
|
||||
@@ -794,6 +785,7 @@ sub UnquoteHtml {
|
||||
sub UrlEncode {
|
||||
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) {
|
||||
@@ -912,13 +904,6 @@ sub RSS {
|
||||
# translations will be double encoded when printing the result.
|
||||
my $tDiff = T('diff');
|
||||
my $tHistory = T('history');
|
||||
if ($HttpCharset eq 'UTF-8' and ($tDiff ne 'diff' or $tHistory ne 'history')) {
|
||||
eval { local $SIG{__DIE__};
|
||||
require Encode;
|
||||
$tDiff = Encode::decode_utf8($tDiff);
|
||||
$tHistory = Encode::decode_utf8($tHistory);
|
||||
}
|
||||
}
|
||||
my $wikins = 'http://purl.org/rss/1.0/modules/wiki/';
|
||||
my $rdfns = 'http://www.w3.org/1999/02/22-rdf-syntax-ns#';
|
||||
@uris = map { s/^"?(.*?)"?$/$1/; $_; } @uris; # strip quotes of uris
|
||||
@@ -1030,8 +1015,8 @@ sub GetRss {
|
||||
if (GetParam('cache', $UseCache) > 0) {
|
||||
foreach my $uri (keys %todo) { # read cached rss files if possible
|
||||
if ($Now - (stat($todo{$uri}))[9] < $RssCacheHours * 3600) {
|
||||
$data{$uri} = ReadFile($todo{$uri});
|
||||
delete($todo{$uri}); # no need to fetch them below
|
||||
$data{$uri} = ReadFile($todo{$uri});
|
||||
delete($todo{$uri}); # no need to fetch them below
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1048,8 +1033,8 @@ sub GetRss {
|
||||
%todo = (); # because the uris in the response may have changed due to redirects
|
||||
my $entries = $pua->wait();
|
||||
foreach (keys %$entries) {
|
||||
my $uri = $entries->{$_}->request->uri;
|
||||
$data{$uri} = $entries->{$_}->response->content;
|
||||
my $uri = $entries->{$_}->request->uri;
|
||||
$data{$uri} = $entries->{$_}->response->content;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1059,7 +1044,10 @@ sub GetRss {
|
||||
if (GetParam('cache', $UseCache) > 0) {
|
||||
CreateDir($RssDir);
|
||||
foreach my $uri (@need_cache) {
|
||||
WriteStringToFile(GetRssFile($uri), $data{$uri});
|
||||
my $data = $data{$uri};
|
||||
# possibly a Latin-1 file without encoding attribute will cause a problem?
|
||||
$data =~ s/encoding="[^"]*"/encoding="UTF-8"/; # content was converted
|
||||
WriteStringToFile(GetRssFile($uri), $data) if $data;
|
||||
}
|
||||
}
|
||||
return $str, %data;
|
||||
@@ -1277,18 +1265,22 @@ sub PrintPageDiff { # print diff for open page
|
||||
}
|
||||
}
|
||||
|
||||
sub PageHtml { #FIXME: A bit buggy, this. STDOUT should be explicitly closed before returning.
|
||||
sub PageHtml {
|
||||
my ($id, $limit, $error) = @_;
|
||||
my $result = '';
|
||||
my ($diff, $page);
|
||||
local *STDOUT;
|
||||
OpenPage($id);
|
||||
open(STDOUT, '>', \$result) or die "Can't open memory file: $!";
|
||||
open(STDOUT, '>', \$diff) or die "Can't open memory file: $!";
|
||||
binmode(STDOUT, ":utf8");
|
||||
PrintPageDiff();
|
||||
return $error if $limit and length($result) > $limit;
|
||||
my $diff = $result;
|
||||
utf8::decode($diff);
|
||||
return $error if $limit and length($diff) > $limit;
|
||||
open(STDOUT, '>', \$page) or die "Can't open memory file: $!";
|
||||
binmode(STDOUT, ":utf8");
|
||||
PrintPageHtml();
|
||||
return $diff . $q->p($error) if $limit and length($result) > $limit;
|
||||
return $result;
|
||||
utf8::decode($page);
|
||||
return $diff . $q->p($error) if $limit and length($diff . $page) > $limit;
|
||||
return $diff . $page;
|
||||
}
|
||||
|
||||
sub T {
|
||||
@@ -1313,9 +1305,17 @@ sub Tss {
|
||||
|
||||
sub GetId {
|
||||
my $id = UnquoteHtml(GetParam('id', GetParam('title', ''))); # id=x or title=x -> x
|
||||
$id = join('_', $q->keywords) unless $id; # script?p+q -> p_q
|
||||
if (not $id) {
|
||||
my @keywords = $q->keywords;
|
||||
foreach my $keyword (@keywords) {
|
||||
utf8::decode($keyword);
|
||||
}
|
||||
$id = join('_', @keywords) unless $id; # script?p+q -> p_q
|
||||
}
|
||||
if ($UsePathInfo) {
|
||||
my @path = split(/\//, $q->path_info);
|
||||
my $path = $q->path_info;
|
||||
utf8::decode($path);
|
||||
my @path = split(/\//, $path);
|
||||
$id = pop(@path) unless $id; # script/p/q -> q
|
||||
foreach my $p (@path) {
|
||||
SetParam($p, 1); # script/p/q -> p=1
|
||||
@@ -1500,7 +1500,7 @@ sub GetRcLines { # starttime, hash of seen pages to use as a second return value
|
||||
my %following = ();
|
||||
my @result = ();
|
||||
# check the first timestamp in the default file, maybe read old log file
|
||||
open(F, $RcFile);
|
||||
open(F, '<:encoding(UTF-8)', $RcFile);
|
||||
my $line = <F>;
|
||||
my ($ts) = split(/$FS/o, $line); # the first timestamp in the regular rc file
|
||||
if (not $ts or $ts > $starttime) { # we need to read the old rc file, too
|
||||
@@ -1586,7 +1586,7 @@ sub GetRcLinesFor {
|
||||
rcclusteronly rcfilteronly match lang followup);
|
||||
# parsing and filtering
|
||||
my @result = ();
|
||||
open(F,$file) or return ();
|
||||
open(F, '<:encoding(UTF-8)', $file) or return ();
|
||||
while (my $line = <F>) {
|
||||
chomp($line);
|
||||
my ($ts, $id, $minor, $summary, $host, $username, $revision,
|
||||
@@ -1815,7 +1815,7 @@ sub RcHtml {
|
||||
$more .= ";$_=$val" if $val;
|
||||
}
|
||||
$html .= $q->p({-class=>'more'}, ScriptLink($more, T('More...'), 'more'));
|
||||
return GetFormStart() . $html . $q->endform;
|
||||
return GetFormStart(undef, 'get', 'rc') . $html . $q->endform;
|
||||
}
|
||||
|
||||
sub PrintRcHtml { # to append RC to existing page, or action=rc directly
|
||||
@@ -1872,7 +1872,7 @@ sub GetRcRss {
|
||||
}
|
||||
}
|
||||
}
|
||||
my $rss = qq{<?xml version="1.0" encoding="$HttpCharset"?>\n};
|
||||
my $rss = qq{<?xml version="1.0" encoding="UTF-8"?>\n};
|
||||
if ($RssStyleSheet =~ /\.(xslt?|xml)$/) {
|
||||
$rss .= qq{<?xml-stylesheet type="text/xml" href="$RssStyleSheet" ?>\n};
|
||||
} elsif ($RssStyleSheet) {
|
||||
@@ -2218,15 +2218,16 @@ sub GetHeader {
|
||||
$result .= $q->start_div({-class=>'header'});
|
||||
if (not $embed and $LogoUrl) {
|
||||
my $url = $IndexHash{$LogoUrl} ? GetDownloadLink($LogoUrl, 2) : $LogoUrl;
|
||||
$result .= ScriptLink(UrlEncode($HomePage), $q->img({-src=>$url, -alt=>$alt, -class=>'logo'}), 'logo');
|
||||
$result .= ScriptLink(UrlEncode($HomePage),
|
||||
$q->img({-src=>$url, -alt=>$alt, -class=>'logo'}), 'logo');
|
||||
}
|
||||
if (GetParam('toplinkbar', $TopLinkBar)) {
|
||||
$result .= GetGotoBar($id);
|
||||
if (%SpecialDays) {
|
||||
my ($sec, $min, $hour, $mday, $mon, $year) = gmtime($Now);
|
||||
if ($SpecialDays{($mon + 1) . '-' . $mday}) {
|
||||
$result .= $q->br() . $q->span({-class=>'specialdays'},
|
||||
$SpecialDays{($mon + 1) . '-' . $mday});
|
||||
$result .= $q->br() . $q->span({-class=>'specialdays'},
|
||||
$SpecialDays{($mon + 1) . '-' . $mday});
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -2243,11 +2244,11 @@ sub GetHttpHeader {
|
||||
return if $PrintedHeader;
|
||||
$PrintedHeader = 1;
|
||||
my ($type, $ts, $status, $encoding) = @_; # $ts is undef, a ts, or 'nocache'
|
||||
$q->charset($type =~ m!^(text/|application/xml)! ? 'utf-8' : ''); # text/plain, text/html, application/xml: UTF-8
|
||||
my %headers = (-cache_control=>($UseCache < 0 ? 'no-cache' : 'max-age=10'));
|
||||
$headers{-etag} = $ts || PageEtag() if GetParam('cache', $UseCache) >= 2;
|
||||
$headers{'-last-modified'} = TimeToRFC822($ts) if $ts and $ts ne 'nocache'; # RFC 2616 section 13.3.4
|
||||
$headers{-type} = GetParam('mime-type', $type);
|
||||
$headers{-type} .= "; charset=$HttpCharset" if $HttpCharset;
|
||||
$headers{-status} = $status if $status;
|
||||
$headers{-Content_Encoding} = $encoding if $encoding;
|
||||
my $cookie = Cookie();
|
||||
@@ -2263,7 +2264,7 @@ sub CookieData {
|
||||
my ($changed, $visible, %params);
|
||||
foreach my $key (keys %CookieParameters) {
|
||||
my $default = $CookieParameters{$key};
|
||||
my $value = GetParam($key, $default); # values are URL encoded
|
||||
my $value = GetParam($key, $default);
|
||||
$params{$key} = $value if $value ne $default;
|
||||
# The cookie is considered to have changed under the following
|
||||
# condition: If the value was already set, and the new value is
|
||||
@@ -2280,6 +2281,7 @@ sub Cookie {
|
||||
my ($changed, $visible, %params) = CookieData(); # params are URL encoded
|
||||
if ($changed) {
|
||||
my $cookie = join(UrlEncode($FS), %params); # no CTL in field values
|
||||
utf8::encode($cookie); # prevent casting to Latin 1
|
||||
my $result = $q->cookie(-name=>$CookieName, -value=>$cookie,
|
||||
-expires=>'+2y');
|
||||
$Message .= $q->p(T('Cookie: ') . $CookieName . ', '
|
||||
@@ -2297,10 +2299,9 @@ sub GetHtmlHeader { # always HTML!
|
||||
. T('Edit this page') . '" href="'
|
||||
. ScriptUrl('action=edit;id=' . UrlEncode(GetId())) . '" />' if $id;
|
||||
return $DocumentHeader
|
||||
. $q->head($q->title($title) . $base
|
||||
. GetCss() . GetRobots() . GetFeeds() . $HtmlHeaders
|
||||
. '<meta http-equiv="Content-Type" content="text/html; charset='
|
||||
. $HttpCharset . '"/>')
|
||||
. $q->head($q->title($title) . $base
|
||||
. GetCss() . GetRobots() . GetFeeds() . $HtmlHeaders
|
||||
. '<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />')
|
||||
. '<body class="' . GetParam('theme', $ScriptName) . '">';
|
||||
}
|
||||
|
||||
@@ -2319,7 +2320,7 @@ sub GetFeeds { # default for $HtmlHeaders
|
||||
my $id = GetId(); # runs during Init, not during DoBrowseRequest
|
||||
$html .= '<link rel="alternate" type="application/rss+xml" title="'
|
||||
. QuoteHtml("$SiteName: $id") . '" href="' . $ScriptName
|
||||
. '?action=rss;rcidonly=' . UrlEncode(FreeToNormal($id)) . '" />' if $id;
|
||||
. '?action=rss;rcidonly=' . UrlEncode(FreeToNormal($id)) . '" />' if $id;
|
||||
my $username = GetParam('username', '');
|
||||
$html .= '<link rel="alternate" type="application/rss+xml" '
|
||||
. 'title="Follow-ups for ' . NormalToFree($username) . '" '
|
||||
@@ -2452,7 +2453,9 @@ sub GetCommentForm {
|
||||
sub GetFormStart {
|
||||
my ($ignore, $method, $class) = @_;
|
||||
$method ||= 'post';
|
||||
return $q->start_multipart_form(-method=>$method, -action=>$FullUrl, -class=>$class);
|
||||
$class ||= 'form';
|
||||
return $q->start_multipart_form(-method=>$method, -action=>$FullUrl,
|
||||
-accept_charset=>'utf-8', -class=>$class);
|
||||
}
|
||||
|
||||
sub GetSearchForm {
|
||||
@@ -2536,6 +2539,7 @@ sub DoDiff { # Actualy call the diff program
|
||||
WriteStringToFile($oldName, $_[0]);
|
||||
WriteStringToFile($newName, $_[1]);
|
||||
my $diff_out = `diff $oldName $newName`;
|
||||
utf8::decode($diff_out); # needs decoding
|
||||
$diff_out =~ s/\\ No newline.*\n//g; # Get rid of common complaint.
|
||||
ReleaseLockDir('diff');
|
||||
# No need to unlink temp files--next diff will just overwrite.
|
||||
@@ -2662,7 +2666,9 @@ sub OpenPage { # Sets global variables
|
||||
%Page = ();
|
||||
$Page{ts} = $Now;
|
||||
$Page{revision} = 0;
|
||||
if ($id eq $HomePage and (open(F, $ReadMe) or open(F, 'README'))) {
|
||||
if ($id eq $HomePage
|
||||
and (open(F, '<:encoding(UTF-8)', $ReadMe)
|
||||
or open(F, '<:encoding(UTF-8)', 'README'))) {
|
||||
local $/ = undef;
|
||||
$Page{text} = <F>;
|
||||
close F;
|
||||
@@ -2717,12 +2723,12 @@ sub GetKeptRevision { # Call after OpenPage
|
||||
}
|
||||
|
||||
sub GetPageFile {
|
||||
my ($id, $revision) = @_;
|
||||
my ($id) = @_;
|
||||
return $PageDir . '/' . GetPageDirectory($id) . "/$id.pg";
|
||||
}
|
||||
|
||||
sub GetKeepFile {
|
||||
my ($id, $revision) = @_; die 'No revision' unless $revision; #FIXME
|
||||
my ($id, $revision) = @_; die "No revision for $id" unless $revision; #FIXME
|
||||
return $KeepDir . '/' . GetPageDirectory($id) . "/$id/$revision.kp";
|
||||
}
|
||||
|
||||
@@ -2732,7 +2738,7 @@ sub GetKeepDir {
|
||||
}
|
||||
|
||||
sub GetKeepFiles {
|
||||
return glob(GetKeepDir(shift) . '/*.kp'); # files such as 1.kp, 2.kp, etc.
|
||||
return bsd_glob(GetKeepDir(shift) . '/*.kp'); # files such as 1.kp, 2.kp, etc.
|
||||
}
|
||||
|
||||
sub GetKeepRevisions {
|
||||
@@ -2790,8 +2796,9 @@ sub ExpireKeepFiles { # call with opened page
|
||||
}
|
||||
|
||||
sub ReadFile {
|
||||
my $fileName = shift;
|
||||
if (open(IN, "<$fileName")) {
|
||||
my $file = shift;
|
||||
utf8::encode($file); # filenames are bytes!
|
||||
if (open(IN, '<:encoding(UTF-8)', $file)) {
|
||||
local $/ = undef; # Read complete files
|
||||
my $data=<IN>;
|
||||
close IN;
|
||||
@@ -2801,18 +2808,19 @@ sub ReadFile {
|
||||
}
|
||||
|
||||
sub ReadFileOrDie {
|
||||
my ($fileName) = @_;
|
||||
my ($file) = @_;
|
||||
my ($status, $data);
|
||||
($status, $data) = ReadFile($fileName);
|
||||
($status, $data) = ReadFile($file);
|
||||
if (!$status) {
|
||||
ReportError(Ts('Cannot open %s', $fileName) . ": $!", '500 INTERNAL SERVER ERROR');
|
||||
ReportError(Ts('Cannot open %s', $file) . ": $!", '500 INTERNAL SERVER ERROR');
|
||||
}
|
||||
return $data;
|
||||
}
|
||||
|
||||
sub WriteStringToFile {
|
||||
my ($file, $string) = @_;
|
||||
open(OUT, ">$file")
|
||||
utf8::encode($file);
|
||||
open(OUT, '>:encoding(UTF-8)', $file)
|
||||
or ReportError(Ts('Cannot write %s', $file) . ": $!", '500 INTERNAL SERVER ERROR');
|
||||
print OUT $string;
|
||||
close(OUT);
|
||||
@@ -2820,7 +2828,8 @@ sub WriteStringToFile {
|
||||
|
||||
sub AppendStringToFile {
|
||||
my ($file, $string) = @_;
|
||||
open(OUT, ">>$file")
|
||||
utf8::encode($file);
|
||||
open(OUT, '>>:encoding(UTF-8)', $file)
|
||||
or ReportError(Ts('Cannot write %s', $file) . ": $!", '500 INTERNAL SERVER ERROR');
|
||||
print OUT $string;
|
||||
close(OUT);
|
||||
@@ -2828,6 +2837,7 @@ sub AppendStringToFile {
|
||||
|
||||
sub CreateDir {
|
||||
my ($newdir) = @_;
|
||||
utf8::encode($newdir);
|
||||
return if -d $newdir;
|
||||
mkdir($newdir, 0775)
|
||||
or ReportError(Ts('Cannot create %s', $newdir) . ": $!", '500 INTERNAL SERVER ERROR');
|
||||
@@ -2895,7 +2905,7 @@ sub ReleaseLock {
|
||||
sub ForceReleaseLock {
|
||||
my $pattern = shift;
|
||||
my $forced;
|
||||
foreach my $name (glob $pattern) {
|
||||
foreach my $name (bsd_glob $pattern) {
|
||||
# First try to obtain lock (in case of normal edit lock)
|
||||
$forced = 1 if !RequestLockDir($name, 5, 3, 0);
|
||||
ReleaseLockDir($name); # Release the lock, even if we didn't get it.
|
||||
@@ -2968,7 +2978,7 @@ sub TimeToRFC822 {
|
||||
sub GetHiddenValue {
|
||||
my ($name, $value) = @_;
|
||||
$q->param($name, $value);
|
||||
return $q->hidden($name);
|
||||
return $q->input({-type=>"hidden", -name=>$name, -value=>$value});
|
||||
}
|
||||
|
||||
sub GetRemoteHost { # when testing, these variables are undefined.
|
||||
@@ -3122,6 +3132,7 @@ sub DoDownload {
|
||||
if @UploadTypes and not $allowed{$type};
|
||||
print GetHttpHeader($type, $ts, undef, $encoding);
|
||||
require MIME::Base64;
|
||||
binmode(STDOUT, ":pop:raw"); # need to pop utf8 for Windows users!?
|
||||
print MIME::Base64::decode($data);
|
||||
} else {
|
||||
print GetHttpHeader('text/plain', $ts);
|
||||
@@ -3257,8 +3268,8 @@ sub DoIndex {
|
||||
push(@menu, $q->b(Ts('(for %s)', GetParam('lang', '')))) if GetParam('lang', '');
|
||||
print $q->start_div({-class=>'content index'}),
|
||||
GetFormStart(undef, 'get', 'index'), GetHiddenValue('action', 'index'),
|
||||
$q->p(join($q->br(), @menu)), $q->end_form(),
|
||||
$q->h2(Ts('%s pages found.', ($#pages + 1))), $q->start_p();
|
||||
$q->p(join($q->br(), @menu)), $q->end_form(),
|
||||
$q->h2(Ts('%s pages found.', ($#pages + 1))), $q->start_p();
|
||||
}
|
||||
foreach (@pages) {
|
||||
PrintPage($_);
|
||||
@@ -3289,6 +3300,7 @@ sub PrintPage {
|
||||
sub AllPagesList {
|
||||
my $refresh = GetParam('refresh', 0);
|
||||
return @IndexList if @IndexList and not $refresh;
|
||||
SetParam('refresh', 0) if $refresh;
|
||||
if (not $refresh and -f $IndexFile) {
|
||||
my ($status, $rawIndex) = ReadFile($IndexFile); # not fatal
|
||||
if ($status) {
|
||||
@@ -3300,11 +3312,12 @@ sub AllPagesList {
|
||||
}
|
||||
@IndexList = ();
|
||||
%IndexHash = ();
|
||||
# Try to write out the list for future runs. If file exists and cannot be changed, error!
|
||||
# If file exists and cannot be changed, error!
|
||||
my $locked = RequestLockDir('index', undef, undef, -f $IndexFile);
|
||||
foreach (glob("$PageDir/*/*.pg $PageDir/*/.*.pg")) { # find .dotfiles, too
|
||||
foreach (bsd_glob("$PageDir/*/*.pg"), bsd_glob("$PageDir/*/.*.pg")) {
|
||||
next unless m|/.*/(.+)\.pg$|;
|
||||
my $id = $1;
|
||||
utf8::decode($id);
|
||||
push(@IndexList, $id);
|
||||
$IndexHash{$id} = 1;
|
||||
}
|
||||
@@ -3358,7 +3371,9 @@ sub PageIsUploadedFile {
|
||||
return undef if $OpenPageName eq $id;
|
||||
if ($IndexHash{$id}) {
|
||||
my $file = GetPageFile($id);
|
||||
open(FILE, "<$file") or ReportError(Ts('Cannot open %s', $file) . ": $!", '500 INTERNAL SERVER ERROR');
|
||||
utf8::encode($file); # filenames are bytes!
|
||||
open(FILE, '<:encoding(UTF-8)', $file)
|
||||
or ReportError(Ts('Cannot open %s', $file) . ": $!", '500 INTERNAL SERVER ERROR');
|
||||
while (defined($_ = <FILE>) and $_ !~ /^text: /) {
|
||||
} # read lines until we get to the text key
|
||||
close FILE;
|
||||
@@ -3402,7 +3417,7 @@ sub GrepFiltered { # grep is so much faster!!
|
||||
# if we know of any remaining grep incompatibilities we should
|
||||
# return @pages here!
|
||||
$regexp = quotemeta($regexp);
|
||||
open(F,"grep -rli $regexp '$PageDir' 2>/dev/null |");
|
||||
open(F, '-|:encoding(UTF-8)', "grep -rli $regexp '$PageDir' 2>/dev/null");
|
||||
while (<F>) {
|
||||
push(@result, $1) if m/.*\/(.*)\.pg/ and not $found{$1};
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user