forked from github/kensanata.oddmuse
Compare commits
13 Commits
unicodeico
...
2.3.6
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
bd2715a35e | ||
|
|
986e4fc65f | ||
|
|
908cecffb9 | ||
|
|
07226ae7a1 | ||
|
|
c90258ef4b | ||
|
|
f500092a6a | ||
|
|
d1f1f65c9b | ||
|
|
aae0cb6379 | ||
|
|
2b0a0d9a14 | ||
|
|
69fcb9646b | ||
|
|
a0bf615960 | ||
|
|
c024f553fd | ||
|
|
c97d6a576f |
@@ -321,7 +321,6 @@ div.sister {
|
||||
float:left;
|
||||
margin-right:1ex;
|
||||
padding-right:1ex;
|
||||
border-right:1px dashed;
|
||||
}
|
||||
div.sister p { padding:1ex; margin:0; }
|
||||
div.sister hr { display:none; }
|
||||
|
||||
@@ -47,8 +47,8 @@ textarea, pre, code, tt {
|
||||
.browse { min-height: 3em; }
|
||||
.header form, .header p { margin: 0; }
|
||||
/* hide the buttons but don't use display:none because of
|
||||
http://stackoverflow.com/questions/5665203/getting-iphone-go-button-to-submit-form */
|
||||
.header input[type="submit"] { position: absolute; visibility: hidden; }
|
||||
http://stackoverflow.com/questions/5665203/getting-iphone-go-button-to-submit-form
|
||||
.header input[type="submit"] { position: absolute; visibility: hidden; } */
|
||||
.header input { width: 5em; font-size: 80%; }
|
||||
.footer { clear:both; font-size: 90%; }
|
||||
.content input { font-size: 80%; line-height: 125%; }
|
||||
@@ -205,6 +205,7 @@ span.result { font-size:larger; }
|
||||
span.info { font-size:smaller; font-style:italic; }
|
||||
div.rc hr { display: none; }
|
||||
div.rc li { padding-bottom: 0.5em; }
|
||||
div.rc li strong { font-weight: normal; }
|
||||
|
||||
/* Tables */
|
||||
table.user {
|
||||
|
||||
47
css/wiki.css
47
css/wiki.css
@@ -219,50 +219,3 @@ code {
|
||||
background: #eee;
|
||||
white-space: pre-wrap;
|
||||
}
|
||||
|
||||
@font-face {
|
||||
font-family: 'Gentium Basic';
|
||||
font-style: normal;
|
||||
font-weight: 700;
|
||||
src: local('Gentium Basic Bold'), local('GentiumBasic-Bold'), url(/fonts/GenBasB.woff) format('woff');
|
||||
}
|
||||
|
||||
@font-face {
|
||||
font-family: 'Gentium Basic';
|
||||
font-style: italic;
|
||||
font-weight: 400;
|
||||
src: local('Gentium Basic Italic'), local('GentiumBasic-Italic'), url(/fonts/GenBasI.woff) format('woff');
|
||||
}
|
||||
|
||||
@font-face {
|
||||
font-family: 'Gentium Basic';
|
||||
font-style: italic;
|
||||
font-weight: 700;
|
||||
src: local('Gentium Basic Bold Italic'), local('GentiumBasic-BoldItalic'), url(/fonts/GenBasBI.woff) format('woff');
|
||||
}
|
||||
|
||||
@font-face {
|
||||
font-family: 'Gentium Basic';
|
||||
font-style: normal;
|
||||
font-weight: 400;
|
||||
src: local('Gentium Basic'), local('GentiumBasic'), url(/fonts/GenBasR.woff) format('woff');
|
||||
}
|
||||
|
||||
@font-face {
|
||||
font-family: 'Gentium Plus';
|
||||
font-style: normal;
|
||||
font-weight: 400;
|
||||
src: local('Gentium Plus'), local('GentiumPlus'), url(/fonts/GentiumPlus-R.woff) format('woff');
|
||||
}
|
||||
|
||||
@font-face {
|
||||
font-family: 'Gentium Plus';
|
||||
font-style: italic;
|
||||
font-weight: 400;
|
||||
src: local('Gentium Plus Italic'), local('GentiumPlus-Italic'), url(/fonts/GentiumPlus-I.woff) format('woff');
|
||||
}
|
||||
|
||||
@font-face {
|
||||
font-family: 'Symbola';
|
||||
src: local('Symbola'), url('/fonts/Symbola.woff') format('woff') url('/fonts/Symbola.ttf') format('truetype');
|
||||
}
|
||||
|
||||
@@ -89,9 +89,9 @@ Ungültige Seite %s (Darf nicht mit .lck enden)
|
||||
Invalid Page %s
|
||||
Ungültige Seite %s
|
||||
There are no comments, yet. Be the first to leave a comment!
|
||||
|
||||
Es gibt noch keine Kommentare, sei der Erste der einen hinterlässt!
|
||||
Welcome!
|
||||
|
||||
Willkommen!
|
||||
This page does not exist, but you can %s.
|
||||
Diese Seite gibt es nicht, aber du kannst %s.
|
||||
create it now
|
||||
@@ -343,9 +343,9 @@ Die Sperre wurde %s gesetzt.
|
||||
Maybe the user running this script is no longer allowed to remove the lock directory?
|
||||
Vielleicht darf der user, welcher dieses script ausführt, das Sperr-Verzeichnis nicht löschen?
|
||||
Sometimes locks are left behind if a job crashes.
|
||||
|
||||
Manchmal bleiben Sperren erhalten, wenn ein Prozess abbricht.
|
||||
After ten minutes, you could try to unlock the wiki.
|
||||
|
||||
Nach zehn Minuten kann versucht werden, das Wiki zu entsperren.
|
||||
This operation may take several seconds...
|
||||
Das könnte einige Sekunden dauern...
|
||||
Forced unlock of %s lock.
|
||||
@@ -435,7 +435,7 @@ Grund unbekannt.
|
||||
%s pages found.
|
||||
%s Seiten gefunden.
|
||||
Preview: %s
|
||||
|
||||
Vorschau: %s
|
||||
Replaced: %s
|
||||
Ersetzt: %s
|
||||
Search for: %s
|
||||
@@ -786,7 +786,7 @@ Kommentar hinzufügen
|
||||
ordinary changes
|
||||
normale Änderungen
|
||||
%s days
|
||||
|
||||
%s Tage
|
||||
################################################################################
|
||||
# modules/edit-paragraphs.pl
|
||||
################################################################################
|
||||
@@ -1398,9 +1398,9 @@ Portrait
|
||||
# modules/preview.pl
|
||||
################################################################################
|
||||
Pages with changed HTML
|
||||
|
||||
Seiten mit geändertem HTML
|
||||
Preview changes in HTML output
|
||||
|
||||
Vorschau der Änderungen der HTML-Ausgabe
|
||||
################################################################################
|
||||
# modules/private-pages.pl
|
||||
################################################################################
|
||||
|
||||
@@ -691,11 +691,6 @@ Clustermap
|
||||
|
||||
Pages without a Cluster
|
||||
|
||||
################################################################################
|
||||
# modules/comment-div-wrapper.pl
|
||||
################################################################################
|
||||
Comments:
|
||||
|
||||
################################################################################
|
||||
# modules/commentcount.pl
|
||||
################################################################################
|
||||
@@ -703,6 +698,11 @@ Comments on
|
||||
|
||||
Comment on
|
||||
|
||||
################################################################################
|
||||
# modules/comment-div-wrapper.pl
|
||||
################################################################################
|
||||
Comments:
|
||||
|
||||
################################################################################
|
||||
# modules/compilation.pl
|
||||
################################################################################
|
||||
@@ -1239,7 +1239,7 @@ Test / Always enabled / Always disabled
|
||||
|
||||
Start
|
||||
|
||||
Bisection proccess is already active.
|
||||
Bisecting proccess is already active.
|
||||
|
||||
Stop
|
||||
|
||||
@@ -1280,6 +1280,11 @@ You linked more than %s times to the same domain. It would seem that only a spam
|
||||
|
||||
Namespaces
|
||||
|
||||
################################################################################
|
||||
# modules/nearlink-create.pl
|
||||
################################################################################
|
||||
(create locally)
|
||||
|
||||
################################################################################
|
||||
# modules/near-links.pl
|
||||
################################################################################
|
||||
@@ -1299,11 +1304,6 @@ EditNearLinks
|
||||
|
||||
The same page on other sites:
|
||||
|
||||
################################################################################
|
||||
# modules/nearlink-create.pl
|
||||
################################################################################
|
||||
(create locally)
|
||||
|
||||
################################################################################
|
||||
# modules/no-question-mark.pl
|
||||
################################################################################
|
||||
@@ -1662,4 +1662,5 @@ Edit %s.
|
||||
################################################################################
|
||||
Tags:
|
||||
|
||||
#
|
||||
END_OF_TRANSLATION
|
||||
|
||||
188
scripts/alexine/bot.p6
Executable file
188
scripts/alexine/bot.p6
Executable file
@@ -0,0 +1,188 @@
|
||||
#!/usr/bin/env perl6
|
||||
use Net::IRC::Bot;
|
||||
use Net::IRC::Modules::Autoident;
|
||||
use Net::IRC::Modules::Tell;
|
||||
use Net::IRC::CommandHandler;
|
||||
|
||||
sub wikiLink($page is copy) {
|
||||
$page ~~ s:g/\s/_/; # quick and dirty
|
||||
return “https://oddmuse.org/wiki/$page”;
|
||||
}
|
||||
|
||||
class Intermap {
|
||||
has $.intermapLink is rw = ‘https://oddmuse.org/wiki/Local_Intermap?raw=1’;
|
||||
has %!intermap;
|
||||
|
||||
method update {
|
||||
# TODO https breaks HTTP::UserAgent, workaround with curl
|
||||
my $proc = run(‘curl’, $!intermapLink, :out);
|
||||
my $text = $proc.out.slurp-rest;
|
||||
$proc.out.close; # RT #126561
|
||||
return False unless $proc;
|
||||
for $text ~~ m:global〈 ^^ \h+ $<name>=\S+ \s+ $<value>=.+? $$ 〉 {
|
||||
%!intermap{~$_<name>} = ~$_<value>; # TODO map!
|
||||
}
|
||||
return True;
|
||||
}
|
||||
|
||||
method said ($e) {
|
||||
self.update if not %!intermap or $e.what ~~ / ‘update intermap’ /; # lazy init
|
||||
for $e.what ~~ m:global〈 $<name>=<-[\s :]>+ ‘:’ $<value>=\S+ 〉 { # quick and dirty
|
||||
next unless %!intermap{.<name>}:exists;
|
||||
my $link = %!intermap{~.<name>};
|
||||
my $replacement = $_<value>;
|
||||
$link ~~ s{ \%s | $ } = $replacement;
|
||||
$e.msg: $link;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
class Pages {
|
||||
method said ($e) {
|
||||
for $e.what ~~ m:global〈 ‘[[’ $<page>=<-[ \] ]>+ ‘]]’ 〉 { # quick and dirty
|
||||
$e.msg: wikiLink ~.<page>;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
class Sorry {
|
||||
has $.answers is rw = « ‘I'm so sorry!’ ‘Please forgive me!’
|
||||
‘I should have done better!’
|
||||
‘I promise that it won't happen again!’ »;
|
||||
|
||||
method said ($e) {
|
||||
if $e.what ~~ / ^ "{ $e.bot.nick }" [‘:’|‘,’] / {
|
||||
$e.msg: $!answers.pick;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
class RecentChanges {
|
||||
has $.delay is rw = 30;
|
||||
has $.url is rw = ‘https://oddmuse.org/wiki?action=rss;all=0;showedit=0;rollback=1;from=’;
|
||||
has $!last = time;
|
||||
|
||||
method joined ($e) {
|
||||
start loop {
|
||||
sleep $!delay;
|
||||
self.process: $e;
|
||||
}
|
||||
}
|
||||
|
||||
method process ($e) {
|
||||
my $newLast = time;
|
||||
# TODO https breaks HTTP::UserAgent, workaround with curl
|
||||
my $proc = run(‘curl’, $!url ~ $!last, :out);
|
||||
my $xml = $proc.out.slurp-rest;
|
||||
$proc.out.close; # RT #126561
|
||||
return False unless $proc;
|
||||
$!last = $newLast;
|
||||
|
||||
use XML;
|
||||
for from-xml($xml).elements(:TAG<item>, :RECURSE) {
|
||||
my $title = ~.elements(:TAG<title>, :SINGLE).contents;
|
||||
my $desc = ~.elements(:TAG<description>, :SINGLE).contents;
|
||||
my $author = ~.elements(:TAG<dc:contributor>, :SINGLE).contents;
|
||||
$e.msg: “Wiki: [$title] <$author> – $desc ({wikiLink $title})”;
|
||||
}
|
||||
return True;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
class RecentCommits {
|
||||
has $.delay is rw = 30;
|
||||
has $.url = ‘https://github.com/kensanata/oddmuse.git’;
|
||||
has $.repo = ‘repo’;
|
||||
|
||||
method joined ($e) {
|
||||
start {
|
||||
if $!repo.IO !~~ :e {
|
||||
fail unless run(‘git’, ‘clone’, $!url, $!repo);
|
||||
}
|
||||
loop {
|
||||
sleep $!delay;
|
||||
self.process: $e;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
method process ($e) {
|
||||
my $proc1 = run(‘git’, ‘--git-dir’, $!repo ~ ‘/.git’, ‘fetch’) ;
|
||||
return False unless $proc1;
|
||||
my $proc2 = run(‘git’, ‘--git-dir’, $!repo ~ ‘/.git’, ‘log’,
|
||||
‘--pretty=format:Commit: %s (https://github.com/kensanata/oddmuse/commit/%h)’,
|
||||
‘...origin’, :out);
|
||||
$e.msg: $_ for $proc2.out;
|
||||
$proc2.out.close; # RT #126561
|
||||
return False unless $proc2;
|
||||
|
||||
run(‘git’, ‘--git-dir’, $!repo ~ ‘/.git’, ‘merge’, ‘-q’);
|
||||
return True;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
class Backlog does Net::IRC::CommandHandler {
|
||||
has $.limit is rw = 60 * 60 * 48;
|
||||
has $.delay is rw = 30; # seconds before file deletion
|
||||
has $.path is rw = ‘backlogs/’;
|
||||
has $.link is rw = ‘http://alexine.oddmuse.org/backlogs/’; # TODO https
|
||||
has %.messages = ();
|
||||
|
||||
multi method said ($e) {
|
||||
%!messages{$e.where} = [] unless %!messages{$e.where}:exists;
|
||||
%!messages{$e.where}.push: { ‘when’ => time, ‘who’ => $e.who<nick>, ‘what’ => $e.what };
|
||||
self.clean;
|
||||
}
|
||||
|
||||
method clean {
|
||||
for %!messages.values -> $value { # each channel
|
||||
for $value.kv -> $index, $elem { # each message
|
||||
last if time - $elem<when> < $!limit;
|
||||
LAST { $value.splice(0, $index) } # at least one message will be kept
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
method backlog ($e, $match) is cmd {
|
||||
self.clean;
|
||||
mkdir $!path unless $!path.IO ~~ :d;
|
||||
my $name = ^2**128 .pick.base(36);
|
||||
my $fh = open “$!path/$name”, :w;
|
||||
$fh.say(“<{.<who>}> {.<what>}”) for @(%!messages{$e.where});
|
||||
$fh.close;
|
||||
$e.msg: “$!link$name”;
|
||||
Promise.in($!delay).then: { unlink “$!path/$name” };
|
||||
}
|
||||
|
||||
method forget ($e, $match) is cmd {
|
||||
%!messages{$e.where} = [];
|
||||
$e.msg: ‘OK, we didn't have this conversation.’;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
sub MAIN(Str :$nick = ‘alexine’, Str :$password is copy = ‘’, Str :$channel = ‘#oddmuse’) {
|
||||
$password = prompt ‘Nickserv password: ’ unless $password;
|
||||
Net::IRC::Bot.new(
|
||||
nick => $nick,
|
||||
username => $nick,
|
||||
realname => $nick,
|
||||
server => ‘irc.freenode.org’,
|
||||
channels => [ $channel ],
|
||||
debug => True,
|
||||
|
||||
modules => (
|
||||
Intermap.new(),
|
||||
Pages.new(),
|
||||
Sorry.new(),
|
||||
RecentChanges.new(),
|
||||
#RecentCommits.new(),
|
||||
Backlog.new(prefix => ‘.’),
|
||||
Net::IRC::Modules::Tell.new(prefix => ‘.’),
|
||||
Net::IRC::Modules::Autoident.new(password => $password),
|
||||
),
|
||||
).run;
|
||||
}
|
||||
@@ -21,6 +21,7 @@ TEST_LOG="$WORKING_DIRECTORY/log"
|
||||
ODDMUSE_TEST_LOCATION="$WORKING_DIRECTORY/oddmuse-for-tests/"
|
||||
GIT_LOCATION="$WORKING_DIRECTORY/"
|
||||
LAST_COMMIT_FILE="$WORKING_DIRECTORY/last_commit"
|
||||
LAST_STATUS_FILE="$WORKING_DIRECTORY/last_status"
|
||||
FIRST_TESTABLE_COMMIT='1c0801bd6ca23de71c7c360a18a648c2b953f1da'
|
||||
RESULT_FILE="$WORKING_DIRECTORY/output"
|
||||
WIKIPUT='../config/oddmuse/scripts/cli/wikiput'
|
||||
@@ -49,7 +50,9 @@ while :; do
|
||||
"${git[@]}" reset --hard origin/master # starting our search from the last commit
|
||||
|
||||
[[ -f $LAST_COMMIT_FILE ]] || echo "$FIRST_TESTABLE_COMMIT" > "$LAST_COMMIT_FILE"
|
||||
[[ -f $LAST_STATUS_FILE ]] || echo 0 > "$LAST_STATUS_FILE"
|
||||
lastCommit=$(< "$LAST_COMMIT_FILE")
|
||||
lastStatus=$(< "$LAST_STATUS_FILE")
|
||||
|
||||
logOutput=$("${git[@]}" log --topo-order --pretty=oneline | grep --before 1 -m 1 "^$lastCommit")
|
||||
(($(wc -l <<< "$logOutput") < 2)) && exit 0 # No more commits to process, good!
|
||||
@@ -65,14 +68,16 @@ while :; do
|
||||
printf "%s\n" "$output" > "$RESULT_FILE"
|
||||
# echo "Duration: $((duration/60))m$((duration%60))s Status: $status" >> "$RESULT_FILE"
|
||||
printf "%s\n" "$currentCommit" > "$LAST_COMMIT_FILE"
|
||||
printf "%s\n" "$status" > "$LAST_STATUS_FILE"
|
||||
|
||||
"${gitRepo[@]}" add -- "$(readlink -m -- "$RESULT_FILE")" "$(readlink -m -- "$LAST_COMMIT_FILE")"
|
||||
"${gitRepo[@]}" add -- "$(readlink -m -- "$RESULT_FILE")" "$(readlink -m -- "$LAST_COMMIT_FILE")" "$(readlink -m -- "$LAST_STATUS_FILE")"
|
||||
"${gitRepo[@]}" commit -m "Test status at $currentCommit (automated commit)"
|
||||
|
||||
"${gitRepo[@]}" push
|
||||
|
||||
if (( status == 0 )); then
|
||||
"$WIKIPUT" -m -u "$USER_NAME" -s 'Tests PASSED' -z 'ham' "$WIKI_LOCATION/$STATUS_PAGE" <<< $'TEST STATUS – **OK**\n\n'"Commit:${currentCommit:0:7} – see [[$OUT_PAGE|test log]]"
|
||||
(( lastStatus == 0 )) && minor='-m' || minor='' # we will use unquoted variable on purpose
|
||||
"$WIKIPUT" $minor -u "$USER_NAME" -s 'Tests PASSED' -z 'ham' "$WIKI_LOCATION/$STATUS_PAGE" <<< $'TEST STATUS – **OK**\n\n'"Commit:${currentCommit:0:7} – see [[$OUT_PAGE|test log]]"
|
||||
else
|
||||
"$WIKIPUT" -u "$USER_NAME" -s 'Tests FAILED' -z 'ham' "$WIKI_LOCATION/$STATUS_PAGE" <<< $'TEST STATUS – **FAIL**\n\n'"Commit:${currentCommit:0:7} – see [[$OUT_PAGE|test log]]"
|
||||
fi
|
||||
|
||||
@@ -85,7 +85,7 @@ Examples
|
||||
--------
|
||||
|
||||
Journal pages only:
|
||||
$0 --match '^\d{4}-\d{2}-\d{2}'
|
||||
$0 --match '^\\d{4}-\\d{2}-\\d{2}'
|
||||
|
||||
Skip comment pages:
|
||||
$0 --match '^(?!Comments_on_)'
|
||||
|
||||
2
t/atom.t
2
t/atom.t
@@ -48,7 +48,7 @@ sub random_port {
|
||||
my $port = random_port();
|
||||
$ScriptName = "http://localhost:$port";
|
||||
|
||||
AppendStringToFile($ConfigFile, "\$ScriptName = $ScriptName;\n");
|
||||
AppendStringToFile($ConfigFile, "\$ScriptName = '$ScriptName';\n");
|
||||
|
||||
add_module('atom.pl');
|
||||
|
||||
|
||||
10
t/css.t
10
t/css.t
@@ -20,13 +20,13 @@ AppendStringToFile($ConfigFile, "\$StyleSheetPage = 'css';\n");
|
||||
|
||||
# Default
|
||||
xpath_test(get_page('HomePage'),
|
||||
'//link[@type="text/css"][@rel="stylesheet"][@href="http://www.oddmuse.org/default.css"]');
|
||||
'//link[@type="text/css"][@rel="stylesheet"][@href="https://oddmuse.org/default.css"]');
|
||||
|
||||
# StyleSheetPage
|
||||
update_page('css', "em { font-weight: bold; }", 'some css', 0, 1);
|
||||
$page = get_page('HomePage');
|
||||
negative_xpath_test($page,
|
||||
'//link[@type="text/css"][@rel="stylesheet"][@href="http://www.oddmuse.org/default.css"]');
|
||||
'//link[@type="text/css"][@rel="stylesheet"][@href="https://oddmuse.org/default.css"]');
|
||||
xpath_test($page,
|
||||
'//link[@type="text/css"][@rel="stylesheet"][@href="http://localhost/wiki.pl?action=browse;id=css;raw=1;mime-type=text/css"]');
|
||||
|
||||
@@ -34,7 +34,7 @@ xpath_test($page,
|
||||
AppendStringToFile($ConfigFile, "\$StyleSheet = 'http://example.org/test.css';\n");
|
||||
$page = get_page('HomePage');
|
||||
negative_xpath_test($page,
|
||||
'//link[@type="text/css"][@rel="stylesheet"][@href="http://www.oddmuse.org/default.css"]',
|
||||
'//link[@type="text/css"][@rel="stylesheet"][@href="https://oddmuse.org/default.css"]',
|
||||
'//link[@type="text/css"][@rel="stylesheet"][@href="http://localhost/wiki.pl?action=browse;id=css;raw=1;mime-type=text/css"]');
|
||||
xpath_test($page,
|
||||
'//link[@type="text/css"][@rel="stylesheet"][@href="http://example.org/test.css"]');
|
||||
@@ -43,7 +43,7 @@ xpath_test($page,
|
||||
AppendStringToFile($ConfigFile, "\$StyleSheet = ['http://example.org/test.css', 'http://example.org/another.css'];\n");
|
||||
$page = get_page('HomePage');
|
||||
negative_xpath_test($page,
|
||||
'//link[@type="text/css"][@rel="stylesheet"][@href="http://www.oddmuse.org/default.css"]',
|
||||
'//link[@type="text/css"][@rel="stylesheet"][@href="https://oddmuse.org/default.css"]',
|
||||
'//link[@type="text/css"][@rel="stylesheet"][@href="http://localhost/wiki.pl?action=browse;id=css;raw=1;mime-type=text/css"]');
|
||||
xpath_test($page,
|
||||
'//link[@type="text/css"][@rel="stylesheet"][@href="http://example.org/test.css"]');
|
||||
@@ -53,7 +53,7 @@ xpath_test($page,
|
||||
# Parameter
|
||||
$page = get_page('action=browse id=HomePage css=http://example.org/my.css');
|
||||
negative_xpath_test($page,
|
||||
'//link[@type="text/css"][@rel="stylesheet"][@href="http://www.oddmuse.org/default.css"]',
|
||||
'//link[@type="text/css"][@rel="stylesheet"][@href="https://oddmuse.org/default.css"]',
|
||||
'//link[@type="text/css"][@rel="stylesheet"][@href="http://localhost/wiki.pl?action=browse;id=css;raw=1;mime-type=text/css"]',
|
||||
'//link[@type="text/css"][@rel="stylesheet"][@href="http://example.org/test.css"]');
|
||||
xpath_test($page,
|
||||
|
||||
13
t/search.t
13
t/search.t
@@ -15,7 +15,7 @@
|
||||
|
||||
require 't/test.pl';
|
||||
package OddMuse;
|
||||
use Test::More tests => 72;
|
||||
use Test::More tests => 89;
|
||||
use utf8; # tests contain UTF-8 characters and it matters
|
||||
|
||||
add_module('mac.pl');
|
||||
@@ -116,6 +116,17 @@ xpath_test($page, '//a[@class="more"][@href="http://localhost/wiki.pl?search=Som
|
||||
$page = get_page('search=Something preview=1 offset=10 num=10 replace=Other pwd=foo');
|
||||
test_page($page, map { "Page_$_" } ('K' .. 'M'));
|
||||
|
||||
# Now do the replacement
|
||||
|
||||
$page = get_page('search=Something replace=Other pwd=foo');
|
||||
test_page($page, 'Replaced: Something → Other', '13 pages found',
|
||||
map { "Page_$_" } ('A' .. 'M'));
|
||||
|
||||
# Verify that the change has been made
|
||||
|
||||
test_page(get_page('search=Other'), 'Search for: Other', '13 pages found');
|
||||
|
||||
|
||||
# Replace with backreferences, where the replacement pattern is no longer found.
|
||||
# Take 'fuuz and barz.' and replace ([a-z]+)z with x$1 results in 'xfuu and xbar.'
|
||||
test_page(get_page('"search=([a-z]%2b)z" replace=x%241 pwd=foo'), '1 pages found');
|
||||
|
||||
50
wiki.pl
50
wiki.pl
@@ -101,7 +101,6 @@ our $EditPass //= ''; # Whitespace separated passwords.
|
||||
our $PassHashFunction //= ''; # Name of the function to create hashes
|
||||
our $PassSalt //= ''; # Salt will be added to any password before hashing
|
||||
|
||||
our $UnicodeIcons = ''; # 1 = Use unicode characters as icons (fallback font is recommended)
|
||||
our $BannedHosts = 'BannedHosts'; # Page for banned hosts
|
||||
our $BannedCanRead = 1; # 1 = banned cannot edit, 0 = banned cannot read
|
||||
our $BannedContent = 'BannedContent'; # Page for banned content (usually for link-ban)
|
||||
@@ -1171,7 +1170,7 @@ sub GetEditLink { # shortcut
|
||||
$id = FreeToNormal($id);
|
||||
my $action = 'action=edit;id=' . UrlEncode($id);
|
||||
$action .= ';upload=1' if $upload;
|
||||
return ScriptLink($action, NormalToFree($name), 'edit', undef, ($UnicodeIcons && '✎ ') . T('Click to edit this page'), $accesskey);
|
||||
return ScriptLink($action, NormalToFree($name), 'edit', undef, T('Click to edit this page'), $accesskey);
|
||||
}
|
||||
|
||||
sub ScriptUrl {
|
||||
@@ -1675,24 +1674,24 @@ sub RcHeader {
|
||||
my @menu;
|
||||
if ($all) {
|
||||
push(@menu, ScriptLink("$action;days=$days;all=0;showedit=$edits",
|
||||
($UnicodeIcons && '● ') . T('List latest change per page only')));
|
||||
T('List latest change per page only')));
|
||||
} else {
|
||||
push(@menu, ScriptLink("$action;days=$days;all=1;showedit=$edits",
|
||||
($UnicodeIcons && '○ ') . T('List all changes')));
|
||||
T('List all changes')));
|
||||
if ($rollback) {
|
||||
push(@menu, ScriptLink("$action;days=$days;all=0;rollback=0;"
|
||||
. "showedit=$edits", ($UnicodeIcons && '● ') . T('Skip rollbacks')));
|
||||
. "showedit=$edits", T('Skip rollbacks')));
|
||||
} else {
|
||||
push(@menu, ScriptLink("$action;days=$days;all=0;rollback=1;"
|
||||
. "showedit=$edits", ($UnicodeIcons && '○ ') . T('Include rollbacks')));
|
||||
. "showedit=$edits", T('Include rollbacks')));
|
||||
}
|
||||
}
|
||||
if ($edits) {
|
||||
push(@menu, ScriptLink("$action;days=$days;all=$all;showedit=0",
|
||||
($UnicodeIcons && '● ') . T('List only major changes')));
|
||||
T('List only major changes')));
|
||||
} else {
|
||||
push(@menu, ScriptLink("$action;days=$days;all=$all;showedit=1",
|
||||
($UnicodeIcons && '○ ') . T('Include minor changes')));
|
||||
T('Include minor changes')));
|
||||
}
|
||||
return $html .
|
||||
$q->p(join(' | ', (map { ScriptLink("$action;days=$_;all=$all;showedit=$edits", $_); } @RcDays)),
|
||||
@@ -2120,10 +2119,10 @@ sub DoRollback {
|
||||
sub DoAdminPage {
|
||||
my ($id, @rest) = @_;
|
||||
my @menu = ();
|
||||
push(@menu, ScriptLink('action=index', ($UnicodeIcons && '🗐 ') . T('Index of all pages'), 'index')) if $Action{index};
|
||||
push(@menu, ScriptLink('action=version', ($UnicodeIcons && '❓ ') . T('Wiki Version'), 'version')) if $Action{version};
|
||||
push(@menu, ScriptLink('action=password', ($UnicodeIcons && '🛂 ') . T('Password'), 'password')) if $Action{password};
|
||||
push(@menu, ScriptLink('action=maintain', ($UnicodeIcons && '♻ ') . T('Run maintenance'), 'maintain')) if $Action{maintain};
|
||||
push(@menu, ScriptLink('action=index', T('Index of all pages'), 'index')) if $Action{index};
|
||||
push(@menu, ScriptLink('action=version', T('Wiki Version'), 'version')) if $Action{version};
|
||||
push(@menu, ScriptLink('action=password', T('Password'), 'password')) if $Action{password};
|
||||
push(@menu, ScriptLink('action=maintain', T('Run maintenance'), 'maintain')) if $Action{maintain};
|
||||
my @locks;
|
||||
for my $pattern (@KnownLocks) {
|
||||
for my $name (bsd_glob $pattern) {
|
||||
@@ -2378,7 +2377,7 @@ sub GetCss { # prevent javascript injection
|
||||
if ($IndexHash{$StyleSheetPage} and not @css) {
|
||||
push (@css, "$ScriptName?action=browse;id=" . UrlEncode($StyleSheetPage) . ";raw=1;mime-type=text/css")
|
||||
}
|
||||
push (@css, 'http://www.oddmuse.org/default.css') unless @css;
|
||||
push (@css, 'https://oddmuse.org/default.css') unless @css;
|
||||
return join('', map { qq(<link type="text/css" rel="stylesheet" href="$_" />) } @css);
|
||||
}
|
||||
|
||||
@@ -2455,20 +2454,20 @@ sub GetFooterLinks {
|
||||
if ($id =~ /$CommentsPattern/) {
|
||||
push(@elements, GetPageLink($1, undef, 'original', T('a'))) if $1;
|
||||
} else {
|
||||
push(@elements, GetPageLink(($UnicodeIcons && '💬 ') . $CommentsPrefix . $id, undef, 'comment', T('c')));
|
||||
push(@elements, GetPageLink($CommentsPrefix . $id, undef, 'comment', T('c')));
|
||||
}
|
||||
}
|
||||
if (UserCanEdit($id, 0)) {
|
||||
if ($rev) { # showing old revision
|
||||
push(@elements, GetOldPageLink('edit', $id, $rev, ($UnicodeIcons && '⎇ ') . Ts('Edit revision %s of this page', $rev)));
|
||||
push(@elements, GetOldPageLink('edit', $id, $rev, Ts('Edit revision %s of this page', $rev)));
|
||||
} else { # showing current revision
|
||||
push(@elements, GetEditLink($id, ($UnicodeIcons && '✎ ') . T('Edit this page'), undef, T('e')));
|
||||
push(@elements, GetEditLink($id, T('Edit this page'), undef, T('e')));
|
||||
}
|
||||
} else { # no permission or generated page
|
||||
push(@elements, ScriptLink('action=password', ($UnicodeIcons && '🔒 ') . T('This page is read-only'), 'password'));
|
||||
push(@elements, ScriptLink('action=password', T('This page is read-only'), 'password'));
|
||||
}
|
||||
}
|
||||
push(@elements, GetHistoryLink($id, ($UnicodeIcons && '⍿ ') . T('View other revisions'))) if $Action{history} and $id and $rev ne 'history';
|
||||
push(@elements, GetHistoryLink($id, T('View other revisions'))) if $Action{history} and $id and $rev ne 'history';
|
||||
push(@elements, GetPageLink($id, T('View current revision')),
|
||||
GetRCLink($id, T('View all changes'))) if $Action{history} and $rev ne '';
|
||||
if ($Action{contrib} and $id and $rev eq 'history') {
|
||||
@@ -2477,7 +2476,7 @@ sub GetFooterLinks {
|
||||
if ($Action{admin} and GetParam('action', '') ne 'admin') {
|
||||
my $action = 'action=admin';
|
||||
$action .= ';id=' . UrlEncode($id) if $id;
|
||||
push(@elements, ScriptLink($action, ($UnicodeIcons && '⚙ ') . T('Administration'), 'admin'));
|
||||
push(@elements, ScriptLink($action, T('Administration'), 'admin'));
|
||||
}
|
||||
return @elements ? $q->div({-class=>'edit bar'}, @elements) : '';
|
||||
}
|
||||
@@ -3410,6 +3409,11 @@ sub DoSearch {
|
||||
if (GetParam('preview', '')) { # Preview button was used
|
||||
print GetHeader('', Ts('Preview: %s', $string . " → " . $replacement));
|
||||
print $q->start_div({-class=>'content replacement'});
|
||||
print GetFormStart(undef, 'post', 'replace');
|
||||
print GetHiddenValue('search', $string);
|
||||
print GetHiddenValue('replace', $replacement);
|
||||
print GetHiddenValue('delete', GetParam('delete', 0));
|
||||
print $q->submit(-value=>T('Go!')) . $q->end_form();
|
||||
@results = ReplaceAndDiff($re, UnquoteHtml($replacement));
|
||||
} else {
|
||||
print GetHeader('', Ts('Replaced: %s', $string . " → " . $replacement));
|
||||
@@ -3581,7 +3585,7 @@ sub SearchExtract {
|
||||
sub ReplaceAndSave {
|
||||
my ($from, $to) = @_;
|
||||
RequestLockOrError(); # fatal
|
||||
my @result = Replace($from, $to, sub {
|
||||
my @result = Replace($from, $to, 1, sub {
|
||||
my ($id, $new) = @_;
|
||||
Save($id, $new, $from . ' → ' . $to, 1, ($Page{host} ne $q->remote_addr()));
|
||||
});
|
||||
@@ -3591,7 +3595,7 @@ sub ReplaceAndSave {
|
||||
|
||||
sub ReplaceAndDiff {
|
||||
my ($from, $to) = @_;
|
||||
my @found = Replace($from, $to, sub {
|
||||
my @found = Replace($from, $to, 0, sub {
|
||||
my ($id, $new) = @_;
|
||||
print $q->h2(GetPageLink($id)), $q->div({-class=>'diff'}, ImproveDiff(DoDiff($Page{text}, $new)));
|
||||
});
|
||||
@@ -3607,7 +3611,7 @@ sub ReplaceAndDiff {
|
||||
}
|
||||
|
||||
sub Replace {
|
||||
my ($from, $to, $func) = @_; # $func takes $id and $new text
|
||||
my ($from, $to, $all, $func) = @_; # $func takes $id and $new text
|
||||
my $lang = GetParam('lang', '');
|
||||
my $num = GetParam('num', 10);
|
||||
my $offset = GetParam('offset', 0);
|
||||
@@ -3627,7 +3631,7 @@ sub Replace {
|
||||
};
|
||||
if (s/$from/$replacement->()/egi) { # allows use of backreferences
|
||||
push (@result, $id);
|
||||
$func->($id, $_) if @result > $offset and @result <= $offset + $num;
|
||||
$func->($id, $_) if $all or @result > $offset and @result <= $offset + $num;
|
||||
}
|
||||
}
|
||||
return @result;
|
||||
|
||||
Reference in New Issue
Block a user